aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.2.1/libjava/java
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.2.1/libjava/java')
-rw-r--r--gcc-4.2.1/libjava/java/io/BufferedInputStream.java390
-rw-r--r--gcc-4.2.1/libjava/java/io/File.java1416
-rw-r--r--gcc-4.2.1/libjava/java/io/InputStreamReader.java332
-rw-r--r--gcc-4.2.1/libjava/java/io/ObjectInputStream.java1979
-rw-r--r--gcc-4.2.1/libjava/java/io/OutputStreamWriter.java347
-rw-r--r--gcc-4.2.1/libjava/java/io/PrintStream.java566
-rw-r--r--gcc-4.2.1/libjava/java/io/VMObjectStreamClass.java140
-rw-r--r--gcc-4.2.1/libjava/java/io/natFilePosix.cc458
-rw-r--r--gcc-4.2.1/libjava/java/io/natFileWin32.cc351
-rw-r--r--gcc-4.2.1/libjava/java/io/natObjectInputStream.cc80
-rw-r--r--gcc-4.2.1/libjava/java/io/natVMObjectStreamClass.cc87
-rw-r--r--gcc-4.2.1/libjava/java/lang/Character.java3867
-rw-r--r--gcc-4.2.1/libjava/java/lang/Class.h667
-rw-r--r--gcc-4.2.1/libjava/java/lang/Class.java1032
-rw-r--r--gcc-4.2.1/libjava/java/lang/ClassLoader.java998
-rw-r--r--gcc-4.2.1/libjava/java/lang/EcosProcess.java63
-rw-r--r--gcc-4.2.1/libjava/java/lang/Math.java973
-rw-r--r--gcc-4.2.1/libjava/java/lang/Object.h91
-rw-r--r--gcc-4.2.1/libjava/java/lang/Object.java519
-rw-r--r--gcc-4.2.1/libjava/java/lang/Package.java317
-rw-r--r--gcc-4.2.1/libjava/java/lang/PosixProcess.java475
-rw-r--r--gcc-4.2.1/libjava/java/lang/Runtime.java747
-rw-r--r--gcc-4.2.1/libjava/java/lang/SecurityManager.java1057
-rw-r--r--gcc-4.2.1/libjava/java/lang/String.java1397
-rw-r--r--gcc-4.2.1/libjava/java/lang/StringBuffer.java1178
-rw-r--r--gcc-4.2.1/libjava/java/lang/StringBuilder.java1002
-rw-r--r--gcc-4.2.1/libjava/java/lang/System.java560
-rw-r--r--gcc-4.2.1/libjava/java/lang/Thread.java1128
-rw-r--r--gcc-4.2.1/libjava/java/lang/VMClassLoader.java348
-rw-r--r--gcc-4.2.1/libjava/java/lang/VMCompiler.java360
-rw-r--r--gcc-4.2.1/libjava/java/lang/VMDouble.java111
-rw-r--r--gcc-4.2.1/libjava/java/lang/VMFloat.java99
-rw-r--r--gcc-4.2.1/libjava/java/lang/VMSecurityManager.java68
-rw-r--r--gcc-4.2.1/libjava/java/lang/VMThrowable.java82
-rw-r--r--gcc-4.2.1/libjava/java/lang/Win32Process.java90
-rw-r--r--gcc-4.2.1/libjava/java/lang/management/VMManagementFactory.java84
-rw-r--r--gcc-4.2.1/libjava/java/lang/natCharacter.cc237
-rw-r--r--gcc-4.2.1/libjava/java/lang/natClass.cc1269
-rw-r--r--gcc-4.2.1/libjava/java/lang/natClassLoader.cc624
-rw-r--r--gcc-4.2.1/libjava/java/lang/natDouble.cc214
-rw-r--r--gcc-4.2.1/libjava/java/lang/natEcosProcess.cc25
-rw-r--r--gcc-4.2.1/libjava/java/lang/natFloat.cc52
-rw-r--r--gcc-4.2.1/libjava/java/lang/natMath.cc184
-rw-r--r--gcc-4.2.1/libjava/java/lang/natObject.cc1457
-rw-r--r--gcc-4.2.1/libjava/java/lang/natPosixProcess.cc455
-rw-r--r--gcc-4.2.1/libjava/java/lang/natRuntime.cc319
-rw-r--r--gcc-4.2.1/libjava/java/lang/natString.cc1044
-rw-r--r--gcc-4.2.1/libjava/java/lang/natStringBuffer.cc42
-rw-r--r--gcc-4.2.1/libjava/java/lang/natStringBuilder.cc29
-rw-r--r--gcc-4.2.1/libjava/java/lang/natSystem.cc150
-rw-r--r--gcc-4.2.1/libjava/java/lang/natThread.cc472
-rw-r--r--gcc-4.2.1/libjava/java/lang/natVMClassLoader.cc230
-rw-r--r--gcc-4.2.1/libjava/java/lang/natVMSecurityManager.cc29
-rw-r--r--gcc-4.2.1/libjava/java/lang/natVMThrowable.cc45
-rw-r--r--gcc-4.2.1/libjava/java/lang/natWin32Process.cc351
-rw-r--r--gcc-4.2.1/libjava/java/lang/ref/Reference.java210
-rw-r--r--gcc-4.2.1/libjava/java/lang/ref/natReference.cc370
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/Array.java458
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/Constructor.java398
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/Field.java801
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/Method.java444
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/Modifier.java375
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/VMProxy.java143
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/natArray.cc360
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/natConstructor.cc72
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/natField.cc439
-rw-r--r--gcc-4.2.1/libjava/java/lang/reflect/natMethod.cc654
-rw-r--r--gcc-4.2.1/libjava/java/net/InetAddress.java819
-rw-r--r--gcc-4.2.1/libjava/java/net/URL.java974
-rw-r--r--gcc-4.2.1/libjava/java/net/URLClassLoader.java1452
-rw-r--r--gcc-4.2.1/libjava/java/net/VMInetAddress.java117
-rw-r--r--gcc-4.2.1/libjava/java/net/VMNetworkInterface.java66
-rw-r--r--gcc-4.2.1/libjava/java/net/VMURLConnection.java76
-rw-r--r--gcc-4.2.1/libjava/java/net/natInetAddressNoNet.cc36
-rw-r--r--gcc-4.2.1/libjava/java/net/natInetAddressPosix.cc304
-rw-r--r--gcc-4.2.1/libjava/java/net/natInetAddressWin32.cc168
-rw-r--r--gcc-4.2.1/libjava/java/net/natURLClassLoader.cc22
-rw-r--r--gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceNoNet.cc21
-rw-r--r--gcc-4.2.1/libjava/java/net/natVMNetworkInterfacePosix.cc163
-rw-r--r--gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceWin32.cc144
-rw-r--r--gcc-4.2.1/libjava/java/nio/Buffer.java361
-rw-r--r--gcc-4.2.1/libjava/java/nio/DirectByteBufferImpl.java431
-rw-r--r--gcc-4.2.1/libjava/java/nio/MappedByteBuffer.java89
-rw-r--r--gcc-4.2.1/libjava/java/nio/MappedByteBufferImpl.java360
-rw-r--r--gcc-4.2.1/libjava/java/nio/VMDirectByteBuffer.java53
-rw-r--r--gcc-4.2.1/libjava/java/nio/channels/VMChannels.java85
-rw-r--r--gcc-4.2.1/libjava/java/nio/channels/natVMChannels.cc37
-rw-r--r--gcc-4.2.1/libjava/java/nio/charset/Charset.java412
-rw-r--r--gcc-4.2.1/libjava/java/nio/charset/spi/CharsetProvider.java96
-rw-r--r--gcc-4.2.1/libjava/java/nio/natDirectByteBufferImpl.cc72
-rw-r--r--gcc-4.2.1/libjava/java/security/Security.java714
-rw-r--r--gcc-4.2.1/libjava/java/security/VMAccessControlState.java103
-rw-r--r--gcc-4.2.1/libjava/java/security/VMAccessController.java255
-rw-r--r--gcc-4.2.1/libjava/java/security/VMSecureRandom.java134
-rw-r--r--gcc-4.2.1/libjava/java/security/natVMAccessControlState.cc32
-rw-r--r--gcc-4.2.1/libjava/java/security/natVMAccessController.cc23
-rw-r--r--gcc-4.2.1/libjava/java/text/Collator.java395
-rw-r--r--gcc-4.2.1/libjava/java/text/DateFormatSymbols.java502
-rw-r--r--gcc-4.2.1/libjava/java/text/DecimalFormatSymbols.java613
-rw-r--r--gcc-4.2.1/libjava/java/text/natCollator.cc74
-rw-r--r--gcc-4.2.1/libjava/java/util/Calendar.java1277
-rw-r--r--gcc-4.2.1/libjava/java/util/Currency.java355
-rw-r--r--gcc-4.2.1/libjava/java/util/GregorianCalendar.java1358
-rw-r--r--gcc-4.2.1/libjava/java/util/Locale.java864
-rw-r--r--gcc-4.2.1/libjava/java/util/ResourceBundle.java580
-rw-r--r--gcc-4.2.1/libjava/java/util/VMTimeZone.java345
-rw-r--r--gcc-4.2.1/libjava/java/util/logging/LogManager.java981
-rw-r--r--gcc-4.2.1/libjava/java/util/logging/Logger.java1206
-rw-r--r--gcc-4.2.1/libjava/java/util/logging/natLogger.cc49
-rw-r--r--gcc-4.2.1/libjava/java/util/natResourceBundle.cc29
-rw-r--r--gcc-4.2.1/libjava/java/util/natVMTimeZone.cc145
-rw-r--r--gcc-4.2.1/libjava/java/util/zip/Deflater.java334
-rw-r--r--gcc-4.2.1/libjava/java/util/zip/Inflater.java269
-rw-r--r--gcc-4.2.1/libjava/java/util/zip/natDeflater.cc216
-rw-r--r--gcc-4.2.1/libjava/java/util/zip/natInflater.cc214
115 files changed, 52836 insertions, 0 deletions
diff --git a/gcc-4.2.1/libjava/java/io/BufferedInputStream.java b/gcc-4.2.1/libjava/java/io/BufferedInputStream.java
new file mode 100644
index 000000000..36e58f636
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/BufferedInputStream.java
@@ -0,0 +1,390 @@
+/* BufferedInputStream.java -- An input stream that implements buffering
+ Copyright (C) 1998, 1999, 2001, 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.io;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This subclass of <code>FilterInputStream</code> buffers input from an
+ * underlying implementation to provide a possibly more efficient read
+ * mechanism. It maintains the buffer and buffer state in instance
+ * variables that are available to subclasses. The default buffer size
+ * of 2048 bytes can be overridden by the creator of the stream.
+ * <p>
+ * This class also implements mark/reset functionality. It is capable
+ * of remembering any number of input bytes, to the limits of
+ * system memory or the size of <code>Integer.MAX_VALUE</code>
+ * <p>
+ * Please note that this class does not properly handle character
+ * encodings. Consider using the <code>BufferedReader</code> class which
+ * does.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Jeroen Frijters (jeroen@frijters.net)
+ */
+public class BufferedInputStream extends FilterInputStream
+{
+
+ /**
+ * This is the default buffer size
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 2048;
+
+ /**
+ * The buffer used for storing data from the underlying stream.
+ */
+ protected byte[] buf;
+
+ /**
+ * The number of valid bytes currently in the buffer. It is also the index
+ * of the buffer position one byte past the end of the valid data.
+ */
+ protected int count;
+
+ /**
+ * The index of the next character that will by read from the buffer.
+ * When <code>pos == count</code>, the buffer is empty.
+ */
+ protected int pos;
+
+ /**
+ * The value of <code>pos</code> when the <code>mark()</code> method was
+ * called.
+ * This is set to -1 if there is no mark set.
+ */
+ protected int markpos = -1;
+
+ /**
+ * This is the maximum number of bytes than can be read after a
+ * call to <code>mark()</code> before the mark can be discarded.
+ * After this may bytes are read, the <code>reset()</code> method
+ * may not be called successfully.
+ */
+ protected int marklimit;
+
+ /**
+ * This is the initial buffer size. When the buffer is grown because
+ * of marking requirements, it will be grown by bufferSize increments.
+ * The underlying stream will be read in chunks of bufferSize.
+ */
+ private final int bufferSize;
+
+ /**
+ * This method initializes a new <code>BufferedInputStream</code> that will
+ * read from the specified subordinate stream with a default buffer size
+ * of 2048 bytes
+ *
+ * @param in The subordinate stream to read from
+ */
+ public BufferedInputStream(InputStream in)
+ {
+ this(in, DEFAULT_BUFFER_SIZE);
+ }
+
+ /**
+ * This method initializes a new <code>BufferedInputStream</code> that will
+ * read from the specified subordinate stream with a buffer size that
+ * is specified by the caller.
+ *
+ * @param in The subordinate stream to read from
+ * @param size The buffer size to use
+ *
+ * @exception IllegalArgumentException when size is smaller then 1
+ */
+ public BufferedInputStream(InputStream in, int size)
+ {
+ super(in);
+ if (size <= 0)
+ throw new IllegalArgumentException();
+ buf = new byte[size];
+ // initialize pos & count to bufferSize, to prevent refill from
+ // allocating a new buffer (if the caller starts out by calling mark()).
+ pos = count = bufferSize = size;
+ }
+
+ /**
+ * This method returns the number of bytes that can be read from this
+ * stream before a read can block. A return of 0 indicates that blocking
+ * might (or might not) occur on the very next read attempt.
+ * <p>
+ * The number of available bytes will be the number of read ahead bytes
+ * stored in the internal buffer plus the number of available bytes in
+ * the underlying stream.
+ *
+ * @return The number of bytes that can be read before blocking could occur
+ *
+ * @exception IOException If an error occurs
+ */
+ public synchronized int available() throws IOException
+ {
+ return count - pos + in.available();
+ }
+
+ /**
+ * This method closes the underlying input stream and frees any
+ * resources associated with it. Sets <code>buf</code> to <code>null</code>.
+ *
+ * @exception IOException If an error occurs.
+ */
+ public void close() throws IOException
+ {
+ // Free up the array memory.
+ buf = null;
+ pos = count = 0;
+ markpos = -1;
+ in.close();
+ }
+
+ /**
+ * This method marks a position in the input to which the stream can be
+ * "reset" by calling the <code>reset()</code> method. The parameter
+ * <code>readlimit</code> is the number of bytes that can be read from the
+ * stream after setting the mark before the mark becomes invalid. For
+ * example, if <code>mark()</code> is called with a read limit of 10, then
+ * when 11 bytes of data are read from the stream before the
+ * <code>reset()</code> method is called, then the mark is invalid and the
+ * stream object instance is not required to remember the mark.
+ * <p>
+ * Note that the number of bytes that can be remembered by this method
+ * can be greater than the size of the internal read buffer. It is also
+ * not dependent on the subordinate stream supporting mark/reset
+ * functionality.
+ *
+ * @param readlimit The number of bytes that can be read before the mark
+ * becomes invalid
+ */
+ public synchronized void mark(int readlimit)
+ {
+ marklimit = readlimit;
+ markpos = pos;
+ }
+
+ /**
+ * This method returns <code>true</code> to indicate that this class
+ * supports mark/reset functionality.
+ *
+ * @return <code>true</code> to indicate that mark/reset functionality is
+ * supported
+ *
+ */
+ public boolean markSupported()
+ {
+ return true;
+ }
+
+ /**
+ * This method reads an unsigned byte from the input stream and returns it
+ * as an int in the range of 0-255. This method also will return -1 if
+ * the end of the stream has been reached.
+ * <p>
+ * This method will block until the byte can be read.
+ *
+ * @return The byte read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+ public synchronized int read() throws IOException
+ {
+ if (pos >= count && !refill())
+ return -1; // EOF
+
+ return buf[pos++] & 0xFF;
+ }
+
+ /**
+ * This method reads bytes from a stream and stores them into a caller
+ * supplied buffer. It starts storing the data at index <code>off</code>
+ * into the buffer and attempts to read <code>len</code> bytes. This method
+ * can return before reading the number of bytes requested, but it will try
+ * to read the requested number of bytes by repeatedly calling the underlying
+ * stream as long as available() for this stream continues to return a
+ * non-zero value (or until the requested number of bytes have been read).
+ * The actual number of bytes read is returned as an int. A -1 is returned
+ * to indicate the end of the stream.
+ * <p>
+ * This method will block until some data can be read.
+ *
+ * @param b The array into which the bytes read should be stored
+ * @param off The offset into the array to start storing bytes
+ * @param len The requested number of bytes to read
+ *
+ * @return The actual number of bytes read, or -1 if end of stream.
+ *
+ * @exception IOException If an error occurs.
+ * @exception IndexOutOfBoundsException when <code>off</code> or
+ * <code>len</code> are negative, or when <code>off + len</code>
+ * is larger then the size of <code>b</code>,
+ */
+ public synchronized int read(byte[] b, int off, int len) throws IOException
+ {
+ if (off < 0 || len < 0 || b.length - off < len)
+ throw new IndexOutOfBoundsException();
+
+ if (len == 0)
+ return 0;
+
+ if (pos >= count && !refill())
+ return -1; // No bytes were read before EOF.
+
+ int totalBytesRead = Math.min(count - pos, len);
+ System.arraycopy(buf, pos, b, off, totalBytesRead);
+ pos += totalBytesRead;
+ off += totalBytesRead;
+ len -= totalBytesRead;
+
+ while (len > 0 && in.available() > 0 && refill())
+ {
+ int remain = Math.min(count - pos, len);
+ System.arraycopy(buf, pos, b, off, remain);
+ pos += remain;
+ off += remain;
+ len -= remain;
+ totalBytesRead += remain;
+ }
+
+ return totalBytesRead;
+ }
+
+ /**
+ * This method resets a stream to the point where the <code>mark()</code>
+ * method was called. Any bytes that were read after the mark point was
+ * set will be re-read during subsequent reads.
+ * <p>
+ * This method will throw an IOException if the number of bytes read from
+ * the stream since the call to <code>mark()</code> exceeds the mark limit
+ * passed when establishing the mark.
+ *
+ * @exception IOException If <code>mark()</code> was never called or more
+ * then <code>marklimit</code> bytes were read since the last
+ * call to <code>mark()</code>
+ */
+ public synchronized void reset() throws IOException
+ {
+ if (markpos == -1)
+ throw new IOException(buf == null ? "Stream closed." : "Invalid mark.");
+
+ pos = markpos;
+ }
+
+ /**
+ * This method skips the specified number of bytes in the stream. It
+ * returns the actual number of bytes skipped, which may be less than the
+ * requested amount.
+ *
+ * @param n The requested number of bytes to skip
+ *
+ * @return The actual number of bytes skipped.
+ *
+ * @exception IOException If an error occurs
+ */
+ public synchronized long skip(long n) throws IOException
+ {
+ if (buf == null)
+ throw new IOException("Stream closed.");
+
+ final long origN = n;
+
+ while (n > 0L)
+ {
+ if (pos >= count)
+ {
+ if (markpos == -1)
+ {
+ // Buffer is empty and no mark is set, skip on the
+ // underlying stream.
+ n -= in.skip(n);
+ break;
+ }
+ else if (!refill())
+ break;
+ }
+
+ int numread = (int) Math.min((long) (count - pos), n);
+ pos += numread;
+ n -= numread;
+ }
+
+ return origN - n;
+ }
+
+ // GCJ LOCAL: package-private for use by InputStreamReader
+ /**
+ * Called to refill the buffer (when count is equal to pos).
+ *
+ * @return <code>true</code> when at least one additional byte was read
+ * into <code>buf</code>, <code>false</code> otherwise (at EOF).
+ */
+ boolean refill() throws IOException
+ {
+ if (buf == null)
+ throw new IOException("Stream closed.");
+
+ if (markpos == -1 || count - markpos >= marklimit)
+ {
+ markpos = -1;
+ pos = count = 0;
+ }
+ else
+ {
+ byte[] newbuf = buf;
+ if (markpos < bufferSize)
+ {
+ newbuf = new byte[count - markpos + bufferSize];
+ }
+ System.arraycopy(buf, markpos, newbuf, 0, count - markpos);
+ buf = newbuf;
+ count -= markpos;
+ pos -= markpos;
+ markpos = 0;
+ }
+
+ int numread = in.read(buf, count, bufferSize);
+
+ if (numread <= 0) // EOF
+ return false;
+
+ count += numread;
+ return true;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/io/File.java b/gcc-4.2.1/libjava/java/io/File.java
new file mode 100644
index 000000000..33776abad
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/File.java
@@ -0,0 +1,1416 @@
+/* File.java -- Class representing a file on disk
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
+ 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.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import gnu.classpath.Configuration;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * Status: Complete to version 1.3.
+ */
+
+/**
+ * This class represents a file or directory on a local disk. It provides
+ * facilities for dealing with a variety of systems that use various
+ * types of path separators ("/" versus "\", for example). It also
+ * contains method useful for creating and deleting files and directories.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ */
+public class File implements Serializable, Comparable
+{
+ private static final long serialVersionUID = 301077366599181567L;
+
+ // QUERY arguments to access function.
+ private final static int READ = 0;
+ private final static int WRITE = 1;
+ private final static int EXISTS = 2;
+
+ // QUERY arguments to stat function.
+ private final static int DIRECTORY = 0;
+ private final static int ISFILE = 1;
+ private final static int ISHIDDEN = 2;
+
+ // QUERY arguments to attr function.
+ private final static int MODIFIED = 0;
+ private final static int LENGTH = 1;
+
+ private final native long attr (int query);
+ // On OSF1 V5.0, `stat' is a macro. It is easiest to use the name
+ // `_stat' instead. We do the same thing for `_access' just in
+ // case.
+ private final native boolean _access (int query);
+ private final native boolean _stat (int query);
+
+ /**
+ * This is the path separator string for the current host. This field
+ * contains the value of the <code>file.separator</code> system property.
+ * An example separator string would be "/" on the GNU system.
+ */
+ public static final String separator = System.getProperty("file.separator");
+ private static final String dupSeparator = separator + separator;
+
+ /**
+ * This is the first character of the file separator string. On many
+ * hosts (for example, on the GNU system), this represents the entire
+ * separator string. The complete separator string is obtained from the
+ * <code>file.separator</code>system property.
+ */
+ public static final char separatorChar = separator.charAt(0);
+
+ /**
+ * This is the string that is used to separate the host name from the
+ * path name in paths than include the host name. It is the value of
+ * the <code>path.separator</code> system property.
+ */
+ public static final String pathSeparator
+ = System.getProperty("path.separator");
+
+ /**
+ * This is the first character of the string used to separate the host name
+ * from the path name in paths that include a host. The separator string
+ * is taken from the <code>path.separator</code> system property.
+ */
+ public static final char pathSeparatorChar = pathSeparator.charAt(0);
+
+ static final String tmpdir = System.getProperty("java.io.tmpdir");
+ static int maxPathLen;
+ static boolean caseSensitive;
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javaio");
+ }
+
+ init_native();
+ }
+
+ // Native function called at class initialization. This should should
+ // set the maxPathLen and caseSensitive variables.
+ private static native void init_native();
+
+ /**
+ * This is the path to the file set when the object is created. It
+ * may be an absolute or relative path name.
+ */
+ private String path;
+
+ // We keep a counter for use by createTempFile. We choose the first
+ // value randomly to try to avoid clashes with other VMs.
+ private static long counter = Double.doubleToLongBits (Math.random());
+
+ /**
+ * This method tests whether or not the current thread is allowed to
+ * to read the file pointed to by this object. This will be true if and
+ * and only if 1) the file exists and 2) the <code>SecurityManager</code>
+ * (if any) allows access to the file via it's <code>checkRead</code>
+ * method 3) the file is readable.
+ *
+ * @return <code>true</code> if reading is allowed,
+ * <code>false</code> otherwise
+ *
+ * @exception SecurityException If the <code>SecurityManager</code>
+ * does not allow access to the file
+ */
+ public boolean canRead()
+ {
+ checkRead();
+ return _access (READ);
+ }
+
+ /**
+ * This method test whether or not the current thread is allowed to
+ * write to this object. This will be true if and only if 1) The
+ * <code>SecurityManager</code> (if any) allows write access to the
+ * file and 2) The file exists and 3) The file is writable. To determine
+ * whether or not a non-existent file can be created, check the parent
+ * directory for write access.
+ *
+ * @return <code>true</code> if writing is allowed, <code>false</code>
+ * otherwise
+ *
+ * @exception SecurityException If the <code>SecurityManager</code>
+ * does not allow access to the file
+ */
+ public boolean canWrite()
+ {
+ checkWrite();
+ return _access (WRITE);
+ }
+
+ private native boolean performCreate() throws IOException;
+
+ /**
+ * This method creates a new file of zero length with the same name as
+ * the path of this <code>File</code> object if an only if that file
+ * does not already exist.
+ * <p>
+ * A <code>SecurityManager.checkWrite</code> check is done prior
+ * to performing this action.
+ *
+ * @return <code>true</code> if the file was created, <code>false</code> if
+ * the file alread existed.
+ *
+ * @exception IOException If an I/O error occurs
+ * @exception SecurityException If the <code>SecurityManager</code> will
+ * not allow this operation to be performed.
+ *
+ * @since 1.2
+ */
+ public boolean createNewFile() throws IOException
+ {
+ checkWrite();
+ return performCreate();
+ }
+
+ /*
+ * This native method handles the actual deleting of the file
+ */
+ private native boolean performDelete();
+
+ /**
+ * This method deletes the file represented by this object. If this file
+ * is a directory, it must be empty in order for the delete to succeed.
+ *
+ * @return <code>true</code> if the file was deleted, <code>false</code>
+ * otherwise
+ *
+ * @exception SecurityException If deleting of the file is not allowed
+ */
+ public synchronized boolean delete()
+ {
+ SecurityManager s = System.getSecurityManager();
+
+ if (s != null)
+ s.checkDelete(path);
+
+ return performDelete();
+ }
+
+ /**
+ * This method tests two <code>File</code> objects for equality by
+ * comparing the path of the specified <code>File</code> against the path
+ * of this object. The two objects are equal if an only if 1) The
+ * argument is not null 2) The argument is a <code>File</code> object and
+ * 3) The path of the <code>File</code>argument is equal to the path
+ * of this object.
+ * <p>
+ * The paths of the files are determined by calling the
+ * <code>getPath()</code>
+ * method on each object.
+ *
+ * @return <code>true</code> if the two objects are equal,
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof File))
+ return false;
+
+ File other = (File) obj;
+
+ if (caseSensitive)
+ return path.equals(other.path);
+ else
+ return path.equalsIgnoreCase(other.path);
+ }
+
+ /*
+ * This method tests whether or not the file represented by the
+ * object actually exists on the filesystem.
+ */
+ private boolean internalExists()
+ {
+ return _access (EXISTS);
+ }
+
+ /**
+ * This method tests whether or not the file represented by the object
+ * actually exists on the filesystem.
+ *
+ * @return <code>true</code> if the file exists, <code>false</code>otherwise.
+ *
+ * @exception SecurityException If reading of the file is not permitted
+ */
+ public boolean exists()
+ {
+ checkRead();
+ return internalExists();
+ }
+
+ /**
+ * This method initializes a new <code>File</code> object to represent
+ * a file with the specified path.
+ *
+ * @param name The path name of the file
+ */
+ public File(String name)
+ {
+ path = normalizePath (name);
+ }
+
+ // Remove duplicate and redundant separator characters.
+ private String normalizePath(String p)
+ {
+ // On Windows, convert any '/' to '\'. This appears to be the same logic
+ // that Sun's Win32 Java performs.
+ if (separatorChar == '\\')
+ {
+ p = p.replace ('/', '\\');
+ // We have to special case the "\c:" prefix.
+ if (p.length() > 2 && p.charAt(0) == '\\' &&
+ ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
+ (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
+ p.charAt(2) == ':')
+ p = p.substring(1);
+ }
+
+ int dupIndex = p.indexOf(dupSeparator);
+ int plen = p.length();
+
+ // Special case: permit Windows UNC path prefix.
+ if (dupSeparator.equals("\\\\") && dupIndex == 0)
+ dupIndex = p.indexOf(dupSeparator, 1);
+
+ if (dupIndex == -1)
+ {
+ // Ignore trailing separator (though on Windows "a:\", for
+ // example, is a valid and minimal path).
+ if (plen > 1 && p.charAt (plen - 1) == separatorChar)
+ {
+ if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':'))
+ return p.substring (0, plen - 1);
+ }
+ else
+ return p;
+ }
+
+ StringBuffer newpath = new StringBuffer(plen);
+ int last = 0;
+ while (dupIndex != -1)
+ {
+ newpath.append(p.substring(last, dupIndex));
+ // Ignore the duplicate path characters.
+ while (p.charAt(dupIndex) == separatorChar)
+ {
+ dupIndex++;
+ if (dupIndex == plen)
+ return newpath.toString();
+ }
+ newpath.append(separatorChar);
+ last = dupIndex;
+ dupIndex = p.indexOf(dupSeparator, last);
+ }
+
+ // Again, ignore possible trailing separator (except special cases
+ // like "a:\" on Windows).
+ int end;
+ if (plen > 1 && p.charAt (plen - 1) == separatorChar)
+ {
+ if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')
+ end = plen;
+ else
+ end = plen - 1;
+ }
+ else
+ end = plen;
+ newpath.append(p.substring(last, end));
+
+ return newpath.toString();
+ }
+
+ /**
+ * This method initializes a new <code>File</code> object to represent
+ * a file in the specified named directory. The path name to the file
+ * will be the directory name plus the separator string plus the file
+ * name. If the directory path name ends in the separator string, another
+ * separator string will still be appended.
+ *
+ * @param dirPath The path to the directory the file resides in
+ * @param name The name of the file
+ */
+ public File(String dirPath, String name)
+ {
+ if (name == null)
+ throw new NullPointerException();
+ if (dirPath != null)
+ {
+ if (dirPath.length() > 0)
+ {
+ // Try to be smart about the number of separator characters.
+ if (dirPath.charAt(dirPath.length() - 1) == separatorChar
+ || name.length() == 0)
+ path = normalizePath(dirPath + name);
+ else
+ path = normalizePath(dirPath + separatorChar + name);
+ }
+ else
+ {
+ // If dirPath is empty, use a system dependant
+ // default prefix.
+ // Note that the leading separators in name have
+ // to be chopped off, to prevent them forming
+ // a UNC prefix on Windows.
+ if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
+ {
+ int skip = 0;
+ while(name.length() > skip
+ && (name.charAt(skip) == separatorChar
+ || name.charAt(skip) == '/'))
+ {
+ skip++;
+ }
+ name = name.substring(skip);
+ }
+ path = normalizePath(separatorChar + name);
+ }
+ }
+ else
+ path = normalizePath(name);
+ }
+
+ /**
+ * This method initializes a new <code>File</code> object to represent
+ * a file in the specified directory. If the <code>directory</code>
+ * argument is <code>null</code>, the file is assumed to be in the
+ * current directory as specified by the <code>user.dir</code> system
+ * property
+ *
+ * @param directory The directory this file resides in
+ * @param name The name of the file
+ */
+ public File(File directory, String name)
+ {
+ this (directory == null ? null : directory.path, name);
+ }
+
+ /**
+ * This method initializes a new <code>File</code> object to represent
+ * a file corresponding to the specified <code>file:</code> protocol URI.
+ *
+ * @param uri The uri.
+ */
+ public File(URI uri)
+ {
+ if (uri == null)
+ throw new NullPointerException("uri is null");
+
+ if (!uri.getScheme().equals("file"))
+ throw new IllegalArgumentException("invalid uri protocol");
+
+ String name = uri.getPath();
+ if (name == null)
+ throw new IllegalArgumentException("URI \"" + uri
+ + "\" is not hierarchical");
+ path = normalizePath(name);
+ }
+
+ /**
+ * This method returns the path of this file as an absolute path name.
+ * If the path name is already absolute, then it is returned. Otherwise
+ * the value returned is the current directory plus the separatory
+ * string plus the path of the file. The current directory is determined
+ * from the <code>user.dir</code> system property.
+ *
+ * @return The absolute path of this file
+ */
+ public String getAbsolutePath()
+ {
+ if (isAbsolute())
+ return path;
+ else if (separatorChar == '\\'
+ && path.length() > 0 && path.charAt (0) == '\\')
+ {
+ // On Windows, even if the path starts with a '\\' it is not
+ // really absolute until we prefix the drive specifier from
+ // the current working directory to it.
+ return System.getProperty ("user.dir").substring (0, 2) + path;
+ }
+ else if (separatorChar == '\\'
+ && path.length() > 1 && path.charAt (1) == ':'
+ && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
+ || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
+ {
+ // On Windows, a process has a current working directory for
+ // each drive and a path like "G:foo\bar" would mean the
+ // absolute path "G:\wombat\foo\bar" if "\wombat" is the
+ // working directory on the G drive.
+ String drvDir = null;
+ try
+ {
+ drvDir = new File (path.substring (0, 2)).getCanonicalPath();
+ }
+ catch (IOException e)
+ {
+ drvDir = path.substring (0, 2) + "\\";
+ }
+
+ // Note: this would return "C:\\." for the path "C:.", if "\"
+ // is the working folder on the C drive, but this is
+ // consistent with what Sun's JRE 1.4.1.01 actually returns!
+ if (path.length() > 2)
+ return drvDir + '\\' + path.substring (2, path.length());
+ else
+ return drvDir;
+ }
+ else
+ return System.getProperty ("user.dir") + separatorChar + path;
+ }
+
+ /**
+ * This method returns a <code>File</code> object representing the
+ * absolute path of this object.
+ *
+ * @return A <code>File</code> with the absolute path of the object.
+ *
+ * @since 1.2
+ */
+ public File getAbsoluteFile()
+ {
+ return new File(getAbsolutePath());
+ }
+
+ /**
+ * This method returns a canonical representation of the pathname of
+ * this file. The actual form of the canonical representation is
+ * system-dependent. On the GNU system, conversion to canonical
+ * form involves the removal of redundant separators, references to
+ * "." and "..", and symbolic links.
+ * <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 native String getCanonicalPath() throws IOException;
+
+ /**
+ * This method returns a <code>File</code> object representing the
+ * canonical path of this object.
+ *
+ * @return A <code>File</code> instance representing the canonical path of
+ * this object.
+ *
+ * @exception IOException If an error occurs.
+ *
+ * @since 1.2
+ */
+ public File getCanonicalFile() throws IOException
+ {
+ return new File(getCanonicalPath());
+ }
+
+ /**
+ * 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
+ */
+ public String getName()
+ {
+ int nameSeqIndex = 0;
+
+ if (separatorChar == '\\' && path.length() > 1)
+ {
+ // On Windows, ignore the drive specifier or the leading '\\'
+ // of a UNC network path, if any (a.k.a. the "prefix").
+ if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
+ || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
+ || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
+ && path.charAt (1) == ':'))
+ {
+ if (path.length() > 2)
+ nameSeqIndex = 2;
+ else
+ return "";
+ }
+ }
+
+ String nameSeq
+ = (nameSeqIndex > 0 ? path.substring (nameSeqIndex) : path);
+
+ int last = nameSeq.lastIndexOf (separatorChar);
+
+ return nameSeq.substring (last + 1);
+ }
+
+ /**
+ * This method returns a <code>String</code> the represents this file's
+ * parent. <code>null</code> is returned if the file has no parent. The
+ * parent is determined via a simple operation which removes the
+ *
+ * @return The parent directory of this file
+ */
+ public String getParent()
+ {
+ String prefix = null;
+ int nameSeqIndex = 0;
+
+ // The "prefix", if present, is the leading "/" on UNIX and
+ // either the drive specifier (e.g. "C:") or the leading "\\"
+ // of a UNC network path on Windows.
+ if (separatorChar == '/' && path.charAt (0) == '/')
+ {
+ prefix = "/";
+ nameSeqIndex = 1;
+ }
+ else if (separatorChar == '\\' && path.length() > 1)
+ {
+ if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
+ || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
+ || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
+ && path.charAt (1) == ':'))
+ {
+ prefix = path.substring (0, 2);
+ nameSeqIndex = 2;
+ }
+ }
+
+ // According to the JDK docs, the returned parent path is the
+ // portion of the name sequence before the last separator
+ // character, if found, prefixed by the prefix, otherwise null.
+ if (nameSeqIndex < path.length())
+ {
+ String nameSeq = path.substring (nameSeqIndex, path.length());
+ int last = nameSeq.lastIndexOf (separatorChar);
+ if (last == -1)
+ return prefix;
+ else if (last == (nameSeq.length() - 1))
+ // Note: The path would not have a trailing separator
+ // except for cases like "C:\" on Windows (see
+ // normalizePath( )), where Sun's JRE 1.4 returns null.
+ return null;
+ else if (last == 0)
+ last++;
+
+ if (prefix != null)
+ return prefix + nameSeq.substring (0, last);
+ else
+ return nameSeq.substring (0, last);
+ }
+ else
+ // Sun's JRE 1.4 returns null if the prefix is the only
+ // component of the path - so "/" gives null on UNIX and
+ // "C:", "\\", etc. return null on Windows.
+ return null;
+ }
+
+ /**
+ * This method returns a <code>File</code> object representing the parent
+ * file of this one.
+ *
+ * @return a <code>File</code> for the parent of this object.
+ * <code>null</code>
+ * will be returned if this object does not have a parent.
+ *
+ * @since 1.2
+ */
+ public File getParentFile()
+ {
+ String parent = getParent();
+ return parent != null ? new File(parent) : null;
+ }
+
+ /**
+ * Returns the path name that represents this file. May be a relative
+ * or an absolute path name
+ *
+ * @return The pathname of this file
+ */
+ public String getPath()
+ {
+ return path;
+ }
+
+ /**
+ * This method returns a hash code representing this file. It is the
+ * hash code of the path of this file (as returned by <code>getPath()</code>)
+ * exclusived or-ed with the value 1234321.
+ *
+ * @return The hash code for this object
+ */
+ public int hashCode()
+ {
+ if (caseSensitive)
+ return path.hashCode() ^ 1234321;
+ else
+ return path.toLowerCase().hashCode() ^ 1234321;
+ }
+
+ /**
+ * This method returns true if this object represents an absolute file
+ * path and false if it does not. The definition of an absolute path varies
+ * by system. As an example, on GNU systems, a path is absolute if it starts
+ * with a "/".
+ *
+ * @return <code>true</code> if this object represents an absolute
+ * file name, <code>false</code> otherwise.
+ */
+ public native boolean isAbsolute();
+
+ /*
+ * This method tests whether or not the file represented by this
+ * object is a directory.
+ */
+ private boolean internalIsDirectory()
+ {
+ return _stat (DIRECTORY);
+ }
+
+ /**
+ * This method tests whether or not the file represented by this object
+ * is a directory. In order for this method to return <code>true</code>,
+ * the file represented by this object must exist and be a directory.
+ *
+ * @return <code>true</code> if this file is a directory, <code>false</code>
+ * otherwise
+ *
+ * @exception SecurityException If reading of the file is not permitted
+ */
+ public boolean isDirectory()
+ {
+ checkRead();
+ return internalIsDirectory();
+ }
+
+ /**
+ * This method tests whether or not the file represented by this object
+ * is a "plain" file. A file is a plain file if and only if it 1) Exists,
+ * 2) Is not a directory or other type of special file.
+ *
+ * @return <code>true</code> if this is a plain file, <code>false</code>
+ * otherwise
+ *
+ * @exception SecurityException If reading of the file is not permitted
+ */
+ public boolean isFile()
+ {
+ checkRead();
+ return _stat (ISFILE);
+ }
+
+ /**
+ * 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
+ */
+ public boolean isHidden()
+ {
+ checkRead();
+ return _stat (ISHIDDEN);
+ }
+
+ /**
+ * This method returns the last modification time of this file. The
+ * time value returned is an abstract value that should not be interpreted
+ * as a specified time value. It is only useful for comparing to other
+ * such time values returned on the same system. In that case, the larger
+ * value indicates a more recent modification time.
+ * <p>
+ * If the file does not exist, then a value of 0 is returned.
+ *
+ * @return The last modification time of the file
+ *
+ * @exception SecurityException If reading of the file is not permitted
+ */
+ public long lastModified()
+ {
+ checkRead();
+ return attr (MODIFIED);
+ }
+
+ /**
+ * This method returns the length of the file represented by this object,
+ * or 0 if the specified file does not exist.
+ *
+ * @return The length of the file
+ *
+ * @exception SecurityException If reading of the file is not permitted
+ */
+ public long length()
+ {
+ checkRead();
+ return attr (LENGTH);
+ }
+
+ /*
+ * This native function actually produces the list of file in this
+ * directory
+ */
+ private final native Object[] performList (FilenameFilter filter,
+ FileFilter fileFilter,
+ Class result_type);
+
+ /**
+ * This method returns a array of <code>String</code>'s representing the
+ * list of files is then directory represented by this object. If this
+ * object represents a non-directory file or a non-existent file, then
+ * <code>null</code> is returned. The list of files will not contain
+ * any names such as "." or ".." which indicate the current or parent
+ * directory. Also, the names are not guaranteed to be sorted.
+ * <p>
+ * In this form of the <code>list()</code> method, a filter is specified
+ * that allows the caller to control which files are returned in the
+ * list. The <code>FilenameFilter</code> specified is called for each
+ * file returned to determine whether or not that file should be included
+ * in the list.
+ * <p>
+ * A <code>SecurityManager</code> check is made prior to reading the
+ * directory. If read access to the directory is denied, an exception
+ * will be thrown.
+ *
+ * @param filter An object which will identify files to exclude from
+ * the directory listing.
+ *
+ * @return An array of files in the directory, or <code>null</code>
+ * if this object does not represent a valid directory.
+ *
+ * @exception SecurityException If read access is not allowed to the
+ * directory by the <code>SecurityManager</code>
+ */
+ public String[] list(FilenameFilter filter)
+ {
+ checkRead();
+ return (String[]) performList (filter, null, String.class);
+ }
+
+ /**
+ * This method returns a array of <code>String</code>'s representing the
+ * list of files is then directory represented by this object. If this
+ * object represents a non-directory file or a non-existent file, then
+ * <code>null</code> is returned. The list of files will not contain
+ * any names such as "." or ".." which indicate the current or parent
+ * directory. Also, the names are not guaranteed to be sorted.
+ * <p>
+ * A <code>SecurityManager</code> check is made prior to reading the
+ * directory. If read access to the directory is denied, an exception
+ * will be thrown.
+ *
+ * @return An array of files in the directory, or <code>null</code> if
+ * this object does not represent a valid directory.
+ *
+ * @exception SecurityException If read access is not allowed to the
+ * directory by the <code>SecurityManager</code>
+ */
+ public String[] list()
+ {
+ checkRead();
+ return (String[]) performList (null, null, String.class);
+ }
+
+ /**
+ * This method returns an array of <code>File</code> objects representing
+ * all the files in the directory represented by this object. If this
+ * object does not represent a directory, <code>null</code> is returned.
+ * Each of the returned <code>File</code> object is constructed with this
+ * object as its parent.
+ * <p>
+ * A <code>SecurityManager</code> check is made prior to reading the
+ * directory. If read access to the directory is denied, an exception
+ * will be thrown.
+ *
+ * @return An array of <code>File</code> objects for this directory.
+ *
+ * @exception SecurityException If the <code>SecurityManager</code> denies
+ * access to this directory.
+ *
+ * @since 1.2
+ */
+ public File[] listFiles()
+ {
+ checkRead();
+ return (File[]) performList (null, null, File.class);
+ }
+
+ /**
+ * This method returns an array of <code>File</code> objects representing
+ * all the files in the directory represented by this object. If this
+ * object does not represent a directory, <code>null</code> is returned.
+ * Each of the returned <code>File</code> object is constructed with this
+ * object as its parent.
+ * <p>
+ * In this form of the <code>listFiles()</code> method, a filter is specified
+ * that allows the caller to control which files are returned in the
+ * list. The <code>FilenameFilter</code> specified is called for each
+ * file returned to determine whether or not that file should be included
+ * in the list.
+ * <p>
+ * A <code>SecurityManager</code> check is made prior to reading the
+ * directory. If read access to the directory is denied, an exception
+ * will be thrown.
+ *
+ * @return An array of <code>File</code> objects for this directory.
+ *
+ * @exception SecurityException If the <code>SecurityManager</code> denies
+ * access to this directory.
+ *
+ * @since 1.2
+ */
+ public File[] listFiles(FilenameFilter filter)
+ {
+ checkRead();
+ return (File[]) performList (filter, null, File.class);
+ }
+
+ /**
+ * This method returns an array of <code>File</code> objects representing
+ * all the files in the directory represented by this object. If this
+ * object does not represent a directory, <code>null</code> is returned.
+ * Each of the returned <code>File</code> object is constructed with this
+ * object as its parent.
+ * <p>
+ * In this form of the <code>listFiles()</code> method, a filter is specified
+ * that allows the caller to control which files are returned in the
+ * list. The <code>FileFilter</code> specified is called for each
+ * file returned to determine whether or not that file should be included
+ * in the list.
+ * <p>
+ * A <code>SecurityManager</code> check is made prior to reading the
+ * directory. If read access to the directory is denied, an exception
+ * will be thrown.
+ *
+ * @return An array of <code>File</code> objects for this directory.
+ *
+ * @exception SecurityException If the <code>SecurityManager</code> denies
+ * access to this directory.
+ *
+ * @since 1.2
+ */
+ public File[] listFiles(FileFilter filter)
+ {
+ checkRead();
+ return (File[]) performList (null, filter, File.class);
+ }
+
+ /**
+ * This method returns a <code>String</code> that is the path name of the
+ * file as returned by <code>getPath</code>.
+ *
+ * @return A <code>String</code> representation of this file
+ */
+ public String toString()
+ {
+ return path;
+ }
+
+ /**
+ * @return A <code>URI</code> for this object.
+ */
+ public URI toURI()
+ {
+ String abspath = getAbsolutePath();
+
+ if (isDirectory())
+ abspath = abspath + separator;
+
+ try
+ {
+ return new URI("file", abspath.replace(separatorChar, '/'), null);
+ }
+ catch (URISyntaxException use)
+ {
+ // Can't happen.
+ throw new RuntimeException(use);
+ }
+ }
+
+ /**
+ * This method returns a <code>URL</code> with the <code>file:</code>
+ * protocol that represents this file. The exact form of this URL is
+ * system dependent.
+ *
+ * @return A <code>URL</code> for this object.
+ *
+ * @exception MalformedURLException If the URL cannot be created
+ * successfully.
+ */
+ public URL toURL() throws MalformedURLException
+ {
+ // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
+ // while on UNIX, it returns URLs of the form "file:/foo/bar.txt".
+ if (separatorChar == '\\')
+ return new URL ("file:/" + getAbsolutePath().replace ('\\', '/')
+ + (isDirectory() ? "/" : ""));
+ else
+ return new URL ("file:" + getAbsolutePath()
+ + (isDirectory() ? "/" : ""));
+ }
+
+ /*
+ * This native method actually creates the directory
+ */
+ private final native boolean performMkdir();
+
+ /**
+ * This method creates a directory for the path represented by this object.
+ *
+ * @return <code>true</code> if the directory was created,
+ * <code>false</code> otherwise
+ *
+ * @exception SecurityException If write access is not allowed to this file
+ */
+ public boolean mkdir()
+ {
+ checkWrite();
+ return performMkdir();
+ }
+
+ private static boolean mkdirs (File x)
+ {
+ if (x.isDirectory())
+ return true;
+ String p = x.getPath();
+ String parent = x.getParent();
+ if (parent != null)
+ {
+ x.path = parent;
+ if (! mkdirs (x))
+ return false;
+ x.path = p;
+ }
+ return x.mkdir();
+ }
+
+ /**
+ * This method creates a directory for the path represented by this file.
+ * It will also create any intervening parent directories if necessary.
+ *
+ * @return <code>true</code> if the directory was created,
+ * <code>false</code> otherwise
+ *
+ * @exception SecurityException If write access is not allowed to this file
+ */
+ public boolean mkdirs()
+ {
+ checkWrite();
+ if (isDirectory())
+ return false;
+ return mkdirs (new File (path));
+ }
+
+ private static synchronized String nextValue()
+ {
+ return Long.toString(counter++, Character.MAX_RADIX);
+ }
+
+ /**
+ * This method creates a temporary file in the specified directory. If
+ * the directory name is null, then this method uses the system temporary
+ * directory. The files created are guaranteed not to currently exist and
+ * the same file name will never be used twice in the same virtual
+ * machine instance.
+ * The system temporary directory is determined by examinging the
+ * <code>java.io.tmpdir</code> system property.
+ * <p>
+ * The <code>prefix</code> parameter is a sequence of at least three
+ * characters that are used as the start of the generated filename. The
+ * <code>suffix</code> parameter is a sequence of characters that is used
+ * to terminate the file name. This parameter may be <code>null</code>
+ * and if it is, the suffix defaults to ".tmp".
+ * <p>
+ * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
+ * method is used to verify that this operation is permitted.
+ *
+ * @param prefix The character prefix to use in generating the path name.
+ * @param suffix The character suffix to use in generating the path name.
+ * @param directory The directory to create the file in, or
+ * <code>null</code> for the default temporary directory
+ *
+ * @exception IllegalArgumentException If the patterns is not valid
+ * @exception SecurityException If there is no permission to perform
+ * this operation
+ * @exception IOException If an error occurs
+ *
+ * @since 1.2
+ */
+ public static File createTempFile(String prefix, String suffix,
+ File directory)
+ throws IOException
+ {
+ // Grab the system temp directory if necessary
+ if (directory == null)
+ {
+ String dirname = tmpdir;
+ if (dirname == null)
+ throw new IOException("Cannot determine system temporary directory");
+
+ directory = new File(dirname);
+ if (!directory.internalExists())
+ throw new IOException("System temporary directory "
+ + directory.getName() + " does not exist.");
+ if (!directory.internalIsDirectory())
+ throw new IOException("System temporary directory "
+ + directory.getName()
+ + " is not really a directory.");
+ }
+
+ // Check if prefix is at least 3 characters long
+ if (prefix.length() < 3)
+ throw new IllegalArgumentException("Prefix too short: " + prefix);
+
+ // Set default value of suffix
+ if (suffix == null)
+ suffix = ".tmp";
+
+ // Truncation rules.
+ // `6' is the number of characters we generate.
+ if (prefix.length() + 6 + suffix.length() > maxPathLen)
+ {
+ int suf_len = 0;
+ if (suffix.charAt(0) == '.')
+ suf_len = 4;
+ suffix = suffix.substring(0, suf_len);
+ if (prefix.length() + 6 + suf_len > maxPathLen)
+ prefix = prefix.substring(0, maxPathLen - 6 - suf_len);
+ }
+
+ File f;
+
+ // How many times should we try? We choose 100.
+ for (int i = 0; i < 100; ++i)
+ {
+ // This is ugly.
+ String t = "ZZZZZZ" + nextValue();
+ String l = prefix + t.substring(t.length() - 6) + suffix;
+ try
+ {
+ f = new File(directory, l);
+ if (f.createNewFile())
+ return f;
+ }
+ catch (IOException ignored)
+ {
+ }
+ }
+
+ throw new IOException ("cannot create temporary file");
+ }
+
+ /*
+ * This native method sets the permissions to make the file read only.
+ */
+ private native boolean performSetReadOnly();
+
+ /**
+ * This method sets the file represented by this object to be read only.
+ * A read only file or directory cannot be modified. Please note that
+ * GNU systems allow read only files to be deleted if the directory it
+ * is contained in is writable.
+ *
+ * @return <code>true</code> if the operation succeeded, <code>false</code>
+ * otherwise.
+ *
+ * @exception SecurityException If the <code>SecurityManager</code> does
+ * not allow this operation.
+ *
+ * @since 1.2
+ */
+ public boolean setReadOnly()
+ {
+ // Do a security check before trying to do anything else.
+ checkWrite();
+ return performSetReadOnly();
+ }
+
+ private static native File[] performListRoots();
+
+ /**
+ * 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
+ */
+ public static File[] listRoots()
+ {
+ File[] roots = performListRoots();
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ {
+ // Only return roots to which the security manager permits read access.
+ int count = roots.length;
+ for (int i = 0; i < roots.length; i++)
+ {
+ try
+ {
+ s.checkRead (roots[i].path);
+ }
+ catch (SecurityException sx)
+ {
+ roots[i] = null;
+ count--;
+ }
+ }
+ if (count != roots.length)
+ {
+ File[] newRoots = new File[count];
+ int k = 0;
+ for (int i=0; i < roots.length; i++)
+ {
+ if (roots[i] != null)
+ newRoots[k++] = roots[i];
+ }
+ roots = newRoots;
+ }
+ }
+ return roots;
+ }
+
+ /**
+ * This method creates a temporary file in the system temporary directory.
+ * The files created are guaranteed not to currently exist and the same file
+ * name will never be used twice in the same virtual machine instance. The
+ * system temporary directory is determined by examinging the
+ * <code>java.io.tmpdir</code> system property.
+ * <p>
+ * The <code>prefix</code> parameter is a sequence of at least three
+ * characters that are used as the start of the generated filename. The
+ * <code>suffix</code> parameter is a sequence of characters that is used
+ * to terminate the file name. This parameter may be <code>null</code>
+ * and if it is, the suffix defaults to ".tmp".
+ * <p>
+ * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
+ * method is used to verify that this operation is permitted.
+ * <p>
+ * This method is identical to calling
+ * <code>createTempFile(prefix, suffix, null)</code>.
+ *
+ * @param prefix The character prefix to use in generating the path name.
+ * @param suffix The character suffix to use in generating the path name.
+ *
+ * @exception IllegalArgumentException If the prefix or suffix are not valid.
+ * @exception SecurityException If there is no permission to perform
+ * this operation
+ * @exception IOException If an error occurs
+ */
+ public static File createTempFile(String prefix, String suffix)
+ throws IOException
+ {
+ return createTempFile(prefix, suffix, null);
+ }
+
+ /**
+ * This method compares the specified <code>File</code> to this one
+ * to test for equality. It does this by comparing the canonical path names
+ * of the files.
+ * <p>
+ * The canonical paths of the files are determined by calling the
+ * <code>getCanonicalPath</code> method on each object.
+ * <p>
+ * This method returns a 0 if the specified <code>Object</code> is equal
+ * to this one, a negative value if it is less than this one
+ * a positive value if it is greater than this one.
+ *
+ * @return An integer as described above
+ *
+ * @since 1.2
+ */
+ public int compareTo(File other)
+ {
+ if (caseSensitive)
+ return path.compareTo (other.path);
+ else
+ return path.compareToIgnoreCase (other.path);
+ }
+
+ /**
+ * This method compares the specified <code>Object</code> to this one
+ * to test for equality. It does this by comparing the canonical path names
+ * of the files. This method is identical to <code>compareTo(File)</code>
+ * except that if the <code>Object</code> passed to it is not a
+ * <code>File</code>, it throws a <code>ClassCastException</code>
+ * <p>
+ * The canonical paths of the files are determined by calling the
+ * <code>getCanonicalPath</code> method on each object.
+ * <p>
+ * This method returns a 0 if the specified <code>Object</code> is equal
+ * to this one, a negative value if it is less than this one
+ * a positive value if it is greater than this one.
+ *
+ * @return An integer as described above
+ *
+ * @exception ClassCastException If the passed <code>Object</code> is
+ * not a <code>File</code>
+ *
+ * @since 1.2
+ */
+ public int compareTo(Object obj)
+ {
+ return compareTo((File) obj);
+ }
+
+ /*
+ * This native method actually performs the rename.
+ */
+ private native boolean performRenameTo (File dest);
+
+ /**
+ * This method renames the file represented by this object to the path
+ * of the file represented by the argument <code>File</code>.
+ *
+ * @param dest The <code>File</code> object representing the target name
+ *
+ * @return <code>true</code> if the rename succeeds, <code>false</code>
+ * otherwise.
+ *
+ * @exception SecurityException If write access is not allowed to the
+ * file by the <code>SecurityMananger</code>.
+ */
+ public synchronized boolean renameTo(File dest)
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ {
+ s.checkWrite (getPath());
+ s.checkWrite (dest.getPath());
+ }
+ return performRenameTo (dest);
+ }
+
+ /*
+ * This method does the actual setting of the modification time.
+ */
+ private native boolean performSetLastModified(long time);
+
+ /**
+ * This method sets the modification time on the file to the specified
+ * value. This is specified as the number of seconds since midnight
+ * on January 1, 1970 GMT.
+ *
+ * @param time The desired modification time.
+ *
+ * @return <code>true</code> if the operation succeeded, <code>false</code>
+ * otherwise.
+ *
+ * @exception IllegalArgumentException If the specified time is negative.
+ * @exception SecurityException If the <code>SecurityManager</code> will
+ * not allow this operation.
+ *
+ * @since 1.2
+ */
+ public boolean setLastModified(long time)
+ {
+ if (time < 0)
+ throw new IllegalArgumentException("Negative modification time: " + time);
+
+ checkWrite();
+ return performSetLastModified(time);
+ }
+
+ private void checkWrite()
+ {
+ // Check the SecurityManager
+ SecurityManager s = System.getSecurityManager();
+
+ if (s != null)
+ s.checkWrite(path);
+ }
+
+ private void checkRead()
+ {
+ // Check the SecurityManager
+ SecurityManager s = System.getSecurityManager();
+
+ if (s != null)
+ s.checkRead(path);
+ }
+
+ /**
+ * Calling this method requests that the file represented by this object
+ * be deleted when the virtual machine exits. Note that this request cannot
+ * be cancelled. Also, it will only be carried out if the virtual machine
+ * exits normally.
+ *
+ * @exception SecurityException If deleting of the file is not allowed
+ *
+ * @since 1.2
+ */
+ // FIXME: This should use the ShutdownHook API once we implement that.
+ public void deleteOnExit()
+ {
+ // Check the SecurityManager
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkDelete (getPath());
+
+ DeleteFileHelper.add(this);
+ }
+
+ private void writeObject(ObjectOutputStream oos) throws IOException
+ {
+ oos.defaultWriteObject();
+ oos.writeChar(separatorChar);
+ }
+
+ private void readObject(ObjectInputStream ois)
+ throws ClassNotFoundException, IOException
+ {
+ ois.defaultReadObject();
+
+ // If the file was from an OS with a different dir separator,
+ // fixup the path to use the separator on this OS.
+ char oldSeparatorChar = ois.readChar();
+
+ if (oldSeparatorChar != separatorChar)
+ path = path.replace(oldSeparatorChar, separatorChar);
+ }
+
+} // class File
+
diff --git a/gcc-4.2.1/libjava/java/io/InputStreamReader.java b/gcc-4.2.1/libjava/java/io/InputStreamReader.java
new file mode 100644
index 000000000..91568c5cc
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/InputStreamReader.java
@@ -0,0 +1,332 @@
+/* InputStreamReader.java -- Reader than transforms bytes to chars
+ Copyright (C) 1998, 1999, 2001, 2003, 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.io;
+
+import gnu.gcj.convert.*;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+
+/**
+ * This class reads characters from a byte input stream. The characters
+ * read are converted from bytes in the underlying stream by a
+ * decoding layer. The decoding layer transforms bytes to chars according
+ * to an encoding standard. There are many available encodings to choose
+ * from. The desired encoding can either be specified by name, or if no
+ * encoding is selected, the system default encoding will be used. The
+ * system default encoding name is determined from the system property
+ * <code>file.encoding</code>. The only encodings that are guaranteed to
+ * be availalbe are "8859_1" (the Latin-1 character set) and "UTF8".
+ * Unforunately, Java does not provide a mechanism for listing the
+ * ecodings that are supported in a given implementation.
+ * <p>
+ * Here is a list of standard encoding names that may be available:
+ * <p>
+ * <ul>
+ * <li>8859_1 (ISO-8859-1/Latin-1)</li>
+ * <li>8859_2 (ISO-8859-2/Latin-2)</li>
+ * <li>8859_3 (ISO-8859-3/Latin-3)</li>
+ * <li>8859_4 (ISO-8859-4/Latin-4)</li>
+ * <li>8859_5 (ISO-8859-5/Latin-5)</li>
+ * <li>8859_6 (ISO-8859-6/Latin-6)</li>
+ * <li>8859_7 (ISO-8859-7/Latin-7)</li>
+ * <li>8859_8 (ISO-8859-8/Latin-8)</li>
+ * <li>8859_9 (ISO-8859-9/Latin-9)</li>
+ * <li>ASCII (7-bit ASCII)</li>
+ * <li>UTF8 (UCS Transformation Format-8)</li>
+ * <li>More later</li>
+ * </ul>
+ * <p>
+ * It is recommended that applications do not use
+ * <code>InputStreamReader</code>'s
+ * directly. Rather, for efficiency purposes, an object of this class
+ * should be wrapped by a <code>BufferedReader</code>.
+ * <p>
+ * Due to a deficiency the Java class library design, there is no standard
+ * way for an application to install its own byte-character encoding.
+ *
+ * @see BufferedReader
+ * @see InputStream
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Per Bothner (bothner@cygnus.com)
+ * @date April 22, 1998.
+ */
+public class InputStreamReader extends Reader
+{
+ BufferedInputStream in;
+
+ // Buffer of chars read from in and converted but not consumed.
+ char[] work;
+ // Next available character (in work buffer) to read.
+ int wpos;
+ // Last available character (in work buffer) to read.
+ int wcount;
+
+ /*
+ * This is the byte-character decoder class that does the reading and
+ * translation of bytes from the underlying stream.
+ */
+ BytesToUnicode converter;
+
+ /**
+ * This method initializes a new instance of <code>InputStreamReader</code>
+ * to read from the specified stream using the default encoding.
+ *
+ * @param in The <code>InputStream</code> to read from
+ */
+ public InputStreamReader(InputStream in)
+ {
+ this(in, BytesToUnicode.getDefaultDecoder());
+ }
+
+ /**
+ * This method initializes a new instance of <code>InputStreamReader</code>
+ * to read from the specified stream using a caller supplied character
+ * encoding scheme. Note that due to a deficiency in the Java language
+ * design, there is no way to determine which encodings are supported.
+ *
+ * @param in The <code>InputStream</code> to read from
+ * @param encoding_name The name of the encoding scheme to use
+ *
+ * @exception UnsupportedEncodingException If the encoding scheme
+ * requested is not available.
+ */
+ public InputStreamReader(InputStream in, String encoding_name)
+ throws UnsupportedEncodingException
+ {
+ this(in, BytesToUnicode.getDecoder(encoding_name));
+ }
+
+ /**
+ * Creates an InputStreamReader that uses a decoder of the given
+ * charset to decode the bytes in the InputStream into
+ * characters.
+ */
+ public InputStreamReader(InputStream in, Charset charset)
+ {
+ this(in, new BytesToCharsetAdaptor(charset));
+ }
+
+ /**
+ * Creates an InputStreamReader that uses the given charset decoder
+ * to decode the bytes in the InputStream into characters.
+ */
+ public InputStreamReader(InputStream in, CharsetDecoder decoder)
+ {
+ this(in, new BytesToCharsetAdaptor(decoder));
+ }
+
+ private InputStreamReader(InputStream in, BytesToUnicode decoder)
+ {
+ // FIXME: someone could pass in a BufferedInputStream whose buffer
+ // is smaller than the longest encoded character for this
+ // encoding. We will probably go into an infinite loop in this
+ // case. We probably ought to just have our own byte buffering
+ // here.
+ this.in = in instanceof BufferedInputStream
+ ? (BufferedInputStream) in
+ : new BufferedInputStream(in);
+ /* Don't need to call super(in) here as long as the lock gets set. */
+ this.lock = in;
+ converter = decoder;
+ converter.setInput(this.in.buf, 0, 0);
+ }
+
+ /**
+ * This method closes this stream, as well as the underlying
+ * <code>InputStream</code>.
+ *
+ * @exception IOException If an error occurs
+ */
+ public void close() throws IOException
+ {
+ synchronized (lock)
+ {
+ if (in != null)
+ in.close();
+ in = null;
+ work = null;
+ wpos = wcount = 0;
+ }
+ }
+
+ /**
+ * This method returns the name of the encoding that is currently in use
+ * by this object. If the stream has been closed, this method is allowed
+ * to return <code>null</code>.
+ *
+ * @return The current encoding name
+ */
+ public String getEncoding()
+ {
+ return in != null ? converter.getName() : null;
+ }
+
+ /**
+ * This method checks to see if the stream is read to be read. It
+ * will return <code>true</code> if is, or <code>false</code> if it is not.
+ * If the stream is not ready to be read, it could (although is not required
+ * to) block on the next read attempt.
+ *
+ * @return <code>true</code> if the stream is ready to be read,
+ * <code>false</code> otherwise
+ *
+ * @exception IOException If an error occurs
+ */
+ public boolean ready() throws IOException
+ {
+ synchronized (lock)
+ {
+ if (in == null)
+ throw new IOException("Stream closed");
+
+ if (wpos < wcount)
+ return true;
+
+ // According to the spec, an InputStreamReader is ready if its
+ // input buffer is not empty (above), or if bytes are
+ // available on the underlying byte stream.
+ return in.available () > 0;
+ }
+ }
+
+ /**
+ * This method reads up to <code>length</code> characters from the stream into
+ * the specified array starting at index <code>offset</code> into the
+ * array.
+ *
+ * @param buf The character array to recieve the data read
+ * @param offset The offset into the array to start storing characters
+ * @param length The requested number of characters to read.
+ *
+ * @return The actual number of characters read, or -1 if end of stream.
+ *
+ * @exception IOException If an error occurs
+ */
+ public int read (char[] buf, int offset, int length) throws IOException
+ {
+ synchronized (lock)
+ {
+ if (in == null)
+ throw new IOException("Stream closed");
+
+ if (length == 0)
+ return 0;
+
+ int wavail = wcount - wpos;
+ if (wavail <= 0)
+ {
+ // Nothing waiting, so refill their buffer.
+ return refill(buf, offset, length);
+ }
+
+ if (length > wavail)
+ length = wavail;
+ System.arraycopy(work, wpos, buf, offset, length);
+ wpos += length;
+ return length;
+ }
+ }
+
+ /**
+ * This method reads a single character of data from the stream.
+ *
+ * @return The char read, as an int, or -1 if end of stream.
+ *
+ * @exception IOException If an error occurs
+ */
+ public int read() throws IOException
+ {
+ synchronized (lock)
+ {
+ if (in == null)
+ throw new IOException("Stream closed");
+
+ int wavail = wcount - wpos;
+ if (wavail <= 0)
+ {
+ // Nothing waiting, so refill our internal buffer.
+ wpos = wcount = 0;
+ if (work == null)
+ work = new char[100];
+ int count = refill(work, 0, work.length);
+ if (count == -1)
+ return -1;
+ wcount += count;
+ }
+
+ return work[wpos++];
+ }
+ }
+
+ // Read more bytes and convert them into the specified buffer.
+ // Returns the number of converted characters or -1 on EOF.
+ private int refill(char[] buf, int offset, int length) throws IOException
+ {
+ for (;;)
+ {
+ // We have knowledge of the internals of BufferedInputStream
+ // here. Eww.
+ // BufferedInputStream.refill() can only be called when
+ // `pos>=count'.
+ boolean r = in.pos < in.count || in.refill ();
+ if (! r)
+ return -1;
+ converter.setInput(in.buf, in.pos, in.count);
+ int count = converter.read(buf, offset, length);
+
+ // We might have bytes but not have made any progress. In
+ // this case we try to refill. If refilling fails, we assume
+ // we have a malformed character at the end of the stream.
+ if (count == 0 && converter.inpos == in.pos)
+ {
+ in.mark(in.count);
+ if (! in.refill ())
+ throw new CharConversionException ();
+ in.reset();
+ }
+ else
+ {
+ in.skip(converter.inpos - in.pos);
+ if (count > 0)
+ return count;
+ }
+ }
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/io/ObjectInputStream.java b/gcc-4.2.1/libjava/java/io/ObjectInputStream.java
new file mode 100644
index 000000000..54661a9bc
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/ObjectInputStream.java
@@ -0,0 +1,1979 @@
+/* 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.Configuration;
+import gnu.java.io.ObjectIdentityWrapper;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Vector;
+
+public class ObjectInputStream extends InputStream
+ implements ObjectInput, ObjectStreamConstants
+{
+ /**
+ * Creates a new <code>ObjectInputStream</code> that will do all of
+ * its reading from <code>in</code>. This method also checks
+ * the stream by reading the header information (stream magic number
+ * and stream version).
+ *
+ * @exception IOException Reading stream header from underlying
+ * stream cannot be completed.
+ *
+ * @exception StreamCorruptedException An invalid stream magic
+ * number or stream version was read from the stream.
+ *
+ * @see #readStreamHeader()
+ */
+ public ObjectInputStream(InputStream in)
+ throws IOException, StreamCorruptedException
+ {
+ if (Configuration.DEBUG)
+ {
+ String val = System.getProperty("gcj.dumpobjects");
+ if (dump == false && val != null && !val.equals(""))
+ {
+ dump = true;
+ System.out.println ("Serialization debugging enabled");
+ }
+ else if (dump == true && (val == null || val.equals("")))
+ {
+ dump = false;
+ System.out.println ("Serialization debugging disabled");
+ }
+ }
+
+ this.resolveEnabled = false;
+ this.isDeserializing = false;
+ this.blockDataPosition = 0;
+ this.blockDataBytes = 0;
+ this.blockData = new byte[BUFFER_SIZE];
+ this.blockDataInput = new DataInputStream(this);
+ this.realInputStream = new DataInputStream(in);
+ this.nextOID = baseWireHandle;
+ this.objectLookupTable = new Hashtable();
+ this.validators = new Vector();
+ this.classLookupTable = new Hashtable();
+ setBlockDataMode(true);
+ readStreamHeader();
+ }
+
+
+ /**
+ * Returns the next deserialized object read from the underlying stream.
+ *
+ * This method can be overriden by a class by implementing
+ * <code>private void readObject (ObjectInputStream)</code>.
+ *
+ * If an exception is thrown from this method, the stream is left in
+ * an undefined state. This method can also throw Errors and
+ * RuntimeExceptions if caused by existing readResolve() user code.
+ *
+ * @return The object read from the underlying stream.
+ *
+ * @exception ClassNotFoundException The class that an object being
+ * read in belongs to cannot be found.
+ *
+ * @exception IOException Exception from underlying
+ * <code>InputStream</code>.
+ */
+ public final Object readObject() throws ClassNotFoundException, IOException
+ {
+ if (this.useSubclassMethod)
+ return readObjectOverride();
+
+ boolean was_deserializing;
+
+ Object ret_val;
+ was_deserializing = this.isDeserializing;
+
+ boolean is_consumed = false;
+ boolean old_mode = setBlockDataMode(false);
+
+ this.isDeserializing = true;
+
+ byte marker = this.realInputStream.readByte();
+
+ depth += 2;
+
+ if(dump) dumpElement("MARKER: 0x" + Integer.toHexString(marker) + " ");
+
+ try
+ {
+ switch (marker)
+ {
+ case TC_ENDBLOCKDATA:
+ {
+ ret_val = null;
+ is_consumed = true;
+ break;
+ }
+
+ case TC_BLOCKDATA:
+ case TC_BLOCKDATALONG:
+ {
+ if (marker == TC_BLOCKDATALONG)
+ { if(dump) dumpElementln("BLOCKDATALONG"); }
+ else
+ { if(dump) dumpElementln("BLOCKDATA"); }
+ readNextBlock(marker);
+ throw new StreamCorruptedException("Unexpected blockData");
+ }
+
+ case TC_NULL:
+ {
+ if(dump) dumpElementln("NULL");
+ ret_val = null;
+ break;
+ }
+
+ case TC_REFERENCE:
+ {
+ if(dump) dumpElement("REFERENCE ");
+ Integer oid = new Integer(this.realInputStream.readInt());
+ if(dump) dumpElementln(Integer.toHexString(oid.intValue()));
+ ret_val = ((ObjectIdentityWrapper)
+ this.objectLookupTable.get(oid)).object;
+ break;
+ }
+
+ case TC_CLASS:
+ {
+ if(dump) dumpElementln("CLASS");
+ ObjectStreamClass osc = (ObjectStreamClass)readObject();
+ Class clazz = osc.forClass();
+ assignNewHandle(clazz);
+ ret_val = clazz;
+ break;
+ }
+
+ case TC_PROXYCLASSDESC:
+ {
+ if(dump) dumpElementln("PROXYCLASS");
+ int n_intf = this.realInputStream.readInt();
+ String[] intfs = new String[n_intf];
+ for (int i = 0; i < n_intf; i++)
+ {
+ intfs[i] = this.realInputStream.readUTF();
+ }
+
+ boolean oldmode = setBlockDataMode(true);
+ Class cl = resolveProxyClass(intfs);
+ setBlockDataMode(oldmode);
+
+ ObjectStreamClass osc = lookupClass(cl);
+ if (osc.firstNonSerializableParentConstructor == null)
+ {
+ osc.realClassIsSerializable = true;
+ osc.fields = osc.fieldMapping = new ObjectStreamField[0];
+ try
+ {
+ osc.firstNonSerializableParentConstructor =
+ Object.class.getConstructor(new Class[0]);
+ }
+ catch (NoSuchMethodException x)
+ {
+ throw (InternalError)
+ new InternalError("Object ctor missing").initCause(x);
+ }
+ }
+ assignNewHandle(osc);
+
+ if (!is_consumed)
+ {
+ byte b = this.realInputStream.readByte();
+ if (b != TC_ENDBLOCKDATA)
+ throw new IOException("Data annotated to class was not consumed." + b);
+ }
+ else
+ is_consumed = false;
+ ObjectStreamClass superosc = (ObjectStreamClass)readObject();
+ osc.setSuperclass(superosc);
+ ret_val = osc;
+ break;
+ }
+
+ case TC_CLASSDESC:
+ {
+ ObjectStreamClass osc = readClassDescriptor();
+
+ if (!is_consumed)
+ {
+ byte b = this.realInputStream.readByte();
+ if (b != TC_ENDBLOCKDATA)
+ throw new IOException("Data annotated to class was not consumed." + b);
+ }
+ else
+ is_consumed = false;
+
+ osc.setSuperclass ((ObjectStreamClass)readObject());
+ ret_val = osc;
+ break;
+ }
+
+ case TC_STRING:
+ case TC_LONGSTRING:
+ {
+ if(dump) dumpElement("STRING=");
+ String s = this.realInputStream.readUTF();
+ if(dump) dumpElementln(s);
+ ret_val = processResolution(null, s, assignNewHandle(s));
+ break;
+ }
+
+ case TC_ARRAY:
+ {
+ if(dump) dumpElementln("ARRAY");
+ ObjectStreamClass osc = (ObjectStreamClass)readObject();
+ Class componentType = osc.forClass().getComponentType();
+ if(dump) dumpElement("ARRAY LENGTH=");
+ int length = this.realInputStream.readInt();
+ if(dump) dumpElementln (length + "; COMPONENT TYPE=" + componentType);
+ Object array = Array.newInstance(componentType, length);
+ int handle = assignNewHandle(array);
+ readArrayElements(array, componentType);
+ if(dump)
+ for (int i = 0, len = Array.getLength(array); i < len; i++)
+ dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
+ ret_val = processResolution(null, array, handle);
+ break;
+ }
+
+ case TC_OBJECT:
+ {
+ if(dump) dumpElementln("OBJECT");
+ ObjectStreamClass osc = (ObjectStreamClass)readObject();
+ Class clazz = osc.forClass();
+
+ if (!osc.realClassIsSerializable)
+ throw new NotSerializableException
+ (clazz + " is not Serializable, and thus cannot be deserialized.");
+
+ if (osc.realClassIsExternalizable)
+ {
+ Externalizable obj = osc.newInstance();
+
+ int handle = assignNewHandle(obj);
+
+ boolean read_from_blocks = ((osc.getFlags() & SC_BLOCK_DATA) != 0);
+
+ boolean oldmode = this.readDataFromBlock;
+ if (read_from_blocks)
+ setBlockDataMode(true);
+
+ obj.readExternal(this);
+
+ if (read_from_blocks)
+ {
+ setBlockDataMode(oldmode);
+ if (!oldmode)
+ if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
+ throw new IOException("No end of block data seen for class with readExternal (ObjectInputStream) method.");
+ }
+
+ ret_val = processResolution(osc, obj, handle);
+ break;
+ } // end if (osc.realClassIsExternalizable)
+
+ Object obj = newObject(clazz, osc.firstNonSerializableParentConstructor);
+
+ int handle = assignNewHandle(obj);
+ Object prevObject = this.currentObject;
+ ObjectStreamClass prevObjectStreamClass = this.currentObjectStreamClass;
+
+ this.currentObject = obj;
+ ObjectStreamClass[] hierarchy =
+ inputGetObjectStreamClasses(clazz);
+
+ for (int i = 0; i < hierarchy.length; i++)
+ {
+ this.currentObjectStreamClass = hierarchy[i];
+
+ if(dump) dumpElementln("Reading fields of " + this.currentObjectStreamClass.getName ());
+
+ // XXX: should initialize fields in classes in the hierarchy
+ // that aren't in the stream
+ // should skip over classes in the stream that aren't in the
+ // real classes hierarchy
+
+ Method readObjectMethod = this.currentObjectStreamClass.readObjectMethod;
+ if (readObjectMethod != null)
+ {
+ fieldsAlreadyRead = false;
+ boolean oldmode = setBlockDataMode(true);
+ callReadMethod(readObjectMethod, this.currentObjectStreamClass.forClass(), obj);
+ setBlockDataMode(oldmode);
+ }
+ else
+ {
+ readFields(obj, currentObjectStreamClass);
+ }
+
+ if (this.currentObjectStreamClass.hasWriteMethod())
+ {
+ if(dump) dumpElement("ENDBLOCKDATA? ");
+ try
+ {
+ // FIXME: XXX: This try block is to
+ // catch EOF which is thrown for some
+ // objects. That indicates a bug in
+ // the logic.
+
+ if (this.realInputStream.readByte() != TC_ENDBLOCKDATA)
+ throw new IOException
+ ("No end of block data seen for class with readObject (ObjectInputStream) method.");
+ if(dump) dumpElementln("yes");
+ }
+// catch (EOFException e)
+// {
+// if(dump) dumpElementln("no, got EOFException");
+// }
+ catch (IOException e)
+ {
+ if(dump) dumpElementln("no, got IOException");
+ }
+ }
+ }
+
+ this.currentObject = prevObject;
+ this.currentObjectStreamClass = prevObjectStreamClass;
+ ret_val = processResolution(osc, obj, handle);
+
+ break;
+ }
+
+ case TC_RESET:
+ if(dump) dumpElementln("RESET");
+ clearHandles();
+ ret_val = readObject();
+ break;
+
+ case TC_EXCEPTION:
+ {
+ if(dump) dumpElement("EXCEPTION=");
+ Exception e = (Exception)readObject();
+ if(dump) dumpElementln(e.toString());
+ clearHandles();
+ throw new WriteAbortedException("Exception thrown during writing of stream", e);
+ }
+
+ default:
+ throw new IOException("Unknown marker on stream: " + marker);
+ }
+ }
+ finally
+ {
+ setBlockDataMode(old_mode);
+
+ this.isDeserializing = was_deserializing;
+
+ depth -= 2;
+
+ if (! was_deserializing)
+ {
+ if (validators.size() > 0)
+ invokeValidators();
+ }
+ }
+
+ return ret_val;
+ }
+
+ /**
+ * This method makes a partial check of types for the fields
+ * contained given in arguments. It checks primitive types of
+ * fields1 against non primitive types of fields2. This method
+ * assumes the two lists has already been sorted according to
+ * the Java specification.
+ *
+ * @param name Name of the class owning the given fields.
+ * @param fields1 First list to check.
+ * @param fields2 Second list to check.
+ * @throws InvalidClassException if a field in fields1, which has a primitive type, is a present
+ * in the non primitive part in fields2.
+ */
+ private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2)
+ throws InvalidClassException
+ {
+ int nonPrimitive = 0;
+
+ for (nonPrimitive = 0;
+ nonPrimitive < fields1.length
+ && fields1[nonPrimitive].isPrimitive(); nonPrimitive++)
+ {
+ }
+
+ if (nonPrimitive == fields1.length)
+ return;
+
+ int i = 0;
+ ObjectStreamField f1;
+ ObjectStreamField f2;
+
+ while (i < fields2.length
+ && nonPrimitive < fields1.length)
+ {
+ f1 = fields1[nonPrimitive];
+ f2 = fields2[i];
+
+ if (!f2.isPrimitive())
+ break;
+
+ int compVal = f1.getName().compareTo (f2.getName());
+
+ if (compVal < 0)
+ {
+ nonPrimitive++;
+ }
+ else if (compVal > 0)
+ {
+ i++;
+ }
+ else
+ {
+ throw new InvalidClassException
+ ("invalid field type for " + f2.getName() +
+ " in class " + name);
+ }
+ }
+ }
+
+ /**
+ * This method reads a class descriptor from the real input stream
+ * and use these data to create a new instance of ObjectStreamClass.
+ * Fields are sorted and ordered for the real read which occurs for
+ * each instance of the described class. Be aware that if you call that
+ * method you must ensure that the stream is synchronized, in the other
+ * case it may be completely desynchronized.
+ *
+ * @return A new instance of ObjectStreamClass containing the freshly
+ * created descriptor.
+ * @throws ClassNotFoundException if the required class to build the
+ * descriptor has not been found in the system.
+ * @throws IOException An input/output error occured.
+ * @throws InvalidClassException If there was a compatibility problem
+ * between the class present in the system and the serialized class.
+ */
+ protected ObjectStreamClass readClassDescriptor()
+ throws ClassNotFoundException, IOException
+ {
+ if(dump) dumpElement("CLASSDESC NAME=");
+ String name = this.realInputStream.readUTF();
+ if(dump) dumpElement(name + "; UID=");
+ long uid = this.realInputStream.readLong ();
+ if(dump) dumpElement(Long.toHexString(uid) + "; FLAGS=");
+ byte flags = this.realInputStream.readByte ();
+ if(dump) dumpElement(Integer.toHexString(flags) + "; FIELD COUNT=");
+ short field_count = this.realInputStream.readShort();
+ if(dump) dumpElementln(Short.toString(field_count));
+ ObjectStreamField[] fields = new ObjectStreamField[field_count];
+ ObjectStreamClass osc = new ObjectStreamClass(name, uid,
+ flags, fields);
+ assignNewHandle(osc);
+
+ if (callersClassLoader == null)
+ callersClassLoader = currentLoader();
+
+ for (int i = 0; i < field_count; i++)
+ {
+ if(dump) dumpElement(" TYPE CODE=");
+ char type_code = (char)this.realInputStream.readByte();
+ if(dump) dumpElement(type_code + "; FIELD NAME=");
+ String field_name = this.realInputStream.readUTF();
+ if(dump) dumpElementln(field_name);
+ String class_name;
+
+ // If the type code is an array or an object we must
+ // decode a String here. In the other case we convert
+ // the type code and pass it to ObjectStreamField.
+ // Type codes are decoded by gnu.java.lang.reflect.TypeSignature.
+ if (type_code == 'L' || type_code == '[')
+ class_name = (String)readObject();
+ else
+ class_name = String.valueOf(type_code);
+
+ fields[i] =
+ new ObjectStreamField(field_name, class_name, callersClassLoader);
+ }
+
+ /* Now that fields have been read we may resolve the class
+ * (and read annotation if needed). */
+ Class clazz;
+ try
+ {
+ clazz = resolveClass(osc);
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ // Maybe it was an primitive class?
+ if (name.equals("void"))
+ clazz = Void.TYPE;
+ else if (name.equals("boolean"))
+ clazz = Boolean.TYPE;
+ else if (name.equals("byte"))
+ clazz = Byte.TYPE;
+ else if (name.equals("short"))
+ clazz = Short.TYPE;
+ else if (name.equals("char"))
+ clazz = Character.TYPE;
+ else if (name.equals("int"))
+ clazz = Integer.TYPE;
+ else if (name.equals("long"))
+ clazz = Long.TYPE;
+ else if (name.equals("float"))
+ clazz = Float.TYPE;
+ else if (name.equals("double"))
+ clazz = Double.TYPE;
+ else
+ throw cnfe;
+ }
+
+ boolean oldmode = setBlockDataMode(true);
+ osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
+ classLookupTable.put(clazz, osc);
+ setBlockDataMode(oldmode);
+
+ // find the first non-serializable, non-abstract
+ // class in clazz's inheritance hierarchy
+ Class first_nonserial = clazz.getSuperclass();
+ // Maybe it is a primitive class, those don't have a super class,
+ // or Object itself. Otherwise we can keep getting the superclass
+ // till we hit the Object class, or some other non-serializable class.
+
+ if (first_nonserial == null)
+ first_nonserial = clazz;
+ else
+ while (Serializable.class.isAssignableFrom(first_nonserial)
+ || Modifier.isAbstract(first_nonserial.getModifiers()))
+ first_nonserial = first_nonserial.getSuperclass();
+
+ final Class local_constructor_class = first_nonserial;
+
+ osc.firstNonSerializableParentConstructor =
+ (Constructor)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ try
+ {
+ Constructor c = local_constructor_class.
+ getDeclaredConstructor(new Class[0]);
+ if (Modifier.isPrivate(c.getModifiers()))
+ return null;
+ return c;
+ }
+ catch (NoSuchMethodException e)
+ {
+ // error will be reported later, in newObject()
+ return null;
+ }
+ }
+ });
+
+ osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);
+ osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);
+
+ ObjectStreamField[] stream_fields = osc.fields;
+ ObjectStreamField[] real_fields = ObjectStreamClass.lookupForClassObject(clazz).fields;
+ ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];
+
+ int stream_idx = 0;
+ int real_idx = 0;
+ int map_idx = 0;
+
+ /*
+ * Check that there is no type inconsistencies between the lists.
+ * A special checking must be done for the two groups: primitive types and
+ * not primitive types.
+ */
+ checkTypeConsistency(name, real_fields, stream_fields);
+ checkTypeConsistency(name, stream_fields, real_fields);
+
+
+ while (stream_idx < stream_fields.length
+ || real_idx < real_fields.length)
+ {
+ ObjectStreamField stream_field = null;
+ ObjectStreamField real_field = null;
+
+ if (stream_idx == stream_fields.length)
+ {
+ real_field = real_fields[real_idx++];
+ }
+ else if (real_idx == real_fields.length)
+ {
+ stream_field = stream_fields[stream_idx++];
+ }
+ else
+ {
+ int comp_val =
+ real_fields[real_idx].compareTo (stream_fields[stream_idx]);
+
+ if (comp_val < 0)
+ {
+ real_field = real_fields[real_idx++];
+ }
+ else if (comp_val > 0)
+ {
+ stream_field = stream_fields[stream_idx++];
+ }
+ else
+ {
+ stream_field = stream_fields[stream_idx++];
+ real_field = real_fields[real_idx++];
+ if (stream_field.getType() != real_field.getType())
+ throw new InvalidClassException
+ ("invalid field type for " + real_field.getName() +
+ " in class " + name);
+ }
+ }
+
+ /* If some of stream_fields does not correspond to any of real_fields,
+ * or the opposite, then fieldmapping will go short.
+ */
+ if (map_idx == fieldmapping.length)
+ {
+ ObjectStreamField[] newfieldmapping =
+ new ObjectStreamField[fieldmapping.length + 2];
+ System.arraycopy(fieldmapping, 0,
+ newfieldmapping, 0, fieldmapping.length);
+ fieldmapping = newfieldmapping;
+ }
+ fieldmapping[map_idx++] = stream_field;
+ fieldmapping[map_idx++] = real_field;
+ }
+ osc.fieldMapping = fieldmapping;
+
+ return osc;
+ }
+
+ /**
+ * Reads the current objects non-transient, non-static fields from
+ * the current class from the underlying output stream.
+ *
+ * This method is intended to be called from within a object's
+ * <code>private void readObject (ObjectInputStream)</code>
+ * method.
+ *
+ * @exception ClassNotFoundException The class that an object being
+ * read in belongs to cannot be found.
+ *
+ * @exception NotActiveException This method was called from a
+ * context other than from the current object's and current class's
+ * <code>private void readObject (ObjectInputStream)</code>
+ * method.
+ *
+ * @exception IOException Exception from underlying
+ * <code>OutputStream</code>.
+ */
+ public void defaultReadObject()
+ throws ClassNotFoundException, IOException, NotActiveException
+ {
+ if (this.currentObject == null || this.currentObjectStreamClass == null)
+ throw new NotActiveException("defaultReadObject called by non-active"
+ + " class and/or object");
+
+ if (fieldsAlreadyRead)
+ throw new NotActiveException("defaultReadObject called but fields "
+ + "already read from stream (by "
+ + "defaultReadObject or readFields)");
+
+ boolean oldmode = setBlockDataMode(false);
+ readFields(this.currentObject, this.currentObjectStreamClass);
+ setBlockDataMode(oldmode);
+
+ fieldsAlreadyRead = true;
+ }
+
+
+ /**
+ * Registers a <code>ObjectInputValidation</code> to be carried out
+ * on the object graph currently being deserialized before it is
+ * returned to the original caller of <code>readObject ()</code>.
+ * The order of validation for multiple
+ * <code>ObjectInputValidation</code>s can be controled using
+ * <code>priority</code>. Validators with higher priorities are
+ * called first.
+ *
+ * @see java.io.ObjectInputValidation
+ *
+ * @exception InvalidObjectException <code>validator</code> is
+ * <code>null</code>
+ *
+ * @exception NotActiveException an attempt was made to add a
+ * validator outside of the <code>readObject</code> method of the
+ * object currently being deserialized
+ */
+ public void registerValidation(ObjectInputValidation validator,
+ int priority)
+ throws InvalidObjectException, NotActiveException
+ {
+ if (this.currentObject == null || this.currentObjectStreamClass == null)
+ throw new NotActiveException("registerValidation called by non-active "
+ + "class and/or object");
+
+ if (validator == null)
+ throw new InvalidObjectException("attempt to add a null "
+ + "ObjectInputValidation object");
+
+ this.validators.addElement(new ValidatorAndPriority (validator,
+ priority));
+ }
+
+
+ /**
+ * Called when a class is being deserialized. This is a hook to
+ * allow subclasses to read in information written by the
+ * <code>annotateClass (Class)</code> method of an
+ * <code>ObjectOutputStream</code>.
+ *
+ * This implementation looks up the active call stack for a
+ * <code>ClassLoader</code>; if a <code>ClassLoader</code> is found,
+ * it is used to load the class associated with <code>osc</code>,
+ * otherwise, the default system <code>ClassLoader</code> is used.
+ *
+ * @exception IOException Exception from underlying
+ * <code>OutputStream</code>.
+ *
+ * @see java.io.ObjectOutputStream#annotateClass (java.lang.Class)
+ */
+ protected Class resolveClass(ObjectStreamClass osc)
+ throws ClassNotFoundException, IOException
+ {
+ if (callersClassLoader == null)
+ {
+ callersClassLoader = currentLoader ();
+ if (Configuration.DEBUG && dump)
+ {
+ dumpElementln ("CallersClassLoader = " + callersClassLoader);
+ }
+ }
+
+ return Class.forName(osc.getName(), true, callersClassLoader);
+ }
+
+ /**
+ * Returns the most recent user defined ClassLoader on the execution stack
+ * or null if none is found.
+ */
+ // GCJ LOCAL: native method.
+ private native ClassLoader currentLoader();
+
+ /**
+ * Lookup a class stored in the local hashtable. If it is not
+ * use the global lookup function in ObjectStreamClass to build
+ * the ObjectStreamClass. This method is requested according to
+ * the behaviour detected in the JDK by Kaffe's team.
+ *
+ * @param clazz Class to lookup in the hash table or for which
+ * we must build a descriptor.
+ * @return A valid instance of ObjectStreamClass corresponding
+ * to the specified class.
+ */
+ private ObjectStreamClass lookupClass(Class clazz)
+ {
+ if (clazz == null)
+ return null;
+
+ ObjectStreamClass oclazz;
+ oclazz = (ObjectStreamClass)classLookupTable.get(clazz);
+ if (oclazz == null)
+ return ObjectStreamClass.lookup(clazz);
+ else
+ return oclazz;
+ }
+
+ /**
+ * Reconstruct class hierarchy the same way
+ * {@link java.io.ObjectStreamClass.getObjectStreamClasses(java.lang.Class)} does
+ * but using lookupClass instead of ObjectStreamClass.lookup. This
+ * dup is necessary localize the lookup table. Hopefully some future
+ * rewritings will be able to prevent this.
+ *
+ * @param clazz This is the class for which we want the hierarchy.
+ *
+ * @return An array of valid {@link java.io.ObjectStreamClass} instances which
+ * represent the class hierarchy for clazz.
+ */
+ private ObjectStreamClass[] inputGetObjectStreamClasses(Class clazz)
+ {
+ ObjectStreamClass osc = lookupClass(clazz);
+
+ if (osc == null)
+ return new ObjectStreamClass[0];
+ else
+ {
+ Vector oscs = new Vector();
+
+ while (osc != null)
+ {
+ oscs.addElement(osc);
+ osc = osc.getSuper();
+ }
+
+ int count = oscs.size();
+ ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[count];
+
+ for (int i = count - 1; i >= 0; i--)
+ sorted_oscs[count - i - 1] = (ObjectStreamClass) oscs.elementAt(i);
+
+ return sorted_oscs;
+ }
+ }
+
+ /**
+ * Allows subclasses to resolve objects that are read from the
+ * stream with other objects to be returned in their place. This
+ * method is called the first time each object is encountered.
+ *
+ * This method must be enabled before it will be called in the
+ * serialization process.
+ *
+ * @exception IOException Exception from underlying
+ * <code>OutputStream</code>.
+ *
+ * @see #enableResolveObject(boolean)
+ */
+ protected Object resolveObject(Object obj) throws IOException
+ {
+ return obj;
+ }
+
+
+ protected Class resolveProxyClass(String[] intfs)
+ throws IOException, ClassNotFoundException
+ {
+ ClassLoader cl = currentLoader();
+
+ Class[] clss = new Class[intfs.length];
+ if(cl == null)
+ {
+ for (int i = 0; i < intfs.length; i++)
+ clss[i] = Class.forName(intfs[i]);
+ cl = ClassLoader.getSystemClassLoader();
+ }
+ else
+ for (int i = 0; i < intfs.length; i++)
+ clss[i] = cl.loadClass(intfs[i]);
+ try
+ {
+ return Proxy.getProxyClass(cl, clss);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ClassNotFoundException(null, e);
+ }
+ }
+
+ /**
+ * If <code>enable</code> is <code>true</code> and this object is
+ * trusted, then <code>resolveObject (Object)</code> will be called
+ * in subsequent calls to <code>readObject (Object)</code>.
+ * Otherwise, <code>resolveObject (Object)</code> will not be called.
+ *
+ * @exception SecurityException This class is not trusted.
+ */
+ protected boolean enableResolveObject (boolean enable)
+ throws SecurityException
+ {
+ if (enable)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new SerializablePermission("enableSubstitution"));
+ }
+
+ boolean old_val = this.resolveEnabled;
+ this.resolveEnabled = enable;
+ return old_val;
+ }
+
+ /**
+ * Reads stream magic and stream version information from the
+ * underlying stream.
+ *
+ * @exception IOException Exception from underlying stream.
+ *
+ * @exception StreamCorruptedException An invalid stream magic
+ * number or stream version was read from the stream.
+ */
+ protected void readStreamHeader()
+ throws IOException, StreamCorruptedException
+ {
+ if(dump) dumpElement("STREAM MAGIC ");
+ if (this.realInputStream.readShort() != STREAM_MAGIC)
+ throw new StreamCorruptedException("Invalid stream magic number");
+
+ if(dump) dumpElementln("STREAM VERSION ");
+ if (this.realInputStream.readShort() != STREAM_VERSION)
+ throw new StreamCorruptedException("Invalid stream version number");
+ }
+
+ public int read() throws IOException
+ {
+ if (this.readDataFromBlock)
+ {
+ if (this.blockDataPosition >= this.blockDataBytes)
+ readNextBlock();
+ return (this.blockData[this.blockDataPosition++] & 0xff);
+ }
+ else
+ return this.realInputStream.read();
+ }
+
+ public int read(byte[] data, int offset, int length) throws IOException
+ {
+ if (this.readDataFromBlock)
+ {
+ if (this.blockDataPosition + length > this.blockDataBytes)
+ {
+ int remain = this.blockDataBytes - this.blockDataPosition;
+ if (remain != 0)
+ {
+ System.arraycopy(this.blockData, this.blockDataPosition,
+ data, offset, remain);
+ offset += remain;
+ length -= remain;
+ }
+ readNextBlock ();
+ }
+
+ System.arraycopy(this.blockData, this.blockDataPosition,
+ data, offset, length);
+ this.blockDataPosition += length;
+
+ return length;
+ }
+ else
+ return this.realInputStream.read(data, offset, length);
+ }
+
+ public int available() throws IOException
+ {
+ if (this.readDataFromBlock)
+ {
+ if (this.blockDataPosition >= this.blockDataBytes)
+ readNextBlock ();
+
+ return this.blockDataBytes - this.blockDataPosition;
+ }
+ else
+ return this.realInputStream.available();
+ }
+
+ public void close() throws IOException
+ {
+ this.realInputStream.close();
+ }
+
+ public boolean readBoolean() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode (true);
+ boolean value = this.dataInputStream.readBoolean ();
+ if (switchmode)
+ setBlockDataMode (oldmode);
+ return value;
+ }
+
+ public byte readByte() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ byte value = this.dataInputStream.readByte();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public int readUnsignedByte() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 1)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ int value = this.dataInputStream.readUnsignedByte();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public short readShort() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ short value = this.dataInputStream.readShort();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public int readUnsignedShort() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ int value = this.dataInputStream.readUnsignedShort();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public char readChar() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 2)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ char value = this.dataInputStream.readChar();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public int readInt() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ int value = this.dataInputStream.readInt();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public long readLong() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ long value = this.dataInputStream.readLong();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public float readFloat() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 4)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ float value = this.dataInputStream.readFloat();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public double readDouble() throws IOException
+ {
+ boolean switchmode = true;
+ boolean oldmode = this.readDataFromBlock;
+ if (!oldmode || this.blockDataBytes - this.blockDataPosition >= 8)
+ switchmode = false;
+ if (switchmode)
+ oldmode = setBlockDataMode(true);
+ double value = this.dataInputStream.readDouble();
+ if (switchmode)
+ setBlockDataMode(oldmode);
+ return value;
+ }
+
+ public void readFully(byte data[]) throws IOException
+ {
+ this.dataInputStream.readFully(data);
+ }
+
+ public void readFully(byte data[], int offset, int size)
+ throws IOException
+ {
+ this.dataInputStream.readFully(data, offset, size);
+ }
+
+ public int skipBytes(int len) throws IOException
+ {
+ return this.dataInputStream.skipBytes(len);
+ }
+
+ /**
+ * @deprecated
+ * @see java.io.DataInputStream#readLine ()
+ */
+ public String readLine() throws IOException
+ {
+ return this.dataInputStream.readLine();
+ }
+
+ public String readUTF() throws IOException
+ {
+ return this.dataInputStream.readUTF();
+ }
+
+ /**
+ * This class allows a class to specify exactly which fields should
+ * be read, and what values should be read for these fields.
+ *
+ * XXX: finish up comments
+ */
+ public abstract static class GetField
+ {
+ public abstract ObjectStreamClass getObjectStreamClass();
+
+ public abstract boolean defaulted(String name)
+ throws IOException, IllegalArgumentException;
+
+ public abstract boolean get(String name, boolean defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract char get(String name, char defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract byte get(String name, byte defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract short get(String name, short defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract int get(String name, int defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract long get(String name, long defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract float get(String name, float defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract double get(String name, double defvalue)
+ throws IOException, IllegalArgumentException;
+
+ public abstract Object get(String name, Object defvalue)
+ throws IOException, IllegalArgumentException;
+ }
+
+ /**
+ * This method should be called by a method called 'readObject' in the
+ * deserializing class (if present). It cannot (and should not)be called
+ * outside of it. Its goal is to read all fields in the real input stream
+ * and keep them accessible through the {@link #GetField} class. Calling
+ * this method will not alter the deserializing object.
+ *
+ * @return A valid freshly created 'GetField' instance to get access to
+ * the deserialized stream.
+ * @throws IOException An input/output exception occured.
+ * @throws ClassNotFoundException
+ * @throws NotActiveException
+ */
+ public GetField readFields()
+ throws IOException, ClassNotFoundException, NotActiveException
+ {
+ if (this.currentObject == null || this.currentObjectStreamClass == null)
+ throw new NotActiveException("readFields called by non-active class and/or object");
+
+ if (prereadFields != null)
+ return prereadFields;
+
+ if (fieldsAlreadyRead)
+ throw new NotActiveException("readFields called but fields already read from"
+ + " stream (by defaultReadObject or readFields)");
+
+ final ObjectStreamClass clazz = this.currentObjectStreamClass;
+ final byte[] prim_field_data = new byte[clazz.primFieldSize];
+ final Object[] objs = new Object[clazz.objectFieldCount];
+
+ // Apparently Block data is not used with GetField as per
+ // empirical evidence against JDK 1.2. Also see Mauve test
+ // java.io.ObjectInputOutput.Test.GetPutField.
+ boolean oldmode = setBlockDataMode(false);
+ readFully(prim_field_data);
+ for (int i = 0; i < objs.length; ++ i)
+ objs[i] = readObject();
+ setBlockDataMode(oldmode);
+
+ prereadFields = new GetField()
+ {
+ public ObjectStreamClass getObjectStreamClass()
+ {
+ return clazz;
+ }
+
+ public boolean defaulted(String name)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField f = clazz.getField(name);
+
+ /* First if we have a serialized field use the descriptor */
+ if (f != null)
+ {
+ /* It is in serialPersistentFields but setClass tells us
+ * it should not be set. This value is defaulted.
+ */
+ if (f.isPersistent() && !f.isToSet())
+ return true;
+
+ return false;
+ }
+
+ /* This is not a serialized field. There should be
+ * a default value only if the field really exists.
+ */
+ try
+ {
+ return (clazz.forClass().getDeclaredField (name) != null);
+ }
+ catch (NoSuchFieldException e)
+ {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+
+ public boolean get(String name, boolean defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Boolean.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ return prim_field_data[field.getOffset()] == 0 ? false : true;
+ }
+
+ public char get(String name, char defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Character.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset();
+
+ return (char)(((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public byte get(String name, byte defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Byte.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ return prim_field_data[field.getOffset()];
+ }
+
+ public short get(String name, short defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Short.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset();
+
+ return (short)(((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public int get(String name, int defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Integer.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset();
+
+ return ((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF);
+ }
+
+ public long get(String name, long defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Long.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset();
+
+ return (long)(((prim_field_data[off++] & 0xFFL) << 56)
+ | ((prim_field_data[off++] & 0xFFL) << 48)
+ | ((prim_field_data[off++] & 0xFFL) << 40)
+ | ((prim_field_data[off++] & 0xFFL) << 32)
+ | ((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public float get(String name, float defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Float.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset();
+
+ return Float.intBitsToFloat(((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF));
+ }
+
+ public double get(String name, double defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field = getField(name, Double.TYPE);
+
+ if (field == null)
+ return defvalue;
+
+ int off = field.getOffset();
+
+ return Double.longBitsToDouble
+ ( (long) (((prim_field_data[off++] & 0xFFL) << 56)
+ | ((prim_field_data[off++] & 0xFFL) << 48)
+ | ((prim_field_data[off++] & 0xFFL) << 40)
+ | ((prim_field_data[off++] & 0xFFL) << 32)
+ | ((prim_field_data[off++] & 0xFF) << 24)
+ | ((prim_field_data[off++] & 0xFF) << 16)
+ | ((prim_field_data[off++] & 0xFF) << 8)
+ | (prim_field_data[off] & 0xFF)));
+ }
+
+ public Object get(String name, Object defvalue)
+ throws IOException, IllegalArgumentException
+ {
+ ObjectStreamField field =
+ getField(name, defvalue == null ? null : defvalue.getClass ());
+
+ if (field == null)
+ return defvalue;
+
+ return objs[field.getOffset()];
+ }
+
+ private ObjectStreamField getField(String name, Class type)
+ throws IllegalArgumentException
+ {
+ ObjectStreamField field = clazz.getField(name);
+ boolean illegal = false;
+
+ try
+ {
+ try
+ {
+ Class field_type = field.getType();
+
+ if (type == field_type ||
+ (type == null && !field_type.isPrimitive()))
+ {
+ /* See defaulted */
+ return field;
+ }
+
+ illegal = true;
+ throw new IllegalArgumentException
+ ("Field requested is of type "
+ + field_type.getName()
+ + ", but requested type was "
+ + (type == null ? "Object" : type.getName()));
+ }
+ catch (NullPointerException _)
+ {
+ /* Here we catch NullPointerException, because it may
+ only come from the call 'field.getType()'. If field
+ is null, we have to return null and classpath ethic
+ say we must try to avoid 'if (xxx == null)'.
+ */
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw e;
+ }
+
+ return null;
+ }
+ finally
+ {
+ /* If this is an unassigned field we should return
+ * the default value.
+ */
+ if (!illegal && field != null && !field.isToSet() && field.isPersistent())
+ return null;
+
+ /* We do not want to modify transient fields. They should
+ * be left to 0.
+ */
+ try
+ {
+ Field f = clazz.forClass().getDeclaredField(name);
+ if (Modifier.isTransient(f.getModifiers()))
+ throw new IllegalArgumentException
+ ("no such field (non transient) " + name);
+ if (field == null && f.getType() != type)
+ throw new IllegalArgumentException
+ ("Invalid requested type for field " + name);
+ }
+ catch (NoSuchFieldException e)
+ {
+ if (field == null)
+ throw new IllegalArgumentException(e.getMessage());
+ }
+
+ }
+ }
+ };
+
+ fieldsAlreadyRead = true;
+ return prereadFields;
+ }
+
+ /**
+ * Protected constructor that allows subclasses to override
+ * deserialization. This constructor should be called by subclasses
+ * that wish to override <code>readObject (Object)</code>. This
+ * method does a security check <i>NOTE: currently not
+ * implemented</i>, then sets a flag that informs
+ * <code>readObject (Object)</code> to call the subclasses
+ * <code>readObjectOverride (Object)</code> method.
+ *
+ * @see #readObjectOverride()
+ */
+ protected ObjectInputStream()
+ throws IOException, SecurityException
+ {
+ SecurityManager sec_man = System.getSecurityManager();
+ if (sec_man != null)
+ sec_man.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
+ this.useSubclassMethod = true;
+ }
+
+ /**
+ * This method allows subclasses to override the default
+ * de serialization mechanism provided by
+ * <code>ObjectInputStream</code>. To make this method be used for
+ * writing objects, subclasses must invoke the 0-argument
+ * constructor on this class from their constructor.
+ *
+ * @see #ObjectInputStream()
+ */
+ protected Object readObjectOverride()
+ throws ClassNotFoundException, IOException, OptionalDataException
+ {
+ throw new IOException("Subclass of ObjectInputStream must implement readObjectOverride");
+ }
+
+ /**
+ * Assigns the next available handle to <code>obj</code>.
+ *
+ * @param obj The object for which we want a new handle.
+ * @return A valid handle for the specified object.
+ */
+ private int assignNewHandle(Object obj)
+ {
+ this.objectLookupTable.put(new Integer(this.nextOID),
+ new ObjectIdentityWrapper(obj));
+ return this.nextOID++;
+ }
+
+ private Object processResolution(ObjectStreamClass osc, Object obj, int handle)
+ throws IOException
+ {
+ if (osc != null && obj instanceof Serializable)
+ {
+ try
+ {
+ Method m = osc.readResolveMethod;
+ if(m != null)
+ {
+ obj = m.invoke(obj, new Object[] {});
+ }
+ }
+ catch (IllegalAccessException ignore)
+ {
+ }
+ catch (InvocationTargetException exception)
+ {
+ Throwable cause = exception.getCause();
+ if (cause instanceof ObjectStreamException)
+ throw (ObjectStreamException) cause;
+ else if (cause instanceof RuntimeException)
+ throw (RuntimeException) cause;
+ else if (cause instanceof Error)
+ throw (Error) cause;
+ }
+ }
+
+ if (this.resolveEnabled)
+ obj = resolveObject(obj);
+
+ this.objectLookupTable.put(new Integer(handle),
+ new ObjectIdentityWrapper(obj));
+
+ return obj;
+ }
+
+ private void clearHandles()
+ {
+ this.objectLookupTable.clear();
+ this.nextOID = baseWireHandle;
+ }
+
+ private void readNextBlock() throws IOException
+ {
+ readNextBlock(this.realInputStream.readByte());
+ }
+
+ private void readNextBlock(byte marker) throws IOException
+ {
+ if (marker == TC_BLOCKDATA)
+ {
+ if(dump) dumpElement("BLOCK DATA SIZE=");
+ this.blockDataBytes = this.realInputStream.readUnsignedByte();
+ if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
+ }
+ else if (marker == TC_BLOCKDATALONG)
+ {
+ if(dump) dumpElement("BLOCK DATA LONG SIZE=");
+ this.blockDataBytes = this.realInputStream.readInt();
+ if(dump) dumpElementln (Integer.toString(this.blockDataBytes));
+ }
+ else
+ {
+ throw new EOFException("Attempt to read primitive data, but no data block is active.");
+ }
+
+ if (this.blockData.length < this.blockDataBytes)
+ this.blockData = new byte[this.blockDataBytes];
+
+ this.realInputStream.readFully (this.blockData, 0, this.blockDataBytes);
+ this.blockDataPosition = 0;
+ }
+
+ private void readArrayElements (Object array, Class clazz)
+ throws ClassNotFoundException, IOException
+ {
+ if (clazz.isPrimitive())
+ {
+ if (clazz == Boolean.TYPE)
+ {
+ boolean[] cast_array = (boolean[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readBoolean();
+ return;
+ }
+ if (clazz == Byte.TYPE)
+ {
+ byte[] cast_array = (byte[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readByte();
+ return;
+ }
+ if (clazz == Character.TYPE)
+ {
+ char[] cast_array = (char[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readChar();
+ return;
+ }
+ if (clazz == Double.TYPE)
+ {
+ double[] cast_array = (double[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readDouble();
+ return;
+ }
+ if (clazz == Float.TYPE)
+ {
+ float[] cast_array = (float[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readFloat();
+ return;
+ }
+ if (clazz == Integer.TYPE)
+ {
+ int[] cast_array = (int[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readInt();
+ return;
+ }
+ if (clazz == Long.TYPE)
+ {
+ long[] cast_array = (long[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readLong();
+ return;
+ }
+ if (clazz == Short.TYPE)
+ {
+ short[] cast_array = (short[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = this.realInputStream.readShort();
+ return;
+ }
+ }
+ else
+ {
+ Object[] cast_array = (Object[])array;
+ for (int i=0; i < cast_array.length; i++)
+ cast_array[i] = readObject();
+ }
+ }
+
+ private void readFields (Object obj, ObjectStreamClass stream_osc)
+ throws ClassNotFoundException, IOException
+ {
+ ObjectStreamField[] fields = stream_osc.fieldMapping;
+
+ for (int i = 0; i < fields.length; i += 2)
+ {
+ ObjectStreamField stream_field = fields[i];
+ ObjectStreamField real_field = fields[i + 1];
+ boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
+ boolean set_value = (real_field != null && real_field.isToSet());
+ String field_name;
+ char type;
+
+ if (stream_field != null)
+ {
+ field_name = stream_field.getName();
+ type = stream_field.getTypeCode();
+ }
+ else
+ {
+ field_name = real_field.getName();
+ type = real_field.getTypeCode();
+ }
+
+ switch(type)
+ {
+ case 'Z':
+ {
+ boolean value =
+ read_value ? this.realInputStream.readBoolean() : false;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setBooleanField(obj, value);
+ break;
+ }
+ case 'B':
+ {
+ byte value =
+ read_value ? this.realInputStream.readByte() : 0;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setByteField(obj, value);
+ break;
+ }
+ case 'C':
+ {
+ char value =
+ read_value ? this.realInputStream.readChar(): 0;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setCharField(obj, value);
+ break;
+ }
+ case 'D':
+ {
+ double value =
+ read_value ? this.realInputStream.readDouble() : 0;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setDoubleField(obj, value);
+ break;
+ }
+ case 'F':
+ {
+ float value =
+ read_value ? this.realInputStream.readFloat() : 0;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setFloatField(obj, value);
+ break;
+ }
+ case 'I':
+ {
+ int value =
+ read_value ? this.realInputStream.readInt() : 0;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setIntField(obj, value);
+ break;
+ }
+ case 'J':
+ {
+ long value =
+ read_value ? this.realInputStream.readLong() : 0;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setLongField(obj, value);
+ break;
+ }
+ case 'S':
+ {
+ short value =
+ read_value ? this.realInputStream.readShort() : 0;
+ if (dump && read_value && set_value)
+ dumpElementln(" " + field_name + ": " + value);
+ if (set_value)
+ real_field.setShortField(obj, value);
+ break;
+ }
+ case 'L':
+ case '[':
+ {
+ Object value =
+ read_value ? readObject() : null;
+ if (set_value)
+ real_field.setObjectField(obj, value);
+ break;
+ }
+ default:
+ throw new InternalError("Invalid type code: " + type);
+ }
+ }
+ }
+
+ // Toggles writing primitive data to block-data buffer.
+ private boolean setBlockDataMode (boolean on)
+ {
+ boolean oldmode = this.readDataFromBlock;
+ this.readDataFromBlock = on;
+
+ if (on)
+ this.dataInputStream = this.blockDataInput;
+ else
+ this.dataInputStream = this.realInputStream;
+ return oldmode;
+ }
+
+ // returns a new instance of REAL_CLASS that has been constructed
+ // only to the level of CONSTRUCTOR_CLASS (a super class of REAL_CLASS)
+ private Object newObject (Class real_class, Constructor constructor)
+ throws ClassNotFoundException, IOException
+ {
+ if (constructor == null)
+ throw new InvalidClassException("Missing accessible no-arg base class constructor for " + real_class.getName());
+ try
+ {
+ return allocateObject(real_class, constructor.getDeclaringClass(), constructor);
+ }
+ catch (InstantiationException e)
+ {
+ throw new ClassNotFoundException
+ ("Instance of " + real_class + " could not be created");
+ }
+ }
+
+ // runs all registered ObjectInputValidations in prioritized order
+ // on OBJ
+ private void invokeValidators() throws InvalidObjectException
+ {
+ Object[] validators = new Object[this.validators.size()];
+ this.validators.copyInto (validators);
+ Arrays.sort (validators);
+
+ try
+ {
+ for (int i=0; i < validators.length; i++)
+ ((ObjectInputValidation)validators[i]).validateObject();
+ }
+ finally
+ {
+ this.validators.removeAllElements();
+ }
+ }
+
+ private void callReadMethod (Method readObject, Class klass, Object obj)
+ throws ClassNotFoundException, IOException
+ {
+ try
+ {
+ readObject.invoke(obj, new Object[] { this });
+ }
+ catch (InvocationTargetException x)
+ {
+ /* Rethrow if possible. */
+ Throwable exception = x.getTargetException();
+ if (exception instanceof RuntimeException)
+ throw (RuntimeException) exception;
+ if (exception instanceof IOException)
+ throw (IOException) exception;
+ if (exception instanceof ClassNotFoundException)
+ throw (ClassNotFoundException) exception;
+
+ throw new IOException("Exception thrown from readObject() on " +
+ klass + ": " + exception.getClass().getName());
+ }
+ catch (Exception x)
+ {
+ throw new IOException("Failure invoking readObject() on " +
+ klass + ": " + x.getClass().getName());
+ }
+
+ // Invalidate fields which has been read through readFields.
+ prereadFields = null;
+ }
+
+ private native Object allocateObject(Class clazz, Class constr_clazz, Constructor constructor)
+ throws InstantiationException;
+
+ private static final int BUFFER_SIZE = 1024;
+
+ private DataInputStream realInputStream;
+ private DataInputStream dataInputStream;
+ private DataInputStream blockDataInput;
+ private int blockDataPosition;
+ private int blockDataBytes;
+ private byte[] blockData;
+ private boolean useSubclassMethod;
+ private int nextOID;
+ private boolean resolveEnabled;
+ private Hashtable objectLookupTable;
+ private Object currentObject;
+ private ObjectStreamClass currentObjectStreamClass;
+ private boolean readDataFromBlock;
+ private boolean isDeserializing;
+ private boolean fieldsAlreadyRead;
+ private Vector validators;
+ private Hashtable classLookupTable;
+ private GetField prereadFields;
+
+ private ClassLoader callersClassLoader;
+ private static boolean dump;
+
+ // The nesting depth for debugging output
+ private int depth = 0;
+
+ private void dumpElement (String msg)
+ {
+ System.out.print(msg);
+ }
+
+ private void dumpElementln (String msg)
+ {
+ System.out.println(msg);
+ for (int i = 0; i < depth; i++)
+ System.out.print (" ");
+ System.out.print (Thread.currentThread() + ": ");
+ }
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary ("javaio");
+ }
+ }
+
+ // used to keep a prioritized list of object validators
+ private static final class ValidatorAndPriority implements Comparable
+ {
+ int priority;
+ ObjectInputValidation validator;
+
+ ValidatorAndPriority (ObjectInputValidation validator, int priority)
+ {
+ this.priority = priority;
+ this.validator = validator;
+ }
+
+ public int compareTo (Object o)
+ {
+ ValidatorAndPriority vap = (ValidatorAndPriority)o;
+ return this.priority - vap.priority;
+ }
+ }
+}
+
diff --git a/gcc-4.2.1/libjava/java/io/OutputStreamWriter.java b/gcc-4.2.1/libjava/java/io/OutputStreamWriter.java
new file mode 100644
index 000000000..aac1684c6
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/OutputStreamWriter.java
@@ -0,0 +1,347 @@
+/* OutputStreamWriter.java -- Writer that converts chars to bytes
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 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.gcj.convert.UnicodeToBytes;
+import gnu.gcj.convert.CharsetToBytesAdaptor;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+
+/**
+ * This class writes characters to an output stream that is byte oriented
+ * It converts the chars that are written to bytes using an encoding layer,
+ * which is specific to a particular encoding standard. The desired
+ * encoding can either be specified by name, or if no encoding is specified,
+ * the system default encoding will be used. The system default encoding
+ * name is determined from the system property <code>file.encoding</code>.
+ * The only encodings that are guaranteed to be available are "8859_1"
+ * (the Latin-1 character set) and "UTF8". Unfortunately, Java does not
+ * provide a mechanism for listing the encodings that are supported in
+ * a given implementation.
+ * <p>
+ * Here is a list of standard encoding names that may be available:
+ * <p>
+ * <ul>
+ * <li>8859_1 (ISO-8859-1/Latin-1)
+ * <li>8859_2 (ISO-8859-2/Latin-2)
+ * <li>8859_3 (ISO-8859-3/Latin-3)
+ * <li>8859_4 (ISO-8859-4/Latin-4)
+ * <li>8859_5 (ISO-8859-5/Latin-5)
+ * <li>8859_6 (ISO-8859-6/Latin-6)
+ * <li>8859_7 (ISO-8859-7/Latin-7)
+ * <li>8859_8 (ISO-8859-8/Latin-8)
+ * <li>8859_9 (ISO-8859-9/Latin-9)
+ * <li>ASCII (7-bit ASCII)
+ * <li>UTF8 (UCS Transformation Format-8)
+ * <li>More Later
+ * </ul>
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Per Bothner (bothner@cygnus.com)
+ * @date April 17, 1998.
+ */
+public class OutputStreamWriter extends Writer
+{
+ BufferedOutputStream out;
+
+ /**
+ * This is the byte-character encoder class that does the writing and
+ * translation of characters to bytes before writing to the underlying
+ * class.
+ */
+ UnicodeToBytes converter;
+
+ /* Temporary buffer. */
+ private char[] work;
+ private int wcount;
+
+ private OutputStreamWriter(OutputStream out, UnicodeToBytes encoder)
+ {
+ this.out = out instanceof BufferedOutputStream
+ ? (BufferedOutputStream) out
+ : new BufferedOutputStream(out, 250);
+ /* Don't need to call super(out) here as long as the lock gets set. */
+ this.lock = out;
+ this.converter = encoder;
+ }
+
+ /**
+ * This method initializes a new instance of <code>OutputStreamWriter</code>
+ * to write to the specified stream using a caller supplied character
+ * encoding scheme. Note that due to a deficiency in the Java language
+ * design, there is no way to determine which encodings are supported.
+ *
+ * @param out The <code>OutputStream</code> to write to
+ * @param encoding_scheme The name of the encoding scheme to use for
+ * character to byte translation
+ *
+ * @exception UnsupportedEncodingException If the named encoding is
+ * not available.
+ */
+ public OutputStreamWriter (OutputStream out, String encoding_scheme)
+ throws UnsupportedEncodingException
+ {
+ this(out, UnicodeToBytes.getEncoder(encoding_scheme));
+ }
+
+ /**
+ * This method initializes a new instance of <code>OutputStreamWriter</code>
+ * to write to the specified stream using the default encoding.
+ *
+ * @param out The <code>OutputStream</code> to write to
+ */
+ public OutputStreamWriter (OutputStream out)
+ {
+ this(out, UnicodeToBytes.getDefaultEncoder());
+ }
+
+ /**
+ * This method initializes a new instance of <code>OutputStreamWriter</code>
+ * to write to the specified stream using a given <code>Charset</code>.
+ *
+ * @param out The <code>OutputStream</code> to write to
+ * @param cs The <code>Charset</code> of the encoding to use
+ */
+ public OutputStreamWriter(OutputStream out, Charset cs)
+ {
+ this(out, new CharsetToBytesAdaptor(cs));
+ }
+
+ /**
+ * This method initializes a new instance of <code>OutputStreamWriter</code>
+ * to write to the specified stream using a given
+ * <code>CharsetEncoder</code>.
+ *
+ * @param out The <code>OutputStream</code> to write to
+ * @param enc The <code>CharsetEncoder</code> to encode the output with
+ */
+ public OutputStreamWriter(OutputStream out, CharsetEncoder enc)
+ {
+ this(out, new CharsetToBytesAdaptor(enc));
+ }
+
+ /**
+ * This method closes this stream, and the underlying
+ * <code>OutputStream</code>
+ *
+ * @exception IOException If an error occurs
+ */
+ public void close () throws IOException
+ {
+ synchronized (lock)
+ {
+ if (out != null)
+ {
+ converter.setFinished();
+ flush();
+ out.close();
+ out = null;
+ }
+ work = null;
+ }
+ }
+
+ /**
+ * This method returns the name of the character encoding scheme currently
+ * in use by this stream. If the stream has been closed, then this method
+ * may return <code>null</code>.
+ *
+ * @return The encoding scheme name
+ */
+ public String getEncoding ()
+ {
+ return out != null ? converter.getName() : null;
+ }
+
+ /**
+ * This method flushes any buffered bytes to the underlying output sink.
+ *
+ * @exception IOException If an error occurs
+ */
+ public void flush () throws IOException
+ {
+ synchronized (lock)
+ {
+ if (out == null)
+ throw new IOException("Stream closed");
+
+ // Always write -- if we are close()ing then we want to make
+ // sure the converter is flushed.
+ if (work == null)
+ work = new char[100];
+ writeChars(work, 0, wcount);
+ wcount = 0;
+
+ out.flush();
+ }
+ }
+
+ /**
+ * This method writes <code>count</code> characters from the specified
+ * array to the output stream starting at position <code>offset</code>
+ * into the array.
+ *
+ * @param buf The array of character to write from
+ * @param offset The offset into the array to start writing chars from
+ * @param count The number of chars to write.
+ *
+ * @exception IOException If an error occurs
+ */
+ public void write (char[] buf, int offset, int count) throws IOException
+ {
+ synchronized (lock)
+ {
+ if (out == null)
+ throw new IOException("Stream closed");
+
+ if (wcount > 0)
+ {
+ writeChars(work, 0, wcount);
+ wcount = 0;
+ }
+ writeChars(buf, offset, count);
+ }
+ }
+
+ /*
+ * Writes characters through to the inferior BufferedOutputStream.
+ * Ignores wcount and the work buffer.
+ */
+ private void writeChars(char[] buf, int offset, int count)
+ throws IOException
+ {
+ do
+ {
+ // We must flush if out.count == out.buf.length.
+ // It is probably a good idea to flush if out.buf is almost full.
+ // This test is an approximation for "almost full".
+ if (out.count + count >= out.buf.length)
+ {
+ out.flush();
+ if (out.count != 0)
+ throw new IOException("unable to flush output byte buffer");
+ }
+ converter.setOutput(out.buf, out.count);
+ int converted = converter.write(buf, offset, count);
+ // Must set this before we flush the output stream, because
+ // flushing will reset 'out.count'.
+ out.count = converter.count;
+ // Flush if we cannot make progress.
+ if (converted == 0 && out.count == converter.count)
+ {
+ out.flush();
+ if (out.count != 0)
+ throw new IOException("unable to flush output byte buffer");
+ }
+ offset += converted;
+ count -= converted;
+ }
+ while (count > 0 || converter.havePendingBytes());
+ }
+
+ /**
+ * This method writes <code>count</code> bytes from the specified
+ * <code>String</code> starting at position <code>offset</code> into the
+ * <code>String</code>.
+ *
+ * @param str The <code>String</code> to write chars from
+ * @param offset The position in the <code>String</code> to start
+ * writing chars from
+ * @param count The number of chars to write
+ *
+ * @exception IOException If an error occurs
+ */
+ public void write (String str, int offset, int count) throws IOException
+ {
+ synchronized (lock)
+ {
+ if (out == null)
+ throw new IOException("Stream closed");
+
+ if (work == null)
+ work = new char[100];
+ int wlength = work.length;
+ while (count > 0)
+ {
+ int size = count;
+ if (wcount + size > wlength)
+ {
+ if (2*wcount > wlength)
+ {
+ writeChars(work, 0, wcount);
+ wcount = 0;
+ }
+ if (wcount + size > wlength)
+ size = wlength - wcount;
+ }
+ str.getChars(offset, offset+size, work, wcount);
+ offset += size;
+ count -= size;
+ wcount += size;
+ }
+ }
+ }
+
+ /**
+ * This method writes a single character to the output stream.
+ *
+ * @param ch The char to write, passed as an int.
+ *
+ * @exception IOException If an error occurs
+ */
+ public void write (int ch) throws IOException
+ {
+ synchronized (lock)
+ {
+ if (out == null)
+ throw new IOException("Stream closed");
+
+ if (work == null)
+ work = new char[100];
+ if (wcount >= work.length)
+ {
+ writeChars(work, 0, wcount);
+ wcount = 0;
+ }
+ work[wcount++] = (char) ch;
+ }
+ }
+
+} // class OutputStreamWriter
+
diff --git a/gcc-4.2.1/libjava/java/io/PrintStream.java b/gcc-4.2.1/libjava/java/io/PrintStream.java
new file mode 100644
index 000000000..dc26edafd
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/PrintStream.java
@@ -0,0 +1,566 @@
+/* PrintStream.java -- OutputStream for printing output
+ Copyright (C) 1998, 1999, 2001, 2003, 2004, 2005, 2006 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.gcj.convert.UnicodeToBytes;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * Status: Believed complete and correct to 1.3
+ */
+
+/**
+ * This class prints Java primitive values and object to a stream as
+ * text. None of the methods in this class throw an exception. However,
+ * errors can be detected by calling the <code>checkError()</code> method.
+ * Additionally, this stream can be designated as "autoflush" when
+ * created so that any writes are automatically flushed to the underlying
+ * output sink when the current line is terminated.
+ * <p>
+ * This class converts char's into byte's using the system default encoding.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Tom Tromey (tromey@cygnus.com)
+ */
+public class PrintStream extends FilterOutputStream
+{
+ /* Notice the implementation is quite similar to OutputStreamWriter.
+ * This leads to some minor duplication, because neither inherits
+ * from the other, and we want to maximize performance. */
+
+ // Line separator string.
+ private static final char[] line_separator
+ = System.getProperty("line.separator").toCharArray();
+
+ UnicodeToBytes converter;
+
+ // Work buffer of characters for converter.
+ char[] work = new char[100];
+ // Work buffer of bytes where we temporarily keep converter output.
+ byte[] work_bytes = new byte[100];
+
+ /**
+ * This boolean indicates whether or not an error has ever occurred
+ * on this stream.
+ */
+ private boolean error_occurred = false;
+
+ /**
+ * This is <code>true</code> if auto-flush is enabled,
+ * <code>false</code> otherwise
+ */
+ private boolean auto_flush;
+
+ /**
+ * This method intializes a new <code>PrintStream</code> object to write
+ * to the specified output sink.
+ *
+ * @param out The <code>OutputStream</code> to write to.
+ */
+ public PrintStream (OutputStream out)
+ {
+ this (out, false);
+ }
+
+ /**
+ * This method intializes a new <code>PrintStream</code> object to write
+ * to the specified output sink. This constructor also allows "auto-flush"
+ * functionality to be specified where the stream will be flushed after
+ * every <code>print</code> or <code>println</code> call, when the
+ * <code>write</code> methods with array arguments are called, or when a
+ * single new-line character is written.
+ * <p>
+ *
+ * @param out The <code>OutputStream</code> to write to.
+ * @param auto_flush <code>true</code> to flush the stream after every
+ * line, <code>false</code> otherwise
+ */
+ public PrintStream (OutputStream out, boolean auto_flush)
+ {
+ super (out);
+
+ converter = UnicodeToBytes.getDefaultEncoder();
+ this.auto_flush = auto_flush;
+ }
+
+ /**
+ * This method intializes a new <code>PrintStream</code> object to write
+ * to the specified output sink. This constructor also allows "auto-flush"
+ * functionality to be specified where the stream will be flushed after
+ * every <code>print</code> or <code>println</code> call, when the
+ * <code>write</code> methods with array arguments are called, or when a
+ * single new-line character is written.
+ * <p>
+ *
+ * @param out The <code>OutputStream</code> to write to.
+ * @param auto_flush <code>true</code> to flush the stream after every
+ * line, <code>false</code> otherwise
+ * @param encoding The name of the character encoding to use for this
+ * object.
+ */
+ public PrintStream (OutputStream out, boolean auto_flush, String encoding)
+ throws UnsupportedEncodingException
+ {
+ super (out);
+
+ converter = UnicodeToBytes.getEncoder (encoding);
+ this.auto_flush = auto_flush;
+ }
+
+ /**
+ * This method checks to see if an error has occurred on this stream. Note
+ * that once an error has occurred, this method will continue to report
+ * <code>true</code> forever for this stream. Before checking for an
+ * error condition, this method flushes the stream.
+ *
+ * @return <code>true</code> if an error has occurred,
+ * <code>false</code> otherwise
+ */
+ public boolean checkError ()
+ {
+ flush ();
+ return error_occurred;
+ }
+
+ /**
+ * This method can be called by subclasses to indicate that an error
+ * has occurred and should be reported by <code>checkError</code>.
+ */
+ protected void setError ()
+ {
+ error_occurred = true;
+ }
+
+ /**
+ * This method closes this stream and all underlying streams.
+ */
+ public void close ()
+ {
+ try
+ {
+ converter.setFinished();
+ writeChars(new char[0], 0, 0);
+ flush();
+ out.close();
+ }
+ catch (InterruptedIOException iioe)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (IOException e)
+ {
+ setError ();
+ }
+ }
+
+ /**
+ * This method flushes any buffered bytes to the underlying stream and
+ * then flushes that stream as well.
+ */
+ public void flush ()
+ {
+ try
+ {
+ out.flush();
+ }
+ catch (InterruptedIOException iioe)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (IOException e)
+ {
+ setError ();
+ }
+ }
+
+ private synchronized void print (String str, boolean println)
+ {
+ try
+ {
+ writeChars(str, 0, str.length());
+ if (println)
+ writeChars(line_separator, 0, line_separator.length);
+ if (auto_flush)
+ flush();
+ }
+ catch (InterruptedIOException iioe)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (IOException e)
+ {
+ setError ();
+ }
+ }
+
+ private synchronized void print (char[] chars, int pos, int len,
+ boolean println)
+ {
+ try
+ {
+ writeChars(chars, pos, len);
+ if (println)
+ writeChars(line_separator, 0, line_separator.length);
+ if (auto_flush)
+ flush();
+ }
+ catch (InterruptedIOException iioe)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (IOException e)
+ {
+ setError ();
+ }
+ }
+
+ private void writeChars(char[] buf, int offset, int count)
+ throws IOException
+ {
+ do
+ {
+ converter.setOutput(work_bytes, 0);
+ int converted = converter.write(buf, offset, count);
+ offset += converted;
+ count -= converted;
+ out.write(work_bytes, 0, converter.count);
+ }
+ while (count > 0 || converter.havePendingBytes());
+ }
+
+ private void writeChars(String str, int offset, int count)
+ throws IOException
+ {
+ do
+ {
+ converter.setOutput(work_bytes, 0);
+ int converted = converter.write(str, offset, count, work);
+ offset += converted;
+ count -= converted;
+ out.write(work_bytes, 0, converter.count);
+ }
+ while (count > 0 || converter.havePendingBytes());
+ }
+
+ /**
+ * This methods prints a boolean value to the stream. <code>true</code>
+ * values are printed as "true" and <code>false</code> values are printed
+ * as "false".
+ *
+ * @param bool The <code>boolean</code> value to print
+ */
+ public void print (boolean bool)
+ {
+ print(String.valueOf(bool), false);
+ }
+
+ /**
+ * This method prints an integer to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ *
+ * @param inum The <code>int</code> value to be printed
+ */
+ public void print (int inum)
+ {
+ print(String.valueOf(inum), false);
+ }
+
+ /**
+ * This method prints a long to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ *
+ * @param lnum The <code>long</code> value to be printed
+ */
+ public void print (long lnum)
+ {
+ print(String.valueOf(lnum), false);
+ }
+
+ /**
+ * This method prints a float to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ *
+ * @param fnum The <code>float</code> value to be printed
+ */
+ public void print (float fnum)
+ {
+ print(String.valueOf(fnum), false);
+ }
+
+ /**
+ * This method prints a double to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ *
+ * @param dnum The <code>double</code> value to be printed
+ */
+ public void print (double dnum)
+ {
+ print(String.valueOf(dnum), false);
+ }
+
+ /**
+ * This method prints an <code>Object</code> to the stream. The actual
+ * value printed is determined by calling the <code>String.valueOf()</code>
+ * method.
+ *
+ * @param obj The <code>Object</code> to print.
+ */
+ public void print (Object obj)
+ {
+ print(obj == null ? "null" : obj.toString(), false);
+ }
+
+ /**
+ * This method prints a <code>String</code> to the stream. The actual
+ * value printed depends on the system default encoding.
+ *
+ * @param str The <code>String</code> to print.
+ */
+ public void print (String str)
+ {
+ print(str == null ? "null" : str, false);
+ }
+
+ /**
+ * This method prints a char to the stream. The actual value printed is
+ * determined by the character encoding in use.
+ *
+ * @param ch The <code>char</code> value to be printed
+ */
+ public synchronized void print (char ch)
+ {
+ work[0] = ch;
+ print(work, 0, 1, false);
+ }
+
+ /**
+ * This method prints an array of characters to the stream. The actual
+ * value printed depends on the system default encoding.
+ *
+ * @param charArray The array of characters to print.
+ */
+ public void print (char[] charArray)
+ {
+ print(charArray, 0, charArray.length, false);
+ }
+
+ /**
+ * This method prints a line separator sequence to the stream. The value
+ * printed is determined by the system property <xmp>line.separator</xmp>
+ * and is not necessarily the Unix '\n' newline character.
+ */
+ public void println ()
+ {
+ print(line_separator, 0, line_separator.length, false);
+ }
+
+ /**
+ * This methods prints a boolean value to the stream. <code>true</code>
+ * values are printed as "true" and <code>false</code> values are printed
+ * as "false".
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param bool The <code>boolean</code> value to print
+ */
+ public void println (boolean bool)
+ {
+ print(String.valueOf(bool), true);
+ }
+
+ /**
+ * This method prints an integer to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param inum The <code>int</code> value to be printed
+ */
+ public void println (int inum)
+ {
+ print(String.valueOf(inum), true);
+ }
+
+ /**
+ * This method prints a long to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param lnum The <code>long</code> value to be printed
+ */
+ public void println (long lnum)
+ {
+ print(String.valueOf(lnum), true);
+ }
+
+ /**
+ * This method prints a float to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param fnum The <code>float</code> value to be printed
+ */
+ public void println (float fnum)
+ {
+ print(String.valueOf(fnum), true);
+ }
+
+ /**
+ * This method prints a double to the stream. The value printed is
+ * determined using the <code>String.valueOf()</code> method.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param dnum The <code>double</code> value to be printed
+ */
+ public void println (double dnum)
+ {
+ print(String.valueOf(dnum), true);
+ }
+
+ /**
+ * This method prints an <code>Object</code> to the stream. The actual
+ * value printed is determined by calling the <code>String.valueOf()</code>
+ * method.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param obj The <code>Object</code> to print.
+ */
+ public void println (Object obj)
+ {
+ print(obj == null ? "null" : obj.toString(), true);
+ }
+
+ /**
+ * This method prints a <code>String</code> to the stream. The actual
+ * value printed depends on the system default encoding.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param str The <code>String</code> to print.
+ */
+ public void println (String str)
+ {
+ print (str == null ? "null" : str, true);
+ }
+
+ /**
+ * This method prints a char to the stream. The actual value printed is
+ * determined by the character encoding in use.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param ch The <code>char</code> value to be printed
+ */
+ public synchronized void println (char ch)
+ {
+ work[0] = ch;
+ print(work, 0, 1, true);
+ }
+
+ /**
+ * This method prints an array of characters to the stream. The actual
+ * value printed depends on the system default encoding.
+ * <p>
+ * This method prints a line termination sequence after printing the value.
+ *
+ * @param charArray The array of characters to print.
+ */
+ public void println (char[] charArray)
+ {
+ print(charArray, 0, charArray.length, true);
+ }
+
+ /**
+ * This method writes a byte of data to the stream. If auto-flush is
+ * enabled, printing a newline character will cause the stream to be
+ * flushed after the character is written.
+ *
+ * @param oneByte The byte to be written
+ */
+ public void write (int oneByte)
+ {
+ try
+ {
+ out.write (oneByte & 0xff);
+
+ if (auto_flush && (oneByte == '\n'))
+ flush ();
+ }
+ catch (InterruptedIOException iioe)
+ {
+ Thread.currentThread ().interrupt ();
+ }
+ catch (IOException e)
+ {
+ setError ();
+ }
+ }
+
+ /**
+ * This method writes <code>len</code> bytes from the specified array
+ * starting at index <code>offset</code> into the array.
+ *
+ * @param buffer The array of bytes to write
+ * @param offset The index into the array to start writing from
+ * @param len The number of bytes to write
+ */
+ public void write (byte[] buffer, int offset, int len)
+ {
+ try
+ {
+ out.write (buffer, offset, len);
+
+ if (auto_flush)
+ flush ();
+ }
+ catch (InterruptedIOException iioe)
+ {
+ Thread.currentThread ().interrupt ();
+ }
+ catch (IOException e)
+ {
+ setError ();
+ }
+ }
+} // class PrintStream
+
diff --git a/gcc-4.2.1/libjava/java/io/VMObjectStreamClass.java b/gcc-4.2.1/libjava/java/io/VMObjectStreamClass.java
new file mode 100644
index 000000000..3900855ab
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/VMObjectStreamClass.java
@@ -0,0 +1,140 @@
+/* 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 "double" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified "float" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified "long" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified "int" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified "short" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified "char" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified "byte" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified "boolean" field, allowing final values
+ * to 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);
+
+ /**
+ * Sets the value of the specified object field, allowing final values
+ * to 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);
+}
diff --git a/gcc-4.2.1/libjava/java/io/natFilePosix.cc b/gcc-4.2.1/libjava/java/io/natFilePosix.cc
new file mode 100644
index 000000000..c9bf858f1
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/natFilePosix.cc
@@ -0,0 +1,458 @@
+// natFile.cc - Native part of File class for POSIX.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006
+ Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <string.h>
+#include <utime.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/io/File.h>
+#include <java/io/IOException.h>
+#include <java/util/ArrayList.h>
+#include <java/lang/String.h>
+#include <java/io/FilenameFilter.h>
+#include <java/io/FileFilter.h>
+#include <java/lang/System.h>
+
+jboolean
+java::io::File::_access (jint query)
+{
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+ JvAssert (query == READ || query == WRITE || query == EXISTS);
+#ifdef HAVE_ACCESS
+ int mode;
+ if (query == READ)
+ mode = R_OK;
+ else if (query == WRITE)
+ mode = W_OK;
+ else
+ mode = F_OK;
+ return ::access (buf, mode) == 0;
+#else
+ return false;
+#endif
+}
+
+jboolean
+java::io::File::_stat (jint query)
+{
+ if (query == ISHIDDEN)
+ return getName()->charAt(0) == '.';
+
+#ifdef HAVE_STAT
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+ struct stat sb;
+ if (::stat (buf, &sb))
+ return false;
+
+ JvAssert (query == DIRECTORY || query == ISFILE);
+ jboolean r = S_ISDIR (sb.st_mode);
+ return query == DIRECTORY ? r : ! r;
+#else
+ return false;
+#endif
+}
+
+jlong
+java::io::File::attr (jint query)
+{
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+#ifdef HAVE_STAT
+ struct stat sb;
+ // FIXME: not sure about return value here.
+ if (::stat (buf, &sb))
+ return 0;
+
+ JvAssert (query == MODIFIED || query == LENGTH);
+ return query == MODIFIED ? (jlong)sb.st_mtime * 1000 : sb.st_size;
+#else
+ // There's no good choice here.
+ return 23;
+#endif
+}
+
+// These two methods are used to maintain dynamically allocated
+// buffers for getCanonicalPath without the overhead of calling
+// realloc every time a buffer is modified. Buffers are sized
+// at the smallest multiple of CHUNKSIZ that is greater than or
+// equal to the desired length. The default CHUNKSIZ is 256,
+// longer than most paths, so in most cases a getCanonicalPath
+// will require only one malloc per buffer.
+
+#define CHUNKLOG 8
+#define CHUNKSIZ (1 << CHUNKLOG)
+
+static int
+nextChunkSize (int size)
+{
+ return ((size >> CHUNKLOG) + ((size & (CHUNKSIZ - 1)) ? 1 : 0)) << CHUNKLOG;
+}
+
+static char *
+maybeGrowBuf (char *buf, int *size, int required)
+{
+ if (required > *size)
+ {
+ *size = nextChunkSize (required);
+ buf = (char *) _Jv_Realloc (buf, *size);
+ }
+ return buf;
+}
+
+// Return a canonical representation of the pathname of this file. On
+// the GNU system this involves the removal of redundant separators,
+// references to "." and "..", and symbolic links.
+//
+// The conversion proceeds on a component-by-component basis: symbolic
+// links and references to ".." are resolved as and when they occur.
+// This means that if "/foo/bar" is a symbolic link to "/baz" then the
+// canonical form of "/foo/bar/.." is "/" and not "/foo".
+//
+// In order to mimic the behaviour of proprietary JVMs, non-existant
+// path components are allowed (a departure from the normal GNU system
+// convention). This means that if "/foo/bar" is a symbolic link to
+// "/baz", the canonical form of "/non-existant-directory/../foo/bar"
+// is "/baz".
+
+jstring
+java::io::File::getCanonicalPath (void)
+{
+ jstring path = getAbsolutePath ();
+
+ int len = JvGetStringUTFLength (path);
+ int srcl = nextChunkSize (len + 1);
+ char *src = (char *) _Jv_Malloc (srcl);
+ JvGetStringUTFRegion (path, 0, path->length(), src);
+ src[len] = '\0';
+ int srci = 1;
+
+ int dstl = nextChunkSize (2);
+ char *dst = (char *) _Jv_Malloc (dstl);
+ dst[0] = '/';
+ int dsti = 1;
+
+ bool fschecks = true;
+
+ while (src[srci] != '\0')
+ {
+ // Skip slashes.
+ while (src[srci] == '/')
+ srci++;
+ int tmpi = srci;
+ // Find next slash.
+ while (src[srci] != '/' && src[srci] != '\0')
+ srci++;
+ if (srci == tmpi)
+ // We hit the end.
+ break;
+ len = srci - tmpi;
+
+ // Handle "." and "..".
+ if (len == 1 && src[tmpi] == '.')
+ continue;
+ if (len == 2 && src[tmpi] == '.' && src[tmpi + 1] == '.')
+ {
+ while (dsti > 1 && dst[dsti - 1] != '/')
+ dsti--;
+ if (dsti != 1)
+ dsti--;
+ // Reenable filesystem checking if disabled, as we might
+ // have reversed over whatever caused the problem before.
+ // At least one proprietary JVM has inconsistencies because
+ // it does not do this.
+ fschecks = true;
+ continue;
+ }
+
+ // Handle real path components.
+ dst = maybeGrowBuf (dst, &dstl, dsti + (dsti > 1 ? 1 : 0) + len + 1);
+ int dsti_save = dsti;
+ if (dsti > 1)
+ dst[dsti++] = '/';
+ strncpy (&dst[dsti], &src[tmpi], len);
+ dsti += len;
+ if (fschecks == false)
+ continue;
+
+#if defined (HAVE_LSTAT) && defined (HAVE_READLINK)
+ struct stat sb;
+ dst[dsti] = '\0';
+ if (::lstat (dst, &sb) == 0)
+ {
+ if (S_ISLNK (sb.st_mode))
+ {
+ int tmpl = CHUNKSIZ;
+ char *tmp = (char *) _Jv_Malloc (tmpl);
+
+ while (1)
+ {
+ tmpi = ::readlink (dst, tmp, tmpl);
+ if (tmpi < 1)
+ {
+ _Jv_Free (src);
+ _Jv_Free (dst);
+ _Jv_Free (tmp);
+ throw new IOException (
+ JvNewStringLatin1 ("readlink failed"));
+ }
+ if (tmpi < tmpl)
+ break;
+ tmpl += CHUNKSIZ;
+ tmp = (char *) _Jv_Realloc (tmp, tmpl);
+ }
+
+ // Prepend the link's path to src.
+ tmp = maybeGrowBuf (tmp, &tmpl, tmpi + strlen (&src[srci]) + 1);
+ strcpy(&tmp[tmpi], &src[srci]);
+ _Jv_Free (src);
+ src = tmp;
+ srcl = tmpl;
+ srci = 0;
+
+ // Either replace or append dst depending on whether the
+ // link is relative or absolute.
+ dsti = src[0] == '/' ? 1 : dsti_save;
+ }
+ }
+ else
+ {
+ // Something doesn't exist, or we don't have permission to
+ // read it, or a previous path component is a directory, or
+ // a symlink is looped. Whatever, we can't check the
+ // filesystem any more.
+ fschecks = false;
+ }
+#endif // HAVE_LSTAT && HAVE_READLINK
+ }
+ dst[dsti] = '\0';
+
+ // FIXME: what encoding to assume for file names? This affects many
+ // calls.
+ path = JvNewStringUTF (dst);
+ _Jv_Free (src);
+ _Jv_Free (dst);
+ return path;
+}
+
+jboolean
+java::io::File::isAbsolute (void)
+{
+ return path->length() > 0 && path->charAt(0) == '/';
+}
+
+jobjectArray
+java::io::File::performList (java::io::FilenameFilter *filter,
+ java::io::FileFilter *fileFilter,
+ java::lang::Class *result_type)
+{
+ /* Some systems have dirent.h, but no directory reading functions like
+ opendir. */
+#if defined(HAVE_DIRENT_H) && defined(HAVE_OPENDIR)
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+ DIR *dir = opendir (buf);
+ if (! dir)
+ return NULL;
+
+ java::util::ArrayList *list = new java::util::ArrayList ();
+ struct dirent *d;
+#if defined(HAVE_READDIR_R) && defined(_POSIX_PTHREAD_SEMANTICS)
+ int name_max = pathconf (buf, _PC_NAME_MAX);
+ char dbuf[sizeof (struct dirent) + name_max + 1];
+ while (readdir_r (dir, (struct dirent *) dbuf, &d) == 0 && d != NULL)
+#else /* HAVE_READDIR_R */
+ while ((d = readdir (dir)) != NULL)
+#endif /* HAVE_READDIR_R */
+ {
+ // Omit "." and "..".
+ if (d->d_name[0] == '.'
+ && (d->d_name[1] == '\0'
+ || (d->d_name[1] == '.' && d->d_name[2] == '\0')))
+ continue;
+
+ jstring name = JvNewStringUTF (d->d_name);
+ if (filter && ! filter->accept(this, name))
+ continue;
+
+ if (result_type == &java::io::File::class$)
+ {
+ java::io::File *file = new java::io::File (this, name);
+ if (fileFilter && ! fileFilter->accept(file))
+ continue;
+
+ list->add(file);
+ }
+ else
+ list->add(name);
+ }
+
+ closedir (dir);
+
+ jobjectArray ret = JvNewObjectArray (list->size(), result_type, NULL);
+ list->toArray(ret);
+ return ret;
+#else /* HAVE_DIRENT_H && HAVE_OPENDIR */
+ return NULL;
+#endif /* HAVE_DIRENT_H && HAVE_OPENDIR */
+}
+
+jboolean
+java::io::File::performMkdir (void)
+{
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+#ifdef HAVE_MKDIR
+ return ::mkdir (buf, 0755) == 0;
+#else
+ return false;
+#endif
+}
+
+jboolean
+java::io::File::performSetReadOnly (void)
+{
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+#if defined (HAVE_STAT) && defined (HAVE_CHMOD)
+ struct stat sb;
+ if (::stat (buf, &sb))
+ return false;
+
+ if (::chmod(buf, sb.st_mode & 0555))
+ return false;
+ return true;
+#else
+ return false;
+#endif
+}
+
+JArray< ::java::io::File *>*
+java::io::File::performListRoots ()
+{
+ ::java::io::File *f = new ::java::io::File (JvNewStringLatin1 ("/"));
+ JArray<java::io::File *> *unixroot
+ = reinterpret_cast <JArray<java::io::File *>*>
+ (JvNewObjectArray (1, &java::io::File::class$, f));
+ elements (unixroot) [0] = f;
+ return unixroot;
+}
+
+jboolean
+java::io::File::performRenameTo (File *dest)
+{
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+ char *buf2
+ = (char *) __builtin_alloca (JvGetStringUTFLength (dest->path) + 1);
+ total = JvGetStringUTFRegion (dest->path, 0, dest->path->length(), buf2);
+ buf2[total] = '\0';
+
+#ifdef HAVE_RENAME
+ return ::rename (buf, buf2) == 0;
+#else
+ return false;
+#endif
+}
+
+jboolean
+java::io::File::performSetLastModified (jlong time)
+{
+#ifdef HAVE_UTIME
+ utimbuf tb;
+
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+ tb.actime = time / 1000;
+ tb.modtime = time / 1000;
+ return (::utime (buf, &tb) == 0);
+#else
+ return false;
+#endif
+}
+
+jboolean
+java::io::File::performCreate (void)
+{
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+ int fd = ::open (buf, O_CREAT | O_EXCL, 0644);
+
+ if (fd < 0)
+ {
+ if (errno == EEXIST)
+ return false;
+ throw new IOException (JvNewStringLatin1 (strerror (errno)));
+ }
+ else
+ {
+ ::close (fd);
+ return true;
+ }
+}
+
+jboolean
+java::io::File::performDelete (void)
+{
+ char *buf = (char *) __builtin_alloca (JvGetStringUTFLength (path) + 1);
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf);
+ buf[total] = '\0';
+
+#ifdef HAVE_UNLINK
+#ifdef HAVE_RMDIR
+ if (! ::rmdir (buf))
+ return true;
+ if (errno == ENOTDIR)
+#endif // HAVE_RMDIR
+ return ::unlink (buf) == 0;
+#endif // HAVE_UNLINK
+ return false;
+}
+
+void
+java::io::File::init_native ()
+{
+ maxPathLen = MAXPATHLEN;
+ caseSensitive = true;
+}
diff --git a/gcc-4.2.1/libjava/java/io/natFileWin32.cc b/gcc-4.2.1/libjava/java/io/natFileWin32.cc
new file mode 100644
index 000000000..cff86dda7
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/natFileWin32.cc
@@ -0,0 +1,351 @@
+// natFileWin32.cc - Native part of File class for Win32.
+
+/* Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#undef STRICT
+
+#include <java/io/File.h>
+#include <java/io/IOException.h>
+#include <java/util/Vector.h>
+#include <java/lang/String.h>
+#include <java/io/FilenameFilter.h>
+#include <java/io/FileFilter.h>
+#include <java/lang/System.h>
+
+// Java timestamps are milliseconds since the UNIX epoch (00:00:00 UTC on
+// January 1, 1970) while Win32 file-times are 100-nanosecond intervals
+// since the Win32 epoch (00:00:00 UTC on January 1, 1601). The following
+// constant represents the number of milliseconds to be added to a
+// Java timestamp to base it on the Win32 epoch.
+//
+// There were 369 years between 1601 and 1970, including 89 leap years
+// (since 1700, 1800 and 1900 were not leap years):
+//
+// (89*366 + 280*365) days * 86400 seconds/day = 11644473600 seconds
+//
+#define WIN32_EPOCH_MILLIS 11644473600000LL
+
+jboolean
+java::io::File::_access (jint query)
+{
+ JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
+ if (!canon)
+ return false;
+
+ JvAssert (query == READ || query == WRITE || query == EXISTS);
+
+ // FIXME: Is it possible to differentiate between existing and reading?
+ // If the file exists but cannot be read because of the secuirty attributes
+ // on an NTFS disk this wont work (it reports it can be read but cant)
+ // Could we use something from the security API?
+ DWORD attributes = GetFileAttributes (canon);
+ if ((query == EXISTS) || (query == READ))
+ return (attributes == 0xffffffff) ? false : true;
+ else
+ return ((attributes != 0xffffffff) &&
+ ((attributes & FILE_ATTRIBUTE_READONLY) == 0)) ? true : false;
+}
+
+jboolean
+java::io::File::_stat (jint query)
+{
+ JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
+ if (!canon)
+ return false;
+
+ JvAssert (query == DIRECTORY || query == ISFILE);
+
+ DWORD attributes = GetFileAttributes (canon);
+ if (attributes == 0xffffffff)
+ return false;
+
+ if (query == DIRECTORY)
+ return attributes & FILE_ATTRIBUTE_DIRECTORY ? true : false;
+ else
+ return attributes & FILE_ATTRIBUTE_DIRECTORY ? false : true;
+}
+
+jlong
+java::io::File::attr (jint query)
+{
+ JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
+ if (!canon)
+ return false;
+
+ JvAssert (query == MODIFIED || query == LENGTH);
+
+ WIN32_FIND_DATA info;
+ HANDLE sHandle;
+ if ( ( sHandle = FindFirstFile( canon, &info)) == INVALID_HANDLE_VALUE)
+ return 0;
+
+ FindClose( sHandle);
+
+ if (query == LENGTH)
+ return ((long long)info.nFileSizeHigh) << 32
+ | (unsigned long long)info.nFileSizeLow;
+ else
+ {
+ // The file time as returned by Windows is in terms of the number
+ // of 100-nanosecond intervals since 00:00:00 UTC, January 1, 1601.
+ return (((((long long)info.ftLastWriteTime.dwHighDateTime) << 32)
+ | ((unsigned long long)info.ftLastWriteTime.dwLowDateTime))
+ - WIN32_EPOCH_MILLIS*10000LL) / 10000LL;
+ }
+}
+
+jstring
+java::io::File::getCanonicalPath (void)
+{
+ JV_TEMP_STRING_WIN32 (cpath, path);
+
+ // If the filename is blank, use the current directory.
+ LPCTSTR thepath = cpath.buf();
+ if (*thepath == 0)
+ thepath = _T(".");
+
+ LPTSTR unused;
+ TCHAR buf2[MAX_PATH];
+ if(!GetFullPathName(thepath, MAX_PATH, buf2, &unused))
+ throw new IOException (JvNewStringLatin1 ("GetFullPathName failed"));
+
+ return _Jv_Win32NewString (buf2);
+}
+
+jboolean
+java::io::File::isAbsolute (void)
+{
+ // See if the path represents a Windows UNC network path.
+ if (path->length () > 2
+ && (path->charAt (0) == '\\') && (path->charAt (1) == '\\'))
+ return true;
+
+ // Note that the path is not an absolute path even if it starts with
+ // a '/' or a '\' because it lacks a drive specifier.
+
+ if (path->length() < 3)
+ return false;
+ // Hard-code A-Za-z because Windows (I think) can't use non-ASCII
+ // letters as drive names.
+ if ((path->charAt(0) < 'a' || path->charAt(0) > 'z')
+ && (path->charAt(0) < 'A' || path->charAt(0) > 'Z'))
+ return false;
+ return (path->charAt(1) == ':'
+ && (path->charAt(2) == '/' || path->charAt(2) == '\\'));
+}
+
+void java::io::File::init_native ()
+{
+ maxPathLen = MAX_PATH;
+ caseSensitive = false;
+}
+
+jobjectArray
+java::io::File::performList (java::io::FilenameFilter *filter,
+ java::io::FileFilter *fileFilter,
+ java::lang::Class *clazz)
+{
+ jstring canon = getCanonicalPath();
+ if (! canon)
+ return NULL;
+
+ int len = canon->length();
+ TCHAR buf[len + 5];
+
+ JV_TEMP_STRING_WIN32(canonstr, canon);
+
+ _tcscpy(buf, canonstr);
+ if (buf[len - 1] == _T('\\'))
+ _tcscpy (&buf[len], _T("*.*"));
+ else
+ _tcscpy (&buf[len], _T("\\*.*"));
+
+ WIN32_FIND_DATA data;
+ HANDLE handle = FindFirstFile (buf, &data);
+ if (handle == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ java::util::Vector *vec = new java::util::Vector ();
+
+ do
+ {
+ if (_tcscmp (data.cFileName, _T(".")) &&
+ _tcscmp (data.cFileName, _T("..")))
+ {
+ jstring name = _Jv_Win32NewString (data.cFileName);
+
+ if (filter && !filter->accept(this, name))
+ continue;
+ if (clazz == &java::io::File::class$)
+ {
+ java::io::File *file = new java::io::File (this, name);
+ if (fileFilter && !fileFilter->accept(file))
+ continue;
+ vec->addElement (file);
+ }
+ else
+ vec->addElement (name);
+ }
+ }
+ while (FindNextFile (handle, &data));
+
+ if (GetLastError () != ERROR_NO_MORE_FILES)
+ return NULL;
+
+ FindClose (handle);
+
+ jobjectArray ret = JvNewObjectArray (vec->size(), clazz, NULL);
+ vec->copyInto (ret);
+ return ret;
+}
+
+jboolean
+java::io::File::performMkdir (void)
+{
+ JV_TEMP_STRING_WIN32 (cpath, path);
+ return (CreateDirectory(cpath, NULL)) ? true : false;
+}
+
+jboolean
+java::io::File::performRenameTo (File *dest)
+{
+ JV_TEMP_STRING_WIN32 (pathFrom, path);
+ JV_TEMP_STRING_WIN32 (pathTo, dest->path);
+ return (MoveFile(pathFrom, pathTo)) ? true : false;
+}
+
+jboolean
+java::io::File::performDelete ()
+{
+ JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
+ if (!canon)
+ return false;
+
+ DWORD attributes = GetFileAttributes (canon);
+ if (attributes == 0xffffffff)
+ return false;
+
+ if (attributes & FILE_ATTRIBUTE_DIRECTORY)
+ return (RemoveDirectory (canon)) ? true : false;
+ else
+ return (DeleteFile (canon)) ? true : false;
+}
+
+jboolean java::io::File::performCreate (void)
+{
+ JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
+ if (!canon)
+ return false;
+
+ HANDLE h = CreateFile (canon, 0, 0, NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle (h);
+ return true;
+ }
+ else
+ {
+ if (GetLastError () == ERROR_ALREADY_EXISTS)
+ return false;
+ else
+ throw new IOException (JvNewStringLatin1 ("CreateFile failed"));
+ }
+}
+
+jboolean java::io::File::performSetReadOnly ()
+{
+ JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
+ if (!canon)
+ return false;
+
+ DWORD attrs = GetFileAttributes (canon);
+ if (attrs != INVALID_FILE_ATTRIBUTES)
+ {
+ if (SetFileAttributes (canon, attrs | FILE_ATTRIBUTE_READONLY) != 0)
+ return true;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+jboolean java::io::File::performSetLastModified (jlong time)
+{
+ JV_TEMP_STRING_WIN32 (canon, getCanonicalPath());
+ if (!canon)
+ return false;
+
+ FILETIME modTime;
+ long long mTime100ns = ((long long) time /* Ha! */
+ + WIN32_EPOCH_MILLIS) * 10000LL;
+
+ modTime.dwLowDateTime = (DWORD) mTime100ns;
+ modTime.dwHighDateTime = (DWORD) (mTime100ns >> 32);
+
+ jboolean retVal = false;
+ HANDLE h = CreateFile (canon, FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ if (SetFileTime (h, NULL, &modTime, &modTime) != 0)
+ retVal = true;
+
+ CloseHandle (h);
+ }
+
+ return retVal;
+}
+
+JArray<java::io::File*>* java::io::File::performListRoots ()
+{
+ DWORD drivesBitmap = GetLogicalDrives ();
+ DWORD mask;
+
+ // Possible drive letters are from ASCII 'A'-'Z'.
+ int numDrives = 0;
+ mask = 1;
+ for (int i = 0; i < 26; i++)
+ {
+ if ((drivesBitmap & mask) != 0)
+ numDrives++;
+ mask <<= 1;
+ }
+
+ JArray<java::io::File *> *roots
+ = reinterpret_cast <JArray<java::io::File *>*>
+ (JvNewObjectArray (numDrives, &java::io::File::class$, NULL));
+
+ ::java::io::File **rootsArray = elements (roots);
+
+ char aDriveRoot[] = {'A', ':', '\\', '\0'};
+ mask = 1;
+ for (int i = 0, j = 0; i < 26; i++)
+ {
+ if ((drivesBitmap & mask) != 0)
+ {
+ rootsArray[j]
+ = new ::java::io::File (JvNewStringLatin1 (aDriveRoot));
+ j++;
+ }
+ mask <<= 1;
+ aDriveRoot[0]++;
+ }
+
+ return roots;
+}
diff --git a/gcc-4.2.1/libjava/java/io/natObjectInputStream.cc b/gcc-4.2.1/libjava/java/io/natObjectInputStream.cc
new file mode 100644
index 000000000..2d1a55665
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/natObjectInputStream.cc
@@ -0,0 +1,80 @@
+// natObjectInputStream.cc - Native part of ObjectInputStream class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2005 Free Software Foundation
+
+ This ObjectInputStream is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the ObjectInputStream "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <gcj/method.h>
+
+#include <java/io/ObjectInputStream$GetField.h>
+#include <java/io/ObjectInputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/Class.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/Method.h>
+#include <java-stack.h>
+
+#ifdef DEBUG
+#include <java/lang/System.h>
+#include <java/io/PrintStream.h>
+#endif
+
+jobject
+java::io::ObjectInputStream::allocateObject (jclass klass, jclass,
+ ::java::lang::reflect::Constructor *ctr)
+{
+ jobject obj = NULL;
+ using namespace java::lang::reflect;
+
+ try
+ {
+ JvAssert (klass && ! klass->isArray ());
+ if (klass->isInterface() || Modifier::isAbstract(klass->getModifiers()))
+ obj = NULL;
+ else
+ {
+ obj = _Jv_AllocObject (klass);
+ }
+ }
+ catch (jthrowable t)
+ {
+ return NULL;
+ }
+
+ jmethodID meth = _Jv_FromReflectedConstructor (ctr);
+
+ // This is a bit inefficient, and a bit of a hack, since we don't
+ // actually use the Method and since what is returned isn't
+ // technically a Method. We can't use Method.invoke as it looks up
+ // the declared method.
+ JArray<jclass> *arg_types
+ = (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$,
+ NULL);
+
+ // We lie about this being a constructor. If we put `true' here
+ // then _Jv_CallAnyMethodA would try to allocate the object for us.
+ _Jv_CallAnyMethodA (obj, JvPrimClass (void), meth, false, arg_types, NULL);
+
+ return obj;
+}
+
+java::lang::ClassLoader *
+java::io::ObjectInputStream::currentLoader ()
+{
+ jclass caller = _Jv_StackTrace::GetCallingClass (&ObjectInputStream::class$);
+ if (caller)
+ return caller->getClassLoaderInternal();
+ return NULL;
+}
diff --git a/gcc-4.2.1/libjava/java/io/natVMObjectStreamClass.cc b/gcc-4.2.1/libjava/java/io/natVMObjectStreamClass.cc
new file mode 100644
index 000000000..847b540f0
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/io/natVMObjectStreamClass.cc
@@ -0,0 +1,87 @@
+// natVMObjectStreamClass.cc - Native part of VMObjectStreamClass class.
+
+/* Copyright (C) 2003 Free Software Foundation
+
+ This VMObjectStreamClass is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the ObjectInputStream "LIBGCJ_LICENSE" for
+details. */
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/io/VMObjectStreamClass.h>
+#include <java/lang/Class.h>
+#include <java/lang/reflect/Field.h>
+
+using namespace java::lang::reflect;
+
+jboolean
+java::io::VMObjectStreamClass::hasClassInitializer (jclass klass)
+{
+ if (klass->isPrimitive())
+ return false;
+ _Jv_Method *meth = _Jv_GetMethodLocal(klass, gcj::clinit_name,
+ gcj::void_signature);
+ return (meth != NULL);
+}
+
+void
+java::io::VMObjectStreamClass::setDoubleNative (Field *f, jobject obj,
+ jdouble val)
+{
+ f->setDouble (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setFloatNative (Field *f, jobject obj,
+ jfloat val)
+{
+ f->setFloat (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setLongNative (Field *f, jobject obj, jlong val)
+{
+ f->setLong (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setIntNative (Field *f, jobject obj, jint val)
+{
+ f->setInt (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setShortNative (Field *f, jobject obj,
+ jshort val)
+{
+ f->setShort (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setCharNative (Field *f, jobject obj, jchar val)
+{
+ f->setChar (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setByteNative (Field *f, jobject obj, jbyte val)
+{
+ f->setByte (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setBooleanNative (Field *f, jobject obj,
+ jboolean val)
+{
+ f->setBoolean (NULL, obj, val, false);
+}
+
+void
+java::io::VMObjectStreamClass::setObjectNative (Field *f, jobject obj,
+ jobject val)
+{
+ f->set (NULL, obj, val, f->getType(), false);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/Character.java b/gcc-4.2.1/libjava/java/lang/Character.java
new file mode 100644
index 000000000..ec6d2a4af
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Character.java
@@ -0,0 +1,3867 @@
+/* java.lang.Character -- Wrapper class for char, and Unicode subsets
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 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. */
+
+/*
+ * Note: This class must not be merged with Classpath. Gcj uses C-style
+ * arrays (see include/java-chartables.h) to store the Unicode character
+ * database, whereas Classpath uses Java objects (char[] extracted from
+ * String constants) in gnu.java.lang.CharData. Gcj's approach is more
+ * efficient, because there is no vtable or data relocation to worry about.
+ * However, despite the difference in the database interface, the two
+ * versions share identical algorithms.
+ */
+
+package java.lang;
+
+import java.io.Serializable;
+import java.text.Collator;
+import java.util.Locale;
+
+/**
+ * Wrapper class for the primitive char data type. In addition, this class
+ * allows one to retrieve property information and perform transformations
+ * on the 57,707 defined characters in the Unicode Standard, Version 3.0.0.
+ * java.lang.Character is designed to be very dynamic, and as such, it
+ * retrieves information on the Unicode character set from a separate
+ * database, gnu.java.lang.CharData, which can be easily upgraded.
+ *
+ * <p>For predicates, boundaries are used to describe
+ * the set of characters for which the method will return true.
+ * This syntax uses fairly normal regular expression notation.
+ * See 5.13 of the Unicode Standard, Version 3.0, for the
+ * boundary specification.
+ *
+ * <p>See <a href="http://www.unicode.org">http://www.unicode.org</a>
+ * for more information on the Unicode Standard.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Paul N. Fisher
+ * @author Jochen Hoenicke
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class Character implements Serializable, Comparable
+{
+ /**
+ * A subset of Unicode blocks.
+ *
+ * @author Paul N. Fisher
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.2
+ */
+ public static class Subset
+ {
+ /** The name of the subset. */
+ private final String name;
+
+ /**
+ * Construct a new subset of characters.
+ *
+ * @param name the name of the subset
+ * @throws NullPointerException if name is null
+ */
+ protected Subset(String name)
+ {
+ // Note that name.toString() is name, unless name was null.
+ this.name = name.toString();
+ }
+
+ /**
+ * Compares two Subsets for equality. This is <code>final</code>, and
+ * restricts the comparison on the <code>==</code> operator, so it returns
+ * true only for the same object.
+ *
+ * @param o the object to compare
+ * @return true if o is this
+ */
+ public final boolean equals(Object o)
+ {
+ return o == this;
+ }
+
+ /**
+ * Makes the original hashCode of Object final, to be consistent with
+ * equals.
+ *
+ * @return the hash code for this object
+ */
+ public final int hashCode()
+ {
+ return super.hashCode();
+ }
+
+ /**
+ * Returns the name of the subset.
+ *
+ * @return the name
+ */
+ public final String toString()
+ {
+ return name;
+ }
+ } // class Subset
+
+ /**
+ * A family of character subsets in the Unicode specification. A character
+ * is in at most one of these blocks.
+ *
+ * This inner class was generated automatically from
+ * <code>libjava/gnu/gcj/convert/Blocks-3.txt</code>, by some perl scripts.
+ * This Unicode definition file can be found on the
+ * <a href="http://www.unicode.org">http://www.unicode.org</a> website.
+ * JDK 1.4 uses Unicode version 3.0.0.
+ *
+ * @author scripts/unicode-blocks.pl (written by Eric Blake)
+ * @since 1.2
+ */
+ public static final class UnicodeBlock extends Subset
+ {
+ /** The start of the subset. */
+ private final int start;
+
+ /** The end of the subset. */
+ private final int end;
+
+ /** The canonical name of the block according to the Unicode standard. */
+ private final String canonicalName;
+
+ /** Constants for the <code>forName()</code> method */
+ private static final int CANONICAL_NAME = 0;
+ private static final int NO_SPACES_NAME = 1;
+ private static final int CONSTANT_NAME = 2;
+
+ /**
+ * Constructor for strictly defined blocks.
+ *
+ * @param start the start character of the range
+ * @param end the end character of the range
+ * @param name the block name
+ */
+ private UnicodeBlock(int start, int end, String name,
+ String canonicalName)
+ {
+ super(name);
+ this.start = start;
+ this.end = end;
+ this.canonicalName = canonicalName;
+ }
+
+ /**
+ * Returns the Unicode character block which a character belongs to.
+ * <strong>Note</strong>: This method does not support the use of
+ * supplementary characters. For such support, <code>of(int)</code>
+ * should be used instead.
+ *
+ * @param ch the character to look up
+ * @return the set it belongs to, or null if it is not in one
+ */
+ public static UnicodeBlock of(char ch)
+ {
+ return of((int) ch);
+ }
+
+ /**
+ * Returns the Unicode character block which a code point belongs to.
+ *
+ * @param codePoint the character to look up
+ * @return the set it belongs to, or null if it is not in one.
+ * @throws IllegalArgumentException if the specified code point is
+ * invalid.
+ * @since 1.5
+ */
+ public static UnicodeBlock of(int codePoint)
+ {
+ if (codePoint > MAX_CODE_POINT)
+ throw new IllegalArgumentException("The supplied integer value is " +
+ "too large to be a codepoint.");
+ // Simple binary search for the correct block.
+ int low = 0;
+ int hi = sets.length - 1;
+ while (low <= hi)
+ {
+ int mid = (low + hi) >> 1;
+ UnicodeBlock b = sets[mid];
+ if (codePoint < b.start)
+ hi = mid - 1;
+ else if (codePoint > b.end)
+ low = mid + 1;
+ else
+ return b;
+ }
+ return null;
+ }
+
+ /**
+ * <p>
+ * Returns the <code>UnicodeBlock</code> with the given name, as defined
+ * by the Unicode standard. The version of Unicode in use is defined by
+ * the <code>Character</code> class, and the names are given in the
+ * <code>Blocks-<version>.txt</code> file corresponding to that version.
+ * The name may be specified in one of three ways:
+ * </p>
+ * <ol>
+ * <li>The canonical, human-readable name used by the Unicode standard.
+ * This is the name with all spaces and hyphens retained. For example,
+ * `Basic Latin' retrieves the block, UnicodeBlock.BASIC_LATIN.</li>
+ * <li>The canonical name with all spaces removed e.g. `BasicLatin'.</li>
+ * <li>The name used for the constants specified by this class, which
+ * is the canonical name with all spaces and hyphens replaced with
+ * underscores e.g. `BASIC_LATIN'</li>
+ * </ol>
+ * <p>
+ * The names are compared case-insensitively using the case comparison
+ * associated with the U.S. English locale. The method recognises the
+ * previous names used for blocks as well as the current ones. At
+ * present, this simply means that the deprecated `SURROGATES_AREA'
+ * will be recognised by this method (the <code>of()</code> methods
+ * only return one of the three new surrogate blocks).
+ * </p>
+ *
+ * @param blockName the name of the block to look up.
+ * @return the specified block.
+ * @throws NullPointerException if the <code>blockName</code> is
+ * <code>null</code>.
+ * @throws IllegalArgumentException if the name does not match any Unicode
+ * block.
+ * @since 1.5
+ */
+ public static final UnicodeBlock forName(String blockName)
+ {
+ int type;
+ if (blockName.indexOf(' ') != -1)
+ type = CANONICAL_NAME;
+ else if (blockName.indexOf('_') != -1)
+ type = CONSTANT_NAME;
+ else
+ type = NO_SPACES_NAME;
+ Collator usCollator = Collator.getInstance(Locale.US);
+ usCollator.setStrength(Collator.PRIMARY);
+ /* Special case for deprecated blocks not in sets */
+ switch (type)
+ {
+ case CANONICAL_NAME:
+ if (usCollator.compare(blockName, "Surrogates Area") == 0)
+ return SURROGATES_AREA;
+ break;
+ case NO_SPACES_NAME:
+ if (usCollator.compare(blockName, "SurrogatesArea") == 0)
+ return SURROGATES_AREA;
+ break;
+ case CONSTANT_NAME:
+ if (usCollator.compare(blockName, "SURROGATES_AREA") == 0)
+ return SURROGATES_AREA;
+ break;
+ }
+ /* Other cases */
+ int setLength = sets.length;
+ switch (type)
+ {
+ case CANONICAL_NAME:
+ for (int i = 0; i < setLength; i++)
+ {
+ UnicodeBlock block = sets[i];
+ if (usCollator.compare(blockName, block.canonicalName) == 0)
+ return block;
+ }
+ break;
+ case NO_SPACES_NAME:
+ for (int i = 0; i < setLength; i++)
+ {
+ UnicodeBlock block = sets[i];
+ String nsName = block.canonicalName.replaceAll(" ","");
+ if (usCollator.compare(blockName, nsName) == 0)
+ return block;
+ }
+ break;
+ case CONSTANT_NAME:
+ for (int i = 0; i < setLength; i++)
+ {
+ UnicodeBlock block = sets[i];
+ if (usCollator.compare(blockName, block.toString()) == 0)
+ return block;
+ }
+ break;
+ }
+ throw new IllegalArgumentException("No Unicode block found for " +
+ blockName + ".");
+ }
+
+ /**
+ * Basic Latin.
+ * 0x0000 - 0x007F.
+ */
+ public static final UnicodeBlock BASIC_LATIN
+ = new UnicodeBlock(0x0000, 0x007F,
+ "BASIC_LATIN",
+ "Basic Latin");
+
+ /**
+ * Latin-1 Supplement.
+ * 0x0080 - 0x00FF.
+ */
+ public static final UnicodeBlock LATIN_1_SUPPLEMENT
+ = new UnicodeBlock(0x0080, 0x00FF,
+ "LATIN_1_SUPPLEMENT",
+ "Latin-1 Supplement");
+
+ /**
+ * Latin Extended-A.
+ * 0x0100 - 0x017F.
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_A
+ = new UnicodeBlock(0x0100, 0x017F,
+ "LATIN_EXTENDED_A",
+ "Latin Extended-A");
+
+ /**
+ * Latin Extended-B.
+ * 0x0180 - 0x024F.
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_B
+ = new UnicodeBlock(0x0180, 0x024F,
+ "LATIN_EXTENDED_B",
+ "Latin Extended-B");
+
+ /**
+ * IPA Extensions.
+ * 0x0250 - 0x02AF.
+ */
+ public static final UnicodeBlock IPA_EXTENSIONS
+ = new UnicodeBlock(0x0250, 0x02AF,
+ "IPA_EXTENSIONS",
+ "IPA Extensions");
+
+ /**
+ * Spacing Modifier Letters.
+ * 0x02B0 - 0x02FF.
+ */
+ public static final UnicodeBlock SPACING_MODIFIER_LETTERS
+ = new UnicodeBlock(0x02B0, 0x02FF,
+ "SPACING_MODIFIER_LETTERS",
+ "Spacing Modifier Letters");
+
+ /**
+ * Combining Diacritical Marks.
+ * 0x0300 - 0x036F.
+ */
+ public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS
+ = new UnicodeBlock(0x0300, 0x036F,
+ "COMBINING_DIACRITICAL_MARKS",
+ "Combining Diacritical Marks");
+
+ /**
+ * Greek.
+ * 0x0370 - 0x03FF.
+ */
+ public static final UnicodeBlock GREEK
+ = new UnicodeBlock(0x0370, 0x03FF,
+ "GREEK",
+ "Greek");
+
+ /**
+ * Cyrillic.
+ * 0x0400 - 0x04FF.
+ */
+ public static final UnicodeBlock CYRILLIC
+ = new UnicodeBlock(0x0400, 0x04FF,
+ "CYRILLIC",
+ "Cyrillic");
+
+ /**
+ * Cyrillic Supplementary.
+ * 0x0500 - 0x052F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY
+ = new UnicodeBlock(0x0500, 0x052F,
+ "CYRILLIC_SUPPLEMENTARY",
+ "Cyrillic Supplementary");
+
+ /**
+ * Armenian.
+ * 0x0530 - 0x058F.
+ */
+ public static final UnicodeBlock ARMENIAN
+ = new UnicodeBlock(0x0530, 0x058F,
+ "ARMENIAN",
+ "Armenian");
+
+ /**
+ * Hebrew.
+ * 0x0590 - 0x05FF.
+ */
+ public static final UnicodeBlock HEBREW
+ = new UnicodeBlock(0x0590, 0x05FF,
+ "HEBREW",
+ "Hebrew");
+
+ /**
+ * Arabic.
+ * 0x0600 - 0x06FF.
+ */
+ public static final UnicodeBlock ARABIC
+ = new UnicodeBlock(0x0600, 0x06FF,
+ "ARABIC",
+ "Arabic");
+
+ /**
+ * Syriac.
+ * 0x0700 - 0x074F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock SYRIAC
+ = new UnicodeBlock(0x0700, 0x074F,
+ "SYRIAC",
+ "Syriac");
+
+ /**
+ * Thaana.
+ * 0x0780 - 0x07BF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock THAANA
+ = new UnicodeBlock(0x0780, 0x07BF,
+ "THAANA",
+ "Thaana");
+
+ /**
+ * Devanagari.
+ * 0x0900 - 0x097F.
+ */
+ public static final UnicodeBlock DEVANAGARI
+ = new UnicodeBlock(0x0900, 0x097F,
+ "DEVANAGARI",
+ "Devanagari");
+
+ /**
+ * Bengali.
+ * 0x0980 - 0x09FF.
+ */
+ public static final UnicodeBlock BENGALI
+ = new UnicodeBlock(0x0980, 0x09FF,
+ "BENGALI",
+ "Bengali");
+
+ /**
+ * Gurmukhi.
+ * 0x0A00 - 0x0A7F.
+ */
+ public static final UnicodeBlock GURMUKHI
+ = new UnicodeBlock(0x0A00, 0x0A7F,
+ "GURMUKHI",
+ "Gurmukhi");
+
+ /**
+ * Gujarati.
+ * 0x0A80 - 0x0AFF.
+ */
+ public static final UnicodeBlock GUJARATI
+ = new UnicodeBlock(0x0A80, 0x0AFF,
+ "GUJARATI",
+ "Gujarati");
+
+ /**
+ * Oriya.
+ * 0x0B00 - 0x0B7F.
+ */
+ public static final UnicodeBlock ORIYA
+ = new UnicodeBlock(0x0B00, 0x0B7F,
+ "ORIYA",
+ "Oriya");
+
+ /**
+ * Tamil.
+ * 0x0B80 - 0x0BFF.
+ */
+ public static final UnicodeBlock TAMIL
+ = new UnicodeBlock(0x0B80, 0x0BFF,
+ "TAMIL",
+ "Tamil");
+
+ /**
+ * Telugu.
+ * 0x0C00 - 0x0C7F.
+ */
+ public static final UnicodeBlock TELUGU
+ = new UnicodeBlock(0x0C00, 0x0C7F,
+ "TELUGU",
+ "Telugu");
+
+ /**
+ * Kannada.
+ * 0x0C80 - 0x0CFF.
+ */
+ public static final UnicodeBlock KANNADA
+ = new UnicodeBlock(0x0C80, 0x0CFF,
+ "KANNADA",
+ "Kannada");
+
+ /**
+ * Malayalam.
+ * 0x0D00 - 0x0D7F.
+ */
+ public static final UnicodeBlock MALAYALAM
+ = new UnicodeBlock(0x0D00, 0x0D7F,
+ "MALAYALAM",
+ "Malayalam");
+
+ /**
+ * Sinhala.
+ * 0x0D80 - 0x0DFF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock SINHALA
+ = new UnicodeBlock(0x0D80, 0x0DFF,
+ "SINHALA",
+ "Sinhala");
+
+ /**
+ * Thai.
+ * 0x0E00 - 0x0E7F.
+ */
+ public static final UnicodeBlock THAI
+ = new UnicodeBlock(0x0E00, 0x0E7F,
+ "THAI",
+ "Thai");
+
+ /**
+ * Lao.
+ * 0x0E80 - 0x0EFF.
+ */
+ public static final UnicodeBlock LAO
+ = new UnicodeBlock(0x0E80, 0x0EFF,
+ "LAO",
+ "Lao");
+
+ /**
+ * Tibetan.
+ * 0x0F00 - 0x0FFF.
+ */
+ public static final UnicodeBlock TIBETAN
+ = new UnicodeBlock(0x0F00, 0x0FFF,
+ "TIBETAN",
+ "Tibetan");
+
+ /**
+ * Myanmar.
+ * 0x1000 - 0x109F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock MYANMAR
+ = new UnicodeBlock(0x1000, 0x109F,
+ "MYANMAR",
+ "Myanmar");
+
+ /**
+ * Georgian.
+ * 0x10A0 - 0x10FF.
+ */
+ public static final UnicodeBlock GEORGIAN
+ = new UnicodeBlock(0x10A0, 0x10FF,
+ "GEORGIAN",
+ "Georgian");
+
+ /**
+ * Hangul Jamo.
+ * 0x1100 - 0x11FF.
+ */
+ public static final UnicodeBlock HANGUL_JAMO
+ = new UnicodeBlock(0x1100, 0x11FF,
+ "HANGUL_JAMO",
+ "Hangul Jamo");
+
+ /**
+ * Ethiopic.
+ * 0x1200 - 0x137F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock ETHIOPIC
+ = new UnicodeBlock(0x1200, 0x137F,
+ "ETHIOPIC",
+ "Ethiopic");
+
+ /**
+ * Cherokee.
+ * 0x13A0 - 0x13FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CHEROKEE
+ = new UnicodeBlock(0x13A0, 0x13FF,
+ "CHEROKEE",
+ "Cherokee");
+
+ /**
+ * Unified Canadian Aboriginal Syllabics.
+ * 0x1400 - 0x167F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS
+ = new UnicodeBlock(0x1400, 0x167F,
+ "UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS",
+ "Unified Canadian Aboriginal Syllabics");
+
+ /**
+ * Ogham.
+ * 0x1680 - 0x169F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock OGHAM
+ = new UnicodeBlock(0x1680, 0x169F,
+ "OGHAM",
+ "Ogham");
+
+ /**
+ * Runic.
+ * 0x16A0 - 0x16FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock RUNIC
+ = new UnicodeBlock(0x16A0, 0x16FF,
+ "RUNIC",
+ "Runic");
+
+ /**
+ * Tagalog.
+ * 0x1700 - 0x171F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGALOG
+ = new UnicodeBlock(0x1700, 0x171F,
+ "TAGALOG",
+ "Tagalog");
+
+ /**
+ * Hanunoo.
+ * 0x1720 - 0x173F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock HANUNOO
+ = new UnicodeBlock(0x1720, 0x173F,
+ "HANUNOO",
+ "Hanunoo");
+
+ /**
+ * Buhid.
+ * 0x1740 - 0x175F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock BUHID
+ = new UnicodeBlock(0x1740, 0x175F,
+ "BUHID",
+ "Buhid");
+
+ /**
+ * Tagbanwa.
+ * 0x1760 - 0x177F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGBANWA
+ = new UnicodeBlock(0x1760, 0x177F,
+ "TAGBANWA",
+ "Tagbanwa");
+
+ /**
+ * Khmer.
+ * 0x1780 - 0x17FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock KHMER
+ = new UnicodeBlock(0x1780, 0x17FF,
+ "KHMER",
+ "Khmer");
+
+ /**
+ * Mongolian.
+ * 0x1800 - 0x18AF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock MONGOLIAN
+ = new UnicodeBlock(0x1800, 0x18AF,
+ "MONGOLIAN",
+ "Mongolian");
+
+ /**
+ * Limbu.
+ * 0x1900 - 0x194F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LIMBU
+ = new UnicodeBlock(0x1900, 0x194F,
+ "LIMBU",
+ "Limbu");
+
+ /**
+ * Tai Le.
+ * 0x1950 - 0x197F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAI_LE
+ = new UnicodeBlock(0x1950, 0x197F,
+ "TAI_LE",
+ "Tai Le");
+
+ /**
+ * Khmer Symbols.
+ * 0x19E0 - 0x19FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock KHMER_SYMBOLS
+ = new UnicodeBlock(0x19E0, 0x19FF,
+ "KHMER_SYMBOLS",
+ "Khmer Symbols");
+
+ /**
+ * Phonetic Extensions.
+ * 0x1D00 - 0x1D7F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock PHONETIC_EXTENSIONS
+ = new UnicodeBlock(0x1D00, 0x1D7F,
+ "PHONETIC_EXTENSIONS",
+ "Phonetic Extensions");
+
+ /**
+ * Latin Extended Additional.
+ * 0x1E00 - 0x1EFF.
+ */
+ public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL
+ = new UnicodeBlock(0x1E00, 0x1EFF,
+ "LATIN_EXTENDED_ADDITIONAL",
+ "Latin Extended Additional");
+
+ /**
+ * Greek Extended.
+ * 0x1F00 - 0x1FFF.
+ */
+ public static final UnicodeBlock GREEK_EXTENDED
+ = new UnicodeBlock(0x1F00, 0x1FFF,
+ "GREEK_EXTENDED",
+ "Greek Extended");
+
+ /**
+ * General Punctuation.
+ * 0x2000 - 0x206F.
+ */
+ public static final UnicodeBlock GENERAL_PUNCTUATION
+ = new UnicodeBlock(0x2000, 0x206F,
+ "GENERAL_PUNCTUATION",
+ "General Punctuation");
+
+ /**
+ * Superscripts and Subscripts.
+ * 0x2070 - 0x209F.
+ */
+ public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS
+ = new UnicodeBlock(0x2070, 0x209F,
+ "SUPERSCRIPTS_AND_SUBSCRIPTS",
+ "Superscripts and Subscripts");
+
+ /**
+ * Currency Symbols.
+ * 0x20A0 - 0x20CF.
+ */
+ public static final UnicodeBlock CURRENCY_SYMBOLS
+ = new UnicodeBlock(0x20A0, 0x20CF,
+ "CURRENCY_SYMBOLS",
+ "Currency Symbols");
+
+ /**
+ * Combining Marks for Symbols.
+ * 0x20D0 - 0x20FF.
+ */
+ public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS
+ = new UnicodeBlock(0x20D0, 0x20FF,
+ "COMBINING_MARKS_FOR_SYMBOLS",
+ "Combining Marks for Symbols");
+
+ /**
+ * Letterlike Symbols.
+ * 0x2100 - 0x214F.
+ */
+ public static final UnicodeBlock LETTERLIKE_SYMBOLS
+ = new UnicodeBlock(0x2100, 0x214F,
+ "LETTERLIKE_SYMBOLS",
+ "Letterlike Symbols");
+
+ /**
+ * Number Forms.
+ * 0x2150 - 0x218F.
+ */
+ public static final UnicodeBlock NUMBER_FORMS
+ = new UnicodeBlock(0x2150, 0x218F,
+ "NUMBER_FORMS",
+ "Number Forms");
+
+ /**
+ * Arrows.
+ * 0x2190 - 0x21FF.
+ */
+ public static final UnicodeBlock ARROWS
+ = new UnicodeBlock(0x2190, 0x21FF,
+ "ARROWS",
+ "Arrows");
+
+ /**
+ * Mathematical Operators.
+ * 0x2200 - 0x22FF.
+ */
+ public static final UnicodeBlock MATHEMATICAL_OPERATORS
+ = new UnicodeBlock(0x2200, 0x22FF,
+ "MATHEMATICAL_OPERATORS",
+ "Mathematical Operators");
+
+ /**
+ * Miscellaneous Technical.
+ * 0x2300 - 0x23FF.
+ */
+ public static final UnicodeBlock MISCELLANEOUS_TECHNICAL
+ = new UnicodeBlock(0x2300, 0x23FF,
+ "MISCELLANEOUS_TECHNICAL",
+ "Miscellaneous Technical");
+
+ /**
+ * Control Pictures.
+ * 0x2400 - 0x243F.
+ */
+ public static final UnicodeBlock CONTROL_PICTURES
+ = new UnicodeBlock(0x2400, 0x243F,
+ "CONTROL_PICTURES",
+ "Control Pictures");
+
+ /**
+ * Optical Character Recognition.
+ * 0x2440 - 0x245F.
+ */
+ public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION
+ = new UnicodeBlock(0x2440, 0x245F,
+ "OPTICAL_CHARACTER_RECOGNITION",
+ "Optical Character Recognition");
+
+ /**
+ * Enclosed Alphanumerics.
+ * 0x2460 - 0x24FF.
+ */
+ public static final UnicodeBlock ENCLOSED_ALPHANUMERICS
+ = new UnicodeBlock(0x2460, 0x24FF,
+ "ENCLOSED_ALPHANUMERICS",
+ "Enclosed Alphanumerics");
+
+ /**
+ * Box Drawing.
+ * 0x2500 - 0x257F.
+ */
+ public static final UnicodeBlock BOX_DRAWING
+ = new UnicodeBlock(0x2500, 0x257F,
+ "BOX_DRAWING",
+ "Box Drawing");
+
+ /**
+ * Block Elements.
+ * 0x2580 - 0x259F.
+ */
+ public static final UnicodeBlock BLOCK_ELEMENTS
+ = new UnicodeBlock(0x2580, 0x259F,
+ "BLOCK_ELEMENTS",
+ "Block Elements");
+
+ /**
+ * Geometric Shapes.
+ * 0x25A0 - 0x25FF.
+ */
+ public static final UnicodeBlock GEOMETRIC_SHAPES
+ = new UnicodeBlock(0x25A0, 0x25FF,
+ "GEOMETRIC_SHAPES",
+ "Geometric Shapes");
+
+ /**
+ * Miscellaneous Symbols.
+ * 0x2600 - 0x26FF.
+ */
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS
+ = new UnicodeBlock(0x2600, 0x26FF,
+ "MISCELLANEOUS_SYMBOLS",
+ "Miscellaneous Symbols");
+
+ /**
+ * Dingbats.
+ * 0x2700 - 0x27BF.
+ */
+ public static final UnicodeBlock DINGBATS
+ = new UnicodeBlock(0x2700, 0x27BF,
+ "DINGBATS",
+ "Dingbats");
+
+ /**
+ * Miscellaneous Mathematical Symbols-A.
+ * 0x27C0 - 0x27EF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A
+ = new UnicodeBlock(0x27C0, 0x27EF,
+ "MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A",
+ "Miscellaneous Mathematical Symbols-A");
+
+ /**
+ * Supplemental Arrows-A.
+ * 0x27F0 - 0x27FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A
+ = new UnicodeBlock(0x27F0, 0x27FF,
+ "SUPPLEMENTAL_ARROWS_A",
+ "Supplemental Arrows-A");
+
+ /**
+ * Braille Patterns.
+ * 0x2800 - 0x28FF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock BRAILLE_PATTERNS
+ = new UnicodeBlock(0x2800, 0x28FF,
+ "BRAILLE_PATTERNS",
+ "Braille Patterns");
+
+ /**
+ * Supplemental Arrows-B.
+ * 0x2900 - 0x297F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B
+ = new UnicodeBlock(0x2900, 0x297F,
+ "SUPPLEMENTAL_ARROWS_B",
+ "Supplemental Arrows-B");
+
+ /**
+ * Miscellaneous Mathematical Symbols-B.
+ * 0x2980 - 0x29FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B
+ = new UnicodeBlock(0x2980, 0x29FF,
+ "MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B",
+ "Miscellaneous Mathematical Symbols-B");
+
+ /**
+ * Supplemental Mathematical Operators.
+ * 0x2A00 - 0x2AFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS
+ = new UnicodeBlock(0x2A00, 0x2AFF,
+ "SUPPLEMENTAL_MATHEMATICAL_OPERATORS",
+ "Supplemental Mathematical Operators");
+
+ /**
+ * Miscellaneous Symbols and Arrows.
+ * 0x2B00 - 0x2BFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS
+ = new UnicodeBlock(0x2B00, 0x2BFF,
+ "MISCELLANEOUS_SYMBOLS_AND_ARROWS",
+ "Miscellaneous Symbols and Arrows");
+
+ /**
+ * CJK Radicals Supplement.
+ * 0x2E80 - 0x2EFF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT
+ = new UnicodeBlock(0x2E80, 0x2EFF,
+ "CJK_RADICALS_SUPPLEMENT",
+ "CJK Radicals Supplement");
+
+ /**
+ * Kangxi Radicals.
+ * 0x2F00 - 0x2FDF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock KANGXI_RADICALS
+ = new UnicodeBlock(0x2F00, 0x2FDF,
+ "KANGXI_RADICALS",
+ "Kangxi Radicals");
+
+ /**
+ * Ideographic Description Characters.
+ * 0x2FF0 - 0x2FFF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS
+ = new UnicodeBlock(0x2FF0, 0x2FFF,
+ "IDEOGRAPHIC_DESCRIPTION_CHARACTERS",
+ "Ideographic Description Characters");
+
+ /**
+ * CJK Symbols and Punctuation.
+ * 0x3000 - 0x303F.
+ */
+ public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION
+ = new UnicodeBlock(0x3000, 0x303F,
+ "CJK_SYMBOLS_AND_PUNCTUATION",
+ "CJK Symbols and Punctuation");
+
+ /**
+ * Hiragana.
+ * 0x3040 - 0x309F.
+ */
+ public static final UnicodeBlock HIRAGANA
+ = new UnicodeBlock(0x3040, 0x309F,
+ "HIRAGANA",
+ "Hiragana");
+
+ /**
+ * Katakana.
+ * 0x30A0 - 0x30FF.
+ */
+ public static final UnicodeBlock KATAKANA
+ = new UnicodeBlock(0x30A0, 0x30FF,
+ "KATAKANA",
+ "Katakana");
+
+ /**
+ * Bopomofo.
+ * 0x3100 - 0x312F.
+ */
+ public static final UnicodeBlock BOPOMOFO
+ = new UnicodeBlock(0x3100, 0x312F,
+ "BOPOMOFO",
+ "Bopomofo");
+
+ /**
+ * Hangul Compatibility Jamo.
+ * 0x3130 - 0x318F.
+ */
+ public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO
+ = new UnicodeBlock(0x3130, 0x318F,
+ "HANGUL_COMPATIBILITY_JAMO",
+ "Hangul Compatibility Jamo");
+
+ /**
+ * Kanbun.
+ * 0x3190 - 0x319F.
+ */
+ public static final UnicodeBlock KANBUN
+ = new UnicodeBlock(0x3190, 0x319F,
+ "KANBUN",
+ "Kanbun");
+
+ /**
+ * Bopomofo Extended.
+ * 0x31A0 - 0x31BF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock BOPOMOFO_EXTENDED
+ = new UnicodeBlock(0x31A0, 0x31BF,
+ "BOPOMOFO_EXTENDED",
+ "Bopomofo Extended");
+
+ /**
+ * Katakana Phonetic Extensions.
+ * 0x31F0 - 0x31FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS
+ = new UnicodeBlock(0x31F0, 0x31FF,
+ "KATAKANA_PHONETIC_EXTENSIONS",
+ "Katakana Phonetic Extensions");
+
+ /**
+ * Enclosed CJK Letters and Months.
+ * 0x3200 - 0x32FF.
+ */
+ public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS
+ = new UnicodeBlock(0x3200, 0x32FF,
+ "ENCLOSED_CJK_LETTERS_AND_MONTHS",
+ "Enclosed CJK Letters and Months");
+
+ /**
+ * CJK Compatibility.
+ * 0x3300 - 0x33FF.
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY
+ = new UnicodeBlock(0x3300, 0x33FF,
+ "CJK_COMPATIBILITY",
+ "CJK Compatibility");
+
+ /**
+ * CJK Unified Ideographs Extension A.
+ * 0x3400 - 0x4DBF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
+ = new UnicodeBlock(0x3400, 0x4DBF,
+ "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A",
+ "CJK Unified Ideographs Extension A");
+
+ /**
+ * Yijing Hexagram Symbols.
+ * 0x4DC0 - 0x4DFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS
+ = new UnicodeBlock(0x4DC0, 0x4DFF,
+ "YIJING_HEXAGRAM_SYMBOLS",
+ "Yijing Hexagram Symbols");
+
+ /**
+ * CJK Unified Ideographs.
+ * 0x4E00 - 0x9FFF.
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS
+ = new UnicodeBlock(0x4E00, 0x9FFF,
+ "CJK_UNIFIED_IDEOGRAPHS",
+ "CJK Unified Ideographs");
+
+ /**
+ * Yi Syllables.
+ * 0xA000 - 0xA48F.
+ * @since 1.4
+ */
+ public static final UnicodeBlock YI_SYLLABLES
+ = new UnicodeBlock(0xA000, 0xA48F,
+ "YI_SYLLABLES",
+ "Yi Syllables");
+
+ /**
+ * Yi Radicals.
+ * 0xA490 - 0xA4CF.
+ * @since 1.4
+ */
+ public static final UnicodeBlock YI_RADICALS
+ = new UnicodeBlock(0xA490, 0xA4CF,
+ "YI_RADICALS",
+ "Yi Radicals");
+
+ /**
+ * Hangul Syllables.
+ * 0xAC00 - 0xD7AF.
+ */
+ public static final UnicodeBlock HANGUL_SYLLABLES
+ = new UnicodeBlock(0xAC00, 0xD7AF,
+ "HANGUL_SYLLABLES",
+ "Hangul Syllables");
+
+ /**
+ * High Surrogates.
+ * 0xD800 - 0xDB7F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock HIGH_SURROGATES
+ = new UnicodeBlock(0xD800, 0xDB7F,
+ "HIGH_SURROGATES",
+ "High Surrogates");
+
+ /**
+ * High Private Use Surrogates.
+ * 0xDB80 - 0xDBFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES
+ = new UnicodeBlock(0xDB80, 0xDBFF,
+ "HIGH_PRIVATE_USE_SURROGATES",
+ "High Private Use Surrogates");
+
+ /**
+ * Low Surrogates.
+ * 0xDC00 - 0xDFFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LOW_SURROGATES
+ = new UnicodeBlock(0xDC00, 0xDFFF,
+ "LOW_SURROGATES",
+ "Low Surrogates");
+
+ /**
+ * Private Use Area.
+ * 0xE000 - 0xF8FF.
+ */
+ public static final UnicodeBlock PRIVATE_USE_AREA
+ = new UnicodeBlock(0xE000, 0xF8FF,
+ "PRIVATE_USE_AREA",
+ "Private Use Area");
+
+ /**
+ * CJK Compatibility Ideographs.
+ * 0xF900 - 0xFAFF.
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS
+ = new UnicodeBlock(0xF900, 0xFAFF,
+ "CJK_COMPATIBILITY_IDEOGRAPHS",
+ "CJK Compatibility Ideographs");
+
+ /**
+ * Alphabetic Presentation Forms.
+ * 0xFB00 - 0xFB4F.
+ */
+ public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS
+ = new UnicodeBlock(0xFB00, 0xFB4F,
+ "ALPHABETIC_PRESENTATION_FORMS",
+ "Alphabetic Presentation Forms");
+
+ /**
+ * Arabic Presentation Forms-A.
+ * 0xFB50 - 0xFDFF.
+ */
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A
+ = new UnicodeBlock(0xFB50, 0xFDFF,
+ "ARABIC_PRESENTATION_FORMS_A",
+ "Arabic Presentation Forms-A");
+
+ /**
+ * Variation Selectors.
+ * 0xFE00 - 0xFE0F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock VARIATION_SELECTORS
+ = new UnicodeBlock(0xFE00, 0xFE0F,
+ "VARIATION_SELECTORS",
+ "Variation Selectors");
+
+ /**
+ * Combining Half Marks.
+ * 0xFE20 - 0xFE2F.
+ */
+ public static final UnicodeBlock COMBINING_HALF_MARKS
+ = new UnicodeBlock(0xFE20, 0xFE2F,
+ "COMBINING_HALF_MARKS",
+ "Combining Half Marks");
+
+ /**
+ * CJK Compatibility Forms.
+ * 0xFE30 - 0xFE4F.
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_FORMS
+ = new UnicodeBlock(0xFE30, 0xFE4F,
+ "CJK_COMPATIBILITY_FORMS",
+ "CJK Compatibility Forms");
+
+ /**
+ * Small Form Variants.
+ * 0xFE50 - 0xFE6F.
+ */
+ public static final UnicodeBlock SMALL_FORM_VARIANTS
+ = new UnicodeBlock(0xFE50, 0xFE6F,
+ "SMALL_FORM_VARIANTS",
+ "Small Form Variants");
+
+ /**
+ * Arabic Presentation Forms-B.
+ * 0xFE70 - 0xFEFF.
+ */
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B
+ = new UnicodeBlock(0xFE70, 0xFEFF,
+ "ARABIC_PRESENTATION_FORMS_B",
+ "Arabic Presentation Forms-B");
+
+ /**
+ * Halfwidth and Fullwidth Forms.
+ * 0xFF00 - 0xFFEF.
+ */
+ public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS
+ = new UnicodeBlock(0xFF00, 0xFFEF,
+ "HALFWIDTH_AND_FULLWIDTH_FORMS",
+ "Halfwidth and Fullwidth Forms");
+
+ /**
+ * Specials.
+ * 0xFFF0 - 0xFFFF.
+ */
+ public static final UnicodeBlock SPECIALS
+ = new UnicodeBlock(0xFFF0, 0xFFFF,
+ "SPECIALS",
+ "Specials");
+
+ /**
+ * Linear B Syllabary.
+ * 0x10000 - 0x1007F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LINEAR_B_SYLLABARY
+ = new UnicodeBlock(0x10000, 0x1007F,
+ "LINEAR_B_SYLLABARY",
+ "Linear B Syllabary");
+
+ /**
+ * Linear B Ideograms.
+ * 0x10080 - 0x100FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock LINEAR_B_IDEOGRAMS
+ = new UnicodeBlock(0x10080, 0x100FF,
+ "LINEAR_B_IDEOGRAMS",
+ "Linear B Ideograms");
+
+ /**
+ * Aegean Numbers.
+ * 0x10100 - 0x1013F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock AEGEAN_NUMBERS
+ = new UnicodeBlock(0x10100, 0x1013F,
+ "AEGEAN_NUMBERS",
+ "Aegean Numbers");
+
+ /**
+ * Old Italic.
+ * 0x10300 - 0x1032F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock OLD_ITALIC
+ = new UnicodeBlock(0x10300, 0x1032F,
+ "OLD_ITALIC",
+ "Old Italic");
+
+ /**
+ * Gothic.
+ * 0x10330 - 0x1034F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock GOTHIC
+ = new UnicodeBlock(0x10330, 0x1034F,
+ "GOTHIC",
+ "Gothic");
+
+ /**
+ * Ugaritic.
+ * 0x10380 - 0x1039F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock UGARITIC
+ = new UnicodeBlock(0x10380, 0x1039F,
+ "UGARITIC",
+ "Ugaritic");
+
+ /**
+ * Deseret.
+ * 0x10400 - 0x1044F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock DESERET
+ = new UnicodeBlock(0x10400, 0x1044F,
+ "DESERET",
+ "Deseret");
+
+ /**
+ * Shavian.
+ * 0x10450 - 0x1047F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SHAVIAN
+ = new UnicodeBlock(0x10450, 0x1047F,
+ "SHAVIAN",
+ "Shavian");
+
+ /**
+ * Osmanya.
+ * 0x10480 - 0x104AF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock OSMANYA
+ = new UnicodeBlock(0x10480, 0x104AF,
+ "OSMANYA",
+ "Osmanya");
+
+ /**
+ * Cypriot Syllabary.
+ * 0x10800 - 0x1083F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CYPRIOT_SYLLABARY
+ = new UnicodeBlock(0x10800, 0x1083F,
+ "CYPRIOT_SYLLABARY",
+ "Cypriot Syllabary");
+
+ /**
+ * Byzantine Musical Symbols.
+ * 0x1D000 - 0x1D0FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS
+ = new UnicodeBlock(0x1D000, 0x1D0FF,
+ "BYZANTINE_MUSICAL_SYMBOLS",
+ "Byzantine Musical Symbols");
+
+ /**
+ * Musical Symbols.
+ * 0x1D100 - 0x1D1FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MUSICAL_SYMBOLS
+ = new UnicodeBlock(0x1D100, 0x1D1FF,
+ "MUSICAL_SYMBOLS",
+ "Musical Symbols");
+
+ /**
+ * Tai Xuan Jing Symbols.
+ * 0x1D300 - 0x1D35F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS
+ = new UnicodeBlock(0x1D300, 0x1D35F,
+ "TAI_XUAN_JING_SYMBOLS",
+ "Tai Xuan Jing Symbols");
+
+ /**
+ * Mathematical Alphanumeric Symbols.
+ * 0x1D400 - 0x1D7FF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS
+ = new UnicodeBlock(0x1D400, 0x1D7FF,
+ "MATHEMATICAL_ALPHANUMERIC_SYMBOLS",
+ "Mathematical Alphanumeric Symbols");
+
+ /**
+ * CJK Unified Ideographs Extension B.
+ * 0x20000 - 0x2A6DF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
+ = new UnicodeBlock(0x20000, 0x2A6DF,
+ "CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B",
+ "CJK Unified Ideographs Extension B");
+
+ /**
+ * CJK Compatibility Ideographs Supplement.
+ * 0x2F800 - 0x2FA1F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT
+ = new UnicodeBlock(0x2F800, 0x2FA1F,
+ "CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT",
+ "CJK Compatibility Ideographs Supplement");
+
+ /**
+ * Tags.
+ * 0xE0000 - 0xE007F.
+ * @since 1.5
+ */
+ public static final UnicodeBlock TAGS
+ = new UnicodeBlock(0xE0000, 0xE007F,
+ "TAGS",
+ "Tags");
+
+ /**
+ * Variation Selectors Supplement.
+ * 0xE0100 - 0xE01EF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT
+ = new UnicodeBlock(0xE0100, 0xE01EF,
+ "VARIATION_SELECTORS_SUPPLEMENT",
+ "Variation Selectors Supplement");
+
+ /**
+ * Supplementary Private Use Area-A.
+ * 0xF0000 - 0xFFFFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A
+ = new UnicodeBlock(0xF0000, 0xFFFFF,
+ "SUPPLEMENTARY_PRIVATE_USE_AREA_A",
+ "Supplementary Private Use Area-A");
+
+ /**
+ * Supplementary Private Use Area-B.
+ * 0x100000 - 0x10FFFF.
+ * @since 1.5
+ */
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B
+ = new UnicodeBlock(0x100000, 0x10FFFF,
+ "SUPPLEMENTARY_PRIVATE_USE_AREA_B",
+ "Supplementary Private Use Area-B");
+
+ /**
+ * Surrogates Area.
+ * 'D800' - 'DFFF'.
+ * @deprecated As of 1.5, the three areas,
+ * <a href="#HIGH_SURROGATES">HIGH_SURROGATES</a>,
+ * <a href="#HIGH_PRIVATE_USE_SURROGATES">HIGH_PRIVATE_USE_SURROGATES</a>
+ * and <a href="#LOW_SURROGATES">LOW_SURROGATES</a>, as defined
+ * by the Unicode standard, should be used in preference to
+ * this. These are also returned from calls to <code>of(int)</code>
+ * and <code>of(char)</code>.
+ */
+ public static final UnicodeBlock SURROGATES_AREA
+ = new UnicodeBlock(0xD800, 0xDFFF,
+ "SURROGATES_AREA",
+ "Surrogates Area");
+
+ /**
+ * The defined subsets.
+ */
+ private static final UnicodeBlock sets[] = {
+ BASIC_LATIN,
+ LATIN_1_SUPPLEMENT,
+ LATIN_EXTENDED_A,
+ LATIN_EXTENDED_B,
+ IPA_EXTENSIONS,
+ SPACING_MODIFIER_LETTERS,
+ COMBINING_DIACRITICAL_MARKS,
+ GREEK,
+ CYRILLIC,
+ CYRILLIC_SUPPLEMENTARY,
+ ARMENIAN,
+ HEBREW,
+ ARABIC,
+ SYRIAC,
+ THAANA,
+ DEVANAGARI,
+ BENGALI,
+ GURMUKHI,
+ GUJARATI,
+ ORIYA,
+ TAMIL,
+ TELUGU,
+ KANNADA,
+ MALAYALAM,
+ SINHALA,
+ THAI,
+ LAO,
+ TIBETAN,
+ MYANMAR,
+ GEORGIAN,
+ HANGUL_JAMO,
+ ETHIOPIC,
+ CHEROKEE,
+ UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS,
+ OGHAM,
+ RUNIC,
+ TAGALOG,
+ HANUNOO,
+ BUHID,
+ TAGBANWA,
+ KHMER,
+ MONGOLIAN,
+ LIMBU,
+ TAI_LE,
+ KHMER_SYMBOLS,
+ PHONETIC_EXTENSIONS,
+ LATIN_EXTENDED_ADDITIONAL,
+ GREEK_EXTENDED,
+ GENERAL_PUNCTUATION,
+ SUPERSCRIPTS_AND_SUBSCRIPTS,
+ CURRENCY_SYMBOLS,
+ COMBINING_MARKS_FOR_SYMBOLS,
+ LETTERLIKE_SYMBOLS,
+ NUMBER_FORMS,
+ ARROWS,
+ MATHEMATICAL_OPERATORS,
+ MISCELLANEOUS_TECHNICAL,
+ CONTROL_PICTURES,
+ OPTICAL_CHARACTER_RECOGNITION,
+ ENCLOSED_ALPHANUMERICS,
+ BOX_DRAWING,
+ BLOCK_ELEMENTS,
+ GEOMETRIC_SHAPES,
+ MISCELLANEOUS_SYMBOLS,
+ DINGBATS,
+ MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A,
+ SUPPLEMENTAL_ARROWS_A,
+ BRAILLE_PATTERNS,
+ SUPPLEMENTAL_ARROWS_B,
+ MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B,
+ SUPPLEMENTAL_MATHEMATICAL_OPERATORS,
+ MISCELLANEOUS_SYMBOLS_AND_ARROWS,
+ CJK_RADICALS_SUPPLEMENT,
+ KANGXI_RADICALS,
+ IDEOGRAPHIC_DESCRIPTION_CHARACTERS,
+ CJK_SYMBOLS_AND_PUNCTUATION,
+ HIRAGANA,
+ KATAKANA,
+ BOPOMOFO,
+ HANGUL_COMPATIBILITY_JAMO,
+ KANBUN,
+ BOPOMOFO_EXTENDED,
+ KATAKANA_PHONETIC_EXTENSIONS,
+ ENCLOSED_CJK_LETTERS_AND_MONTHS,
+ CJK_COMPATIBILITY,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A,
+ YIJING_HEXAGRAM_SYMBOLS,
+ CJK_UNIFIED_IDEOGRAPHS,
+ YI_SYLLABLES,
+ YI_RADICALS,
+ HANGUL_SYLLABLES,
+ HIGH_SURROGATES,
+ HIGH_PRIVATE_USE_SURROGATES,
+ LOW_SURROGATES,
+ PRIVATE_USE_AREA,
+ CJK_COMPATIBILITY_IDEOGRAPHS,
+ ALPHABETIC_PRESENTATION_FORMS,
+ ARABIC_PRESENTATION_FORMS_A,
+ VARIATION_SELECTORS,
+ COMBINING_HALF_MARKS,
+ CJK_COMPATIBILITY_FORMS,
+ SMALL_FORM_VARIANTS,
+ ARABIC_PRESENTATION_FORMS_B,
+ HALFWIDTH_AND_FULLWIDTH_FORMS,
+ SPECIALS,
+ LINEAR_B_SYLLABARY,
+ LINEAR_B_IDEOGRAMS,
+ AEGEAN_NUMBERS,
+ OLD_ITALIC,
+ GOTHIC,
+ UGARITIC,
+ DESERET,
+ SHAVIAN,
+ OSMANYA,
+ CYPRIOT_SYLLABARY,
+ BYZANTINE_MUSICAL_SYMBOLS,
+ MUSICAL_SYMBOLS,
+ TAI_XUAN_JING_SYMBOLS,
+ MATHEMATICAL_ALPHANUMERIC_SYMBOLS,
+ CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B,
+ CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT,
+ TAGS,
+ VARIATION_SELECTORS_SUPPLEMENT,
+ SUPPLEMENTARY_PRIVATE_USE_AREA_A,
+ SUPPLEMENTARY_PRIVATE_USE_AREA_B,
+ };
+ } // class UnicodeBlock
+
+ /**
+ * The immutable value of this Character.
+ *
+ * @serial the value of this Character
+ */
+ private final char value;
+
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 3786198910865385080L;
+
+ /**
+ * Smallest value allowed for radix arguments in Java. This value is 2.
+ *
+ * @see #digit(char, int)
+ * @see #forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
+ */
+ public static final int MIN_RADIX = 2;
+
+ /**
+ * Largest value allowed for radix arguments in Java. This value is 36.
+ *
+ * @see #digit(char, int)
+ * @see #forDigit(int, int)
+ * @see Integer#toString(int, int)
+ * @see Integer#valueOf(String)
+ */
+ public static final int MAX_RADIX = 36;
+
+ /**
+ * The minimum value the char data type can hold.
+ * This value is <code>'\\u0000'</code>.
+ */
+ public static final char MIN_VALUE = '\u0000';
+
+ /**
+ * The maximum value the char data type can hold.
+ * This value is <code>'\\uFFFF'</code>.
+ */
+ public static final char MAX_VALUE = '\uFFFF';
+
+ /**
+ * Class object representing the primitive char data type.
+ *
+ * @since 1.1
+ */
+ public static final Class TYPE = VMClassLoader.getPrimitiveClass('C');
+
+ /**
+ * The number of bits needed to represent a <code>char</code>.
+ * @since 1.5
+ */
+ public static final int SIZE = 16;
+
+ // This caches some Character values, and is used by boxing
+ // conversions via valueOf(). We must cache at least 0..127;
+ // this constant controls how much we actually cache.
+ private static final int MAX_CACHE = 127;
+ private static Character[] charCache = new Character[MAX_CACHE + 1];
+
+ /**
+ * Lu = Letter, Uppercase (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte UPPERCASE_LETTER = 1;
+
+ /**
+ * Ll = Letter, Lowercase (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte LOWERCASE_LETTER = 2;
+
+ /**
+ * Lt = Letter, Titlecase (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte TITLECASE_LETTER = 3;
+
+ /**
+ * Mn = Mark, Non-Spacing (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte NON_SPACING_MARK = 6;
+
+ /**
+ * Mc = Mark, Spacing Combining (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte COMBINING_SPACING_MARK = 8;
+
+ /**
+ * Me = Mark, Enclosing (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte ENCLOSING_MARK = 7;
+
+ /**
+ * Nd = Number, Decimal Digit (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte DECIMAL_DIGIT_NUMBER = 9;
+
+ /**
+ * Nl = Number, Letter (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte LETTER_NUMBER = 10;
+
+ /**
+ * No = Number, Other (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_NUMBER = 11;
+
+ /**
+ * Zs = Separator, Space (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte SPACE_SEPARATOR = 12;
+
+ /**
+ * Zl = Separator, Line (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte LINE_SEPARATOR = 13;
+
+ /**
+ * Zp = Separator, Paragraph (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte PARAGRAPH_SEPARATOR = 14;
+
+ /**
+ * Cc = Other, Control (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte CONTROL = 15;
+
+ /**
+ * Cf = Other, Format (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte FORMAT = 16;
+
+ /**
+ * Cs = Other, Surrogate (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte SURROGATE = 19;
+
+ /**
+ * Co = Other, Private Use (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte PRIVATE_USE = 18;
+
+ /**
+ * Cn = Other, Not Assigned (Normative).
+ *
+ * @since 1.1
+ */
+ public static final byte UNASSIGNED = 0;
+
+ /**
+ * Lm = Letter, Modifier (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte MODIFIER_LETTER = 4;
+
+ /**
+ * Lo = Letter, Other (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_LETTER = 5;
+
+ /**
+ * Pc = Punctuation, Connector (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte CONNECTOR_PUNCTUATION = 23;
+
+ /**
+ * Pd = Punctuation, Dash (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte DASH_PUNCTUATION = 20;
+
+ /**
+ * Ps = Punctuation, Open (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte START_PUNCTUATION = 21;
+
+ /**
+ * Pe = Punctuation, Close (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte END_PUNCTUATION = 22;
+
+ /**
+ * Pi = Punctuation, Initial Quote (Informative).
+ *
+ * @since 1.4
+ */
+ public static final byte INITIAL_QUOTE_PUNCTUATION = 29;
+
+ /**
+ * Pf = Punctuation, Final Quote (Informative).
+ *
+ * @since 1.4
+ */
+ public static final byte FINAL_QUOTE_PUNCTUATION = 30;
+
+ /**
+ * Po = Punctuation, Other (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_PUNCTUATION = 24;
+
+ /**
+ * Sm = Symbol, Math (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte MATH_SYMBOL = 25;
+
+ /**
+ * Sc = Symbol, Currency (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte CURRENCY_SYMBOL = 26;
+
+ /**
+ * Sk = Symbol, Modifier (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte MODIFIER_SYMBOL = 27;
+
+ /**
+ * So = Symbol, Other (Informative).
+ *
+ * @since 1.1
+ */
+ public static final byte OTHER_SYMBOL = 28;
+
+ /**
+ * Undefined bidirectional character type. Undefined char values have
+ * undefined directionality in the Unicode specification.
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_UNDEFINED = -1;
+
+ /**
+ * Strong bidirectional character type "L".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0;
+
+ /**
+ * Strong bidirectional character type "R".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1;
+
+ /**
+ * Strong bidirectional character type "AL".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2;
+
+ /**
+ * Weak bidirectional character type "EN".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3;
+
+ /**
+ * Weak bidirectional character type "ES".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4;
+
+ /**
+ * Weak bidirectional character type "ET".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5;
+
+ /**
+ * Weak bidirectional character type "AN".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6;
+
+ /**
+ * Weak bidirectional character type "CS".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7;
+
+ /**
+ * Weak bidirectional character type "NSM".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_NONSPACING_MARK = 8;
+
+ /**
+ * Weak bidirectional character type "BN".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9;
+
+ /**
+ * Neutral bidirectional character type "B".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10;
+
+ /**
+ * Neutral bidirectional character type "S".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11;
+
+ /**
+ * Strong bidirectional character type "WS".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_WHITESPACE = 12;
+
+ /**
+ * Neutral bidirectional character type "ON".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13;
+
+ /**
+ * Strong bidirectional character type "LRE".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14;
+
+ /**
+ * Strong bidirectional character type "LRO".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15;
+
+ /**
+ * Strong bidirectional character type "RLE".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16;
+
+ /**
+ * Strong bidirectional character type "RLO".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17;
+
+ /**
+ * Weak bidirectional character type "PDF".
+ *
+ * @since 1.4
+ */
+ public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
+
+ /**
+ * Mask for grabbing the type out of the result of readChar.
+ * @see #readChar(char)
+ */
+ private static final int TYPE_MASK = 0x1F;
+
+ /**
+ * Mask for grabbing the non-breaking space flag out of the result of
+ * readChar.
+ * @see #readChar(char)
+ */
+ private static final int NO_BREAK_MASK = 0x20;
+
+ /**
+ * Mask for grabbing the mirrored directionality flag out of the result
+ * of readChar.
+ * @see #readChar(char)
+ */
+ private static final int MIRROR_MASK = 0x40;
+
+ /**
+ * Min value for supplementary code point.
+ *
+ * @since 1.5
+ */
+ public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x10000;
+
+ /**
+ * Min value for code point.
+ *
+ * @since 1.5
+ */
+ public static final int MIN_CODE_POINT = 0;
+
+
+ /**
+ * Max value for code point.
+ *
+ * @since 1.5
+ */
+ public static final int MAX_CODE_POINT = 0x010ffff;
+
+
+ /**
+ * Minimum high surrogate code in UTF-16 encoding.
+ *
+ * @since 1.5
+ */
+ public static final char MIN_HIGH_SURROGATE = '\ud800';
+
+ /**
+ * Maximum high surrogate code in UTF-16 encoding.
+ *
+ * @since 1.5
+ */
+ public static final char MAX_HIGH_SURROGATE = '\udbff';
+
+ /**
+ * Minimum low surrogate code in UTF-16 encoding.
+ *
+ * @since 1.5
+ */
+ public static final char MIN_LOW_SURROGATE = '\udc00';
+
+ /**
+ * Maximum low surrogate code in UTF-16 encoding.
+ *
+ * @since 1.5
+ */
+ public static final char MAX_LOW_SURROGATE = '\udfff';
+
+ /**
+ * Minimum surrogate code in UTF-16 encoding.
+ *
+ * @since 1.5
+ */
+ public static final char MIN_SURROGATE = MIN_HIGH_SURROGATE;
+
+ /**
+ * Maximum low surrogate code in UTF-16 encoding.
+ *
+ * @since 1.5
+ */
+ public static final char MAX_SURROGATE = MAX_LOW_SURROGATE;
+
+ /**
+ * Grabs an attribute offset from the Unicode attribute database. The lower
+ * 5 bits are the character type, the next 2 bits are flags, and the top
+ * 9 bits are the offset into the attribute tables. Note that the top 9
+ * bits are meaningless in this context; they are useful only in the native
+ * code.
+ *
+ * @param ch the character to look up
+ * @return the character's attribute offset and type
+ * @see #TYPE_MASK
+ * @see #NO_BREAK_MASK
+ * @see #MIRROR_MASK
+ */
+ private static native char readChar(char ch);
+
+ /**
+ * Grabs an attribute offset from the Unicode attribute database. The lower
+ * 5 bits are the character type, the next 2 bits are flags, and the top
+ * 9 bits are the offset into the attribute tables. Note that the top 9
+ * bits are meaningless in this context; they are useful only in the native
+ * code.
+ *
+ * @param codePoint the character to look up
+ * @return the character's attribute offset and type
+ * @see #TYPE_MASK
+ * @see #NO_BREAK_MASK
+ * @see #MIRROR_MASK
+ */
+ private static native char readCodePoint(int codePoint);
+
+ /**
+ * Wraps up a character.
+ *
+ * @param value the character to wrap
+ */
+ public Character(char value)
+ {
+ this.value = value;
+ }
+
+ /**
+ * Returns the character which has been wrapped by this class.
+ *
+ * @return the character wrapped
+ */
+ public char charValue()
+ {
+ return value;
+ }
+
+ /**
+ * Returns the numerical value (unsigned) of the wrapped character.
+ * Range of returned values: 0x0000-0xFFFF.
+ *
+ * @return the value of the wrapped character
+ */
+ public int hashCode()
+ {
+ return value;
+ }
+
+ /**
+ * Determines if an object is equal to this object. This is only true for
+ * another Character object wrapping the same value.
+ *
+ * @param o object to compare
+ * @return true if o is a Character with the same value
+ */
+ public boolean equals(Object o)
+ {
+ return o instanceof Character && value == ((Character) o).value;
+ }
+
+ /**
+ * Converts the wrapped character into a String.
+ *
+ * @return a String containing one character -- the wrapped character
+ * of this instance
+ */
+ public String toString()
+ {
+ // This assumes that String.valueOf(char) can create a single-character
+ // String more efficiently than through the public API.
+ return String.valueOf(value);
+ }
+
+ /**
+ * Returns a String of length 1 representing the specified character.
+ *
+ * @param ch the character to convert
+ * @return a String containing the character
+ * @since 1.4
+ */
+ public static String toString(char ch)
+ {
+ // This assumes that String.valueOf(char) can create a single-character
+ // String more efficiently than through the public API.
+ return String.valueOf(ch);
+ }
+
+ /**
+ * Determines if a character is a Unicode lowercase letter. For example,
+ * <code>'a'</code> is lowercase.
+ * <br>
+ * lowercase = [Ll]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode lowercase letter, else false
+ * @see #isUpperCase(char)
+ * @see #isTitleCase(char)
+ * @see #toLowerCase(char)
+ * @see #getType(char)
+ */
+ public static boolean isLowerCase(char ch)
+ {
+ return getType(ch) == LOWERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode lowercase letter. For example,
+ * <code>'a'</code> is lowercase. Unlike isLowerCase(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * lowercase = [Ll]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode lowercase letter, else false
+ * @see #isUpperCase(int)
+ * @see #isTitleCase(int)
+ * @see #toLowerCase(int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isLowerCase(int codePoint)
+ {
+ return getType(codePoint) == LOWERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode uppercase letter. For example,
+ * <code>'A'</code> is uppercase.
+ * <br>
+ * uppercase = [Lu]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode uppercase letter, else false
+ * @see #isLowerCase(char)
+ * @see #isTitleCase(char)
+ * @see #toUpperCase(char)
+ * @see #getType(char)
+ */
+ public static boolean isUpperCase(char ch)
+ {
+ return getType(ch) == UPPERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode uppercase letter. For example,
+ * <code>'A'</code> is uppercase. Unlike isUpperCase(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * uppercase = [Lu]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode uppercase letter, else false
+ * @see #isLowerCase(int)
+ * @see #isTitleCase(int)
+ * @see #toUpperCase(int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isUpperCase(int codePoint)
+ {
+ return getType(codePoint) == UPPERCASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode titlecase letter. For example,
+ * the character "Lj" (Latin capital L with small letter j) is titlecase.
+ * <br>
+ * titlecase = [Lt]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode titlecase letter, else false
+ * @see #isLowerCase(char)
+ * @see #isUpperCase(char)
+ * @see #toTitleCase(char)
+ * @see #getType(char)
+ */
+ public static boolean isTitleCase(char ch)
+ {
+ return getType(ch) == TITLECASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode titlecase letter. For example,
+ * the character "Lj" (Latin capital L with small letter j) is titlecase.
+ * Unlike isTitleCase(char), this method supports supplementary Unicode
+ * code points.
+ * <br>
+ * titlecase = [Lt]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode titlecase letter, else false
+ * @see #isLowerCase(int)
+ * @see #isUpperCase(int)
+ * @see #toTitleCase(int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isTitleCase(int codePoint)
+ {
+ return getType(codePoint) == TITLECASE_LETTER;
+ }
+
+ /**
+ * Determines if a character is a Unicode decimal digit. For example,
+ * <code>'0'</code> is a digit.
+ * <br>
+ * Unicode decimal digit = [Nd]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode decimal digit, else false
+ * @see #digit(char, int)
+ * @see #forDigit(int, int)
+ * @see #getType(char)
+ */
+ public static boolean isDigit(char ch)
+ {
+ return getType(ch) == DECIMAL_DIGIT_NUMBER;
+ }
+
+ /**
+ * Determines if a character is a Unicode decimal digit. For example,
+ * <code>'0'</code> is a digit. Unlike isDigit(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Unicode decimal digit = [Nd]
+ *
+ * @param codePoint character to test
+ * @return true if ccodePoint is a Unicode decimal digit, else false
+ * @see #digit(int, int)
+ * @see #forDigit(int, int)
+ * @see #getType(int)
+ * @since 1.5
+ */
+ public static boolean isDigit(int codePoint)
+ {
+ return getType(codePoint) == DECIMAL_DIGIT_NUMBER;
+ }
+
+ /**
+ * Determines if a character is part of the Unicode Standard. This is an
+ * evolving standard, but covers every character in the data file.
+ * <br>
+ * defined = not [Cn]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode character, else false
+ * @see #isDigit(char)
+ * @see #isLetter(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isLowerCase(char)
+ * @see #isTitleCase(char)
+ * @see #isUpperCase(char)
+ */
+ public static boolean isDefined(char ch)
+ {
+ return getType(ch) != UNASSIGNED;
+ }
+
+ /**
+ * Determines if a character is part of the Unicode Standard. This is an
+ * evolving standard, but covers every character in the data file. Unlike
+ * isDefined(char), this method supports supplementary Unicode code points.
+ * <br>
+ * defined = not [Cn]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode character, else false
+ * @see #isDigit(int)
+ * @see #isLetter(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isLowerCase(int)
+ * @see #isTitleCase(int)
+ * @see #isUpperCase(int)
+ * @since 1.5
+ */
+ public static boolean isDefined(int codePoint)
+ {
+ return getType(codePoint) != UNASSIGNED;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter. Not all letters have case,
+ * so this may return true when isLowerCase and isUpperCase return false.
+ * <br>
+ * letter = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode letter, else false
+ * @see #isDigit(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isJavaLetter(char)
+ * @see #isJavaLetterOrDigit(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isLowerCase(char)
+ * @see #isTitleCase(char)
+ * @see #isUnicodeIdentifierStart(char)
+ * @see #isUpperCase(char)
+ */
+ public static boolean isLetter(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter. Not all letters have case,
+ * so this may return true when isLowerCase and isUpperCase return false.
+ * Unlike isLetter(char), this method supports supplementary Unicode code
+ * points.
+ * <br>
+ * letter = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode letter, else false
+ * @see #isDigit(int)
+ * @see #isJavaIdentifierStart(int)
+ * @see #isJavaLetter(int)
+ * @see #isJavaLetterOrDigit(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isLowerCase(int)
+ * @see #isTitleCase(int)
+ * @see #isUnicodeIdentifierStart(int)
+ * @see #isUpperCase(int)
+ * @since 1.5
+ */
+ public static boolean isLetter(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter or a Unicode digit. This
+ * is the combination of isLetter and isDigit.
+ * <br>
+ * letter or digit = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nd]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode letter or a Unicode digit, else false
+ * @see #isDigit(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isJavaLetter(char)
+ * @see #isJavaLetterOrDigit(char)
+ * @see #isLetter(char)
+ * @see #isUnicodeIdentifierPart(char)
+ */
+ public static boolean isLetterOrDigit(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode letter or a Unicode digit. This
+ * is the combination of isLetter and isDigit. Unlike isLetterOrDigit(char),
+ * this method supports supplementary Unicode code points.
+ * <br>
+ * letter or digit = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nd]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode letter or a Unicode digit, else false
+ * @see #isDigit(int)
+ * @see #isJavaIdentifierPart(int)
+ * @see #isJavaLetter(int)
+ * @see #isJavaLetterOrDigit(int)
+ * @see #isLetter(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isLetterOrDigit(int codePoint)
+ {
+ return ((1 << getType(codePoint)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))) != 0);
+ }
+
+ /**
+ * Determines if a character can start a Java identifier. This is the
+ * combination of isLetter, any character where getType returns
+ * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
+ * (like '_').
+ *
+ * @param ch character to test
+ * @return true if ch can start a Java identifier, else false
+ * @deprecated Replaced by {@link #isJavaIdentifierStart(char)}
+ * @see #isJavaLetterOrDigit(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetter(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierStart(char)
+ */
+ public static boolean isJavaLetter(char ch)
+ {
+ return isJavaIdentifierStart(ch);
+ }
+
+ /**
+ * Determines if a character can start a Java identifier. This is the
+ * combination of isLetter, any character where getType returns
+ * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
+ * (like '_'). Unlike isJavaIdentifierStart(char), this method supports
+ * supplementary Unicode code points.
+ * <br>
+ * Java identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can start a Java identifier, else false
+ * @see #isJavaIdentifierPart(int)
+ * @see #isLetter(int)
+ * @see #isUnicodeIdentifierStart(int)
+ * @since 1.5
+ */
+ public static boolean isJavaIdentifierStart(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION))) != 0;
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Java identifier. This is the combination of isJavaLetter (isLetter,
+ * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
+ * numeric letter (like Roman numerals), combining marks, non-spacing marks,
+ * or isIdentifierIgnorable.
+ *
+ * @param ch character to test
+ * @return true if ch can follow the first letter in a Java identifier
+ * @deprecated Replaced by {@link #isJavaIdentifierPart(char)}
+ * @see #isJavaLetter(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetter(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @see #isIdentifierIgnorable(char)
+ */
+ public static boolean isJavaLetterOrDigit(char ch)
+ {
+ return isJavaIdentifierPart(ch);
+ }
+
+ /**
+ * Determines if a character can start a Java identifier. This is the
+ * combination of isLetter, any character where getType returns
+ * LETTER_NUMBER, currency symbols (like '$'), and connecting punctuation
+ * (like '_').
+ * <br>
+ * Java identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]
+ *
+ * @param ch character to test
+ * @return true if ch can start a Java identifier, else false
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetter(char)
+ * @see #isUnicodeIdentifierStart(char)
+ * @since 1.1
+ */
+ public static boolean isJavaIdentifierStart(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION))) != 0;
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Java identifier. This is the combination of isJavaLetter (isLetter,
+ * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
+ * numeric letter (like Roman numerals), combining marks, non-spacing marks,
+ * or isIdentifierIgnorable.
+ * <br>
+ * Java identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]|[Mn]|[Mc]|[Nd]|[Cf]
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param ch character to test
+ * @return true if ch can follow the first letter in a Java identifier
+ * @see #isIdentifierIgnorable(char)
+ * @see #isJavaIdentifierStart(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isJavaIdentifierPart(char ch)
+ {
+ int category = getType(ch);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(ch));
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Java identifier. This is the combination of isJavaLetter (isLetter,
+ * type of LETTER_NUMBER, currency, connecting punctuation) and digit,
+ * numeric letter (like Roman numerals), combining marks, non-spacing marks,
+ * or isIdentifierIgnorable. Unlike isJavaIdentifierPart(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Java identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Sc]|[Pc]|[Mn]|[Mc]|[Nd]|[Cf]
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can follow the first letter in a Java identifier
+ * @see #isIdentifierIgnorable(int)
+ * @see #isJavaIdentifierStart(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isJavaIdentifierPart(int codePoint)
+ {
+ int category = getType(codePoint);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CURRENCY_SYMBOL)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(codePoint));
+ }
+
+ /**
+ * Determines if a character can start a Unicode identifier. Only
+ * letters can start a Unicode identifier, but this includes characters
+ * in LETTER_NUMBER.
+ * <br>
+ * Unicode identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]
+ *
+ * @param ch character to test
+ * @return true if ch can start a Unicode identifier, else false
+ * @see #isJavaIdentifierStart(char)
+ * @see #isLetter(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isUnicodeIdentifierStart(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER))) != 0;
+ }
+
+ /**
+ * Determines if a character can start a Unicode identifier. Only
+ * letters can start a Unicode identifier, but this includes characters
+ * in LETTER_NUMBER. Unlike isUnicodeIdentifierStart(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Unicode identifier start = [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can start a Unicode identifier, else false
+ * @see #isJavaIdentifierStart(int)
+ * @see #isLetter(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isUnicodeIdentifierStart(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << LETTER_NUMBER))) != 0;
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Unicode identifier. This includes letters, connecting punctuation,
+ * digits, numeric letters, combining marks, non-spacing marks, and
+ * isIdentifierIgnorable.
+ * <br>
+ * Unicode identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Mn]|[Mc]|[Nd]|[Pc]|[Cf]|
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param ch character to test
+ * @return true if ch can follow the first letter in a Unicode identifier
+ * @see #isIdentifierIgnorable(char)
+ * @see #isJavaIdentifierPart(char)
+ * @see #isLetterOrDigit(char)
+ * @see #isUnicodeIdentifierStart(char)
+ * @since 1.1
+ */
+ public static boolean isUnicodeIdentifierPart(char ch)
+ {
+ int category = getType(ch);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(ch));
+ }
+
+ /**
+ * Determines if a character can follow the first letter in
+ * a Unicode identifier. This includes letters, connecting punctuation,
+ * digits, numeric letters, combining marks, non-spacing marks, and
+ * isIdentifierIgnorable. Unlike isUnicodeIdentifierPart(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Unicode identifier extender =
+ * [Lu]|[Ll]|[Lt]|[Lm]|[Lo]|[Nl]|[Mn]|[Mc]|[Nd]|[Pc]|[Cf]|
+ * |U+0000-U+0008|U+000E-U+001B|U+007F-U+009F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint can follow the first letter in a Unicode
+ * identifier
+ * @see #isIdentifierIgnorable(int)
+ * @see #isJavaIdentifierPart(int)
+ * @see #isLetterOrDigit(int)
+ * @see #isUnicodeIdentifierStart(int)
+ * @since 1.5
+ */
+ public static boolean isUnicodeIdentifierPart(int codePoint)
+ {
+ int category = getType(codePoint);
+ return ((1 << category)
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << TITLECASE_LETTER)
+ | (1 << MODIFIER_LETTER)
+ | (1 << OTHER_LETTER)
+ | (1 << NON_SPACING_MARK)
+ | (1 << COMBINING_SPACING_MARK)
+ | (1 << DECIMAL_DIGIT_NUMBER)
+ | (1 << LETTER_NUMBER)
+ | (1 << CONNECTOR_PUNCTUATION)
+ | (1 << FORMAT))) != 0
+ || (category == CONTROL && isIdentifierIgnorable(codePoint));
+ }
+
+ /**
+ * Determines if a character is ignorable in a Unicode identifier. This
+ * includes the non-whitespace ISO control characters (<code>'\u0000'</code>
+ * through <code>'\u0008'</code>, <code>'\u000E'</code> through
+ * <code>'\u001B'</code>, and <code>'\u007F'</code> through
+ * <code>'\u009F'</code>), and FORMAT characters.
+ * <br>
+ * Unicode identifier ignorable = [Cf]|U+0000-U+0008|U+000E-U+001B
+ * |U+007F-U+009F
+ *
+ * @param ch character to test
+ * @return true if ch is ignorable in a Unicode or Java identifier
+ * @see #isJavaIdentifierPart(char)
+ * @see #isUnicodeIdentifierPart(char)
+ * @since 1.1
+ */
+ public static boolean isIdentifierIgnorable(char ch)
+ {
+ return (ch <= '\u009F' && (ch < '\t' || ch >= '\u007F'
+ || (ch <= '\u001B' && ch >= '\u000E')))
+ || getType(ch) == FORMAT;
+ }
+
+ /**
+ * Determines if a character is ignorable in a Unicode identifier. This
+ * includes the non-whitespace ISO control characters (<code>'\u0000'</code>
+ * through <code>'\u0008'</code>, <code>'\u000E'</code> through
+ * <code>'\u001B'</code>, and <code>'\u007F'</code> through
+ * <code>'\u009F'</code>), and FORMAT characters. Unlike
+ * isIdentifierIgnorable(char), this method supports supplementary Unicode
+ * code points.
+ * <br>
+ * Unicode identifier ignorable = [Cf]|U+0000-U+0008|U+000E-U+001B
+ * |U+007F-U+009F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is ignorable in a Unicode or Java identifier
+ * @see #isJavaIdentifierPart(int)
+ * @see #isUnicodeIdentifierPart(int)
+ * @since 1.5
+ */
+ public static boolean isIdentifierIgnorable(int codePoint)
+ {
+ return ((codePoint >= 0 && codePoint <= 0x0008)
+ || (codePoint >= 0x000E && codePoint <= 0x001B)
+ || (codePoint >= 0x007F && codePoint <= 0x009F)
+ || getType(codePoint) == FORMAT);
+ }
+
+ /**
+ * Converts a Unicode character into its lowercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isLowerCase(toLowerCase(ch)) does not always return true.
+ *
+ * @param ch character to convert to lowercase
+ * @return lowercase mapping of ch, or ch if lowercase mapping does
+ * not exist
+ * @see #isLowerCase(char)
+ * @see #isUpperCase(char)
+ * @see #toTitleCase(char)
+ * @see #toUpperCase(char)
+ */
+ public static native char toLowerCase(char ch);
+
+ /**
+ * Converts a Unicode character into its lowercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isLowerCase(toLowerCase(codePoint)) does not always return true.
+ * Unlike toLowerCase(char), this method supports supplementary Unicode
+ * code points.
+ *
+ * @param codePoint character to convert to lowercase
+ * @return lowercase mapping of codePoint, or codePoint if lowercase
+ * mapping does not exist
+ * @see #isLowerCase(int)
+ * @see #isUpperCase(int)
+ * @see #toTitleCase(int)
+ * @see #toUpperCase(int)
+ * @since 1.5
+ */
+ public static native int toLowerCase(int codePoint);
+
+ /**
+ * Converts a Unicode character into its uppercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isUpperCase(toUpperCase(ch)) does not always return true.
+ *
+ * @param ch character to convert to uppercase
+ * @return uppercase mapping of ch, or ch if uppercase mapping does
+ * not exist
+ * @see #isLowerCase(char)
+ * @see #isUpperCase(char)
+ * @see #toLowerCase(char)
+ * @see #toTitleCase(char)
+ */
+ public static native char toUpperCase(char ch);
+
+ /**
+ * Converts a Unicode character into its uppercase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isUpperCase(toUpperCase(codePoint)) does not always return true.
+ * Unlike toUpperCase(char), this method supports supplementary
+ * Unicode code points.
+ *
+ * @param codePoint character to convert to uppercase
+ * @return uppercase mapping of codePoint, or codePoint if uppercase
+ * mapping does not exist
+ * @see #isLowerCase(int)
+ * @see #isUpperCase(int)
+ * @see #toLowerCase(int)
+ * @see #toTitleCase(int)
+ * @since 1.5
+ */
+ public static native int toUpperCase(int codePoint);
+
+ /**
+ * Converts a Unicode character into its titlecase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isTitleCase(toTitleCase(ch)) does not always return true.
+ *
+ * @param ch character to convert to titlecase
+ * @return titlecase mapping of ch, or ch if titlecase mapping does
+ * not exist
+ * @see #isTitleCase(char)
+ * @see #toLowerCase(char)
+ * @see #toUpperCase(char)
+ */
+ public static native char toTitleCase(char ch);
+
+ /**
+ * Converts a Unicode character into its titlecase equivalent mapping.
+ * If a mapping does not exist, then the character passed is returned.
+ * Note that isTitleCase(toTitleCase(codePoint)) does not always return true.
+ * Unlike toTitleCase(char), this method supports supplementary
+ * Unicode code points.
+ *
+ * @param codePoint character to convert to titlecase
+ * @return titlecase mapping of codePoint, or codePoint if titlecase
+ * mapping does not exist
+ * @see #isTitleCase(int)
+ * @see #toLowerCase(int)
+ * @see #toUpperCase(int)
+ * @since 1.5
+ */
+ public static native int toTitleCase(int codePoint);
+
+ /**
+ * Converts a character into a digit of the specified radix. If the radix
+ * exceeds MIN_RADIX or MAX_RADIX, or if the result of getNumericValue(ch)
+ * exceeds the radix, or if ch is not a decimal digit or in the case
+ * insensitive set of 'a'-'z', the result is -1.
+ * <br>
+ * character argument boundary = [Nd]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param ch character to convert into a digit
+ * @param radix radix in which ch is a digit
+ * @return digit which ch represents in radix, or -1 not a valid digit
+ * @see #MIN_RADIX
+ * @see #MAX_RADIX
+ * @see #forDigit(int, int)
+ * @see #isDigit(char)
+ * @see #getNumericValue(char)
+ */
+ public static native int digit(char ch, int radix);
+
+ /**
+ * Converts a character into a digit of the specified radix. If the radix
+ * exceeds MIN_RADIX or MAX_RADIX, or if the result of getNumericValue(int)
+ * exceeds the radix, or if codePoint is not a decimal digit or in the case
+ * insensitive set of 'a'-'z', the result is -1. Unlike digit(char, int),
+ * this method supports supplementary Unicode code points.
+ * <br>
+ * character argument boundary = [Nd]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param codePoint character to convert into a digit
+ * @param radix radix in which codePoint is a digit
+ * @return digit which codePoint represents in radix, or -1 not a valid digit
+ * @see #MIN_RADIX
+ * @see #MAX_RADIX
+ * @see #forDigit(int, int)
+ * @see #isDigit(int)
+ * @see #getNumericValue(int)
+ * @since 1.5
+ */
+ public static native int digit(int codePoint, int radix);
+
+ /**
+ * Returns the Unicode numeric value property of a character. For example,
+ * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50.
+ *
+ * <p>This method also returns values for the letters A through Z, (not
+ * specified by Unicode), in these ranges: <code>'\u0041'</code>
+ * through <code>'\u005A'</code> (uppercase); <code>'\u0061'</code>
+ * through <code>'\u007A'</code> (lowercase); and <code>'\uFF21'</code>
+ * through <code>'\uFF3A'</code>, <code>'\uFF41'</code> through
+ * <code>'\uFF5A'</code> (full width variants).
+ *
+ * <p>If the character lacks a numeric value property, -1 is returned.
+ * If the character has a numeric value property which is not representable
+ * as a nonnegative integer, such as a fraction, -2 is returned.
+ *
+ * character argument boundary = [Nd]|[Nl]|[No]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param ch character from which the numeric value property will
+ * be retrieved
+ * @return the numeric value property of ch, or -1 if it does not exist, or
+ * -2 if it is not representable as a nonnegative integer
+ * @see #forDigit(int, int)
+ * @see #digit(char, int)
+ * @see #isDigit(char)
+ * @since 1.1
+ */
+ public static native int getNumericValue(char ch);
+
+ /**
+ * Returns the Unicode numeric value property of a character. For example,
+ * <code>'\\u216C'</code> (the Roman numeral fifty) returns 50.
+ *
+ * <p>This method also returns values for the letters A through Z, (not
+ * specified by Unicode), in these ranges: <code>'\u0041'</code>
+ * through <code>'\u005A'</code> (uppercase); <code>'\u0061'</code>
+ * through <code>'\u007A'</code> (lowercase); and <code>'\uFF21'</code>
+ * through <code>'\uFF3A'</code>, <code>'\uFF41'</code> through
+ * <code>'\uFF5A'</code> (full width variants).
+ *
+ * <p>If the character lacks a numeric value property, -1 is returned.
+ * If the character has a numeric value property which is not representable
+ * as a nonnegative integer, such as a fraction, -2 is returned.
+ *
+ * Unlike getNumericValue(char), this method supports supplementary Unicode
+ * code points.
+ *
+ * character argument boundary = [Nd]|[Nl]|[No]|U+0041-U+005A|U+0061-U+007A
+ * |U+FF21-U+FF3A|U+FF41-U+FF5A
+ *
+ * @param codePoint character from which the numeric value property will
+ * be retrieved
+ * @return the numeric value property of codePoint, or -1 if it does not
+ * exist, or -2 if it is not representable as a nonnegative integer
+ * @see #forDigit(int, int)
+ * @see #digit(int, int)
+ * @see #isDigit(int)
+ * @since 1.5
+ */
+ public static native int getNumericValue(int codePoint);
+
+ /**
+ * Determines if a character is a ISO-LATIN-1 space. This is only the five
+ * characters <code>'\t'</code>, <code>'\n'</code>, <code>'\f'</code>,
+ * <code>'\r'</code>, and <code>' '</code>.
+ * <br>
+ * Java space = U+0020|U+0009|U+000A|U+000C|U+000D
+ *
+ * @param ch character to test
+ * @return true if ch is a space, else false
+ * @deprecated Replaced by {@link #isWhitespace(char)}
+ * @see #isSpaceChar(char)
+ * @see #isWhitespace(char)
+ */
+ public static boolean isSpace(char ch)
+ {
+ // Performing the subtraction up front alleviates need to compare longs.
+ return ch-- <= ' ' && ((1 << ch)
+ & ((1 << (' ' - 1))
+ | (1 << ('\t' - 1))
+ | (1 << ('\n' - 1))
+ | (1 << ('\r' - 1))
+ | (1 << ('\f' - 1)))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode space character. This includes
+ * SPACE_SEPARATOR, LINE_SEPARATOR, and PARAGRAPH_SEPARATOR.
+ * <br>
+ * Unicode space = [Zs]|[Zp]|[Zl]
+ *
+ * @param ch character to test
+ * @return true if ch is a Unicode space, else false
+ * @see #isWhitespace(char)
+ * @since 1.1
+ */
+ public static boolean isSpaceChar(char ch)
+ {
+ return ((1 << getType(ch))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0;
+ }
+
+ /**
+ * Determines if a character is a Unicode space character. This includes
+ * SPACE_SEPARATOR, LINE_SEPARATOR, and PARAGRAPH_SEPARATOR. Unlike
+ * isSpaceChar(char), this method supports supplementary Unicode code points.
+ * <br>
+ * Unicode space = [Zs]|[Zp]|[Zl]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is a Unicode space, else false
+ * @see #isWhitespace(int)
+ * @since 1.5
+ */
+ public static boolean isSpaceChar(int codePoint)
+ {
+ return ((1 << getType(codePoint))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0;
+ }
+
+ /**
+ * Determines if a character is Java whitespace. This includes Unicode
+ * space characters (SPACE_SEPARATOR, LINE_SEPARATOR, and
+ * PARAGRAPH_SEPARATOR) except the non-breaking spaces
+ * (<code>'\u00A0'</code>, <code>'\u2007'</code>, and <code>'\u202F'</code>);
+ * and these characters: <code>'\u0009'</code>, <code>'\u000A'</code>,
+ * <code>'\u000B'</code>, <code>'\u000C'</code>, <code>'\u000D'</code>,
+ * <code>'\u001C'</code>, <code>'\u001D'</code>, <code>'\u001E'</code>,
+ * and <code>'\u001F'</code>.
+ * <br>
+ * Java whitespace = ([Zs] not Nb)|[Zl]|[Zp]|U+0009-U+000D|U+001C-U+001F
+ *
+ * @param ch character to test
+ * @return true if ch is Java whitespace, else false
+ * @see #isSpaceChar(char)
+ * @since 1.1
+ */
+ public static boolean isWhitespace(char ch)
+ {
+ int attr = readChar(ch);
+ return ((((1 << (attr & TYPE_MASK))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0)
+ && (attr & NO_BREAK_MASK) == 0)
+ || (ch <= '\u001F' && ((1 << ch)
+ & ((1 << '\t')
+ | (1 << '\n')
+ | (1 << '\u000B')
+ | (1 << '\u000C')
+ | (1 << '\r')
+ | (1 << '\u001C')
+ | (1 << '\u001D')
+ | (1 << '\u001E')
+ | (1 << '\u001F'))) != 0);
+ }
+
+ /**
+ * Determines if a character is Java whitespace. This includes Unicode
+ * space characters (SPACE_SEPARATOR, LINE_SEPARATOR, and
+ * PARAGRAPH_SEPARATOR) except the non-breaking spaces
+ * (<code>'\u00A0'</code>, <code>'\u2007'</code>, and <code>'\u202F'</code>);
+ * and these characters: <code>'\u0009'</code>, <code>'\u000A'</code>,
+ * <code>'\u000B'</code>, <code>'\u000C'</code>, <code>'\u000D'</code>,
+ * <code>'\u001C'</code>, <code>'\u001D'</code>, <code>'\u001E'</code>,
+ * and <code>'\u001F'</code>. Unlike isWhitespace(char), this method
+ * supports supplementary Unicode code points.
+ * <br>
+ * Java whitespace = ([Zs] not Nb)|[Zl]|[Zp]|U+0009-U+000D|U+001C-U+001F
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is Java whitespace, else false
+ * @see #isSpaceChar(int)
+ * @since 1.5
+ */
+ public static boolean isWhitespace(int codePoint)
+ {
+ int plane = codePoint >>> 16;
+ if (plane > 2 && plane != 14)
+ return false;
+ int attr = readCodePoint(codePoint);
+ return ((((1 << (attr & TYPE_MASK))
+ & ((1 << SPACE_SEPARATOR)
+ | (1 << LINE_SEPARATOR)
+ | (1 << PARAGRAPH_SEPARATOR))) != 0)
+ && (attr & NO_BREAK_MASK) == 0)
+ || (codePoint <= '\u001F' && ((1 << codePoint)
+ & ((1 << '\t')
+ | (1 << '\n')
+ | (1 << '\u000B')
+ | (1 << '\u000C')
+ | (1 << '\r')
+ | (1 << '\u001C')
+ | (1 << '\u001D')
+ | (1 << '\u001E')
+ | (1 << '\u001F'))) != 0);
+ }
+
+ /**
+ * Determines if a character has the ISO Control property.
+ * <br>
+ * ISO Control = [Cc]
+ *
+ * @param ch character to test
+ * @return true if ch is an ISO Control character, else false
+ * @see #isSpaceChar(char)
+ * @see #isWhitespace(char)
+ * @since 1.1
+ */
+ public static boolean isISOControl(char ch)
+ {
+ return getType(ch) == CONTROL;
+ }
+
+ /**
+ * Determines if a character has the ISO Control property. Unlike
+ * isISOControl(char), this method supports supplementary unicode
+ * code points.
+ * <br>
+ * ISO Control = [Cc]
+ *
+ * @param codePoint character to test
+ * @return true if codePoint is an ISO Control character, else false
+ * @see #isSpaceChar(int)
+ * @see #isWhitespace(int)
+ * @since 1.5
+ */
+ public static boolean isISOControl(int codePoint)
+ {
+ return getType(codePoint) == CONTROL;
+ }
+
+ /**
+ * Returns the Unicode general category property of a character.
+ *
+ * @param ch character from which the general category property will
+ * be retrieved
+ * @return the character category property of ch as an integer
+ * @see #UNASSIGNED
+ * @see #UPPERCASE_LETTER
+ * @see #LOWERCASE_LETTER
+ * @see #TITLECASE_LETTER
+ * @see #MODIFIER_LETTER
+ * @see #OTHER_LETTER
+ * @see #NON_SPACING_MARK
+ * @see #ENCLOSING_MARK
+ * @see #COMBINING_SPACING_MARK
+ * @see #DECIMAL_DIGIT_NUMBER
+ * @see #LETTER_NUMBER
+ * @see #OTHER_NUMBER
+ * @see #SPACE_SEPARATOR
+ * @see #LINE_SEPARATOR
+ * @see #PARAGRAPH_SEPARATOR
+ * @see #CONTROL
+ * @see #FORMAT
+ * @see #PRIVATE_USE
+ * @see #SURROGATE
+ * @see #DASH_PUNCTUATION
+ * @see #START_PUNCTUATION
+ * @see #END_PUNCTUATION
+ * @see #CONNECTOR_PUNCTUATION
+ * @see #OTHER_PUNCTUATION
+ * @see #MATH_SYMBOL
+ * @see #CURRENCY_SYMBOL
+ * @see #MODIFIER_SYMBOL
+ * @see #INITIAL_QUOTE_PUNCTUATION
+ * @see #FINAL_QUOTE_PUNCTUATION
+ * @since 1.1
+ */
+ public static native int getType(char ch);
+
+ /**
+ * Returns the Unicode general category property of a character. Supports
+ * supplementary Unicode code points.
+ *
+ * @param codePoint character from which the general category property will
+ * be retrieved
+ * @return the character category property of codePoint as an integer
+ * @see #UNASSIGNED
+ * @see #UPPERCASE_LETTER
+ * @see #LOWERCASE_LETTER
+ * @see #TITLECASE_LETTER
+ * @see #MODIFIER_LETTER
+ * @see #OTHER_LETTER
+ * @see #NON_SPACING_MARK
+ * @see #ENCLOSING_MARK
+ * @see #COMBINING_SPACING_MARK
+ * @see #DECIMAL_DIGIT_NUMBER
+ * @see #LETTER_NUMBER
+ * @see #OTHER_NUMBER
+ * @see #SPACE_SEPARATOR
+ * @see #LINE_SEPARATOR
+ * @see #PARAGRAPH_SEPARATOR
+ * @see #CONTROL
+ * @see #FORMAT
+ * @see #PRIVATE_USE
+ * @see #SURROGATE
+ * @see #DASH_PUNCTUATION
+ * @see #START_PUNCTUATION
+ * @see #END_PUNCTUATION
+ * @see #CONNECTOR_PUNCTUATION
+ * @see #OTHER_PUNCTUATION
+ * @see #MATH_SYMBOL
+ * @see #CURRENCY_SYMBOL
+ * @see #MODIFIER_SYMBOL
+ * @see #INITIAL_QUOTE_PUNCTUATION
+ * @see #FINAL_QUOTE_PUNCTUATION
+ * @since 1.5
+ */
+ public static native int getType(int codePoint);
+
+ /**
+ * Converts a digit into a character which represents that digit
+ * in a specified radix. If the radix exceeds MIN_RADIX or MAX_RADIX,
+ * or the digit exceeds the radix, then the null character <code>'\0'</code>
+ * is returned. Otherwise the return value is in '0'-'9' and 'a'-'z'.
+ * <br>
+ * return value boundary = U+0030-U+0039|U+0061-U+007A
+ *
+ * @param digit digit to be converted into a character
+ * @param radix radix of digit
+ * @return character representing digit in radix, or '\0'
+ * @see #MIN_RADIX
+ * @see #MAX_RADIX
+ * @see #digit(char, int)
+ */
+ public static char forDigit(int digit, int radix)
+ {
+ if (radix < MIN_RADIX || radix > MAX_RADIX
+ || digit < 0 || digit >= radix)
+ return '\0';
+ return (char) (digit < 10 ? ('0' + digit) : ('a' - 10 + digit));
+ }
+
+ /**
+ * Returns the Unicode directionality property of the character. This
+ * is used in the visual ordering of text.
+ *
+ * @param ch the character to look up
+ * @return the directionality constant, or DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+ * @see #DIRECTIONALITY_ARABIC_NUMBER
+ * @see #DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_NONSPACING_MARK
+ * @see #DIRECTIONALITY_BOUNDARY_NEUTRAL
+ * @see #DIRECTIONALITY_PARAGRAPH_SEPARATOR
+ * @see #DIRECTIONALITY_SEGMENT_SEPARATOR
+ * @see #DIRECTIONALITY_WHITESPACE
+ * @see #DIRECTIONALITY_OTHER_NEUTRALS
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+ * @see #DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+ * @since 1.4
+ */
+ public static native byte getDirectionality(char ch);
+
+ /**
+ * Returns the Unicode directionality property of the character. This
+ * is used in the visual ordering of text. Unlike getDirectionality(char),
+ * this method supports supplementary Unicode code points.
+ *
+ * @param codePoint the character to look up
+ * @return the directionality constant, or DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_UNDEFINED
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR
+ * @see #DIRECTIONALITY_ARABIC_NUMBER
+ * @see #DIRECTIONALITY_COMMON_NUMBER_SEPARATOR
+ * @see #DIRECTIONALITY_NONSPACING_MARK
+ * @see #DIRECTIONALITY_BOUNDARY_NEUTRAL
+ * @see #DIRECTIONALITY_PARAGRAPH_SEPARATOR
+ * @see #DIRECTIONALITY_SEGMENT_SEPARATOR
+ * @see #DIRECTIONALITY_WHITESPACE
+ * @see #DIRECTIONALITY_OTHER_NEUTRALS
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING
+ * @see #DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING
+ * @see #DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE
+ * @see #DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+ * @since 1.5
+ */
+ public static native byte getDirectionality(int codePoint);
+
+ /**
+ * Determines whether the character is mirrored according to Unicode. For
+ * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in
+ * left-to-right text, but ')' in right-to-left text.
+ *
+ * @param ch the character to look up
+ * @return true if the character is mirrored
+ * @since 1.4
+ */
+ public static boolean isMirrored(char ch)
+ {
+ return (readChar(ch) & MIRROR_MASK) != 0;
+ }
+
+ /**
+ * Determines whether the character is mirrored according to Unicode. For
+ * example, <code>\u0028</code> (LEFT PARENTHESIS) appears as '(' in
+ * left-to-right text, but ')' in right-to-left text. Unlike
+ * isMirrored(char), this method supports supplementary Unicode code points.
+ *
+ * @param codePoint the character to look up
+ * @return true if the character is mirrored
+ * @since 1.5
+ */
+ public static boolean isMirrored(int codePoint)
+ {
+ int plane = codePoint >>> 16;
+ if (plane > 2 && plane != 14)
+ return false;
+ return (readCodePoint(codePoint) & MIRROR_MASK) != 0;
+ }
+
+ /**
+ * Compares another Character to this Character, numerically.
+ *
+ * @param anotherCharacter Character to compare with this Character
+ * @return a negative integer if this Character is less than
+ * anotherCharacter, zero if this Character is equal, and
+ * a positive integer if this Character is greater
+ * @throws NullPointerException if anotherCharacter is null
+ * @since 1.2
+ */
+ public int compareTo(Character anotherCharacter)
+ {
+ return value - anotherCharacter.value;
+ }
+
+ /**
+ * Compares an object to this Character. Assuming the object is a
+ * Character object, this method performs the same comparison as
+ * compareTo(Character).
+ *
+ * @param o object to compare
+ * @return the comparison value
+ * @throws ClassCastException if o is not a Character object
+ * @throws NullPointerException if o is null
+ * @see #compareTo(Character)
+ * @since 1.2
+ */
+ public int compareTo(Object o)
+ {
+ return compareTo((Character) o);
+ }
+
+ /**
+ * Returns an <code>Character</code> object wrapping the value.
+ * In contrast to the <code>Character</code> constructor, this method
+ * will cache some values. It is used by boxing conversion.
+ *
+ * @param val the value to wrap
+ * @return the <code>Character</code>
+ *
+ * @since 1.5
+ */
+ public static Character valueOf(char val)
+ {
+ if (val > MAX_CACHE)
+ return new Character(val);
+ synchronized (charCache)
+ {
+ if (charCache[val - MIN_VALUE] == null)
+ charCache[val - MIN_VALUE] = new Character(val);
+ return charCache[val - MIN_VALUE];
+ }
+ }
+
+ /**
+ * Reverse the bytes in val.
+ * @since 1.5
+ */
+ public static char reverseBytes(char val)
+ {
+ return (char) (((val >> 8) & 0xff) | ((val << 8) & 0xff00));
+ }
+
+ /**
+ * Converts a unicode code point to a UTF-16 representation of that
+ * code point.
+ *
+ * @param codePoint the unicode code point
+ *
+ * @return the UTF-16 representation of that code point
+ *
+ * @throws IllegalArgumentException if the code point is not a valid
+ * unicode code point
+ *
+ * @since 1.5
+ */
+ public static char[] toChars(int codePoint)
+ {
+ char[] result = new char[charCount(codePoint)];
+ int ignore = toChars(codePoint, result, 0);
+ return result;
+ }
+
+ /**
+ * Converts a unicode code point to its UTF-16 representation.
+ *
+ * @param codePoint the unicode code point
+ * @param dst the target char array
+ * @param dstIndex the start index for the target
+ *
+ * @return number of characters written to <code>dst</code>
+ *
+ * @throws IllegalArgumentException if <code>codePoint</code> is not a
+ * valid unicode code point
+ * @throws NullPointerException if <code>dst</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if <code>dstIndex</code> is not valid
+ * in <code>dst</code> or if the UTF-16 representation does not
+ * fit into <code>dst</code>
+ *
+ * @since 1.5
+ */
+ public static int toChars(int codePoint, char[] dst, int dstIndex)
+ {
+ if (!isValidCodePoint(codePoint))
+ {
+ throw new IllegalArgumentException("not a valid code point: "
+ + codePoint);
+ }
+
+ int result;
+ if (isSupplementaryCodePoint(codePoint))
+ {
+ // Write second char first to cause IndexOutOfBoundsException
+ // immediately.
+ final int cp2 = codePoint - 0x10000;
+ dst[dstIndex + 1] = (char) ((cp2 % 0x400) + (int) MIN_LOW_SURROGATE);
+ dst[dstIndex] = (char) ((cp2 / 0x400) + (int) MIN_HIGH_SURROGATE);
+ result = 2;
+ }
+ else
+ {
+ dst[dstIndex] = (char) codePoint;
+ result = 1;
+ }
+ return result;
+ }
+
+ /**
+ * Return number of 16-bit characters required to represent the given
+ * code point.
+ *
+ * @param codePoint a unicode code point
+ *
+ * @return 2 if codePoint >= 0x10000, 1 otherwise.
+ *
+ * @since 1.5
+ */
+ public static int charCount(int codePoint)
+ {
+ return
+ (codePoint >= MIN_SUPPLEMENTARY_CODE_POINT)
+ ? 2
+ : 1;
+ }
+
+ /**
+ * Determines whether the specified code point is
+ * in the range 0x10000 .. 0x10FFFF, i.e. the character is within the Unicode
+ * supplementary character range.
+ *
+ * @param codePoint a Unicode code point
+ *
+ * @return <code>true</code> if code point is in supplementary range
+ *
+ * @since 1.5
+ */
+ public static boolean isSupplementaryCodePoint(int codePoint)
+ {
+ return codePoint >= MIN_SUPPLEMENTARY_CODE_POINT
+ && codePoint <= MAX_CODE_POINT;
+ }
+
+ /**
+ * Determines whether the specified code point is
+ * in the range 0x0000 .. 0x10FFFF, i.e. it is a valid Unicode code point.
+ *
+ * @param codePoint a Unicode code point
+ *
+ * @return <code>true</code> if code point is valid
+ *
+ * @since 1.5
+ */
+ public static boolean isValidCodePoint(int codePoint)
+ {
+ return codePoint >= MIN_CODE_POINT && codePoint <= MAX_CODE_POINT;
+ }
+
+ /**
+ * Return true if the given character is a high surrogate.
+ * @param ch the character
+ * @return true if the character is a high surrogate character
+ *
+ * @since 1.5
+ */
+ public static boolean isHighSurrogate(char ch)
+ {
+ return ch >= MIN_HIGH_SURROGATE && ch <= MAX_HIGH_SURROGATE;
+ }
+
+ /**
+ * Return true if the given character is a low surrogate.
+ * @param ch the character
+ * @return true if the character is a low surrogate character
+ *
+ * @since 1.5
+ */
+ public static boolean isLowSurrogate(char ch)
+ {
+ return ch >= MIN_LOW_SURROGATE && ch <= MAX_LOW_SURROGATE;
+ }
+
+ /**
+ * Return true if the given characters compose a surrogate pair.
+ * This is true if the first character is a high surrogate and the
+ * second character is a low surrogate.
+ * @param ch1 the first character
+ * @param ch2 the first character
+ * @return true if the characters compose a surrogate pair
+ *
+ * @since 1.5
+ */
+ public static boolean isSurrogatePair(char ch1, char ch2)
+ {
+ return isHighSurrogate(ch1) && isLowSurrogate(ch2);
+ }
+
+ /**
+ * Given a valid surrogate pair, this returns the corresponding
+ * code point.
+ * @param high the high character of the pair
+ * @param low the low character of the pair
+ * @return the corresponding code point
+ *
+ * @since 1.5
+ */
+ public static int toCodePoint(char high, char low)
+ {
+ return ((high - MIN_HIGH_SURROGATE) * 0x400) +
+ (low - MIN_LOW_SURROGATE) + 0x10000;
+ }
+
+ /**
+ * Get the code point at the specified index in the CharSequence.
+ * This is like CharSequence#charAt(int), but if the character is
+ * the start of a surrogate pair, and there is a following
+ * character, and this character completes the pair, then the
+ * corresponding supplementary code point is returned. Otherwise,
+ * the character at the index is returned.
+ *
+ * @param sequence the CharSequence
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointAt(CharSequence sequence, int index)
+ {
+ int len = sequence.length();
+ if (index < 0 || index >= len)
+ throw new IndexOutOfBoundsException();
+ char high = sequence.charAt(index);
+ if (! isHighSurrogate(high) || ++index >= len)
+ return high;
+ char low = sequence.charAt(index);
+ if (! isLowSurrogate(low))
+ return high;
+ return toCodePoint(high, low);
+ }
+
+ /**
+ * Get the code point at the specified index in the CharSequence.
+ * If the character is the start of a surrogate pair, and there is a
+ * following character, and this character completes the pair, then
+ * the corresponding supplementary code point is returned.
+ * Otherwise, the character at the index is returned.
+ *
+ * @param chars the character array in which to look
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointAt(char[] chars, int index)
+ {
+ return codePointAt(chars, index, chars.length);
+ }
+
+ /**
+ * Get the code point at the specified index in the CharSequence.
+ * If the character is the start of a surrogate pair, and there is a
+ * following character within the specified range, and this
+ * character completes the pair, then the corresponding
+ * supplementary code point is returned. Otherwise, the character
+ * at the index is returned.
+ *
+ * @param chars the character array in which to look
+ * @param index the index of the codepoint to get, starting at 0
+ * @param limit the limit past which characters should not be examined
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;=
+ * limit, or if limit is negative or &gt;= the length of the array
+ * @since 1.5
+ */
+ public static int codePointAt(char[] chars, int index, int limit)
+ {
+ if (index < 0 || index >= limit || limit < 0 || limit >= chars.length)
+ throw new IndexOutOfBoundsException();
+ char high = chars[index];
+ if (! isHighSurrogate(high) || ++index >= limit)
+ return high;
+ char low = chars[index];
+ if (! isLowSurrogate(low))
+ return high;
+ return toCodePoint(high, low);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(char[], int), but checks the characters at
+ * <code>index-1</code> and <code>index-2</code> to see if they form
+ * a supplementary code point. If they do not, the character at
+ * <code>index-1</code> is returned.
+ *
+ * @param chars the character array
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointBefore(char[] chars, int index)
+ {
+ return codePointBefore(chars, index, 1);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(char[], int), but checks the characters at
+ * <code>index-1</code> and <code>index-2</code> to see if they form
+ * a supplementary code point. If they do not, the character at
+ * <code>index-1</code> is returned. The start parameter is used to
+ * limit the range of the array which may be examined.
+ *
+ * @param chars the character array
+ * @param index the index just past the codepoint to get, starting at 0
+ * @param start the index before which characters should not be examined
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is &gt; start or &gt;
+ * the length of the array, or if limit is negative or &gt;= the
+ * length of the array
+ * @since 1.5
+ */
+ public static int codePointBefore(char[] chars, int index, int start)
+ {
+ if (index < start || index > chars.length
+ || start < 0 || start >= chars.length)
+ throw new IndexOutOfBoundsException();
+ --index;
+ char low = chars[index];
+ if (! isLowSurrogate(low) || --index < start)
+ return low;
+ char high = chars[index];
+ if (! isHighSurrogate(high))
+ return low;
+ return toCodePoint(high, low);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(CharSequence, int), but checks the characters at
+ * <code>index-1</code> and <code>index-2</code> to see if they form
+ * a supplementary code point. If they do not, the character at
+ * <code>index-1</code> is returned.
+ *
+ * @param sequence the CharSequence
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public static int codePointBefore(CharSequence sequence, int index)
+ {
+ int len = sequence.length();
+ if (index < 1 || index > len)
+ throw new IndexOutOfBoundsException();
+ --index;
+ char low = sequence.charAt(index);
+ if (! isLowSurrogate(low) || --index < 0)
+ return low;
+ char high = sequence.charAt(index);
+ if (! isHighSurrogate(high))
+ return low;
+ return toCodePoint(high, low);
+ }
+} // class Character
diff --git a/gcc-4.2.1/libjava/java/lang/Class.h b/gcc-4.2.1/libjava/java/lang/Class.h
new file mode 100644
index 000000000..a884cd6c5
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Class.h
@@ -0,0 +1,667 @@
+// Class.h - Header file for java.lang.Class. -*- c++ -*-
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written primary using compiler source and Class.java as guides.
+#ifndef __JAVA_LANG_CLASS_H__
+#define __JAVA_LANG_CLASS_H__
+
+#pragma interface
+
+#include <stddef.h>
+#include <java/lang/Object.h>
+#include <java/lang/String.h>
+#include <java/net/URL.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/security/ProtectionDomain.h>
+#include <java/lang/Package.h>
+
+// Avoid including SystemClassLoader.h.
+extern "Java"
+{
+ namespace gnu
+ {
+ namespace gcj
+ {
+ namespace runtime
+ {
+ class SystemClassLoader;
+ }
+ }
+ }
+}
+
+// We declare these here to avoid including gcj/cni.h.
+extern "C" void _Jv_InitClass (jclass klass);
+extern "C" jclass _Jv_NewClassFromInitializer
+ (const char *class_initializer);
+extern "C" void _Jv_RegisterNewClasses (char **classes);
+extern "C" void _Jv_RegisterClasses (const jclass *classes);
+extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes,
+ size_t count);
+
+// This must be predefined with "C" linkage.
+extern "C" void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
+ int meth_idx);
+extern "C" void *_Jv_ResolvePoolEntry (jclass this_class, jint index);
+
+// These are the possible values for the `state' field of the class
+// structure. Note that ordering is important here. Whenever the
+// state changes, one should notify all waiters of this class.
+enum
+{
+ JV_STATE_NOTHING = 0, // Set by compiler.
+
+ JV_STATE_PRELOADING = 1, // Can do _Jv_FindClass.
+
+ // There is an invariant through libgcj that a class will always be
+ // at a state greater than or equal to JV_STATE_LOADING when it is
+ // returned by a class loader to user code. Hence, defineclass.cc
+ // installs supers before returning a class, C++-ABI-compiled
+ // classes are created with supers installed, and BC-ABI-compiled
+ // classes are linked to this state before being returned by their
+ // class loader.
+ JV_STATE_LOADING = 3, // Has super installed.
+ JV_STATE_READ = 4, // Has been completely defined.
+ JV_STATE_LOADED = 5, // Has Miranda methods defined.
+
+ JV_STATE_COMPILED = 6, // This was a compiled class.
+
+ JV_STATE_PREPARED = 7, // Layout & static init done.
+ JV_STATE_LINKED = 9, // Strings interned.
+
+ JV_STATE_IN_PROGRESS = 10, // <clinit> running.
+
+ JV_STATE_ERROR = 12,
+
+ JV_STATE_PHANTOM = 13, // Bytecode is missing. In many cases we can
+ // work around that. If not, throw a
+ // NoClassDefFoundError.
+
+ JV_STATE_DONE = 14, // Must be last.
+
+
+};
+
+struct _Jv_Field;
+struct _Jv_VTable;
+union _Jv_word;
+struct _Jv_ArrayVTable;
+class _Jv_Linker;
+class _Jv_ExecutionEngine;
+class _Jv_CompiledEngine;
+class _Jv_IndirectCompiledEngine;
+class _Jv_InterpreterEngine;
+
+#ifdef INTERPRETER
+class _Jv_ClassReader;
+class _Jv_InterpClass;
+class _Jv_InterpMethod;
+#endif
+
+struct _Jv_Constants
+{
+ jint size;
+ jbyte *tags;
+ _Jv_word *data;
+};
+
+struct _Jv_Method
+{
+ // Method name.
+ _Jv_Utf8Const *name;
+ // Method signature.
+ _Jv_Utf8Const *signature;
+ // Access flags.
+ _Jv_ushort accflags;
+ // Method's index in the vtable.
+ _Jv_ushort index;
+ // Pointer to underlying function.
+ void *ncode;
+ // NULL-terminated list of exception class names; can be NULL if
+ // there are none such.
+ _Jv_Utf8Const **throws;
+
+ _Jv_Method *getNextMethod ()
+ { return this + 1; }
+};
+
+// The table used to resolve interface calls.
+struct _Jv_IDispatchTable
+{
+ // Index into interface's ioffsets.
+ jshort iindex;
+ jshort itable_length;
+ // Class Interface dispatch table.
+ void *itable[0];
+};
+
+// Used by _Jv_Linker::get_interfaces ()
+struct _Jv_ifaces
+{
+ jclass *list;
+ jshort len;
+ jshort count;
+};
+
+struct _Jv_MethodSymbol
+{
+ _Jv_Utf8Const *class_name;
+ _Jv_Utf8Const *name;
+ _Jv_Utf8Const *signature;
+};
+
+struct _Jv_OffsetTable
+{
+ jint state;
+ jint offsets[];
+};
+
+struct _Jv_AddressTable
+{
+ jint state;
+ void *addresses[];
+};
+
+struct _Jv_CatchClass
+{
+ java::lang::Class **address;
+ _Jv_Utf8Const *classname;
+};
+
+// Possible values for the assertion_code field in the type assertion table.
+enum
+{
+ JV_ASSERT_END_OF_TABLE = 0,
+ JV_ASSERT_TYPES_COMPATIBLE = 1,
+ JV_ASSERT_IS_INSTANTIABLE = 2
+};
+
+// Entry in the type assertion table, used to validate type constraints
+// for binary compatibility.
+struct _Jv_TypeAssertion
+{
+ jint assertion_code;
+ _Jv_Utf8Const *op1;
+ _Jv_Utf8Const *op2;
+};
+
+#define JV_PRIMITIVE_VTABLE ((_Jv_VTable *) -1)
+
+#define JV_CLASS(Obj) ((jclass) (*(_Jv_VTable **) Obj)->clas)
+
+// Forward declarations for friends of java::lang::Class
+
+// Friend functions implemented in natClass.cc.
+_Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+jboolean _Jv_IsAssignableFrom (jclass, jclass);
+jboolean _Jv_IsAssignableFromSlow (jclass, jclass);
+jboolean _Jv_InterfaceAssignableFrom (jclass, jclass);
+
+_Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
+ _Jv_Utf8Const*, jclass * = NULL);
+jfieldID JvGetFirstInstanceField (jclass);
+jint JvNumInstanceFields (jclass);
+jfieldID JvGetFirstStaticField (jclass);
+jint JvNumStaticFields (jclass);
+
+jobject _Jv_AllocObject (jclass);
+void *_Jv_AllocObj (jint, jclass);
+void *_Jv_AllocPtrFreeObj (jint, jclass);
+void *_Jv_AllocArray (jint, jclass);
+
+bool _Jv_getInterfaceMethod(jclass, jclass&, int&,
+ const _Jv_Utf8Const*,
+ const _Jv_Utf8Const*);
+
+jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID,
+ jboolean);
+jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID,
+ jboolean);
+jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
+
+jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
+jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
+jint JvNumMethods (jclass);
+jmethodID JvGetFirstMethod (jclass);
+_Jv_Utf8Const *_Jv_GetClassNameUtf8 (jclass);
+
+#ifdef INTERPRETER
+// Finds a desired interpreter method in the given class or NULL if not found
+class _Jv_MethodBase;
+_Jv_MethodBase *_Jv_FindInterpreterMethod (jclass, jmethodID);
+#endif
+
+// Friend classes and functions to implement the ClassLoader
+class java::lang::ClassLoader;
+class java::lang::VMClassLoader;
+
+class java::io::ObjectOutputStream;
+class java::io::ObjectInputStream;
+class java::io::ObjectStreamClass;
+
+void _Jv_RegisterClassHookDefault (jclass klass);
+void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+void _Jv_UnregisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+void _Jv_UnregisterClass (jclass);
+jclass _Jv_FindClassNoException (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+jclass _Jv_FindClass (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+jclass _Jv_FindClassInCache (_Jv_Utf8Const *name);
+jclass _Jv_PopClass (void);
+void _Jv_PushClass (jclass k);
+void _Jv_NewArrayClass (jclass element,
+ java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable = 0);
+jclass _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader);
+void _Jv_InitNewClassFields (jclass klass);
+
+// Friend functions and classes in prims.cc
+void _Jv_InitPrimClass (jclass, const char *, char, int);
+jstring _Jv_GetMethodString (jclass, _Jv_Method *, jclass = NULL);
+
+jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass,
+ jint flags);
+jclass _Jv_GetArrayClass (jclass klass, java::lang::ClassLoader *loader);
+
+jboolean _Jv_IsInterpretedClass (jclass);
+jboolean _Jv_IsBinaryCompatibilityABI (jclass);
+
+jboolean _Jv_IsPhantomClass (jclass);
+
+void _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *);
+
+#ifdef INTERPRETER
+void _Jv_InitField (jobject, jclass, int);
+#endif
+
+class _Jv_StackTrace;
+class _Jv_BytecodeVerifier;
+class java::io::VMObjectStreamClass;
+
+void _Jv_sharedlib_register_hook (jclass klass);
+
+
+class java::lang::Class : public java::lang::Object
+{
+public:
+ static jclass forName (jstring className, jboolean initialize,
+ java::lang::ClassLoader *loader);
+ static jclass forName (jstring className);
+ JArray<jclass> *getClasses (void);
+
+ java::lang::ClassLoader *getClassLoader (void);
+private:
+ java::lang::ClassLoader *getClassLoader (jclass caller);
+public:
+ // This is an internal method that circumvents the usual security
+ // checks when getting the class loader.
+ java::lang::ClassLoader *getClassLoaderInternal (void)
+ {
+ return loader;
+ }
+
+ java::lang::reflect::Constructor *getConstructor (JArray<jclass> *);
+ JArray<java::lang::reflect::Constructor *> *getConstructors (void);
+ java::lang::reflect::Constructor *getDeclaredConstructor (JArray<jclass> *);
+ JArray<java::lang::reflect::Constructor *> *getDeclaredConstructors (jboolean);
+ java::lang::reflect::Field *getDeclaredField (jstring);
+ JArray<java::lang::reflect::Field *> *getDeclaredFields ();
+ JArray<java::lang::reflect::Field *> *getDeclaredFields (jboolean);
+ java::lang::reflect::Method *getDeclaredMethod (jstring, JArray<jclass> *);
+ JArray<java::lang::reflect::Method *> *getDeclaredMethods (void);
+
+ JArray<jclass> *getDeclaredClasses (void);
+ JArray<jclass> *getDeclaredClasses (jboolean);
+ jclass getDeclaringClass (void);
+
+ java::lang::reflect::Field *getField (jstring);
+private:
+ JArray<java::lang::reflect::Field *> internalGetFields ();
+ java::lang::reflect::Field *getField (jstring, jint);
+ jint _getMethods (JArray<java::lang::reflect::Method *> *result,
+ jint offset);
+ java::lang::reflect::Field *getPrivateField (jstring);
+ java::lang::reflect::Method *getPrivateMethod (jstring, JArray<jclass> *);
+ java::security::ProtectionDomain *getProtectionDomain0 ();
+
+ java::lang::reflect::Method *_getMethod (jstring, JArray<jclass> *);
+ java::lang::reflect::Method *_getDeclaredMethod (jstring, JArray<jclass> *);
+
+public:
+ JArray<java::lang::reflect::Field *> *getFields (void);
+
+ JArray<jclass> *getInterfaces (void);
+
+ void getSignature (java::lang::StringBuffer *buffer);
+ static jstring getSignature (JArray<jclass> *, jboolean is_constructor);
+ JArray<java::lang::reflect::Method *> *getMethods (void);
+
+ inline jint getModifiers (void)
+ {
+ return accflags & java::lang::reflect::Modifier::ALL_FLAGS;
+ }
+
+ jstring getName (void);
+
+ java::net::URL *getResource (jstring resourceName);
+ java::io::InputStream *getResourceAsStream (jstring resourceName);
+ JArray<jobject> *getSigners (void);
+ void setSigners(JArray<jobject> *);
+
+ inline jclass getSuperclass (void)
+ {
+ return superclass;
+ }
+
+ inline jclass getInterface (jint n)
+ {
+ return interfaces[n];
+ }
+
+ inline jboolean isArray (void)
+ {
+ return name->first() == '[';
+ }
+
+ inline jclass getComponentType (void)
+ {
+ return isArray () ? element_type : 0;
+ }
+
+ jboolean isAssignableFrom (jclass cls);
+ jboolean isInstance (jobject obj);
+
+ inline jboolean isInterface (void)
+ {
+ return (accflags & java::lang::reflect::Modifier::INTERFACE) != 0;
+ }
+
+ inline jboolean isPrimitive (void)
+ {
+ return vtable == JV_PRIMITIVE_VTABLE;
+ }
+
+ jobject newInstance (void);
+ java::security::ProtectionDomain *getProtectionDomain (void);
+ java::lang::Package *getPackage (void);
+ jstring toString (void);
+ jboolean desiredAssertionStatus (void);
+
+ JArray<java::lang::reflect::TypeVariable *> *getTypeParameters (void);
+
+ java::lang::Class *getEnclosingClass (void);
+ java::lang::reflect::Constructor *getEnclosingConstructor (void);
+ java::lang::reflect::Method *getEnclosingMethod (void);
+ jboolean isEnum (void);
+
+ // FIXME: this probably shouldn't be public.
+ jint size (void)
+ {
+ return size_in_bytes;
+ }
+
+ // The index of the first method we declare ourself (as opposed to
+ // inheriting).
+ inline jint firstMethodIndex (void)
+ {
+ return vtable_method_count - method_count;
+ }
+
+ // finalization
+ void finalize ();
+
+ // This constructor is used to create Class object for the primitive
+ // types. See prims.cc.
+ Class ();
+
+ static java::lang::Class class$;
+
+private:
+
+ void memberAccessCheck (jint flags);
+
+ void initializeClass (void);
+
+ static jstring getPackagePortion (jstring);
+
+ void set_state (jint nstate)
+ {
+ state = nstate;
+ notifyAll ();
+ }
+
+ // Friend functions implemented in natClass.cc.
+ friend _Jv_Method *::_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature);
+ friend jboolean (::_Jv_IsAssignableFrom) (jclass, jclass);
+ friend jboolean (::_Jv_IsAssignableFromSlow) (jclass, jclass);
+ friend jboolean (::_Jv_InterfaceAssignableFrom) (jclass, jclass);
+ friend void *::_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
+ int method_idx);
+
+ friend void ::_Jv_InitClass (jclass klass);
+ friend java::lang::Class* ::_Jv_NewClassFromInitializer (const char *class_initializer);
+ friend void _Jv_RegisterNewClasses (void **classes);
+
+ friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
+ _Jv_Utf8Const*, jclass *);
+ friend jfieldID (::JvGetFirstInstanceField) (jclass);
+ friend jint (::JvNumInstanceFields) (jclass);
+ friend jfieldID (::JvGetFirstStaticField) (jclass);
+ friend jint (::JvNumStaticFields) (jclass);
+
+ friend jobject (::_Jv_AllocObject) (jclass);
+ friend void *::_Jv_AllocObj (jint, jclass);
+ friend void *::_Jv_AllocPtrFreeObj (jint, jclass);
+ friend void *::_Jv_AllocArray (jint, jclass);
+
+ friend jobject (::_Jv_JNI_ToReflectedField) (_Jv_JNIEnv *, jclass, jfieldID,
+ jboolean);
+ friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID,
+ jboolean);
+ friend jfieldID (::_Jv_FromReflectedField) (java::lang::reflect::Field *);
+
+ friend jmethodID (::_Jv_FromReflectedMethod) (java::lang::reflect::Method *);
+ friend jmethodID (::_Jv_FromReflectedConstructor) (java::lang::reflect::Constructor *);
+ friend jint (::JvNumMethods) (jclass);
+ friend jmethodID (::JvGetFirstMethod) (jclass);
+ friend _Jv_Utf8Const *::_Jv_GetClassNameUtf8 (jclass);
+#ifdef INTERPRETER
+ friend _Jv_MethodBase *(::_Jv_FindInterpreterMethod) (jclass klass,
+ jmethodID desired_method);
+#endif
+
+ // Friends classes and functions to implement the ClassLoader
+ friend class java::lang::ClassLoader;
+ friend class java::lang::VMClassLoader;
+
+ friend class java::io::ObjectOutputStream;
+ friend class java::io::ObjectInputStream;
+ friend class java::io::ObjectStreamClass;
+
+ friend void ::_Jv_RegisterClasses (const jclass *classes);
+ friend void ::_Jv_RegisterClasses_Counted (const jclass *classes,
+ size_t count);
+ friend void ::_Jv_RegisterClassHookDefault (jclass klass);
+ friend void ::_Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+ friend void ::_Jv_UnregisterInitiatingLoader (jclass,java::lang::ClassLoader*);
+ friend void ::_Jv_UnregisterClass (jclass);
+ friend jclass (::_Jv_FindClassNoException) (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+ friend jclass (::_Jv_FindClass) (_Jv_Utf8Const *name,
+ java::lang::ClassLoader *loader);
+ friend jclass (::_Jv_FindClassInCache) (_Jv_Utf8Const *name);
+ friend jclass (::_Jv_PopClass) (void);
+ friend void ::_Jv_PushClass (jclass k);
+ friend void ::_Jv_NewArrayClass (jclass element,
+ java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable);
+ friend jclass (::_Jv_NewClass) (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader);
+ friend void ::_Jv_InitNewClassFields (jclass klass);
+
+ // in prims.cc
+ friend void ::_Jv_InitPrimClass (jclass, const char *, char, int);
+
+ friend jstring (::_Jv_GetMethodString) (jclass, _Jv_Method *, jclass);
+
+ friend jboolean (::_Jv_CheckAccess) (jclass self_klass, jclass other_klass,
+ jint flags);
+
+ friend bool (::_Jv_getInterfaceMethod) (jclass, jclass&, int&,
+ const _Jv_Utf8Const*,
+ const _Jv_Utf8Const*);
+
+ friend jclass (::_Jv_GetArrayClass) (jclass klass,
+ java::lang::ClassLoader *loader);
+
+ friend jboolean (::_Jv_IsInterpretedClass) (jclass);
+ friend jboolean (::_Jv_IsBinaryCompatibilityABI) (jclass);
+
+ friend jboolean (::_Jv_IsPhantomClass) (jclass);
+
+#ifdef INTERPRETER
+ friend void ::_Jv_InitField (jobject, jclass, int);
+
+ friend class ::_Jv_ClassReader;
+ friend class ::_Jv_InterpClass;
+ friend class ::_Jv_InterpMethod;
+#endif
+ friend class ::_Jv_StackTrace;
+
+#ifdef JV_MARKOBJ_DECL
+ friend JV_MARKOBJ_DECL;
+#endif
+
+ friend class ::_Jv_BytecodeVerifier;
+ friend class java::io::VMObjectStreamClass;
+
+ friend class ::_Jv_Linker;
+ friend class ::_Jv_ExecutionEngine;
+ friend class ::_Jv_CompiledEngine;
+ friend class ::_Jv_IndirectCompiledEngine;
+ friend class ::_Jv_InterpreterEngine;
+
+ friend void ::_Jv_sharedlib_register_hook (jclass klass);
+
+ friend void *::_Jv_ResolvePoolEntry (jclass this_class, jint index);
+
+ friend void ::_Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *);
+
+ // Chain for class pool. This also doubles as the ABI version
+ // number. It is only used for this purpose at class registration
+ // time, and only for precompiled classes.
+ jclass next_or_version;
+ // Name of class.
+ _Jv_Utf8Const *name;
+ // Access flags for class.
+ _Jv_ushort accflags;
+ // The superclass, or null for Object.
+ jclass superclass;
+ // Class constants.
+ _Jv_Constants constants;
+ // Methods. If this is an array class, then this field holds a
+ // pointer to the element type.
+ union
+ {
+ _Jv_Method *methods;
+ jclass element_type;
+ };
+ // Number of methods. If this class is primitive, this holds the
+ // character used to represent this type in a signature.
+ jshort method_count;
+ // Number of methods in the vtable.
+ jshort vtable_method_count;
+ // The fields.
+ _Jv_Field *fields;
+ // Size of instance fields, in bytes.
+ jint size_in_bytes;
+ // Total number of fields (instance and static).
+ jshort field_count;
+ // Number of static fields.
+ jshort static_field_count;
+ // The vtbl for all objects of this class.
+ _Jv_VTable *vtable;
+ // Virtual method offset table.
+ _Jv_OffsetTable *otable;
+ // Offset table symbols.
+ _Jv_MethodSymbol *otable_syms;
+ // Address table
+ _Jv_AddressTable *atable;
+ _Jv_MethodSymbol *atable_syms;
+ // Interface table
+ _Jv_AddressTable *itable;
+ _Jv_MethodSymbol *itable_syms;
+ _Jv_CatchClass *catch_classes;
+ // Interfaces implemented by this class.
+ jclass *interfaces;
+ // The class loader for this class.
+ java::lang::ClassLoader *loader;
+ // Number of interfaces.
+ jshort interface_count;
+ // State of this class.
+ jbyte state;
+ // The thread which has locked this class. Used during class
+ // initialization.
+ java::lang::Thread *thread;
+ // How many levels of "extends" this class is removed from Object.
+ jshort depth;
+ // Vector of this class's superclasses, ordered by decreasing depth.
+ jclass *ancestors;
+ // In a regular class, this field points to the Class Interface Dispatch
+ // Table. In an interface, it points to the ioffsets table.
+ union
+ {
+ _Jv_IDispatchTable *idt;
+ jshort *ioffsets;
+ };
+ // Pointer to the class that represents an array of this class.
+ jclass arrayclass;
+ // Security Domain to which this class belongs (or null).
+ java::security::ProtectionDomain *protectionDomain;
+ // Pointer to the type assertion table for this class.
+ _Jv_TypeAssertion *assertion_table;
+ // Signers of this class (or null).
+ JArray<jobject> *hack_signers;
+ // Used by Jv_PopClass and _Jv_PushClass to communicate with StackTrace.
+ jclass chain;
+ // Additional data, specific to the generator (JIT, native,
+ // interpreter) of this class.
+ void *aux_info;
+ // Execution engine.
+ _Jv_ExecutionEngine *engine;
+};
+
+// Inline functions that are friends of java::lang::Class
+
+inline void _Jv_InitClass (jclass klass)
+{
+ if (__builtin_expect (klass->state == JV_STATE_DONE, true))
+ return;
+ klass->initializeClass ();
+}
+
+// Return array class corresponding to element type KLASS, creating it if
+// necessary.
+inline jclass
+_Jv_GetArrayClass (jclass klass, java::lang::ClassLoader *loader)
+{
+ extern void _Jv_NewArrayClass (jclass element,
+ java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable = 0);
+ if (__builtin_expect (!klass->arrayclass, false))
+ _Jv_NewArrayClass (klass, loader);
+ return klass->arrayclass;
+}
+
+#endif /* __JAVA_LANG_CLASS_H__ */
diff --git a/gcc-4.2.1/libjava/java/lang/Class.java b/gcc-4.2.1/libjava/java/lang/Class.java
new file mode 100644
index 000000000..75819e868
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Class.java
@@ -0,0 +1,1032 @@
+/* Class.java -- Representation of a Java class.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+ 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.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+
+/**
+ * A Class represents a Java type. There will never be multiple Class
+ * objects with identical names and ClassLoaders. Primitive types, array
+ * types, and void also have a Class object.
+ *
+ * <p>Arrays with identical type and number of dimensions share the same class.
+ * The array class ClassLoader is the same as the ClassLoader of the element
+ * type of the array (which can be null to indicate the bootstrap classloader).
+ * The name of an array class is <code>[&lt;signature format&gt;;</code>.
+ * <p> For example,
+ * String[]'s class is <code>[Ljava.lang.String;</code>. boolean, byte,
+ * short, char, int, long, float and double have the "type name" of
+ * Z,B,S,C,I,J,F,D for the purposes of array classes. If it's a
+ * multidimensioned array, the same principle applies:
+ * <code>int[][][]</code> == <code>[[[I</code>.
+ *
+ * <p>There is no public constructor - Class objects are obtained only through
+ * the virtual machine, as defined in ClassLoaders.
+ *
+ * @serialData Class objects serialize specially:
+ * <code>TC_CLASS ClassDescriptor</code>. For more serialization information,
+ * see {@link ObjectStreamClass}.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @since 1.0
+ * @see ClassLoader
+ */
+public final class Class implements Type, GenericDeclaration, Serializable
+{
+ /**
+ * Class is non-instantiable from Java code; only the VM can create
+ * instances of this class.
+ */
+ private Class ()
+ {
+ }
+
+ // Initialize the class.
+ private native void initializeClass ();
+
+ // finalization
+ protected native void finalize () throws Throwable;
+
+ /**
+ * Use the classloader of the current class to load, link, and initialize
+ * a class. This is equivalent to your code calling
+ * <code>Class.forName(name, true, getClass().getClassLoader())</code>.
+ *
+ * @param name the name of the class to find
+ * @return the Class object representing the class
+ * @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
+ */
+ public static native Class forName (String className)
+ throws ClassNotFoundException;
+
+ // A private internal method that is called by compiler-generated code.
+ private static Class forName (String className, Class caller)
+ throws ClassNotFoundException
+ {
+ return forName(className, true, caller.getClassLoaderInternal());
+ }
+
+
+ /**
+ * Use the specified classloader to load and link a class. If the loader
+ * is null, this uses the bootstrap class loader (provide the security
+ * check succeeds). Unfortunately, this method cannot be used to obtain
+ * the Class objects for primitive types or for void, you have to use
+ * the fields in the appropriate java.lang wrapper classes.
+ *
+ * <p>Calls <code>classloader.loadclass(name, initialize)</code>.
+ *
+ * @param name the name of the class to find
+ * @param initialize whether or not to initialize the class at this time
+ * @param classloader the classloader to use to find the class; null means
+ * to use the bootstrap class loader
+ * @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
+ * @throws SecurityException if the <code>classloader</code> argument
+ * is <code>null</code> and the caller does not have the
+ * <code>RuntimePermission("getClassLoader")</code> permission
+ * @see ClassLoader
+ * @since 1.2
+ */
+ public static native Class forName (String className, boolean initialize,
+ ClassLoader loader)
+ throws ClassNotFoundException;
+
+ /**
+ * Get all the public member classes and interfaces declared in this
+ * class or inherited from superclasses. This returns an array of length
+ * 0 if there are no member classes, including for primitive types. A
+ * security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public member classes in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Class[] getClasses()
+ {
+ memberAccessCheck(Member.PUBLIC);
+ return internalGetClasses();
+ }
+
+ /**
+ * Like <code>getClasses()</code> but without the security checks.
+ */
+ private Class[] internalGetClasses()
+ {
+ ArrayList list = new ArrayList();
+ list.addAll(Arrays.asList(getDeclaredClasses(true)));
+ Class superClass = getSuperclass();
+ if (superClass != null)
+ list.addAll(Arrays.asList(superClass.internalGetClasses()));
+ return (Class[])list.toArray(new Class[list.size()]);
+ }
+
+ /**
+ * Get the ClassLoader that loaded this class. If the class was loaded
+ * by the bootstrap classloader, this method will return null.
+ * If there is a security manager, and the caller's class loader is not
+ * an ancestor of the requested one, a security check of
+ * <code>RuntimePermission("getClassLoader")</code>
+ * must first succeed. Primitive types and void return null.
+ *
+ * @return the ClassLoader that loaded this class
+ * @throws SecurityException if the security check fails
+ * @see ClassLoader
+ * @see RuntimePermission
+ */
+ public native ClassLoader getClassLoader ();
+
+ // A private internal method that is called by compiler-generated code.
+ private final native ClassLoader getClassLoader (Class caller);
+
+ /**
+ * Internal method that circumvents the usual security checks when
+ * getting the class loader.
+ */
+ private native ClassLoader getClassLoaderInternal ();
+
+ /**
+ * 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.
+ *
+ * @return the array type of this class, or null
+ * @see Array
+ * @since 1.1
+ */
+ public native Class getComponentType ();
+
+ /**
+ * Get a public constructor declared in this class. If the constructor takes
+ * no argument, an array of zero elements and null are equivalent for the
+ * types argument. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param types the type of each parameter
+ * @return the constructor
+ * @throws NoSuchMethodException if the constructor does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getConstructors()
+ * @since 1.1
+ */
+ public native Constructor getConstructor(Class[] args)
+ throws NoSuchMethodException;
+
+ /**
+ * Get all the public constructors of this class. This returns an array of
+ * length 0 if there are no constructors, including for primitive types,
+ * arrays, and interfaces. It does, however, include the default
+ * constructor if one was supplied by the compiler. A security check may
+ * be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public constructors in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Constructor[] getConstructors()
+ {
+ memberAccessCheck(Member.PUBLIC);
+ return getDeclaredConstructors(true);
+ }
+
+ /**
+ * Get a constructor declared in this class. If the constructor takes no
+ * argument, an array of zero elements and null are equivalent for the
+ * types argument. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param types the type of each parameter
+ * @return the constructor
+ * @throws NoSuchMethodException if the constructor does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getDeclaredConstructors()
+ * @since 1.1
+ */
+ public native Constructor getDeclaredConstructor(Class[] args)
+ throws NoSuchMethodException;
+
+ /**
+ * Get all the declared member classes and interfaces in this class, but
+ * not those inherited from superclasses. This returns an array of length
+ * 0 if there are no member classes, including for primitive types. A
+ * security check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all declared member classes in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Class[] getDeclaredClasses()
+ {
+ memberAccessCheck(Member.DECLARED);
+ return getDeclaredClasses(false);
+ }
+
+ native Class[] getDeclaredClasses (boolean publicOnly);
+
+ /**
+ * Get all the declared constructors of this class. This returns an array of
+ * length 0 if there are no constructors, including for primitive types,
+ * arrays, and interfaces. It does, however, include the default
+ * constructor if one was supplied by the compiler. A security check may
+ * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all constructors in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Constructor[] getDeclaredConstructors()
+ {
+ memberAccessCheck(Member.DECLARED);
+ return getDeclaredConstructors(false);
+ }
+
+ native Constructor[] getDeclaredConstructors (boolean publicOnly);
+
+ /**
+ * Get a field declared in this class, where name is its simple name. The
+ * implicit length field of arrays is not available. A security check may
+ * be performed, with <code>checkMemberAccess(this, Member.DECLARED)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param name the name of the field
+ * @return the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getDeclaredFields()
+ * @since 1.1
+ */
+ public native Field getDeclaredField(String fieldName)
+ throws NoSuchFieldException;
+
+ /**
+ * Get all the declared fields in this class, but not those inherited from
+ * superclasses. This returns an array of length 0 if there are no fields,
+ * including for primitive types. This does not return the implicit length
+ * field of arrays. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all declared fields in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Field[] getDeclaredFields()
+ {
+ memberAccessCheck(Member.DECLARED);
+ return getDeclaredFields(false);
+ }
+
+ native Field[] getDeclaredFields (boolean publicOnly);
+
+ private native Method _getDeclaredMethod(String methodName, Class[] args);
+
+ /**
+ * Get a method declared in this class, where name is its simple name. The
+ * implicit methods of Object are not available from arrays or interfaces.
+ * Constructors (named "&lt;init&gt;" in the class file) and class initializers
+ * (name "&lt;clinit&gt;") are not available. The Virtual Machine allows
+ * multiple methods with the same signature but differing return types; in
+ * such a case the most specific return types are favored, then the final
+ * choice is arbitrary. If the method takes no argument, an array of zero
+ * elements and null are equivalent for the types argument. A security
+ * check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param methodName the name of the method
+ * @param types the type of each parameter
+ * @return the method
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getDeclaredMethods()
+ * @since 1.1
+ */
+ public Method getDeclaredMethod(String methodName, Class[] args)
+ throws NoSuchMethodException
+ {
+ memberAccessCheck(Member.DECLARED);
+
+ if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
+ throw new NoSuchMethodException(methodName);
+
+ Method match = _getDeclaredMethod(methodName, args);
+ if (match == null)
+ throw new NoSuchMethodException(methodName);
+ return match;
+ }
+
+ /**
+ * Get all the declared methods in this class, but not those inherited from
+ * superclasses. This returns an array of length 0 if there are no methods,
+ * including for primitive types. This does include the implicit methods of
+ * arrays and interfaces which mirror methods of Object, nor does it
+ * include constructors or the class initialization methods. The Virtual
+ * Machine allows multiple methods with the same signature but differing
+ * return types; all such methods are in the returned array. A security
+ * check may be performed, with
+ * <code>checkMemberAccess(this, Member.DECLARED)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all declared methods in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public native Method[] getDeclaredMethods();
+
+ /**
+ * If this is a nested or inner class, return the class that declared it.
+ * If not, return null.
+ *
+ * @return the declaring class of this class
+ * @since 1.1
+ */
+ // This is marked as unimplemented in the JCL book.
+ public native Class getDeclaringClass ();
+
+ private native Field getField (String fieldName, int hash)
+ throws NoSuchFieldException;
+
+ /**
+ * Get a public field declared or inherited in this class, where name is
+ * its simple name. If the class contains multiple accessible fields by
+ * that name, an arbitrary one is returned. The implicit length field of
+ * arrays is not available. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param fieldName the name of the field
+ * @return the field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getFields()
+ * @since 1.1
+ */
+ public Field getField(String fieldName)
+ throws NoSuchFieldException
+ {
+ memberAccessCheck(Member.PUBLIC);
+ Field field = getField(fieldName, fieldName.hashCode());
+ if (field == null)
+ throw new NoSuchFieldException(fieldName);
+ return field;
+ }
+
+ /**
+ * Get all the public fields declared in this class or inherited from
+ * superclasses. This returns an array of length 0 if there are no fields,
+ * including for primitive types. This does not return the implicit length
+ * field of arrays. A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public fields in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public Field[] getFields()
+ {
+ memberAccessCheck(Member.PUBLIC);
+ return internalGetFields();
+ }
+
+ /**
+ * Like <code>getFields()</code> but without the security checks.
+ */
+ private Field[] internalGetFields()
+ {
+ HashSet set = new HashSet();
+ set.addAll(Arrays.asList(getDeclaredFields(true)));
+ Class[] interfaces = getInterfaces();
+ for (int i = 0; i < interfaces.length; i++)
+ set.addAll(Arrays.asList(interfaces[i].internalGetFields()));
+ Class superClass = getSuperclass();
+ if (superClass != null)
+ set.addAll(Arrays.asList(superClass.internalGetFields()));
+ return (Field[])set.toArray(new Field[set.size()]);
+ }
+
+ /**
+ * Returns the <code>Package</code> in which this class is defined
+ * Returns null when this information is not available from the
+ * classloader of this class.
+ *
+ * @return the package for this class, if it is available
+ * @since 1.2
+ */
+ public Package getPackage()
+ {
+ ClassLoader cl = getClassLoaderInternal();
+ if (cl != null)
+ return cl.getPackage(getPackagePortion(getName()));
+ else
+ return VMClassLoader.getPackage(getPackagePortion(getName()));
+ }
+
+ /**
+ * 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.
+ *
+ * @return the interfaces this class directly implements
+ */
+ public native Class[] getInterfaces ();
+
+ private final native void getSignature(StringBuffer buffer);
+ private static final native String getSignature(Class[] args,
+ boolean is_construtor);
+
+ public native Method _getMethod(String methodName, Class[] args);
+
+ /**
+ * Get a public method declared or inherited in this class, where name is
+ * its simple name. The implicit methods of Object are not available from
+ * interfaces. Constructors (named "&lt;init&gt;" in the class file) and class
+ * initializers (name "&lt;clinit&gt;") are not available. The Virtual
+ * Machine allows multiple methods with the same signature but differing
+ * return types, and the class can inherit multiple methods of the same
+ * return type; in such a case the most specific return types are favored,
+ * then the final choice is arbitrary. If the method takes no argument, an
+ * array of zero elements and null are equivalent for the types argument.
+ * A security check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @param methodName the name of the method
+ * @param types the type of each parameter
+ * @return the method
+ * @throws NoSuchMethodException if the method does not exist
+ * @throws SecurityException if the security check fails
+ * @see #getMethods()
+ * @since 1.1
+ */
+ public Method getMethod(String methodName, Class[] args)
+ throws NoSuchMethodException
+ {
+ memberAccessCheck(Member.PUBLIC);
+
+ if ("<init>".equals(methodName) || "<clinit>".equals(methodName))
+ throw new NoSuchMethodException(methodName);
+
+ Method method = _getMethod(methodName, args);
+ if (method == null)
+ throw new NoSuchMethodException(methodName);
+ return method;
+ }
+
+ private native int _getMethods (Method[] result, int offset);
+
+ /**
+ * Get all the public methods declared in this class or inherited from
+ * superclasses. This returns an array of length 0 if there are no methods,
+ * including for primitive types. This does not include the implicit
+ * methods of interfaces which mirror methods of Object, nor does it
+ * include constructors or the class initialization methods. The Virtual
+ * Machine allows multiple methods with the same signature but differing
+ * return types; all such methods are in the returned array. A security
+ * check may be performed, with
+ * <code>checkMemberAccess(this, Member.PUBLIC)</code> as well as
+ * <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return all public methods in this class
+ * @throws SecurityException if the security check fails
+ * @since 1.1
+ */
+ public native Method[] getMethods();
+
+ /**
+ * 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.
+ *
+ * @return the modifiers of this class
+ * @see Modifer
+ * @since 1.1
+ */
+ public native int getModifiers ();
+
+ /**
+ * Get the name of this class, separated by dots for package separators.
+ * If the class represents a primitive type, or void, then the
+ * name of the type as it appears in the Java programming language
+ * is returned. For instance, <code>Byte.TYPE.getName()</code>
+ * returns "byte".
+ *
+ * Arrays are specially encoded as shown on this table.
+ * <pre>
+ * array type [<em>element type</em>
+ * (note that the element type is encoded per
+ * this table)
+ * boolean Z
+ * byte B
+ * char C
+ * short S
+ * int I
+ * long J
+ * float F
+ * double D
+ * void V
+ * class or interface, alone: &lt;dotted name&gt;
+ * class or interface, as element type: L&lt;dotted name&gt;;
+ * </pre>
+ *
+ * @return the name of this class
+ */
+ public native String getName ();
+
+ /**
+ * Get a resource URL using this class's package using the
+ * getClassLoader().getResource() method. If this class was loaded using
+ * the system classloader, ClassLoader.getSystemResource() is used instead.
+ *
+ * <p>If the name you supply is absolute (it starts with a <code>/</code>),
+ * then the leading <code>/</code> is removed and it is passed on to
+ * getResource(). If it is relative, the package name is prepended, and
+ * <code>.</code>'s are replaced with <code>/</code>.
+ *
+ * <p>The URL returned is system- and classloader-dependent, and could
+ * change across implementations.
+ *
+ * @param resourceName the name of the resource, generally a path
+ * @return the URL to the resource
+ * @throws NullPointerException if name is null
+ * @since 1.1
+ */
+ public URL getResource(String resourceName)
+ {
+ String name = resourcePath(resourceName);
+ ClassLoader loader = getClassLoaderInternal();
+ if (loader == null)
+ return ClassLoader.getSystemResource(name);
+ return loader.getResource(name);
+ }
+
+ /**
+ * Get a resource using this class's package using the
+ * getClassLoader().getResourceAsStream() method. If this class was loaded
+ * using the system classloader, ClassLoader.getSystemResource() is used
+ * instead.
+ *
+ * <p>If the name you supply is absolute (it starts with a <code>/</code>),
+ * then the leading <code>/</code> is removed and it is passed on to
+ * getResource(). If it is relative, the package name is prepended, and
+ * <code>.</code>'s are replaced with <code>/</code>.
+ *
+ * <p>The URL returned is system- and classloader-dependent, and could
+ * change across implementations.
+ *
+ * @param resourceName the name of the resource, generally a path
+ * @return an InputStream with the contents of the resource in it, or null
+ * @throws NullPointerException if name is null
+ * @since 1.1
+ */
+ public InputStream getResourceAsStream(String resourceName)
+ {
+ String name = resourcePath(resourceName);
+ ClassLoader loader = getClassLoaderInternal();
+ if (loader == null)
+ return ClassLoader.getSystemResourceAsStream(name);
+ return loader.getResourceAsStream(name);
+ }
+
+ private String resourcePath(String resourceName)
+ {
+ if (resourceName.length() > 0)
+ {
+ if (resourceName.charAt(0) != '/')
+ {
+ String pkg = getPackagePortion(getName());
+ if (pkg.length() > 0)
+ resourceName = pkg.replace('.','/') + '/' + resourceName;
+ }
+ else
+ {
+ resourceName = resourceName.substring(1);
+ }
+ }
+ return resourceName;
+ }
+
+ /**
+ * Get the signers of this class. This returns null if there are no signers,
+ * such as for primitive types or void.
+ *
+ * @return the signers of this class
+ * @since 1.1
+ */
+ public native Object[] getSigners ();
+
+ /**
+ * Set the signers of this class.
+ *
+ * @param signers the signers of this class
+ */
+ native void setSigners(Object[] signers);
+
+ /**
+ * 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.
+ *
+ * @return the direct superclass of this class
+ */
+ public native Class getSuperclass ();
+
+ /**
+ * Return whether this class is an array type.
+ *
+ * @return whether this class is an array type
+ * @since 1.1
+ */
+ public native boolean isArray ();
+
+ /**
+ * 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 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
+ */
+ public native boolean isAssignableFrom (Class c);
+
+ /**
+ * Discover whether an Object is an instance of this Class. Think of it
+ * as almost like <code>o instanceof (this class)</code>.
+ *
+ * @param o the Object to check
+ * @return whether o is an instance of this class
+ * @since 1.1
+ */
+ public native boolean isInstance (Object o);
+
+ /**
+ * Check whether this class is an interface or not. Array types are not
+ * interfaces.
+ *
+ * @return whether this class is an interface or not
+ */
+ public native boolean isInterface ();
+
+ /**
+ * 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.
+ *
+ * @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
+ */
+ public native boolean isPrimitive ();
+
+ /**
+ * Get a new instance of this class by calling the no-argument constructor.
+ * The class is initialized if it has not been already. A security check
+ * may be performed, with <code>checkMemberAccess(this, Member.PUBLIC)</code>
+ * as well as <code>checkPackageAccess</code> both having to succeed.
+ *
+ * @return a new instance of this class
+ * @throws InstantiationException if there is not a no-arg constructor
+ * for this class, including interfaces, abstract classes, arrays,
+ * primitive types, and void; or if an exception occurred during
+ * the constructor
+ * @throws IllegalAccessException if you are not allowed to access the
+ * no-arg constructor because of scoping reasons
+ * @throws SecurityException if the security check fails
+ * @throws ExceptionInInitializerError if class initialization caused by
+ * this call fails with an exception
+ */
+ public native Object newInstance ()
+ throws InstantiationException, IllegalAccessException;
+
+ // We need a native method to retrieve the protection domain, because we
+ // can't add fields to java.lang.Class that are accessible from Java.
+ private native ProtectionDomain getProtectionDomain0();
+
+ /**
+ * Returns the protection domain of this class. If the classloader did not
+ * record the protection domain when creating this class the unknown
+ * protection domain is returned which has a <code>null</code> code source
+ * and all permissions. A security check may be performed, with
+ * <code>RuntimePermission("getProtectionDomain")</code>.
+ *
+ * @return the protection domain
+ * @throws SecurityException if the security manager exists and the caller
+ * does not have <code>RuntimePermission("getProtectionDomain")</code>.
+ * @see RuntimePermission
+ * @since 1.2
+ */
+ public ProtectionDomain getProtectionDomain()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(VMClassLoader.protectionDomainPermission);
+
+ ProtectionDomain protectionDomain = getProtectionDomain0();
+
+ if (protectionDomain == null)
+ return VMClassLoader.unknownProtectionDomain;
+ else
+ return protectionDomain;
+ }
+
+ /**
+ * Return the human-readable form of this Object. For an object, this
+ * is either "interface " or "class " followed by <code>getName()</code>,
+ * for primitive types and void it is just <code>getName()</code>.
+ *
+ * @return the human-readable form of this Object
+ */
+ public String toString()
+ {
+ if (isPrimitive())
+ return getName();
+ return (isInterface() ? "interface " : "class ") + getName();
+ }
+
+ /**
+ * Returns the desired assertion status of this class, if it were to be
+ * initialized at this moment. The class assertion status, if set, is
+ * returned; the backup is the default package status; then if there is
+ * a class loader, that default is returned; and finally the system default
+ * is returned. This method seldom needs calling in user code, but exists
+ * for compilers to implement the assert statement. Note that there is no
+ * guarantee that the result of this method matches the class's actual
+ * assertion status.
+ *
+ * @return the desired assertion status
+ * @see ClassLoader#setClassAssertionStatus(String, boolean)
+ * @see ClassLoader#setPackageAssertionStatus(String, boolean)
+ * @see ClassLoader#setDefaultAssertionStatus(boolean)
+ * @since 1.4
+ */
+ public boolean desiredAssertionStatus()
+ {
+ ClassLoader c = getClassLoaderInternal();
+ Object status;
+ if (c == null)
+ return VMClassLoader.defaultAssertionStatus();
+ if (c.classAssertionStatus != null)
+ synchronized (c)
+ {
+ status = c.classAssertionStatus.get(getName());
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ else
+ {
+ status = ClassLoader.systemClassAssertionStatus.get(getName());
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ if (c.packageAssertionStatus != null)
+ synchronized (c)
+ {
+ String name = getPackagePortion(getName());
+ if ("".equals(name))
+ status = c.packageAssertionStatus.get(null);
+ else
+ do
+ {
+ status = c.packageAssertionStatus.get(name);
+ name = getPackagePortion(name);
+ }
+ while (! "".equals(name) && status == null);
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ else
+ {
+ String name = getPackagePortion(getName());
+ if ("".equals(name))
+ status = ClassLoader.systemPackageAssertionStatus.get(null);
+ else
+ do
+ {
+ status = ClassLoader.systemPackageAssertionStatus.get(name);
+ name = getPackagePortion(name);
+ }
+ while (! "".equals(name) && status == null);
+ if (status != null)
+ return status.equals(Boolean.TRUE);
+ }
+ return c.defaultAssertionStatus;
+ }
+
+ /**
+ * Strip the last portion of the name (after the last dot).
+ *
+ * @param name the name to get package of
+ * @return the package name, or "" if no package
+ */
+ private static String getPackagePortion(String name)
+ {
+ int lastInd = name.lastIndexOf('.');
+ if (lastInd == -1)
+ return "";
+ return name.substring(0, lastInd);
+ }
+
+ /**
+ * Perform security checks common to all of the methods that
+ * get members of this Class.
+ */
+ private void memberAccessCheck(int which)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ sm.checkMemberAccess(this, which);
+ Package pkg = getPackage();
+ if (pkg != null)
+ sm.checkPackageAccess(pkg.getName());
+ }
+ }
+
+ /**
+ * Returns the simple name for this class, as used in the source
+ * code. For normal classes, this is the content returned by
+ * <code>getName()</code> which follows the last ".". Anonymous
+ * classes have no name, and so the result of calling this method is
+ * "". The simple name of an array consists of the simple name of
+ * its component type, followed by "[]". Thus, an array with the
+ * component type of an anonymous class has a simple name of simply
+ * "[]".
+ *
+ * @return the simple name for this class.
+ * @since 1.5
+ */
+ public String getSimpleName()
+ {
+ // FIXME write real implementation
+ return "";
+ }
+
+ /**
+ * Returns the class which immediately encloses this class. If this class
+ * is a top-level class, this method returns <code>null</code>.
+ *
+ * @return the immediate enclosing class, or <code>null</code> if this is
+ * a top-level class.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should return Class<?> */
+ public Class getEnclosingClass()
+ {
+ // FIXME write real implementation
+ return null;
+ }
+
+ /**
+ * Returns the constructor which immediately encloses this class. If
+ * this class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @return the immediate enclosing constructor if this class is
+ * declared within a constructor. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should return Constructor<?> */
+ public Constructor getEnclosingConstructor()
+ {
+ // FIXME write real implementation
+ return null;
+ }
+
+ /**
+ * Returns the method which immediately encloses this class. If
+ * this class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @return the immediate enclosing method if this class is
+ * declared within a method. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ public Method getEnclosingMethod()
+ {
+ // FIXME write real implementation
+ return null;
+ }
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this class, in declaration order.
+ * An array of size zero is returned if this class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should return TypeVariable<Class<T>> */
+ public TypeVariable[] getTypeParameters()
+ {
+ // FIXME - provide real implementation.
+ return new TypeVariable[0];
+ }
+
+ /**
+ * Returns true if this class is an <code>Enum</code>.
+ *
+ * @return true if this is an enumeration class.
+ * @since 1.5
+ */
+ public boolean isEnum()
+ {
+ // FIXME - provide real implementation.
+ return false;
+ }
+
+}
diff --git a/gcc-4.2.1/libjava/java/lang/ClassLoader.java b/gcc-4.2.1/libjava/java/lang/ClassLoader.java
new file mode 100644
index 000000000..bcbfc298b
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/ClassLoader.java
@@ -0,0 +1,998 @@
+/* ClassLoader.java -- responsible for loading classes into the VM
+ Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006 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 gnu.classpath.SystemProperties;
+import gnu.java.util.DoubleEnumeration;
+import gnu.java.util.EmptyEnumeration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The ClassLoader is a way of customizing the way Java gets its classes
+ * and loads them into memory. The verifier and other standard Java things
+ * still run, but the ClassLoader is allowed great flexibility in determining
+ * where to get the classfiles and when to load and resolve them. For that
+ * matter, a custom ClassLoader can perform on-the-fly code generation or
+ * modification!
+ *
+ * <p>Every classloader has a parent classloader that is consulted before
+ * the 'child' classloader when classes or resources should be loaded.
+ * This is done to make sure that classes can be loaded from an hierarchy of
+ * multiple classloaders and classloaders do not accidentially redefine
+ * already loaded classes by classloaders higher in the hierarchy.
+ *
+ * <p>The grandparent of all classloaders is the bootstrap classloader, which
+ * loads all the standard system classes as implemented by GNU Classpath. The
+ * other special classloader is the system classloader (also called
+ * application classloader) that loads all classes from the CLASSPATH
+ * (<code>java.class.path</code> system property). The system classloader
+ * is responsible for finding the application classes from the classpath,
+ * and delegates all requests for the standard library classes to its parent
+ * the bootstrap classloader. Most programs will load all their classes
+ * through the system classloaders.
+ *
+ * <p>The bootstrap classloader in GNU Classpath is implemented as a couple of
+ * static (native) methods on the package private class
+ * <code>java.lang.VMClassLoader</code>, the system classloader is an
+ * instance of <code>gnu.java.lang.SystemClassLoader</code>
+ * (which is a subclass of <code>java.net.URLClassLoader</code>).
+ *
+ * <p>Users of a <code>ClassLoader</code> will normally just use the methods
+ * <ul>
+ * <li> <code>loadClass()</code> to load a class.</li>
+ * <li> <code>getResource()</code> or <code>getResourceAsStream()</code>
+ * to access a resource.</li>
+ * <li> <code>getResources()</code> to get an Enumeration of URLs to all
+ * the resources provided by the classloader and its parents with the
+ * same name.</li>
+ * </ul>
+ *
+ * <p>Subclasses should implement the methods
+ * <ul>
+ * <li> <code>findClass()</code> which is called by <code>loadClass()</code>
+ * when the parent classloader cannot provide a named class.</li>
+ * <li> <code>findResource()</code> which is called by
+ * <code>getResource()</code> when the parent classloader cannot provide
+ * a named resource.</li>
+ * <li> <code>findResources()</code> which is called by
+ * <code>getResource()</code> to combine all the resources with the
+ * same name from the classloader and its parents.</li>
+ * <li> <code>findLibrary()</code> which is called by
+ * <code>Runtime.loadLibrary()</code> when a class defined by the
+ * classloader wants to load a native library.</li>
+ * </ul>
+ *
+ * @author John Keiser
+ * @author Mark Wielaard
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Class
+ * @since 1.0
+ * @status still missing 1.4 functionality
+ */
+public abstract class ClassLoader
+{
+ /**
+ * All classes loaded by this classloader. VM's may choose to implement
+ * this cache natively; but it is here available for use if necessary. It
+ * is not private in order to allow native code (and trusted subclasses)
+ * access to this field.
+ */
+ final HashMap loadedClasses = new HashMap();
+
+ /**
+ * All packages defined by this classloader. It is not private in order to
+ * allow native code (and trusted subclasses) access to this field.
+ */
+ final HashMap definedPackages = new HashMap();
+
+ /**
+ * The classloader that is consulted before this classloader.
+ * If null then the parent is the bootstrap classloader.
+ */
+ private final ClassLoader parent;
+
+ /**
+ * This is true if this classloader was successfully initialized.
+ * This flag is needed to avoid a class loader attack: even if the
+ * security manager rejects an attempt to create a class loader, the
+ * malicious class could have a finalize method which proceeds to
+ * define classes.
+ */
+ private final boolean initialized;
+
+ /**
+ * System/Application classloader: defaults to an instance of
+ * gnu.java.lang.SystemClassLoader, unless the first invocation of
+ * getSystemClassLoader loads another class loader because of the
+ * java.system.class.loader property. The initialization of this field
+ * is somewhat circular - getSystemClassLoader() checks whether this
+ * field is null in order to bypass a security check.
+ */
+ static final ClassLoader systemClassLoader =
+ VMClassLoader.getSystemClassLoader();
+
+ static
+ {
+ // Find out if we have to install a default security manager. Note
+ // that this is done here because we potentially need the system
+ // class loader to load the security manager and note also that we
+ // don't need the security manager until the system class loader
+ // is created. If the runtime chooses to use a class loader that
+ // doesn't have the system class loader as its parent, it is
+ // responsible for setting up a security manager before doing so.
+ String secman = SystemProperties.getProperty("java.security.manager");
+ if (secman != null && SecurityManager.current == null)
+ {
+ if (secman.equals("") || secman.equals("default"))
+ {
+ SecurityManager.current = new SecurityManager();
+ }
+ else
+ {
+ try
+ {
+ Class cl = Class.forName(secman, false, systemClassLoader);
+ SecurityManager.current = (SecurityManager) cl.newInstance();
+ }
+ catch (Exception x)
+ {
+ throw (InternalError)
+ new InternalError("Unable to create SecurityManager")
+ .initCause(x);
+ }
+ }
+ }
+ }
+
+ /**
+ * The default protection domain, used when defining a class with a null
+ * paramter for the domain.
+ */
+ static final ProtectionDomain defaultProtectionDomain;
+ static
+ {
+ CodeSource cs = new CodeSource(null, null);
+ PermissionCollection perm = Policy.getPolicy().getPermissions(cs);
+ defaultProtectionDomain = new ProtectionDomain(cs, perm);
+ }
+
+ /**
+ * The desired assertion status of classes loaded by this loader, if not
+ * overridden by package or class instructions.
+ */
+ // Package visible for use by Class.
+ boolean defaultAssertionStatus = VMClassLoader.defaultAssertionStatus();
+
+ /**
+ * The command-line state of the package assertion status overrides. This
+ * map is never modified, so it does not need to be synchronized.
+ */
+ // Package visible for use by Class.
+ static final Map systemPackageAssertionStatus
+ = VMClassLoader.packageAssertionStatus();
+
+ /**
+ * The map of package assertion status overrides, or null if no package
+ * overrides have been specified yet. The values of the map should be
+ * Boolean.TRUE or Boolean.FALSE, and the unnamed package is represented
+ * by the null key. This map must be synchronized on this instance.
+ */
+ // Package visible for use by Class.
+ Map packageAssertionStatus;
+
+ /**
+ * The command-line state of the class assertion status overrides. This
+ * map is never modified, so it does not need to be synchronized.
+ */
+ // Package visible for use by Class.
+ static final Map systemClassAssertionStatus
+ = VMClassLoader.classAssertionStatus();
+
+ /**
+ * The map of class assertion status overrides, or null if no class
+ * overrides have been specified yet. The values of the map should be
+ * Boolean.TRUE or Boolean.FALSE. This map must be synchronized on this
+ * instance.
+ */
+ // Package visible for use by Class.
+ Map classAssertionStatus;
+
+ /**
+ * Create a new ClassLoader with as parent the system classloader. There
+ * may be a security check for <code>checkCreateClassLoader</code>.
+ *
+ * @throws SecurityException if the security check fails
+ */
+ protected ClassLoader() throws SecurityException
+ {
+ this(systemClassLoader);
+ }
+
+ /**
+ * Create a new ClassLoader with the specified parent. The parent will
+ * be consulted when a class or resource is requested through
+ * <code>loadClass()</code> or <code>getResource()</code>. Only when the
+ * parent classloader cannot provide the requested class or resource the
+ * <code>findClass()</code> or <code>findResource()</code> method
+ * of this classloader will be called. There may be a security check for
+ * <code>checkCreateClassLoader</code>.
+ *
+ * @param parent the classloader's parent, or null for the bootstrap
+ * classloader
+ * @throws SecurityException if the security check fails
+ * @since 1.2
+ */
+ protected ClassLoader(ClassLoader parent)
+ {
+ // May we create a new classloader?
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkCreateClassLoader();
+ this.parent = parent;
+ this.initialized = true;
+ }
+
+ /**
+ * Load a class using this ClassLoader or its parent, without resolving
+ * it. Calls <code>loadClass(name, false)</code>.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findClass()</code> which is called by this method.</p>
+ *
+ * @param name the name of the class relative to this ClassLoader
+ * @return the loaded class
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ public Class loadClass(String name) throws ClassNotFoundException
+ {
+ return loadClass(name, false);
+ }
+
+ private native Class loadClassFromSig(String name)
+ throws ClassNotFoundException;
+
+ /**
+ * Load a class using this ClassLoader or its parent, possibly resolving
+ * it as well using <code>resolveClass()</code>. It first tries to find
+ * out if the class has already been loaded through this classloader by
+ * calling <code>findLoadedClass()</code>. Then it calls
+ * <code>loadClass()</code> on the parent classloader (or when there is
+ * no parent it uses the VM bootclassloader). If the class is still
+ * not loaded it tries to create a new class by calling
+ * <code>findClass()</code>. Finally when <code>resolve</code> is
+ * <code>true</code> it also calls <code>resolveClass()</code> on the
+ * newly loaded class.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findClass()</code> which is called by this method.</p>
+ *
+ * @param name the fully qualified name of the class to load
+ * @param resolve whether or not to resolve the class
+ * @return the loaded class
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ protected synchronized Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ // Arrays are handled specially.
+ Class c;
+ if (name.length() > 0 && name.charAt(0) == '[')
+ c = loadClassFromSig(name);
+ else
+ {
+ // Have we already loaded this class?
+ c = findLoadedClass(name);
+ if (c == null)
+ {
+ // Can the class be loaded by a parent?
+ try
+ {
+ if (parent == null)
+ {
+ c = VMClassLoader.loadClass(name, resolve);
+ if (c != null)
+ return c;
+ }
+ else
+ {
+ return parent.loadClass(name, resolve);
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ }
+ // Still not found, we have to do it ourself.
+ c = findClass(name);
+ }
+ }
+ if (resolve)
+ resolveClass(c);
+ return c;
+ }
+
+ /**
+ * Called for every class name that is needed but has not yet been
+ * defined by this classloader or one of its parents. It is called by
+ * <code>loadClass()</code> after both <code>findLoadedClass()</code> and
+ * <code>parent.loadClass()</code> couldn't provide the requested class.
+ *
+ * <p>The default implementation throws a
+ * <code>ClassNotFoundException</code>. Subclasses should override this
+ * method. An implementation of this method in a subclass should get the
+ * class bytes of the class (if it can find them), if the package of the
+ * requested class doesn't exist it should define the package and finally
+ * it should call define the actual class. It does not have to resolve the
+ * class. It should look something like the following:<br>
+ *
+ * <pre>
+ * // Get the bytes that describe the requested class
+ * byte[] classBytes = classLoaderSpecificWayToFindClassBytes(name);
+ * // Get the package name
+ * int lastDot = name.lastIndexOf('.');
+ * if (lastDot != -1)
+ * {
+ * String packageName = name.substring(0, lastDot);
+ * // Look if the package already exists
+ * if (getPackage(packageName) == null)
+ * {
+ * // define the package
+ * definePackage(packageName, ...);
+ * }
+ * }
+ * // Define and return the class
+ * return defineClass(name, classBytes, 0, classBytes.length);
+ * </pre>
+ *
+ * <p><code>loadClass()</code> makes sure that the <code>Class</code>
+ * returned by <code>findClass()</code> will later be returned by
+ * <code>findLoadedClass()</code> when the same class name is requested.
+ *
+ * @param name class name to find (including the package name)
+ * @return the requested Class
+ * @throws ClassNotFoundException when the class can not be found
+ * @since 1.2
+ */
+ protected Class findClass(String name) throws ClassNotFoundException
+ {
+ throw new ClassNotFoundException(name);
+ }
+
+ /**
+ * Helper to define a class using a string of bytes. This version is not
+ * secure.
+ *
+ * @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
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ * @throws IndexOutOfBoundsException if offset or len is negative, or
+ * offset + len exceeds data
+ * @deprecated use {@link #defineClass(String, byte[], int, int)} instead
+ */
+ protected final Class defineClass(byte[] data, int offset, int len)
+ throws ClassFormatError
+ {
+ return defineClass(null, data, offset, len);
+ }
+
+ /**
+ * Helper to define a class using a string of bytes without a
+ * ProtectionDomain. Subclasses should call this method from their
+ * <code>findClass()</code> implementation. The name should use '.'
+ * separators, and discard the trailing ".class". The default protection
+ * domain has the permissions of
+ * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>.
+ *
+ * @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
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ * @throws IndexOutOfBoundsException if offset or len is negative, or
+ * offset + len exceeds data
+ * @throws SecurityException if name starts with "java."
+ * @since 1.1
+ */
+ protected final Class defineClass(String name, byte[] data, int offset,
+ int len) throws ClassFormatError
+ {
+ return defineClass(name, data, offset, len, null);
+ }
+
+ /**
+ * Helper to define a class using a string of bytes. Subclasses should call
+ * this method from their <code>findClass()</code> implementation. If the
+ * domain is null, the default of
+ * <code>Policy.getPolicy().getPermissions(new CodeSource(null, null))</code>
+ * is used. Once a class has been defined in a package, all further classes
+ * in that package must have the same set of certificates or a
+ * SecurityException is thrown.
+ *
+ * @param name the name to give the class. 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 domain the ProtectionDomain to give to the class, null for the
+ * default protection domain
+ * @return the class that was defined
+ * @throws ClassFormatError if data is not in proper classfile format
+ * @throws IndexOutOfBoundsException if offset or len is negative, or
+ * offset + len exceeds data
+ * @throws SecurityException if name starts with "java.", or if certificates
+ * do not match up
+ * @since 1.2
+ */
+ protected final synchronized Class defineClass(String name, byte[] data,
+ int offset, int len,
+ ProtectionDomain domain)
+ throws ClassFormatError
+ {
+ if (domain == null)
+ domain = defaultProtectionDomain;
+ if (! initialized)
+ throw new SecurityException("attempt to define class from uninitialized class loader");
+
+ Class retval = VMClassLoader.defineClass(this, name, data,
+ offset, len, domain);
+ loadedClasses.put(retval.getName(), retval);
+ return retval;
+ }
+
+ /**
+ * Links the class, if that has not already been done. Linking basically
+ * resolves all references to other classes made by this class.
+ *
+ * @param c the class to resolve
+ * @throws NullPointerException if c is null
+ * @throws LinkageError if linking fails
+ */
+ protected final void resolveClass(Class c)
+ {
+ VMClassLoader.resolveClass(c);
+ }
+
+ /**
+ * Helper to find a Class using the system classloader, possibly loading it.
+ * A subclass usually does not need to call this, if it correctly
+ * overrides <code>findClass(String)</code>.
+ *
+ * @param name the name of the class to find
+ * @return the found class
+ * @throws ClassNotFoundException if the class cannot be found
+ */
+ protected final Class findSystemClass(String name)
+ throws ClassNotFoundException
+ {
+ return Class.forName(name, false, systemClassLoader);
+ }
+
+ /**
+ * Returns the parent of this classloader. If the parent of this
+ * classloader is the bootstrap classloader then this method returns
+ * <code>null</code>. A security check may be performed on
+ * <code>RuntimePermission("getClassLoader")</code>.
+ *
+ * @return the parent <code>ClassLoader</code>
+ * @throws SecurityException if the security check fails
+ * @since 1.2
+ */
+ public final ClassLoader getParent()
+ {
+ // Check if we may return the parent classloader.
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ Class c = VMSecurityManager.getClassContext(ClassLoader.class)[0];
+ ClassLoader cl = c.getClassLoader();
+ if (cl != null && ! cl.isAncestorOf(this))
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+ return parent;
+ }
+
+ /**
+ * Helper to set the signers of a class. This should be called after
+ * defining the class.
+ *
+ * @param c the Class to set signers of
+ * @param signers the signers to set
+ * @since 1.1
+ */
+ protected final void setSigners(Class c, Object[] signers)
+ {
+ c.setSigners(signers);
+ }
+
+ /**
+ * Helper to find an already-loaded class in this ClassLoader.
+ *
+ * @param name the name of the class to find
+ * @return the found Class, or null if it is not found
+ * @since 1.1
+ */
+ protected final synchronized Class findLoadedClass(String name)
+ {
+ // NOTE: If the VM is keeping its own cache, it may make sense to have
+ // this method be native.
+ return (Class) loadedClasses.get(name);
+ }
+
+ /**
+ * Get the URL to a resource using this classloader or one of its parents.
+ * First tries to get the resource by calling <code>getResource()</code>
+ * on the parent classloader. If the parent classloader returns null then
+ * it tries finding the resource by calling <code>findResource()</code> on
+ * this classloader. The resource name should be separated by '/' for path
+ * elements.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findResource()</code> which is called by this method.
+ *
+ * @param name the name of the resource relative to this classloader
+ * @return the URL to the resource or null when not found
+ */
+ public URL getResource(String name)
+ {
+ URL result;
+
+ if (parent == null)
+ result = VMClassLoader.getResource(name);
+ else
+ result = parent.getResource(name);
+
+ if (result == null)
+ result = findResource(name);
+ return result;
+ }
+
+ /**
+ * Returns an Enumeration of all resources with a given name that can
+ * be found by this classloader and its parents. Certain classloaders
+ * (such as the URLClassLoader when given multiple jar files) can have
+ * multiple resources with the same name that come from multiple locations.
+ * It can also occur that a parent classloader offers a resource with a
+ * certain name and the child classloader also offers a resource with that
+ * same name. <code>getResource()</code> only offers the first resource (of the
+ * parent) with a given name. This method lists all resources with the
+ * same name. The name should use '/' as path separators.
+ *
+ * <p>The Enumeration is created by first calling <code>getResources()</code>
+ * on the parent classloader and then calling <code>findResources()</code>
+ * on this classloader.</p>
+ *
+ * @param name the resource name
+ * @return an enumaration of all resources found
+ * @throws IOException if I/O errors occur in the process
+ * @since 1.2
+ */
+ public final Enumeration getResources(String name) throws IOException
+ {
+ Enumeration parentResources;
+ if (parent == null)
+ parentResources = VMClassLoader.getResources(name);
+ else
+ parentResources = parent.getResources(name);
+ return new DoubleEnumeration(parentResources, findResources(name));
+ }
+
+ /**
+ * Called whenever all locations of a named resource are needed.
+ * It is called by <code>getResources()</code> after it has called
+ * <code>parent.getResources()</code>. The results are combined by
+ * the <code>getResources()</code> method.
+ *
+ * <p>The default implementation always returns an empty Enumeration.
+ * Subclasses should override it when they can provide an Enumeration of
+ * URLs (possibly just one element) to the named resource.
+ * The first URL of the Enumeration should be the same as the one
+ * returned by <code>findResource</code>.
+ *
+ * @param name the name of the resource to be found
+ * @return a possibly empty Enumeration of URLs to the named resource
+ * @throws IOException if I/O errors occur in the process
+ * @since 1.2
+ */
+ protected Enumeration findResources(String name) throws IOException
+ {
+ return EmptyEnumeration.getInstance();
+ }
+
+ /**
+ * Called whenever a resource is needed that could not be provided by
+ * one of the parents of this classloader. It is called by
+ * <code>getResource()</code> after <code>parent.getResource()</code>
+ * couldn't provide the requested resource.
+ *
+ * <p>The default implementation always returns null. Subclasses should
+ * override this method when they can provide a way to return a URL
+ * to a named resource.
+ *
+ * @param name the name of the resource to be found
+ * @return a URL to the named resource or null when not found
+ * @since 1.2
+ */
+ protected URL findResource(String name)
+ {
+ return null;
+ }
+
+ /**
+ * Get the URL to a resource using the system classloader.
+ *
+ * @param name the name of the resource relative to the system classloader
+ * @return the URL to the resource
+ * @since 1.1
+ */
+ public static final URL getSystemResource(String name)
+ {
+ return systemClassLoader.getResource(name);
+ }
+
+ /**
+ * Get an Enumeration of URLs to resources with a given name using the
+ * the system classloader. The enumeration firsts lists the resources with
+ * the given name that can be found by the bootstrap classloader followed
+ * by the resources with the given name that can be found on the classpath.
+ *
+ * @param name the name of the resource relative to the system classloader
+ * @return an Enumeration of URLs to the resources
+ * @throws IOException if I/O errors occur in the process
+ * @since 1.2
+ */
+ public static Enumeration getSystemResources(String name) throws IOException
+ {
+ return systemClassLoader.getResources(name);
+ }
+
+ /**
+ * Get a resource as stream using this classloader or one of its parents.
+ * First calls <code>getResource()</code> and if that returns a URL to
+ * the resource then it calls and returns the InputStream given by
+ * <code>URL.openStream()</code>.
+ *
+ * <p>Subclasses should not override this method but should override
+ * <code>findResource()</code> which is called by this method.
+ *
+ * @param name the name of the resource relative to this classloader
+ * @return an InputStream to the resource, or null
+ * @since 1.1
+ */
+ public InputStream getResourceAsStream(String name)
+ {
+ try
+ {
+ URL url = getResource(name);
+ if (url == null)
+ return null;
+ return url.openStream();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Get a resource using the system classloader.
+ *
+ * @param name the name of the resource relative to the system classloader
+ * @return an input stream for the resource, or null
+ * @since 1.1
+ */
+ public static final InputStream getSystemResourceAsStream(String name)
+ {
+ try
+ {
+ URL url = getSystemResource(name);
+ if (url == null)
+ return null;
+ return url.openStream();
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the system classloader. The system classloader (also called
+ * the application classloader) is the classloader that was used to
+ * load the application classes on the classpath (given by the system
+ * property <code>java.class.path</code>. This is set as the context
+ * class loader for a thread. The system property
+ * <code>java.system.class.loader</code>, if defined, is taken to be the
+ * name of the class to use as the system class loader, which must have
+ * a public constructor which takes a ClassLoader as a parent; otherwise this
+ * uses gnu.java.lang.SystemClassLoader.
+ *
+ * <p>Note that this is different from the bootstrap classloader that
+ * actually loads all the real "system" classes (the bootstrap classloader
+ * is the parent of the returned system classloader).
+ *
+ * <p>A security check will be performed for
+ * <code>RuntimePermission("getClassLoader")</code> if the calling class
+ * is not a parent of the system class loader.
+ *
+ * @return the system class loader
+ * @throws SecurityException if the security check fails
+ * @throws IllegalStateException if this is called recursively
+ * @throws Error if <code>java.system.class.loader</code> fails to load
+ * @since 1.2
+ */
+ public static ClassLoader getSystemClassLoader()
+ {
+ // Check if we may return the system classloader
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ Class c = VMSecurityManager.getClassContext(ClassLoader.class)[0];
+ ClassLoader cl = c.getClassLoader();
+ if (cl != null && cl != systemClassLoader)
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+
+ return systemClassLoader;
+ }
+
+ /**
+ * Defines a new package and creates a Package object. The package should
+ * be defined before any class in the package is defined with
+ * <code>defineClass()</code>. The package should not yet be defined
+ * before in this classloader or in one of its parents (which means that
+ * <code>getPackage()</code> should return <code>null</code>). All
+ * parameters except the <code>name</code> of the package may be
+ * <code>null</code>.
+ *
+ * <p>Subclasses should call this method from their <code>findClass()</code>
+ * implementation before calling <code>defineClass()</code> on a Class
+ * in a not yet defined Package (which can be checked by calling
+ * <code>getPackage()</code>).
+ *
+ * @param name the name of the Package
+ * @param specTitle the name of the specification
+ * @param specVendor the name of the specification designer
+ * @param specVersion the version of this specification
+ * @param implTitle the name of the implementation
+ * @param implVendor the vendor that wrote this implementation
+ * @param implVersion the version of this implementation
+ * @param sealed if sealed the origin of the package classes
+ * @return the Package object for the specified package
+ * @throws IllegalArgumentException if the package name is null or it
+ * was already defined by this classloader or one of its parents
+ * @see Package
+ * @since 1.2
+ */
+ protected Package definePackage(String name, String specTitle,
+ String specVendor, String specVersion,
+ String implTitle, String implVendor,
+ String implVersion, URL sealed)
+ {
+ if (getPackage(name) != null)
+ throw new IllegalArgumentException("Package " + name
+ + " already defined");
+ Package p = new Package(name, specTitle, specVendor, specVersion,
+ implTitle, implVendor, implVersion, sealed);
+ synchronized (definedPackages)
+ {
+ definedPackages.put(name, p);
+ }
+ return p;
+ }
+
+ /**
+ * Returns the Package object for the requested package name. It returns
+ * null when the package is not defined by this classloader or one of its
+ * parents.
+ *
+ * @param name the package name to find
+ * @return the package, if defined
+ * @since 1.2
+ */
+ protected Package getPackage(String name)
+ {
+ Package p;
+ if (parent == null)
+ p = VMClassLoader.getPackage(name);
+ else
+ p = parent.getPackage(name);
+
+ if (p == null)
+ {
+ synchronized (definedPackages)
+ {
+ p = (Package) definedPackages.get(name);
+ }
+ }
+ return p;
+ }
+
+ /**
+ * Returns all Package objects defined by this classloader and its parents.
+ *
+ * @return an array of all defined packages
+ * @since 1.2
+ */
+ protected Package[] getPackages()
+ {
+ // Get all our packages.
+ Package[] packages;
+ synchronized(definedPackages)
+ {
+ packages = new Package[definedPackages.size()];
+ definedPackages.values().toArray(packages);
+ }
+
+ // If we have a parent get all packages defined by our parents.
+ Package[] parentPackages;
+ if (parent == null)
+ parentPackages = VMClassLoader.getPackages();
+ else
+ parentPackages = parent.getPackages();
+
+ Package[] allPackages = new Package[parentPackages.length
+ + packages.length];
+ System.arraycopy(parentPackages, 0, allPackages, 0,
+ parentPackages.length);
+ System.arraycopy(packages, 0, allPackages, parentPackages.length,
+ packages.length);
+ return allPackages;
+ }
+
+ /**
+ * Called by <code>Runtime.loadLibrary()</code> to get an absolute path
+ * to a (system specific) library that was requested by a class loaded
+ * by this classloader. The default implementation returns
+ * <code>null</code>. It should be implemented by subclasses when they
+ * have a way to find the absolute path to a library. If this method
+ * returns null the library is searched for in the default locations
+ * (the directories listed in the <code>java.library.path</code> system
+ * property).
+ *
+ * @param name the (system specific) name of the requested library
+ * @return the full pathname to the requested library, or null
+ * @see Runtime#loadLibrary()
+ * @since 1.2
+ */
+ protected String findLibrary(String name)
+ {
+ return null;
+ }
+
+ /**
+ * Set the default assertion status for classes loaded by this classloader,
+ * used unless overridden by a package or class request.
+ *
+ * @param enabled true to set the default to enabled
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public void setDefaultAssertionStatus(boolean enabled)
+ {
+ defaultAssertionStatus = enabled;
+ }
+
+ /**
+ * Set the default assertion status for packages, used unless overridden
+ * by a class request. This default also covers subpackages, unless they
+ * are also specified. The unnamed package should use null for the name.
+ *
+ * @param name the package (and subpackages) to affect
+ * @param enabled true to set the default to enabled
+ * @see #setDefaultAssertionStatus(String, boolean)
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public synchronized void setPackageAssertionStatus(String name,
+ boolean enabled)
+ {
+ if (packageAssertionStatus == null)
+ packageAssertionStatus
+ = new HashMap(systemPackageAssertionStatus);
+ packageAssertionStatus.put(name, Boolean.valueOf(enabled));
+ }
+
+ /**
+ * Set the default assertion status for a class. This only affects the
+ * status of top-level classes, any other string is harmless.
+ *
+ * @param name the class to affect
+ * @param enabled true to set the default to enabled
+ * @throws NullPointerException if name is null
+ * @see #setDefaultAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @see #clearAssertionStatus()
+ * @since 1.4
+ */
+ public synchronized void setClassAssertionStatus(String name,
+ boolean enabled)
+ {
+ if (classAssertionStatus == null)
+ classAssertionStatus = new HashMap(systemClassAssertionStatus);
+ // The toString() hack catches null, as required.
+ classAssertionStatus.put(name.toString(), Boolean.valueOf(enabled));
+ }
+
+ /**
+ * Resets the default assertion status of this classloader, its packages
+ * and classes, all to false. This allows overriding defaults inherited
+ * from the command line.
+ *
+ * @see #setDefaultAssertionStatus(boolean)
+ * @see #setClassAssertionStatus(String, boolean)
+ * @see #setPackageAssertionStatus(String, boolean)
+ * @since 1.4
+ */
+ public synchronized void clearAssertionStatus()
+ {
+ defaultAssertionStatus = false;
+ packageAssertionStatus = new HashMap();
+ classAssertionStatus = new HashMap();
+ }
+
+ /**
+ * Return true if this loader is either the specified class loader
+ * or an ancestor thereof.
+ * @param loader the class loader to check
+ */
+ final boolean isAncestorOf(ClassLoader loader)
+ {
+ while (loader != null)
+ {
+ if (this == loader)
+ return true;
+ loader = loader.parent;
+ }
+ return false;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/EcosProcess.java b/gcc-4.2.1/libjava/java/lang/EcosProcess.java
new file mode 100644
index 000000000..aff534a39
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/EcosProcess.java
@@ -0,0 +1,63 @@
+// EcosProcess.java - Subclass of Process for eCos systems.
+
+/* Copyright (C) 1998, 1999 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date May 11, 1999
+ */
+
+// This is entirely internal to our implementation.
+
+// This file is copied to `ConcreteProcess.java' before compilation.
+// Hence the class name apparently does not match the file name.
+final class ConcreteProcess extends Process
+{
+ // See natEcosProcess.cc to understand why this is native.
+ public native void destroy ();
+
+ public int exitValue ()
+ {
+ return 0;
+ }
+ public InputStream getErrorStream ()
+ {
+ return null;
+ }
+
+ public InputStream getInputStream ()
+ {
+ return null;
+ }
+
+ public OutputStream getOutputStream ()
+ {
+ return null;
+ }
+
+ public int waitFor () throws InterruptedException
+ {
+ return 0;
+ }
+
+ public ConcreteProcess (String[] progarray,
+ String[] envp,
+ File dir)
+ throws IOException
+ {
+ throw new IOException ("eCos processes unimplemented");
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/Math.java b/gcc-4.2.1/libjava/java/lang/Math.java
new file mode 100644
index 000000000..836b8bd86
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Math.java
@@ -0,0 +1,973 @@
+/* java.lang.Math -- common mathematical functions, native allowed
+ Copyright (C) 1998, 2001, 2002, 2003, 2006 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 gnu.classpath.Configuration;
+
+import java.util.Random;
+
+/**
+ * Helper class containing useful mathematical functions and constants.
+ * <P>
+ *
+ * Note that angles are specified in radians. Conversion functions are
+ * provided for your convenience.
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ */
+public final class Math
+{
+ /**
+ * Math is non-instantiable
+ */
+ private Math()
+ {
+ }
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalang");
+ }
+ }
+
+ /**
+ * A random number generator, initialized on first use.
+ */
+ private static Random rand;
+
+ /**
+ * The most accurate approximation to the mathematical constant <em>e</em>:
+ * <code>2.718281828459045</code>. Used in natural log and exp.
+ *
+ * @see #log(double)
+ * @see #exp(double)
+ */
+ public static final double E = 2.718281828459045;
+
+ /**
+ * The most accurate approximation to the mathematical constant <em>pi</em>:
+ * <code>3.141592653589793</code>. This is the ratio of a circle's diameter
+ * to its circumference.
+ */
+ public static final double PI = 3.141592653589793;
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ * <P>
+ *
+ * Note that the the largest negative value (Integer.MIN_VALUE) cannot
+ * be made positive. In this case, because of the rules of negation in
+ * a computer, MIN_VALUE is what will be returned.
+ * This is a <em>negative</em> value. You have been warned.
+ *
+ * @param i the number to take the absolute value of
+ * @return the absolute value
+ * @see Integer#MIN_VALUE
+ */
+ public static int abs(int i)
+ {
+ return (i < 0) ? -i : i;
+ }
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ * <P>
+ *
+ * Note that the the largest negative value (Long.MIN_VALUE) cannot
+ * be made positive. In this case, because of the rules of negation in
+ * a computer, MIN_VALUE is what will be returned.
+ * This is a <em>negative</em> value. You have been warned.
+ *
+ * @param l the number to take the absolute value of
+ * @return the absolute value
+ * @see Long#MIN_VALUE
+ */
+ public static long abs(long l)
+ {
+ return (l < 0) ? -l : l;
+ }
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ * <P>
+ *
+ * This is equivalent, but faster than, calling
+ * <code>Float.intBitsToFloat(0x7fffffff & Float.floatToIntBits(a))</code>.
+ *
+ * @param f the number to take the absolute value of
+ * @return the absolute value
+ */
+ public static float abs(float f)
+ {
+ return (f <= 0) ? 0 - f : f;
+ }
+
+ /**
+ * Take the absolute value of the argument.
+ * (Absolute value means make it positive.)
+ *
+ * This is equivalent, but faster than, calling
+ * <code>Double.longBitsToDouble(Double.doubleToLongBits(a)
+ * &lt;&lt; 1) &gt;&gt;&gt; 1);</code>.
+ *
+ * @param d the number to take the absolute value of
+ * @return the absolute value
+ */
+ public static double abs(double d)
+ {
+ return (d <= 0) ? 0 - d : d;
+ }
+
+ /**
+ * Return whichever argument is smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static int min(int a, int b)
+ {
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static long min(long a, long b)
+ {
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is smaller. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, -0 is always smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static float min(float a, float b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; < will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return -(-a - b);
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is smaller. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, -0 is always smaller.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the smaller of the two numbers
+ */
+ public static double min(double a, double b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; < will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return -(-a - b);
+ return (a < b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static int max(int a, int b)
+ {
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static long max(long a, long b)
+ {
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, 0 is always larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static float max(float a, float b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; > will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return a - -b;
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * Return whichever argument is larger. If either argument is NaN, the
+ * result is NaN, and when comparing 0 and -0, 0 is always larger.
+ *
+ * @param a the first number
+ * @param b a second number
+ * @return the larger of the two numbers
+ */
+ public static double max(double a, double b)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return a;
+ // no need to check if b is NaN; > will work correctly
+ // recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
+ if (a == 0 && b == 0)
+ return a - -b;
+ return (a > b) ? a : b;
+ }
+
+ /**
+ * The trigonometric function <em>sin</em>. The sine of NaN or infinity is
+ * NaN, and the sine of 0 retains its sign. This is accurate within 1 ulp,
+ * and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return sin(a)
+ */
+ public static native double sin(double a);
+
+ /**
+ * The trigonometric function <em>cos</em>. The cosine of NaN or infinity is
+ * NaN. This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return cos(a)
+ */
+ public static native double cos(double a);
+
+ /**
+ * The trigonometric function <em>tan</em>. The tangent of NaN or infinity
+ * is NaN, and the tangent of 0 retains its sign. This is accurate within 1
+ * ulp, and is semi-monotonic.
+ *
+ * @param a the angle (in radians)
+ * @return tan(a)
+ */
+ public static native double tan(double a);
+
+ /**
+ * The trigonometric function <em>arcsin</em>. The range of angles returned
+ * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN or
+ * its absolute value is beyond 1, the result is NaN; and the arcsine of
+ * 0 retains its sign. This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the sin to turn back into an angle
+ * @return arcsin(a)
+ */
+ public static native double asin(double a);
+
+ /**
+ * The trigonometric function <em>arccos</em>. The range of angles returned
+ * is 0 to pi radians (0 to 180 degrees). If the argument is NaN or
+ * its absolute value is beyond 1, the result is NaN. This is accurate
+ * within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the cos to turn back into an angle
+ * @return arccos(a)
+ */
+ public static native double acos(double a);
+
+ /**
+ * The trigonometric function <em>arcsin</em>. The range of angles returned
+ * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN, the
+ * result is NaN; and the arctangent of 0 retains its sign. This is accurate
+ * within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the tan to turn back into an angle
+ * @return arcsin(a)
+ * @see #atan2(double, double)
+ */
+ public static native double atan(double a);
+
+ /**
+ * A special version of the trigonometric function <em>arctan</em>, for
+ * converting rectangular coordinates <em>(x, y)</em> to polar
+ * <em>(r, theta)</em>. This computes the arctangent of x/y in the range
+ * of -pi to pi radians (-180 to 180 degrees). Special cases:<ul>
+ * <li>If either argument is NaN, the result is NaN.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * positive, or the first argument is positive and finite and the second
+ * argument is positive infinity, then the result is positive zero.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * positive, or the first argument is negative and finite and the second
+ * argument is positive infinity, then the result is negative zero.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * negative, or the first argument is positive and finite and the second
+ * argument is negative infinity, then the result is the double value
+ * closest to pi.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * negative, or the first argument is negative and finite and the second
+ * argument is negative infinity, then the result is the double value
+ * closest to -pi.</li>
+ * <li>If the first argument is positive and the second argument is
+ * positive zero or negative zero, or the first argument is positive
+ * infinity and the second argument is finite, then the result is the
+ * double value closest to pi/2.</li>
+ * <li>If the first argument is negative and the second argument is
+ * positive zero or negative zero, or the first argument is negative
+ * infinity and the second argument is finite, then the result is the
+ * double value closest to -pi/2.</li>
+ * <li>If both arguments are positive infinity, then the result is the
+ * double value closest to pi/4.</li>
+ * <li>If the first argument is positive infinity and the second argument
+ * is negative infinity, then the result is the double value closest to
+ * 3*pi/4.</li>
+ * <li>If the first argument is negative infinity and the second argument
+ * is positive infinity, then the result is the double value closest to
+ * -pi/4.</li>
+ * <li>If both arguments are negative infinity, then the result is the
+ * double value closest to -3*pi/4.</li>
+ *
+ * </ul><p>This is accurate within 2 ulps, and is semi-monotonic. To get r,
+ * use sqrt(x*x+y*y).
+ *
+ * @param y the y position
+ * @param x the x position
+ * @return <em>theta</em> in the conversion of (x, y) to (r, theta)
+ * @see #atan(double)
+ */
+ public static native double atan2(double y, double x);
+
+ /**
+ * Take <em>e</em><sup>a</sup>. The opposite of <code>log()</code>. If the
+ * argument is NaN, the result is NaN; if the argument is positive infinity,
+ * the result is positive infinity; and if the argument is negative
+ * infinity, the result is positive zero. This is accurate within 1 ulp,
+ * and is semi-monotonic.
+ *
+ * @param a the number to raise to the power
+ * @return the number raised to the power of <em>e</em>
+ * @see #log(double)
+ * @see #pow(double, double)
+ */
+ public static native double exp(double a);
+
+ /**
+ * Take ln(a) (the natural log). The opposite of <code>exp()</code>. If the
+ * argument is NaN or negative, the result is NaN; if the argument is
+ * positive infinity, the result is positive infinity; and if the argument
+ * is either zero, the result is negative infinity. This is accurate within
+ * 1 ulp, and is semi-monotonic.
+ *
+ * <p>Note that the way to get log<sub>b</sub>(a) is to do this:
+ * <code>ln(a) / ln(b)</code>.
+ *
+ * @param a the number to take the natural log of
+ * @return the natural log of <code>a</code>
+ * @see #exp(double)
+ */
+ public static native double log(double a);
+
+ /**
+ * Take a square root. If the argument is NaN or negative, the result is
+ * NaN; if the argument is positive infinity, the result is positive
+ * infinity; and if the result is either zero, the result is the same.
+ * This is accurate within the limits of doubles.
+ *
+ * <p>For other roots, use pow(a, 1 / rootNumber).
+ *
+ * @param a the numeric argument
+ * @return the square root of the argument
+ * @see #pow(double, double)
+ */
+ public static native double sqrt(double a);
+
+ /**
+ * Raise a number to a power. Special cases:<ul>
+ * <li>If the second argument is positive or negative zero, then the result
+ * is 1.0.</li>
+ * <li>If the second argument is 1.0, then the result is the same as the
+ * first argument.</li>
+ * <li>If the second argument is NaN, then the result is NaN.</li>
+ * <li>If the first argument is NaN and the second argument is nonzero,
+ * then the result is NaN.</li>
+ * <li>If the absolute value of the first argument is greater than 1 and
+ * the second argument is positive infinity, or the absolute value of the
+ * first argument is less than 1 and the second argument is negative
+ * infinity, then the result is positive infinity.</li>
+ * <li>If the absolute value of the first argument is greater than 1 and
+ * the second argument is negative infinity, or the absolute value of the
+ * first argument is less than 1 and the second argument is positive
+ * infinity, then the result is positive zero.</li>
+ * <li>If the absolute value of the first argument equals 1 and the second
+ * argument is infinite, then the result is NaN.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * greater than zero, or the first argument is positive infinity and the
+ * second argument is less than zero, then the result is positive zero.</li>
+ * <li>If the first argument is positive zero and the second argument is
+ * less than zero, or the first argument is positive infinity and the
+ * second argument is greater than zero, then the result is positive
+ * infinity.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * greater than zero but not a finite odd integer, or the first argument is
+ * negative infinity and the second argument is less than zero but not a
+ * finite odd integer, then the result is positive zero.</li>
+ * <li>If the first argument is negative zero and the second argument is a
+ * positive finite odd integer, or the first argument is negative infinity
+ * and the second argument is a negative finite odd integer, then the result
+ * is negative zero.</li>
+ * <li>If the first argument is negative zero and the second argument is
+ * less than zero but not a finite odd integer, or the first argument is
+ * negative infinity and the second argument is greater than zero but not a
+ * finite odd integer, then the result is positive infinity.</li>
+ * <li>If the first argument is negative zero and the second argument is a
+ * negative finite odd integer, or the first argument is negative infinity
+ * and the second argument is a positive finite odd integer, then the result
+ * is negative infinity.</li>
+ * <li>If the first argument is less than zero and the second argument is a
+ * finite even integer, then the result is equal to the result of raising
+ * the absolute value of the first argument to the power of the second
+ * argument.</li>
+ * <li>If the first argument is less than zero and the second argument is a
+ * finite odd integer, then the result is equal to the negative of the
+ * result of raising the absolute value of the first argument to the power
+ * of the second argument.</li>
+ * <li>If the first argument is finite and less than zero and the second
+ * argument is finite and not an integer, then the result is NaN.</li>
+ * <li>If both arguments are integers, then the result is exactly equal to
+ * the mathematical result of raising the first argument to the power of
+ * the second argument if that result can in fact be represented exactly as
+ * a double value.</li>
+ *
+ * </ul><p>(In the foregoing descriptions, a floating-point value is
+ * considered to be an integer if and only if it is a fixed point of the
+ * method {@link #ceil(double)} or, equivalently, a fixed point of the
+ * method {@link #floor(double)}. A value is a fixed point of a one-argument
+ * method if and only if the result of applying the method to the value is
+ * equal to the value.) This is accurate within 1 ulp, and is semi-monotonic.
+ *
+ * @param a the number to raise
+ * @param b the power to raise it to
+ * @return a<sup>b</sup>
+ */
+ public static native double pow(double a, double b);
+
+ /**
+ * Get the IEEE 754 floating point remainder on two numbers. This is the
+ * value of <code>x - y * <em>n</em></code>, where <em>n</em> is the closest
+ * double to <code>x / y</code> (ties go to the even n); for a zero
+ * remainder, the sign is that of <code>x</code>. If either argument is NaN,
+ * the first argument is infinite, or the second argument is zero, the result
+ * is NaN; if x is finite but y is infinite, the result is x. This is
+ * accurate within the limits of doubles.
+ *
+ * @param x the dividend (the top half)
+ * @param y the divisor (the bottom half)
+ * @return the IEEE 754-defined floating point remainder of x/y
+ * @see #rint(double)
+ */
+ public static native double IEEEremainder(double x, double y);
+
+ /**
+ * Take the nearest integer that is that is greater than or equal to the
+ * argument. If the argument is NaN, infinite, or zero, the result is the
+ * same; if the argument is between -1 and 0, the result is negative zero.
+ * Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer &gt;= <code>a</code>
+ */
+ public static native double ceil(double a);
+
+ /**
+ * Take the nearest integer that is that is less than or equal to the
+ * argument. If the argument is NaN, infinite, or zero, the result is the
+ * same. Note that <code>Math.ceil(x) == -Math.floor(-x)</code>.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer &lt;= <code>a</code>
+ */
+ public static native double floor(double a);
+
+ /**
+ * Take the nearest integer to the argument. If it is exactly between
+ * two integers, the even integer is taken. If the argument is NaN,
+ * infinite, or zero, the result is the same.
+ *
+ * @param a the value to act upon
+ * @return the nearest integer to <code>a</code>
+ */
+ public static native double rint(double a);
+
+ /**
+ * Take the nearest integer to the argument. This is equivalent to
+ * <code>(int) Math.floor(a + 0.5f)</code>. If the argument is NaN, the result
+ * is 0; otherwise if the argument is outside the range of int, the result
+ * will be Integer.MIN_VALUE or Integer.MAX_VALUE, as appropriate.
+ *
+ * @param a the argument to round
+ * @return the nearest integer to the argument
+ * @see Integer#MIN_VALUE
+ * @see Integer#MAX_VALUE
+ */
+ public static int round(float a)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return 0;
+ return (int) floor(a + 0.5f);
+ }
+
+ /**
+ * Take the nearest long to the argument. This is equivalent to
+ * <code>(long) Math.floor(a + 0.5)</code>. If the argument is NaN, the
+ * result is 0; otherwise if the argument is outside the range of long, the
+ * result will be Long.MIN_VALUE or Long.MAX_VALUE, as appropriate.
+ *
+ * @param a the argument to round
+ * @return the nearest long to the argument
+ * @see Long#MIN_VALUE
+ * @see Long#MAX_VALUE
+ */
+ public static long round(double a)
+ {
+ // this check for NaN, from JLS 15.21.1, saves a method call
+ if (a != a)
+ return 0;
+ return (long) floor(a + 0.5d);
+ }
+
+ /**
+ * Get a random number. This behaves like Random.nextDouble(), seeded by
+ * System.currentTimeMillis() when first called. In other words, the number
+ * is from a pseudorandom sequence, and lies in the range [+0.0, 1.0).
+ * This random sequence is only used by this method, and is threadsafe,
+ * although you may want your own random number generator if it is shared
+ * among threads.
+ *
+ * @return a random number
+ * @see Random#nextDouble()
+ * @see System#currentTimeMillis()
+ */
+ public static synchronized double random()
+ {
+ if (rand == null)
+ rand = new Random();
+ return rand.nextDouble();
+ }
+
+ /**
+ * Convert from degrees to radians. The formula for this is
+ * radians = degrees * (pi/180); however it is not always exact given the
+ * limitations of floating point numbers.
+ *
+ * @param degrees an angle in degrees
+ * @return the angle in radians
+ * @since 1.2
+ */
+ public static double toRadians(double degrees)
+ {
+ return (degrees * PI) / 180;
+ }
+
+ /**
+ * Convert from radians to degrees. The formula for this is
+ * degrees = radians * (180/pi); however it is not always exact given the
+ * limitations of floating point numbers.
+ *
+ * @param rads an angle in radians
+ * @return the angle in degrees
+ * @since 1.2
+ */
+ public static double toDegrees(double rads)
+ {
+ return (rads * 180) / PI;
+ }
+
+ /**
+ * <p>
+ * Take a cube root. If the argument is <code>NaN</code>, an infinity or
+ * zero, then the original value is returned. The returned result is
+ * within 1 ulp of the exact result. For a finite value, <code>x</code>,
+ * the cube root of <code>-x</code> is equal to the negation of the cube root
+ * of <code>x</code>.
+ * </p>
+ * <p>
+ * For a square root, use <code>sqrt</code>. For other roots, use
+ * <code>pow(a, 1 / rootNumber)</code>.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the cube root of the argument
+ * @see #sqrt(double)
+ * @see #pow(double, double)
+ * @since 1.5
+ */
+ public static native double cbrt(double a);
+
+ /**
+ * <p>
+ * Returns the hyperbolic cosine of the given value. For a value,
+ * <code>x</code>, the hyperbolic cosine is <code>(e<sup>x</sup> +
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, then the original value is
+ * returned. For either infinity, positive infinity is returned.
+ * The hyperbolic cosine of zero is 1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic cosine of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double cosh(double a);
+
+ /**
+ * <p>
+ * Returns <code>e<sup>a</sup> - 1. For values close to 0, the
+ * result of <code>expm1(a) + 1</code> tend to be much closer to the
+ * exact result than simply <code>exp(x)</code>. The result is within
+ * 1 ulp of the exact result, and results are semi-monotonic. For finite
+ * inputs, the returned value is greater than or equal to -1.0. Once
+ * a result enters within half a ulp of this limit, the limit is returned.
+ * </p>
+ * <p>
+ * For <code>NaN</code>, positive infinity and zero, the original value
+ * is returned. Negative infinity returns a result of -1.0 (the limit).
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return <code>e<sup>a</sup> - 1</code>
+ * @since 1.5
+ */
+ public static native double expm1(double a);
+
+ /**
+ * <p>
+ * Returns the hypotenuse, <code>a<sup>2</sup> + b<sup>2</sup></code>,
+ * without intermediate overflow or underflow. The returned result is
+ * within 1 ulp of the exact result. If one parameter is held constant,
+ * then the result in the other parameter is semi-monotonic.
+ * </p>
+ * <p>
+ * If either of the arguments is an infinity, then the returned result
+ * is positive infinity. Otherwise, if either argument is <code>NaN</code>,
+ * then <code>NaN</code> is returned.
+ * </p>
+ *
+ * @param a the first parameter.
+ * @param b the second parameter.
+ * @return the hypotenuse matching the supplied parameters.
+ * @since 1.5
+ */
+ public static native double hypot(double a, double b);
+
+ /**
+ * <p>
+ * Returns the base 10 logarithm of the supplied value. The returned
+ * result is within 1 ulp of the exact result, and the results are
+ * semi-monotonic.
+ * </p>
+ * <p>
+ * Arguments of either <code>NaN</code> or less than zero return
+ * <code>NaN</code>. An argument of positive infinity returns positive
+ * infinity. Negative infinity is returned if either positive or negative
+ * zero is supplied. Where the argument is the result of
+ * <code>10<sup>n</sup</code>, then <code>n</code> is returned.
+ * </p>
+ *
+ * @param a the numeric argument.
+ * @return the base 10 logarithm of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double log10(double a);
+
+ /**
+ * <p>
+ * Returns the natural logarithm resulting from the sum of the argument,
+ * <code>a</code> and 1. For values close to 0, the
+ * result of <code>log1p(a)</code> tend to be much closer to the
+ * exact result than simply <code>log(1.0+a)</code>. The returned
+ * result is within 1 ulp of the exact result, and the results are
+ * semi-monotonic.
+ * </p>
+ * <p>
+ * Arguments of either <code>NaN</code> or less than -1 return
+ * <code>NaN</code>. An argument of positive infinity or zero
+ * returns the original argument. Negative infinity is returned from an
+ * argument of -1.
+ * </p>
+ *
+ * @param a the numeric argument.
+ * @return the natural logarithm of <code>a</code> + 1.
+ * @since 1.5
+ */
+ public static native double log1p(double a);
+
+ /**
+ * <p>
+ * Returns the sign of the argument as follows:
+ * </p>
+ * <ul>
+ * <li>If <code>a</code> is greater than zero, the result is 1.0.</li>
+ * <li>If <code>a</code> is less than zero, the result is -1.0.</li>
+ * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
+ * <li>If <code>a</code> is positive or negative zero, the result is the
+ * same.</li>
+ * </ul>
+ *
+ * @param a the numeric argument.
+ * @return the sign of the argument.
+ * @since 1.5.
+ */
+ public static double signum(double a)
+ {
+ if (Double.isNaN(a))
+ return Double.NaN;
+ if (a > 0)
+ return 1.0;
+ if (a < 0)
+ return -1.0;
+ return a;
+ }
+
+ /**
+ * <p>
+ * Returns the sign of the argument as follows:
+ * </p>
+ * <ul>
+ * <li>If <code>a</code> is greater than zero, the result is 1.0f.</li>
+ * <li>If <code>a</code> is less than zero, the result is -1.0f.</li>
+ * <li>If <code>a</code> is <code>NaN</code>, the result is <code>NaN</code>.
+ * <li>If <code>a</code> is positive or negative zero, the result is the
+ * same.</li>
+ * </ul>
+ *
+ * @param a the numeric argument.
+ * @return the sign of the argument.
+ * @since 1.5.
+ */
+ public static float signum(float a)
+ {
+ if (Float.isNaN(a))
+ return Float.NaN;
+ if (a > 0)
+ return 1.0f;
+ if (a < 0)
+ return -1.0f;
+ return a;
+ }
+
+ /**
+ * <p>
+ * Returns the hyperbolic sine of the given value. For a value,
+ * <code>x</code>, the hyperbolic sine is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/2</code>
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result.
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code>, an infinity or a zero, then the
+ * original value is returned.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic sine of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double sinh(double a);
+
+ /**
+ * <p>
+ * Returns the hyperbolic tangent of the given value. For a value,
+ * <code>x</code>, the hyperbolic tangent is <code>(e<sup>x</sup> -
+ * e<sup>-x</sup>)/(e<sup>x</sup> + e<sup>-x</sup>)</code>
+ * (i.e. <code>sinh(a)/cosh(a)</code>)
+ * with <code>e</code> being <a href="#E">Euler's number</a>. The returned
+ * result is within 2.5 ulps of the exact result. The absolute value
+ * of the exact result is always less than 1. Computed results are thus
+ * less than or equal to 1 for finite arguments, with results within
+ * half a ulp of either positive or negative 1 returning the appropriate
+ * limit value (i.e. as if the argument was an infinity).
+ * </p>
+ * <p>
+ * If the supplied value is <code>NaN</code> or zero, then the original
+ * value is returned. Positive infinity returns +1.0 and negative infinity
+ * returns -1.0.
+ * </p>
+ *
+ * @param a the numeric argument
+ * @return the hyperbolic tangent of <code>a</code>.
+ * @since 1.5
+ */
+ public static native double tanh(double a);
+
+ /**
+ * Return the ulp for the given double argument. The ulp is the
+ * difference between the argument and the next larger double. Note
+ * that the sign of the double argument is ignored, that is,
+ * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned.
+ * If the argument is an infinity, then +Inf is returned. If the
+ * argument is zero (either positive or negative), then
+ * {@link Double#MIN_VALUE} is returned.
+ * @param d the double whose ulp should be returned
+ * @return the difference between the argument and the next larger double
+ * @since 1.5
+ */
+ public static double ulp(double d)
+ {
+ if (Double.isNaN(d))
+ return d;
+ if (Double.isInfinite(d))
+ return Double.POSITIVE_INFINITY;
+ // This handles both +0.0 and -0.0.
+ if (d == 0.0)
+ return Double.MIN_VALUE;
+ long bits = Double.doubleToLongBits(d);
+ final int mantissaBits = 52;
+ final int exponentBits = 11;
+ final long mantMask = (1L << mantissaBits) - 1;
+ long mantissa = bits & mantMask;
+ final long expMask = (1L << exponentBits) - 1;
+ long exponent = (bits >>> mantissaBits) & expMask;
+
+ // Denormal number, so the answer is easy.
+ if (exponent == 0)
+ {
+ long result = (exponent << mantissaBits) | 1L;
+ return Double.longBitsToDouble(result);
+ }
+
+ // Conceptually we want to have '1' as the mantissa. Then we would
+ // shift the mantissa over to make a normal number. If this underflows
+ // the exponent, we will make a denormal result.
+ long newExponent = exponent - mantissaBits;
+ long newMantissa;
+ if (newExponent > 0)
+ newMantissa = 0;
+ else
+ {
+ newMantissa = 1L << -(newExponent - 1);
+ newExponent = 0;
+ }
+ return Double.longBitsToDouble((newExponent << mantissaBits) | newMantissa);
+ }
+
+ /**
+ * Return the ulp for the given float argument. The ulp is the
+ * difference between the argument and the next larger float. Note
+ * that the sign of the float argument is ignored, that is,
+ * ulp(x) == ulp(-x). If the argument is a NaN, then NaN is returned.
+ * If the argument is an infinity, then +Inf is returned. If the
+ * argument is zero (either positive or negative), then
+ * {@link Float#MIN_VALUE} is returned.
+ * @param f the float whose ulp should be returned
+ * @return the difference between the argument and the next larger float
+ * @since 1.5
+ */
+ public static float ulp(float f)
+ {
+ if (Float.isNaN(f))
+ return f;
+ if (Float.isInfinite(f))
+ return Float.POSITIVE_INFINITY;
+ // This handles both +0.0 and -0.0.
+ if (f == 0.0)
+ return Float.MIN_VALUE;
+ int bits = Float.floatToIntBits(f);
+ final int mantissaBits = 23;
+ final int exponentBits = 8;
+ final int mantMask = (1 << mantissaBits) - 1;
+ int mantissa = bits & mantMask;
+ final int expMask = (1 << exponentBits) - 1;
+ int exponent = (bits >>> mantissaBits) & expMask;
+
+ // Denormal number, so the answer is easy.
+ if (exponent == 0)
+ {
+ int result = (exponent << mantissaBits) | 1;
+ return Float.intBitsToFloat(result);
+ }
+
+ // Conceptually we want to have '1' as the mantissa. Then we would
+ // shift the mantissa over to make a normal number. If this underflows
+ // the exponent, we will make a denormal result.
+ int newExponent = exponent - mantissaBits;
+ int newMantissa;
+ if (newExponent > 0)
+ newMantissa = 0;
+ else
+ {
+ newMantissa = 1 << -(newExponent - 1);
+ newExponent = 0;
+ }
+ return Float.intBitsToFloat((newExponent << mantissaBits) | newMantissa);
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/Object.h b/gcc-4.2.1/libjava/java/lang/Object.h
new file mode 100644
index 000000000..54fd447d1
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Object.h
@@ -0,0 +1,91 @@
+// Object.h - Header file for java.lang.Object. -*- c++ -*-
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#ifndef __JAVA_LANG_OBJECT_H__
+#define __JAVA_LANG_OBJECT_H__
+
+#pragma interface
+
+#include <gcj/javaprims.h>
+
+extern "Java"
+{
+// This class is mainly here as a kludge to get G++ to allocate two
+// extra entries in each vtable.
+struct _JvObjectPrefix
+{
+protected:
+ // New ABI Compatibility Dummy, #1 and 2.
+ virtual void nacd_1 (void) {}; // This slot really contains the Class pointer.
+ // For IA64, the GC descriptor goes into the second word of the nacd1 descr.
+# ifndef __ia64__
+ virtual void nacd_2 (void) {}; // Actually the GC bitmap marking descriptor.
+# endif
+};
+}
+
+// Forward declarations for friends of java::lang::Object
+void _Jv_MonitorEnter (jobject obj);
+void _Jv_MonitorExit (jobject obj);
+void _Jv_InitializeSyncMutex (void);
+void _Jv_FinalizeObject (jobject obj);
+bool _Jv_ObjectCheckMonitor (jobject obj);
+
+class java::lang::Object : public _JvObjectPrefix
+{
+protected:
+ virtual void finalize (void);
+public:
+ // Order must match order in Object.java.
+ jclass getClass (void);
+ virtual jint hashCode (void);
+ void notify (void);
+ void notifyAll (void);
+ void wait (jlong timeout, jint nanos);
+ virtual jboolean equals (jobject obj);
+ Object (void);
+ virtual jstring toString (void);
+ void wait (void);
+ void wait (jlong timeout);
+
+ friend void ::_Jv_MonitorEnter (jobject obj);
+ friend void ::_Jv_MonitorExit (jobject obj);
+ friend void ::_Jv_InitializeSyncMutex (void);
+ friend void ::_Jv_FinalizeObject (jobject obj);
+ friend bool ::_Jv_ObjectCheckMonitor (jobject obj);
+
+#ifdef JV_MARKOBJ_DECL
+ friend JV_MARKOBJ_DECL;
+#endif
+#ifdef JV_MARKARRAY_DECL
+ friend JV_MARKARRAY_DECL;
+#endif
+
+ static java::lang::Class class$;
+
+protected:
+ virtual jobject clone (void);
+
+private:
+ // This does not actually refer to a Java object. Instead it is a
+ // placeholder for a piece of internal data (the synchronization
+ // information).
+# ifndef JV_HASH_SYNCHRONIZATION
+ jobject sync_info;
+# endif
+
+ // Initialize the sync_info field. Not called with JV_HASH_SYNCHRONIZATION.
+ void sync_init (void);
+
+public:
+ virtual void throwNoSuchMethodError (void);
+};
+
+#endif /* __JAVA_LANG_OBJECT_H__ */
diff --git a/gcc-4.2.1/libjava/java/lang/Object.java b/gcc-4.2.1/libjava/java/lang/Object.java
new file mode 100644
index 000000000..e81a48a9f
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Object.java
@@ -0,0 +1,519 @@
+/* java.lang.Object - The universal superclass in Java
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 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.lang;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * plus gcj compiler sources (to determine object layout)
+ * Status: Complete to version 1.1
+ */
+
+/**
+ * Object is the ultimate superclass of every class
+ * (excepting interfaces). When you define a class that
+ * does not extend any other class, it implicitly extends
+ * java.lang.Object. Also, an anonymous class based on
+ * an interface will extend Object.
+ *
+ * <p>It provides general-purpose methods that every single
+ * Object, regardless of race, sex or creed, implements.
+ * All of the public methods may be invoked on arrays or
+ * interfaces. The protected methods <code>clone</code>
+ * and <code>finalize</code> are not accessible on arrays
+ * or interfaces, but all array types have a public version
+ * of <code>clone</code> which is accessible.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Tom Tromey (tromey@cygnus.com)
+ */
+public class Object
+{
+ /**
+ * Called on an object by the Virtual Machine at most once,
+ * at some point after the Object is determined unreachable
+ * but before it is destroyed. You would think that this
+ * means it eventually is called on every Object, but this is
+ * not necessarily the case. If execution terminates
+ * abnormally, garbage collection does not always happen.
+ * Thus you cannot rely on this method to always work.
+ * For finer control over garbage collection, use references
+ * from the {@link java.lang.ref} package.
+ *
+ * <p>Virtual Machines are free to not call this method if
+ * they can determine that it does nothing important; for
+ * example, if your class extends Object and overrides
+ * finalize to do simply <code>super.finalize()</code>.
+ *
+ * <p>finalize() will be called by a {@link Thread} that has no
+ * locks on any Objects, and may be called concurrently.
+ * There are no guarantees on the order in which multiple
+ * objects are finalized. This means that finalize() is
+ * usually unsuited for performing actions that must be
+ * thread-safe, and that your implementation must be
+ * use defensive programming if it is to always work.
+ *
+ * <p>If an Exception is thrown from finalize() during garbage
+ * collection, it will be patently ignored and the Object will
+ * still be destroyed.
+ *
+ * <p>It is allowed, although not typical, for user code to call
+ * finalize() directly. User invocation does not affect whether
+ * automatic invocation will occur. It is also permitted,
+ * although not recommended, for a finalize() method to "revive"
+ * an object by making it reachable from normal code again.
+ *
+ * <p>Unlike constructors, finalize() does not get called
+ * for an object's superclass unless the implementation
+ * specifically calls <code>super.finalize()</code>.
+ *
+ * <p>The default implementation does nothing.
+ *
+ * @throws Throwable permits a subclass to throw anything in an
+ * overridden version; but the default throws nothing
+ * @see System#gc()
+ * @see System#runFinalizersOnExit(boolean)
+ * @see java.lang.ref
+ */
+ // This must come first. See _JvObjectPrefix in Object.h.
+ protected void finalize () throws Throwable
+ {
+ }
+
+ /**
+ * Returns the runtime {@link Class} of this Object.
+ *
+ * <p>The class object can also be obtained without a runtime
+ * instance by using the class literal, as in:
+ * <code>Foo.class</code>. Notice that the class literal
+ * also works on primitive types, making it useful for
+ * reflection purposes.
+ *
+ * @return the class of this Object
+ */
+ public final native Class getClass();
+
+ /**
+ * Get a value that represents this Object, as uniquely as
+ * possible within the confines of an int.
+ *
+ * <p>There are some requirements on this method which
+ * subclasses must follow:<br>
+ *
+ * <ul>
+ * <li>Semantic equality implies identical hashcodes. In other
+ * words, if <code>a.equals(b)</code> is true, then
+ * <code>a.hashCode() == b.hashCode()</code> must be as well.
+ * However, the reverse is not necessarily true, and two
+ * objects may have the same hashcode without being equal.</li>
+ * <li>It must be consistent. Whichever value o.hashCode()
+ * returns on the first invocation must be the value
+ * returned on all later invocations as long as the object
+ * exists. Notice, however, that the result of hashCode may
+ * change between separate executions of a Virtual Machine,
+ * because it is not invoked on the same object.</li>
+ * </ul>
+ *
+ * <p>Notice that since <code>hashCode</code> is used in
+ * {@link java.util.Hashtable} and other hashing classes,
+ * a poor implementation will degrade the performance of hashing
+ * (so don't blindly implement it as returning a constant!). Also,
+ * if calculating the hash is time-consuming, a class may consider
+ * caching the results.
+ *
+ * <p>The default implementation returns
+ * <code>System.identityHashCode(this)</code>
+ *
+ * @return the hash code for this Object
+ * @see #equals(Object)
+ * @see System#identityHashCode(Object)
+ */
+ public native int hashCode();
+
+ /**
+ * Wakes up one of the {@link Thread}s that has called
+ * <code>wait</code> on this Object. Only the owner
+ * of a lock on this Object may call this method. This lock
+ * is obtained by a <code>synchronized</code> method or statement.
+ *
+ * <p>The Thread to wake up is chosen arbitrarily. The
+ * awakened thread is not guaranteed to be the next thread
+ * to actually obtain the lock on this object.
+ *
+ * <p>This thread still holds a lock on the object, so it is
+ * typical to release the lock by exiting the synchronized
+ * code, calling wait(), or calling {@link Thread#sleep()}, so
+ * that the newly awakened thread can actually resume. The
+ * awakened thread will most likely be awakened with an
+ * {@link InterruptedException}, but that is not guaranteed.
+ *
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own the lock on the Object
+ * @see #notifyAll()
+ * @see #wait()
+ * @see #wait(long)
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final native void notify();
+
+ /**
+ * Wakes up all of the {@link Thread}s that have called
+ * <code>wait</code> on this Object. Only the owner
+ * of a lock on this Object may call this method. This lock
+ * is obtained by a <code>synchronized</code> method or statement.
+ *
+ * <p>There are no guarantees as to which thread will next
+ * obtain the lock on the object.
+ *
+ * <p>This thread still holds a lock on the object, so it is
+ * typical to release the lock by exiting the synchronized
+ * code, calling wait(), or calling {@link Thread#sleep()}, so
+ * that one of the newly awakened threads can actually resume.
+ * The resuming thread will most likely be awakened with an
+ * {@link InterruptedException}, but that is not guaranteed.
+ *
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own the lock on the Object
+ * @see #notify()
+ * @see #wait()
+ * @see #wait(long)
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final native void notifyAll();
+
+ /**
+ * Waits a specified amount of time (or indefinitely if
+ * the time specified is 0) for someone to call notify()
+ * or notifyAll() on this Object, waking up this Thread.
+ *
+ * <p>The Thread that calls wait must have a lock on this Object,
+ * obtained by a <code>synchronized</code> method or statement.
+ * After calling wait, the thread loses the lock on this
+ * object until the method completes (abruptly or normally),
+ * at which time it regains the lock. All locks held on
+ * other objects remain in force, even though the thread is
+ * inactive. Therefore, caution must be used to avoid deadlock.
+ *
+ * <p>Usually, this call will complete normally if the time
+ * expires, or abruptly with {@link InterruptedException}
+ * if another thread called notify, but neither result
+ * is guaranteed.
+ *
+ * <p>The waiting period is nowhere near as precise as
+ * nanoseconds; considering that even wait(int) is inaccurate,
+ * how much can you expect? But on supporting
+ * implementations, this offers somewhat more granularity
+ * than milliseconds.
+ *
+ * @param ms the number of milliseconds to wait (1,000
+ * milliseconds = 1 second)
+ * @param ns the number of nanoseconds to wait over and
+ * above ms (1,000,000 nanoseconds = 1 millisecond)
+ * @throws IllegalArgumentException if ms &lt; 0 or ns is not
+ * in the range 0 to 999,999
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own a lock on this Object
+ * @throws InterruptedException if some other Thread
+ * interrupts this Thread
+ * @see #notify()
+ * @see #notifyAll()
+ * @see #wait()
+ * @see #wait(long)
+ * @see Thread
+ */
+ public final native void wait(long timeout, int nanos)
+ throws InterruptedException;
+
+ /**
+ * Determine whether this Object is semantically equal
+ * to another Object.
+ *
+ * <p>There are some fairly strict requirements on this
+ * method which subclasses must follow:<br>
+ * <ul>
+ * <li>It must be transitive. If <code>a.equals(b)</code> and
+ * <code>b.equals(c)</code>, then <code>a.equals(c)</code>
+ * must be true as well.</li>
+ * <li>It must be symmetric. <code>a.equals(b)</code> and
+ * <code>b.equals(a)</code> must have the same value.</li>
+ * <li>It must be reflexive. <code>a.equals(a)</code> must
+ * always be true.</li>
+ * <li>It must be consistent. Whichever value a.equals(b)
+ * returns on the first invocation must be the value
+ * returned on all later invocations.</li>
+ * <li><code>a.equals(null)</code> must be false.</li>
+ * <li>It must be consistent with hashCode(). That is,
+ * <code>a.equals(b)</code> must imply
+ * <code>a.hashCode() == b.hashCode()</code>.
+ * The reverse is not true; two objects that are not
+ * equal may have the same hashcode, but that has
+ * the potential to harm hashing performance.</li>
+ * </ul>
+ *
+ * <p>This is typically overridden to throw a {@link ClassCastException}
+ * if the argument is not comparable to the class performing
+ * the comparison, but that is not a requirement. It is legal
+ * for <code>a.equals(b)</code> to be true even though
+ * <code>a.getClass() != b.getClass()</code>. Also, it
+ * is typical to never cause a {@link NullPointerException}.
+ *
+ * <p>In general, the Collections API ({@link java.util}) use the
+ * <code>equals</code> method rather than the <code>==</code>
+ * operator to compare objects. However, {@link java.util.IdentityHashMap}
+ * is an exception to this rule, for its own good reasons.
+ *
+ * <p>The default implementation returns <code>this == o</code>.
+ *
+ * @param obj the Object to compare to
+ * @return whether this Object is semantically equal to another
+ * @see #hashCode()
+ */
+ public boolean equals(Object obj)
+ {
+ return this == obj;
+ }
+
+ /**
+ * The basic constructor. Object is special, because it has no
+ * superclass, so there is no call to super().
+ *
+ * @throws OutOfMemoryError Technically, this constructor never
+ * throws an OutOfMemoryError, because the memory has
+ * already been allocated by this point. But as all
+ * instance creation expressions eventually trace back
+ * to this constructor, and creating an object allocates
+ * memory, we list that possibility here.
+ */
+ public Object()
+ {
+ }
+
+ /**
+ * Convert this Object to a human-readable String.
+ * There are no limits placed on how long this String
+ * should be or what it should contain. We suggest you
+ * make it as intuitive as possible to be able to place
+ * it into {@link java.io.PrintStream#println() System.out.println()}
+ * and such.
+ *
+ * <p>It is typical, but not required, to ensure that this method
+ * never completes abruptly with a {@link RuntimeException}.
+ *
+ * <p>This method will be called when performing string
+ * concatenation with this object. If the result is
+ * <code>null</code>, string concatenation will instead
+ * use <code>"null"</code>.
+ *
+ * <p>The default implementation returns
+ * <code>getClass().getName() + "@" +
+ * Integer.toHexString(hashCode())</code>.
+ *
+ * @return the String representing this Object, which may be null
+ * @throws OutOfMemoryError The default implementation creates a new
+ * String object, therefore it must allocate memory
+ * @see #getClass()
+ * @see #hashCode()
+ * @see Class#getName()
+ * @see Integer#toHexString(int)
+ */
+ public String toString()
+ {
+ return getClass().getName() + '@' + Integer.toHexString(hashCode());
+ }
+
+ /**
+ * Waits indefinitely for notify() or notifyAll() to be
+ * called on the Object in question. Implementation is
+ * identical to wait(0).
+ *
+ * <p>The Thread that calls wait must have a lock on this Object,
+ * obtained by a <code>synchronized</code> method or statement.
+ * After calling wait, the thread loses the lock on this
+ * object until the method completes (abruptly or normally),
+ * at which time it regains the lock. All locks held on
+ * other objects remain in force, even though the thread is
+ * inactive. Therefore, caution must be used to avoid deadlock.
+ *
+ * <p>While it is typical that this method will complete abruptly
+ * with an {@link InterruptedException}, it is not guaranteed. So,
+ * it is typical to call wait inside an infinite loop:<br>
+ *
+ * <pre>
+ * try
+ * {
+ * while (true)
+ * lock.wait();
+ * }
+ * catch (InterruptedException e)
+ * {
+ * }
+ * </pre>
+ *
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own a lock on this Object
+ * @throws InterruptedException if some other Thread
+ * interrupts this Thread
+ * @see #notify()
+ * @see #notifyAll()
+ * @see #wait(long)
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final void wait() throws InterruptedException
+ {
+ wait(0, 0);
+ }
+
+ /**
+ * Waits a specified amount of time (or indefinitely if
+ * the time specified is 0) for someone to call notify()
+ * or notifyAll() on this Object, waking up this Thread.
+ *
+ * <p>The Thread that calls wait must have a lock on this Object,
+ * obtained by a <code>synchronized</code> method or statement.
+ * After calling wait, the thread loses the lock on this
+ * object until the method completes (abruptly or normally),
+ * at which time it regains the lock. All locks held on
+ * other objects remain in force, even though the thread is
+ * inactive. Therefore, caution must be used to avoid deadlock.
+ *
+ * <p>Usually, this call will complete normally if the time
+ * expires, or abruptly with {@link InterruptedException}
+ * if another thread called notify, but neither result
+ * is guaranteed.
+ *
+ * <p>The waiting period is only *roughly* the amount of time
+ * you requested. It cannot be exact because of the overhead
+ * of the call itself. Most Virtual Machiness treat the
+ * argument as a lower limit on the time spent waiting, but
+ * even that is not guaranteed. Besides, some other thread
+ * may hold the lock on the object when the time expires, so
+ * the current thread may still have to wait to reobtain the
+ * lock.
+ *
+ * @param timeout the minimum number of milliseconds to wait (1000
+ * milliseconds = 1 second), or 0 for an indefinite wait
+ * @throws IllegalArgumentException if ms &lt; 0
+ * @throws IllegalMonitorStateException if this Thread
+ * does not own a lock on this Object
+ * @throws InterruptedException if some other Thread
+ * interrupts this Thread
+ * @see #notify()
+ * @see #notifyAll()
+ * @see #wait()
+ * @see #wait(long, int)
+ * @see Thread
+ */
+ public final void wait(long timeout) throws InterruptedException
+ {
+ wait(timeout, 0);
+ }
+
+ /**
+ * This method may be called to create a new copy of the
+ * Object. The typical behavior is as follows:<br>
+ * <ul>
+ * <li><code>o == o.clone()</code> is false</li>
+ * <li><code>o.getClass() == o.clone().getClass()</code>
+ * is true</li>
+ * <li><code>o.equals(o)</code> is true</li>
+ * </ul>
+ *
+ * <p>However, these are not strict requirements, and may
+ * be violated if necessary. Of the three requirements, the
+ * last is the most commonly violated, particularly if the
+ * subclass does not override {@link #equals(Object)}.
+ *
+ * <p>If the Object you call clone() on does not implement
+ * {@link Cloneable} (which is a placeholder interface), then
+ * a CloneNotSupportedException is thrown. Notice that
+ * Object does not implement Cloneable; this method exists
+ * as a convenience for subclasses that do.
+ *
+ * <p>Object's implementation of clone allocates space for the
+ * new Object using the correct class, without calling any
+ * constructors, and then fills in all of the new field values
+ * with the old field values. Thus, it is a shallow copy.
+ * However, subclasses are permitted to make a deep copy.
+ *
+ * <p>All array types implement Cloneable, and override
+ * this method as follows (it should never fail):<br>
+ * <pre>
+ * public Object clone()
+ * {
+ * try
+ * {
+ * super.clone();
+ * }
+ * catch (CloneNotSupportedException e)
+ * {
+ * throw new InternalError(e.getMessage());
+ * }
+ * }
+ * </pre>
+ *
+ * @return a copy of the Object
+ * @throws CloneNotSupportedException If this Object does not
+ * implement Cloneable
+ * @throws OutOfMemoryError Since cloning involves memory allocation,
+ * even though it may bypass constructors, you might run
+ * out of memory
+ * @see Cloneable
+ */
+ protected native Object clone() throws CloneNotSupportedException;
+
+ // This initializes the sync_info member. It is here for
+ // completeness (some day we'll be able to auto-generate Object.h).
+ private final native void sync_init();
+
+ // If we fail to find a method at class loading time we put the
+ // vtable index of this method in its place: any attempt to call
+ // that method will result in an error.
+ void throwNoSuchMethodError()
+ {
+ throw new NoSuchMethodError("in " + getClass());
+ }
+
+ // Note that we don't mention the sync_info field here. If we do,
+ // jc1 will not work correctly.
+}
diff --git a/gcc-4.2.1/libjava/java/lang/Package.java b/gcc-4.2.1/libjava/java/lang/Package.java
new file mode 100644
index 000000000..0bf4315db
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Package.java
@@ -0,0 +1,317 @@
+/* Package.java -- information about a package
+ Copyright (C) 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.lang;
+
+import java.net.URL;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+
+/**
+ * Everything you ever wanted to know about a package. This class makes it
+ * possible to attach specification and implementation information to a
+ * package as explained in the
+ * <a href="http://java.sun.com/products/jdk/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersionSpecification">Package Versioning Specification</a>
+ * section of the
+ * <a href="http://java.sun.com/products/jdk/1.3/docs/guide/versioning/spec/VersioningSpecification.html">Product Versioning Specification</a>.
+ * It also allows packages to be sealed with respect to the originating URL.
+ *
+ * <p>The most useful method is the <code>isCompatibleWith()</code> method that
+ * compares a desired version of a specification with the version of the
+ * specification as implemented by a package. A package is considered
+ * compatible with another version if the version of the specification is
+ * equal or higher then the requested version. Version numbers are represented
+ * as strings of positive numbers separated by dots (e.g. "1.2.0").
+ * The first number is called the major number, the second the minor,
+ * the third the micro, etc. A version is considered higher then another
+ * version if it has a bigger major number then the another version or when
+ * the major numbers of the versions are equal if it has a bigger minor number
+ * then the other version, etc. (If a version has no minor, micro, etc numbers
+ * then they are considered the be 0.)
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ * @see ClassLoader#definePackage(String, String, String, String, String,
+ * String, String, URL)
+ * @since 1.2
+ * @status updated to 1.4
+ */
+public class Package
+{
+ /** The name of the Package */
+ private final String name;
+
+ /** The name if the implementation */
+ private final String implTitle;
+
+ /** The vendor that wrote this implementation */
+ private final String implVendor;
+
+ /** The version of this implementation */
+ private final String implVersion;
+
+ /** The name of the specification */
+ private final String specTitle;
+
+ /** The name of the specification designer */
+ private final String specVendor;
+
+ /** The version of this specification */
+ private final String specVersion;
+
+ /** If sealed the origin of the package classes, otherwise null */
+ private final URL sealed;
+
+ /**
+ * A package local constructor for the Package class. All parameters except
+ * the <code>name</code> of the package may be <code>null</code>.
+ * There are no public constructors defined for Package; this is a package
+ * local constructor that is used by java.lang.Classloader.definePackage().
+ *
+ * @param name The name of the Package
+ * @param specTitle The name of the specification
+ * @param specVendor The name of the specification designer
+ * @param specVersion The version of this specification
+ * @param implTitle The name of the implementation
+ * @param implVendor The vendor that wrote this implementation
+ * @param implVersion The version of this implementation
+ * @param sealed If sealed the origin of the package classes
+ */
+ Package(String name,
+ String specTitle, String specVendor, String specVersion,
+ String implTitle, String implVendor, String implVersion, URL sealed)
+ {
+ if (name == null)
+ throw new IllegalArgumentException("null Package name");
+
+ this.name = name;
+ this.implTitle = implTitle;
+ this.implVendor = implVendor;
+ this.implVersion = implVersion;
+ this.specTitle = specTitle;
+ this.specVendor = specVendor;
+ this.specVersion = specVersion;
+ this.sealed = sealed;
+ }
+
+ /**
+ * Returns the Package name in dot-notation.
+ *
+ * @return the non-null package name
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Returns the name of the specification, or null if unknown.
+ *
+ * @return the specification title
+ */
+ public String getSpecificationTitle()
+ {
+ return specTitle;
+ }
+
+ /**
+ * Returns the version of the specification, or null if unknown.
+ *
+ * @return the specification version
+ */
+ public String getSpecificationVersion()
+ {
+ return specVersion;
+ }
+
+ /**
+ * Returns the name of the specification designer, or null if unknown.
+ *
+ * @return the specification vendor
+ */
+ public String getSpecificationVendor()
+ {
+ return specVendor;
+ }
+
+ /**
+ * Returns the name of the implementation, or null if unknown.
+ *
+ * @return the implementation title
+ */
+ public String getImplementationTitle()
+ {
+ return implTitle;
+ }
+
+ /**
+ * Returns the version of this implementation, or null if unknown.
+ *
+ * @return the implementation version
+ */
+ public String getImplementationVersion()
+ {
+ return implVersion;
+ }
+
+ /**
+ * Returns the vendor that wrote this implementation, or null if unknown.
+ *
+ * @return the implementation vendor
+ */
+ public String getImplementationVendor()
+ {
+ return implVendor;
+ }
+
+ /**
+ * Returns true if this Package is sealed.
+ *
+ * @return true if the package is sealed
+ */
+ public boolean isSealed()
+ {
+ return sealed != null;
+ }
+
+ /**
+ * Returns true if this Package is sealed and the origin of the classes is
+ * the given URL.
+ *
+ * @param url the URL to test
+ * @return true if the package is sealed by this URL
+ * @throws NullPointerException if url is null
+ */
+ public boolean isSealed(URL url)
+ {
+ return url.equals(sealed);
+ }
+
+ /**
+ * Checks if the version of the specification is higher or at least as high
+ * as the desired version. Comparison is done by sequentially comparing
+ * dotted decimal numbers from the parameter and from
+ * <code>getSpecificationVersion</code>.
+ *
+ * @param version the (minimal) desired version of the specification
+ *
+ * @return true if the version is compatible, false otherwise
+ *
+ * @Throws NumberFormatException if either version string is invalid
+ * @throws NullPointerException if either version string is null
+ */
+ public boolean isCompatibleWith(String version)
+ {
+ StringTokenizer versionTokens = new StringTokenizer(version, ".");
+ StringTokenizer specTokens = new StringTokenizer(specVersion, ".");
+ try
+ {
+ while (versionTokens.hasMoreElements())
+ {
+ int vers = Integer.parseInt(versionTokens.nextToken());
+ int spec = Integer.parseInt(specTokens.nextToken());
+ if (spec < vers)
+ return false;
+ else if (spec > vers)
+ return true;
+ // They must be equal, next Token please!
+ }
+ }
+ catch (NoSuchElementException e)
+ {
+ // This must have been thrown by spec.nextToken() so return false.
+ return false;
+ }
+ // They must have been exactly the same version.
+ // Or the specVersion has more subversions. That is also good.
+ return true;
+ }
+
+ /**
+ * Returns the named package if it is known by the callers class loader.
+ * It may return null if the package is unknown, when there is no
+ * information on that particular package available or when the callers
+ * classloader is null.
+ *
+ * @param name the name of the desired package
+ * @return the package by that name in the current ClassLoader
+ */
+ public static Package getPackage(String name)
+ {
+ // Get the caller's classloader
+ ClassLoader cl = VMSecurityManager.currentClassLoader(Package.class);
+ return cl != null ? cl.getPackage(name) : VMClassLoader.getPackage(name);
+ }
+
+ /**
+ * Returns all the packages that are known to the callers class loader.
+ * It may return an empty array if the classloader of the caller is null.
+ *
+ * @return an array of all known packages
+ */
+ public static Package[] getPackages()
+ {
+ // Get the caller's classloader
+ Class c = VMSecurityManager.getClassContext(Package.class)[1];
+ ClassLoader cl = c.getClassLoader();
+ return cl != null ? cl.getPackages() : VMClassLoader.getPackages();
+ }
+
+ /**
+ * Returns the hashCode of the name of this package.
+ *
+ * @return the hash code
+ */
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+
+ /**
+ * Returns a string representation of this package. It is specified to
+ * be <code>"package " + getName() + (getSpecificationTitle() == null
+ * ? "" : ", " + getSpecificationTitle()) + (getSpecificationVersion()
+ * == null ? "" : ", version " + getSpecificationVersion())</code>.
+ *
+ * @return the string representation of the package
+ */
+ public String toString()
+ {
+ return ("package " + name + (specTitle == null ? "" : ", " + specTitle)
+ + (specVersion == null ? "" : ", version " + specVersion));
+ }
+} // class Package
diff --git a/gcc-4.2.1/libjava/java/lang/PosixProcess.java b/gcc-4.2.1/libjava/java/lang/PosixProcess.java
new file mode 100644
index 000000000..fbd6c4c8a
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/PosixProcess.java
@@ -0,0 +1,475 @@
+// PosixProcess.java - Subclass of Process for POSIX systems.
+/* Copyright (C) 1998, 1999, 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+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;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date May 3, 1999
+ * @author David Daney <ddaney@avtrex.com> Rewrote using
+ * ProcessManager
+ */
+
+// This is entirely internal to our implementation.
+// This file is copied to `ConcreteProcess.java' before compilation.
+// Hence the class name apparently does not match the file name.
+final class ConcreteProcess extends Process
+{
+ static class ProcessManager extends Thread
+ {
+ /**
+ * A list of {@link ConcreteProcess ConcreteProcesses} to be
+ * started. The queueLock object is used as the lock Object
+ * for all process related operations. To avoid dead lock
+ * ensure queueLock is obtained before ConcreteProcess.
+ */
+ List queue = new LinkedList();
+ private Map pidToProcess = new HashMap();
+ private boolean ready = false;
+ private long reaperPID;
+
+ ProcessManager()
+ {
+ super("ProcessManager");
+ // Don't keep the (main) process from exiting on our account.
+ this.setDaemon(true);
+ }
+
+ /**
+ * Get the ConcreteProcess object with the given pid and
+ * remove it from the map. This method is called from the
+ * native code for {@link #reap()). The mapping is removed so
+ * the ConcreteProcesses can be GCed after they terminate.
+ *
+ * @param p The pid of the process.
+ */
+ private ConcreteProcess removeProcessFromMap(long p)
+ {
+ return (ConcreteProcess) pidToProcess.remove(new Long(p));
+ }
+
+ /**
+ * Put the given ConcreteProcess in the map using the Long
+ * value of its pid as the key.
+ *
+ * @param p The ConcreteProcess.
+ */
+ void addProcessToMap(ConcreteProcess p)
+ {
+ pidToProcess.put(new Long(p.pid), p);
+ }
+
+ /**
+ * Queue up the ConcreteProcess and awake the ProcessManager.
+ * The ProcessManager will start the ConcreteProcess from its
+ * thread so it can be reaped when it terminates.
+ *
+ * @param p The ConcreteProcess.
+ */
+ void startExecuting(ConcreteProcess p)
+ {
+ synchronized (queueLock)
+ {
+ queue.add(p);
+ signalReaper(); // If blocked in waitForSignal().
+ queueLock.notifyAll(); // If blocked in wait();
+ }
+ }
+
+ /**
+ * Block until the ProcessManager thread is ready to accept
+ * commands.
+ */
+ void waitUntilReady()
+ {
+ synchronized (this)
+ {
+ try
+ {
+ while (! ready)
+ wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // Ignore.
+ }
+ }
+ }
+
+ /**
+ * Main Process starting/reaping loop.
+ */
+ public void run()
+ {
+ init();
+ // Now ready to accept requests.
+ synchronized (this)
+ {
+ ready = true;
+ this.notifyAll();
+ }
+
+ for (;;)
+ {
+ try
+ {
+ synchronized (queueLock)
+ {
+ boolean haveMoreChildren = reap();
+ if (! haveMoreChildren && queue.size() == 0)
+ {
+ // This reaper thread could exit, but we
+ // keep it alive for a while in case
+ // someone wants to start more Processes.
+ try
+ {
+ queueLock.wait(1000L);
+ if (queue.size() == 0)
+ {
+ processManager = null;
+ return; // Timed out.
+ }
+ }
+ catch (InterruptedException ie)
+ {
+ // Ignore and exit the thread.
+ return;
+ }
+ }
+ while (queue.size() > 0)
+ {
+ ConcreteProcess p = (ConcreteProcess) queue.remove(0);
+ p.spawn(this);
+ }
+ }
+
+ // Wait for a SIGCHLD from either an exiting
+ // process or the startExecuting() method. This
+ // is done outside of the synchronized block to
+ // allow other threads to enter and submit more
+ // jobs.
+ waitForSignal();
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace(System.err);
+ }
+ }
+ }
+
+ /**
+ * Setup native signal handlers and other housekeeping things.
+ *
+ */
+ private native void init();
+
+ /**
+ * Block waiting for SIGCHLD.
+ *
+ */
+ private native void waitForSignal();
+
+ /**
+ * Try to reap as many children as possible without blocking.
+ *
+ * @return true if more live children exist.
+ *
+ */
+ private native boolean reap();
+
+ /**
+ * Send SIGCHLD to the reaper thread.
+ */
+ private native void signalReaper();
+ }
+
+ public void destroy()
+ {
+ // Synchronized on the queueLock. This ensures that the reaper
+ // thread cannot be doing a wait() on the child.
+ // Otherwise there would be a race where the OS could
+ // create a process with the same pid between the wait()
+ // and the update of the state which would cause a kill to
+ // the wrong process.
+ synchronized (queueLock)
+ {
+ synchronized (this)
+ {
+ // If there is no ProcessManager we cannot kill.
+ if (state != STATE_TERMINATED)
+ {
+ if (processManager == null)
+ throw new InternalError();
+ nativeDestroy();
+ }
+ }
+ }
+ }
+
+ private native void nativeDestroy();
+
+ public int exitValue()
+ {
+ synchronized (this)
+ {
+ if (state != STATE_TERMINATED)
+ throw new IllegalThreadStateException("Process has not exited");
+ }
+ return status;
+ }
+
+ /**
+ * Called by native code when process exits.
+ *
+ * Already synchronized (this). Close any streams that we can to
+ * conserve file descriptors.
+ *
+ * The outputStream can be closed as any future writes will
+ * generate an IOException due to EPIPE.
+ *
+ * The inputStream and errorStream can only be closed if the user
+ * has not obtained a reference to them AND they have no bytes
+ * available. Since the process has terminated they will never have
+ * any more data available and can safely be replaced by
+ * EOFInputStreams.
+ */
+ void processTerminationCleanup()
+ {
+ try
+ {
+ outputStream.close();
+ }
+ catch (IOException ioe)
+ {
+ // Ignore.
+ }
+ try
+ {
+ if (returnedErrorStream == null && errorStream.available() == 0)
+ {
+ errorStream.close();
+ errorStream = null;
+ }
+ }
+ catch (IOException ioe)
+ {
+ // Ignore.
+ }
+ try
+ {
+ if (returnedInputStream == null && inputStream.available() == 0)
+ {
+ inputStream.close();
+ inputStream = null;
+ }
+ }
+ catch (IOException ioe)
+ {
+ // Ignore.
+ }
+ }
+
+ public synchronized InputStream getErrorStream()
+ {
+ if (returnedErrorStream != null)
+ return returnedErrorStream;
+
+ if (errorStream == null)
+ returnedErrorStream = EOFInputStream.instance;
+ else
+ returnedErrorStream = errorStream;
+
+ return returnedErrorStream;
+ }
+
+ public synchronized InputStream getInputStream()
+ {
+ if (returnedInputStream != null)
+ return returnedInputStream;
+
+ if (inputStream == null)
+ returnedInputStream = EOFInputStream.instance;
+ else
+ returnedInputStream = inputStream;
+
+ return returnedInputStream;
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return outputStream;
+ }
+
+ public int waitFor() throws InterruptedException
+ {
+ synchronized (this)
+ {
+ while (state != STATE_TERMINATED)
+ wait();
+ }
+ return status;
+ }
+
+ /**
+ * Start this process running. This should only be called by the
+ * ProcessManager.
+ *
+ * @param pm The ProcessManager that made the call.
+ */
+ void spawn(ProcessManager pm)
+ {
+ synchronized (this)
+ {
+ // Do the fork/exec magic.
+ nativeSpawn();
+ // There is no race with reap() in the pidToProcess map
+ // because this is always called from the same thread
+ // doing the reaping.
+ pm.addProcessToMap(this);
+ state = STATE_RUNNING;
+ // Notify anybody waiting on state change.
+ this.notifyAll();
+ }
+ }
+
+ /**
+ * Do the fork and exec.
+ */
+ private native void nativeSpawn();
+
+ // This file is copied to `ConcreteProcess.java' before
+ // compilation. Hence the constructor name apparently does not
+ // match the file name.
+ ConcreteProcess(String[] progarray, String[] envp, File dir)
+ throws IOException
+ {
+ // Check to ensure there is something to run, and avoid
+ // dereferencing null pointers in native code.
+ if (progarray[0] == null)
+ throw new NullPointerException();
+
+ this.progarray = progarray;
+ this.envp = envp;
+ this.dir = dir;
+
+ // Start a ProcessManager if there is not one already running.
+ synchronized (queueLock)
+ {
+ if (processManager == null)
+ {
+ processManager = new ProcessManager();
+ processManager.start();
+ processManager.waitUntilReady();
+ }
+
+ // Queue this ConcreteProcess for starting by the ProcessManager.
+ processManager.startExecuting(this);
+ }
+
+ // Wait until ProcessManager has started us.
+ synchronized (this)
+ {
+ while (state == STATE_WAITING_TO_START)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ie)
+ {
+ // FIXME: What to do when interrupted while blocking in a constructor?
+ // Ignore.
+ }
+ }
+ }
+
+ // If there was a problem, re-throw it.
+ if (exception != null)
+ {
+ if (exception instanceof IOException)
+ {
+ IOException ioe = new IOException(exception.toString());
+ ioe.initCause(exception);
+ throw ioe;
+ }
+
+ // Not an IOException. Something bad happened.
+ InternalError ie = new InternalError(exception.toString());
+ ie.initCause(exception);
+ throw ie;
+ }
+
+ // If we get here, all is well, the Process has started.
+ }
+
+ private String[] progarray;
+ private String[] envp;
+ private File dir;
+
+ /** Set by the ProcessManager on problems starting. */
+ private Throwable exception;
+
+ /** The process id. This is cast to a pid_t on the native side. */
+ private long pid;
+
+ // FIXME: Why doesn't the friend declaration in ConcreteProcess.h
+ // allow ConcreteProcess$ProcessManager native code access these
+ // when they are private?
+
+ /** Before the process is forked. */
+ static final int STATE_WAITING_TO_START = 0;
+
+ /** After the fork. */
+ static final int STATE_RUNNING = 1;
+
+ /** After exit code has been collected. */
+ static final int STATE_TERMINATED = 2;
+
+ /** One of STATE_WAITING_TO_START, STATE_RUNNING, STATE_TERMINATED. */
+ int state;
+
+ /** The exit status, if the child has exited. */
+ int status;
+
+ /** The streams. */
+ private InputStream errorStream;
+ private InputStream inputStream;
+ private OutputStream outputStream;
+
+ /** InputStreams obtained by the user. Not null indicates that the
+ * user has obtained the stream.
+ */
+ private InputStream returnedErrorStream;
+ private InputStream returnedInputStream;
+
+ /**
+ * Lock Object for all processManager related locking.
+ */
+ private static Object queueLock = new Object();
+ private static ProcessManager processManager;
+
+ static class EOFInputStream extends InputStream
+ {
+ static EOFInputStream instance = new EOFInputStream();
+ public int read()
+ {
+ return -1;
+ }
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/Runtime.java b/gcc-4.2.1/libjava/java/lang/Runtime.java
new file mode 100644
index 000000000..3466f19f2
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Runtime.java
@@ -0,0 +1,747 @@
+/* Runtime.java -- access to the VM process
+ Copyright (C) 1998, 2002, 2003, 2004, 2005, 2006 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.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * Runtime represents the Virtual Machine.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Jeroen Frijters
+ */
+// No idea why this class isn't final, since you can't build a subclass!
+public class Runtime
+{
+ /**
+ * The library path, to search when loading libraries. We can also safely use
+ * this as a lock for synchronization.
+ */
+ private final String[] libpath;
+
+ static
+ {
+ init();
+ }
+
+ /**
+ * The thread that started the exit sequence. Access to this field must
+ * be thread-safe; lock on libpath to avoid deadlock with user code.
+ * <code>runFinalization()</code> may want to look at this to see if ALL
+ * finalizers should be run, because the virtual machine is about to halt.
+ */
+ private Thread exitSequence;
+
+ /**
+ * All shutdown hooks. This is initialized lazily, and set to null once all
+ * shutdown hooks have run. Access to this field must be thread-safe; lock
+ * on libpath to avoid deadlock with user code.
+ */
+ private Set shutdownHooks;
+
+ /** True if we should finalize on exit. */
+ private boolean finalizeOnExit;
+
+ /**
+ * The one and only runtime instance.
+ */
+ private static final Runtime current = new Runtime();
+
+ /**
+ * Not instantiable by a user, this should only create one instance.
+ */
+ private Runtime()
+ {
+ if (current != null)
+ throw new InternalError("Attempt to recreate Runtime");
+
+ // We don't use libpath in the libgcj implementation. We still
+ // set it to something to allow the various synchronizations to
+ // work.
+ libpath = new String[0];
+ }
+
+ /**
+ * Get the current Runtime object for this JVM. This is necessary to access
+ * the many instance methods of this class.
+ *
+ * @return the current Runtime object
+ */
+ public static Runtime getRuntime()
+ {
+ return current;
+ }
+
+ /**
+ * Exit the Java runtime. This method will either throw a SecurityException
+ * or it will never return. The status code is returned to the system; often
+ * a non-zero status code indicates an abnormal exit. Of course, there is a
+ * security check, <code>checkExit(status)</code>.
+ *
+ * <p>First, all shutdown hooks are run, in unspecified order, and
+ * concurrently. Next, if finalization on exit has been enabled, all pending
+ * finalizers are run. Finally, the system calls <code>halt</code>.</p>
+ *
+ * <p>If this is run a second time after shutdown has already started, there
+ * are two actions. If shutdown hooks are still executing, it blocks
+ * indefinitely. Otherwise, if the status is nonzero it halts immediately;
+ * if it is zero, it blocks indefinitely. This is typically called by
+ * <code>System.exit</code>.</p>
+ *
+ * @param status the status to exit with
+ * @throws SecurityException if permission is denied
+ * @see #addShutdownHook(Thread)
+ * @see #runFinalizersOnExit(boolean)
+ * @see #runFinalization()
+ * @see #halt(int)
+ */
+ public void exit(int status)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExit(status);
+ exitNoChecks(status);
+ }
+
+ // Accessor to avoid adding a vtable slot.
+ static void exitNoChecksAccessor(int status)
+ {
+ current.exitNoChecks(status);
+ }
+
+ // Private since we can't add a vtable slot in 4.1.x.
+ private void exitNoChecks(int status)
+ {
+ if (runShutdownHooks())
+ exitInternal(status);
+
+ // Someone else already called runShutdownHooks().
+ // Make sure we are not/no longer in the shutdownHooks set.
+ // And wait till the thread that is calling runShutdownHooks() finishes.
+ synchronized (libpath)
+ {
+ if (shutdownHooks != null)
+ {
+ shutdownHooks.remove(Thread.currentThread());
+ // Interrupt the exit sequence thread, in case it was waiting
+ // inside a join on our thread.
+ exitSequence.interrupt();
+ // Shutdown hooks are still running, so we clear status to
+ // make sure we don't halt.
+ status = 0;
+ }
+ }
+
+ // If exit() is called again after the shutdown hooks have run, but
+ // while finalization for exit is going on and the status is non-zero
+ // we halt immediately.
+ if (status != 0)
+ exitInternal(status);
+
+ while (true)
+ try
+ {
+ exitSequence.join();
+ }
+ catch (InterruptedException e)
+ {
+ // Ignore, we've suspended indefinitely to let all shutdown
+ // hooks complete, and to let any non-zero exits through, because
+ // this is a duplicate call to exit(0).
+ }
+ }
+
+ /**
+ * On first invocation, run all the shutdown hooks and return true.
+ * Any subsequent invocations will simply return false.
+ * Note that it is package accessible so that VMRuntime can call it
+ * when VM exit is not triggered by a call to Runtime.exit().
+ *
+ * @return was the current thread the first one to call this method?
+ */
+ boolean runShutdownHooks()
+ {
+ boolean first = false;
+ synchronized (libpath) // Synch on libpath, not this, to avoid deadlock.
+ {
+ if (exitSequence == null)
+ {
+ first = true;
+ exitSequence = Thread.currentThread();
+ if (shutdownHooks != null)
+ {
+ Iterator i = shutdownHooks.iterator();
+ while (i.hasNext()) // Start all shutdown hooks.
+ try
+ {
+ ((Thread) i.next()).start();
+ }
+ catch (IllegalThreadStateException e)
+ {
+ i.remove();
+ }
+ }
+ }
+ }
+ if (first)
+ {
+ if (shutdownHooks != null)
+ {
+ // Check progress of all shutdown hooks. As a hook completes,
+ // remove it from the set. If a hook calls exit, it removes
+ // itself from the set, then waits indefinitely on the
+ // exitSequence thread. Once the set is empty, set it to null to
+ // signal all finalizer threads that halt may be called.
+ while (true)
+ {
+ Thread[] hooks;
+ synchronized (libpath)
+ {
+ hooks = new Thread[shutdownHooks.size()];
+ shutdownHooks.toArray(hooks);
+ }
+ if (hooks.length == 0)
+ break;
+ for (int i = 0; i < hooks.length; i++)
+ {
+ try
+ {
+ synchronized (libpath)
+ {
+ if (!shutdownHooks.contains(hooks[i]))
+ continue;
+ }
+ hooks[i].join();
+ synchronized (libpath)
+ {
+ shutdownHooks.remove(hooks[i]);
+ }
+ }
+ catch (InterruptedException x)
+ {
+ // continue waiting on the next thread
+ }
+ }
+ }
+ synchronized (libpath)
+ {
+ shutdownHooks = null;
+ }
+ }
+ // Run finalization on all finalizable objects (even if they are
+ // still reachable).
+ runFinalizationForExit();
+ }
+ return first;
+ }
+
+ /**
+ * Register a new shutdown hook. This is invoked when the program exits
+ * normally (because all non-daemon threads ended, or because
+ * <code>System.exit</code> was invoked), or when the user terminates
+ * the virtual machine (such as by typing ^C, or logging off). There is
+ * a security check to add hooks,
+ * <code>RuntimePermission("shutdownHooks")</code>.
+ *
+ * <p>The hook must be an initialized, but unstarted Thread. The threads
+ * are run concurrently, and started in an arbitrary order; and user
+ * threads or daemons may still be running. Once shutdown hooks have
+ * started, they must all complete, or else you must use <code>halt</code>,
+ * to actually finish the shutdown sequence. Attempts to modify hooks
+ * after shutdown has started result in IllegalStateExceptions.</p>
+ *
+ * <p>It is imperative that you code shutdown hooks defensively, as you
+ * do not want to deadlock, and have no idea what other hooks will be
+ * running concurrently. It is also a good idea to finish quickly, as the
+ * virtual machine really wants to shut down!</p>
+ *
+ * <p>There are no guarantees that such hooks will run, as there are ways
+ * to forcibly kill a process. But in such a drastic case, shutdown hooks
+ * would do little for you in the first place.</p>
+ *
+ * @param hook an initialized, unstarted Thread
+ * @throws IllegalArgumentException if the hook is already registered or run
+ * @throws IllegalStateException if the virtual machine is already in
+ * the shutdown sequence
+ * @throws SecurityException if permission is denied
+ * @since 1.3
+ * @see #removeShutdownHook(Thread)
+ * @see #exit(int)
+ * @see #halt(int)
+ */
+ public void addShutdownHook(Thread hook)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("shutdownHooks"));
+ if (hook.isAlive() || hook.getThreadGroup() == null)
+ throw new IllegalArgumentException("The hook thread " + hook + " must not have been already run or started");
+ synchronized (libpath)
+ {
+ if (exitSequence != null)
+ throw new IllegalStateException("The Virtual Machine is exiting. It is not possible anymore to add any hooks");
+ if (shutdownHooks == null)
+ shutdownHooks = new HashSet(); // Lazy initialization.
+ if (! shutdownHooks.add(hook))
+ throw new IllegalArgumentException(hook.toString() + " had already been inserted");
+ }
+ }
+
+ /**
+ * De-register a shutdown hook. As when you registered it, there is a
+ * security check to remove hooks,
+ * <code>RuntimePermission("shutdownHooks")</code>.
+ *
+ * @param hook the hook to remove
+ * @return true if the hook was successfully removed, false if it was not
+ * registered in the first place
+ * @throws IllegalStateException if the virtual machine is already in
+ * the shutdown sequence
+ * @throws SecurityException if permission is denied
+ * @since 1.3
+ * @see #addShutdownHook(Thread)
+ * @see #exit(int)
+ * @see #halt(int)
+ */
+ public boolean removeShutdownHook(Thread hook)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("shutdownHooks"));
+ synchronized (libpath)
+ {
+ if (exitSequence != null)
+ throw new IllegalStateException();
+ if (shutdownHooks != null)
+ return shutdownHooks.remove(hook);
+ }
+ return false;
+ }
+
+ /**
+ * Forcibly terminate the virtual machine. This call never returns. It is
+ * much more severe than <code>exit</code>, as it bypasses all shutdown
+ * hooks and initializers. Use caution in calling this! Of course, there is
+ * a security check, <code>checkExit(status)</code>.
+ *
+ * @param status the status to exit with
+ * @throws SecurityException if permission is denied
+ * @since 1.3
+ * @see #exit(int)
+ * @see #addShutdownHook(Thread)
+ */
+ public void halt(int status)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExit(status);
+ exitInternal(status);
+ }
+
+ /**
+ * Tell the VM to run the finalize() method on every single Object before
+ * it exits. Note that the JVM may still exit abnormally and not perform
+ * this, so you still don't have a guarantee. And besides that, this is
+ * inherently unsafe in multi-threaded code, as it may result in deadlock
+ * as multiple threads compete to manipulate objects. This value defaults to
+ * <code>false</code>. There is a security check, <code>checkExit(0)</code>.
+ *
+ * @param finalizeOnExit whether to finalize all Objects on exit
+ * @throws SecurityException if permission is denied
+ * @see #exit(int)
+ * @see #gc()
+ * @since 1.1
+ * @deprecated never rely on finalizers to do a clean, thread-safe,
+ * mop-up from your code
+ */
+ public static void runFinalizersOnExit(boolean finalizeOnExit)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExit(0);
+ current.finalizeOnExit = finalizeOnExit;
+ }
+
+ /**
+ * Create a new subprocess with the specified command line. Calls
+ * <code>exec(cmdline, null, null)</code>. A security check is performed,
+ * <code>checkExec</code>.
+ *
+ * @param cmdline the command to call
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmdline is null
+ * @throws IndexOutOfBoundsException if cmdline is ""
+ */
+ public Process exec(String cmdline) throws IOException
+ {
+ return exec(cmdline, null, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line and environment.
+ * If the environment is null, the process inherits the environment of
+ * this process. Calls <code>exec(cmdline, env, null)</code>. A security
+ * check is performed, <code>checkExec</code>.
+ *
+ * @param cmdline the command to call
+ * @param env the environment to use, in the format name=value
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmdline is null, or env has null entries
+ * @throws IndexOutOfBoundsException if cmdline is ""
+ */
+ public Process exec(String cmdline, String[] env) throws IOException
+ {
+ return exec(cmdline, env, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, environment, and
+ * working directory. If the environment is null, the process inherits the
+ * environment of this process. If the directory is null, the process uses
+ * the current working directory. This splits cmdline into an array, using
+ * the default StringTokenizer, then calls
+ * <code>exec(cmdArray, env, dir)</code>. A security check is performed,
+ * <code>checkExec</code>.
+ *
+ * @param cmdline the command to call
+ * @param env the environment to use, in the format name=value
+ * @param dir the working directory to use
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmdline is null, or env has null entries
+ * @throws IndexOutOfBoundsException if cmdline is ""
+ * @since 1.3
+ */
+ public Process exec(String cmdline, String[] env, File dir)
+ throws IOException
+ {
+ StringTokenizer t = new StringTokenizer(cmdline);
+ String[] cmd = new String[t.countTokens()];
+ for (int i = 0; i < cmd.length; i++)
+ cmd[i] = t.nextToken();
+ return exec(cmd, env, dir);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, already
+ * tokenized. Calls <code>exec(cmd, null, null)</code>. A security check
+ * is performed, <code>checkExec</code>.
+ *
+ * @param cmd the command to call
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmd is null, or has null entries
+ * @throws IndexOutOfBoundsException if cmd is length 0
+ */
+ public Process exec(String[] cmd) throws IOException
+ {
+ return exec(cmd, null, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, already
+ * tokenized, and specified environment. If the environment is null, the
+ * process inherits the environment of this process. Calls
+ * <code>exec(cmd, env, null)</code>. A security check is performed,
+ * <code>checkExec</code>.
+ *
+ * @param cmd the command to call
+ * @param env the environment to use, in the format name=value
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmd is null, or cmd or env has null
+ * entries
+ * @throws IndexOutOfBoundsException if cmd is length 0
+ */
+ public Process exec(String[] cmd, String[] env) throws IOException
+ {
+ return exec(cmd, env, null);
+ }
+
+ /**
+ * Create a new subprocess with the specified command line, already
+ * tokenized, and the specified environment and working directory. If the
+ * environment is null, the process inherits the environment of this
+ * process. If the directory is null, the process uses the current working
+ * directory. A security check is performed, <code>checkExec</code>.
+ *
+ * @param cmd the command to call
+ * @param env the environment to use, in the format name=value
+ * @param dir the working directory to use
+ * @return the Process object
+ * @throws SecurityException if permission is denied
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if cmd is null, or cmd or env has null
+ * entries
+ * @throws IndexOutOfBoundsException if cmd is length 0
+ * @since 1.3
+ */
+ public Process exec(String[] cmd, String[] env, File dir)
+ throws IOException
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkExec(cmd[0]);
+ return execInternal(cmd, env, dir);
+ }
+
+ /**
+ * 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
+ */
+ public 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
+ */
+ public 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
+ */
+ public 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
+ */
+ public 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.
+ */
+ public 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()
+ */
+ public native void runFinalization();
+
+ /**
+ * 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
+ */
+ public 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
+ */
+ public native void traceMethodCalls(boolean on);
+
+ /**
+ * Load a native library using the system-dependent filename. This is similar
+ * to loadLibrary, except the only name mangling done is inserting "_g"
+ * before the final ".so" if the VM was invoked by the name "java_g". There
+ * may be a security check, of <code>checkLink</code>.
+ *
+ * @param filename the file to load
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the library is not found
+ */
+ public void load(String filename)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkLink(filename);
+ _load(filename, false);
+ }
+
+ /**
+ * Load a native library using a system-independent "short name" for the
+ * library. It will be transformed to a correct filename in a
+ * system-dependent manner (for example, in Windows, "mylib" will be turned
+ * into "mylib.dll"). This is done as follows: if the context that called
+ * load has a ClassLoader cl, then <code>cl.findLibrary(libpath)</code> is
+ * used to convert the name. If that result was null, or there was no class
+ * loader, this searches each directory of the system property
+ * <code>java.library.path</code> for a file named
+ * <code>System.mapLibraryName(libname)</code>. There may be a security
+ * check, of <code>checkLink</code>.
+ *
+ * @param libname the library to load
+ *
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the library is not found
+ *
+ * @see System#mapLibraryName(String)
+ * @see ClassLoader#findLibrary(String)
+ */
+ public void loadLibrary(String libname)
+ {
+ // This is different from the Classpath implementation, but I
+ // believe it is more correct.
+ SecurityManager sm = SecurityManager.current; // Be thread-safe!
+ if (sm != null)
+ sm.checkLink(libname);
+ _load(libname, true);
+ }
+
+ /**
+ * Return a localized version of this InputStream, meaning all characters
+ * are localized before they come out the other end.
+ *
+ * @param in the stream to localize
+ * @return the localized stream
+ * @deprecated <code>InputStreamReader</code> is the preferred way to read
+ * local encodings
+ */
+ public InputStream getLocalizedInputStream(InputStream in)
+ {
+ return in;
+ }
+
+ /**
+ * Return a localized version of this OutputStream, meaning all characters
+ * are localized before they are sent to the other end.
+ *
+ * @param out the stream to localize
+ * @return the localized stream
+ * @deprecated <code>OutputStreamWriter</code> is the preferred way to write
+ * local encodings
+ */
+ public OutputStream getLocalizedOutputStream(OutputStream out)
+ {
+ return out;
+ }
+
+ /**
+ * Native method that actually shuts down the virtual machine.
+ *
+ * @param status the status to end the process with
+ */
+ native void exitInternal(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 do_search True if we should search the load path for the file
+ */
+ native void _load(String filename, boolean do_search);
+
+ /**
+ *This is a helper function for the ClassLoader which can load
+ * compiled libraries. Returns true if library (which is just the
+ * base name -- path searching is done by this function) was loaded,
+ * false otherwise.
+ */
+ native boolean loadLibraryInternal(String libname);
+
+ /**
+ * A helper for Runtime static initializer which does some internal native
+ * initialization.
+ */
+ private static native void init ();
+
+ /**
+ * Run finalizers when exiting.
+ */
+ private native void runFinalizationForExit();
+
+ /**
+ * Map a system-independent "short name" to the full file name, and append
+ * it to the path.
+ * XXX This method is being replaced by System.mapLibraryName.
+ *
+ * @param pathname the path
+ * @param libname the short version of the library name
+ * @return the full filename
+ */
+ static native String nativeGetLibname(String pathname, 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.
+ *
+ * @param cmd the non-null command tokens
+ * @param env the non-null 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
+ * @throws IOException if the exec fails
+ */
+ native Process execInternal(String[] cmd, String[] env, File dir)
+ throws IOException;
+} // class Runtime
diff --git a/gcc-4.2.1/libjava/java/lang/SecurityManager.java b/gcc-4.2.1/libjava/java/lang/SecurityManager.java
new file mode 100644
index 000000000..c803c5b85
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/SecurityManager.java
@@ -0,0 +1,1057 @@
+/* SecurityManager.java -- security checks for privileged actions
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006
+ 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.awt.AWTPermission;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FilePermission;
+import java.lang.reflect.Member;
+import java.net.InetAddress;
+import java.net.SocketPermission;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.security.PrivilegedAction;
+import java.security.Security;
+import java.security.SecurityPermission;
+import java.util.PropertyPermission;
+import java.util.StringTokenizer;
+
+/**
+ * SecurityManager is a class you can extend to create your own Java
+ * security policy. By default, there is no SecurityManager installed in
+ * 1.1, which means that all things are permitted to all people. The security
+ * manager, if set, is consulted before doing anything with potentially
+ * dangerous results, and throws a <code>SecurityException</code> if the
+ * action is forbidden.
+ *
+ * <p>A typical check is as follows, just before the dangerous operation:<br>
+ * <pre>
+ * SecurityManager sm = System.getSecurityManager();
+ * if (sm != null)
+ * sm.checkABC(<em>argument</em>, ...);
+ * </pre>
+ * Note that this is thread-safe, by caching the security manager in a local
+ * variable rather than risking a NullPointerException if the mangager is
+ * changed between the check for null and before the permission check.
+ *
+ * <p>The special method <code>checkPermission</code> is a catchall, and
+ * the default implementation calls
+ * <code>AccessController.checkPermission</code>. In fact, all the other
+ * methods default to calling checkPermission.
+ *
+ * <p>Sometimes, the security check needs to happen from a different context,
+ * such as when called from a worker thread. In such cases, use
+ * <code>getSecurityContext</code> to take a snapshot that can be passed
+ * to the worker thread:<br>
+ * <pre>
+ * Object context = null;
+ * SecurityManager sm = System.getSecurityManager();
+ * if (sm != null)
+ * context = sm.getSecurityContext(); // defaults to an AccessControlContext
+ * // now, in worker thread
+ * if (sm != null)
+ * sm.checkPermission(permission, context);
+ * </pre>
+ *
+ * <p>Permissions fall into these categories: File, Socket, Net, Security,
+ * Runtime, Property, AWT, Reflect, and Serializable. Each of these
+ * permissions have a property naming convention, that follows a hierarchical
+ * naming convention, to make it easy to grant or deny several permissions
+ * at once. Some permissions also take a list of permitted actions, such
+ * as "read" or "write", to fine-tune control even more. The permission
+ * <code>java.security.AllPermission</code> grants all permissions.
+ *
+ * <p>The default methods in this class deny all things to all people. You
+ * must explicitly grant permission for anything you want to be legal when
+ * subclassing this class.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see ClassLoader
+ * @see SecurityException
+ * @see #checkTopLevelWindow(Object)
+ * @see System#getSecurityManager()
+ * @see System#setSecurityManager(SecurityManager)
+ * @see AccessController
+ * @see AccessControlContext
+ * @see AccessControlException
+ * @see Permission
+ * @see BasicPermission
+ * @see java.io.FilePermission
+ * @see java.net.SocketPermission
+ * @see java.util.PropertyPermission
+ * @see RuntimePermission
+ * @see java.awt.AWTPermission
+ * @see Policy
+ * @see SecurityPermission
+ * @see ProtectionDomain
+ * @since 1.0
+ * @status still missing 1.4 functionality
+ */
+public class SecurityManager
+{
+ /**
+ * The current security manager. This is located here instead of in
+ * System, to avoid security problems, as well as bootstrap issues.
+ * Make sure to access it in a thread-safe manner; it is package visible
+ * to avoid overhead in java.lang.
+ */
+ static volatile SecurityManager current;
+
+ /**
+ * Tells whether or not the SecurityManager is currently performing a
+ * security check.
+ * @deprecated Use {@link #checkPermission(Permission)} instead.
+ */
+ protected boolean inCheck;
+
+ /**
+ * Construct a new security manager. There may be a security check, of
+ * <code>RuntimePermission("createSecurityManager")</code>.
+ *
+ * @throws SecurityException if permission is denied
+ */
+ public SecurityManager()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("createSecurityManager"));
+ }
+
+ /**
+ * Tells whether or not the SecurityManager is currently performing a
+ * security check.
+ *
+ * @return true if the SecurityManager is in a security check
+ * @see #inCheck
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ public boolean getInCheck()
+ {
+ return inCheck;
+ }
+
+ /**
+ * Get a list of all the classes currently executing methods on the Java
+ * stack. getClassContext()[0] is the currently executing method (ie. the
+ * class that CALLED getClassContext, not SecurityManager).
+ *
+ * @return an array of classes on the Java execution stack
+ */
+ protected Class[] getClassContext()
+ {
+ return VMSecurityManager.getClassContext(SecurityManager.class);
+ }
+
+ /**
+ * Find the ClassLoader of the first non-system class on the execution
+ * stack. A non-system class is one whose ClassLoader is not equal to
+ * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
+ * will return null in three cases:
+ *
+ * <ul>
+ * <li>All methods on the stack are from system classes</li>
+ * <li>All methods on the stack up to the first "privileged" caller, as
+ * created by {@link AccessController#doPrivileged(PrivilegedAction)},
+ * are from system classes</li>
+ * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
+ * </ul>
+ *
+ * @return the most recent non-system ClassLoader on the execution stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected ClassLoader currentClassLoader()
+ {
+ return VMSecurityManager.currentClassLoader(SecurityManager.class);
+ }
+
+ /**
+ * Find the first non-system class on the execution stack. A non-system
+ * class is one whose ClassLoader is not equal to
+ * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
+ * will return null in three cases:
+ *
+ * <ul>
+ * <li>All methods on the stack are from system classes</li>
+ * <li>All methods on the stack up to the first "privileged" caller, as
+ * created by {@link AccessController#doPrivileged(PrivilegedAction)},
+ * are from system classes</li>
+ * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
+ * </ul>
+ *
+ * @return the most recent non-system Class on the execution stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected Class currentLoadedClass()
+ {
+ int i = classLoaderDepth();
+ return i >= 0 ? getClassContext()[i] : null;
+ }
+
+ /**
+ * Get the depth of a particular class on the execution stack.
+ *
+ * @param className the fully-qualified name to search for
+ * @return the index of the class on the stack, or -1
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected int classDepth(String className)
+ {
+ Class[] c = getClassContext();
+ for (int i = 0; i < c.length; i++)
+ if (className.equals(c[i].getName()))
+ return i;
+ return -1;
+ }
+
+ /**
+ * Get the depth on the execution stack of the most recent non-system class.
+ * A non-system class is one whose ClassLoader is not equal to
+ * {@link ClassLoader#getSystemClassLoader()} or its ancestors. This
+ * will return -1 in three cases:
+ *
+ * <ul>
+ * <li>All methods on the stack are from system classes</li>
+ * <li>All methods on the stack up to the first "privileged" caller, as
+ * created by {@link AccessController#doPrivileged(PrivilegedAction)},
+ * are from system classes</li>
+ * <li>A check of <code>java.security.AllPermission</code> succeeds.</li>
+ * </ul>
+ *
+ * @return the index of the most recent non-system Class on the stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected int classLoaderDepth()
+ {
+ try
+ {
+ checkPermission(new AllPermission());
+ }
+ catch (SecurityException e)
+ {
+ Class[] c = getClassContext();
+ for (int i = 0; i < c.length; i++)
+ if (c[i].getClassLoader() != null)
+ // XXX Check if c[i] is AccessController, or a system class.
+ return i;
+ }
+ return -1;
+ }
+
+ /**
+ * Tell whether the specified class is on the execution stack.
+ *
+ * @param className the fully-qualified name of the class to find
+ * @return whether the specified class is on the execution stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected boolean inClass(String className)
+ {
+ return classDepth(className) != -1;
+ }
+
+ /**
+ * Tell whether there is a class loaded with an explicit ClassLoader on
+ * the stack.
+ *
+ * @return whether a class with an explicit ClassLoader is on the stack
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ protected boolean inClassLoader()
+ {
+ return classLoaderDepth() != -1;
+ }
+
+ /**
+ * Get an implementation-dependent Object that contains enough information
+ * about the current environment to be able to perform standard security
+ * checks later. This is used by trusted methods that need to verify that
+ * their callers have sufficient access to perform certain operations.
+ *
+ * <p>Currently the only methods that use this are checkRead() and
+ * checkConnect(). The default implementation returns an
+ * <code>AccessControlContext</code>.
+ *
+ * @return a security context
+ * @see #checkConnect(String, int, Object)
+ * @see #checkRead(String, Object)
+ * @see AccessControlContext
+ * @see AccessController#getContext()
+ */
+ public Object getSecurityContext()
+ {
+ return AccessController.getContext();
+ }
+
+ /**
+ * Check if the current thread is allowed to perform an operation that
+ * requires the specified <code>Permission</code>. This defaults to
+ * <code>AccessController.checkPermission</code>.
+ *
+ * @param perm the <code>Permission</code> required
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if perm is null
+ * @since 1.2
+ */
+ public void checkPermission(Permission perm)
+ {
+ AccessController.checkPermission(perm);
+ }
+
+ /**
+ * Check if the current thread is allowed to perform an operation that
+ * requires the specified <code>Permission</code>. This is done in a
+ * context previously returned by <code>getSecurityContext()</code>. The
+ * default implementation expects context to be an AccessControlContext,
+ * and it calls <code>AccessControlContext.checkPermission(perm)</code>.
+ *
+ * @param perm the <code>Permission</code> required
+ * @param context a security context
+ * @throws SecurityException if permission is denied, or if context is
+ * not an AccessControlContext
+ * @throws NullPointerException if perm is null
+ * @see #getSecurityContext()
+ * @see AccessControlContext#checkPermission(Permission)
+ * @since 1.2
+ */
+ public void checkPermission(Permission perm, Object context)
+ {
+ if (! (context instanceof AccessControlContext))
+ throw new SecurityException("Missing context");
+ ((AccessControlContext) context).checkPermission(perm);
+ }
+
+ /**
+ * Check if the current thread is allowed to create a ClassLoader. This
+ * method is called from ClassLoader.ClassLoader(), and checks
+ * <code>RuntimePermission("createClassLoader")</code>. If you override
+ * this, you should call <code>super.checkCreateClassLoader()</code> rather
+ * than throwing an exception.
+ *
+ * @throws SecurityException if permission is denied
+ * @see ClassLoader#ClassLoader()
+ */
+ public void checkCreateClassLoader()
+ {
+ checkPermission(new RuntimePermission("createClassLoader"));
+ }
+
+ /**
+ * Check if the current thread is allowed to modify another Thread. This is
+ * called by Thread.stop(), suspend(), resume(), interrupt(), destroy(),
+ * setPriority(), setName(), and setDaemon(). The default implementation
+ * checks <code>RuntimePermission("modifyThread")</code> on system threads
+ * (ie. threads in ThreadGroup with a null parent), and returns silently on
+ * other threads.
+ *
+ * <p>If you override this, you must do two things. First, call
+ * <code>super.checkAccess(t)</code>, to make sure you are not relaxing
+ * requirements. Second, if the calling thread has
+ * <code>RuntimePermission("modifyThread")</code>, return silently, so that
+ * core classes (the Classpath library!) can modify any thread.
+ *
+ * @param thread the other Thread to check
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if thread is null
+ * @see Thread#stop()
+ * @see Thread#suspend()
+ * @see Thread#resume()
+ * @see Thread#setPriority(int)
+ * @see Thread#setName(String)
+ * @see Thread#setDaemon(boolean)
+ */
+ public void checkAccess(Thread thread)
+ {
+ if (thread.getThreadGroup() != null
+ && thread.getThreadGroup().getParent() == null)
+ checkPermission(new RuntimePermission("modifyThread"));
+ }
+
+ /**
+ * Check if the current thread is allowed to modify a ThreadGroup. This is
+ * called by Thread.Thread() (to add a thread to the ThreadGroup),
+ * ThreadGroup.ThreadGroup() (to add this ThreadGroup to a parent),
+ * ThreadGroup.stop(), suspend(), resume(), interrupt(), destroy(),
+ * setDaemon(), and setMaxPriority(). The default implementation
+ * checks <code>RuntimePermission("modifyThread")</code> on the system group
+ * (ie. the one with a null parent), and returns silently on other groups.
+ *
+ * <p>If you override this, you must do two things. First, call
+ * <code>super.checkAccess(t)</code>, to make sure you are not relaxing
+ * requirements. Second, if the calling thread has
+ * <code>RuntimePermission("modifyThreadGroup")</code>, return silently,
+ * so that core classes (the Classpath library!) can modify any thread.
+ *
+ * @param g the ThreadGroup to check
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if g is null
+ * @see Thread#Thread()
+ * @see ThreadGroup#ThreadGroup(String)
+ * @see ThreadGroup#stop()
+ * @see ThreadGroup#suspend()
+ * @see ThreadGroup#resume()
+ * @see ThreadGroup#interrupt()
+ * @see ThreadGroup#setDaemon(boolean)
+ * @see ThreadGroup#setMaxPriority(int)
+ */
+ public void checkAccess(ThreadGroup g)
+ {
+ if (g.getParent() == null)
+ checkPermission(new RuntimePermission("modifyThreadGroup"));
+ }
+
+ /**
+ * Check if the current thread is allowed to exit the JVM with the given
+ * status. This method is called from Runtime.exit() and Runtime.halt().
+ * The default implementation checks
+ * <code>RuntimePermission("exitVM")</code>. If you override this, call
+ * <code>super.checkExit</code> rather than throwing an exception.
+ *
+ * @param status the status to exit with
+ * @throws SecurityException if permission is denied
+ * @see Runtime#exit(int)
+ * @see Runtime#halt(int)
+ */
+ public void checkExit(int status)
+ {
+ checkPermission(new RuntimePermission("exitVM"));
+ }
+
+ /**
+ * Check if the current thread is allowed to execute the given program. This
+ * method is called from Runtime.exec(). If the name is an absolute path,
+ * the default implementation checks
+ * <code>FilePermission(program, "execute")</code>, otherwise it checks
+ * <code>FilePermission("&lt;&lt;ALL FILES&gt;&gt;", "execute")</code>. If
+ * you override this, call <code>super.checkExec</code> rather than
+ * throwing an exception.
+ *
+ * @param program the name of the program to exec
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if program is null
+ * @see Runtime#exec(String[], String[], File)
+ */
+ public void checkExec(String program)
+ {
+ if (! program.equals(new File(program).getAbsolutePath()))
+ program = "<<ALL FILES>>";
+ checkPermission(new FilePermission(program, "execute"));
+ }
+
+ /**
+ * Check if the current thread is allowed to link in the given native
+ * library. This method is called from Runtime.load() (and hence, by
+ * loadLibrary() as well). The default implementation checks
+ * <code>RuntimePermission("loadLibrary." + filename)</code>. If you
+ * override this, call <code>super.checkLink</code> rather than throwing
+ * an exception.
+ *
+ * @param filename the full name of the library to load
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if filename is null
+ * @see Runtime#load(String)
+ */
+ public void checkLink(String filename)
+ {
+ // Use the toString() hack to do the null check.
+ checkPermission(new RuntimePermission("loadLibrary."
+ + filename.toString()));
+ }
+
+ /**
+ * Check if the current thread is allowed to read the given file using the
+ * FileDescriptor. This method is called from
+ * FileInputStream.FileInputStream(). The default implementation checks
+ * <code>RuntimePermission("readFileDescriptor")</code>. If you override
+ * this, call <code>super.checkRead</code> rather than throwing an
+ * exception.
+ *
+ * @param desc the FileDescriptor representing the file to access
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if desc is null
+ * @see FileInputStream#FileInputStream(FileDescriptor)
+ */
+ public void checkRead(FileDescriptor desc)
+ {
+ if (desc == null)
+ throw new NullPointerException();
+ checkPermission(new RuntimePermission("readFileDescriptor"));
+ }
+
+ /**
+ * Check if the current thread is allowed to read the given file. This
+ * method is called from FileInputStream.FileInputStream(),
+ * RandomAccessFile.RandomAccessFile(), File.exists(), canRead(), isFile(),
+ * isDirectory(), lastModified(), length() and list(). The default
+ * implementation checks <code>FilePermission(filename, "read")</code>. If
+ * you override this, call <code>super.checkRead</code> rather than
+ * throwing an exception.
+ *
+ * @param filename the full name of the file to access
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if filename is null
+ * @see File
+ * @see FileInputStream#FileInputStream(String)
+ * @see RandomAccessFile#RandomAccessFile(String, String)
+ */
+ public void checkRead(String filename)
+ {
+ checkPermission(new FilePermission(filename, "read"));
+ }
+
+ /**
+ * Check if the current thread is allowed to read the given file. using the
+ * given security context. The context must be a result of a previous call
+ * to <code>getSecurityContext()</code>. The default implementation checks
+ * <code>AccessControlContext.checkPermission(new FilePermission(filename,
+ * "read"))</code>. If you override this, call <code>super.checkRead</code>
+ * rather than throwing an exception.
+ *
+ * @param filename the full name of the file to access
+ * @param context the context to determine access for
+ * @throws SecurityException if permission is denied, or if context is
+ * not an AccessControlContext
+ * @throws NullPointerException if filename is null
+ * @see #getSecurityContext()
+ * @see AccessControlContext#checkPermission(Permission)
+ */
+ public void checkRead(String filename, Object context)
+ {
+ if (! (context instanceof AccessControlContext))
+ throw new SecurityException("Missing context");
+ AccessControlContext ac = (AccessControlContext) context;
+ ac.checkPermission(new FilePermission(filename, "read"));
+ }
+
+ /**
+ * Check if the current thread is allowed to write the given file using the
+ * FileDescriptor. This method is called from
+ * FileOutputStream.FileOutputStream(). The default implementation checks
+ * <code>RuntimePermission("writeFileDescriptor")</code>. If you override
+ * this, call <code>super.checkWrite</code> rather than throwing an
+ * exception.
+ *
+ * @param desc the FileDescriptor representing the file to access
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if desc is null
+ * @see FileOutputStream#FileOutputStream(FileDescriptor)
+ */
+ public void checkWrite(FileDescriptor desc)
+ {
+ if (desc == null)
+ throw new NullPointerException();
+ checkPermission(new RuntimePermission("writeFileDescriptor"));
+ }
+
+ /**
+ * Check if the current thread is allowed to write the given file. This
+ * method is called from FileOutputStream.FileOutputStream(),
+ * RandomAccessFile.RandomAccessFile(), File.canWrite(), mkdir(), and
+ * renameTo(). The default implementation checks
+ * <code>FilePermission(filename, "write")</code>. If you override this,
+ * call <code>super.checkWrite</code> rather than throwing an exception.
+ *
+ * @param filename the full name of the file to access
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if filename is null
+ * @see File
+ * @see File#canWrite()
+ * @see File#mkdir()
+ * @see File#renameTo(File)
+ * @see FileOutputStream#FileOutputStream(String)
+ * @see RandomAccessFile#RandomAccessFile(String, String)
+ */
+ public void checkWrite(String filename)
+ {
+ checkPermission(new FilePermission(filename, "write"));
+ }
+
+ /**
+ * Check if the current thread is allowed to delete the given file. This
+ * method is called from File.delete(). The default implementation checks
+ * <code>FilePermission(filename, "delete")</code>. If you override this,
+ * call <code>super.checkDelete</code> rather than throwing an exception.
+ *
+ * @param filename the full name of the file to delete
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if filename is null
+ * @see File#delete()
+ */
+ public void checkDelete(String filename)
+ {
+ checkPermission(new FilePermission(filename, "delete"));
+ }
+
+ /**
+ * Check if the current thread is allowed to connect to a given host on a
+ * given port. This method is called from Socket.Socket(). A port number
+ * of -1 indicates the caller is attempting to determine an IP address, so
+ * the default implementation checks
+ * <code>SocketPermission(host, "resolve")</code>. Otherwise, the default
+ * implementation checks
+ * <code>SocketPermission(host + ":" + port, "connect")</code>. If you
+ * override this, call <code>super.checkConnect</code> rather than throwing
+ * an exception.
+ *
+ * @param host the host to connect to
+ * @param port the port to connect on
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if host is null
+ * @see Socket#Socket()
+ */
+ public void checkConnect(String host, int port)
+ {
+ if (port == -1)
+ checkPermission(new SocketPermission(host, "resolve"));
+ else
+ // Use the toString() hack to do the null check.
+ checkPermission(new SocketPermission(host.toString() + ":" + port,
+ "connect"));
+ }
+
+ /**
+ * Check if the current thread is allowed to connect to a given host on a
+ * given port, using the given security context. The context must be a
+ * result of a previous call to <code>getSecurityContext</code>. A port
+ * number of -1 indicates the caller is attempting to determine an IP
+ * address, so the default implementation checks
+ * <code>AccessControlContext.checkPermission(new SocketPermission(host,
+ * "resolve"))</code>. Otherwise, the default implementation checks
+ * <code>AccessControlContext.checkPermission(new SocketPermission(host
+ * + ":" + port, "connect"))</code>. If you override this, call
+ * <code>super.checkConnect</code> rather than throwing an exception.
+ *
+ * @param host the host to connect to
+ * @param port the port to connect on
+ * @param context the context to determine access for
+ *
+ * @throws SecurityException if permission is denied, or if context is
+ * not an AccessControlContext
+ * @throws NullPointerException if host is null
+ *
+ * @see #getSecurityContext()
+ * @see AccessControlContext#checkPermission(Permission)
+ */
+ public void checkConnect(String host, int port, Object context)
+ {
+ if (! (context instanceof AccessControlContext))
+ throw new SecurityException("Missing context");
+ AccessControlContext ac = (AccessControlContext) context;
+ if (port == -1)
+ ac.checkPermission(new SocketPermission(host, "resolve"));
+ else
+ // Use the toString() hack to do the null check.
+ ac.checkPermission(new SocketPermission(host.toString() + ":" + port,
+ "connect"));
+ }
+
+ /**
+ * Check if the current thread is allowed to listen to a specific port for
+ * data. This method is called by ServerSocket.ServerSocket(). The default
+ * implementation checks
+ * <code>SocketPermission("localhost:" + (port == 0 ? "1024-" : "" + port),
+ * "listen")</code>. If you override this, call
+ * <code>super.checkListen</code> rather than throwing an exception.
+ *
+ * @param port the port to listen on
+ * @throws SecurityException if permission is denied
+ * @see ServerSocket#ServerSocket(int)
+ */
+ public void checkListen(int port)
+ {
+ checkPermission(new SocketPermission("localhost:"
+ + (port == 0 ? "1024-" : "" +port),
+ "listen"));
+ }
+
+ /**
+ * Check if the current thread is allowed to accept a connection from a
+ * particular host on a particular port. This method is called by
+ * ServerSocket.implAccept(). The default implementation checks
+ * <code>SocketPermission(host + ":" + port, "accept")</code>. If you
+ * override this, call <code>super.checkAccept</code> rather than throwing
+ * an exception.
+ *
+ * @param host the host which wishes to connect
+ * @param port the port the connection will be on
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if host is null
+ * @see ServerSocket#accept()
+ */
+ public void checkAccept(String host, int port)
+ {
+ // Use the toString() hack to do the null check.
+ checkPermission(new SocketPermission(host.toString() + ":" + port,
+ "accept"));
+ }
+
+ /**
+ * Check if the current thread is allowed to read and write multicast to
+ * a particular address. The default implementation checks
+ * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>.
+ * If you override this, call <code>super.checkMulticast</code> rather than
+ * throwing an exception.
+ *
+ * @param addr the address to multicast to
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if host is null
+ * @since 1.1
+ */
+ public void checkMulticast(InetAddress addr)
+ {
+ checkPermission(new SocketPermission(addr.getHostAddress(),
+ "accept,connect"));
+ }
+
+ /**
+ *Check if the current thread is allowed to read and write multicast to
+ * a particular address with a particular ttl (time-to-live) value. The
+ * default implementation ignores ttl, and checks
+ * <code>SocketPermission(addr.getHostAddress(), "accept,connect")</code>.
+ * If you override this, call <code>super.checkMulticast</code> rather than
+ * throwing an exception.
+ *
+ * @param addr the address to multicast to
+ * @param ttl value in use for multicast send
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if host is null
+ * @since 1.1
+ * @deprecated use {@link #checkPermission(Permission)} instead
+ */
+ public void checkMulticast(InetAddress addr, byte ttl)
+ {
+ checkPermission(new SocketPermission(addr.getHostAddress(),
+ "accept,connect"));
+ }
+
+ /**
+ * Check if the current thread is allowed to read or write all the system
+ * properties at once. This method is called by System.getProperties()
+ * and setProperties(). The default implementation checks
+ * <code>PropertyPermission("*", "read,write")</code>. If you override
+ * this, call <code>super.checkPropertiesAccess</code> rather than
+ * throwing an exception.
+ *
+ * @throws SecurityException if permission is denied
+ * @see System#getProperties()
+ * @see System#setProperties(Properties)
+ */
+ public void checkPropertiesAccess()
+ {
+ checkPermission(new PropertyPermission("*", "read,write"));
+ }
+
+ /**
+ * Check if the current thread is allowed to read a particular system
+ * property (writes are checked directly via checkPermission). This method
+ * is called by System.getProperty() and setProperty(). The default
+ * implementation checks <code>PropertyPermission(key, "read")</code>. If
+ * you override this, call <code>super.checkPropertyAccess</code> rather
+ * than throwing an exception.
+ *
+ * @param key the key of the property to check
+ *
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ *
+ * @see System#getProperty(String)
+ */
+ public void checkPropertyAccess(String key)
+ {
+ checkPermission(new PropertyPermission(key, "read"));
+ }
+
+ /**
+ * Check if the current thread is allowed to create a top-level window. If
+ * it is not, the operation should still go through, but some sort of
+ * nonremovable warning should be placed on the window to show that it
+ * is untrusted. This method is called by Window.Window(). The default
+ * implementation checks
+ * <code>AWTPermission("showWindowWithoutWarningBanner")</code>, and returns
+ * true if no exception was thrown. If you override this, use
+ * <code>return super.checkTopLevelWindow</code> rather than returning
+ * false.
+ *
+ * @param window the window to create
+ * @return true if there is permission to show the window without warning
+ * @throws NullPointerException if window is null
+ * @see java.awt.Window#Window(java.awt.Frame)
+ */
+ public boolean checkTopLevelWindow(Object window)
+ {
+ if (window == null)
+ throw new NullPointerException();
+ try
+ {
+ checkPermission(new AWTPermission("showWindowWithoutWarningBanner"));
+ return true;
+ }
+ catch (SecurityException e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Check if the current thread is allowed to create a print job. This
+ * method is called by Toolkit.getPrintJob(). The default implementation
+ * checks <code>RuntimePermission("queuePrintJob")</code>. If you override
+ * this, call <code>super.checkPrintJobAccess</code> rather than throwing
+ * an exception.
+ *
+ * @throws SecurityException if permission is denied
+ * @see java.awt.Toolkit#getPrintJob(java.awt.Frame, String, Properties)
+ * @since 1.1
+ */
+ public void checkPrintJobAccess()
+ {
+ checkPermission(new RuntimePermission("queuePrintJob"));
+ }
+
+ /**
+ * Check if the current thread is allowed to use the system clipboard. This
+ * method is called by Toolkit.getSystemClipboard(). The default
+ * implementation checks <code>AWTPermission("accessClipboard")</code>. If
+ * you override this, call <code>super.checkSystemClipboardAccess</code>
+ * rather than throwing an exception.
+ *
+ * @throws SecurityException if permission is denied
+ * @see java.awt.Toolkit#getSystemClipboard()
+ * @since 1.1
+ */
+ public void checkSystemClipboardAccess()
+ {
+ checkPermission(new AWTPermission("accessClipboard"));
+ }
+
+ /**
+ * Check if the current thread is allowed to use the AWT event queue. This
+ * method is called by Toolkit.getSystemEventQueue(). The default
+ * implementation checks <code>AWTPermission("accessEventQueue")</code>.
+ * you override this, call <code>super.checkAwtEventQueueAccess</code>
+ * rather than throwing an exception.
+ *
+ * @throws SecurityException if permission is denied
+ * @see java.awt.Toolkit#getSystemEventQueue()
+ * @since 1.1
+ */
+ public void checkAwtEventQueueAccess()
+ {
+ checkPermission(new AWTPermission("accessEventQueue"));
+ }
+
+ /**
+ * Check if the current thread is allowed to access the specified package
+ * at all. This method is called by ClassLoader.loadClass() in user-created
+ * ClassLoaders. The default implementation gets a list of all restricted
+ * packages, via <code>Security.getProperty("package.access")</code>. Then,
+ * if packageName starts with or equals any restricted package, it checks
+ * <code>RuntimePermission("accessClassInPackage." + packageName)</code>.
+ * If you override this, you should call
+ * <code>super.checkPackageAccess</code> before doing anything else.
+ *
+ * @param packageName the package name to check access to
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if packageName is null
+ * @see ClassLoader#loadClass(String, boolean)
+ * @see Security#getProperty(String)
+ */
+ public void checkPackageAccess(String packageName)
+ {
+ checkPackageList(packageName, "package.access", "accessClassInPackage.");
+ }
+
+ /**
+ * Check if the current thread is allowed to define a class into the
+ * specified package. This method is called by ClassLoader.loadClass() in
+ * user-created ClassLoaders. The default implementation gets a list of all
+ * restricted packages, via
+ * <code>Security.getProperty("package.definition")</code>. Then, if
+ * packageName starts with or equals any restricted package, it checks
+ * <code>RuntimePermission("defineClassInPackage." + packageName)</code>.
+ * If you override this, you should call
+ * <code>super.checkPackageDefinition</code> before doing anything else.
+ *
+ * @param packageName the package name to check access to
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if packageName is null
+ * @see ClassLoader#loadClass(String, boolean)
+ * @see Security#getProperty(String)
+ */
+ public void checkPackageDefinition(String packageName)
+ {
+ checkPackageList(packageName, "package.definition", "defineClassInPackage.");
+ }
+
+ /**
+ * Check if the current thread is allowed to set the current socket factory.
+ * This method is called by Socket.setSocketImplFactory(),
+ * ServerSocket.setSocketFactory(), and URL.setURLStreamHandlerFactory().
+ * The default implementation checks
+ * <code>RuntimePermission("setFactory")</code>. If you override this, call
+ * <code>super.checkSetFactory</code> rather than throwing an exception.
+ *
+ * @throws SecurityException if permission is denied
+ * @see Socket#setSocketImplFactory(SocketImplFactory)
+ * @see ServerSocket#setSocketFactory(SocketImplFactory)
+ * @see URL#setURLStreamHandlerFactory(URLStreamHandlerFactory)
+ */
+ public void checkSetFactory()
+ {
+ checkPermission(new RuntimePermission("setFactory"));
+ }
+
+ /**
+ * Check if the current thread is allowed to get certain types of Methods,
+ * Fields and Constructors from a Class object. This method is called by
+ * Class.getMethod[s](), Class.getField[s](), Class.getConstructor[s],
+ * Class.getDeclaredMethod[s](), Class.getDeclaredField[s](), and
+ * Class.getDeclaredConstructor[s](). The default implementation allows
+ * PUBLIC access, and access to classes defined by the same classloader as
+ * the code performing the reflection. Otherwise, it checks
+ * <code>RuntimePermission("accessDeclaredMembers")</code>. If you override
+ * this, do not call <code>super.checkMemberAccess</code>, as this would
+ * mess up the stack depth check that determines the ClassLoader requesting
+ * the access.
+ *
+ * @param c the Class to check
+ * @param memberType either DECLARED or PUBLIC
+ * @throws SecurityException if permission is denied, including when
+ * memberType is not DECLARED or PUBLIC
+ * @throws NullPointerException if c is null
+ * @see Class
+ * @see Member#DECLARED
+ * @see Member#PUBLIC
+ * @since 1.1
+ */
+ public void checkMemberAccess(Class c, int memberType)
+ {
+ if (c == null)
+ throw new NullPointerException();
+ if (memberType == Member.PUBLIC)
+ return;
+ // XXX Allow access to classes created by same classloader before next
+ // check.
+ checkPermission(new RuntimePermission("accessDeclaredMembers"));
+ }
+
+ /**
+ * Test whether a particular security action may be taken. The default
+ * implementation checks <code>SecurityPermission(action)</code>. If you
+ * override this, call <code>super.checkSecurityAccess</code> rather than
+ * throwing an exception.
+ *
+ * @param action the desired action to take
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if action is null
+ * @throws IllegalArgumentException if action is ""
+ * @since 1.1
+ */
+ public void checkSecurityAccess(String action)
+ {
+ checkPermission(new SecurityPermission(action));
+ }
+
+ /**
+ * Get the ThreadGroup that a new Thread should belong to by default. Called
+ * by Thread.Thread(). The default implementation returns the current
+ * ThreadGroup of the current Thread. <STRONG>Spec Note:</STRONG> it is not
+ * clear whether the new Thread is guaranteed to pass the
+ * checkAccessThreadGroup() test when using this ThreadGroup, but I presume
+ * so.
+ *
+ * @return the ThreadGroup to put the new Thread into
+ * @since 1.1
+ */
+ public ThreadGroup getThreadGroup()
+ {
+ return Thread.currentThread().getThreadGroup();
+ }
+
+ /**
+ * Helper that checks a comma-separated list of restricted packages, from
+ * <code>Security.getProperty("package.definition")</code>, for the given
+ * package access permission. If packageName starts with or equals any
+ * restricted package, it checks
+ * <code>RuntimePermission(permission + packageName)</code>.
+ *
+ * @param packageName the package name to check access to
+ * @param restriction "package.access" or "package.definition"
+ * @param permission the base permission, including the '.'
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if packageName is null
+ * @see #checkPackageAccess(String)
+ * @see #checkPackageDefinition(String)
+ */
+ void checkPackageList(String packageName, final String restriction,
+ String permission)
+ {
+ if (packageName == null)
+ throw new NullPointerException();
+
+ String list = (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return Security.getProperty(restriction);
+ }
+ });
+
+ if (list == null || list.equals(""))
+ return;
+
+ String packageNamePlusDot = packageName + ".";
+
+ StringTokenizer st = new StringTokenizer(list, ",");
+ while (st.hasMoreTokens())
+ {
+ if (packageNamePlusDot.startsWith(st.nextToken()))
+ {
+ Permission p = new RuntimePermission(permission + packageName);
+ checkPermission(p);
+ return;
+ }
+ }
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/String.java b/gcc-4.2.1/libjava/java/lang/String.java
new file mode 100644
index 000000000..bd75797a2
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/String.java
@@ -0,0 +1,1397 @@
+/* String.java -- immutable character sequences; the object of string literals
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.lang.Comparable;
+import java.util.Comparator;
+import java.util.Locale;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Strings represent an immutable set of characters. All String literals
+ * are instances of this class, and two string literals with the same contents
+ * refer to the same String object.
+ *
+ * <p>This class also includes a number of methods for manipulating the
+ * contents of strings (of course, creating a new object if there are any
+ * changes, as String is immutable). Case mapping relies on Unicode 3.0.0
+ * standards, where some character sequences have a different number of
+ * characters in the uppercase version than the lower case.
+ *
+ * <p>Strings are special, in that they are the only object with an overloaded
+ * operator. When you use '+' with at least one String argument, both
+ * arguments have String conversion performed on them, and another String (not
+ * guaranteed to be unique) results.
+ *
+ * <p>String is special-cased when doing data serialization - rather than
+ * listing the fields of this class, a String object is converted to a string
+ * literal in the object stream.
+ *
+ * @author Paul N. Fisher
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Per Bothner (bothner@cygnus.com)
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class String implements Serializable, Comparable, CharSequence
+{
+ // WARNING: String is a CORE class in the bootstrap cycle. See the comments
+ // in vm/reference/java/lang/Runtime for implications of this fact.
+
+ /**
+ * This is probably not necessary because this class is special cased already
+ * but it will avoid showing up as a discrepancy when comparing SUIDs.
+ */
+ private static final long serialVersionUID = -6849794470754667710L;
+
+ /**
+ * This is the object that holds the characters that make up the
+ * String. It might be a char[], or it could be String. It could
+ * even be `this'. The actual characters can't be located using
+ * pure Java code.
+ * @see #boffset
+ */
+ private Object data;
+
+ /**
+ * This is a <emph>byte</emph> offset of the actual characters from
+ * the start of the character-holding object. Don't use this field
+ * in Java code.
+ */
+ private int boffset;
+
+ /**
+ * Holds the number of characters in value. Package visible for use
+ * by trusted code.
+ */
+ int count;
+
+ /**
+ * Caches the result of hashCode(). If this value is zero, the hashcode
+ * is considered uncached (even if 0 is the correct hash value).
+ */
+ private int cachedHashCode;
+
+ /**
+ * An implementation for {@link CASE_INSENSITIVE_ORDER}.
+ * This must be {@link Serializable}. The class name is dictated by
+ * compatibility with Sun's JDK.
+ */
+ private static final class CaseInsensitiveComparator
+ implements Comparator, Serializable
+ {
+ /**
+ * Compatible with JDK 1.2.
+ */
+ private static final long serialVersionUID = 8575799808933029326L;
+
+ /**
+ * The default private constructor generates unnecessary overhead.
+ */
+ CaseInsensitiveComparator() {}
+
+ /**
+ * Compares to Strings, using
+ * <code>String.compareToIgnoreCase(String)</code>.
+ *
+ * @param o1 the first string
+ * @param o2 the second string
+ * @return &lt; 0, 0, or &gt; 0 depending on the case-insensitive
+ * comparison of the two strings.
+ * @throws NullPointerException if either argument is null
+ * @throws ClassCastException if either argument is not a String
+ * @see #compareToIgnoreCase(String)
+ */
+ public int compare(Object o1, Object o2)
+ {
+ return ((String) o1).compareToIgnoreCase((String) o2);
+ }
+ } // class CaseInsensitiveComparator
+
+ /**
+ * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>.
+ * This comparator is {@link Serializable}. Note that it ignores Locale,
+ * for that, you want a Collator.
+ *
+ * @see Collator#compare(String, String)
+ * @since 1.2
+ */
+ public static final Comparator CASE_INSENSITIVE_ORDER
+ = new CaseInsensitiveComparator();
+
+ /**
+ * Creates an empty String (length 0). Unless you really need a new object,
+ * consider using <code>""</code> instead.
+ */
+ public String()
+ {
+ data = "".data;
+ boffset = 0;
+ count = 0;
+ }
+
+ /**
+ * Copies the contents of a String to a new String. Since Strings are
+ * immutable, only a shallow copy is performed.
+ *
+ * @param str String to copy
+ * @throws NullPointerException if value is null
+ */
+ public String(String str)
+ {
+ data = str.data;
+ boffset = str.boffset;
+ count = str.count;
+ cachedHashCode = str.cachedHashCode;
+ }
+
+ /**
+ * Creates a new String using the character sequence of the char array.
+ * Subsequent changes to data do not affect the String.
+ *
+ * @param data char array to copy
+ * @throws NullPointerException if data is null
+ */
+ public String(char[] data)
+ {
+ init(data, 0, data.length, false);
+ }
+
+ /**
+ * Creates a new String using the character sequence of a subarray of
+ * characters. The string starts at offset, and copies count chars.
+ * Subsequent changes to data do not affect the String.
+ *
+ * @param data char array to copy
+ * @param offset position (base 0) to start copying out of data
+ * @param count the number of characters from data to copy
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &gt; data.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public String(char[] data, int offset, int count)
+ {
+ init(data, offset, count, false);
+ }
+
+ /**
+ * Creates a new String using an 8-bit array of integer values, starting at
+ * an offset, and copying up to the count. Each character c, using
+ * corresponding byte b, is created in the new String as if by performing:
+ *
+ * <pre>
+ * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
+ * </pre>
+ *
+ * @param ascii array of integer values
+ * @param hibyte top byte of each Unicode character
+ * @param offset position (base 0) to start copying out of ascii
+ * @param count the number of characters from ascii to copy
+ * @throws NullPointerException if ascii is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &gt; ascii.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #String(byte[])
+ * @see #String(byte[], String)
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], int, int, String)
+ * @deprecated use {@link #String(byte[], int, int, String)} to perform
+ * correct encoding
+ */
+ public String(byte[] ascii, int hibyte, int offset, int count)
+ {
+ init(ascii, hibyte, offset, count);
+ }
+
+ /**
+ * Creates a new String using an 8-bit array of integer values. Each
+ * character c, using corresponding byte b, is created in the new String
+ * as if by performing:
+ *
+ * <pre>
+ * c = (char) (((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
+ * </pre>
+ *
+ * @param ascii array of integer values
+ * @param hibyte top byte of each Unicode character
+ * @throws NullPointerException if ascii is null
+ * @see #String(byte[])
+ * @see #String(byte[], String)
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], int, int, String)
+ * @see #String(byte[], int, int, int)
+ * @deprecated use {@link #String(byte[], String)} to perform
+ * correct encoding
+ */
+ public String(byte[] ascii, int hibyte)
+ {
+ init(ascii, hibyte, 0, ascii.length);
+ }
+
+ /**
+ * Creates a new String using the portion of the byte array starting at the
+ * offset and ending at offset + count. Uses the specified encoding type
+ * to decode the byte array, so the resulting string may be longer or
+ * shorter than the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
+ * see {@link java.nio.charset.Charset}. The behavior is not specified if
+ * the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @param offset the offset to start at
+ * @param count the number of characters in the array to use
+ * @param encoding the name of the encoding to use
+ * @throws NullPointerException if data or encoding is null
+ * @throws IndexOutOfBoundsException if offset or count is incorrect
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @throws UnsupportedEncodingException if encoding is not found
+ * @throws Error if the decoding fails
+ * @since 1.1
+ */
+ public String(byte[] data, int offset, int count, String encoding)
+ throws UnsupportedEncodingException
+ {
+ init (data, offset, count, encoding);
+ }
+
+ /**
+ * Creates a new String using the byte array. Uses the specified encoding
+ * type to decode the byte array, so the resulting string may be longer or
+ * shorter than the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}, and for valid character sets,
+ * see {@link java.nio.charset.Charset}. The behavior is not specified if
+ * the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @param encoding the name of the encoding to use
+ * @throws NullPointerException if data or encoding is null
+ * @throws UnsupportedEncodingException if encoding is not found
+ * @throws Error if the decoding fails
+ * @see #String(byte[], int, int, String)
+ * @since 1.1
+ */
+ public String(byte[] data, String encoding)
+ throws UnsupportedEncodingException
+ {
+ this(data, 0, data.length, encoding);
+ }
+
+ /**
+ * Creates a new String using the portion of the byte array starting at the
+ * offset and ending at offset + count. Uses the encoding of the platform's
+ * default charset, so the resulting string may be longer or shorter than
+ * the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
+ * if the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @param offset the offset to start at
+ * @param count the number of characters in the array to use
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if offset or count is incorrect
+ * @throws Error if the decoding fails
+ * @see #String(byte[], int, int, String)
+ * @since 1.1
+ */
+ public String(byte[] data, int offset, int count)
+ {
+ try
+ {
+ init (data, offset, count,
+ System.getProperty("file.encoding", "8859_1"));
+ }
+ catch (UnsupportedEncodingException x1)
+ {
+ // Maybe the default encoding is bad.
+ try
+ {
+ init (data, offset, count, "8859_1");
+ }
+ catch (UnsupportedEncodingException x2)
+ {
+ // We know this can't happen.
+ }
+ }
+ }
+
+ /**
+ * Creates a new String using the byte array. Uses the encoding of the
+ * platform's default charset, so the resulting string may be longer or
+ * shorter than the byte array. For more decoding control, use
+ * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified
+ * if the decoder encounters invalid characters; this implementation throws
+ * an Error.
+ *
+ * @param data byte array to copy
+ * @throws NullPointerException if data is null
+ * @throws Error if the decoding fails
+ * @see #String(byte[], int, int)
+ * @see #String(byte[], int, int, String)
+ * @since 1.1
+ */
+ public String(byte[] data)
+ {
+ this(data, 0, data.length);
+ }
+
+ /**
+ * Creates a new String using the character sequence represented by
+ * the StringBuffer. Subsequent changes to buf do not affect the String.
+ *
+ * @param buffer StringBuffer to copy
+ * @throws NullPointerException if buffer is null
+ */
+ public String(StringBuffer buffer)
+ {
+ synchronized (buffer)
+ {
+ // Share unless buffer is 3/4 empty.
+ boolean should_copy = ((buffer.count << 2) < buffer.value.length);
+ if (! should_copy)
+ buffer.shared = true;
+ init (buffer.value, 0, buffer.count, ! should_copy);
+ }
+ }
+
+ /**
+ * Creates a new String using the character sequence represented by
+ * the StringBuilder. Subsequent changes to buf do not affect the String.
+ *
+ * @param buffer StringBuilder to copy
+ * @throws NullPointerException if buffer is null
+ */
+ public String(StringBuilder buffer)
+ {
+ this(buffer.value, 0, buffer.count);
+ }
+
+ /**
+ * Special constructor which can share an array when safe to do so.
+ *
+ * @param data the characters to copy
+ * @param offset the location to start from
+ * @param count the number of characters to use
+ * @param dont_copy true if the array is trusted, and need not be copied
+ * @throws NullPointerException if chars is null
+ * @throws StringIndexOutOfBoundsException if bounds check fails
+ */
+ String(char[] data, int offset, int count, boolean dont_copy)
+ {
+ init(data, offset, count, dont_copy);
+ }
+
+ // This is used by gnu.gcj.runtime.StringBuffer, so it must have
+ // package-private protection. It is accessed via CNI and so avoids
+ // ordinary protection mechanisms.
+ String(gnu.gcj.runtime.StringBuffer buffer)
+ {
+ // No need to synchronize or mark the buffer, since we know it is
+ // only used once.
+ init (buffer);
+ }
+
+ /**
+ * Returns the number of characters contained in this String.
+ *
+ * @return the length of this String
+ */
+ public int length()
+ {
+ return count;
+ }
+
+ /**
+ * Returns the character located at the specified index within this String.
+ *
+ * @param index position of character to return (base 0)
+ * @return character located at position index
+ * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public native char charAt(int index);
+
+ /**
+ * Get the code point at the specified index. This is like #charAt(int),
+ * but if the character is the start of a surrogate pair, and the
+ * following character completes the pair, then the corresponding
+ * supplementary code point is returned.
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public synchronized int codePointAt(int index)
+ {
+ // Use the CharSequence overload as we get better range checking
+ // this way.
+ return Character.codePointAt(this, index);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(int), but checks the characters at <code>index-1</code> and
+ * <code>index-2</code> to see if they form a supplementary code point.
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @since 1.5
+ */
+ public synchronized int codePointBefore(int index)
+ {
+ // Use the CharSequence overload as we get better range checking
+ // this way.
+ return Character.codePointBefore(this, index);
+ }
+
+ /**
+ * Copies characters from this String starting at a specified start index,
+ * ending at a specified stop index, to a character array starting at
+ * a specified destination begin index.
+ *
+ * @param srcBegin index to begin copying characters from this String
+ * @param srcEnd index after the last character to be copied from this String
+ * @param dst character array which this String is copied into
+ * @param dstBegin index to start writing characters into dst
+ * @throws NullPointerException if dst is null
+ * @throws IndexOutOfBoundsException if any indices are out of bounds
+ * (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dst problems cause an
+ * ArrayIndexOutOfBoundsException)
+ */
+ public native void getChars(int srcBegin, int srcEnd,
+ char[] dst, int dstBegin);
+
+ /**
+ * Copies the low byte of each character from this String starting at a
+ * specified start index, ending at a specified stop index, to a byte array
+ * starting at a specified destination begin index.
+ *
+ * @param srcBegin index to being copying characters from this String
+ * @param srcEnd index after the last character to be copied from this String
+ * @param dst byte array which each low byte of this String is copied into
+ * @param dstBegin index to start writing characters into dst
+ * @throws NullPointerException if dst is null and copy length is non-zero
+ * @throws IndexOutOfBoundsException if any indices are out of bounds
+ * (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dst problems cause an
+ * ArrayIndexOutOfBoundsException)
+ * @see #getBytes()
+ * @see #getBytes(String)
+ * @deprecated use {@link #getBytes()}, which uses a char to byte encoder
+ */
+ public native void getBytes(int srcBegin, int srcEnd,
+ byte[] dst, int dstBegin);
+
+ /**
+ * Converts the Unicode characters in this String to a byte array. Uses the
+ * specified encoding method, so the result may be longer or shorter than
+ * the String. For more encoding control, use
+ * {@link java.nio.charset.CharsetEncoder}, and for valid character sets,
+ * see {@link java.nio.charset.Charset}. The behavior is not specified if
+ * the encoder encounters a problem; this implementation returns null.
+ *
+ * @param enc encoding name
+ * @return the resulting byte array, or null on a problem
+ * @throws NullPointerException if enc is null
+ * @throws UnsupportedEncodingException if encoding is not supported
+ * @since 1.1
+ */
+ public native byte[] getBytes(String enc)
+ throws UnsupportedEncodingException;
+
+ /**
+ * Converts the Unicode characters in this String to a byte array. Uses the
+ * encoding of the platform's default charset, so the result may be longer
+ * or shorter than the String. For more encoding control, use
+ * {@link java.nio.charset.CharsetEncoder}. The behavior is not specified if
+ * the encoder encounters a problem; this implementation returns null.
+ *
+ * @return the resulting byte array, or null on a problem
+ * @since 1.1
+ */
+ public byte[] getBytes()
+ {
+ try
+ {
+ return getBytes (System.getProperty("file.encoding", "8859_1"));
+ }
+ catch (UnsupportedEncodingException x)
+ {
+ // This probably shouldn't happen, but could if file.encoding
+ // is somehow changed to a value we don't understand.
+ try
+ {
+ return getBytes ("8859_1");
+ }
+ catch (UnsupportedEncodingException x2)
+ {
+ // This really shouldn't happen, because the 8859_1
+ // encoding should always be available.
+ throw new InternalError ("couldn't find 8859_1 encoder");
+ }
+ }
+ }
+
+ /**
+ * Predicate which compares anObject to this. This is true only for Strings
+ * with the same character sequence.
+ *
+ * @param anObject the object to compare
+ * @return true if anObject is semantically equal to this
+ * @see #compareTo(String)
+ * @see #equalsIgnoreCase(String)
+ */
+ public native boolean equals(Object anObject);
+
+ /**
+ * Compares the given StringBuffer to this String. This is true if the
+ * StringBuffer has the same content as this String at this moment.
+ *
+ * @param buffer the StringBuffer to compare to
+ * @return true if StringBuffer has the same character sequence
+ * @throws NullPointerException if the given StringBuffer is null
+ * @since 1.4
+ */
+ public native boolean contentEquals(StringBuffer buffer);
+
+ /**
+ * Compares the given CharSequence to this String. This is true if
+ * the CharSequence has the same content as this String at this
+ * moment.
+ *
+ * @param seq the CharSequence to compare to
+ * @return true if CharSequence has the same character sequence
+ * @throws NullPointerException if the given CharSequence is null
+ * @since 1.5
+ */
+ public native boolean contentEquals(CharSequence seq);
+
+ /**
+ * Compares a String to this String, ignoring case. This does not handle
+ * multi-character capitalization exceptions; instead the comparison is
+ * made on a character-by-character basis, and is true if:<br><ul>
+ * <li><code>c1 == c2</code></li>
+ * <li><code>Character.toUpperCase(c1)
+ * == Character.toUpperCase(c2)</code></li>
+ * <li><code>Character.toLowerCase(c1)
+ * == Character.toLowerCase(c2)</code></li>
+ * </ul>
+ *
+ * @param anotherString String to compare to this String
+ * @return true if anotherString is equal, ignoring case
+ * @see #equals(Object)
+ * @see Character#toUpperCase(char)
+ * @see Character#toLowerCase(char)
+ */
+ public native boolean equalsIgnoreCase(String anotherString);
+
+ /**
+ * Compares this String and another String (case sensitive,
+ * lexicographically). The result is less than 0 if this string sorts
+ * before the other, 0 if they are equal, and greater than 0 otherwise.
+ * After any common starting sequence is skipped, the result is
+ * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings
+ * have characters remaining, or
+ * <code>this.length() - anotherString.length()</code> if one string is
+ * a subsequence of the other.
+ *
+ * @param anotherString the String to compare against
+ * @return the comparison
+ * @throws NullPointerException if anotherString is null
+ */
+ public native int compareTo(String anotherString);
+
+ /**
+ * Behaves like <code>compareTo(java.lang.String)</code> unless the Object
+ * is not a <code>String</code>. Then it throws a
+ * <code>ClassCastException</code>.
+ *
+ * @param o the object to compare against
+ * @return the comparison
+ * @throws NullPointerException if o is null
+ * @throws ClassCastException if o is not a <code>String</code>
+ * @since 1.2
+ */
+ public int compareTo(Object o)
+ {
+ return compareTo((String) o);
+ }
+
+ /**
+ * Compares this String and another String (case insensitive). This
+ * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores
+ * locale and multi-characater capitalization, and compares characters
+ * after performing
+ * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each
+ * character of the string. This is unsatisfactory for locale-based
+ * comparison, in which case you should use {@link java.text.Collator}.
+ *
+ * @param str the string to compare against
+ * @return the comparison
+ * @see Collator#compare(String, String)
+ * @since 1.2
+ */
+ public int compareToIgnoreCase(String str)
+ {
+ return this.toUpperCase().toLowerCase().compareTo(
+ str.toUpperCase().toLowerCase());
+ }
+
+ /**
+ * Predicate which determines if this String matches another String
+ * starting at a specified offset for each String and continuing
+ * for a specified length. Indices out of bounds are harmless, and give
+ * a false result.
+ *
+ * @param toffset index to start comparison at for this String
+ * @param other String to compare region to this String
+ * @param ooffset index to start comparison at for other
+ * @param len number of characters to compare
+ * @return true if regions match (case sensitive)
+ * @throws NullPointerException if other is null
+ */
+ public native boolean regionMatches(int toffset,
+ String other, int ooffset, int len);
+
+ /**
+ * Predicate which determines if this String matches another String
+ * starting at a specified offset for each String and continuing
+ * for a specified length, optionally ignoring case. Indices out of bounds
+ * are harmless, and give a false result. Case comparisons are based on
+ * <code>Character.toLowerCase()</code> and
+ * <code>Character.toUpperCase()</code>, not on multi-character
+ * capitalization expansions.
+ *
+ * @param ignoreCase true if case should be ignored in comparision
+ * @param toffset index to start comparison at for this String
+ * @param other String to compare region to this String
+ * @param oofset index to start comparison at for other
+ * @param len number of characters to compare
+ * @return true if regions match, false otherwise
+ * @throws NullPointerException if other is null
+ */
+ public native boolean regionMatches(boolean ignoreCase, int toffset,
+ String other, int ooffset, int len);
+
+ /**
+ * Predicate which determines if this String contains the given prefix,
+ * beginning comparison at toffset. The result is false if toffset is
+ * negative or greater than this.length(), otherwise it is the same as
+ * <code>this.substring(toffset).startsWith(prefix)</code>.
+ *
+ * @param prefix String to compare
+ * @param toffset offset for this String where comparison starts
+ * @return true if this String starts with prefix
+ * @throws NullPointerException if prefix is null
+ * @see #regionMatches(boolean, int, String, int, int)
+ */
+ public native boolean startsWith(String prefix, int toffset);
+
+ /**
+ * Predicate which determines if this String starts with a given prefix.
+ * If the prefix is an empty String, true is returned.
+ *
+ * @param prefix String to compare
+ * @return true if this String starts with the prefix
+ * @throws NullPointerException if prefix is null
+ * @see #startsWith(String, int)
+ */
+ public boolean startsWith(String prefix)
+ {
+ return startsWith (prefix, 0);
+ }
+
+ /**
+ * Predicate which determines if this String ends with a given suffix.
+ * If the suffix is an empty String, true is returned.
+ *
+ * @param suffix String to compare
+ * @return true if this String ends with the suffix
+ * @throws NullPointerException if suffix is null
+ * @see #regionMatches(boolean, int, String, int, int)
+ */
+ public boolean endsWith(String suffix)
+ {
+ return regionMatches (this.count - suffix.count, suffix, 0, suffix.count);
+ }
+
+ /**
+ * Computes the hashcode for this String. This is done with int arithmetic,
+ * where ** represents exponentiation, by this formula:<br>
+ * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>.
+ *
+ * @return hashcode value of this String
+ */
+ public native int hashCode();
+
+ /**
+ * Finds the first instance of a character in this String.
+ *
+ * @param ch character to find
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public int indexOf(int ch)
+ {
+ return indexOf(ch, 0);
+ }
+
+ /**
+ * Finds the first instance of a character in this String, starting at
+ * a given index. If starting index is less than 0, the search
+ * starts at the beginning of this String. If the starting index
+ * is greater than the length of this String, -1 is returned.
+ *
+ * @param ch character to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public native int indexOf(int ch, int fromIndex);
+
+ /**
+ * Finds the last instance of a character in this String.
+ *
+ * @param ch character to find
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public int lastIndexOf(int ch)
+ {
+ return lastIndexOf(ch, count - 1);
+ }
+
+ /**
+ * Finds the last instance of a character in this String, starting at
+ * a given index. If starting index is greater than the maximum valid
+ * index, then the search begins at the end of this String. If the
+ * starting index is less than zero, -1 is returned.
+ *
+ * @param ch character to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the character, or -1 if not found
+ */
+ public native int lastIndexOf(int ch, int fromIndex);
+
+ /**
+ * Finds the first instance of a String in this String.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int indexOf(String str)
+ {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Finds the first instance of a String in this String, starting at
+ * a given index. If starting index is less than 0, the search
+ * starts at the beginning of this String. If the starting index
+ * is greater than the length of this String, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public native int indexOf(String str, int fromIndex);
+
+ /**
+ * Finds the last instance of a String in this String.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int lastIndexOf(String str)
+ {
+ return lastIndexOf(str, count - str.count);
+ }
+
+ /**
+ * Finds the last instance of a String in this String, starting at
+ * a given index. If starting index is greater than the maximum valid
+ * index, then the search begins at the end of this String. If the
+ * starting index is less than zero, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int lastIndexOf(String str, int fromIndex)
+ {
+ if (fromIndex >= count)
+ fromIndex = count - str.count;
+ for (;; --fromIndex)
+ {
+ if (fromIndex < 0)
+ return -1;
+ if (startsWith(str, fromIndex))
+ return fromIndex;
+ }
+ }
+
+ /**
+ * Creates a substring of this String, starting at a specified index
+ * and ending at the end of this String.
+ *
+ * @param begin index to start substring (base 0)
+ * @return new String which is a substring of this String
+ * @throws IndexOutOfBoundsException if begin &lt; 0 || begin &gt; length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public String substring(int begin)
+ {
+ return substring(begin, count);
+ }
+
+ /**
+ * Creates a substring of this String, starting at a specified index
+ * and ending at one character before a specified index.
+ *
+ * @param begin index to start substring (inclusive, base 0)
+ * @param end index to end at (exclusive)
+ * @return new String which is a substring of this String
+ * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
+ * || begin &gt; end (while unspecified, this is a
+ * StringIndexOutOfBoundsException)
+ */
+ public native String substring(int begin, int end);
+
+ /**
+ * Creates a substring of this String, starting at a specified index
+ * and ending at one character before a specified index. This behaves like
+ * <code>substring(begin, end)</code>.
+ *
+ * @param begin index to start substring (inclusive, base 0)
+ * @param end index to end at (exclusive)
+ * @return new String which is a substring of this String
+ * @throws IndexOutOfBoundsException if begin &lt; 0 || end &gt; length()
+ * || begin &gt; end
+ * @since 1.4
+ */
+ public CharSequence subSequence(int begin, int end)
+ {
+ return substring(begin, end);
+ }
+
+ /**
+ * Concatenates a String to this String. This results in a new string unless
+ * one of the two originals is "".
+ *
+ * @param str String to append to this String
+ * @return newly concatenated String
+ * @throws NullPointerException if str is null
+ */
+ public native String concat(String str);
+
+ /**
+ * Replaces every instance of a character in this String with a new
+ * character. If no replacements occur, this is returned.
+ *
+ * @param oldChar the old character to replace
+ * @param newChar the new character
+ * @return new String with all instances of oldChar replaced with newChar
+ */
+ public native String replace(char oldChar, char newChar);
+
+ /**
+ * Test if this String matches a regular expression. This is shorthand for
+ * <code>{@link Pattern}.matches(regex, this)</code>.
+ *
+ * @param regex the pattern to match
+ * @return true if the pattern matches
+ * @throws NullPointerException if regex is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see Pattern#matches(String, CharSequence)
+ * @since 1.4
+ */
+ public boolean matches(String regex)
+ {
+ return Pattern.matches(regex, this);
+ }
+
+ /**
+ * Replaces the first substring match of the regular expression with a
+ * given replacement. This is shorthand for <code>{@link Pattern}
+ * .compile(regex).matcher(this).replaceFirst(replacement)</code>.
+ *
+ * @param regex the pattern to match
+ * @param replacement the replacement string
+ * @return the modified string
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see #replaceAll(String, String)
+ * @see Pattern#compile(String)
+ * @see Pattern#matcher(CharSequence)
+ * @see Matcher#replaceFirst(String)
+ * @since 1.4
+ */
+ public String replaceFirst(String regex, String replacement)
+ {
+ return Pattern.compile(regex).matcher(this).replaceFirst(replacement);
+ }
+
+ /**
+ * Replaces all matching substrings of the regular expression with a
+ * given replacement. This is shorthand for <code>{@link Pattern}
+ * .compile(regex).matcher(this).replaceAll(replacement)</code>.
+ *
+ * @param regex the pattern to match
+ * @param replacement the replacement string
+ * @return the modified string
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see #replaceFirst(String, String)
+ * @see Pattern#compile(String)
+ * @see Pattern#matcher(CharSequence)
+ * @see Matcher#replaceAll(String)
+ * @since 1.4
+ */
+ public String replaceAll(String regex, String replacement)
+ {
+ return Pattern.compile(regex).matcher(this).replaceAll(replacement);
+ }
+
+ /**
+ * Split this string around the matches of a regular expression. Each
+ * element of the returned array is the largest block of characters not
+ * terminated by the regular expression, in the order the matches are found.
+ *
+ * <p>The limit affects the length of the array. If it is positive, the
+ * array will contain at most n elements (n - 1 pattern matches). If
+ * negative, the array length is unlimited, but there can be trailing empty
+ * entries. if 0, the array length is unlimited, and trailing empty entries
+ * are discarded.
+ *
+ * <p>For example, splitting "boo:and:foo" yields:<br>
+ * <table border=0>
+ * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th>
+ * <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr>
+ * <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr>
+ * <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr>
+ * <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
+ * <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr>
+ * <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr>
+ * </table>
+ *
+ * <p>This is shorthand for
+ * <code>{@link Pattern}.compile(regex).split(this, limit)</code>.
+ *
+ * @param regex the pattern to match
+ * @param limit the limit threshold
+ * @return the array of split strings
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see Pattern#compile(String)
+ * @see Pattern#split(CharSequence, int)
+ * @since 1.4
+ */
+ public String[] split(String regex, int limit)
+ {
+ return Pattern.compile(regex).split(this, limit);
+ }
+
+ /**
+ * Split this string around the matches of a regular expression. Each
+ * element of the returned array is the largest block of characters not
+ * terminated by the regular expression, in the order the matches are found.
+ * The array length is unlimited, and trailing empty entries are discarded,
+ * as though calling <code>split(regex, 0)</code>.
+ *
+ * @param regex the pattern to match
+ * @return the array of split strings
+ * @throws NullPointerException if regex or replacement is null
+ * @throws PatternSyntaxException if regex is invalid
+ * @see #split(String, int)
+ * @see Pattern#compile(String)
+ * @see Pattern#split(CharSequence, int)
+ * @since 1.4
+ */
+ public String[] split(String regex)
+ {
+ return Pattern.compile(regex).split(this, 0);
+ }
+
+ /**
+ * Lowercases this String according to a particular locale. This uses
+ * Unicode's special case mappings, as applied to the given Locale, so the
+ * resulting string may be a different length.
+ *
+ * @param loc locale to use
+ * @return new lowercased String, or this if no characters were lowercased
+ * @throws NullPointerException if loc is null
+ * @see #toUpperCase(Locale)
+ * @since 1.1
+ */
+ public native String toLowerCase(Locale locale);
+
+ /**
+ * Lowercases this String. This uses Unicode's special case mappings, as
+ * applied to the platform's default Locale, so the resulting string may
+ * be a different length.
+ *
+ * @return new lowercased String, or this if no characters were lowercased
+ * @see #toLowerCase(Locale)
+ * @see #toUpperCase()
+ */
+ public String toLowerCase()
+ {
+ // The JDK is a bit confused about what to do here. If we pass in
+ // the default Locale then special Locale handling might be
+ // invoked. However, the docs also say that Character.toLowerCase
+ // rules here. We go with the latter.
+ return toLowerCase (null);
+ }
+
+ /**
+ * Uppercases this String according to a particular locale. This uses
+ * Unicode's special case mappings, as applied to the given Locale, so the
+ * resulting string may be a different length.
+ *
+ * @param loc locale to use
+ * @return new uppercased String, or this if no characters were uppercased
+ * @throws NullPointerException if loc is null
+ * @see #toLowerCase(Locale)
+ * @since 1.1
+ */
+ public native String toUpperCase(Locale locale);
+
+ /**
+ * Uppercases this String. This uses Unicode's special case mappings, as
+ * applied to the platform's default Locale, so the resulting string may
+ * be a different length.
+ *
+ * @return new uppercased String, or this if no characters were uppercased
+ * @see #toUpperCase(Locale)
+ * @see #toLowerCase()
+ */
+ public String toUpperCase()
+ {
+ // The JDK is a bit confused about what to do here. If we pass in
+ // the default Locale then special Locale handling might be
+ // invoked. However, the docs also say that Character.toLowerCase
+ // rules here. We go with the latter.
+ return toUpperCase (null);
+ }
+
+ /**
+ * Trims all characters less than or equal to <code>'\u0020'</code>
+ * (<code>' '</code>) from the beginning and end of this String. This
+ * includes many, but not all, ASCII control characters, and all
+ * {@link Character#whitespace(char)}.
+ *
+ * @return new trimmed String, or this if nothing trimmed
+ */
+ public native String trim();
+
+ /**
+ * Returns this, as it is already a String!
+ *
+ * @return this
+ */
+ public String toString()
+ {
+ return this;
+ }
+
+ /**
+ * Copies the contents of this String into a character array. Subsequent
+ * changes to the array do not affect the String.
+ *
+ * @return character array copying the String
+ */
+ public native char[] toCharArray();
+
+ /**
+ * Returns a String representation of an Object. This is "null" if the
+ * object is null, otherwise it is <code>obj.toString()</code> (which
+ * can be null).
+ *
+ * @param obj the Object
+ * @return the string conversion of obj
+ */
+ public static String valueOf(Object obj)
+ {
+ return obj == null ? "null" : obj.toString();
+ }
+
+ /**
+ * Returns a String representation of a character array. Subsequent
+ * changes to the array do not affect the String.
+ *
+ * @param data the character array
+ * @return a String containing the same character sequence as data
+ * @throws NullPointerException if data is null
+ * @see #valueOf(char[], int, int)
+ * @see #String(char[])
+ */
+ public static String valueOf(char[] data)
+ {
+ return valueOf (data, 0, data.length);
+ }
+
+ /**
+ * Returns a String representing the character sequence of the char array,
+ * starting at the specified offset, and copying chars up to the specified
+ * count. Subsequent changes to the array do not affect the String.
+ *
+ * @param data character array
+ * @param offset position (base 0) to start copying out of data
+ * @param count the number of characters from data to copy
+ * @return String containing the chars from data[offset..offset+count]
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &gt; data.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #String(char[], int, int)
+ */
+ public static native String valueOf(char[] data, int offset, int count);
+
+ /**
+ * Returns a String representing the character sequence of the char array,
+ * starting at the specified offset, and copying chars up to the specified
+ * count. Subsequent changes to the array do not affect the String.
+ *
+ * @param data character array
+ * @param offset position (base 0) to start copying out of data
+ * @param count the number of characters from data to copy
+ * @return String containing the chars from data[offset..offset+count]
+ * @throws NullPointerException if data is null
+ * @throws IndexOutOfBoundsException if (offset &lt; 0 || count &lt; 0
+ * || offset + count &gt; data.length)
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #String(char[], int, int)
+ */
+ public static String copyValueOf(char[] data, int offset, int count)
+ {
+ String r = new String ();
+ r.init(data, offset, count, false);
+ return r;
+ }
+
+ /**
+ * Returns a String representation of a character array. Subsequent
+ * changes to the array do not affect the String.
+ *
+ * @param data the character array
+ * @return a String containing the same character sequence as data
+ * @throws NullPointerException if data is null
+ * @see #copyValueOf(char[], int, int)
+ * @see #String(char[])
+ */
+ public static String copyValueOf(char[] data)
+ {
+ return copyValueOf (data, 0, data.length);
+ }
+
+ /**
+ * Returns a String representing a boolean.
+ *
+ * @param b the boolean
+ * @return "true" if b is true, else "false"
+ */
+ public static String valueOf(boolean b)
+ {
+ return b ? "true" : "false";
+ }
+
+ /**
+ * Returns a String representing a character.
+ *
+ * @param c the character
+ * @return String containing the single character c
+ */
+ public static native String valueOf(char c);
+
+ /**
+ * Returns a String representing an integer.
+ *
+ * @param i the integer
+ * @return String containing the integer in base 10
+ * @see Integer#toString(int)
+ */
+ public static native String valueOf(int i);
+
+ /**
+ * Returns a String representing a long.
+ *
+ * @param l the long
+ * @return String containing the long in base 10
+ * @see Long#toString(long)
+ */
+ public static String valueOf(long l)
+ {
+ return Long.toString(l);
+ }
+
+ /**
+ * Returns a String representing a float.
+ *
+ * @param f the float
+ * @return String containing the float
+ * @see Float#toString(float)
+ */
+ public static String valueOf(float f)
+ {
+ return Float.toString(f);
+ }
+
+ /**
+ * Returns a String representing a double.
+ *
+ * @param d the double
+ * @return String containing the double
+ * @see Double#toString(double)
+ */
+ public static String valueOf(double d)
+ {
+ return Double.toString(d);
+ }
+
+ /**
+ * 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.
+ *
+ * @return the interned String
+ */
+ public native String intern();
+
+ /**
+ * Return the number of code points between two indices in the
+ * <code>String</code>. An unpaired surrogate counts as a
+ * code point for this purpose. Characters outside the indicated
+ * range are not examined, even if the range ends in the middle of a
+ * surrogate pair.
+ *
+ * @param start the starting index
+ * @param end one past the ending index
+ * @return the number of code points
+ * @since 1.5
+ */
+ public synchronized int codePointCount(int start, int end)
+ {
+ if (start < 0 || end > count || start > end)
+ throw new StringIndexOutOfBoundsException();
+
+ int count = 0;
+ while (start < end)
+ {
+ char base = charAt(start);
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == end
+ || start == count
+ || charAt(start + 1) < Character.MIN_LOW_SURROGATE
+ || charAt(start + 1) > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ ++count;
+ }
+ return count;
+ }
+
+ /**
+ * Returns true iff this String contains the sequence of Characters
+ * described in s.
+ * @param s the CharSequence
+ * @return true iff this String contains s
+ *
+ * @since 1.5
+ */
+ public boolean contains (CharSequence s)
+ {
+ return this.indexOf(s.toString()) != -1;
+ }
+
+ /**
+ * Returns a string that is this string with all instances of the sequence
+ * represented by <code>target</code> replaced by the sequence in
+ * <code>replacement</code>.
+ * @param target the sequence to be replaced
+ * @param replacement the sequence used as the replacement
+ * @return the string constructed as above
+ */
+ public String replace (CharSequence target, CharSequence replacement)
+ {
+ String targetString = target.toString();
+ String replaceString = replacement.toString();
+ int targetLength = target.length();
+ int replaceLength = replacement.length();
+
+ int startPos = this.indexOf(targetString);
+ StringBuilder result = new StringBuilder(this);
+ while (startPos != -1)
+ {
+ // Replace the target with the replacement
+ result.replace(startPos, startPos + targetLength, replaceString);
+
+ // Search for a new occurrence of the target
+ startPos = result.indexOf(targetString, startPos + replaceLength);
+ }
+ return result.toString();
+ }
+
+
+ private native void init(char[] chars, int offset, int count,
+ boolean dont_copy);
+ private native void init(byte[] chars, int hibyte, int offset, int count);
+ private native void init(byte[] chars, int offset, int count, String enc)
+ throws UnsupportedEncodingException;
+ private native void init(gnu.gcj.runtime.StringBuffer buffer);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/StringBuffer.java b/gcc-4.2.1/libjava/java/lang/StringBuffer.java
new file mode 100644
index 000000000..c3f112967
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/StringBuffer.java
@@ -0,0 +1,1178 @@
+/* StringBuffer.java -- Growable strings
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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.Serializable;
+
+/**
+ * <code>StringBuffer</code> represents a changeable <code>String</code>.
+ * It provides the operations required to modify the
+ * <code>StringBuffer</code>, including insert, replace, delete, append,
+ * and reverse. It is thread-safe; meaning that all modifications to a buffer
+ * are in synchronized methods.
+ *
+ * <p><code>StringBuffer</code>s are variable-length in nature, so even if
+ * you initialize them to a certain size, they can still grow larger than
+ * that. <em>Capacity</em> indicates the number of characters the
+ * <code>StringBuffer</code> can have in it before it has to grow (growing
+ * the char array is an expensive operation involving <code>new</code>).
+ *
+ * <p>Incidentally, compilers often implement the String operator "+"
+ * by using a <code>StringBuffer</code> operation:<br>
+ * <code>a + b</code><br>
+ * is the same as<br>
+ * <code>new StringBuffer().append(a).append(b).toString()</code>.
+ *
+ * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
+ * efficiency. This will help when a StringBuffer is converted to a String
+ * and the StringBuffer is not changed after that (quite common when performing
+ * string concatenation).
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Tom Tromey
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see String
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public final class StringBuffer implements Serializable, CharSequence
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 3388685877147921107L;
+
+ /**
+ * Index of next available character (and thus the size of the current
+ * string contents). Note that this has permissions set this way so that
+ * String can get the value.
+ *
+ * @serial the number of characters in the buffer
+ */
+ int count;
+
+ /**
+ * The buffer. Note that this has permissions set this way so that String
+ * can get the value.
+ *
+ * @serial the buffer
+ */
+ char[] value;
+
+ /**
+ * True if the buffer is shared with another object (StringBuffer or
+ * String); this means the buffer must be copied before writing to it again.
+ * Note that this has permissions set this way so that String can get the
+ * value.
+ *
+ * @serial whether the buffer is shared
+ */
+ boolean shared;
+
+ /**
+ * The default capacity of a buffer.
+ */
+ private static final int DEFAULT_CAPACITY = 16;
+
+ /**
+ * Create a new StringBuffer with default capacity 16.
+ */
+ public StringBuffer()
+ {
+ this(DEFAULT_CAPACITY);
+ }
+
+ /**
+ * Create an empty <code>StringBuffer</code> with the specified initial
+ * capacity.
+ *
+ * @param capacity the initial capacity
+ * @throws NegativeArraySizeException if capacity is negative
+ */
+ public StringBuffer(int capacity)
+ {
+ value = new char[capacity];
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters in the
+ * specified <code>String</code>. Initial capacity will be the size of the
+ * String plus 16.
+ *
+ * @param str the <code>String</code> to convert
+ * @throws NullPointerException if str is null
+ */
+ public StringBuffer(String str)
+ {
+ // Unfortunately, because the size is 16 larger, we cannot share.
+ count = str.count;
+ value = new char[count + DEFAULT_CAPACITY];
+ str.getChars(0, count, value, 0);
+ }
+
+ /**
+ * Create a new <code>StringBuffer</code> with the characters from the
+ * specified <code>CharSequence</code>. Initial capacity will be the
+ * size of the CharSequence plus 16.
+ *
+ * @param sequence the <code>String</code> to convert
+ * @throws NullPointerException if str is null
+ *
+ * @since 1.5
+ */
+ public StringBuffer(CharSequence sequence)
+ {
+ count = Math.max(0, sequence.length());
+ value = new char[count + DEFAULT_CAPACITY];
+ for (int i = 0; i < count; ++i)
+ value[i] = sequence.charAt(i);
+ }
+
+ /**
+ * Get the length of the <code>String</code> this <code>StringBuffer</code>
+ * would create. Not to be confused with the <em>capacity</em> of the
+ * <code>StringBuffer</code>.
+ *
+ * @return the length of this <code>StringBuffer</code>
+ * @see #capacity()
+ * @see #setLength(int)
+ */
+ public synchronized int length()
+ {
+ return count;
+ }
+
+ /**
+ * Get the total number of characters this <code>StringBuffer</code> can
+ * support before it must be grown. Not to be confused with <em>length</em>.
+ *
+ * @return the capacity of this <code>StringBuffer</code>
+ * @see #length()
+ * @see #ensureCapacity(int)
+ */
+ public synchronized int capacity()
+ {
+ return value.length;
+ }
+
+ /**
+ * Increase the capacity of this <code>StringBuffer</code>. This will
+ * ensure that an expensive growing operation will not occur until
+ * <code>minimumCapacity</code> is reached. The buffer is grown to the
+ * larger of <code>minimumCapacity</code> and
+ * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+ *
+ * @param minimumCapacity the new capacity
+ * @see #capacity()
+ */
+ public synchronized void ensureCapacity(int minimumCapacity)
+ {
+ ensureCapacity_unsynchronized(minimumCapacity);
+ }
+
+ /**
+ * Set the length of this StringBuffer. If the new length is greater than
+ * the current length, all the new characters are set to '\0'. If the new
+ * length is less than the current length, the first <code>newLength</code>
+ * characters of the old array will be preserved, and the remaining
+ * characters are truncated.
+ *
+ * @param newLength the new length
+ * @throws IndexOutOfBoundsException if the new length is negative
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #length()
+ */
+ public synchronized void setLength(int newLength)
+ {
+ if (newLength < 0)
+ throw new StringIndexOutOfBoundsException(newLength);
+
+ int valueLength = value.length;
+
+ /* Always call ensureCapacity_unsynchronized in order to preserve
+ copy-on-write semantics. */
+ ensureCapacity_unsynchronized(newLength);
+
+ if (newLength < valueLength)
+ {
+ /* If the StringBuffer's value just grew, then we know that
+ value is newly allocated and the region between count and
+ newLength is filled with '\0'. */
+ count = newLength;
+ }
+ else
+ {
+ /* The StringBuffer's value doesn't need to grow. However,
+ we should clear out any cruft that may exist. */
+ while (count < newLength)
+ value[count++] = '\0';
+ }
+ }
+
+ /**
+ * Get the character at the specified index.
+ *
+ * @param index the index of the character to get, starting at 0
+ * @return the character at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ */
+ public synchronized char charAt(int index)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ return value[index];
+ }
+
+ /**
+ * Get the code point at the specified index. This is like #charAt(int),
+ * but if the character is the start of a surrogate pair, and the
+ * following character completes the pair, then the corresponding
+ * supplementary code point is returned.
+ * @param index the index of the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public synchronized int codePointAt(int index)
+ {
+ return Character.codePointAt(value, index, count);
+ }
+
+ /**
+ * Get the code point before the specified index. This is like
+ * #codePointAt(int), but checks the characters at <code>index-1</code> and
+ * <code>index-2</code> to see if they form a supplementary code point.
+ * @param index the index just past the codepoint to get, starting at 0
+ * @return the codepoint at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * @since 1.5
+ */
+ public synchronized int codePointBefore(int index)
+ {
+ // Character.codePointBefore() doesn't perform this check. We
+ // could use the CharSequence overload, but this is just as easy.
+ if (index >= count)
+ throw new IndexOutOfBoundsException();
+ return Character.codePointBefore(value, index, 1);
+ }
+
+ /**
+ * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+ * characters will be copied into the array you pass in.
+ *
+ * @param srcOffset the index to start copying from (inclusive)
+ * @param srcEnd the index to stop copying from (exclusive)
+ * @param dst the array to copy into
+ * @param dstOffset the index to start copying into
+ * @throws NullPointerException if dst is null
+ * @throws IndexOutOfBoundsException if any source or target indices are
+ * out of range (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dest problems cause an
+ * ArrayIndexOutOfBoundsException)
+ * @see System#arraycopy(Object, int, Object, int, int)
+ */
+ public synchronized void getChars(int srcOffset, int srcEnd,
+ char[] dst, int dstOffset)
+ {
+ if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
+ throw new StringIndexOutOfBoundsException();
+ System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+ }
+
+ /**
+ * Set the character at the specified index.
+ *
+ * @param index the index of the character to set starting at 0
+ * @param ch the value to set that character to
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public synchronized void setCharAt(int index, char ch)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity_unsynchronized(count);
+ value[index] = ch;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param obj the <code>Object</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(Object)
+ * @see #append(String)
+ */
+ public StringBuffer append(Object obj)
+ {
+ return append(obj == null ? "null" : obj.toString());
+ }
+
+ /**
+ * Append the <code>String</code> to this <code>StringBuffer</code>. If
+ * str is null, the String "null" is appended.
+ *
+ * @param str the <code>String</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public synchronized StringBuffer append(String str)
+ {
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity_unsynchronized(count + len);
+ str.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Append the <code>StringBuffer</code> value of the argument to this
+ * <code>StringBuffer</code>. This behaves the same as
+ * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+ *
+ * @param stringBuffer the <code>StringBuffer</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see #append(Object)
+ * @since 1.4
+ */
+ public synchronized StringBuffer append(StringBuffer stringBuffer)
+ {
+ if (stringBuffer == null)
+ return append("null");
+ synchronized (stringBuffer)
+ {
+ int len = stringBuffer.count;
+ ensureCapacity_unsynchronized(count + len);
+ System.arraycopy(stringBuffer.value, 0, value, count, len);
+ count += len;
+ }
+ return this;
+ }
+
+ /**
+ * Append the <code>CharSequence</code> value of the argument to this
+ * <code>StringBuffer</code>.
+ *
+ * @param sequence the <code>CharSequence</code> to append
+ * @return this <code>StringBuffer</code>
+ * @see #append(Object)
+ * @since 1.5
+ */
+ public synchronized StringBuffer append(CharSequence sequence)
+ {
+ if (sequence == null)
+ sequence = "null";
+ return append(sequence, 0, sequence.length());
+ }
+
+ /**
+ * Append the specified subsequence of the <code>CharSequence</code>
+ * argument to this <code>StringBuffer</code>.
+ *
+ * @param sequence the <code>CharSequence</code> to append
+ * @param start the starting index
+ * @param end one past the ending index
+ * @return this <code>StringBuffer</code>
+ * @see #append(Object)
+ * @since 1.5
+ */
+ public synchronized StringBuffer append(CharSequence sequence,
+ int start, int end)
+ {
+ if (sequence == null)
+ sequence = "null";
+ if (start < 0 || end < 0 || start > end || end > sequence.length())
+ throw new IndexOutOfBoundsException();
+ ensureCapacity_unsynchronized(this.count + end - start);
+ for (int i = start; i < end; ++i)
+ value[count++] = sequence.charAt(i);
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> array to this <code>StringBuffer</code>.
+ * This is similar (but more efficient) than
+ * <code>append(new String(data))</code>, except in the case of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @see #append(char[], int, int)
+ */
+ public StringBuffer append(char[] data)
+ {
+ return append(data, 0, data.length);
+ }
+
+ /**
+ * Append part of the <code>char</code> array to this
+ * <code>StringBuffer</code>. This is similar (but more efficient) than
+ * <code>append(new String(data, offset, count))</code>, except in the case
+ * of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @param offset the start location in <code>str</code>
+ * @param count the number of characters to get from <code>str</code>
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if offset or count is out of range
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public synchronized StringBuffer append(char[] data, int offset, int count)
+ {
+ if (offset < 0 || count < 0 || offset > data.length - count)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity_unsynchronized(this.count + count);
+ System.arraycopy(data, offset, value, this.count, count);
+ this.count += count;
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param bool the <code>boolean</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(boolean)
+ */
+ public StringBuffer append(boolean bool)
+ {
+ return append(bool ? "true" : "false");
+ }
+
+ /**
+ * Append the <code>char</code> to this <code>StringBuffer</code>.
+ *
+ * @param ch the <code>char</code> to append
+ * @return this <code>StringBuffer</code>
+ */
+ public synchronized StringBuffer append(char ch)
+ {
+ ensureCapacity_unsynchronized(count + 1);
+ value[count++] = ch;
+ return this;
+ }
+
+ /**
+ * Append the code point to this <code>StringBuffer</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuffer</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public synchronized StringBuffer appendCodePoint(int code)
+ {
+ int len = Character.charCount(code);
+ ensureCapacity_unsynchronized(count + len);
+ Character.toChars(code, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param inum the <code>int</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(int)
+ */
+ // GCJ LOCAL: this is native for efficiency.
+ public native StringBuffer append (int inum);
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param lnum the <code>long</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(long)
+ */
+ public StringBuffer append(long lnum)
+ {
+ return append(Long.toString(lnum, 10));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param fnum the <code>float</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(float)
+ */
+ public StringBuffer append(float fnum)
+ {
+ return append(Float.toString(fnum));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param dnum the <code>double</code> to convert and append
+ * @return this <code>StringBuffer</code>
+ * @see String#valueOf(double)
+ */
+ public StringBuffer append(double dnum)
+ {
+ return append(Double.toString(dnum));
+ }
+
+ /**
+ * Delete characters from this <code>StringBuffer</code>.
+ * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+ * harmless for end to be larger than length().
+ *
+ * @param start the first character to delete
+ * @param end the index after the last character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @since 1.2
+ */
+ public synchronized StringBuffer delete(int start, int end)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+ if (end > count)
+ end = count;
+ // This will unshare if required.
+ ensureCapacity_unsynchronized(count);
+ if (count - end != 0)
+ System.arraycopy(value, end, value, start, count - end);
+ count -= end - start;
+ return this;
+ }
+
+ /**
+ * Delete a character from this <code>StringBuffer</code>.
+ *
+ * @param index the index of the character to delete
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if index is out of bounds
+ * @since 1.2
+ */
+ public StringBuffer deleteCharAt(int index)
+ {
+ return delete(index, index + 1);
+ }
+
+ /**
+ * Replace characters between index <code>start</code> (inclusive) and
+ * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+ * is larger than the size of this StringBuffer, all characters after
+ * <code>start</code> are replaced.
+ *
+ * @param start the beginning index of characters to delete (inclusive)
+ * @param end the ending index of characters to delete (exclusive)
+ * @param str the new <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @throws NullPointerException if str is null
+ * @since 1.2
+ */
+ public synchronized StringBuffer replace(int start, int end, String str)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+
+ int len = str.count;
+ // Calculate the difference in 'count' after the replace.
+ int delta = len - (end > count ? count : end) + start;
+ ensureCapacity_unsynchronized(count + delta);
+
+ if (delta != 0 && end < count)
+ System.arraycopy(value, end, value, end + delta, count - end);
+
+ str.getChars(0, len, value, start);
+ count += delta;
+ return this;
+ }
+
+ /**
+ * Creates a substring of this StringBuffer, starting at a specified index
+ * and ending at the end of this StringBuffer.
+ *
+ * @param beginIndex index to start substring (base 0)
+ * @return new String which is a substring of this StringBuffer
+ * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
+ * @see #substring(int, int)
+ * @since 1.2
+ */
+ public String substring(int beginIndex)
+ {
+ return substring(beginIndex, count);
+ }
+
+ /**
+ * Creates a substring of this StringBuffer, starting at a specified index
+ * and ending at one character before a specified index. This is implemented
+ * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
+ * the CharSequence interface.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuffer
+ * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
+ * bounds
+ * @see #substring(int, int)
+ * @since 1.4
+ */
+ public CharSequence subSequence(int beginIndex, int endIndex)
+ {
+ return substring(beginIndex, endIndex);
+ }
+
+ /**
+ * Creates a substring of this StringBuffer, starting at a specified index
+ * and ending at one character before a specified index.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuffer
+ * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
+ * of bounds
+ * @since 1.2
+ */
+ public synchronized String substring(int beginIndex, int endIndex)
+ {
+ int len = endIndex - beginIndex;
+ if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
+ throw new StringIndexOutOfBoundsException();
+ if (len == 0)
+ return "";
+ // Don't copy unless substring is smaller than 1/4 of the buffer.
+ boolean share_buffer = ((len << 2) >= value.length);
+ if (share_buffer)
+ this.shared = true;
+ // Package constructor avoids an array copy.
+ return new String(value, beginIndex, len, share_buffer);
+ }
+
+ /**
+ * Insert a subarray of the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>char[]</code> to insert
+ * @param str_offset the index in <code>str</code> to start inserting from
+ * @param len the number of characters to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if any index is out of bounds
+ * @since 1.2
+ */
+ public synchronized StringBuffer insert(int offset,
+ char[] str, int str_offset, int len)
+ {
+ if (offset < 0 || offset > count || len < 0
+ || str_offset < 0 || str_offset > str.length - len)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity_unsynchronized(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ System.arraycopy(str, str_offset, value, offset, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param obj the <code>Object</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @exception StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(Object)
+ */
+ public StringBuffer insert(int offset, Object obj)
+ {
+ return insert(offset, obj == null ? "null" : obj.toString());
+ }
+
+ /**
+ * Insert the <code>String</code> argument into this
+ * <code>StringBuffer</code>. If str is null, the String "null" is used
+ * instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>String</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public synchronized StringBuffer insert(int offset, String str)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity_unsynchronized(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ str.getChars(0, len, value, offset);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset is out of bounds
+ * @since 1.5
+ */
+ public synchronized StringBuffer insert(int offset, CharSequence sequence)
+ {
+ if (sequence == null)
+ sequence = "null";
+ return insert(offset, sequence, 0, sequence.length());
+ }
+
+ /**
+ * Insert a subsequence of the <code>CharSequence</code> argument into this
+ * <code>StringBuffer</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @param start the starting index of the subsequence
+ * @param end one past the ending index of the subsequence
+ * @return this <code>StringBuffer</code>
+ * @throws IndexOutOfBoundsException if offset, start,
+ * or end are out of bounds
+ * @since 1.5
+ */
+ public synchronized StringBuffer insert(int offset, CharSequence sequence,
+ int start, int end)
+ {
+ if (sequence == null)
+ sequence = "null";
+ if (start < 0 || end < 0 || start > end || end > sequence.length())
+ throw new IndexOutOfBoundsException();
+ int len = end - start;
+ ensureCapacity_unsynchronized(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ for (int i = start; i < end; ++i)
+ value[offset++] = sequence.charAt(i);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>char[]</code> argument into this
+ * <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param data the <code>char[]</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws NullPointerException if <code>data</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see #insert(int, char[], int, int)
+ */
+ public StringBuffer insert(int offset, char[] data)
+ {
+ return insert(offset, data, 0, data.length);
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param bool the <code>boolean</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(boolean)
+ */
+ public StringBuffer insert(int offset, boolean bool)
+ {
+ return insert(offset, bool ? "true" : "false");
+ }
+
+ /**
+ * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param ch the <code>char</code> to insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public synchronized StringBuffer insert(int offset, char ch)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ ensureCapacity_unsynchronized(count + 1);
+ System.arraycopy(value, offset, value, offset + 1, count - offset);
+ value[offset] = ch;
+ count++;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param inum the <code>int</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(int)
+ */
+ public StringBuffer insert(int offset, int inum)
+ {
+ return insert(offset, String.valueOf(inum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param lnum the <code>long</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(long)
+ */
+ public StringBuffer insert(int offset, long lnum)
+ {
+ return insert(offset, Long.toString(lnum, 10));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param fnum the <code>float</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(float)
+ */
+ public StringBuffer insert(int offset, float fnum)
+ {
+ return insert(offset, Float.toString(fnum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param dnum the <code>double</code> to convert and insert
+ * @return this <code>StringBuffer</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(double)
+ */
+ public StringBuffer insert(int offset, double dnum)
+ {
+ return insert(offset, Double.toString(dnum));
+ }
+
+ /**
+ * Finds the first instance of a substring in this StringBuffer.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #indexOf(String, int)
+ * @since 1.4
+ */
+ public int indexOf(String str)
+ {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Finds the first instance of a String in this StringBuffer, starting at
+ * a given index. If starting index is less than 0, the search starts at
+ * the beginning of this String. If the starting index is greater than the
+ * length of this String, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public synchronized int indexOf(String str, int fromIndex)
+ {
+ if (fromIndex < 0)
+ fromIndex = 0;
+ int limit = count - str.count;
+ for ( ; fromIndex <= limit; fromIndex++)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Finds the last instance of a substring in this StringBuffer.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #lastIndexOf(String, int)
+ * @since 1.4
+ */
+ public int lastIndexOf(String str)
+ {
+ return lastIndexOf(str, count - str.count);
+ }
+
+ /**
+ * Finds the last instance of a String in this StringBuffer, starting at a
+ * given index. If starting index is greater than the maximum valid index,
+ * then the search begins at the end of this String. If the starting index
+ * is less than zero, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @since 1.4
+ */
+ public synchronized int lastIndexOf(String str, int fromIndex)
+ {
+ fromIndex = Math.min(fromIndex, count - str.count);
+ for ( ; fromIndex >= 0; fromIndex--)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Reverse the characters in this StringBuffer. The same sequence of
+ * characters exists, but in the reverse index ordering.
+ *
+ * @return this <code>StringBuffer</code>
+ */
+ public synchronized StringBuffer reverse()
+ {
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity_unsynchronized(count);
+ for (int i = count >> 1, j = count - i; --i >= 0; ++j)
+ {
+ char c = value[i];
+ value[i] = value[j];
+ value[j] = c;
+ }
+ return this;
+ }
+
+ /**
+ * Convert this <code>StringBuffer</code> to a <code>String</code>. The
+ * String is composed of the characters currently in this StringBuffer. Note
+ * that the result is a copy, and that future modifications to this buffer
+ * do not affect the String.
+ *
+ * @return the characters in this StringBuffer
+ */
+ public String toString()
+ {
+ // The string will set this.shared = true.
+ return new String(this);
+ }
+
+ /**
+ * This may reduce the amount of memory used by the StringBuffer,
+ * by resizing the internal array to remove unused space. However,
+ * this method is not required to resize, so this behavior cannot
+ * be relied upon.
+ * @since 1.5
+ */
+ public synchronized void trimToSize()
+ {
+ int wouldSave = value.length - count;
+ // Some random heuristics: if we save less than 20 characters, who
+ // cares.
+ if (wouldSave < 20)
+ return;
+ // If we save more than 200 characters, shrink.
+ // If we save more than 1/4 of the buffer, shrink.
+ if (wouldSave > 200 || wouldSave * 4 > value.length)
+ {
+ char[] newValue = new char[count];
+ System.arraycopy(value, 0, newValue, 0, count);
+ value = newValue;
+ }
+ }
+
+ /**
+ * Return the number of code points between two indices in the
+ * <code>StringBuffer</code>. An unpaired surrogate counts as a
+ * code point for this purpose. Characters outside the indicated
+ * range are not examined, even if the range ends in the middle of a
+ * surrogate pair.
+ *
+ * @param start the starting index
+ * @param end one past the ending index
+ * @return the number of code points
+ * @since 1.5
+ */
+ public synchronized int codePointCount(int start, int end)
+ {
+ if (start < 0 || end >= count || start > end)
+ throw new StringIndexOutOfBoundsException();
+
+ int count = 0;
+ while (start < end)
+ {
+ char base = value[start];
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == end
+ || start == count
+ || value[start + 1] < Character.MIN_LOW_SURROGATE
+ || value[start + 1] > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ ++count;
+ }
+ return count;
+ }
+
+ /**
+ * Starting at the given index, this counts forward by the indicated
+ * number of code points, and then returns the resulting index. An
+ * unpaired surrogate counts as a single code point for this
+ * purpose.
+ *
+ * @param start the starting index
+ * @param codePoints the number of code points
+ * @return the resulting index
+ * @since 1.5
+ */
+ public synchronized int offsetByCodePoints(int start, int codePoints)
+ {
+ while (codePoints > 0)
+ {
+ char base = value[start];
+ if (base < Character.MIN_HIGH_SURROGATE
+ || base > Character.MAX_HIGH_SURROGATE
+ || start == count
+ || value[start + 1] < Character.MIN_LOW_SURROGATE
+ || value[start + 1] > Character.MAX_LOW_SURROGATE)
+ {
+ // Nothing.
+ }
+ else
+ {
+ // Surrogate pair.
+ ++start;
+ }
+ ++start;
+ --codePoints;
+ }
+ return start;
+ }
+
+ /**
+ * An unsynchronized version of ensureCapacity, used internally to avoid
+ * the cost of a second lock on the same object. This also has the side
+ * effect of duplicating the array, if it was shared (to form copy-on-write
+ * semantics).
+ *
+ * @param minimumCapacity the minimum capacity
+ * @see #ensureCapacity(int)
+ */
+ private void ensureCapacity_unsynchronized(int minimumCapacity)
+ {
+ if (shared || minimumCapacity > value.length)
+ {
+ // We don't want to make a larger vector when `shared' is
+ // set. If we do, then setLength becomes very inefficient
+ // when repeatedly reusing a StringBuffer in a loop.
+ int max = (minimumCapacity > value.length
+ ? value.length * 2 + 2
+ : value.length);
+ minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+ char[] nb = new char[minimumCapacity];
+ System.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ shared = false;
+ }
+ }
+
+ /**
+ * Predicate which determines if a substring of this matches another String
+ * starting at a specified offset for each String and continuing for a
+ * specified length. This is more efficient than creating a String to call
+ * indexOf on.
+ *
+ * @param toffset index to start comparison at for this String
+ * @param other non-null String to compare to region of this
+ * @return true if regions match, false otherwise
+ * @see #indexOf(String, int)
+ * @see #lastIndexOf(String, int)
+ * @see String#regionMatches(boolean, int, String, int, int)
+ */
+ // GCJ LOCAL: native for gcj.
+ private native boolean regionMatches(int toffset, String other);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/StringBuilder.java b/gcc-4.2.1/libjava/java/lang/StringBuilder.java
new file mode 100644
index 000000000..5990a6d8d
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/StringBuilder.java
@@ -0,0 +1,1002 @@
+/* StringBuilder.java -- Unsynchronized growable strings
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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.Serializable;
+
+/**
+ * <code>StringBuilder</code> represents a changeable <code>String</code>.
+ * It provides the operations required to modify the
+ * <code>StringBuilder</code>, including insert, replace, delete, append,
+ * and reverse. It like <code>StringBuffer</code>, but is not
+ * synchronized. It is ideal for use when it is known that the
+ * object will only be used from a single thread.
+ *
+ * <p><code>StringBuilder</code>s are variable-length in nature, so even if
+ * you initialize them to a certain size, they can still grow larger than
+ * that. <em>Capacity</em> indicates the number of characters the
+ * <code>StringBuilder</code> can have in it before it has to grow (growing
+ * the char array is an expensive operation involving <code>new</code>).
+ *
+ * <p>Incidentally, compilers often implement the String operator "+"
+ * by using a <code>StringBuilder</code> operation:<br>
+ * <code>a + b</code><br>
+ * is the same as<br>
+ * <code>new StringBuilder().append(a).append(b).toString()</code>.
+ *
+ * <p>Classpath's StringBuilder is capable of sharing memory with Strings for
+ * efficiency. This will help when a StringBuilder is converted to a String
+ * and the StringBuilder is not changed after that (quite common when
+ * performing string concatenation).
+ *
+ * @author Paul Fisher
+ * @author John Keiser
+ * @author Tom Tromey
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see String
+ * @see StringBuffer
+ *
+ * @since 1.5
+ */
+// FIX15: Implement Appendable when co-variant methods are available
+public final class StringBuilder
+ implements Serializable, CharSequence
+{
+ // Implementation note: if you change this class, you usually will
+ // want to change StringBuffer as well.
+
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = 4383685877147921099L;
+
+ /**
+ * Index of next available character (and thus the size of the current
+ * string contents). Note that this has permissions set this way so that
+ * String can get the value.
+ *
+ * @serial the number of characters in the buffer
+ */
+ int count;
+
+ /**
+ * The buffer. Note that this has permissions set this way so that String
+ * can get the value.
+ *
+ * @serial the buffer
+ */
+ char[] value;
+
+ /**
+ * The default capacity of a buffer.
+ */
+ private static final int DEFAULT_CAPACITY = 16;
+
+ /**
+ * Create a new StringBuilder with default capacity 16.
+ */
+ public StringBuilder()
+ {
+ this(DEFAULT_CAPACITY);
+ }
+
+ /**
+ * Create an empty <code>StringBuilder</code> with the specified initial
+ * capacity.
+ *
+ * @param capacity the initial capacity
+ * @throws NegativeArraySizeException if capacity is negative
+ */
+ public StringBuilder(int capacity)
+ {
+ value = new char[capacity];
+ }
+
+ /**
+ * Create a new <code>StringBuilder</code> with the characters in the
+ * specified <code>String</code>. Initial capacity will be the size of the
+ * String plus 16.
+ *
+ * @param str the <code>String</code> to convert
+ * @throws NullPointerException if str is null
+ */
+ public StringBuilder(String str)
+ {
+ // Unfortunately, because the size is 16 larger, we cannot share.
+ count = str.count;
+ value = new char[count + DEFAULT_CAPACITY];
+ str.getChars(0, count, value, 0);
+ }
+
+ /**
+ * Create a new <code>StringBuilder</code> with the characters in the
+ * specified <code>CharSequence</code>. Initial capacity will be the
+ * length of the sequence plus 16; if the sequence reports a length
+ * less than or equal to 0, then the initial capacity will be 16.
+ *
+ * @param seq the initializing <code>CharSequence</code>
+ * @throws NullPointerException if str is null
+ */
+ public StringBuilder(CharSequence seq)
+ {
+ int len = seq.length();
+ count = len <= 0 ? 0 : len;
+ value = new char[count + DEFAULT_CAPACITY];
+ for (int i = 0; i < len; ++i)
+ value[i] = seq.charAt(i);
+ }
+
+ /**
+ * Get the length of the <code>String</code> this <code>StringBuilder</code>
+ * would create. Not to be confused with the <em>capacity</em> of the
+ * <code>StringBuilder</code>.
+ *
+ * @return the length of this <code>StringBuilder</code>
+ * @see #capacity()
+ * @see #setLength(int)
+ */
+ public int length()
+ {
+ return count;
+ }
+
+ /**
+ * Get the total number of characters this <code>StringBuilder</code> can
+ * support before it must be grown. Not to be confused with <em>length</em>.
+ *
+ * @return the capacity of this <code>StringBuilder</code>
+ * @see #length()
+ * @see #ensureCapacity(int)
+ */
+ public int capacity()
+ {
+ return value.length;
+ }
+
+ /**
+ * Increase the capacity of this <code>StringBuilder</code>. This will
+ * ensure that an expensive growing operation will not occur until
+ * <code>minimumCapacity</code> is reached. The buffer is grown to the
+ * larger of <code>minimumCapacity</code> and
+ * <code>capacity() * 2 + 2</code>, if it is not already large enough.
+ *
+ * @param minimumCapacity the new capacity
+ * @see #capacity()
+ */
+ public void ensureCapacity(int minimumCapacity)
+ {
+ if (minimumCapacity > value.length)
+ {
+ int max = value.length * 2 + 2;
+ minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
+ char[] nb = new char[minimumCapacity];
+ System.arraycopy(value, 0, nb, 0, count);
+ value = nb;
+ }
+ }
+
+ /**
+ * Set the length of this StringBuilder. If the new length is greater than
+ * the current length, all the new characters are set to '\0'. If the new
+ * length is less than the current length, the first <code>newLength</code>
+ * characters of the old array will be preserved, and the remaining
+ * characters are truncated.
+ *
+ * @param newLength the new length
+ * @throws IndexOutOfBoundsException if the new length is negative
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ * @see #length()
+ */
+ public void setLength(int newLength)
+ {
+ if (newLength < 0)
+ throw new StringIndexOutOfBoundsException(newLength);
+
+ int valueLength = value.length;
+
+ /* Always call ensureCapacity in order to preserve copy-on-write
+ semantics. */
+ ensureCapacity(newLength);
+
+ if (newLength < valueLength)
+ {
+ /* If the StringBuilder's value just grew, then we know that
+ value is newly allocated and the region between count and
+ newLength is filled with '\0'. */
+ count = newLength;
+ }
+ else
+ {
+ /* The StringBuilder's value doesn't need to grow. However,
+ we should clear out any cruft that may exist. */
+ while (count < newLength)
+ value[count++] = '\0';
+ }
+ }
+
+ /**
+ * Get the character at the specified index.
+ *
+ * @param index the index of the character to get, starting at 0
+ * @return the character at the specified index
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public char charAt(int index)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ return value[index];
+ }
+
+ /**
+ * Get the specified array of characters. <code>srcOffset - srcEnd</code>
+ * characters will be copied into the array you pass in.
+ *
+ * @param srcOffset the index to start copying from (inclusive)
+ * @param srcEnd the index to stop copying from (exclusive)
+ * @param dst the array to copy into
+ * @param dstOffset the index to start copying into
+ * @throws NullPointerException if dst is null
+ * @throws IndexOutOfBoundsException if any source or target indices are
+ * out of range (while unspecified, source problems cause a
+ * StringIndexOutOfBoundsException, and dest problems cause an
+ * ArrayIndexOutOfBoundsException)
+ * @see System#arraycopy(Object, int, Object, int, int)
+ */
+ public void getChars(int srcOffset, int srcEnd,
+ char[] dst, int dstOffset)
+ {
+ if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
+ throw new StringIndexOutOfBoundsException();
+ System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
+ }
+
+ /**
+ * Set the character at the specified index.
+ *
+ * @param index the index of the character to set starting at 0
+ * @param ch the value to set that character to
+ * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public void setCharAt(int index, char ch)
+ {
+ if (index < 0 || index >= count)
+ throw new StringIndexOutOfBoundsException(index);
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity(count);
+ value[index] = ch;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param obj the <code>Object</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(Object)
+ * @see #append(String)
+ */
+ public StringBuilder append(Object obj)
+ {
+ return append(obj == null ? "null" : obj.toString());
+ }
+
+ /**
+ * Append the <code>String</code> to this <code>StringBuilder</code>. If
+ * str is null, the String "null" is appended.
+ *
+ * @param str the <code>String</code> to append
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(String str)
+ {
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity(count + len);
+ str.getChars(0, len, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Append the <code>StringBuilder</code> value of the argument to this
+ * <code>StringBuilder</code>. This behaves the same as
+ * <code>append((Object) stringBuffer)</code>, except it is more efficient.
+ *
+ * @param stringBuffer the <code>StringBuilder</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see #append(Object)
+ */
+ public StringBuilder append(StringBuffer stringBuffer)
+ {
+ if (stringBuffer == null)
+ return append("null");
+ synchronized (stringBuffer)
+ {
+ int len = stringBuffer.count;
+ ensureCapacity(count + len);
+ System.arraycopy(stringBuffer.value, 0, value, count, len);
+ count += len;
+ }
+ return this;
+ }
+
+ /**
+ * Append the <code>char</code> array to this <code>StringBuilder</code>.
+ * This is similar (but more efficient) than
+ * <code>append(new String(data))</code>, except in the case of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @see #append(char[], int, int)
+ */
+ public StringBuilder append(char[] data)
+ {
+ return append(data, 0, data.length);
+ }
+
+ /**
+ * Append part of the <code>char</code> array to this
+ * <code>StringBuilder</code>. This is similar (but more efficient) than
+ * <code>append(new String(data, offset, count))</code>, except in the case
+ * of null.
+ *
+ * @param data the <code>char[]</code> to append
+ * @param offset the start location in <code>str</code>
+ * @param count the number of characters to get from <code>str</code>
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws IndexOutOfBoundsException if offset or count is out of range
+ * (while unspecified, this is a StringIndexOutOfBoundsException)
+ */
+ public StringBuilder append(char[] data, int offset, int count)
+ {
+ if (offset < 0 || count < 0 || offset > data.length - count)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity(this.count + count);
+ System.arraycopy(data, offset, value, this.count, count);
+ this.count += count;
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param bool the <code>boolean</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(boolean)
+ */
+ public StringBuilder append(boolean bool)
+ {
+ return append(bool ? "true" : "false");
+ }
+
+ /**
+ * Append the <code>char</code> to this <code>StringBuilder</code>.
+ *
+ * @param ch the <code>char</code> to append
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(char ch)
+ {
+ ensureCapacity(count + 1);
+ value[count++] = ch;
+ return this;
+ }
+
+ /**
+ * Append the characters in the <code>CharSequence</code> to this
+ * buffer.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(CharSequence seq)
+ {
+ return append(seq, 0, seq.length());
+ }
+
+ /**
+ * Append some characters from the <code>CharSequence</code> to this
+ * buffer. If the argument is null, the four characters "null" are
+ * appended.
+ *
+ * @param seq the <code>CharSequence</code> providing the characters
+ * @param start the starting index
+ * @param end one past the final index
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder append(CharSequence seq, int start,
+ int end)
+ {
+ if (seq == null)
+ return append("null");
+ if (end - start > 0)
+ {
+ ensureCapacity(count + end - start);
+ for (; start < end; ++start)
+ value[count++] = seq.charAt(start);
+ }
+ return this;
+ }
+
+ /**
+ * Append the code point to this <code>StringBuilder</code>.
+ * This is like #append(char), but will append two characters
+ * if a supplementary code point is given.
+ *
+ * @param code the code point to append
+ * @return this <code>StringBuilder</code>
+ * @see Character#toChars(int, char[], int)
+ * @since 1.5
+ */
+ public synchronized StringBuilder appendCodePoint(int code)
+ {
+ int len = Character.charCount(code);
+ ensureCapacity(count + len);
+ Character.toChars(code, value, count);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param inum the <code>int</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(int)
+ */
+ // FIXME: this is native in libgcj in StringBuffer.
+ public StringBuilder append(int inum)
+ {
+ return append(String.valueOf(inum));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param lnum the <code>long</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(long)
+ */
+ public StringBuilder append(long lnum)
+ {
+ return append(Long.toString(lnum, 10));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param fnum the <code>float</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(float)
+ */
+ public StringBuilder append(float fnum)
+ {
+ return append(Float.toString(fnum));
+ }
+
+ /**
+ * Append the <code>String</code> value of the argument to this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param dnum the <code>double</code> to convert and append
+ * @return this <code>StringBuilder</code>
+ * @see String#valueOf(double)
+ */
+ public StringBuilder append(double dnum)
+ {
+ return append(Double.toString(dnum));
+ }
+
+ /**
+ * Delete characters from this <code>StringBuilder</code>.
+ * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
+ * harmless for end to be larger than length().
+ *
+ * @param start the first character to delete
+ * @param end the index after the last character to delete
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ */
+ public StringBuilder delete(int start, int end)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+ if (end > count)
+ end = count;
+ // This will unshare if required.
+ ensureCapacity(count);
+ if (count - end != 0)
+ System.arraycopy(value, end, value, start, count - end);
+ count -= end - start;
+ return this;
+ }
+
+ /**
+ * Delete a character from this <code>StringBuilder</code>.
+ *
+ * @param index the index of the character to delete
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if index is out of bounds
+ */
+ public StringBuilder deleteCharAt(int index)
+ {
+ return delete(index, index + 1);
+ }
+
+ /**
+ * Replace characters between index <code>start</code> (inclusive) and
+ * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
+ * is larger than the size of this StringBuilder, all characters after
+ * <code>start</code> are replaced.
+ *
+ * @param start the beginning index of characters to delete (inclusive)
+ * @param end the ending index of characters to delete (exclusive)
+ * @param str the new <code>String</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if start or end are out of bounds
+ * @throws NullPointerException if str is null
+ */
+ public StringBuilder replace(int start, int end, String str)
+ {
+ if (start < 0 || start > count || start > end)
+ throw new StringIndexOutOfBoundsException(start);
+
+ int len = str.count;
+ // Calculate the difference in 'count' after the replace.
+ int delta = len - (end > count ? count : end) + start;
+ ensureCapacity(count + delta);
+
+ if (delta != 0 && end < count)
+ System.arraycopy(value, end, value, end + delta, count - end);
+
+ str.getChars(0, len, value, start);
+ count += delta;
+ return this;
+ }
+
+ /**
+ * Creates a substring of this StringBuilder, starting at a specified index
+ * and ending at the end of this StringBuilder.
+ *
+ * @param beginIndex index to start substring (base 0)
+ * @return new String which is a substring of this StringBuilder
+ * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
+ * @see #substring(int, int)
+ */
+ public String substring(int beginIndex)
+ {
+ return substring(beginIndex, count);
+ }
+
+ /**
+ * Creates a substring of this StringBuilder, starting at a specified index
+ * and ending at one character before a specified index. This is implemented
+ * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
+ * the CharSequence interface.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuilder
+ * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
+ * bounds
+ * @see #substring(int, int)
+ */
+ public CharSequence subSequence(int beginIndex, int endIndex)
+ {
+ return substring(beginIndex, endIndex);
+ }
+
+ /**
+ * Creates a substring of this StringBuilder, starting at a specified index
+ * and ending at one character before a specified index.
+ *
+ * @param beginIndex index to start at (inclusive, base 0)
+ * @param endIndex index to end at (exclusive)
+ * @return new String which is a substring of this StringBuilder
+ * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
+ * of bounds
+ */
+ public String substring(int beginIndex, int endIndex)
+ {
+ int len = endIndex - beginIndex;
+ if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
+ throw new StringIndexOutOfBoundsException();
+ if (len == 0)
+ return "";
+ return new String(value, beginIndex, len);
+ }
+
+ /**
+ * Insert a subarray of the <code>char[]</code> argument into this
+ * <code>StringBuilder</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>char[]</code> to insert
+ * @param str_offset the index in <code>str</code> to start inserting from
+ * @param len the number of characters to insert
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>str</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if any index is out of bounds
+ */
+ public StringBuilder insert(int offset,
+ char[] str, int str_offset, int len)
+ {
+ if (offset < 0 || offset > count || len < 0
+ || str_offset < 0 || str_offset > str.length - len)
+ throw new StringIndexOutOfBoundsException();
+ ensureCapacity(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ System.arraycopy(str, str_offset, value, offset, len);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param obj the <code>Object</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @exception StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(Object)
+ */
+ public StringBuilder insert(int offset, Object obj)
+ {
+ return insert(offset, obj == null ? "null" : obj.toString());
+ }
+
+ /**
+ * Insert the <code>String</code> argument into this
+ * <code>StringBuilder</code>. If str is null, the String "null" is used
+ * instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param str the <code>String</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public StringBuilder insert(int offset, String str)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ if (str == null)
+ str = "null";
+ int len = str.count;
+ ensureCapacity(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ str.getChars(0, len, value, offset);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>CharSequence</code> argument into this
+ * <code>StringBuilder</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws IndexOutOfBoundsException if offset is out of bounds
+ */
+ public synchronized StringBuilder insert(int offset, CharSequence sequence)
+ {
+ if (sequence == null)
+ sequence = "null";
+ return insert(offset, sequence, 0, sequence.length());
+ }
+
+ /**
+ * Insert a subsequence of the <code>CharSequence</code> argument into this
+ * <code>StringBuilder</code>. If the sequence is null, the String
+ * "null" is used instead.
+ *
+ * @param offset the place to insert in this buffer
+ * @param sequence the <code>CharSequence</code> to insert
+ * @param start the starting index of the subsequence
+ * @param end one past the ending index of the subsequence
+ * @return this <code>StringBuilder</code>
+ * @throws IndexOutOfBoundsException if offset, start,
+ * or end are out of bounds
+ */
+ public synchronized StringBuilder insert(int offset, CharSequence sequence,
+ int start, int end)
+ {
+ if (sequence == null)
+ sequence = "null";
+ if (start < 0 || end < 0 || start > end || end > sequence.length())
+ throw new IndexOutOfBoundsException();
+ int len = end - start;
+ ensureCapacity(count + len);
+ System.arraycopy(value, offset, value, offset + len, count - offset);
+ for (int i = start; i < end; ++i)
+ value[offset++] = sequence.charAt(i);
+ count += len;
+ return this;
+ }
+
+ /**
+ * Insert the <code>char[]</code> argument into this
+ * <code>StringBuilder</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param data the <code>char[]</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws NullPointerException if <code>data</code> is <code>null</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see #insert(int, char[], int, int)
+ */
+ public StringBuilder insert(int offset, char[] data)
+ {
+ return insert(offset, data, 0, data.length);
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param bool the <code>boolean</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(boolean)
+ */
+ public StringBuilder insert(int offset, boolean bool)
+ {
+ return insert(offset, bool ? "true" : "false");
+ }
+
+ /**
+ * Insert the <code>char</code> argument into this <code>StringBuilder</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param ch the <code>char</code> to insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ */
+ public StringBuilder insert(int offset, char ch)
+ {
+ if (offset < 0 || offset > count)
+ throw new StringIndexOutOfBoundsException(offset);
+ ensureCapacity(count + 1);
+ System.arraycopy(value, offset, value, offset + 1, count - offset);
+ value[offset] = ch;
+ count++;
+ return this;
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param inum the <code>int</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(int)
+ */
+ public StringBuilder insert(int offset, int inum)
+ {
+ return insert(offset, String.valueOf(inum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param lnum the <code>long</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(long)
+ */
+ public StringBuilder insert(int offset, long lnum)
+ {
+ return insert(offset, Long.toString(lnum, 10));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param fnum the <code>float</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(float)
+ */
+ public StringBuilder insert(int offset, float fnum)
+ {
+ return insert(offset, Float.toString(fnum));
+ }
+
+ /**
+ * Insert the <code>String</code> value of the argument into this
+ * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
+ * to <code>String</code>.
+ *
+ * @param offset the place to insert in this buffer
+ * @param dnum the <code>double</code> to convert and insert
+ * @return this <code>StringBuilder</code>
+ * @throws StringIndexOutOfBoundsException if offset is out of bounds
+ * @see String#valueOf(double)
+ */
+ public StringBuilder insert(int offset, double dnum)
+ {
+ return insert(offset, Double.toString(dnum));
+ }
+
+ /**
+ * Finds the first instance of a substring in this StringBuilder.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #indexOf(String, int)
+ */
+ public int indexOf(String str)
+ {
+ return indexOf(str, 0);
+ }
+
+ /**
+ * Finds the first instance of a String in this StringBuilder, starting at
+ * a given index. If starting index is less than 0, the search starts at
+ * the beginning of this String. If the starting index is greater than the
+ * length of this String, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int indexOf(String str, int fromIndex)
+ {
+ if (fromIndex < 0)
+ fromIndex = 0;
+ int limit = count - str.count;
+ for ( ; fromIndex <= limit; fromIndex++)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Finds the last instance of a substring in this StringBuilder.
+ *
+ * @param str String to find
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ * @see #lastIndexOf(String, int)
+ */
+ public int lastIndexOf(String str)
+ {
+ return lastIndexOf(str, count - str.count);
+ }
+
+ /**
+ * Finds the last instance of a String in this StringBuilder, starting at a
+ * given index. If starting index is greater than the maximum valid index,
+ * then the search begins at the end of this String. If the starting index
+ * is less than zero, or the substring is not found, -1 is returned.
+ *
+ * @param str String to find
+ * @param fromIndex index to start the search
+ * @return location (base 0) of the String, or -1 if not found
+ * @throws NullPointerException if str is null
+ */
+ public int lastIndexOf(String str, int fromIndex)
+ {
+ fromIndex = Math.min(fromIndex, count - str.count);
+ for ( ; fromIndex >= 0; fromIndex--)
+ if (regionMatches(fromIndex, str))
+ return fromIndex;
+ return -1;
+ }
+
+ /**
+ * Reverse the characters in this StringBuilder. The same sequence of
+ * characters exists, but in the reverse index ordering.
+ *
+ * @return this <code>StringBuilder</code>
+ */
+ public StringBuilder reverse()
+ {
+ // Call ensureCapacity to enforce copy-on-write.
+ ensureCapacity(count);
+ for (int i = count >> 1, j = count - i; --i >= 0; ++j)
+ {
+ char c = value[i];
+ value[i] = value[j];
+ value[j] = c;
+ }
+ return this;
+ }
+
+ /**
+ * Convert this <code>StringBuilder</code> to a <code>String</code>. The
+ * String is composed of the characters currently in this StringBuilder. Note
+ * that the result is a copy, and that future modifications to this buffer
+ * do not affect the String.
+ *
+ * @return the characters in this StringBuilder
+ */
+ public String toString()
+ {
+ return new String(this);
+ }
+
+ /**
+ * Predicate which determines if a substring of this matches another String
+ * starting at a specified offset for each String and continuing for a
+ * specified length. This is more efficient than creating a String to call
+ * indexOf on.
+ *
+ * @param toffset index to start comparison at for this String
+ * @param other non-null String to compare to region of this
+ * @return true if regions match, false otherwise
+ * @see #indexOf(String, int)
+ * @see #lastIndexOf(String, int)
+ * @see String#regionMatches(boolean, int, String, int, int)
+ */
+ // GCJ LOCAL: Native to access String internals properly.
+ private native boolean regionMatches(int toffset, String other);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/System.java b/gcc-4.2.1/libjava/java/lang/System.java
new file mode 100644
index 000000000..6b125c90a
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/System.java
@@ -0,0 +1,560 @@
+/* System.java -- useful methods to interface with the system
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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 gnu.classpath.SystemProperties;
+
+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;
+import java.util.Properties;
+import java.util.PropertyPermission;
+
+/**
+ * System represents system-wide resources; things that represent the
+ * general environment. As such, all methods are static.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.0
+ * @status still missing 1.4 functionality
+ */
+public final class System
+{
+ // WARNING: System is a CORE class in the bootstrap cycle. See the comments
+ // in vm/reference/java/lang/Runtime for implications of this fact.
+
+ /**
+ * The standard InputStream. This is assigned at startup and starts its
+ * life perfectly valid. Although it is marked final, you can change it
+ * using {@link #setIn(InputStream)} through some hefty VM magic.
+ *
+ * <p>This corresponds to the C stdin and C++ cin variables, which
+ * typically input from the keyboard, but may be used to pipe input from
+ * other processes or files. That should all be transparent to you,
+ * however.
+ */
+ public static final InputStream in
+ = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
+ /**
+ * The standard output PrintStream. This is assigned at startup and
+ * starts its life perfectly valid. Although it is marked final, you can
+ * change it using {@link #setOut(PrintStream)} through some hefty VM magic.
+ *
+ * <p>This corresponds to the C stdout and C++ cout variables, which
+ * typically output normal messages to the screen, but may be used to pipe
+ * output to other processes or files. That should all be transparent to
+ * you, however.
+ */
+ public static final PrintStream out
+ = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true);
+ /**
+ * The standard output PrintStream. This is assigned at startup and
+ * starts its life perfectly valid. Although it is marked final, you can
+ * change it using {@link #setErr(PrintStream)} through some hefty VM magic.
+ *
+ * <p>This corresponds to the C stderr and C++ cerr variables, which
+ * typically output error messages to the screen, but may be used to pipe
+ * output to other processes or files. That should all be transparent to
+ * you, however.
+ */
+ public static final PrintStream err
+ = new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.err)), true);
+
+ /**
+ * This class is uninstantiable.
+ */
+ private System()
+ {
+ }
+
+ /**
+ * Set {@link #in} to a new InputStream. This uses some VM magic to change
+ * a "final" variable, so naturally there is a security check,
+ * <code>RuntimePermission("setIO")</code>.
+ *
+ * @param in the new InputStream
+ * @throws SecurityException if permission is denied
+ * @since 1.1
+ */
+ public static void setIn(InputStream in)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+ setIn0(in);
+ }
+
+ /**
+ * Set {@link #out} to a new PrintStream. This uses some VM magic to change
+ * a "final" variable, so naturally there is a security check,
+ * <code>RuntimePermission("setIO")</code>.
+ *
+ * @param out the new PrintStream
+ * @throws SecurityException if permission is denied
+ * @since 1.1
+ */
+ public static void setOut(PrintStream out)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+
+ setOut0(out);
+ }
+
+ /**
+ * Set {@link #err} to a new PrintStream. This uses some VM magic to change
+ * a "final" variable, so naturally there is a security check,
+ * <code>RuntimePermission("setIO")</code>.
+ *
+ * @param err the new PrintStream
+ * @throws SecurityException if permission is denied
+ * @since 1.1
+ */
+ public static void setErr(PrintStream err)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setIO"));
+ setErr0(err);
+ }
+
+ /**
+ * Set the current SecurityManager. If a security manager already exists,
+ * then <code>RuntimePermission("setSecurityManager")</code> is checked
+ * first. Since this permission is denied by the default security manager,
+ * setting the security manager is often an irreversible action.
+ *
+ * @param sm the new SecurityManager
+ * @throws SecurityException if permission is denied
+ */
+ public static synchronized void setSecurityManager(SecurityManager sm)
+ {
+ // Implementation note: the field lives in SecurityManager because of
+ // bootstrap initialization issues. This method is synchronized so that
+ // no other thread changes it to null before this thread makes the change.
+ if (SecurityManager.current != null)
+ SecurityManager.current.checkPermission
+ (new RuntimePermission("setSecurityManager"));
+ SecurityManager.current = sm;
+ }
+
+ /**
+ * Get the current SecurityManager. If the SecurityManager has not been
+ * set yet, then this method returns null.
+ *
+ * @return the current SecurityManager, or null
+ */
+ public static SecurityManager getSecurityManager()
+ {
+ return SecurityManager.current;
+ }
+
+ /**
+ * 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();
+
+ /**
+ * Get the current time, measured in nanoseconds. The result is as
+ * precise as possible, and is measured against a fixed epoch.
+ * However, unlike currentTimeMillis(), the epoch chosen is
+ * arbitrary and may vary by platform, etc.
+ * @since 1.5
+ */
+ public static native long nanoTime();
+
+ /**
+ * 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
+ */
+ public 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
+ * @since 1.1
+ */
+ public static native int identityHashCode(Object o);
+
+ /**
+ * Get all the system properties at once. A security check may be performed,
+ * <code>checkPropertiesAccess</code>. Note that a security manager may
+ * allow getting a single property, but not the entire group.
+ *
+ * <p>The required properties include:
+ * <dl>
+ * <dt>java.version</dt> <dd>Java version number</dd>
+ * <dt>java.vendor</dt> <dd>Java vendor specific string</dd>
+ * <dt>java.vendor.url</dt> <dd>Java vendor URL</dd>
+ * <dt>java.home</dt> <dd>Java installation directory</dd>
+ * <dt>java.vm.specification.version</dt> <dd>VM Spec version</dd>
+ * <dt>java.vm.specification.vendor</dt> <dd>VM Spec vendor</dd>
+ * <dt>java.vm.specification.name</dt> <dd>VM Spec name</dd>
+ * <dt>java.vm.version</dt> <dd>VM implementation version</dd>
+ * <dt>java.vm.vendor</dt> <dd>VM implementation vendor</dd>
+ * <dt>java.vm.name</dt> <dd>VM implementation name</dd>
+ * <dt>java.specification.version</dt> <dd>Java Runtime Environment version</dd>
+ * <dt>java.specification.vendor</dt> <dd>Java Runtime Environment vendor</dd>
+ * <dt>java.specification.name</dt> <dd>Java Runtime Environment name</dd>
+ * <dt>java.class.version</dt> <dd>Java class version number</dd>
+ * <dt>java.class.path</dt> <dd>Java classpath</dd>
+ * <dt>java.library.path</dt> <dd>Path for finding Java libraries</dd>
+ * <dt>java.io.tmpdir</dt> <dd>Default temp file path</dd>
+ * <dt>java.compiler</dt> <dd>Name of JIT to use</dd>
+ * <dt>java.ext.dirs</dt> <dd>Java extension path</dd>
+ * <dt>os.name</dt> <dd>Operating System Name</dd>
+ * <dt>os.arch</dt> <dd>Operating System Architecture</dd>
+ * <dt>os.version</dt> <dd>Operating System Version</dd>
+ * <dt>file.separator</dt> <dd>File separator ("/" on Unix)</dd>
+ * <dt>path.separator</dt> <dd>Path separator (":" on Unix)</dd>
+ * <dt>line.separator</dt> <dd>Line separator ("\n" on Unix)</dd>
+ * <dt>user.name</dt> <dd>User account name</dd>
+ * <dt>user.home</dt> <dd>User home directory</dd>
+ * <dt>user.dir</dt> <dd>User's current working directory</dd>
+ * </dl>
+ *
+ * In addition, gnu defines several other properties, where ? stands for
+ * each character in '0' through '9':
+ * <dl>
+ * <dt>gnu.classpath.home</dt> <dd>Path to the classpath libraries.</dd>
+ * <dt>gnu.classpath.version</dt> <dd>Version of the classpath libraries.</dd>
+ * <dt>gnu.classpath.vm.shortname</dt> <dd>Succinct version of the VM name;
+ * used for finding property files in file system</dd>
+ * <dt>gnu.classpath.home.url</dt> <dd> Base URL; used for finding
+ * property files in file system</dd>
+ * <dt>gnu.cpu.endian</dt> <dd>big or little</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.ISO-8859-?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso-8859-?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso8859_?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.UTF-8</dt> <dd>UTF8</dd>
+ * <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
+ * </dl>
+ *
+ * @return the system properties, will never be null
+ * @throws SecurityException if permission is denied
+ */
+ public static Properties getProperties()
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertiesAccess();
+ return SystemProperties.getProperties();
+ }
+
+ /**
+ * Set all the system properties at once. A security check may be performed,
+ * <code>checkPropertiesAccess</code>. Note that a security manager may
+ * allow setting a single property, but not the entire group. An argument
+ * of null resets the properties to the startup default.
+ *
+ * @param properties the new set of system properties
+ * @throws SecurityException if permission is denied
+ */
+ public static void setProperties(Properties properties)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertiesAccess();
+ SystemProperties.setProperties(properties);
+ }
+
+ /**
+ * Get a single system property by name. A security check may be performed,
+ * <code>checkPropertyAccess(key)</code>.
+ *
+ * @param key the name of the system property to get
+ * @return the property, or null if not found
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ */
+ public static String getProperty(String key)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertyAccess(key);
+ else if (key.length() == 0)
+ throw new IllegalArgumentException("key can't be empty");
+ return SystemProperties.getProperty(key);
+ }
+
+ /**
+ * Get a single system property by name. A security check may be performed,
+ * <code>checkPropertyAccess(key)</code>.
+ *
+ * @param key the name of the system property to get
+ * @param def the default
+ * @return the property, or def if not found
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ */
+ public static String getProperty(String key, String def)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPropertyAccess(key);
+ return SystemProperties.getProperty(key, def);
+ }
+
+ /**
+ * Set a single system property by name. A security check may be performed,
+ * <code>checkPropertyAccess(key, "write")</code>.
+ *
+ * @param key the name of the system property to set
+ * @param value the new value
+ * @return the previous value, or null
+ * @throws SecurityException if permission is denied
+ * @throws NullPointerException if key is null
+ * @throws IllegalArgumentException if key is ""
+ * @since 1.2
+ */
+ public static String setProperty(String key, String value)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new PropertyPermission(key, "write"));
+ return SystemProperties.setProperty(key, value);
+ }
+
+ /**
+ * Gets the value of an environment variable.
+ *
+ * @param name the name of the environment variable
+ * @return the string value of the variable or null when the
+ * environment variable is not defined.
+ * @throws NullPointerException
+ * @throws SecurityException if permission is denied
+ * @since 1.5
+ * @specnote This method was deprecated in some JDK releases, but
+ * was restored in 1.5.
+ */
+ public static String getenv(String name)
+ {
+ if (name == null)
+ throw new NullPointerException();
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("getenv." + name));
+ return getenv0(name);
+ }
+
+ /**
+ * Terminate the Virtual Machine. This just calls
+ * <code>Runtime.getRuntime().exit(status)</code>, and never returns.
+ * Obviously, a security check is in order, <code>checkExit</code>.
+ *
+ * @param status the exit status; by convention non-zero is abnormal
+ * @throws SecurityException if permission is denied
+ * @see Runtime#exit(int)
+ */
+ public static void exit(int status)
+ {
+ Runtime.getRuntime().exit(status);
+ }
+
+ /**
+ * Calls the garbage collector. This is only a hint, and it is up to the
+ * implementation what this hint suggests, but it usually causes a
+ * best-effort attempt to reclaim unused memory from discarded objects.
+ * This calls <code>Runtime.getRuntime().gc()</code>.
+ *
+ * @see Runtime#gc()
+ */
+ public static void gc()
+ {
+ Runtime.getRuntime().gc();
+ }
+
+ /**
+ * Runs object finalization on pending objects. This is only a hint, and
+ * it is up to the implementation what this hint suggests, but it usually
+ * causes a best-effort attempt to run finalizers on all objects ready
+ * to be reclaimed. This calls
+ * <code>Runtime.getRuntime().runFinalization()</code>.
+ *
+ * @see Runtime#runFinalization()
+ */
+ public static void runFinalization()
+ {
+ Runtime.getRuntime().runFinalization();
+ }
+
+ /**
+ * Tell the Runtime whether to run finalization before exiting the
+ * JVM. This is inherently unsafe in multi-threaded applications,
+ * since it can force initialization on objects which are still in use
+ * by live threads, leading to deadlock; therefore this is disabled by
+ * default. There may be a security check, <code>checkExit(0)</code>. This
+ * calls <code>Runtime.getRuntime().runFinalizersOnExit()</code>.
+ *
+ * @param finalizeOnExit whether to run finalizers on exit
+ * @throws SecurityException if permission is denied
+ * @see Runtime#runFinalizersOnExit()
+ * @since 1.1
+ * @deprecated never rely on finalizers to do a clean, thread-safe,
+ * mop-up from your code
+ */
+ public static void runFinalizersOnExit(boolean finalizeOnExit)
+ {
+ Runtime.getRuntime().runFinalizersOnExit(finalizeOnExit);
+ }
+
+ /**
+ * Load a code file using its explicit system-dependent filename. A security
+ * check may be performed, <code>checkLink</code>. This just calls
+ * <code>Runtime.getRuntime().load(filename)</code>.
+ *
+ * <p>
+ * The library is loaded using the class loader associated with the
+ * class associated with the invoking method.
+ *
+ * @param filename the code file to load
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the file cannot be loaded
+ * @see Runtime#load(String)
+ */
+ public static void load(String filename)
+ {
+ Runtime.getRuntime().load(filename);
+ }
+
+ /**
+ * Load a library using its explicit system-dependent filename. A security
+ * check may be performed, <code>checkLink</code>. This just calls
+ * <code>Runtime.getRuntime().load(filename)</code>.
+ *
+ * <p>
+ * The library is loaded using the class loader associated with the
+ * class associated with the invoking method.
+ *
+ * @param libname the library file to load
+ * @throws SecurityException if permission is denied
+ * @throws UnsatisfiedLinkError if the file cannot be loaded
+ * @see Runtime#load(String)
+ */
+ public static void loadLibrary(String libname)
+ {
+ Runtime.getRuntime().loadLibrary(libname);
+ }
+
+ /**
+ * 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
+ * @since 1.2
+ */
+ public static String mapLibraryName(String libname)
+ {
+ // XXX Fix this!!!!
+ return Runtime.nativeGetLibname("", libname);
+ }
+
+ /**
+ * Set {@link #in} to a new InputStream.
+ *
+ * @param in the new InputStream
+ * @see #setIn(InputStream)
+ */
+ private static native void setIn0(InputStream in);
+
+ /**
+ * Set {@link #out} to a new PrintStream.
+ *
+ * @param out the new PrintStream
+ * @see #setOut(PrintStream)
+ */
+ private static native void setOut0(PrintStream out);
+
+ /**
+ * Set {@link #err} to a new PrintStream.
+ *
+ * @param err the new PrintStream
+ * @see #setErr(PrintStream)
+ */
+ private static native void setErr0(PrintStream err);
+
+ /**
+ * Gets the value of an environment variable.
+ *
+ * @see #getenv(String)
+ */
+ static native String getenv0(String name);
+} // class System
diff --git a/gcc-4.2.1/libjava/java/lang/Thread.java b/gcc-4.2.1/libjava/java/lang/Thread.java
new file mode 100644
index 000000000..2b7fb2aec
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Thread.java
@@ -0,0 +1,1128 @@
+/* Thread -- an independent thread of executable code
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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.gcj.RawData;
+import gnu.gcj.RawDataManaged;
+import gnu.java.util.WeakIdentityHashMap;
+import java.util.Map;
+
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete to version 1.4, with caveats. We do not
+ * implement the deprecated (and dangerous) stop, suspend, and resume
+ * methods. Security implementation is not complete.
+ */
+
+/**
+ * Thread represents a single thread of execution in the VM. When an
+ * application VM starts up, it creates a non-daemon Thread which calls the
+ * main() method of a particular class. There may be other Threads running,
+ * such as the garbage collection thread.
+ *
+ * <p>Threads have names to identify them. These names are not necessarily
+ * unique. Every Thread has a priority, as well, which tells the VM which
+ * Threads should get more running time. New threads inherit the priority
+ * and daemon status of the parent thread, by default.
+ *
+ * <p>There are two methods of creating a Thread: you may subclass Thread and
+ * implement the <code>run()</code> method, at which point you may start the
+ * Thread by calling its <code>start()</code> method, or you may implement
+ * <code>Runnable</code> in the class you want to use and then call new
+ * <code>Thread(your_obj).start()</code>.
+ *
+ * <p>The virtual machine runs until all non-daemon threads have died (either
+ * by returning from the run() method as invoked by start(), or by throwing
+ * an uncaught exception); or until <code>System.exit</code> is called with
+ * adequate permissions.
+ *
+ * <p>It is unclear at what point a Thread should be added to a ThreadGroup,
+ * and at what point it should be removed. Should it be inserted when it
+ * starts, or when it is created? Should it be removed when it is suspended
+ * or interrupted? The only thing that is clear is that the Thread should be
+ * removed when it is stopped.
+ *
+ * @author Tom Tromey
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Runnable
+ * @see Runtime#exit(int)
+ * @see #run()
+ * @see #start()
+ * @see ThreadLocal
+ * @since 1.0
+ * @status updated to 1.4
+ */
+public class Thread implements Runnable
+{
+ /** The minimum priority for a Thread. */
+ public static final int MIN_PRIORITY = 1;
+
+ /** The priority a Thread gets by default. */
+ public static final int NORM_PRIORITY = 5;
+
+ /** The maximum priority for a Thread. */
+ public static final int MAX_PRIORITY = 10;
+
+ /**
+ * The group this thread belongs to. This is set to null by
+ * ThreadGroup.removeThread when the thread dies.
+ */
+ ThreadGroup group;
+
+ /** The object to run(), null if this is the target. */
+ private Runnable runnable;
+
+ /** The thread name, non-null. */
+ String name;
+
+ /** Whether the thread is a daemon. */
+ private boolean daemon;
+
+ /** The thread priority, 1 to 10. */
+ private int priority;
+
+ boolean interrupt_flag;
+ private boolean alive_flag;
+ private boolean startable_flag;
+
+ /** The context classloader for this Thread. */
+ private ClassLoader contextClassLoader;
+
+ /** This thread's ID. */
+ private final long threadId;
+
+ /** The next thread ID to use. */
+ private static long nextThreadId;
+
+ /** The default exception handler. */
+ private static UncaughtExceptionHandler defaultHandler;
+
+ /** Thread local storage. Package accessible for use by
+ * InheritableThreadLocal.
+ */
+ WeakIdentityHashMap locals;
+
+ /** The uncaught exception handler. */
+ UncaughtExceptionHandler exceptionHandler;
+
+ /** The access control state for this thread. Package accessible
+ * for use by java.security.VMAccessControlState's native method.
+ */
+ Object accessControlState = null;
+
+ // This describes the top-most interpreter frame for this thread.
+ RawData interp_frame;
+
+ // Our native data - points to an instance of struct natThread.
+ private RawDataManaged data;
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null,</code>
+ * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ * <p>
+ * Threads created this way must have overridden their
+ * <code>run()</code> method to actually do anything. An example
+ * illustrating this method being used follows:
+ * <p><blockquote><pre>
+ * import java.lang.*;
+ *
+ * class plain01 implements Runnable {
+ * String name;
+ * plain01() {
+ * name = null;
+ * }
+ * plain01(String s) {
+ * name = s;
+ * }
+ * public void run() {
+ * if (name == null)
+ * System.out.println("A new thread created");
+ * else
+ * System.out.println("A new thread with name " + name +
+ * " created");
+ * }
+ * }
+ * class threadtest01 {
+ * public static void main(String args[] ) {
+ * int failed = 0 ;
+ *
+ * <b>Thread t1 = new Thread();</b>
+ * if (t1 != null)
+ * System.out.println("new Thread() succeed");
+ * else {
+ * System.out.println("new Thread() failed");
+ * failed++;
+ * }
+ * }
+ * }
+ * </pre></blockquote>
+ *
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread()
+ {
+ this(null, null, gen_name());
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param target the object whose <code>run</code> method is called.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread(Runnable target)
+ {
+ this(null, target, gen_name());
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, null, name)</code>.
+ *
+ * @param name the name of the new thread.
+ * @see java.lang.Thread#Thread(java.lang.ThreadGroup,
+ * java.lang.Runnable, java.lang.String)
+ */
+ public Thread(String name)
+ {
+ this(null, null, name);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, target,</code>
+ * <i>gname</i><code>)</code>, where <i>gname</i> is
+ * a newly generated name. Automatically generated names are of the
+ * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(ThreadGroup group, Runnable target)
+ {
+ this(group, target, gen_name());
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(group, null, name)</code>
+ *
+ * @param group the group to put the Thread into
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(ThreadGroup group, String name)
+ {
+ this(group, null, name);
+ }
+
+ /**
+ * Allocates a new <code>Thread</code> object. This constructor has
+ * the same effect as <code>Thread(null, target, name)</code>.
+ *
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public Thread(Runnable target, String name)
+ {
+ this(null, target, name);
+ }
+
+ /**
+ * Allocate a new Thread object, with the specified ThreadGroup and name, and
+ * using the specified Runnable object's <code>run()</code> method to
+ * execute. If the Runnable object is null, <code>this</code> (which is
+ * a Runnable) is used instead.
+ *
+ * <p>If the ThreadGroup is null, the security manager is checked. If a
+ * manager exists and returns a non-null object for
+ * <code>getThreadGroup</code>, that group is used; otherwise the group
+ * of the creating thread is used. Note that the security manager calls
+ * <code>checkAccess</code> if the ThreadGroup is not null.
+ *
+ * <p>The new Thread will inherit its creator's priority and daemon status.
+ * These can be changed with <code>setPriority</code> and
+ * <code>setDaemon</code>.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @see Runnable#run()
+ * @see #run()
+ * @see #setDaemon(boolean)
+ * @see #setPriority(int)
+ * @see SecurityManager#checkAccess(ThreadGroup)
+ * @see ThreadGroup#checkAccess()
+ */
+ public Thread(ThreadGroup group, Runnable target, String name)
+ {
+ this(currentThread(), group, target, name);
+ }
+
+ /**
+ * Allocate a new Thread object, as if by
+ * <code>Thread(group, null, name)</code>, and give it the specified stack
+ * size, in bytes. The stack size is <b>highly platform independent</b>,
+ * and the virtual machine is free to round up or down, or ignore it
+ * completely. A higher value might let you go longer before a
+ * <code>StackOverflowError</code>, while a lower value might let you go
+ * longer before an <code>OutOfMemoryError</code>. Or, it may do absolutely
+ * nothing! So be careful, and expect to need to tune this value if your
+ * virtual machine even supports it.
+ *
+ * @param group the group to put the Thread into
+ * @param target the Runnable object to execute
+ * @param name the name for the Thread
+ * @param size the stack size, in bytes; 0 to be ignored
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if this thread cannot access <code>group</code>
+ * @throws IllegalThreadStateException if group is destroyed
+ * @since 1.4
+ */
+ public Thread(ThreadGroup group, Runnable target, String name, long size)
+ {
+ // Just ignore stackSize for now.
+ this(currentThread(), group, target, name);
+ }
+
+ private Thread (Thread current, ThreadGroup g, Runnable r, String n)
+ {
+ // Make sure the current thread may create a new thread.
+ checkAccess();
+
+ // The Class Libraries book says ``threadName cannot be null''. I
+ // take this to mean NullPointerException.
+ if (n == null)
+ throw new NullPointerException ();
+
+ if (g == null)
+ {
+ // If CURRENT is null, then we are bootstrapping the first thread.
+ // Use ThreadGroup.root, the main threadgroup.
+ if (current == null)
+ group = ThreadGroup.root;
+ else
+ group = current.getThreadGroup();
+ }
+ else
+ group = g;
+
+ data = null;
+ interrupt_flag = false;
+ alive_flag = false;
+ startable_flag = true;
+
+ synchronized (Thread.class)
+ {
+ this.threadId = nextThreadId++;
+ }
+
+ if (current != null)
+ {
+ group.checkAccess();
+
+ daemon = current.isDaemon();
+ int gmax = group.getMaxPriority();
+ int pri = current.getPriority();
+ priority = (gmax < pri ? gmax : pri);
+ contextClassLoader = current.contextClassLoader;
+ InheritableThreadLocal.newChildThread(this);
+ }
+ else
+ {
+ daemon = false;
+ priority = NORM_PRIORITY;
+ }
+
+ name = n;
+ group.addThread(this);
+ runnable = r;
+
+ initialize_native ();
+ }
+
+ /**
+ * Get the number of active threads in the current Thread's ThreadGroup.
+ * This implementation calls
+ * <code>currentThread().getThreadGroup().activeCount()</code>.
+ *
+ * @return the number of active threads in the current ThreadGroup
+ * @see ThreadGroup#activeCount()
+ */
+ public static int activeCount()
+ {
+ return currentThread().group.activeCount();
+ }
+
+ /**
+ * Check whether the current Thread is allowed to modify this Thread. This
+ * passes the check on to <code>SecurityManager.checkAccess(this)</code>.
+ *
+ * @throws SecurityException if the current Thread cannot modify this Thread
+ * @see SecurityManager#checkAccess(Thread)
+ */
+ public final void checkAccess()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkAccess(this);
+ }
+
+ /**
+ * Count the number of stack frames in this Thread. The Thread in question
+ * must be suspended when this occurs.
+ *
+ * @return the number of stack frames in this Thread
+ * @throws IllegalThreadStateException if this Thread is not suspended
+ * @deprecated pointless, since suspend is deprecated
+ */
+ public native int countStackFrames();
+
+ /**
+ * Get the currently executing Thread.
+ *
+ * @return the currently executing Thread
+ */
+ public static native Thread currentThread();
+
+ /**
+ * Originally intended to destroy this thread, this method was never
+ * implemented by Sun, and is hence a no-op.
+ */
+ public void destroy()
+ {
+ throw new NoSuchMethodError();
+ }
+
+ /**
+ * Print a stack trace of the current thread to stderr using the same
+ * format as Throwable's printStackTrace() method.
+ *
+ * @see Throwable#printStackTrace()
+ */
+ public static void dumpStack()
+ {
+ (new Exception("Stack trace")).printStackTrace();
+ }
+
+ /**
+ * Copy every active thread in the current Thread's ThreadGroup into the
+ * array. Extra threads are silently ignored. This implementation calls
+ * <code>getThreadGroup().enumerate(array)</code>, which may have a
+ * security check, <code>checkAccess(group)</code>.
+ *
+ * @param array the array to place the Threads into
+ * @return the number of Threads placed into the array
+ * @throws NullPointerException if array is null
+ * @throws SecurityException if you cannot access the ThreadGroup
+ * @see ThreadGroup#enumerate(Thread[])
+ * @see #activeCount()
+ * @see SecurityManager#checkAccess(ThreadGroup)
+ */
+ public static int enumerate(Thread[] array)
+ {
+ return currentThread().group.enumerate(array);
+ }
+
+ /**
+ * Get this Thread's name.
+ *
+ * @return this Thread's name
+ */
+ public final String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Get this Thread's priority.
+ *
+ * @return the Thread's priority
+ */
+ public final int getPriority()
+ {
+ return priority;
+ }
+
+ /**
+ * Get the ThreadGroup this Thread belongs to. If the thread has died, this
+ * returns null.
+ *
+ * @return this Thread's ThreadGroup
+ */
+ public final ThreadGroup getThreadGroup()
+ {
+ return group;
+ }
+
+ /**
+ * 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 test lock ownership on.
+ * @return true if the current thread is currently synchronized on obj
+ * @throws NullPointerException if obj is null
+ * @since 1.4
+ */
+ public static native boolean holdsLock(Object obj);
+
+ /**
+ * Interrupt this Thread. First, there is a security check,
+ * <code>checkAccess</code>. Then, depending on the current state of the
+ * thread, various actions take place:
+ *
+ * <p>If the thread is waiting because of {@link #wait()},
+ * {@link #sleep(long)}, or {@link #join()}, its <i>interrupt status</i>
+ * will be cleared, and an InterruptedException will be thrown. Notice that
+ * this case is only possible if an external thread called interrupt().
+ *
+ * <p>If the thread is blocked in an interruptible I/O operation, in
+ * {@link java.nio.channels.InterruptibleChannel}, the <i>interrupt
+ * status</i> will be set, and ClosedByInterruptException will be thrown.
+ *
+ * <p>If the thread is blocked on a {@link java.nio.channels.Selector}, the
+ * <i>interrupt status</i> will be set, and the selection will return, with
+ * a possible non-zero value, as though by the wakeup() method.
+ *
+ * <p>Otherwise, the interrupt status will be set.
+ *
+ * @throws SecurityException if you cannot modify this Thread
+ */
+ public native void interrupt();
+
+ /**
+ * 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
+ * @see #isInterrupted()
+ */
+ public static boolean interrupted()
+ {
+ return currentThread().isInterrupted(true);
+ }
+
+ /**
+ * Determine whether the given Thread has been interrupted, but leave
+ * the <i>interrupted status</i> alone in the process.
+ *
+ * @return whether the Thread has been interrupted
+ * @see #interrupted()
+ */
+ public boolean isInterrupted()
+ {
+ return interrupt_flag;
+ }
+
+ /**
+ * Determine whether this Thread is alive. A thread which is alive has
+ * started and not yet died.
+ *
+ * @return whether this Thread is alive
+ */
+ public final synchronized boolean isAlive()
+ {
+ return alive_flag;
+ }
+
+ /**
+ * Tell whether this is a daemon Thread or not.
+ *
+ * @return whether this is a daemon Thread or not
+ * @see #setDaemon(boolean)
+ */
+ public final boolean isDaemon()
+ {
+ return daemon;
+ }
+
+ /**
+ * Wait forever for the Thread in question to die.
+ *
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ */
+ public final void join() throws InterruptedException
+ {
+ join(0, 0);
+ }
+
+ /**
+ * Wait the specified amount of time for the Thread in question to die.
+ *
+ * @param ms the number of milliseconds to wait, or 0 for forever
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ */
+ public final void join(long ms) throws InterruptedException
+ {
+ join(ms, 0);
+ }
+
+ /**
+ * 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
+ * @throws IllegalArgumentException if ns is invalid
+ * @XXX A ThreadListener would be nice, to make this efficient.
+ */
+ public final native void join(long ms, int ns)
+ throws InterruptedException;
+
+ /**
+ * Resume a suspended thread.
+ *
+ * @throws SecurityException if you cannot resume the Thread
+ * @see #checkAccess()
+ * @see #suspend()
+ * @deprecated pointless, since suspend is deprecated
+ */
+ public final native void resume();
+
+ private final native void finish_();
+
+ /**
+ * Determine whether the given Thread has been interrupted, but leave
+ * the <i>interrupted status</i> alone in the process.
+ *
+ * @return whether the current Thread has been interrupted
+ * @see #interrupted()
+ */
+ private boolean isInterrupted(boolean clear_flag)
+ {
+ boolean r = interrupt_flag;
+ if (clear_flag && r)
+ {
+ // Only clear the flag if we saw it as set. Otherwise this could
+ // potentially cause us to miss an interrupt in a race condition,
+ // because this method is not synchronized.
+ interrupt_flag = false;
+ }
+ return r;
+ }
+
+ /**
+ * The method of Thread that will be run if there is no Runnable object
+ * associated with the Thread. Thread's implementation does nothing at all.
+ *
+ * @see #start()
+ * @see #Thread(ThreadGroup, Runnable, String)
+ */
+ public void run()
+ {
+ if (runnable != null)
+ runnable.run();
+ }
+
+ /**
+ * Set the daemon status of this Thread. If this is a daemon Thread, then
+ * the VM may exit even if it is still running. This may only be called
+ * before the Thread starts running. There may be a security check,
+ * <code>checkAccess</code>.
+ *
+ * @param daemon whether this should be a daemon thread or not
+ * @throws SecurityException if you cannot modify this Thread
+ * @throws IllegalThreadStateException if the Thread is active
+ * @see #isDaemon()
+ * @see #checkAccess()
+ */
+ public final void setDaemon(boolean daemon)
+ {
+ if (!startable_flag)
+ throw new IllegalThreadStateException();
+ checkAccess();
+ this.daemon = daemon;
+ }
+
+ /**
+ * Returns the context classloader of this Thread. The context
+ * classloader can be used by code that want to load classes depending
+ * on the current thread. Normally classes are loaded depending on
+ * the classloader of the current class. There may be a security check
+ * for <code>RuntimePermission("getClassLoader")</code> if the caller's
+ * class loader is not null or an ancestor of this thread's context class
+ * loader.
+ *
+ * @return the context class loader
+ * @throws SecurityException when permission is denied
+ * @see setContextClassLoader(ClassLoader)
+ * @since 1.2
+ */
+ public synchronized ClassLoader getContextClassLoader()
+ {
+ if (contextClassLoader == null)
+ contextClassLoader = ClassLoader.getSystemClassLoader();
+
+ SecurityManager sm = System.getSecurityManager();
+ // FIXME: we can't currently find the caller's class loader.
+ ClassLoader callers = null;
+ if (sm != null && callers != null)
+ {
+ // See if the caller's class loader is the same as or an
+ // ancestor of this thread's class loader.
+ while (callers != null && callers != contextClassLoader)
+ {
+ // FIXME: should use some internal version of getParent
+ // that avoids security checks.
+ callers = callers.getParent();
+ }
+
+ if (callers != contextClassLoader)
+ sm.checkPermission(new RuntimePermission("getClassLoader"));
+ }
+
+ return contextClassLoader;
+ }
+
+ /**
+ * Sets the context classloader for this Thread. When not explicitly set,
+ * the context classloader for a thread is the same as the context
+ * classloader of the thread that created this thread. The first thread has
+ * as context classloader the system classloader. There may be a security
+ * check for <code>RuntimePermission("setContextClassLoader")</code>.
+ *
+ * @param classloader the new context class loader
+ * @throws SecurityException when permission is denied
+ * @see getContextClassLoader()
+ * @since 1.2
+ */
+ public synchronized void setContextClassLoader(ClassLoader classloader)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+ this.contextClassLoader = classloader;
+ }
+
+ /**
+ * Set this Thread's name. There may be a security check,
+ * <code>checkAccess</code>.
+ *
+ * @param name the new name for this Thread
+ * @throws NullPointerException if name is null
+ * @throws SecurityException if you cannot modify this Thread
+ */
+ public final void setName(String name)
+ {
+ checkAccess();
+ // The Class Libraries book says ``threadName cannot be null''. I
+ // take this to mean NullPointerException.
+ if (name == null)
+ throw new NullPointerException();
+ this.name = name;
+ }
+
+ /**
+ * Causes the currently executing thread object to temporarily pause
+ * and allow other threads to execute.
+ */
+ public 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.
+ *
+ * @param ms the number of milliseconds to sleep, or 0 for forever
+ * @throws InterruptedException if the Thread is interrupted; it's
+ * <i>interrupted status</i> will be cleared
+ * @see #notify()
+ * @see #wait(long)
+ */
+ public static void sleep(long ms) throws InterruptedException
+ {
+ sleep(ms, 0);
+ }
+
+ /**
+ * 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, 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
+ * @throws IllegalArgumentException if ns is invalid
+ * @see #notify()
+ * @see #wait(long, int)
+ */
+ public static native void sleep(long timeout, int nanos)
+ throws InterruptedException;
+
+ /**
+ * Start this Thread, calling the run() method of the Runnable this Thread
+ * was created with, or else the run() method of the Thread itself. This
+ * is the only way to start a new thread; calling run by yourself will just
+ * stay in the same thread. The virtual machine will remove the thread from
+ * its thread group when the run() method completes.
+ *
+ * @throws IllegalThreadStateException if the thread has already started
+ * @see #run()
+ */
+ public native void start();
+
+ /**
+ * Cause this Thread to stop abnormally because of the throw of a ThreadDeath
+ * error. If you stop a Thread that has not yet started, it will stop
+ * immediately when it is actually started.
+ *
+ * <p>This is inherently unsafe, as it can interrupt synchronized blocks and
+ * leave data in bad states. Hence, there is a security check:
+ * <code>checkAccess(this)</code>, plus another one if the current thread
+ * is not this: <code>RuntimePermission("stopThread")</code>. If you must
+ * catch a ThreadDeath, be sure to rethrow it after you have cleaned up.
+ * ThreadDeath is the only exception which does not print a stack trace when
+ * the thread dies.
+ *
+ * @throws SecurityException if you cannot stop the Thread
+ * @see #interrupt()
+ * @see #checkAccess()
+ * @see #start()
+ * @see ThreadDeath
+ * @see ThreadGroup#uncaughtException(Thread, Throwable)
+ * @see SecurityManager#checkAccess(Thread)
+ * @see SecurityManager#checkPermission(Permission)
+ * @deprecated unsafe operation, try not to use
+ */
+ public final void stop()
+ {
+ // Argument doesn't matter, because this is no longer
+ // supported.
+ stop(null);
+ }
+
+ /**
+ * Cause this Thread to stop abnormally and throw the specified exception.
+ * If you stop a Thread that has not yet started, it will stop immediately
+ * when it is actually started. <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. Hence, there is a security check:
+ * <code>checkAccess(this)</code>, plus another one if the current thread
+ * is not this: <code>RuntimePermission("stopThread")</code>. If you must
+ * catch a ThreadDeath, be sure to rethrow it after you have cleaned up.
+ * ThreadDeath is the only exception which does not print a stack trace when
+ * the thread dies.
+ *
+ * @param t the Throwable to throw when the Thread dies
+ * @throws SecurityException if you cannot stop the Thread
+ * @throws NullPointerException in the calling thread, if t is null
+ * @see #interrupt()
+ * @see #checkAccess()
+ * @see #start()
+ * @see ThreadDeath
+ * @see ThreadGroup#uncaughtException(Thread, Throwable)
+ * @see SecurityManager#checkAccess(Thread)
+ * @see SecurityManager#checkPermission(Permission)
+ * @deprecated unsafe operation, try not to use
+ */
+ public final native void stop(Throwable t);
+
+ /**
+ * Suspend this Thread. It will not come back, ever, unless it is resumed.
+ *
+ * <p>This is inherently unsafe, as the suspended thread still holds locks,
+ * and can potentially deadlock your program. Hence, there is a security
+ * check: <code>checkAccess</code>.
+ *
+ * @throws SecurityException if you cannot suspend the Thread
+ * @see #checkAccess()
+ * @see #resume()
+ * @deprecated unsafe operation, try not to use
+ */
+ public final native void suspend();
+
+ /**
+ * Set this Thread's priority. There may be a security check,
+ * <code>checkAccess</code>, then the priority is set to the smaller of
+ * priority and the ThreadGroup maximum priority.
+ *
+ * @param priority the new priority for this Thread
+ * @throws IllegalArgumentException if priority exceeds MIN_PRIORITY or
+ * MAX_PRIORITY
+ * @throws SecurityException if you cannot modify this Thread
+ * @see #getPriority()
+ * @see #checkAccess()
+ * @see ThreadGroup#getMaxPriority()
+ * @see #MIN_PRIORITY
+ * @see #MAX_PRIORITY
+ */
+ public final native void setPriority(int newPriority);
+
+ /**
+ * Returns a string representation of this thread, including the
+ * thread's name, priority, and thread group.
+ *
+ * @return a human-readable String representing this Thread
+ */
+ public String toString()
+ {
+ return ("Thread[" + name + "," + priority + ","
+ + (group == null ? "" : group.getName()) + "]");
+ }
+
+ private final native void initialize_native();
+
+ private final native static String gen_name();
+
+ /**
+ * Returns the map used by ThreadLocal to store the thread local values.
+ */
+ static Map getThreadLocals()
+ {
+ Thread thread = currentThread();
+ Map locals = thread.locals;
+ if (locals == null)
+ {
+ locals = thread.locals = new WeakIdentityHashMap();
+ }
+ return locals;
+ }
+
+ /**
+ * Assigns the given <code>UncaughtExceptionHandler</code> to this
+ * thread. This will then be called if the thread terminates due
+ * to an uncaught exception, pre-empting that of the
+ * <code>ThreadGroup</code>.
+ *
+ * @param h the handler to use for this thread.
+ * @throws SecurityException if the current thread can't modify this thread.
+ * @since 1.5
+ */
+ public void setUncaughtExceptionHandler(UncaughtExceptionHandler h)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkAccess(this);
+ exceptionHandler = h;
+ }
+
+ /**
+ * <p>
+ * Returns the handler used when this thread terminates due to an
+ * uncaught exception. The handler used is determined by the following:
+ * </p>
+ * <ul>
+ * <li>If this thread has its own handler, this is returned.</li>
+ * <li>If not, then the handler of the thread's <code>ThreadGroup</code>
+ * object is returned.</li>
+ * <li>If both are unavailable, then <code>null</code> is returned
+ * (which can only happen when the thread was terminated since
+ * then it won't have an associated thread group anymore).</li>
+ * </ul>
+ *
+ * @return the appropriate <code>UncaughtExceptionHandler</code> or
+ * <code>null</code> if one can't be obtained.
+ * @since 1.5
+ */
+ public UncaughtExceptionHandler getUncaughtExceptionHandler()
+ {
+ return exceptionHandler != null ? exceptionHandler : group;
+ }
+
+ /**
+ * <p>
+ * Sets the default uncaught exception handler used when one isn't
+ * provided by the thread or its associated <code>ThreadGroup</code>.
+ * This exception handler is used when the thread itself does not
+ * have an exception handler, and the thread's <code>ThreadGroup</code>
+ * does not override this default mechanism with its own. As the group
+ * calls this handler by default, this exception handler should not defer
+ * to that of the group, as it may lead to infinite recursion.
+ * </p>
+ * <p>
+ * Uncaught exception handlers are used when a thread terminates due to
+ * an uncaught exception. Replacing this handler allows default code to
+ * be put in place for all threads in order to handle this eventuality.
+ * </p>
+ *
+ * @param h the new default uncaught exception handler to use.
+ * @throws SecurityException if a security manager is present and
+ * disallows the runtime permission
+ * "setDefaultUncaughtExceptionHandler".
+ * @since 1.5
+ */
+ public static void
+ setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler h)
+ {
+ SecurityManager sm = SecurityManager.current; // Be thread-safe.
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("setDefaultUncaughtExceptionHandler"));
+ defaultHandler = h;
+ }
+
+ /**
+ * Returns the handler used by default when a thread terminates
+ * unexpectedly due to an exception, or <code>null</code> if one doesn't
+ * exist.
+ *
+ * @return the default uncaught exception handler.
+ * @since 1.5
+ */
+ public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
+ {
+ return defaultHandler;
+ }
+
+ /**
+ * Returns the unique identifier for this thread. This ID is generated
+ * on thread creation, and may be re-used on its death.
+ *
+ * @return a positive long number representing the thread's ID.
+ * @since 1.5
+ */
+ public long getId()
+ {
+ return threadId;
+ }
+
+ /**
+ * <p>
+ * This interface is used to handle uncaught exceptions
+ * which cause a <code>Thread</code> to terminate. When
+ * a thread, t, is about to terminate due to an uncaught
+ * exception, the virtual machine looks for a class which
+ * implements this interface, in order to supply it with
+ * the dying thread and its uncaught exception.
+ * </p>
+ * <p>
+ * The virtual machine makes two attempts to find an
+ * appropriate handler for the uncaught exception, in
+ * the following order:
+ * </p>
+ * <ol>
+ * <li>
+ * <code>t.getUncaughtExceptionHandler()</code> --
+ * the dying thread is queried first for a handler
+ * specific to that thread.
+ * </li>
+ * <li>
+ * <code>t.getThreadGroup()</code> --
+ * the thread group of the dying thread is used to
+ * handle the exception. If the thread group has
+ * no special requirements for handling the exception,
+ * it may simply forward it on to
+ * <code>Thread.getDefaultUncaughtExceptionHandler()</code>,
+ * the default handler, which is used as a last resort.
+ * </li>
+ * </ol>
+ * <p>
+ * The first handler found is the one used to handle
+ * the uncaught exception.
+ * </p>
+ *
+ * @author Tom Tromey <tromey@redhat.com>
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
+ * @since 1.5
+ * @see Thread#getUncaughtExceptionHandler()
+ * @see Thread#setUncaughtExceptionHander(java.lang.Thread.UncaughtExceptionHandler)
+ * @see Thread#getDefaultUncaughtExceptionHandler()
+ * @see
+ * Thread#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)
+ */
+ public interface UncaughtExceptionHandler
+ {
+ /**
+ * Invoked by the virtual machine with the dying thread
+ * and the uncaught exception. Any exceptions thrown
+ * by this method are simply ignored by the virtual
+ * machine.
+ *
+ * @param thr the dying thread.
+ * @param exc the uncaught exception.
+ */
+ void uncaughtException(Thread thr, Throwable exc);
+ }
+
+ /**
+ * Returns the current state of the thread. This
+ * is designed for monitoring thread behaviour, rather
+ * than for synchronization control.
+ *
+ * @return the current thread state.
+ */
+ public String getState()
+ {
+ // FIXME - Provide real implementation.
+ return "NEW";
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/VMClassLoader.java b/gcc-4.2.1/libjava/java/lang/VMClassLoader.java
new file mode 100644
index 000000000..21019b757
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/VMClassLoader.java
@@ -0,0 +1,348 @@
+/* VMClassLoader.java -- Reference implementation of native interface
+ required by ClassLoader
+ Copyright (C) 1998, 2001, 2002, 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;
+
+import gnu.java.util.EmptyEnumeration;
+import java.lang.reflect.Constructor;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.StringTokenizer;
+import gnu.gcj.runtime.BootClassLoader;
+
+/**
+ * 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
+{
+ // Protection Domain definitions
+ // FIXME: should there be a special protection domain used for native code?
+
+ // The permission required to check what a classes protection domain is.
+ static final Permission protectionDomainPermission
+ = new RuntimePermission("getProtectionDomain");
+ // The protection domain returned if we cannot determine it.
+ static ProtectionDomain unknownProtectionDomain;
+
+ static
+ {
+ Permissions permissions = new Permissions();
+ permissions.add(new AllPermission());
+ unknownProtectionDomain = new ProtectionDomain(null, permissions);
+ }
+
+ static final HashMap definedPackages = new HashMap();
+
+ // This is a helper for handling java.endorsed.dirs. It is null
+ // until we've initialized the system, at which point it is created.
+ static BootClassLoader bootLoader;
+
+ // This keeps track of shared libraries we've already tried to load.
+ private static HashSet tried_libraries;
+
+ // Holds one of the LIB_* constants; used to determine how shared
+ // library loads are done.
+ private static int lib_control;
+
+ private static final int LIB_FULL = 0;
+ private static final int LIB_CACHE = 1;
+ private static final int LIB_NEVER = 2;
+
+ /**
+ * Helper to define a class using a string of bytes. This assumes that
+ * the security checks have already been performed, if necessary.
+ *
+ * <strong>For backward compatibility, this just ignores the protection
+ * domain; that is the wrong behavior, and you should directly implement
+ * this method natively if you can.</strong>
+ *
+ * @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 void resolveClass(Class clazz)
+ {
+ // There doesn't seem to be a need for this to do anything.
+ // Testing reveals that the JDK doesn't seem to do anything here,
+ // either.
+ }
+
+ /**
+ * 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.
+ *
+ * In libgcj, this does nothing, as the default system loader knows
+ * how to find resources that have been linked in.
+ *
+ * @param name the resource to find
+ * @return the URL to the resource
+ */
+ static URL getResource(String name)
+ {
+ if (bootLoader != null)
+ return bootLoader.bootGetResource(name);
+ return null;
+ }
+
+ /**
+ * Helper to get a list of resources from the bootstrap class loader.
+ *
+ * In libgcj, this does nothing, as the default system loader knows
+ * how to find resources that have been linked in.
+ *
+ * @param name the resource to find
+ * @return an enumeration of resources
+ * @throws IOException if one occurs
+ */
+ static Enumeration getResources(String name) throws IOException
+ {
+ if (bootLoader != null)
+ return bootLoader.bootGetResources(name);
+ return EmptyEnumeration.getInstance();
+ }
+
+ /**
+ * 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 synchronized Package getPackage(String name)
+ {
+ return (Package) definedPackages.get(name);
+ }
+
+ /**
+ * 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 synchronized Package[] getPackages()
+ {
+ Package[] packages = new Package[definedPackages.size()];
+ return (Package[]) definedPackages.values().toArray(packages);
+ }
+
+ // Define a package for something loaded natively.
+ static synchronized void definePackageForNative(String className)
+ {
+ int lastDot = className.lastIndexOf('.');
+ if (lastDot != -1)
+ {
+ String packageName = className.substring(0, lastDot);
+ if (getPackage(packageName) == null)
+ {
+ // FIXME: this assumes we're defining the core, which
+ // isn't necessarily so. We could detect this and set up
+ // appropriately. We could also look at a manifest file
+ // compiled into the .so.
+ Package p = new Package(packageName,
+ "Java Platform API Specification",
+ "GNU", "1.4", "gcj", "GNU",
+ null, // FIXME: gcj version.
+ null);
+ definedPackages.put(packageName, p);
+ }
+ }
+ }
+
+ /**
+ * 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 native ClassLoader getSystemClassLoaderInternal();
+
+ static native void initBootLoader(String libdir);
+
+ static void initialize(String libdir)
+ {
+ initBootLoader(libdir);
+
+ String p
+ = System.getProperty ("gnu.gcj.runtime.VMClassLoader.library_control",
+ "");
+ if ("never".equals(p))
+ lib_control = LIB_NEVER;
+ else if ("cache".equals(p))
+ lib_control = LIB_CACHE;
+ else if ("full".equals(p))
+ lib_control = LIB_FULL;
+ else
+ lib_control = LIB_NEVER;
+
+ tried_libraries = new HashSet();
+ }
+
+ /**
+ * Possibly load a .so and search it for classes.
+ */
+ static native Class nativeFindClass(String name);
+
+ static ClassLoader getSystemClassLoader()
+ {
+ // This method is called as the initialization of systemClassLoader,
+ // so if there is a null value, this is the first call and we must check
+ // for java.system.class.loader.
+ String loader = System.getProperty("java.system.class.loader");
+ ClassLoader default_sys = getSystemClassLoaderInternal();
+ if (loader != null)
+ {
+ try
+ {
+ Class load_class = Class.forName(loader, true, default_sys);
+ Constructor c
+ = load_class.getConstructor(new Class[] { ClassLoader.class });
+ default_sys
+ = (ClassLoader) c.newInstance(new Object[] { default_sys });
+ }
+ catch (Exception ex)
+ {
+ throw new Error("Failed to load requested system classloader "
+ + loader, ex);
+ }
+ }
+
+ return default_sys;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/VMCompiler.java b/gcc-4.2.1/libjava/java/lang/VMCompiler.java
new file mode 100644
index 000000000..789445e4f
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/VMCompiler.java
@@ -0,0 +1,360 @@
+/* VMClassLoader.java -- Reference implementation of compiler interface
+ Copyright (C) 2004, 2005, 2006 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.FileOutputStream;
+import java.io.InputStreamReader;
+import java.security.MessageDigest;
+import java.security.ProtectionDomain;
+import java.security.NoSuchAlgorithmException;
+import java.util.WeakHashMap;
+import java.util.HashSet;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import gnu.gcj.runtime.SharedLibHelper;
+import gnu.gcj.runtime.PersistentByteMap;
+import gnu.java.security.hash.MD5;
+
+/**
+ * This class is just a per-VM reflection of java.lang.Compiler.
+ * All methods are defined identically.
+ */
+final class VMCompiler
+{
+ // True if we want to use gcj-jit.
+ public static boolean useCompiler = true;
+
+ // True if we're able to use gcj-jit.
+ public static final boolean canUseCompiler;
+
+ // Compiler to use.
+ public static String gcjJitCompiler;
+
+ // Compiler options.
+ public static String gcjJitCompilerOptions;
+
+ // Temporary directory to use.
+ public static String gcjJitTmpdir;
+
+ // This maps a ClassLoader to a set of SharedLibHelper objects that
+ // it has used. We do things this way to ensure that a
+ // SharedLibHelper is collected if and only if the ClassLoader is.
+ private static WeakHashMap sharedHelperMap = new WeakHashMap();
+
+ private static Vector precompiledMapFiles;
+
+ // We create a single MD5 engine and then clone it whenever we want
+ // a new one.
+
+ // We don't use
+ //
+ // md5Digest = MessageDigest.getInstance("MD5");
+ //
+ // here because that loads a great deal of security provider code as
+ // interpreted bytecode -- before we're able to use this class to
+ // load precompiled classes.
+
+ private static final MD5 md5Digest
+ = new gnu.java.security.hash.MD5();
+
+ static
+ {
+ gcjJitCompiler = System.getProperty("gnu.gcj.jit.compiler");
+ if (gcjJitCompiler == null)
+ canUseCompiler = false;
+ else
+ {
+ gcjJitCompilerOptions = System.getProperty("gnu.gcj.jit.options",
+ "-g");
+ gcjJitTmpdir = System.getProperty("gnu.gcj.jit.cachedir");
+ // Note that we *don't* choose java.io.tmpdir as a default --
+ // that would allow easy attacks against the VM.
+ if (gcjJitTmpdir == null)
+ canUseCompiler = false;
+ else
+ canUseCompiler = true;
+ }
+
+ String prop = System.getProperty ("gnu.gcj.precompiled.db.path");
+ if (prop != null)
+ {
+ precompiledMapFiles = new Vector();
+ // Add the
+ StringTokenizer st
+ = new StringTokenizer (prop,
+ System.getProperty ("path.separator", ":"));
+ {
+ while (st.hasMoreElements ())
+ {
+ String e = st.nextToken ();
+ try
+ {
+ PersistentByteMap map
+ = new PersistentByteMap
+ (e, PersistentByteMap.AccessMode.READ_ONLY);
+ precompiledMapFiles.add(map);
+ }
+ catch (IllegalArgumentException _)
+ {
+ // Not a map file
+ }
+ catch (java.io.IOException _)
+ {
+ }
+ catch (java.nio.BufferUnderflowException _)
+ {
+ // Invalid map file.
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Don't allow new `Compiler's to be made.
+ */
+ private VMCompiler()
+ {
+ }
+
+ private static Class loadSharedLibrary(ClassLoader loader,
+ String fileName,
+ ProtectionDomain domain,
+ String className)
+ {
+ Class c = null;
+ SharedLibHelper helper
+ = SharedLibHelper.findHelper (loader, fileName, domain.getCodeSource(),
+ domain, false);
+ c = helper.findClass (className);
+ if (c != null)
+ {
+ HashSet hs = (HashSet) sharedHelperMap.get(loader);
+ if (hs == null)
+ {
+ hs = new HashSet();
+ sharedHelperMap.put(loader, hs);
+ }
+ hs.add(helper);
+ }
+ return c;
+ }
+
+ /**
+ * Compile a class given the bytes for it. Returns the Class, or
+ * null if compilation failed or otherwise could not be done.
+ */
+ public static Class compileClass(ClassLoader loader,
+ String name, byte[] data,
+ int offset, int len,
+ ProtectionDomain domain)
+ {
+ if (precompiledMapFiles == null
+ && (! useCompiler || ! canUseCompiler))
+ return null;
+
+ byte digest[];
+
+ try
+ {
+ MD5 md = (MD5) md5Digest.clone();
+ md.update(data);
+ digest = md.digest();
+ }
+ catch (NullPointerException _)
+ {
+ // If md5Digest==null -- but really this should never happen
+ // either, since the MD5 digest is in libgcj.
+ return null;
+ }
+
+ // We use lookaside cache files to determine whether these bytes
+ // correspond to a class file that is part of a precompiled DSO.
+ if (precompiledMapFiles != null)
+ {
+ try
+ {
+ Enumeration elements = precompiledMapFiles.elements();
+ while (elements.hasMoreElements())
+ {
+ PersistentByteMap map = (PersistentByteMap)elements.nextElement();
+ byte[] soName = map.get(digest);
+ if (soName != null)
+ return loadSharedLibrary(loader,
+ new String(soName),
+ domain, name);
+ }
+ }
+ catch (Exception _)
+ {
+ }
+ catch (UnknownError _)
+ {
+ // SharedLibHelper will throw UnknownError if the dlopen
+ // fails for some reason. We ignore it and continue on.
+ }
+ }
+
+ if (! useCompiler || ! canUseCompiler)
+ return null;
+
+ try
+ {
+ // FIXME: Make sure that the class represented by the
+ // bytes in DATA really is the class named in NAME. Make
+ // sure it's not "java.*".
+ StringBuffer hexBytes = new StringBuffer(gcjJitTmpdir);
+ hexBytes.append(File.separatorChar);
+ int digestLength = digest.length;
+ for (int i = 0; i < digestLength; ++i)
+ hexBytes.append(Integer.toHexString(digest[i] & 0xff));
+
+ // FIXME: use System.mapLibraryName?
+ // I'm thinking we should use that, plus a class specified
+ // via a property that determines lookup policy.
+ File soFile = new File(hexBytes + ".so");
+ if (soFile.isFile())
+ return loadSharedLibrary (loader, soFile.toString(), domain,
+ name);
+
+ File classFile = new File(hexBytes + ".class");
+ classFile.delete();
+ if (classFile.createNewFile() != true)
+ return null;
+
+ FileOutputStream f = new FileOutputStream (classFile);
+ // FIXME: race condition if bytes change... ?
+ f.write(data, offset, len);
+
+ // Invoke the compiler.
+ StringBuffer command = new StringBuffer(gcjJitCompiler);
+ command.append(" ");
+ command.append(classFile);
+ command.append(" ");
+ command.append(gcjJitCompilerOptions);
+ // These options are required.
+ command.append(" -findirect-dispatch -fjni -shared -fPIC -o ");
+ command.append(soFile);
+ Process p = Runtime.getRuntime().exec(command.toString());
+
+ // Read the process' stderr into a string.
+ StringBuffer err = new StringBuffer();
+ InputStreamReader stderr = new InputStreamReader (p.getErrorStream());
+ char[] inBuf = new char[500];
+ int bytesRead;
+ while ((bytesRead = stderr.read (inBuf)) != -1)
+ err.append(inBuf, 0, bytesRead);
+
+ if (p.waitFor() != 0)
+ {
+ // FIXME: we could log err.toString() somewhere...
+ return null;
+ }
+
+ return loadSharedLibrary(loader, soFile.toString(), domain, name);
+ }
+ catch (Exception _)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * 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()
+ {
+ useCompiler = true;
+ }
+
+ /**
+ * Calling <code>Compiler.disable()</code> will cause the compiler
+ * to be suspended; provided that a compiler even exists.
+ */
+ public static void disable()
+ {
+ useCompiler = false;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/VMDouble.java b/gcc-4.2.1/libjava/java/lang/VMDouble.java
new file mode 100644
index 000000000..9205eb3b3
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/VMDouble.java
@@ -0,0 +1,111 @@
+/* VMDouble.java -- VM Specific Double methods
+ Copyright (C) 2003, 2005, 2006 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
+{
+ /**
+ * 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);
+
+ public static native double parseDouble(String str);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/VMFloat.java b/gcc-4.2.1/libjava/java/lang/VMFloat.java
new file mode 100644
index 000000000..a6570f929
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/VMFloat.java
@@ -0,0 +1,99 @@
+/* VMFloat.java -- VM Specific Float methods
+ Copyright (C) 2003, 2006 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
+{
+ /**
+ * 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
diff --git a/gcc-4.2.1/libjava/java/lang/VMSecurityManager.java b/gcc-4.2.1/libjava/java/lang/VMSecurityManager.java
new file mode 100644
index 000000000..25aeb7c49
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/VMSecurityManager.java
@@ -0,0 +1,68 @@
+/*
+ * java.lang.SecurityManager: part of the Java Class Libraries project.
+ * Copyright (C) 1998, 2001, 2002, 2005 Free Software Foundation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+package java.lang;
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+
+/**
+ ** VMSecurityManager is a helper class for SecurityManager the VM must
+ ** implement.
+ **
+ ** @author John Keiser
+ ** @version 1.1.0, 31 May 1998
+ **/
+class VMSecurityManager
+{
+ /** Get a list of all the classes currently executing
+ ** methods on the Java stack. getClassContext()[0] is
+ ** the currently executing method
+ ** <STRONG>Spec Note:</STRONG> does not say whether
+ ** the stack will include the getClassContext() call or
+ ** the one just before it.
+ **
+ ** @return an array containing all the methods on classes
+ ** on the Java execution stack.
+ **/
+ static native Class[] getClassContext(Class caller);
+
+ /** Get the current ClassLoader--the one nearest to the
+ ** top of the stack.
+ ** @return the current ClassLoader.
+ **/
+ static ClassLoader currentClassLoader(Class caller)
+ {
+ // The docs above are wrong. See the online docs.
+ // FIXME this implementation is a bit wrong too -- the docs say we
+ // must also consider ancestors of the system class loader.
+ ClassLoader systemClassLoader = ClassLoader.systemClassLoader;
+ Class[] classStack = getClassContext (caller);
+ for (int i = 0; i < classStack.length; i++)
+ {
+ ClassLoader loader = classStack[i].getClassLoader();
+ if (loader != null && loader != systemClassLoader)
+ return loader;
+ }
+
+ return null;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/VMThrowable.java b/gcc-4.2.1/libjava/java/lang/VMThrowable.java
new file mode 100644
index 000000000..9dde28d29
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/VMThrowable.java
@@ -0,0 +1,82 @@
+/* java.lang.VMThrowable -- VM support methods for Throwable.
+ Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
+ 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 gnu.gcj.RawDataManaged;
+
+/**
+ * VM dependent state and support methods Throwable.
+ * It is deliberately package local and final and should only be accessed
+ * by the Throwable class.
+ * <p>
+ * This is the version used by libgcj (http://gcc.gnu.org/java/).
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+final class VMThrowable
+{
+ /**
+ * Private contructor, create VMThrowables with StackTrace();
+ */
+ 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);
+
+ // Native stack data.
+ private RawDataManaged data;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/Win32Process.java b/gcc-4.2.1/libjava/java/lang/Win32Process.java
new file mode 100644
index 000000000..b0ef487c2
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/Win32Process.java
@@ -0,0 +1,90 @@
+// Win32Process.java - Subclass of Process for Win32 systems.
+
+/* Copyright (C) 2002, 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * @author Adam Megacz
+ * @date Feb 24, 2002
+ */
+
+// This is entirely internal to our implementation.
+
+// This file is copied to `ConcreteProcess.java' before compilation.
+// Hence the class name apparently does not match the file name.
+final class ConcreteProcess extends Process
+{
+ public native void destroy ();
+
+ public int exitValue ()
+ {
+ if (! hasExited ())
+ throw new IllegalThreadStateException ("Process has not exited");
+
+ return exitCode;
+ }
+
+ public InputStream getErrorStream ()
+ {
+ return errorStream;
+ }
+
+ public InputStream getInputStream ()
+ {
+ return inputStream;
+ }
+
+ public OutputStream getOutputStream ()
+ {
+ return outputStream;
+ }
+
+ public native int waitFor () throws InterruptedException;
+
+ public ConcreteProcess (String[] progarray,
+ String[] envp,
+ File dir)
+ throws IOException
+ {
+ for (int i = 0; i < progarray.length; i++)
+ {
+ String s = progarray[i];
+
+ if ( (s.indexOf (' ') >= 0) || (s.indexOf ('\t') >= 0))
+ progarray[i] = "\"" + s + "\"";
+ }
+
+ startProcess (progarray, envp, dir);
+ }
+
+ // The standard streams (stdin, stdout and stderr, respectively)
+ // of the child as seen by the parent process.
+ private OutputStream outputStream;
+ private InputStream inputStream;
+ private InputStream errorStream;
+
+ // Handle to the child process - cast to HANDLE before use.
+ private int procHandle;
+
+ // Exit code of the child if it has exited.
+ private int exitCode;
+
+ private native boolean hasExited ();
+ private native void startProcess (String[] progarray,
+ String[] envp,
+ File dir)
+ throws IOException;
+ private native void cleanup ();
+}
diff --git a/gcc-4.2.1/libjava/java/lang/management/VMManagementFactory.java b/gcc-4.2.1/libjava/java/lang/management/VMManagementFactory.java
new file mode 100644
index 000000000..6a906c730
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/management/VMManagementFactory.java
@@ -0,0 +1,84 @@
+/* VMManagementFactory.java - VM interface for obtaining system beans.
+ Copyright (C) 2006 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.management;
+
+/**
+ * Provides lists of resources required by the
+ * {@link java.lang.management.ManagementFactory} for
+ * creating beans.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+final class VMManagementFactory
+{
+
+ /**
+ * Return a list of the names of the currently available
+ * memory pools within the virtual machine.
+ *
+ * @return a list of memory pool names.
+ */
+ static String[] getMemoryPoolNames()
+ {
+ return new String[0];
+ }
+
+ /**
+ * Return a list of the names of the currently available
+ * memory managers within the virtual machine. This should
+ * not include the garbage collectors listed below.
+ *
+ * @return a list of memory manager names.
+ */
+ static String[] getMemoryManagerNames()
+ {
+ return new String[0];
+ }
+
+ /**
+ * Return a list of the names of the currently available
+ * garbage collectors within the virtual machine.
+ *
+ * @return a list of garbage collector names.
+ */
+ static String[] getGarbageCollectorNames()
+ {
+ return new String[0];
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natCharacter.cc b/gcc-4.2.1/libjava/java/lang/natCharacter.cc
new file mode 100644
index 000000000..8d246dd56
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natCharacter.cc
@@ -0,0 +1,237 @@
+/* java.lang.Character -- Wrapper class for char, and Unicode subsets
+ Copyright (C) 1998, 1999, 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. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Character.h>
+
+#include <java-chartables.h>
+
+
+
+// These constants define the return values for characters that are unassigned
+// or reserved for private use.
+#define UNASSIGNED_TYPE 0
+#define UNASSIGNED_DIGIT -1
+#define UNASSIGNED_DIRECTION -1
+#define UNASSIGNED_NUMERIC_VALUE -1
+
+#define PRIVATE_TYPE 18
+#define PRIVATE_DIRECTION 0
+
+// The methods that take a char as an argument all have counterparts that
+// take ints. The ones that take chars only work for the BMP or plane 0 of the
+// Unicode standard but the ones that take ints work for all Unicode code
+// points. However, the ones that take chars don't simply redirect the calls
+// because the BMP is by far the most used plane so saving a little time on
+// each call makes sense.
+
+jchar
+java::lang::Character::readChar(jchar ch)
+{
+ // Perform 16-bit addition to find the correct entry in data.
+ return data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)];
+}
+
+jchar
+java::lang::Character::readCodePoint(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ jchar offset = (jchar)(codePoint & 0xffff);
+ // Be careful not to call this method with an unassigned character. The only
+ // characters assigned as of Unicode 4.0.0 belong to planes 0, 1, 2, and 14.
+ return data[plane][(jchar) (blocks[plane][offset >> shift[plane]] + offset)];
+}
+
+jint
+java::lang::Character::getType(jchar ch)
+{
+ // Perform 16-bit addition to find the correct entry in data.
+ return (jint) (data[0][(jchar) (blocks[0][ch >> shift[0]] + ch)] & TYPE_MASK);
+}
+
+jint
+java::lang::Character::getType(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane > 2 && plane != 14)
+ {
+ if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+ return (jint) PRIVATE_TYPE;
+ return (jint) UNASSIGNED_TYPE;
+ }
+ jint offset = codePoint & 0xffff;
+ return (jint)
+ (data[plane]
+ [(jchar) (blocks[plane][offset >> shift[plane]] + offset)] & TYPE_MASK);
+}
+
+jchar
+java::lang::Character::toLowerCase(jchar ch)
+{
+ return (jchar) (ch + lower[0][readChar(ch) >> 7]);
+}
+
+jint
+java::lang::Character::toLowerCase(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane > 2 && plane != 14)
+ return codePoint;
+ return (lower[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
+jchar
+java::lang::Character::toUpperCase(jchar ch)
+{
+ return (jchar) (ch + upper[0][readChar(ch) >> 7]);
+}
+
+jint
+java::lang::Character::toUpperCase(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane > 2 && plane != 14)
+ return codePoint;
+ return (upper[plane][readCodePoint(codePoint) >> 7]) + codePoint;
+}
+
+jchar
+java::lang::Character::toTitleCase(jchar ch)
+{
+ // As title is short, it doesn't hurt to exhaustively iterate over it.
+ for (int i = title_length - 2; i >= 0; i -= 2)
+ if (title[i] == ch)
+ return title[i + 1];
+ return toUpperCase(ch);
+}
+
+jint
+java::lang::Character::toTitleCase(jint codePoint)
+{
+ // As of Unicode 4.0.0 no characters outside of plane 0 have titlecase
+ // mappings that are different from their uppercase mapping.
+ if (codePoint < 0x10000)
+ return toTitleCase((jchar)codePoint);
+ return toUpperCase(codePoint);
+}
+
+jint
+java::lang::Character::digit(jchar ch, jint radix)
+{
+ if (radix < MIN_RADIX || radix > MAX_RADIX)
+ return (jint) -1;
+ jchar attr = readChar(ch);
+ if (((1 << (attr & TYPE_MASK))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))))
+ {
+ // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
+ jint digit = (jint) numValue[0][attr >> 7];
+ return (digit >= 0 && digit < radix) ? digit : (jint) -1;
+ }
+ return (jint) -1;
+}
+
+jint
+java::lang::Character::digit(jint codePoint, jint radix)
+{
+ if (radix < MIN_RADIX || radix > MAX_RADIX)
+ return (jint) -1;
+
+ jint plane = codePoint >> 16;
+ if (plane > 2 && plane != 14)
+ return UNASSIGNED_DIGIT;
+
+ jchar attr = readCodePoint(codePoint);
+ if (((1 << (attr & TYPE_MASK))
+ & ((1 << UPPERCASE_LETTER)
+ | (1 << LOWERCASE_LETTER)
+ | (1 << DECIMAL_DIGIT_NUMBER))))
+ {
+ // Signedness doesn't matter; 0xffff vs. -1 are both rejected.
+ jint digit = (jint) numValue[plane][attr >> 7];
+ if (digit <= -3)
+ digit = largenums[-digit -3];
+ return (digit >= 0 && digit < radix) ? digit : (jint) -1;
+ }
+ return (jint) -1;
+
+}
+
+jint
+java::lang::Character::getNumericValue(jchar ch)
+{
+ // numValue is stored as an array of jshort, since 10000 is the maximum.
+ return (jint) numValue[0][readChar(ch) >> 7];
+}
+
+jint
+java::lang::Character::getNumericValue(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane > 2 && plane != 14)
+ return UNASSIGNED_NUMERIC_VALUE;
+ jshort num = numValue[plane][readCodePoint(codePoint) >> 7];
+ if (num <= -3)
+ return largenums[-num - 3];
+ return num;
+}
+
+jbyte
+java::lang::Character::getDirectionality(jchar ch)
+{
+ return direction[0][readChar(ch) >> 7];
+}
+
+jbyte
+java::lang::Character::getDirectionality(jint codePoint)
+{
+ jint plane = codePoint >> 16;
+ if (plane > 2 && plane != 14)
+ {
+ if (plane > 14 && ((codePoint & 0xffff) < 0xfffe))
+ return (jint) PRIVATE_DIRECTION;
+ return (jint) UNASSIGNED_DIRECTION;
+ }
+ return direction[plane][readCodePoint(codePoint) >> 7];
+}
+
+
diff --git a/gcc-4.2.1/libjava/java/lang/natClass.cc b/gcc-4.2.1/libjava/java/lang/natClass.cc
new file mode 100644
index 000000000..12984291e
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natClass.cc
@@ -0,0 +1,1269 @@
+// natClass.cc - Implementation of java.lang.Class native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <limits.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdio.h>
+
+#pragma implementation "Class.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-threads.h>
+
+#include <java/lang/Class.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/String.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/reflect/Member.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/AbstractMethodError.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ClassCastException.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/lang/ExceptionInInitializerError.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/NoSuchFieldError.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/InstantiationException.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/NoSuchFieldException.h>
+#include <java/lang/NoSuchMethodError.h>
+#include <java/lang/NoSuchMethodException.h>
+#include <java/lang/Thread.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/RuntimePermission.h>
+#include <java/lang/System.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/VMClassLoader.h>
+#include <gcj/method.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/VerifyError.h>
+
+#include <java-cpool.h>
+#include <java-interp.h>
+#include <java-assert.h>
+#include <java-stack.h>
+#include <execution.h>
+
+
+
+using namespace gcj;
+
+jclass
+java::lang::Class::forName (jstring className, jboolean initialize,
+ java::lang::ClassLoader *loader)
+{
+ if (! className)
+ throw new java::lang::NullPointerException;
+
+ jsize length = _Jv_GetStringUTFLength (className);
+ char buffer[length];
+ _Jv_GetStringUTFRegion (className, 0, className->length(), buffer);
+
+ _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length);
+
+ if (! _Jv_VerifyClassName (name))
+ throw new java::lang::ClassNotFoundException (className);
+
+ jclass klass = (buffer[0] == '['
+ ? _Jv_FindClassFromSignature (name->chars(), loader)
+ : _Jv_FindClass (name, loader));
+
+ if (klass == NULL)
+ throw new java::lang::ClassNotFoundException (className);
+
+ if (initialize)
+ _Jv_InitClass (klass);
+
+ return klass;
+}
+
+jclass
+java::lang::Class::forName (jstring className)
+{
+ java::lang::ClassLoader *loader = NULL;
+
+ jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
+ if (caller)
+ loader = caller->getClassLoaderInternal();
+
+ return forName (className, true, loader);
+}
+
+java::lang::ClassLoader *
+java::lang::Class::getClassLoader (void)
+{
+ java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+ if (s != NULL)
+ {
+ jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
+ return getClassLoader (caller);
+ }
+
+ return loader;
+}
+
+java::lang::ClassLoader *
+java::lang::Class::getClassLoader (jclass caller)
+{
+ java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+ if (s != NULL)
+ {
+ ClassLoader *caller_loader = caller->getClassLoaderInternal();
+
+ // If the caller has a non-null class loader, and that loader
+ // is not this class' loader or an ancestor thereof, then do a
+ // security check.
+ if (caller_loader != NULL && ! caller_loader->isAncestorOf(loader))
+ s->checkPermission (new RuntimePermission (JvNewStringLatin1 ("getClassLoader")));
+ }
+
+ return loader;
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getConstructor (JArray<jclass> *param_types)
+{
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
+
+ jstring partial_sig = getSignature (param_types, true);
+ jint hash = partial_sig->hashCode ();
+
+ int i = isPrimitive () ? 0 : method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (methods[i].name, init_name)
+ && _Jv_equal (methods[i].signature, partial_sig, hash))
+ {
+ // Found it. For getConstructor, the constructor must be
+ // public.
+ using namespace java::lang::reflect;
+ if (! Modifier::isPublic(methods[i].accflags))
+ break;
+ Constructor *cons = new Constructor ();
+ cons->offset = (char *) (&methods[i]) - (char *) methods;
+ cons->declaringClass = this;
+ return cons;
+ }
+ }
+ throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
+}
+
+JArray<java::lang::reflect::Constructor *> *
+java::lang::Class::getDeclaredConstructors (jboolean publicOnly)
+{
+ int numConstructors = 0;
+ int max = isPrimitive () ? 0 : method_count;
+ int i;
+ for (i = max; --i >= 0; )
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || ! _Jv_equalUtf8Consts (method->name, init_name))
+ continue;
+ if (publicOnly
+ && ! java::lang::reflect::Modifier::isPublic(method->accflags))
+ continue;
+ numConstructors++;
+ }
+ JArray<java::lang::reflect::Constructor *> *result
+ = (JArray<java::lang::reflect::Constructor *> *)
+ JvNewObjectArray (numConstructors,
+ &java::lang::reflect::Constructor::class$,
+ NULL);
+ java::lang::reflect::Constructor** cptr = elements (result);
+ for (i = 0; i < max; i++)
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || ! _Jv_equalUtf8Consts (method->name, init_name))
+ continue;
+ if (publicOnly
+ && ! java::lang::reflect::Modifier::isPublic(method->accflags))
+ continue;
+ java::lang::reflect::Constructor *cons
+ = new java::lang::reflect::Constructor ();
+ cons->offset = (char *) method - (char *) methods;
+ cons->declaringClass = this;
+ *cptr++ = cons;
+ }
+ return result;
+}
+
+java::lang::reflect::Constructor *
+java::lang::Class::getDeclaredConstructor (JArray<jclass> *param_types)
+{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
+ jstring partial_sig = getSignature (param_types, true);
+ jint hash = partial_sig->hashCode ();
+
+ int i = isPrimitive () ? 0 : method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (methods[i].name, init_name)
+ && _Jv_equal (methods[i].signature, partial_sig, hash))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+ Constructor *cons = new Constructor ();
+ cons->offset = (char *) (&methods[i]) - (char *) methods;
+ cons->declaringClass = this;
+ return cons;
+ }
+ }
+ throw new java::lang::NoSuchMethodException (_Jv_NewStringUtf8Const (init_name));
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getField (jstring name, jint hash)
+{
+ java::lang::reflect::Field* rfield;
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ if (! (field->getModifiers() & java::lang::reflect::Modifier::PUBLIC))
+ continue;
+ rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ jclass superclass = getSuperclass();
+ if (superclass == NULL)
+ return NULL;
+ rfield = superclass->getField(name, hash);
+ for (int i = 0; i < interface_count && rfield == NULL; ++i)
+ rfield = interfaces[i]->getField (name, hash);
+ return rfield;
+}
+
+java::lang::reflect::Field *
+java::lang::Class::getDeclaredField (jstring name)
+{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+ int hash = name->hashCode();
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ throw new java::lang::NoSuchFieldException (name);
+}
+
+JArray<java::lang::reflect::Field *> *
+java::lang::Class::getDeclaredFields (jboolean public_only)
+{
+ int size;
+ if (public_only)
+ {
+ size = 0;
+ for (int i = 0; i < field_count; ++i)
+ {
+ _Jv_Field *field = &fields[i];
+ if ((field->flags & java::lang::reflect::Modifier::PUBLIC))
+ ++size;
+ }
+ }
+ else
+ size = field_count;
+
+ JArray<java::lang::reflect::Field *> *result
+ = (JArray<java::lang::reflect::Field *> *)
+ JvNewObjectArray (size, &java::lang::reflect::Field::class$, NULL);
+ java::lang::reflect::Field** fptr = elements (result);
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (public_only
+ && ! (field->flags & java::lang::reflect::Modifier::PUBLIC))
+ continue;
+ java::lang::reflect::Field* rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ *fptr++ = rfield;
+ }
+ return result;
+}
+
+void
+java::lang::Class::getSignature (java::lang::StringBuffer *buffer)
+{
+ if (isPrimitive())
+ buffer->append((jchar) method_count);
+ else
+ {
+ jstring name = getName();
+ if (name->charAt(0) != '[')
+ buffer->append((jchar) 'L');
+ buffer->append(name);
+ if (name->charAt(0) != '[')
+ buffer->append((jchar) ';');
+ }
+}
+
+// This doesn't have to be native. It is an implementation detail
+// only called from the C++ code, though, so maybe this is clearer.
+jstring
+java::lang::Class::getSignature (JArray<jclass> *param_types,
+ jboolean is_constructor)
+{
+ java::lang::StringBuffer *buf = new java::lang::StringBuffer ();
+ buf->append((jchar) '(');
+ // A NULL param_types means "no parameters".
+ if (param_types != NULL)
+ {
+ jclass *v = elements (param_types);
+ for (int i = 0; i < param_types->length; ++i)
+ v[i]->getSignature(buf);
+ }
+ buf->append((jchar) ')');
+ if (is_constructor)
+ buf->append((jchar) 'V');
+ return buf->toString();
+}
+
+java::lang::reflect::Method *
+java::lang::Class::_getDeclaredMethod (jstring name,
+ JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+ int i = isPrimitive () ? 0 : method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (methods[i].name, utf_name)
+ && _Jv_equaln (methods[i].signature, partial_sig, p_len)
+ && (methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) == 0)
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+ Method *rmethod = new Method ();
+ rmethod->offset = (char*) (&methods[i]) - (char*) methods;
+ rmethod->declaringClass = this;
+ return rmethod;
+ }
+ }
+ return NULL;
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getDeclaredMethods (void)
+{
+ memberAccessCheck(java::lang::reflect::Member::DECLARED);
+
+ int numMethods = 0;
+ int max = isPrimitive () ? 0 : method_count;
+ int i;
+ for (i = max; --i >= 0; )
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name)
+ || _Jv_equalUtf8Consts (method->name, finit_name)
+ || (methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) != 0)
+ continue;
+ numMethods++;
+ }
+ JArray<java::lang::reflect::Method *> *result
+ = (JArray<java::lang::reflect::Method *> *)
+ JvNewObjectArray (numMethods, &java::lang::reflect::Method::class$, NULL);
+ java::lang::reflect::Method** mptr = elements (result);
+ for (i = 0; i < max; i++)
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name)
+ || _Jv_equalUtf8Consts (method->name, finit_name)
+ || (methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) != 0)
+ continue;
+ java::lang::reflect::Method* rmethod
+ = new java::lang::reflect::Method ();
+ rmethod->offset = (char*) method - (char*) methods;
+ rmethod->declaringClass = this;
+ *mptr++ = rmethod;
+ }
+ return result;
+}
+
+jstring
+java::lang::Class::getName (void)
+{
+ return name->toString();
+}
+
+JArray<jclass> *
+java::lang::Class::getDeclaredClasses (jboolean /*publicOnly*/)
+{
+ // Until we have inner classes, it always makes sense to return an
+ // empty array.
+ JArray<jclass> *result
+ = (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$,
+ NULL);
+ return result;
+}
+
+jclass
+java::lang::Class::getDeclaringClass (void)
+{
+ // Until we have inner classes, it makes sense to always return
+ // NULL.
+ return NULL;
+}
+
+JArray<jclass> *
+java::lang::Class::getInterfaces (void)
+{
+ jobjectArray r = JvNewObjectArray (interface_count, getClass (), NULL);
+ jobject *data = elements (r);
+ for (int i = 0; i < interface_count; ++i)
+ {
+ typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+ data[i] = interfaces[i];
+ if ((uaddr)data[i] < (uaddr)constants.size)
+ fprintf (stderr, "ERROR !!!\n");
+ }
+ return reinterpret_cast<JArray<jclass> *> (r);
+}
+
+java::lang::reflect::Method *
+java::lang::Class::_getMethod (jstring name, JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+
+ for (Class *klass = this; klass; klass = klass->getSuperclass())
+ {
+ int i = klass->isPrimitive () ? 0 : klass->method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len)
+ && (klass->methods[i].accflags
+ & java::lang::reflect::Modifier::INVISIBLE) == 0)
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ // Method must be public.
+ if (! Modifier::isPublic (klass->methods[i].accflags))
+ break;
+
+ Method *rmethod = new Method ();
+ rmethod->offset = ((char *) (&klass->methods[i])
+ - (char *) klass->methods);
+ rmethod->declaringClass = klass;
+ return rmethod;
+ }
+ }
+ }
+
+ // If we haven't found a match, and this class is an interface, then
+ // check all the superinterfaces.
+ if (isInterface())
+ {
+ for (int i = 0; i < interface_count; ++i)
+ {
+ using namespace java::lang::reflect;
+ Method *rmethod = interfaces[i]->_getMethod (name, param_types);
+ if (rmethod != NULL)
+ return rmethod;
+ }
+ }
+
+ return NULL;
+}
+
+// This is a very slow implementation, since it re-scans all the
+// methods we've already listed to make sure we haven't duplicated a
+// method. It also over-estimates the required size, so we have to
+// shrink the result array later.
+jint
+java::lang::Class::_getMethods (JArray<java::lang::reflect::Method *> *result,
+ jint offset)
+{
+ jint count = 0;
+
+ // First examine all local methods
+ for (int i = isPrimitive () ? 0 : method_count; --i >= 0; )
+ {
+ _Jv_Method *method = &methods[i];
+ if (method->name == NULL
+ || _Jv_equalUtf8Consts (method->name, clinit_name)
+ || _Jv_equalUtf8Consts (method->name, init_name)
+ || _Jv_equalUtf8Consts (method->name, finit_name)
+ || (method->accflags
+ & java::lang::reflect::Modifier::INVISIBLE) != 0)
+ continue;
+ // Only want public methods.
+ if (! java::lang::reflect::Modifier::isPublic (method->accflags))
+ continue;
+
+ // This is where we over-count the slots required if we aren't
+ // filling the result for real.
+ if (result != NULL)
+ {
+ jboolean add = true;
+ java::lang::reflect::Method **mp = elements (result);
+ // If we already have a method with this name and signature,
+ // then ignore this one. This can happen with virtual
+ // methods.
+ for (int j = 0; j < offset; ++j)
+ {
+ _Jv_Method *meth_2 = _Jv_FromReflectedMethod (mp[j]);
+ if (_Jv_equalUtf8Consts (method->name, meth_2->name)
+ && _Jv_equalUtf8Consts (method->signature,
+ meth_2->signature))
+ {
+ add = false;
+ break;
+ }
+ }
+ if (! add)
+ continue;
+ }
+
+ if (result != NULL)
+ {
+ using namespace java::lang::reflect;
+ Method *rmethod = new Method ();
+ rmethod->offset = (char *) method - (char *) methods;
+ rmethod->declaringClass = this;
+ Method **mp = elements (result);
+ mp[offset + count] = rmethod;
+ }
+ ++count;
+ }
+ offset += count;
+
+ // Now examine superclasses.
+ if (getSuperclass () != NULL)
+ {
+ jint s_count = getSuperclass()->_getMethods (result, offset);
+ offset += s_count;
+ count += s_count;
+ }
+
+ // Finally, examine interfaces.
+ for (int i = 0; i < interface_count; ++i)
+ {
+ int f_count = interfaces[i]->_getMethods (result, offset);
+ count += f_count;
+ offset += f_count;
+ }
+
+ return count;
+}
+
+JArray<java::lang::reflect::Method *> *
+java::lang::Class::getMethods (void)
+{
+ using namespace java::lang::reflect;
+
+ memberAccessCheck(Member::PUBLIC);
+
+ // This will overestimate the size we need.
+ jint count = _getMethods (NULL, 0);
+
+ JArray<Method *> *result
+ = ((JArray<Method *> *) JvNewObjectArray (count,
+ &Method::class$,
+ NULL));
+
+ // When filling the array for real, we get the actual count. Then
+ // we resize the array.
+ jint real_count = _getMethods (result, 0);
+
+ if (real_count != count)
+ {
+ JArray<Method *> *r2
+ = ((JArray<Method *> *) JvNewObjectArray (real_count,
+ &Method::class$,
+ NULL));
+
+ Method **destp = elements (r2);
+ Method **srcp = elements (result);
+
+ for (int i = 0; i < real_count; ++i)
+ *destp++ = *srcp++;
+
+ result = r2;
+ }
+
+ return result;
+}
+
+jboolean
+java::lang::Class::isAssignableFrom (jclass klass)
+{
+ // Arguments may not have been initialized, given ".class" syntax.
+ // This ensures we can at least look at their superclasses.
+ _Jv_Linker::wait_for_state (this, JV_STATE_LOADING);
+ _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
+ return _Jv_IsAssignableFrom (klass, this);
+}
+
+jboolean
+java::lang::Class::isInstance (jobject obj)
+{
+ if (! obj)
+ return false;
+ return _Jv_IsAssignableFrom (JV_CLASS (obj), this);
+}
+
+jobject
+java::lang::Class::newInstance (void)
+{
+ memberAccessCheck(java::lang::reflect::Member::PUBLIC);
+
+ if (isPrimitive ()
+ || isInterface ()
+ || isArray ()
+ || java::lang::reflect::Modifier::isAbstract(accflags))
+ throw new java::lang::InstantiationException (getName ());
+
+ _Jv_InitClass (this);
+
+ _Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature);
+ if (! meth)
+ throw new java::lang::InstantiationException (getName());
+
+ jobject r = _Jv_AllocObject (this);
+ ((void (*) (jobject)) meth->ncode) (r);
+ return r;
+}
+
+void
+java::lang::Class::finalize (void)
+{
+ engine->unregister(this);
+}
+
+// This implements the initialization process for a class. From Spec
+// section 12.4.2.
+void
+java::lang::Class::initializeClass (void)
+{
+ // Short-circuit to avoid needless locking (expression includes
+ // JV_STATE_PHANTOM and JV_STATE_DONE).
+ if (state >= JV_STATE_PHANTOM)
+ return;
+
+ // Step 1. We introduce a new scope so we can synchronize more
+ // easily.
+ {
+ JvSynchronize sync (this);
+
+ if (state < JV_STATE_LINKED)
+ {
+ try
+ {
+ _Jv_Linker::wait_for_state(this, JV_STATE_LINKED);
+ }
+ catch (java::lang::Throwable *x)
+ {
+ // Turn into a NoClassDefFoundError.
+ java::lang::NoClassDefFoundError *result
+ = new java::lang::NoClassDefFoundError(getName());
+ result->initCause(x);
+ throw result;
+ }
+ }
+
+ // Step 2.
+ java::lang::Thread *self = java::lang::Thread::currentThread();
+ self = (java::lang::Thread *) ((long) self | 1);
+ while (state == JV_STATE_IN_PROGRESS && thread && thread != self)
+ wait ();
+
+ // Steps 3 & 4.
+ if (state == JV_STATE_DONE || state == JV_STATE_IN_PROGRESS)
+ return;
+
+ // Step 5.
+ if (state == JV_STATE_ERROR)
+ throw new java::lang::NoClassDefFoundError (getName());
+
+ // Step 6.
+ thread = self;
+ _Jv_Linker::wait_for_state (this, JV_STATE_LINKED);
+ state = JV_STATE_IN_PROGRESS;
+ }
+
+ // Step 7.
+ if (! isInterface () && superclass)
+ {
+ try
+ {
+ _Jv_InitClass (superclass);
+ }
+ catch (java::lang::Throwable *except)
+ {
+ // Caught an exception.
+ JvSynchronize sync (this);
+ state = JV_STATE_ERROR;
+ notifyAll ();
+ throw except;
+ }
+ }
+
+ // Steps 8, 9, 10, 11.
+ try
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name,
+ void_signature);
+ if (meth)
+ ((void (*) (void)) meth->ncode) ();
+ }
+ catch (java::lang::Throwable *except)
+ {
+ if (! java::lang::Error::class$.isInstance(except))
+ {
+ try
+ {
+ except = new ExceptionInInitializerError (except);
+ }
+ catch (java::lang::Throwable *t)
+ {
+ except = t;
+ }
+ }
+
+ JvSynchronize sync (this);
+ state = JV_STATE_ERROR;
+ notifyAll ();
+ throw except;
+ }
+
+ JvSynchronize sync (this);
+ state = JV_STATE_DONE;
+ notifyAll ();
+}
+
+// Only used by serialization
+java::lang::reflect::Field *
+java::lang::Class::getPrivateField (jstring name)
+{
+ int hash = name->hashCode ();
+
+ java::lang::reflect::Field* rfield;
+ for (int i = 0; i < field_count; i++)
+ {
+ _Jv_Field *field = &fields[i];
+ if (! _Jv_equal (field->name, name, hash))
+ continue;
+ rfield = new java::lang::reflect::Field ();
+ rfield->offset = (char*) field - (char*) fields;
+ rfield->declaringClass = this;
+ rfield->name = name;
+ return rfield;
+ }
+ jclass superclass = getSuperclass();
+ if (superclass == NULL)
+ return NULL;
+ rfield = superclass->getPrivateField(name);
+ for (int i = 0; i < interface_count && rfield == NULL; ++i)
+ rfield = interfaces[i]->getPrivateField (name);
+ return rfield;
+}
+
+// Only used by serialization
+java::lang::reflect::Method *
+java::lang::Class::getPrivateMethod (jstring name, JArray<jclass> *param_types)
+{
+ jstring partial_sig = getSignature (param_types, false);
+ jint p_len = partial_sig->length();
+ _Jv_Utf8Const *utf_name = _Jv_makeUtf8Const (name);
+ for (Class *klass = this; klass; klass = klass->getSuperclass())
+ {
+ int i = klass->isPrimitive () ? 0 : klass->method_count;
+ while (--i >= 0)
+ {
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equaln (klass->methods[i].signature, partial_sig, p_len))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ Method *rmethod = new Method ();
+ rmethod->offset = ((char *) (&klass->methods[i])
+ - (char *) klass->methods);
+ rmethod->declaringClass = klass;
+ return rmethod;
+ }
+ }
+ }
+ throw new java::lang::NoSuchMethodException (name);
+}
+
+// Private accessor method for Java code to retrieve the protection domain.
+java::security::ProtectionDomain *
+java::lang::Class::getProtectionDomain0 ()
+{
+ return protectionDomain;
+}
+
+JArray<jobject> *
+java::lang::Class::getSigners()
+{
+ return hack_signers;
+}
+
+void
+java::lang::Class::setSigners(JArray<jobject> *s)
+{
+ hack_signers = s;
+}
+
+
+
+//
+// Some class-related convenience functions.
+//
+
+// Find a method declared in the class. If it is not declared locally
+// (or if it is inherited), return NULL.
+_Jv_Method *
+_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ for (int i = 0; i < klass->method_count; ++i)
+ {
+ if (_Jv_equalUtf8Consts (name, klass->methods[i].name)
+ && _Jv_equalUtf8Consts (signature, klass->methods[i].signature))
+ return &klass->methods[i];
+ }
+ return NULL;
+}
+
+_Jv_Method *
+_Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature,
+ jclass *declarer_result)
+{
+ for (; klass; klass = klass->getSuperclass())
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+
+ if (meth)
+ {
+ if (declarer_result)
+ *declarer_result = klass;
+ return meth;
+ }
+ }
+
+ return NULL;
+}
+
+#ifdef HAVE_TLS
+
+// NOTE: MCACHE_SIZE should be a power of 2 minus one.
+#define MCACHE_SIZE 31
+
+struct _Jv_mcache
+{
+ jclass klass;
+ _Jv_Method *method;
+};
+
+static __thread _Jv_mcache *method_cache;
+#endif // HAVE_TLS
+
+static void *
+_Jv_FindMethodInCache (jclass klass MAYBE_UNUSED,
+ _Jv_Utf8Const *name MAYBE_UNUSED,
+ _Jv_Utf8Const *signature MAYBE_UNUSED)
+{
+#ifdef HAVE_TLS
+ _Jv_mcache *cache = method_cache;
+ if (cache)
+ {
+ int index = name->hash16 () & MCACHE_SIZE;
+ _Jv_mcache *mc = &cache[index];
+ _Jv_Method *m = mc->method;
+
+ if (mc->klass == klass
+ && _Jv_equalUtf8Consts (m->name, name)
+ && _Jv_equalUtf8Consts (m->signature, signature))
+ return mc->method->ncode;
+ }
+#endif // HAVE_TLS
+ return NULL;
+}
+
+static void
+_Jv_AddMethodToCache (jclass klass MAYBE_UNUSED,
+ _Jv_Method *method MAYBE_UNUSED)
+{
+#ifdef HAVE_TLS
+ if (method_cache == NULL)
+ method_cache = (_Jv_mcache *) _Jv_MallocUnchecked((MCACHE_SIZE + 1)
+ * sizeof (_Jv_mcache));
+ // If the allocation failed, just keep going.
+ if (method_cache != NULL)
+ {
+ int index = method->name->hash16 () & MCACHE_SIZE;
+ method_cache[index].method = method;
+ method_cache[index].klass = klass;
+ }
+#endif // HAVE_TLS
+}
+
+// Free this thread's method cache. We explicitly manage this memory
+// as the GC does not yet know how to scan TLS on all platforms.
+void
+_Jv_FreeMethodCache ()
+{
+#ifdef HAVE_TLS
+ if (method_cache != NULL)
+ {
+ _Jv_Free(method_cache);
+ method_cache = NULL;
+ }
+#endif // HAVE_TLS
+}
+
+void *
+_Jv_LookupInterfaceMethod (jclass klass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ using namespace java::lang::reflect;
+
+ void *ncode = _Jv_FindMethodInCache (klass, name, signature);
+ if (ncode != 0)
+ return ncode;
+
+ for (; klass; klass = klass->getSuperclass())
+ {
+ _Jv_Method *meth = _Jv_GetMethodLocal (klass, name, signature);
+ if (! meth)
+ continue;
+
+ if (Modifier::isStatic(meth->accflags))
+ throw new java::lang::IncompatibleClassChangeError
+ (_Jv_GetMethodString (klass, meth));
+ if (Modifier::isAbstract(meth->accflags))
+ throw new java::lang::AbstractMethodError
+ (_Jv_GetMethodString (klass, meth));
+ if (! Modifier::isPublic(meth->accflags))
+ throw new java::lang::IllegalAccessError
+ (_Jv_GetMethodString (klass, meth));
+
+ _Jv_AddMethodToCache (klass, meth);
+
+ return meth->ncode;
+ }
+ throw new java::lang::IncompatibleClassChangeError;
+}
+
+// Fast interface method lookup by index.
+void *
+_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx)
+{
+ _Jv_IDispatchTable *cldt = klass->idt;
+ int idx = iface->ioffsets[cldt->iindex] + method_idx;
+ return cldt->itable[idx];
+}
+
+jboolean
+_Jv_IsAssignableFrom (jclass source, jclass target)
+{
+ if (source == target)
+ return true;
+
+ // If target is array, so must source be.
+ while (target->isArray ())
+ {
+ if (! source->isArray())
+ return false;
+ target = target->getComponentType();
+ source = source->getComponentType();
+ }
+
+ if (target->isInterface())
+ {
+ // Abstract classes have no IDT, and IDTs provide no way to check
+ // two interfaces for assignability.
+ if (__builtin_expect
+ (source->idt == NULL || source->isInterface(), false))
+ return _Jv_InterfaceAssignableFrom (source, target);
+
+ _Jv_IDispatchTable *cl_idt = source->idt;
+
+ if (__builtin_expect ((target->ioffsets == NULL), false))
+ return false; // No class implementing TARGET has been loaded.
+ jshort cl_iindex = cl_idt->iindex;
+ if (cl_iindex < target->ioffsets[0])
+ {
+ jshort offset = target->ioffsets[cl_iindex];
+ if (offset != -1 && offset < cl_idt->itable_length
+ && cl_idt->itable[offset] == target)
+ return true;
+ }
+ return false;
+ }
+
+ // Primitive TYPE classes are only assignable to themselves.
+ if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false))
+ return false;
+
+ if (target == &java::lang::Object::class$)
+ return true;
+ else if (source->ancestors == NULL || target->ancestors == NULL)
+ {
+ // We need this case when either SOURCE or TARGET has not has
+ // its constant-time tables prepared.
+
+ // At this point we know that TARGET can't be Object, so it is
+ // safe to use that as the termination point.
+ while (source && source != &java::lang::Object::class$)
+ {
+ if (source == target)
+ return true;
+ source = source->getSuperclass();
+ }
+ }
+ else if (source->depth >= target->depth
+ && source->ancestors[source->depth - target->depth] == target)
+ return true;
+
+ return false;
+}
+
+// Interface type checking, the slow way. Returns TRUE if IFACE is a
+// superinterface of SOURCE. This is used when SOURCE is also an interface,
+// or a class with no interface dispatch table.
+jboolean
+_Jv_InterfaceAssignableFrom (jclass source, jclass iface)
+{
+ for (int i = 0; i < source->interface_count; i++)
+ {
+ jclass interface = source->interfaces[i];
+ if (iface == interface
+ || _Jv_InterfaceAssignableFrom (interface, iface))
+ return true;
+ }
+
+ if (!source->isInterface()
+ && source->superclass
+ && _Jv_InterfaceAssignableFrom (source->superclass, iface))
+ return true;
+
+ return false;
+}
+
+jboolean
+_Jv_IsInstanceOf(jobject obj, jclass cl)
+{
+ if (__builtin_expect (!obj, false))
+ return false;
+ return _Jv_IsAssignableFrom (JV_CLASS (obj), cl);
+}
+
+void *
+_Jv_CheckCast (jclass c, jobject obj)
+{
+ if (__builtin_expect
+ (obj != NULL && ! _Jv_IsAssignableFrom(JV_CLASS (obj), c), false))
+ throw new java::lang::ClassCastException
+ ((new java::lang::StringBuffer
+ (obj->getClass()->getName()))->append
+ (JvNewStringUTF(" cannot be cast to "))->append
+ (c->getName())->toString());
+
+ return obj;
+}
+
+void
+_Jv_CheckArrayStore (jobject arr, jobject obj)
+{
+ if (obj)
+ {
+ JvAssert (arr != NULL);
+ jclass elt_class = (JV_CLASS (arr))->getComponentType();
+ if (elt_class == &java::lang::Object::class$)
+ return;
+ jclass obj_class = JV_CLASS (obj);
+ if (__builtin_expect
+ (! _Jv_IsAssignableFrom (obj_class, elt_class), false))
+ throw new java::lang::ArrayStoreException
+ ((new java::lang::StringBuffer
+ (JvNewStringUTF("Cannot store ")))->append
+ (obj_class->getName())->append
+ (JvNewStringUTF(" in array of type "))->append
+ (elt_class->getName())->toString());
+ }
+}
+
+jboolean
+_Jv_IsAssignableFromSlow (jclass source, jclass target)
+{
+ // First, strip arrays.
+ while (target->isArray ())
+ {
+ // If target is array, source must be as well.
+ if (! source->isArray ())
+ return false;
+ target = target->getComponentType ();
+ source = source->getComponentType ();
+ }
+
+ // Quick success.
+ if (target == &java::lang::Object::class$)
+ return true;
+
+ // Ensure that the classes have their supers installed.
+ _Jv_Linker::wait_for_state (source, JV_STATE_LOADING);
+ _Jv_Linker::wait_for_state (target, JV_STATE_LOADING);
+
+ do
+ {
+ if (source == target)
+ return true;
+
+ if (target->isPrimitive () || source->isPrimitive ())
+ return false;
+
+ if (target->isInterface ())
+ {
+ for (int i = 0; i < source->interface_count; ++i)
+ {
+ // We use a recursive call because we also need to
+ // check superinterfaces.
+ if (_Jv_IsAssignableFromSlow (source->getInterface (i), target))
+ return true;
+ }
+ }
+ source = source->getSuperclass ();
+ }
+ while (source != NULL);
+
+ return false;
+}
+
+// Lookup an interface method by name. This is very similar to
+// purpose to _getMethod, but the interfaces are quite different. It
+// might be a good idea for _getMethod to call this function.
+//
+// Return true of the method is found, with the class in FOUND_CLASS
+// and the index in INDEX.
+bool
+_Jv_getInterfaceMethod (jclass search_class, jclass &found_class, int &index,
+ const _Jv_Utf8Const *utf_name,
+ const _Jv_Utf8Const *utf_sig)
+{
+ for (jclass klass = search_class; klass; klass = klass->getSuperclass())
+ {
+ // FIXME: Throw an exception?
+ if (!klass->isInterface ())
+ return false;
+
+ int max = klass->method_count;
+ int offset = 0;
+ for (int i = 0; i < max; ++i)
+ {
+ // Skip <clinit> here, as it will not be in the IDT.
+ if (klass->methods[i].name->first() == '<')
+ continue;
+
+ if (_Jv_equalUtf8Consts (klass->methods[i].name, utf_name)
+ && _Jv_equalUtf8Consts (klass->methods[i].signature, utf_sig))
+ {
+ // Found it.
+ using namespace java::lang::reflect;
+
+ // FIXME: Method must be public. Throw an exception?
+ if (! Modifier::isPublic (klass->methods[i].accflags))
+ break;
+
+ found_class = klass;
+ // Interface method indexes count from 1.
+ index = offset + 1;
+ return true;
+ }
+
+ ++offset;
+ }
+ }
+
+ // If we haven't found a match, and this class is an interface, then
+ // check all the superinterfaces.
+ if (search_class->isInterface())
+ {
+ for (int i = 0; i < search_class->interface_count; ++i)
+ {
+ using namespace java::lang::reflect;
+ bool found = _Jv_getInterfaceMethod (search_class->interfaces[i],
+ found_class, index,
+ utf_name, utf_sig);
+ if (found)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#ifdef INTERPRETER
+_Jv_MethodBase *
+_Jv_FindInterpreterMethod (jclass klass, jmethodID desired_method)
+{
+ using namespace java::lang::reflect;
+
+ _Jv_InterpClass *iclass
+ = reinterpret_cast<_Jv_InterpClass *> (klass->aux_info);
+ _Jv_MethodBase **imethods = _Jv_GetFirstMethod (iclass);
+
+ for (int i = 0; i < JvNumMethods (klass); ++i)
+ {
+ _Jv_MethodBase *imeth = imethods[i];
+ if (imeth->get_method () == desired_method)
+ return imeth;
+ }
+
+ return NULL;
+}
+#endif
+
+// Return Utf8 name of a class. This function is here for code that
+// can't access klass->name directly.
+_Jv_Utf8Const*
+_Jv_GetClassNameUtf8 (jclass klass)
+{
+ return klass->name;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natClassLoader.cc b/gcc-4.2.1/libjava/java/lang/natClassLoader.cc
new file mode 100644
index 000000000..2400e0ce2
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natClassLoader.cc
@@ -0,0 +1,624 @@
+// natClassLoader.cc - Implementation of java.lang.ClassLoader native methods.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Author: Kresten Krab Thorup <krab@gnu.org> */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <execution.h>
+
+#include <java-threads.h>
+#include <java-interp.h>
+
+#include <java/lang/Character.h>
+#include <java/lang/Thread.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/IllegalAccessError.h>
+#include <java/lang/LinkageError.h>
+#include <java/lang/NoClassDefFoundError.h>
+#include <java/lang/ClassNotFoundException.h>
+#include <java/lang/ClassCircularityError.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/ClassFormatError.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/Runtime.h>
+#include <java/lang/StringBuffer.h>
+#include <java/io/Serializable.h>
+#include <java/lang/Cloneable.h>
+#include <java/util/HashMap.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+
+// Size of local hash table.
+#define HASH_LEN 1013
+
+// Hash function for Utf8Consts.
+#define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
+
+// This records classes which will be registered with the system class
+// loader when it is initialized.
+static jclass system_class_list;
+
+// This is used as the value of system_class_list after we have
+// initialized the system class loader; it lets us know that we should
+// no longer pay attention to the system abi flag.
+#define SYSTEM_LOADER_INITIALIZED ((jclass) -1)
+
+static jclass loaded_classes[HASH_LEN];
+
+// This is the root of a linked list of classes
+static jclass stack_head;
+
+// While bootstrapping we keep a list of classes we found, so that we
+// can register their packages. There aren't many of these so we
+// just keep a small buffer here and abort if we overflow.
+#define BOOTSTRAP_CLASS_LIST_SIZE 20
+static jclass bootstrap_class_list[BOOTSTRAP_CLASS_LIST_SIZE];
+static int bootstrap_index;
+
+
+
+
+jclass
+java::lang::ClassLoader::loadClassFromSig(jstring name)
+{
+ int len = _Jv_GetStringUTFLength (name);
+ char sig[len + 1];
+ _Jv_GetStringUTFRegion (name, 0, name->length(), sig);
+ jclass result = _Jv_FindClassFromSignature(sig, this);
+ if (result == NULL)
+ throw new ClassNotFoundException(name);
+ return result;
+}
+
+
+
+// This tries to find a class in our built-in cache. This cache is
+// used only for classes which are linked in to the executable or
+// loaded via dlopen().
+jclass
+_Jv_FindClassInCache (_Jv_Utf8Const *name)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ jint hash = HASH_UTF (name);
+
+ jclass klass;
+ for (klass = loaded_classes[hash]; klass; klass = klass->next_or_version)
+ {
+ if (_Jv_equalUtf8Consts (name, klass->name))
+ break;
+ }
+
+ return klass;
+}
+
+void
+_Jv_UnregisterClass (jclass the_class)
+{
+ // This can happen if the class could not be defined properly.
+ if (! the_class->name)
+ return;
+
+ JvSynchronize sync (&java::lang::Class::class$);
+ jint hash = HASH_UTF(the_class->name);
+
+ jclass *klass = &(loaded_classes[hash]);
+ for ( ; *klass; klass = &((*klass)->next_or_version))
+ {
+ if (*klass == the_class)
+ {
+ *klass = (*klass)->next_or_version;
+ break;
+ }
+ }
+}
+
+// Register an initiating class loader for a given class.
+void
+_Jv_RegisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
+{
+ if (! loader)
+ loader = java::lang::VMClassLoader::bootLoader;
+ if (! loader)
+ {
+ // Very early in the bootstrap process, the Bootstrap classloader may
+ // not exist yet.
+ // FIXME: We could maintain a list of these and come back and register
+ // them later.
+ return;
+ }
+ loader->loadedClasses->put(klass->name->toString(), klass);
+}
+
+// If we found an error while defining an interpreted class, we must
+// go back and unregister it.
+void
+_Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
+{
+ if (! loader)
+ loader = java::lang::VMClassLoader::bootLoader;
+ loader->loadedClasses->remove(klass->name->toString());
+}
+
+
+// Class registration.
+//
+// There are two kinds of functions that register classes.
+//
+// Type 1:
+//
+// These take the address of a class that is in an object file.
+// Because these classes are not allocated on the heap, It is also
+// necessary to register the address of the object for garbage
+// collection. This is used with the "old" C++ ABI and with
+// -findirect-dispatch -fno-indirect-classes.
+//
+// Type 2:
+//
+// These take an initializer struct, create the class, and return the
+// address of the newly created class to their caller. These are used
+// with -findirect-dispatch.
+//
+// _Jv_RegisterClasses() and _Jv_RegisterClasses_Counted() are
+// functions of Type 1, and _Jv_NewClassFromInitializer() and
+// _Jv_RegisterNewClasses() are of Type 2.
+
+
+// This function is called many times during startup, before main() is
+// run. At that point in time we know for certain we are running
+// single-threaded, so we don't need to lock when adding classes to the
+// class chain. At all other times, the caller should synchronize on
+// Class::class$.
+void
+_Jv_RegisterClasses (const jclass *classes)
+{
+ _Jv_RegisterLibForGc (classes);
+
+ for (; *classes; ++classes)
+ {
+ jclass klass = *classes;
+
+ if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version))
+ (*_Jv_RegisterClassHook) (klass);
+ }
+}
+
+// This is a version of _Jv_RegisterClasses that takes a count.
+void
+_Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
+{
+ size_t i;
+
+ _Jv_RegisterLibForGc (classes);
+
+ for (i = 0; i < count; i++)
+ {
+ jclass klass = classes[i];
+
+ if (_Jv_CheckABIVersion ((unsigned long) klass->next_or_version))
+ (*_Jv_RegisterClassHook) (klass);
+ }
+}
+
+// Create a class on the heap from an initializer struct.
+jclass
+_Jv_NewClassFromInitializer (const char *class_initializer)
+{
+ /* We create an instance of java::lang::Class and copy all of its
+ fields except the first word (the vtable pointer) from
+ CLASS_INITIALIZER. This first word is pre-initialized by
+ _Jv_AllocObj, and we don't want to overwrite it. */
+
+ jclass new_class
+ = (jclass)_Jv_AllocObj (sizeof (java::lang::Class),
+ &java::lang::Class::class$);
+ const char *src = class_initializer + sizeof (void*);
+ char *dst = (char*)new_class + sizeof (void*);
+ size_t len = sizeof (*new_class) - sizeof (void*);
+ memcpy (dst, src, len);
+
+ new_class->engine = &_Jv_soleIndirectCompiledEngine;
+
+ /* FIXME: Way back before the dawn of time, we overloaded the
+ SYNTHETIC class access modifier to mean INTERPRETED. This was a
+ Bad Thing, but it didn't matter then because classes were never
+ marked synthetic. However, it is possible to redeem the
+ situation: _Jv_NewClassFromInitializer is only called from
+ compiled classes, so we clear the INTERPRETED flag. This is a
+ kludge! */
+ new_class->accflags &= ~java::lang::reflect::Modifier::INTERPRETED;
+
+ if (_Jv_CheckABIVersion ((unsigned long) new_class->next_or_version))
+ (*_Jv_RegisterClassHook) (new_class);
+
+ return new_class;
+}
+
+// Called by compiler-generated code at DSO initialization. CLASSES
+// is an array of pairs: the first item of each pair is a pointer to
+// the initialized data that is a class initializer in a DSO, and the
+// second is a pointer to a class reference.
+// _Jv_NewClassFromInitializer() creates the new class (on the Java
+// heap) and we write the address of the new class into the address
+// pointed to by the second word.
+void
+_Jv_RegisterNewClasses (char **classes)
+{
+ _Jv_InitGC ();
+
+ const char *initializer;
+
+ while ((initializer = *classes++))
+ {
+ jclass *class_ptr = (jclass *)*classes++;
+ *class_ptr = _Jv_NewClassFromInitializer (initializer);
+ }
+}
+
+void
+_Jv_RegisterClassHookDefault (jclass klass)
+{
+ // This is bogus, but there doesn't seem to be a better place to do
+ // it.
+ if (! klass->engine)
+ klass->engine = &_Jv_soleCompiledEngine;
+
+ if (system_class_list != SYSTEM_LOADER_INITIALIZED)
+ {
+ unsigned long abi = (unsigned long) klass->next_or_version;
+ if (! _Jv_ClassForBootstrapLoader (abi))
+ {
+ klass->next_or_version = system_class_list;
+ system_class_list = klass;
+ return;
+ }
+ }
+
+ jint hash = HASH_UTF (klass->name);
+
+ // If the class is already registered, don't re-register it.
+ for (jclass check_class = loaded_classes[hash];
+ check_class != NULL;
+ check_class = check_class->next_or_version)
+ {
+ if (check_class == klass)
+ {
+ // If you get this, it means you have the same class in two
+ // different libraries.
+#define TEXT "Duplicate class registration: "
+ // We size-limit MESSAGE so that you can't trash the stack.
+ char message[200];
+ strcpy (message, TEXT);
+ strncpy (message + sizeof (TEXT) - 1, klass->name->chars(),
+ sizeof (message) - sizeof (TEXT));
+ message[sizeof (message) - 1] = '\0';
+ if (! gcj::runtimeInitialized)
+ JvFail (message);
+ else
+ {
+ java::lang::String *str = JvNewStringLatin1 (message);
+ throw new java::lang::VirtualMachineError (str);
+ }
+ }
+ }
+
+ klass->next_or_version = loaded_classes[hash];
+ loaded_classes[hash] = klass;
+}
+
+// A pointer to a function that actually registers a class.
+// Normally _Jv_RegisterClassHookDefault, but could be some other function
+// that registers the class in e.g. a ClassLoader-local table.
+// Should synchronize on Class:class$ while setting/restore this variable.
+
+void (*_Jv_RegisterClassHook) (jclass cl) = _Jv_RegisterClassHookDefault;
+
+void
+_Jv_RegisterClass (jclass klass)
+{
+ jclass classes[2];
+ classes[0] = klass;
+ classes[1] = NULL;
+ _Jv_RegisterClasses (classes);
+}
+
+// This is used during initialization to register all compiled-in
+// classes that are not part of the core with the system class loader.
+void
+_Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *loader)
+{
+ for (jclass klass = system_class_list;
+ klass;
+ klass = klass->next_or_version)
+ {
+ klass->loader = loader;
+ loader->addClass(klass);
+ }
+ system_class_list = SYSTEM_LOADER_INITIALIZED;
+}
+
+// An internal variant of _Jv_FindClass which simply swallows a
+// NoClassDefFoundError or a ClassNotFoundException. This gives the
+// caller a chance to evaluate the situation and behave accordingly.
+jclass
+_Jv_FindClassNoException (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
+{
+ jclass klass;
+
+ try
+ {
+ klass = _Jv_FindClass(name, loader);
+ }
+ catch ( java::lang::NoClassDefFoundError *ncdfe )
+ {
+ return NULL;
+ }
+ catch ( java::lang::ClassNotFoundException *cnfe )
+ {
+ return NULL;
+ }
+
+ return klass;
+}
+
+jclass
+_Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
+{
+ // See if the class was already loaded by this loader. This handles
+ // initiating loader checks, as we register classes with their
+ // initiating loaders.
+
+ java::lang::ClassLoader *boot = java::lang::VMClassLoader::bootLoader;
+ java::lang::ClassLoader *real = loader;
+ if (! real)
+ real = boot;
+ jstring sname = name->toString();
+ // We might still be bootstrapping the VM, in which case there
+ // won't be a bootstrap class loader yet.
+ jclass klass = real ? real->findLoadedClass (sname) : NULL;
+
+ if (! klass)
+ {
+ if (loader)
+ {
+ // Load using a user-defined loader, jvmspec 5.3.2.
+ // Note that we explicitly must call the single-argument form.
+ klass = loader->loadClass(sname);
+
+ // If "loader" delegated the loadClass operation to another
+ // loader, explicitly register that it is also an initiating
+ // loader of the given class.
+ java::lang::ClassLoader *delegate = (loader == boot
+ ? NULL
+ : loader);
+ if (klass && klass->getClassLoaderInternal () != delegate)
+ _Jv_RegisterInitiatingLoader (klass, loader);
+ }
+ else if (boot)
+ {
+ // Load using the bootstrap loader jvmspec 5.3.1.
+ klass = java::lang::VMClassLoader::loadClass (sname, false);
+
+ // Register that we're an initiating loader.
+ if (klass)
+ _Jv_RegisterInitiatingLoader (klass, 0);
+ }
+ else
+ {
+ // Not even a bootstrap loader, try the built-in cache.
+ klass = _Jv_FindClassInCache (name);
+
+ if (klass)
+ {
+ bool found = false;
+ for (int i = 0; i < bootstrap_index; ++i)
+ {
+ if (bootstrap_class_list[i] == klass)
+ {
+ found = true;
+ break;
+ }
+ }
+ if (! found)
+ {
+ if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
+ abort ();
+ bootstrap_class_list[bootstrap_index++] = klass;
+ }
+ }
+ }
+ }
+
+ return klass;
+}
+
+void
+_Jv_RegisterBootstrapPackages ()
+{
+ for (int i = 0; i < bootstrap_index; ++i)
+ java::lang::VMClassLoader::definePackageForNative(bootstrap_class_list[i]->getName());
+}
+
+jclass
+_Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
+ java::lang::ClassLoader *loader)
+{
+ jclass ret = (jclass) _Jv_AllocObject (&java::lang::Class::class$);
+ ret->name = name;
+ ret->superclass = superclass;
+ ret->loader = loader;
+
+ _Jv_RegisterInitiatingLoader (ret, loader);
+
+ return ret;
+}
+
+static _Jv_IDispatchTable *array_idt = NULL;
+static jshort array_depth = 0;
+static jclass *array_ancestors = NULL;
+
+static jclass interfaces[] =
+{
+ &java::lang::Cloneable::class$,
+ &java::io::Serializable::class$
+};
+
+// Create a class representing an array of ELEMENT and store a pointer to it
+// in element->arrayclass. LOADER is the ClassLoader which _initiated_ the
+// instantiation of this array. ARRAY_VTABLE is the vtable to use for the new
+// array class. This parameter is optional.
+void
+_Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
+ _Jv_VTable *array_vtable)
+{
+ JvSynchronize sync (element);
+
+ _Jv_Utf8Const *array_name;
+ int len;
+
+ if (element->arrayclass)
+ return;
+
+ if (element->isPrimitive())
+ {
+ if (element == JvPrimClass (void))
+ throw new java::lang::ClassNotFoundException ();
+ len = 3;
+ }
+ else
+ len = element->name->len() + 5;
+
+ {
+ char signature[len];
+ int index = 0;
+ signature[index++] = '[';
+ // Compute name of array class.
+ if (element->isPrimitive())
+ {
+ signature[index++] = (char) element->method_count;
+ }
+ else
+ {
+ size_t length = element->name->len();
+ const char *const name = element->name->chars();
+ if (name[0] != '[')
+ signature[index++] = 'L';
+ memcpy (&signature[index], name, length);
+ index += length;
+ if (name[0] != '[')
+ signature[index++] = ';';
+ }
+ array_name = _Jv_makeUtf8Const (signature, index);
+ }
+
+ // Create new array class.
+ jclass array_class = _Jv_NewClass (array_name, &java::lang::Object::class$,
+ element->loader);
+
+ // Note that `vtable_method_count' doesn't include the initial
+ // gc_descr slot.
+ int dm_count = java::lang::Object::class$.vtable_method_count;
+
+ // Create a new vtable by copying Object's vtable.
+ _Jv_VTable *vtable;
+ if (array_vtable)
+ vtable = array_vtable;
+ else
+ vtable = _Jv_VTable::new_vtable (dm_count);
+ vtable->clas = array_class;
+ vtable->gc_descr = java::lang::Object::class$.vtable->gc_descr;
+ for (int i = 0; i < dm_count; ++i)
+ vtable->set_method (i, java::lang::Object::class$.vtable->get_method (i));
+
+ array_class->vtable = vtable;
+ array_class->vtable_method_count
+ = java::lang::Object::class$.vtable_method_count;
+
+ // Stash the pointer to the element type.
+ array_class->element_type = element;
+
+ // Register our interfaces.
+ array_class->interfaces = interfaces;
+ array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
+
+ // Since all array classes have the same interface dispatch table, we can
+ // cache one and reuse it. It is not necessary to synchronize this.
+ if (!array_idt)
+ {
+ _Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
+ array_idt = array_class->idt;
+ array_depth = array_class->depth;
+ array_ancestors = array_class->ancestors;
+ }
+ else
+ {
+ array_class->idt = array_idt;
+ array_class->depth = array_depth;
+ array_class->ancestors = array_ancestors;
+ }
+
+ using namespace java::lang::reflect;
+ {
+ // Array classes are "abstract final" and inherit accessibility
+ // from element type, per vmspec 5.3.3.2
+ _Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
+ | (element->accflags
+ & (Modifier::PUBLIC | Modifier::PROTECTED
+ | Modifier::PRIVATE)));
+ array_class->accflags = accflags;
+ }
+
+ // An array class has no visible instance fields. "length" is invisible to
+ // reflection.
+
+ // Say this class is initialized and ready to go!
+ array_class->state = JV_STATE_DONE;
+
+ // vmspec, section 5.3.3 describes this
+ if (element->loader != loader)
+ _Jv_RegisterInitiatingLoader (array_class, loader);
+
+ element->arrayclass = array_class;
+}
+
+// These two functions form a stack of classes. When a class is loaded
+// it is pushed onto the stack by the class loader; this is so that
+// StackTrace can quickly determine which classes have been loaded.
+
+jclass
+_Jv_PopClass (void)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ if (stack_head)
+ {
+ jclass tmp = stack_head;
+ stack_head = tmp->chain;
+ return tmp;
+ }
+ return NULL;
+}
+
+void
+_Jv_PushClass (jclass k)
+{
+ JvSynchronize sync (&java::lang::Class::class$);
+ jclass tmp = stack_head;
+ stack_head = k;
+ k->chain = tmp;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natDouble.cc b/gcc-4.2.1/libjava/java/lang/natDouble.cc
new file mode 100644
index 000000000..1a33a5715
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natDouble.cc
@@ -0,0 +1,214 @@
+// natDouble.cc - Implementation of java.lang.VMDouble native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <java/lang/String.h>
+#include <java/lang/Double.h>
+#include <java/lang/VMDouble.h>
+#include <java/lang/Character.h>
+#include <java/lang/NumberFormatException.h>
+#include <jvm.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "fdlibm.h"
+
+union u
+{
+ jlong l;
+ jdouble d;
+};
+
+jlong
+java::lang::VMDouble::doubleToLongBits(jdouble value)
+{
+ union u u;
+ u.d = value;
+
+ jlong e = u.l & 0x7ff0000000000000LL;
+ jlong f = u.l & 0x000fffffffffffffLL;
+
+ if (e == 0x7ff0000000000000LL && f != 0L)
+ u.l = 0x7ff8000000000000LL;
+
+ return u.l;
+}
+
+jlong
+java::lang::VMDouble::doubleToRawLongBits(jdouble value)
+{
+ union u u;
+ u.d = value;
+ return u.l;
+}
+
+jdouble
+java::lang::VMDouble::longBitsToDouble(jlong bits)
+{
+ union u u;
+ u.l = bits;
+ return u.d;
+}
+
+jstring
+java::lang::VMDouble::toString(jdouble value, jboolean isFloat)
+{
+ if (Double::isNaN (value))
+ return JvNewStringLatin1 ("NaN", sizeof ("NaN") - 1);
+
+ if (value == Double::POSITIVE_INFINITY)
+ return JvNewStringLatin1 ("Infinity", sizeof ("Infinity") - 1);
+
+ if (value == Double::NEGATIVE_INFINITY)
+ return JvNewStringLatin1 ("-Infinity", sizeof ("-Infinity") - 1);
+
+ char buffer[50], result[50];
+ int decpt, sign;
+
+ _dtoa (value, 0, 20, &decpt, &sign, NULL, buffer, (int)isFloat);
+
+ value = fabs (value);
+
+ char *s = buffer;
+ char *d = result;
+
+ if (sign)
+ *d++ = '-';
+
+ if (value >= 1e-3 && value < 1e7 || value == 0)
+ {
+ if (decpt <= 0)
+ *d++ = '0';
+ else
+ {
+ for (int i = 0; i < decpt; i++)
+ if (*s)
+ *d++ = *s++;
+ else
+ *d++ = '0';
+ }
+
+ *d++ = '.';
+
+ if (*s == 0)
+ {
+ *d++ = '0';
+ decpt++;
+ }
+
+ while (decpt++ < 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d = 0;
+
+ return JvNewStringLatin1 (result, strlen (result));
+ }
+
+ *d++ = *s++;
+ decpt--;
+ *d++ = '.';
+
+ if (*s == 0)
+ *d++ = '0';
+
+ while (*s)
+ *d++ = *s++;
+
+ *d++ = 'E';
+
+ if (decpt < 0)
+ {
+ *d++ = '-';
+ decpt = -decpt;
+ }
+
+ {
+ char exp[4];
+ char *e = exp + sizeof exp;
+
+ *--e = 0;
+ do
+ {
+ *--e = '0' + decpt % 10;
+ decpt /= 10;
+ }
+ while (decpt > 0);
+
+ while (*e)
+ *d++ = *e++;
+ }
+
+ *d = 0;
+
+ return JvNewStringLatin1 (result, strlen (result));
+}
+
+jdouble
+java::lang::VMDouble::parseDouble(jstring str)
+{
+ int length = str->length();
+
+ while (length > 0
+ && Character::isWhitespace(str->charAt(length - 1)))
+ length--;
+
+ // The String could end with a f/F/d/D which is valid but we don't need.
+ bool saw_trailer = false;
+ if (length > 0)
+ {
+ jchar last = str->charAt(length-1);
+ if (last == 'f' || last == 'F' || last == 'd' || last == 'D')
+ {
+ length--;
+ saw_trailer = true;
+ }
+ }
+
+ jsize start = 0;
+ while (length > 0
+ && Character::isWhitespace(str->charAt(start)))
+ start++, length--;
+
+ if (length > 0)
+ {
+ // Note that UTF can expand 3x.
+ char *data = (char *) __builtin_alloca (3 * length + 1);
+ jsize blength = _Jv_GetStringUTFRegion (str, start, length, data);
+ data[blength] = 0;
+
+ if (! saw_trailer)
+ {
+ if (! strcmp (data, "NaN") || ! strcmp (data, "+NaN")
+ || ! strcmp (data, "-NaN"))
+ return Double::NaN;
+ else if (! strcmp (data, "Infinity") || ! strcmp (data, "+Infinity"))
+ return Double::POSITIVE_INFINITY;
+ else if (! strcmp (data, "-Infinity"))
+ return Double::NEGATIVE_INFINITY;
+ }
+
+ struct _Jv_reent reent;
+ memset (&reent, 0, sizeof reent);
+
+ char *endptr;
+ double val = _strtod_r (&reent, data, &endptr);
+ if (endptr == data + blength)
+ return val;
+ }
+ throw new NumberFormatException(str);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natEcosProcess.cc b/gcc-4.2.1/libjava/java/lang/natEcosProcess.cc
new file mode 100644
index 000000000..9cfb19e70
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natEcosProcess.cc
@@ -0,0 +1,25 @@
+// natEcosProcess.cc - Native side of eCos processes.
+
+/* Copyright (C) 1998, 1999 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// The configury system needs this file to exist, since we can't
+// really conditionally link files (an autoconf bug). To avoid having
+// an empty translation unit, we make a single method native. FIXME.
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/lang/ConcreteProcess.h>
+
+void
+java::lang::ConcreteProcess::destroy (void)
+{
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natFloat.cc b/gcc-4.2.1/libjava/java/lang/natFloat.cc
new file mode 100644
index 000000000..f090b815e
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natFloat.cc
@@ -0,0 +1,52 @@
+// natFloat.cc - Implementation of java.lang.VMFloat native methods.
+
+/* Copyright (C) 1998, 1999, 2001, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <java/lang/Float.h>
+#include <java/lang/VMFloat.h>
+#include <jvm.h>
+
+union u
+{
+ jint l;
+ jfloat d;
+};
+
+jint
+java::lang::VMFloat::floatToIntBits(jfloat value)
+{
+ union u u;
+ u.d = value;
+ jint e = u.l & 0x7f800000;
+ jint f = u.l & 0x007fffff;
+
+ if (e == 0x7f800000 && f != 0)
+ u.l = 0x7fc00000;
+
+ return u.l;
+}
+
+jint
+java::lang::VMFloat::floatToRawIntBits(jfloat value)
+{
+ union u u;
+ u.d = value;
+ return u.l;
+}
+
+jfloat
+java::lang::VMFloat::intBitsToFloat(jint bits)
+{
+ union u u;
+ u.l = bits;
+ return u.d;
+}
+
diff --git a/gcc-4.2.1/libjava/java/lang/natMath.cc b/gcc-4.2.1/libjava/java/lang/natMath.cc
new file mode 100644
index 000000000..d86d6307d
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natMath.cc
@@ -0,0 +1,184 @@
+/* Copyright (C) 1998, 1999, 2000, 2002, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @date Tue Sep 22 1998 */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
+ * "The Java Language Specification", ISBN 0-201-63451-1
+ * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
+ * Status: Believed complete and correct.
+ */
+
+#include <config.h>
+
+#include <java/lang/String.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Math.h>
+#include <gcj/array.h>
+
+#include "fdlibm.h"
+
+jdouble java::lang::Math::cos(jdouble x)
+{
+ return (jdouble)::cos((double)x);
+}
+
+jdouble java::lang::Math::sin(jdouble x)
+{
+ return (jdouble)::sin((double)x);
+}
+
+jdouble java::lang::Math::tan(jdouble x)
+{
+ return (jdouble)::tan((double)x);
+}
+
+jdouble java::lang::Math::asin(jdouble x)
+{
+ return (jdouble)::asin((double)x);
+}
+
+jdouble java::lang::Math::acos(jdouble x)
+{
+ return (jdouble)::acos((double)x);
+}
+
+jdouble java::lang::Math::atan(jdouble x)
+{
+ return (jdouble)::atan((double)x);
+}
+
+jdouble java::lang::Math::atan2(jdouble y, jdouble x)
+{
+ return (jdouble)::atan2((double)y, (double)x);
+}
+
+jdouble java::lang::Math::log(jdouble x)
+{
+ return (jdouble)::log((double)x);
+}
+
+jdouble java::lang::Math::exp(jdouble x)
+{
+ return (jdouble)::exp((double)x);
+}
+
+jdouble java::lang::Math::sqrt(jdouble x)
+{
+ return (jdouble)::sqrt((double)x);
+}
+
+jdouble java::lang::Math::pow(jdouble y, jdouble x)
+{
+ return (jdouble)::pow((double)y, (double)x);
+}
+
+jdouble java::lang::Math::IEEEremainder(jdouble y, jdouble x)
+{
+ return (jdouble)::__ieee754_remainder((double)y, (double)x);
+}
+
+jdouble java::lang::Math::rint(jdouble x)
+{
+ return (jdouble)::rint((double)x);
+}
+
+jdouble java::lang::Math::floor(jdouble x)
+{
+ return (jdouble)::floor((double)x);
+}
+
+jdouble java::lang::Math::ceil(jdouble x)
+{
+ return (jdouble)::ceil((double)x);
+}
+
+jdouble java::lang::Math::log10(jdouble x)
+{
+ return (jdouble)::log10((double)x);
+}
+
+jdouble java::lang::Math::cbrt(jdouble x)
+{
+ return (jdouble)::cbrt((double)x);
+}
+
+jdouble java::lang::Math::cosh(jdouble x)
+{
+ return (jdouble)::cosh((double)x);
+}
+
+jdouble java::lang::Math::expm1(jdouble x)
+{
+ return (jdouble)::expm1((double)x);
+}
+
+jdouble java::lang::Math::hypot(jdouble x, jdouble y)
+{
+ return (jdouble)::hypot((double)x, (double)y);
+}
+
+jdouble java::lang::Math::log1p(jdouble x)
+{
+ return (jdouble)::log1p((double)x);
+}
+
+jdouble java::lang::Math::sinh(jdouble x)
+{
+ return (jdouble)::sinh((double)x);
+}
+
+jdouble java::lang::Math::tanh(jdouble x)
+{
+ return (jdouble)::tanh((double)x);
+}
+
+static inline int
+floatToIntBits (jfloat value)
+{
+ union {
+ jint l;
+ jfloat d;
+ } u;
+ u.d = value;
+ return u.l;
+}
+
+static inline bool
+isNaN (jint bits)
+{
+ jint e = bits & 0x7f800000;
+ jint f = bits & 0x007fffff;
+
+ return e == 0x7f800000 && f != 0;
+}
+
+static inline jlong
+doubleToLongBits (jdouble value)
+{
+ union {
+ jlong l;
+ jdouble d;
+ } u;
+ u.d = value;
+ return u.l;
+}
+
+static inline bool
+isNaN (jlong bits)
+{
+ jlong e = bits & 0x7ff0000000000000LL;
+ jlong f = bits & 0x000fffffffffffffLL;
+
+ return e == 0x7ff0000000000000LL && f != 0LL;
+}
+
diff --git a/gcc-4.2.1/libjava/java/lang/natObject.cc b/gcc-4.2.1/libjava/java/lang/natObject.cc
new file mode 100644
index 000000000..87f2044dd
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natObject.cc
@@ -0,0 +1,1457 @@
+// natObject.cc - Implementation of the Object class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <string.h>
+
+#pragma implementation "Object.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java-signal.h>
+#include <java/lang/CloneNotSupportedException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalMonitorStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Class.h>
+#include <java/lang/Cloneable.h>
+#include <java/lang/Thread.h>
+
+#ifdef LOCK_DEBUG
+# include <stdio.h>
+#endif
+
+
+
+using namespace java::lang;
+
+// This is used to represent synchronization information.
+struct _Jv_SyncInfo
+{
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // We only need to keep track of initialization state if we can
+ // possibly finalize this object.
+ bool init;
+#endif
+ _Jv_ConditionVariable_t condition;
+ _Jv_Mutex_t mutex;
+};
+
+
+
+jclass
+java::lang::Object::getClass (void)
+{
+ _Jv_VTable **dt = (_Jv_VTable **) this;
+ return (*dt)->clas;
+}
+
+jint
+java::lang::Object::hashCode (void)
+{
+ return _Jv_HashCode (this);
+}
+
+jobject
+java::lang::Object::clone (void)
+{
+ jclass klass = getClass ();
+ jobject r;
+ jint size;
+
+ // We also clone arrays here. If we put the array code into
+ // __JArray, then we'd have to figure out a way to find the array
+ // vtbl when creating a new array class. This is easier, if uglier.
+ if (klass->isArray())
+ {
+ __JArray *array = (__JArray *) this;
+ jclass comp = getClass()->getComponentType();
+ jint eltsize;
+ if (comp->isPrimitive())
+ {
+ r = _Jv_NewPrimArray (comp, array->length);
+ eltsize = comp->size();
+ }
+ else
+ {
+ r = _Jv_NewObjectArray (array->length, comp, NULL);
+ eltsize = sizeof (jobject);
+ }
+ // We can't use sizeof on __JArray because we must account for
+ // alignment of the element type.
+ size = (_Jv_GetArrayElementFromElementType (array, comp) - (char *) array
+ + array->length * eltsize);
+ }
+ else
+ {
+ if (! java::lang::Cloneable::class$.isAssignableFrom(klass))
+ throw new CloneNotSupportedException;
+
+ size = klass->size();
+ r = _Jv_AllocObject (klass);
+ }
+
+ memcpy ((void *) r, (void *) this, size);
+#ifndef JV_HASH_SYNCHRONIZATION
+ // Guarantee that the locks associated to the two objects are
+ // distinct.
+ r->sync_info = NULL;
+#endif
+ return r;
+}
+
+void
+_Jv_FinalizeObject (jobject obj)
+{
+ // Ignore exceptions. From section 12.6 of the Java Language Spec.
+ try
+ {
+ obj->finalize ();
+ }
+ catch (java::lang::Throwable *t)
+ {
+ // Ignore.
+ }
+}
+
+
+//
+// Synchronization code.
+//
+
+#ifndef JV_HASH_SYNCHRONIZATION
+// This global is used to make sure that only one thread sets an
+// object's `sync_info' field.
+static _Jv_Mutex_t sync_mutex;
+
+// This macro is used to see if synchronization initialization is
+// needed.
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info \
+ || ! ((_Jv_SyncInfo *) ((Obj)->sync_info))->init)
+#else
+# define INIT_NEEDED(Obj) (! (Obj)->sync_info)
+#endif
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function is registered as a finalizer for the sync_info.
+static void
+finalize_sync_info (jobject obj)
+{
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj;
+#if defined (_Jv_HaveCondDestroy)
+ _Jv_CondDestroy (&si->condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+ _Jv_MutexDestroy (&si->mutex);
+#endif
+ si->init = false;
+}
+#endif
+
+// This is called to initialize the sync_info element of an object.
+void
+java::lang::Object::sync_init (void)
+{
+ _Jv_MutexLock (&sync_mutex);
+ // Check again to see if initialization is needed now that we have
+ // the lock.
+ if (INIT_NEEDED (this))
+ {
+ // We assume there are no pointers in the sync_info
+ // representation.
+ _Jv_SyncInfo *si;
+ // We always create a new sync_info, even if there is already
+ // one available. Any given object can only be finalized once.
+ // If we get here and sync_info is not null, then it has already
+ // been finalized. So if we just reinitialize the old one,
+ // we'll never be able to (re-)destroy the mutex and/or
+ // condition variable.
+ si = (_Jv_SyncInfo *) _Jv_AllocBytes (sizeof (_Jv_SyncInfo));
+ _Jv_MutexInit (&si->mutex);
+ _Jv_CondInit (&si->condition);
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Register a finalizer.
+ si->init = true;
+ _Jv_RegisterFinalizer (si, finalize_sync_info);
+#endif
+ sync_info = (jobject) si;
+ }
+ _Jv_MutexUnlock (&sync_mutex);
+}
+
+void
+java::lang::Object::notify (void)
+{
+ if (__builtin_expect (INIT_NEEDED (this), false))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (__builtin_expect (_Jv_CondNotify (&si->condition, &si->mutex), false))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+ if (__builtin_expect (INIT_NEEDED (this), false))
+ sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ if (__builtin_expect (_Jv_CondNotifyAll (&si->condition, &si->mutex), false))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+ if (__builtin_expect (INIT_NEEDED (this), false))
+ sync_init ();
+ if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
+ throw new IllegalArgumentException;
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) sync_info;
+ switch (_Jv_CondWait (&si->condition, &si->mutex, timeout, nanos))
+ {
+ case _JV_NOT_OWNER:
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ case _JV_INTERRUPTED:
+ if (Thread::interrupted ())
+ throw new InterruptedException;
+ }
+}
+
+//
+// Some runtime code.
+//
+
+// This function is called at system startup to initialize the
+// `sync_mutex'.
+void
+_Jv_InitializeSyncMutex (void)
+{
+ _Jv_MutexInit (&sync_mutex);
+}
+
+void
+_Jv_MonitorEnter (jobject obj)
+{
+#ifndef HANDLE_SEGV
+ if (__builtin_expect (! obj, false))
+ throw new java::lang::NullPointerException;
+#endif
+ if (__builtin_expect (INIT_NEEDED (obj), false))
+ obj->sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ _Jv_MutexLock (&si->mutex);
+ // FIXME: In the Windows case, this can return a nonzero error code.
+ // We should turn that into some exception ...
+}
+
+void
+_Jv_MonitorExit (jobject obj)
+{
+ JvAssert (obj);
+ JvAssert (! INIT_NEEDED (obj));
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ if (__builtin_expect (_Jv_MutexUnlock (&si->mutex), false))
+ throw new java::lang::IllegalMonitorStateException;
+}
+
+bool
+_Jv_ObjectCheckMonitor (jobject obj)
+{
+ if (__builtin_expect (INIT_NEEDED (obj), false))
+ obj->sync_init ();
+ _Jv_SyncInfo *si = (_Jv_SyncInfo *) obj->sync_info;
+ return _Jv_MutexCheckMonitor (&si->mutex);
+}
+
+#else /* JV_HASH_SYNCHRONIZATION */
+
+// FIXME: We shouldn't be calling GC_register_finalizer directly.
+#ifndef HAVE_BOEHM_GC
+# error Hash synchronization currently requires boehm-gc
+// That's actually a bit of a lie: It should also work with the null GC,
+// probably even better than the alternative.
+// To really support alternate GCs here, we would need to widen the
+// interface to finalization, since we sometimes have to register a
+// second finalizer for an object that already has one.
+// We might also want to move the GC interface to a .h file, since
+// the number of procedure call levels involved in some of these
+// operations is already ridiculous, and would become worse if we
+// went through the proper intermediaries.
+#else
+# ifdef LIBGCJ_GC_DEBUG
+# define GC_DEBUG
+# endif
+# include "gc.h"
+#endif
+
+// What follows currenly assumes a Linux-like platform.
+// Some of it specifically assumes X86 or IA64 Linux, though that
+// should be easily fixable.
+
+// A Java monitor implemention based on a table of locks.
+// Each entry in the table describes
+// locks held for objects that hash to that location.
+// This started out as a reimplementation of the technique used in SGIs JVM,
+// for which we obtained permission from SGI.
+// But in fact, this ended up quite different, though some ideas are
+// still shared with the original.
+// It was also influenced by some of the published IBM work,
+// though it also differs in many ways from that.
+// We could speed this up if we had a way to atomically update
+// an entire cache entry, i.e. 2 contiguous words of memory.
+// That would usually be the case with a 32 bit ABI on a 64 bit processor.
+// But we don't currently go out of our way to target those.
+// I don't know how to do much better with a N bit ABI on a processor
+// that can atomically update only N bits at a time.
+// Author: Hans-J. Boehm (Hans_Boehm@hp.com, boehm@acm.org)
+
+#include <limits.h>
+#include <unistd.h> // for usleep, sysconf.
+#include <gcj/javaprims.h>
+#include <sysdep/locks.h>
+#include <java/lang/Thread.h>
+
+// Try to determine whether we are on a multiprocessor, i.e. whether
+// spinning may be profitable.
+// This should really use a suitable autoconf macro.
+// False is the conservative answer, though the right one is much better.
+static bool
+is_mp()
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ long nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+ return (nprocs > 1);
+#else
+ return false;
+#endif
+}
+
+// A call to keep_live(p) forces p to be accessible to the GC
+// at this point.
+inline static void
+keep_live(obj_addr_t p)
+{
+ __asm__ __volatile__("" : : "rm"(p) : "memory");
+}
+
+// Each hash table entry holds a single preallocated "lightweight" lock.
+// In addition, it holds a chain of "heavyweight" locks. Lightweight
+// locks do not support Object.wait(), and are converted to heavyweight
+// status in response to contention. Unlike the SGI scheme, both
+// ligtweight and heavyweight locks in one hash entry can be simultaneously
+// in use. (The SGI scheme requires that we be able to acquire a heavyweight
+// lock on behalf of another thread, and can thus convert a lock we don't
+// hold to heavyweight status. Here we don't insist on that, and thus
+// let the original holder of the lighweight lock keep it.)
+
+struct heavy_lock {
+ void * reserved_for_gc;
+ struct heavy_lock *next; // Hash chain link.
+ // Traced by GC.
+ void * old_client_data; // The only other field traced by GC.
+ GC_finalization_proc old_finalization_proc;
+ obj_addr_t address; // Object to which this lock corresponds.
+ // Should not be traced by GC.
+ // Cleared as heavy_lock is destroyed.
+ // Together with the rest of the heavy lock
+ // chain, this is protected by the lock
+ // bit in the hash table entry to which
+ // the chain is attached.
+ _Jv_SyncInfo si;
+ // The remaining fields save prior finalization info for
+ // the object, which we needed to replace in order to arrange
+ // for cleanup of the lock structure.
+};
+
+#ifdef LOCK_DEBUG
+void
+print_hl_list(heavy_lock *hl)
+{
+ heavy_lock *p = hl;
+ for (; 0 != p; p = p->next)
+ fprintf (stderr, "(hl = %p, addr = %p)", p, (void *)(p -> address));
+}
+#endif /* LOCK_DEBUG */
+
+#if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+// If we have to run a destructor for a sync_info member, then this
+// function could be registered as a finalizer for the sync_info.
+// In fact, we now only invoke it explicitly.
+static inline void
+heavy_lock_finalization_proc (heavy_lock *hl)
+{
+#if defined (_Jv_HaveCondDestroy)
+ _Jv_CondDestroy (&hl->si.condition);
+#endif
+#if defined (_Jv_HaveMutexDestroy)
+ _Jv_MutexDestroy (&hl->si.mutex);
+#endif
+ hl->si.init = false;
+}
+#endif /* defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy) */
+
+// We convert the lock back to lightweight status when
+// we exit, so that a single contention episode doesn't doom the lock
+// forever. But we also need to make sure that lock structures for dead
+// objects are eventually reclaimed. We do that in a an additional
+// finalizer on the underlying object.
+// Note that if the corresponding object is dead, it is safe to drop
+// the heavy_lock structure from its list. It is not necessarily
+// safe to deallocate it, since the unlock code could still be running.
+
+struct hash_entry {
+ volatile obj_addr_t address; // Address of object for which lightweight
+ // k is held.
+ // We assume the 3 low order bits are zero.
+ // With the Boehm collector and bitmap
+ // allocation, objects of size 4 bytes are
+ // broken anyway. Thus this is primarily
+ // a constraint on statically allocated
+ // objects used for synchronization.
+ // This allows us to use the low order
+ // bits as follows:
+# define LOCKED 1 // This hash entry is locked, and its
+ // state may be invalid.
+ // The lock protects both the hash_entry
+ // itself (except for the light_count
+ // and light_thr_id fields, which
+ // are protected by the lightweight
+ // lock itself), and any heavy_monitor
+ // structures attached to it.
+# define HEAVY 2 // Heavyweight locks associated with this
+ // hash entry may be held.
+ // The lightweight entry is still valid,
+ // if the leading bits of the address
+ // field are nonzero.
+ // If the LOCKED bit is clear, then this is
+ // set exactly when heavy_count is > 0 .
+ // Stored redundantly so a single
+ // compare-and-swap works in the easy case.
+ // If HEAVY is not set, it is safe to use
+ // an available lightweight lock entry
+ // without checking if there is an existing
+ // heavyweight lock for the same object.
+ // (There may be one, but it won't be held
+ // or waited for.)
+# define REQUEST_CONVERSION 4 // The lightweight lock is held. But
+ // one or more other threads have tried
+ // to acquire the lock, and hence request
+ // conversion to heavyweight status.
+ // The heavyweight lock is already allocated.
+ // Threads requesting conversion are
+ // waiting on the condition variable associated
+ // with the heavyweight lock.
+ // Not used for conversion due to
+ // Object.wait() calls.
+# define FLAGS (LOCKED | HEAVY | REQUEST_CONVERSION)
+ volatile _Jv_ThreadId_t light_thr_id;
+ // Thr_id of holder of lightweight lock.
+ // Only updated by lightweight lock holder.
+ // Must be recognizably invalid if the
+ // lightweight lock is not held.
+# define INVALID_THREAD_ID 0 // Works for Linux?
+ // If zero doesn't work, we have to
+ // initialize lock table.
+ volatile unsigned short light_count;
+ // Number of times the lightweight lock
+ // is held minus one. Zero if lightweight
+ // lock is not held. Only updated by
+ // lightweight lock holder or, in one
+ // case, while holding the LOCKED bit in
+ // a state in which there can be no
+ // lightweight lock holder.
+ unsigned short heavy_count; // Total number of times heavyweight locks
+ // associated with this hash entry are held
+ // or waiting to be acquired.
+ // Threads in wait() are included eventhough
+ // they have temporarily released the lock.
+ // Protected by LOCKED bit.
+ // Threads requesting conversion to heavyweight
+ // status are also included.
+ struct heavy_lock * heavy_locks;
+ // Chain of heavy locks. Protected
+ // by lockbit for he. Locks may
+ // remain allocated here even if HEAVY
+ // is not set and heavy_count is 0.
+ // If a lightweight and heavyweight lock
+ // correspond to the same address, the
+ // lightweight lock is the right one.
+};
+
+#ifndef JV_SYNC_TABLE_SZ
+# define JV_SYNC_TABLE_SZ 2048 // Must be power of 2.
+#endif
+
+hash_entry light_locks[JV_SYNC_TABLE_SZ];
+
+#define JV_SYNC_HASH(p) (((long)p ^ ((long)p >> 10)) & (JV_SYNC_TABLE_SZ-1))
+
+// Note that the light_locks table is scanned conservatively by the
+// collector. It is essential the the heavy_locks field is scanned.
+// Currently the address field may or may not cause the associated object
+// to be retained, depending on whether flag bits are set.
+// This means that we can conceivable get an unexpected deadlock if
+// 1) Object at address A is locked.
+// 2) The client drops A without unlocking it.
+// 3) Flag bits in the address entry are set, so the collector reclaims
+// the object at A.
+// 4) A is reallocated, and an attempt is made to lock the result.
+// This could be fixed by scanning light_locks in a more customized
+// manner that ignores the flag bits. But it can only happen with hand
+// generated semi-illegal .class files, and then it doesn't present a
+// security hole.
+
+#ifdef LOCK_DEBUG
+ void print_he(hash_entry *he)
+ {
+ fprintf(stderr, "lock hash entry = %p, index = %d, address = 0x%lx\n"
+ "\tlight_thr_id = 0x%lx, light_count = %d, "
+ "heavy_count = %d\n\theavy_locks:", he,
+ he - light_locks, (unsigned long)(he -> address),
+ (unsigned long)(he -> light_thr_id),
+ he -> light_count, he -> heavy_count);
+ print_hl_list(he -> heavy_locks);
+ fprintf(stderr, "\n");
+ }
+#endif /* LOCK_DEBUG */
+
+#ifdef LOCK_LOG
+ // Log locking operations. For debugging only.
+ // Logging is intended to be as unintrusive as possible.
+ // Log calls are made after an operation completes, and hence
+ // may not completely reflect actual synchronization ordering.
+ // The choice of events to log is currently a bit haphazard.
+ // The intent is that if we have to track down any other bugs
+ // inthis code, we extend the logging as appropriate.
+ typedef enum
+ {
+ ACQ_LIGHT, ACQ_LIGHT2, ACQ_HEAVY, ACQ_HEAVY2, PROMOTE, REL_LIGHT,
+ REL_HEAVY, REQ_CONV, PROMOTE2, WAIT_START, WAIT_END, NOTIFY, NOTIFY_ALL
+ } event_type;
+
+ struct lock_history
+ {
+ event_type tp;
+ obj_addr_t addr; // Often includes flags.
+ _Jv_ThreadId_t thr;
+ };
+
+ const int LOG_SIZE = 128; // Power of 2.
+
+ lock_history lock_log[LOG_SIZE];
+
+ volatile obj_addr_t log_next = 0;
+ // Next location in lock_log.
+ // Really an int, but we need compare_and_swap.
+
+ static void add_log_entry(event_type t, obj_addr_t a, _Jv_ThreadId_t th)
+ {
+ obj_addr_t my_entry;
+ obj_addr_t next_entry;
+ do
+ {
+ my_entry = log_next;
+ next_entry = ((my_entry + 1) & (LOG_SIZE - 1));
+ }
+ while (!compare_and_swap(&log_next, my_entry, next_entry));
+ lock_log[my_entry].tp = t;
+ lock_log[my_entry].addr = a;
+ lock_log[my_entry].thr = th;
+ }
+
+# define LOG(t, a, th) add_log_entry(t, a, th)
+#else /* !LOCK_LOG */
+# define LOG(t, a, th)
+#endif
+
+static bool mp = false; // Known multiprocesssor.
+
+// Wait for roughly 2^n units, touching as little memory as possible.
+static void
+spin(unsigned n)
+{
+ const unsigned MP_SPINS = 10;
+ const unsigned YIELDS = 4;
+ const unsigned SPINS_PER_UNIT = 30;
+ const unsigned MIN_SLEEP_USECS = 2001; // Shorter times spin under Linux.
+ const unsigned MAX_SLEEP_USECS = 200000;
+ static unsigned spin_limit = 0;
+ static unsigned yield_limit = YIELDS;
+ static bool spin_initialized = false;
+
+ if (!spin_initialized)
+ {
+ mp = is_mp();
+ if (mp)
+ {
+ spin_limit = MP_SPINS;
+ yield_limit = MP_SPINS + YIELDS;
+ }
+ spin_initialized = true;
+ }
+ if (n < spin_limit)
+ {
+ unsigned i = SPINS_PER_UNIT << n;
+ for (; i > 0; --i)
+ __asm__ __volatile__("");
+ }
+ else if (n < yield_limit)
+ {
+ _Jv_ThreadYield();
+ }
+ else
+ {
+ unsigned duration = MIN_SLEEP_USECS << (n - yield_limit);
+ if (n >= 15 + yield_limit || duration > MAX_SLEEP_USECS)
+ duration = MAX_SLEEP_USECS;
+ _Jv_platform_usleep(duration);
+ }
+}
+
+// Wait for a hash entry to become unlocked.
+static void
+wait_unlocked (hash_entry *he)
+{
+ unsigned i = 0;
+ while (he -> address & LOCKED)
+ spin (i++);
+}
+
+// Return the heavy lock for addr if it was already allocated.
+// The client passes in the appropriate hash_entry.
+// We hold the lock for he.
+static inline heavy_lock *
+find_heavy (obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock *hl = he -> heavy_locks;
+ while (hl != 0 && hl -> address != addr) hl = hl -> next;
+ return hl;
+}
+
+// Unlink the heavy lock for the given address from its hash table chain.
+// Dies miserably and conspicuously if it's not there, since that should
+// be impossible.
+static inline void
+unlink_heavy (obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock **currentp = &(he -> heavy_locks);
+ while ((*currentp) -> address != addr)
+ currentp = &((*currentp) -> next);
+ *currentp = (*currentp) -> next;
+}
+
+// Finalization procedure for objects that have associated heavy-weight
+// locks. This may replace the real finalization procedure.
+static void
+heavy_lock_obj_finalization_proc (void *obj, void *cd)
+{
+ heavy_lock *hl = (heavy_lock *)cd;
+
+// This only addresses misalignment of statics, not heap objects. It
+// works only because registering statics for finalization is a noop,
+// no matter what the least significant bits are.
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)0x7);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ hash_entry *he = light_locks + JV_SYNC_HASH(addr);
+ obj_addr_t he_address = (he -> address & ~LOCKED);
+
+ // Acquire lock bit immediately. It's possible that the hl was already
+ // destroyed while we were waiting for the finalizer to run. If it
+ // was, the address field was set to zero. The address filed access is
+ // protected by the lock bit to ensure that we do this exactly once.
+ // The lock bit also protects updates to the objects finalizer.
+ while (!compare_and_swap(&(he -> address), he_address, he_address|LOCKED ))
+ {
+ // Hash table entry is currently locked. We can't safely
+ // touch the list of heavy locks.
+ wait_unlocked(he);
+ he_address = (he -> address & ~LOCKED);
+ }
+ if (0 == hl -> address)
+ {
+ // remove_all_heavy destroyed hl, and took care of the real finalizer.
+ release_set(&(he -> address), he_address);
+ return;
+ }
+ JvAssert(hl -> address == addr);
+ GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
+ if (old_finalization_proc != 0)
+ {
+ // We still need to run a real finalizer. In an idealized
+ // world, in which people write thread-safe finalizers, that is
+ // likely to require synchronization. Thus we reregister
+ // ourselves as the only finalizer, and simply run the real one.
+ // Thus we don't clean up the lock yet, but we're likely to do so
+ // on the next GC cycle.
+ // It's OK if remove_all_heavy actually destroys the heavy lock,
+ // since we've updated old_finalization_proc, and thus the user's
+ // finalizer won't be rerun.
+ void * old_client_data = hl -> old_client_data;
+ hl -> old_finalization_proc = 0;
+ hl -> old_client_data = 0;
+# ifdef HAVE_BOEHM_GC
+ GC_REGISTER_FINALIZER_NO_ORDER(obj, heavy_lock_obj_finalization_proc, cd, 0, 0);
+# endif
+ release_set(&(he -> address), he_address);
+ old_finalization_proc(obj, old_client_data);
+ }
+ else
+ {
+ // The object is really dead, although it's conceivable that
+ // some thread may still be in the process of releasing the
+ // heavy lock. Unlink it and, if necessary, register a finalizer
+ // to destroy sync_info.
+ unlink_heavy(addr, he);
+ hl -> address = 0; // Don't destroy it again.
+ release_set(&(he -> address), he_address);
+# if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Make sure lock is not held and then destroy condvar and mutex.
+ _Jv_MutexLock(&(hl->si.mutex));
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ heavy_lock_finalization_proc (hl);
+# endif
+ }
+}
+
+// We hold the lock on he, and heavy_count is 0.
+// Release the lock by replacing the address with new_address_val.
+// Remove all heavy locks on the list. Note that the only possible way
+// in which a lock may still be in use is if it's in the process of
+// being unlocked.
+// FIXME: Why does this unlock the hash entry? I think that
+// could now be done more cleanly in MonitorExit.
+static void
+remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
+{
+ JvAssert(he -> heavy_count == 0);
+ JvAssert(he -> address & LOCKED);
+ heavy_lock *hl = he -> heavy_locks;
+ he -> heavy_locks = 0;
+ // We would really like to release the lock bit here. Unfortunately, that
+ // Creates a race between or finalizer removal, and the potential
+ // reinstallation of a new finalizer as a new heavy lock is created.
+ // This may need to be revisited.
+ for(; 0 != hl; hl = hl->next)
+ {
+ obj_addr_t obj = hl -> address;
+ JvAssert(0 != obj); // If this was previously finalized, it should no
+ // longer appear on our list.
+ hl -> address = 0; // Finalization proc might still see it after we
+ // finish.
+ GC_finalization_proc old_finalization_proc = hl -> old_finalization_proc;
+ void * old_client_data = hl -> old_client_data;
+# ifdef HAVE_BOEHM_GC
+ // Remove our finalization procedure.
+ // Reregister the clients if applicable.
+ GC_REGISTER_FINALIZER_NO_ORDER((GC_PTR)obj, old_finalization_proc,
+ old_client_data, 0, 0);
+ // Note that our old finalization procedure may have been
+ // previously determined to be runnable, and may still run.
+ // FIXME - direct dependency on boehm GC.
+# endif
+# if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ // Wait for a possible lock holder to finish unlocking it.
+ // This is only an issue if we have to explicitly destroy the mutex
+ // or possibly if we have to destroy a condition variable that is
+ // still being notified.
+ _Jv_MutexLock(&(hl->si.mutex));
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ heavy_lock_finalization_proc (hl);
+# endif
+ }
+ release_set(&(he -> address), new_address_val);
+}
+
+// We hold the lock on he and heavy_count is 0.
+// We release it by replacing the address field with new_address_val.
+// Remove all heavy locks on the list if the list is sufficiently long.
+// This is called periodically to avoid very long lists of heavy locks.
+// This seems to otherwise become an issue with SPECjbb, for example.
+static inline void
+maybe_remove_all_heavy (hash_entry *he, obj_addr_t new_address_val)
+{
+ static const int max_len = 5;
+ heavy_lock *hl = he -> heavy_locks;
+
+ for (int i = 0; i < max_len; ++i)
+ {
+ if (0 == hl)
+ {
+ release_set(&(he -> address), new_address_val);
+ return;
+ }
+ hl = hl -> next;
+ }
+ remove_all_heavy(he, new_address_val);
+}
+
+// Allocate a new heavy lock for addr, returning its address.
+// Assumes we already have the hash_entry locked, and there
+// is currently no lightweight or allocated lock for addr.
+// We register a finalizer for addr, which is responsible for
+// removing the heavy lock when addr goes away, in addition
+// to the responsibilities of any prior finalizer.
+// This unfortunately holds the lock bit for the hash entry while it
+// allocates two objects (on for the finalizer).
+// It would be nice to avoid that somehow ...
+static heavy_lock *
+alloc_heavy(obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock * hl = (heavy_lock *) _Jv_AllocTraceTwo(sizeof (heavy_lock));
+
+ hl -> address = addr;
+ _Jv_MutexInit (&(hl -> si.mutex));
+ _Jv_CondInit (&(hl -> si.condition));
+# if defined (_Jv_HaveCondDestroy) || defined (_Jv_HaveMutexDestroy)
+ hl->si.init = true; // needed ?
+# endif
+ hl -> next = he -> heavy_locks;
+ he -> heavy_locks = hl;
+ // FIXME: The only call that cheats and goes directly to the GC interface.
+# ifdef HAVE_BOEHM_GC
+ GC_REGISTER_FINALIZER_NO_ORDER(
+ (void *)addr, heavy_lock_obj_finalization_proc,
+ hl, &hl->old_finalization_proc,
+ &hl->old_client_data);
+# endif /* HAVE_BOEHM_GC */
+ return hl;
+}
+
+// Return the heavy lock for addr, allocating if necessary.
+// Assumes we have the cache entry locked, and there is no lightweight
+// lock for addr.
+static heavy_lock *
+get_heavy(obj_addr_t addr, hash_entry *he)
+{
+ heavy_lock *hl = find_heavy(addr, he);
+ if (0 == hl)
+ hl = alloc_heavy(addr, he);
+ return hl;
+}
+
+void
+_Jv_MonitorEnter (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ obj_addr_t address;
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned count;
+ const unsigned N_SPINS = 18;
+
+ // We need to somehow check that addr is not NULL on the fast path.
+ // A very predictable
+ // branch on a register value is probably cheaper than dereferencing addr.
+ // We could also permanently lock the NULL entry in the hash table.
+ // But it's not clear that's cheaper either.
+ if (__builtin_expect(!addr, false))
+ throw new java::lang::NullPointerException;
+
+ JvAssert(!(addr & FLAGS));
+retry:
+ if (__builtin_expect(compare_and_swap(&(he -> address),
+ 0, addr),true))
+ {
+ JvAssert(he -> light_thr_id == INVALID_THREAD_ID);
+ JvAssert(he -> light_count == 0);
+ he -> light_thr_id = self;
+ // Count fields are set correctly. Heavy_count was also zero,
+ // but can change asynchronously.
+ // This path is hopefully both fast and the most common.
+ LOG(ACQ_LIGHT, addr, self);
+ return;
+ }
+ address = he -> address;
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+ {
+ if (he -> light_thr_id == self)
+ {
+ // We hold the lightweight lock, and it's for the right
+ // address.
+ count = he -> light_count;
+ if (count == USHRT_MAX)
+ {
+ // I think most JVMs don't check for this.
+ // But I'm not convinced I couldn't turn this into a security
+ // hole, even with a 32 bit counter.
+ throw new java::lang::IllegalMonitorStateException(
+ JvNewStringLatin1("maximum monitor nesting level exceeded"));
+ }
+ he -> light_count = count + 1;
+ return;
+ }
+ else
+ {
+ JvAssert(!(address & LOCKED));
+ // Lightweight lock is held, but by somone else.
+ // Spin a few times. This avoids turning this into a heavyweight
+ // lock if the current holder is about to release it.
+ // FIXME: Does this make sense on a uniprocessor, where
+ // it actually yields? It's probably cheaper to convert.
+ for (unsigned int i = 0; i < N_SPINS; ++i)
+ {
+ if ((he -> address & ~LOCKED) != address) goto retry;
+ spin(i);
+ }
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED ))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ heavy_lock *hl = get_heavy(addr, he);
+ ++ (he -> heavy_count);
+ // The hl lock acquisition can't block for long, since it can
+ // only be held by other threads waiting for conversion, and
+ // they, like us, drop it quickly without blocking.
+ _Jv_MutexLock(&(hl->si.mutex));
+ JvAssert(he -> address == address | LOCKED );
+ release_set(&(he -> address), (address | REQUEST_CONVERSION | HEAVY));
+ // release lock on he
+ LOG(REQ_CONV, (address | REQUEST_CONVERSION | HEAVY), self);
+ // If _Jv_CondWait is interrupted, we ignore the interrupt, but
+ // restore the thread's interrupt status flag when done.
+ jboolean interrupt_flag = false;
+ while ((he -> address & ~FLAGS) == (address & ~FLAGS))
+ {
+ // Once converted, the lock has to retain heavyweight
+ // status, since heavy_count > 0.
+ int r = _Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), 0, 0);
+ if (r == _JV_INTERRUPTED)
+ {
+ interrupt_flag = true;
+ Thread::currentThread()->interrupt_flag = false;
+ }
+ }
+ if (interrupt_flag)
+ Thread::currentThread()->interrupt_flag = interrupt_flag;
+ keep_live(addr);
+ // Guarantee that hl doesn't get unlinked by finalizer.
+ // This is only an issue if the client fails to release
+ // the lock, which is unlikely.
+ JvAssert(he -> address & HEAVY);
+ // Lock has been converted, we hold the heavyweight lock,
+ // heavy_count has been incremented.
+ return;
+ }
+ }
+ obj_addr_t was_heavy = (address & HEAVY);
+ if ((address & LOCKED) ||
+ !compare_and_swap(&(he -> address), address, (address | LOCKED )))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == 0)
+ {
+ // Either was_heavy is true, or something changed out from under us,
+ // since the initial test for 0 failed.
+ JvAssert(!(address & REQUEST_CONVERSION));
+ // Can't convert a nonexistent lightweight lock.
+ heavy_lock *hl;
+ hl = (was_heavy? find_heavy(addr, he) : 0);
+ // The CAS succeeded, so was_heavy is still accurate.
+ if (0 == hl)
+ {
+ // It is OK to use the lighweight lock, since either the
+ // heavyweight lock does not exist, or none of the
+ // heavyweight locks are currently in use. Future threads
+ // trying to acquire the lock will see the lightweight
+ // one first and use that.
+ he -> light_thr_id = self; // OK, since nobody else can hold
+ // light lock or do this at the same time.
+ JvAssert(he -> light_count == 0);
+ JvAssert(was_heavy == (he -> address & HEAVY));
+ release_set(&(he -> address), (addr | was_heavy));
+ LOG(ACQ_LIGHT2, addr | was_heavy, self);
+ }
+ else
+ {
+ // Must use heavy lock.
+ ++ (he -> heavy_count);
+ JvAssert(0 == (address & ~HEAVY));
+ release_set(&(he -> address), HEAVY);
+ LOG(ACQ_HEAVY, addr | was_heavy, self);
+ _Jv_MutexLock(&(hl->si.mutex));
+ keep_live(addr);
+ }
+ return;
+ }
+ // Lightweight lock is held, but does not correspond to this object.
+ // We hold the lock on the hash entry, and he -> address can't
+ // change from under us. Neither can the chain of heavy locks.
+ {
+ JvAssert(0 == he -> heavy_count || (address & HEAVY));
+ heavy_lock *hl = get_heavy(addr, he);
+ ++ (he -> heavy_count);
+ release_set(&(he -> address), address | HEAVY);
+ LOG(ACQ_HEAVY2, address | HEAVY, self);
+ _Jv_MutexLock(&(hl->si.mutex));
+ keep_live(addr);
+ }
+}
+
+
+void
+_Jv_MonitorExit (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ _Jv_ThreadId_t light_thr_id;
+ unsigned count;
+ obj_addr_t address;
+
+retry:
+ light_thr_id = he -> light_thr_id;
+ // Unfortunately, it turns out we always need to read the address
+ // first. Even if we are going to update it with compare_and_swap,
+ // we need to reset light_thr_id, and that's not safe unless we know
+ // that we hold the lock.
+ address = he -> address;
+ // First the (relatively) fast cases:
+ if (__builtin_expect(light_thr_id == self, true))
+ // Above must fail if addr == 0 .
+ {
+ count = he -> light_count;
+ if (__builtin_expect((address & ~HEAVY) == addr, true))
+ {
+ if (count != 0)
+ {
+ // We held the lightweight lock all along. Thus the values
+ // we saw for light_thr_id and light_count must have been valid.
+ he -> light_count = count - 1;
+ return;
+ }
+ else
+ {
+ // We hold the lightweight lock once.
+ he -> light_thr_id = INVALID_THREAD_ID;
+ if (compare_and_swap_release(&(he -> address), address,
+ address & HEAVY))
+ {
+ LOG(REL_LIGHT, address & HEAVY, self);
+ return;
+ }
+ else
+ {
+ he -> light_thr_id = light_thr_id; // Undo prior damage.
+ goto retry;
+ }
+ }
+ }
+ // else lock is not for this address, conversion is requested,
+ // or the lock bit in the address field is set.
+ }
+ else
+ {
+ if (__builtin_expect(!addr, false))
+ throw new java::lang::NullPointerException;
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Lightweight lock held by other thread\n\t"
+ "light_thr_id = 0x%lx, self = 0x%lx, "
+ "address = 0x%lx, heavy_count = %d, pid = %d\n",
+ light_thr_id, self, (unsigned long)address,
+ he -> heavy_count, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ // Someone holds the lightweight lock for this object, and
+ // it can't be us.
+ throw new java::lang::IllegalMonitorStateException(
+ JvNewStringLatin1("current thread not owner"));
+ }
+ else
+ count = he -> light_count;
+ }
+ if (address & LOCKED)
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ // Now the unlikely cases.
+ // We do know that:
+ // - Address is set, and doesn't contain the LOCKED bit.
+ // - If address refers to the same object as addr, then he -> light_thr_id
+ // refers to this thread, and count is valid.
+ // - The case in which we held the lightweight lock has been
+ // completely handled, except for the REQUEST_CONVERSION case.
+ //
+ if ((address & ~FLAGS) == addr)
+ {
+ // The lightweight lock is assigned to this object.
+ // Thus we must be in the REQUEST_CONVERSION case.
+ if (0 != count)
+ {
+ // Defer conversion until we exit completely.
+ he -> light_count = count - 1;
+ return;
+ }
+ JvAssert(he -> light_thr_id == self);
+ JvAssert(address & REQUEST_CONVERSION);
+ // Conversion requested
+ // Convert now.
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ goto retry;
+ heavy_lock *hl = find_heavy(addr, he);
+ JvAssert (0 != hl);
+ // Requestor created it.
+ he -> light_count = 0;
+ JvAssert(he -> heavy_count > 0);
+ // was incremented by requestor.
+ _Jv_MutexLock(&(hl->si.mutex));
+ // Release the he lock after acquiring the mutex.
+ // Otherwise we can accidentally
+ // notify a thread that has already seen a heavyweight
+ // lock.
+ he -> light_thr_id = INVALID_THREAD_ID;
+ release_set(&(he -> address), HEAVY);
+ LOG(PROMOTE, address, self);
+ // lightweight lock now unused.
+ _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ // heavy_count was already incremented by original requestor.
+ keep_live(addr);
+ return;
+ }
+ // lightweight lock not for this object.
+ JvAssert(!(address & LOCKED));
+ JvAssert((address & ~FLAGS) != addr);
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ goto retry;
+ heavy_lock *hl = find_heavy(addr, he);
+ if (NULL == hl)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Failed to find heavyweight lock for addr 0x%lx"
+ " pid = %d\n", addr, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ release_set(&(he -> address), address);
+ throw new java::lang::IllegalMonitorStateException(
+ JvNewStringLatin1("current thread not owner"));
+ }
+ JvAssert(address & HEAVY);
+ count = he -> heavy_count;
+ JvAssert(count > 0);
+ --count;
+ he -> heavy_count = count;
+ if (0 == count)
+ {
+ const unsigned test_freq = 16; // Power of 2
+ static volatile unsigned counter = 0;
+ unsigned my_counter = counter;
+
+ counter = my_counter + 1;
+ if (my_counter%test_freq == 0)
+ {
+ // Randomize the interval length a bit.
+ counter = my_counter + (my_counter >> 4) % (test_freq/2);
+ // Unlock mutex first, to avoid self-deadlock, or worse.
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ maybe_remove_all_heavy(he, address &~HEAVY);
+ // release lock bit, preserving
+ // REQUEST_CONVERSION
+ // and object address.
+ }
+ else
+ {
+ release_set(&(he -> address), address &~HEAVY);
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ // Unlock after releasing the lock bit, so that
+ // we don't switch to another thread prematurely.
+ }
+ }
+ else
+ {
+ release_set(&(he -> address), address);
+ _Jv_MutexUnlock(&(hl->si.mutex));
+ }
+ LOG(REL_HEAVY, addr, self);
+ keep_live(addr);
+}
+
+// Return false if obj's monitor is held by the current thread
+bool
+_Jv_ObjectCheckMonitor (jobject obj)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)obj;
+#endif
+ obj_addr_t address;
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+
+ JvAssert(!(addr & FLAGS));
+ address = he -> address;
+ // Try it the easy way first:
+ if (address == 0) return true;
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)
+ // Fails if entry is LOCKED.
+ // I can't asynchronously become or stop being the holder.
+ return he -> light_thr_id != self;
+retry:
+ // Acquire the hash table entry lock
+ address &= ~LOCKED;
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+
+ bool not_mine;
+
+ if ((address & ~FLAGS) == addr)
+ not_mine = (he -> light_thr_id != self);
+ else
+ {
+ heavy_lock* hl = find_heavy(addr, he);
+ not_mine = hl ? _Jv_MutexCheckMonitor(&hl->si.mutex) : true;
+ }
+
+ release_set(&(he -> address), address); // unlock hash entry
+ return not_mine;
+}
+
+// The rest of these are moderately thin veneers on _Jv_Cond ops.
+// The current version of Notify might be able to make the pthread
+// call AFTER releasing the lock, thus saving some context switches??
+
+void
+java::lang::Object::wait (jlong timeout, jint nanos)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)this;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ unsigned count;
+ obj_addr_t address;
+ heavy_lock *hl;
+
+ if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))
+ throw new IllegalArgumentException;
+retry:
+ address = he -> address;
+ address &= ~LOCKED;
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ // address did not have the lock bit set. We now hold the lock on he.
+ if ((address & ~FLAGS) == addr)
+ {
+ // Convert to heavyweight.
+ if (he -> light_thr_id != self)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Found wrong lightweight lock owner in wait "
+ "address = 0x%lx pid = %d\n", address, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ release_set(&(he -> address), address);
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ }
+ count = he -> light_count;
+ hl = get_heavy(addr, he);
+ he -> light_count = 0;
+ he -> heavy_count += count + 1;
+ for (unsigned i = 0; i <= count; ++i)
+ _Jv_MutexLock(&(hl->si.mutex));
+ // Again release the he lock after acquiring the mutex.
+ he -> light_thr_id = INVALID_THREAD_ID;
+ release_set(&(he -> address), HEAVY); // lightweight lock now unused.
+ LOG(PROMOTE2, addr, self);
+ if (address & REQUEST_CONVERSION)
+ _Jv_CondNotifyAll (&(hl->si.condition), &(hl->si.mutex));
+ // Since we do this before we do a CondWait, we guarantee that
+ // threads waiting on requested conversion are awoken before
+ // a real wait on the same condition variable.
+ // No other notification can occur in the interim, since
+ // we hold the heavy lock, and notifications are made
+ // without acquiring it.
+ }
+ else /* We should hold the heavyweight lock. */
+ {
+ hl = find_heavy(addr, he);
+ release_set(&(he -> address), address);
+ if (0 == hl)
+ {
+# ifdef LOCK_DEBUG
+ fprintf(stderr, "Couldn't find heavy lock in wait "
+ "addr = 0x%lx pid = %d\n", addr, getpid());
+ print_he(he);
+ for(;;) {}
+# endif
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ }
+ JvAssert(address & HEAVY);
+ }
+ LOG(WAIT_START, addr, self);
+ switch (_Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), timeout, nanos))
+ {
+ case _JV_NOT_OWNER:
+ throw new IllegalMonitorStateException (JvNewStringLatin1
+ ("current thread not owner"));
+ case _JV_INTERRUPTED:
+ if (Thread::interrupted ())
+ throw new InterruptedException;
+ }
+ LOG(WAIT_END, addr, self);
+}
+
+void
+java::lang::Object::notify (void)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)this;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ heavy_lock *hl;
+ obj_addr_t address;
+ int result;
+
+retry:
+ address = ((he -> address) & ~LOCKED);
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
+ {
+ // We hold lightweight lock. Since it has not
+ // been inflated, there are no waiters.
+ release_set(&(he -> address), address); // unlock
+ return;
+ }
+ hl = find_heavy(addr, he);
+ // Hl can't disappear since we point to the underlying object.
+ // It's important that we release the lock bit before the notify, since
+ // otherwise we will try to wake up the target while we still hold the
+ // bit. This results in lock bit contention, which we don't handle
+ // terribly well.
+ release_set(&(he -> address), address); // unlock
+ if (0 == hl)
+ {
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+ return;
+ }
+ // We know that we hold the heavyweight lock at this point,
+ // and the lightweight lock is not in use.
+ result = _Jv_CondNotify(&(hl->si.condition), &(hl->si.mutex));
+ LOG(NOTIFY, addr, self);
+ keep_live(addr);
+ if (__builtin_expect (result, 0))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+void
+java::lang::Object::notifyAll (void)
+{
+#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS
+ obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);
+#else
+ obj_addr_t addr = (obj_addr_t)this;
+#endif
+ _Jv_ThreadId_t self = _Jv_ThreadSelf();
+ unsigned hash = JV_SYNC_HASH(addr);
+ hash_entry * he = light_locks + hash;
+ heavy_lock *hl;
+ obj_addr_t address;
+ int result;
+
+retry:
+ address = (he -> address) & ~LOCKED;
+ if (!compare_and_swap(&(he -> address), address, address | LOCKED))
+ {
+ wait_unlocked(he);
+ goto retry;
+ }
+ hl = find_heavy(addr, he);
+ if ((address & ~FLAGS) == addr && he -> light_thr_id == self)
+ {
+ // We hold lightweight lock. Since it has not
+ // been inflated, there are no waiters.
+ release_set(&(he -> address), address); // unlock
+ return;
+ }
+ release_set(&(he -> address), address); // unlock
+ if (0 == hl)
+ {
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+ }
+ result = _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));
+ LOG(NOTIFY_ALL, addr, self);
+ if (__builtin_expect (result, 0))
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("current thread not owner"));
+}
+
+// This is declared in Java code and in Object.h.
+// It should never be called with JV_HASH_SYNCHRONIZATION
+void
+java::lang::Object::sync_init (void)
+{
+ throw new IllegalMonitorStateException(JvNewStringLatin1
+ ("internal error: sync_init"));
+}
+
+// This is called on startup and declared in Object.h.
+// For now we just make it a no-op.
+void
+_Jv_InitializeSyncMutex (void)
+{
+}
+
+#endif /* JV_HASH_SYNCHRONIZATION */
+
diff --git a/gcc-4.2.1/libjava/java/lang/natPosixProcess.cc b/gcc-4.2.1/libjava/java/lang/natPosixProcess.cc
new file mode 100644
index 000000000..77ac69253
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natPosixProcess.cc
@@ -0,0 +1,455 @@
+// natPosixProcess.cc - Native side of POSIX process code.
+
+/* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/lang/ConcreteProcess$ProcessManager.h>
+#include <java/lang/ConcreteProcess.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InternalError.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Thread.h>
+#include <java/io/File.h>
+#include <java/io/FileDescriptor.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/OutOfMemoryError.h>
+
+using gnu::java::nio::channels::FileChannelImpl;
+
+extern char **environ;
+
+static char *
+new_string (jstring string)
+{
+ jsize s = _Jv_GetStringUTFLength (string);
+ char *buf = (char *) _Jv_Malloc (s + 1);
+ _Jv_GetStringUTFRegion (string, 0, string->length(), buf);
+ buf[s] = '\0';
+ return buf;
+}
+
+static void
+cleanup (char **args, char **env, char *path)
+{
+ if (args != NULL)
+ {
+ for (int i = 0; args[i] != NULL; ++i)
+ _Jv_Free (args[i]);
+ _Jv_Free (args);
+ }
+ if (env != NULL)
+ {
+ for (int i = 0; env[i] != NULL; ++i)
+ _Jv_Free (env[i]);
+ _Jv_Free (env);
+ }
+ if (path != NULL)
+ _Jv_Free (path);
+}
+
+// This makes our error handling a bit simpler and it lets us avoid
+// thread bugs where we close a possibly-reopened file descriptor for
+// a second time.
+static void
+myclose (int &fd)
+{
+ if (fd != -1)
+ close (fd);
+ fd = -1;
+}
+
+// There has to be a signal handler in order to be able to
+// sigwait() on SIGCHLD. The information passed is ignored as it
+// will be recovered by the waitpid() call.
+static void
+sigchld_handler (int)
+{
+ // Ignore.
+}
+
+
+// Get ready to enter the main reaper thread loop.
+void
+java::lang::ConcreteProcess$ProcessManager::init ()
+{
+ using namespace java::lang;
+ // Remenber our PID so other threads can kill us.
+ reaperPID = (jlong) pthread_self ();
+
+ // SIGCHLD is blocked in all threads in posix-threads.cc.
+ // Setup the SIGCHLD handler.
+ struct sigaction sa;
+ memset (&sa, 0, sizeof (sa));
+
+ sa.sa_handler = sigchld_handler;
+ // We only want signals when the things exit.
+ sa.sa_flags = SA_NOCLDSTOP;
+
+ if (-1 == sigaction (SIGCHLD, &sa, NULL))
+ goto error;
+
+ // All OK.
+ return;
+
+error:
+ throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::ConcreteProcess$ProcessManager::waitForSignal ()
+{
+ // Wait for SIGCHLD
+ sigset_t mask;
+ pthread_sigmask (0, NULL, &mask);
+ sigdelset (&mask, SIGCHLD);
+
+ // Use sigsuspend() instead of sigwait() as sigwait() doesn't play
+ // nicely with the GC's use of signals.
+ sigsuspend (&mask);
+
+ // Do not check sigsuspend return value. The only legitimate return
+ // is EINTR, but there is a known kernel bug affecting alpha-linux
+ // wrt sigsuspend+handler+sigreturn that can result in a return value
+ // of __NR_sigsuspend and errno unset. Don't fail unnecessarily on
+ // older kernel versions.
+
+ // All OK.
+ return;
+}
+
+jboolean java::lang::ConcreteProcess$ProcessManager::reap ()
+{
+ using namespace java::lang;
+
+ pid_t pid;
+
+ for (;;)
+ {
+ // Get the return code from a dead child process.
+ int status;
+ pid = waitpid ((pid_t) - 1, &status, WNOHANG);
+ if (pid == -1)
+ {
+ if (errno == ECHILD)
+ return false;
+ else
+ goto error;
+ }
+
+ if (pid == 0)
+ return true; // No children to wait for.
+
+ // Look up the process in our pid map.
+ ConcreteProcess * process = removeProcessFromMap ((jlong) pid);
+
+ // Note that if process==NULL, then we have an unknown child.
+ // This is not common, but can happen, and isn't an error.
+ if (process)
+ {
+ JvSynchronize sync (process);
+ process->status = WIFEXITED (status) ? WEXITSTATUS (status) : -1;
+ process->state = ConcreteProcess::STATE_TERMINATED;
+ process->processTerminationCleanup();
+ process->notifyAll ();
+ }
+ }
+
+error:
+ throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::ConcreteProcess$ProcessManager::signalReaper ()
+{
+ int c = pthread_kill ((pthread_t) reaperPID, SIGCHLD);
+ if (c == 0)
+ return;
+ // pthread_kill() failed.
+ throw new InternalError (JvNewStringUTF (strerror (c)));
+}
+
+void
+java::lang::ConcreteProcess::nativeDestroy ()
+{
+ int c = kill ((pid_t) pid, SIGKILL);
+ if (c == 0)
+ return;
+ // kill() failed.
+ throw new InternalError (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::lang::ConcreteProcess::nativeSpawn ()
+{
+ using namespace java::io;
+
+ // Initialize all locals here to make cleanup simpler.
+ char **args = NULL;
+ char **env = NULL;
+ char *path = NULL;
+ int inp[2], outp[2], errp[2], msgp[2];
+ inp[0] = -1;
+ inp[1] = -1;
+ outp[0] = -1;
+ outp[1] = -1;
+ errp[0] = -1;
+ errp[1] = -1;
+ msgp[0] = -1;
+ msgp[1] = -1;
+ errorStream = NULL;
+ inputStream = NULL;
+ outputStream = NULL;
+
+ try
+ {
+ // Transform arrays to native form.
+ args = (char **) _Jv_Malloc ((progarray->length + 1) * sizeof (char *));
+
+ // Initialize so we can gracefully recover.
+ jstring *elts = elements (progarray);
+ for (int i = 0; i <= progarray->length; ++i)
+ args[i] = NULL;
+
+ for (int i = 0; i < progarray->length; ++i)
+ args[i] = new_string (elts[i]);
+ args[progarray->length] = NULL;
+
+ if (envp)
+ {
+ env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *));
+ elts = elements (envp);
+
+ // Initialize so we can gracefully recover.
+ for (int i = 0; i <= envp->length; ++i)
+ env[i] = NULL;
+
+ for (int i = 0; i < envp->length; ++i)
+ env[i] = new_string (elts[i]);
+ env[envp->length] = NULL;
+ }
+
+ // We allocate this here because we can't call malloc() after
+ // the fork.
+ if (dir != NULL)
+ path = new_string (dir->getPath ());
+
+ // Create pipes for I/O. MSGP is for communicating exec()
+ // status.
+ if (pipe (inp) || pipe (outp) || pipe (errp) || pipe (msgp)
+ || fcntl (msgp[1], F_SETFD, FD_CLOEXEC))
+ throw new IOException (JvNewStringUTF (strerror (errno)));
+
+ // We create the streams before forking. Otherwise if we had an
+ // error while creating the streams we would have run the child
+ // with no way to communicate with it.
+ errorStream =
+ new FileInputStream (new
+ FileChannelImpl (errp[0], FileChannelImpl::READ));
+ inputStream =
+ new FileInputStream (new
+ FileChannelImpl (inp[0], FileChannelImpl::READ));
+ outputStream =
+ new FileOutputStream (new FileChannelImpl (outp[1],
+ FileChannelImpl::WRITE));
+
+ // We don't use vfork() because that would cause the local
+ // environment to be set by the child.
+
+ // Use temporary for fork result to avoid dirtying an extra page.
+ pid_t pid_tmp;
+ if ((pid_tmp = fork ()) == -1)
+ throw new IOException (JvNewStringUTF (strerror (errno)));
+
+ if (pid_tmp == 0)
+ {
+ // Child process, so remap descriptors, chdir and exec.
+ if (envp)
+ {
+ // Preserve PATH and LD_LIBRARY_PATH unless specified
+ // explicitly.
+ char *path_val = getenv ("PATH");
+ char *ld_path_val = getenv ("LD_LIBRARY_PATH");
+ environ = env;
+ if (path_val && getenv ("PATH") == NULL)
+ {
+ char *path_env =
+ (char *) _Jv_Malloc (strlen (path_val) + 5 + 1);
+ strcpy (path_env, "PATH=");
+ strcat (path_env, path_val);
+ putenv (path_env);
+ }
+ if (ld_path_val && getenv ("LD_LIBRARY_PATH") == NULL)
+ {
+ char *ld_path_env =
+ (char *) _Jv_Malloc (strlen (ld_path_val) + 16 + 1);
+ strcpy (ld_path_env, "LD_LIBRARY_PATH=");
+ strcat (ld_path_env, ld_path_val);
+ putenv (ld_path_env);
+ }
+ }
+
+ // We ignore errors from dup2 because they should never occur.
+ dup2 (outp[0], 0);
+ dup2 (inp[1], 1);
+ dup2 (errp[1], 2);
+
+ // Use close and not myclose -- we're in the child, and we
+ // aren't worried about the possible race condition.
+ close (inp[0]);
+ close (inp[1]);
+ close (errp[0]);
+ close (errp[1]);
+ close (outp[0]);
+ close (outp[1]);
+ close (msgp[0]);
+
+ // Change directory.
+ if (path != NULL)
+ {
+ if (chdir (path) != 0)
+ {
+ char c = errno;
+ write (msgp[1], &c, 1);
+ _exit (127);
+ }
+ }
+ // Make sure all file descriptors are closed. In
+ // multi-threaded programs, there is a race between when a
+ // descriptor is obtained, when we can set FD_CLOEXEC, and
+ // fork(). If the fork occurs before FD_CLOEXEC is set, the
+ // descriptor would leak to the execed process if we did not
+ // manually close it. So that is what we do. Since we
+ // close all the descriptors, it is redundant to set
+ // FD_CLOEXEC on them elsewhere.
+ int max_fd;
+#ifdef HAVE_GETRLIMIT
+ rlimit rl;
+ int rv = getrlimit(RLIMIT_NOFILE, &rl);
+ if (rv == 0)
+ max_fd = rl.rlim_max - 1;
+ else
+ max_fd = 1024 - 1;
+#else
+ max_fd = 1024 - 1;
+#endif
+ while(max_fd > 2)
+ {
+ if (max_fd != msgp[1])
+ close (max_fd);
+ max_fd--;
+ }
+ // Make sure that SIGCHLD is unblocked for the new process.
+ sigset_t mask;
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGCHLD);
+ sigprocmask (SIG_UNBLOCK, &mask, NULL);
+
+ execvp (args[0], args);
+
+ // Send the parent notification that the exec failed.
+ char c = errno;
+ write (msgp[1], &c, 1);
+ _exit (127);
+ }
+
+ // Parent. Close extra file descriptors and mark ours as
+ // close-on-exec.
+ pid = (jlong) pid_tmp;
+
+ myclose (outp[0]);
+ myclose (inp[1]);
+ myclose (errp[1]);
+ myclose (msgp[1]);
+
+ char c;
+ int r = read (msgp[0], &c, 1);
+ if (r == -1)
+ throw new IOException (JvNewStringUTF (strerror (errno)));
+ else if (r != 0)
+ throw new IOException (JvNewStringUTF (strerror (c)));
+ }
+ catch (java::lang::Throwable *thrown)
+ {
+ // Do some cleanup we only do on failure. If a stream object
+ // has been created, we must close the stream itself (to avoid
+ // duplicate closes when the stream object is collected).
+ // Otherwise we simply close the underlying file descriptor.
+ // We ignore errors here as they are uninteresting.
+
+ try
+ {
+ if (inputStream != NULL)
+ inputStream->close ();
+ else
+ myclose (inp[0]);
+ }
+ catch (java::lang::Throwable *ignore)
+ {
+ }
+
+ try
+ {
+ if (outputStream != NULL)
+ outputStream->close ();
+ else
+ myclose (outp[1]);
+ }
+ catch (java::lang::Throwable *ignore)
+ {
+ }
+
+ try
+ {
+ if (errorStream != NULL)
+ errorStream->close ();
+ else
+ myclose (errp[0]);
+ }
+ catch (java::lang::Throwable *ignore)
+ {
+ }
+
+ // These are potentially duplicate, but it doesn't matter due to
+ // the use of myclose.
+ myclose (outp[0]);
+ myclose (inp[1]);
+ myclose (errp[1]);
+ myclose (msgp[1]);
+
+ exception = thrown;
+ }
+
+ myclose (msgp[0]);
+ cleanup (args, env, path);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natRuntime.cc b/gcc-4.2.1/libjava/java/lang/natRuntime.cc
new file mode 100644
index 000000000..a59ec4bad
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natRuntime.cc
@@ -0,0 +1,319 @@
+// natRuntime.cc - Implementation of native side of Runtime class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-props.h>
+#include <java-stack.h>
+#include <java/lang/Long.h>
+#include <java/lang/Runtime.h>
+#include <java/lang/UnknownError.h>
+#include <java/lang/UnsatisfiedLinkError.h>
+#include <gnu/gcj/runtime/FinalizerThread.h>
+#include <java/io/File.h>
+#include <java/util/TimeZone.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Process.h>
+#include <java/lang/ConcreteProcess.h>
+#include <java/lang/ClassLoader.h>
+
+#include <jni.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <errno.h>
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
+
+
+#ifdef USE_LTDL
+#include <ltdl.h>
+
+/* FIXME: we don't always need this. The next libtool will let us use
+ AC_LTDL_PREOPEN to see if we do. */
+extern const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+
+struct lookup_data
+{
+ const char *symname;
+ void *result;
+};
+
+static int
+find_symbol (lt_dlhandle handle, lt_ptr data)
+{
+ lookup_data *ld = (lookup_data *) data;
+ ld->result = lt_dlsym (handle, ld->symname);
+ return ld->result != NULL;
+}
+
+void *
+_Jv_FindSymbolInExecutable (const char *symname)
+{
+ lookup_data data;
+ data.symname = symname;
+ data.result = NULL;
+ lt_dlforeach (find_symbol, (lt_ptr) &data);
+ return data.result;
+}
+
+#else
+
+void *
+_Jv_FindSymbolInExecutable (const char *)
+{
+ return NULL;
+}
+
+#endif /* USE_LTDL */
+
+
+
+void
+java::lang::Runtime::runFinalizationForExit ()
+{
+ if (finalizeOnExit)
+ _Jv_RunAllFinalizers ();
+}
+
+void
+java::lang::Runtime::exitInternal (jint status)
+{
+ // Make status right for Unix. This is perhaps strange.
+ if (status < 0 || status > 255)
+ status = 255;
+
+ ::exit (status);
+}
+
+jlong
+java::lang::Runtime::freeMemory (void)
+{
+ return _Jv_GCFreeMemory ();
+}
+
+void
+java::lang::Runtime::gc (void)
+{
+ _Jv_RunGC ();
+}
+
+#ifdef USE_LTDL
+// List of names for JNI_OnLoad.
+static const char *onload_names[] = _Jv_platform_onload_names;
+#endif
+
+void
+java::lang::Runtime::_load (jstring path, jboolean do_search)
+{
+ JvSynchronize sync (this);
+ using namespace java::lang;
+#ifdef USE_LTDL
+ jint len = _Jv_GetStringUTFLength (path);
+ char buf[len + 1 + strlen (_Jv_platform_solib_prefix)
+ + strlen (_Jv_platform_solib_suffix)];
+ int offset = 0;
+ if (do_search)
+ {
+ strcpy (buf, _Jv_platform_solib_prefix);
+ offset = strlen (_Jv_platform_solib_prefix);
+ }
+ jsize total = JvGetStringUTFRegion (path, 0, path->length(), &buf[offset]);
+ buf[offset + total] = '\0';
+
+ char *lib_name = buf;
+
+ if (do_search)
+ {
+ ClassLoader *look = _Jv_StackTrace::GetFirstNonSystemClassLoader ();
+
+ if (look != NULL)
+ {
+ // Don't include solib prefix in string passed to
+ // findLibrary.
+ jstring name = look->findLibrary(JvNewStringUTF(&buf[offset]));
+ if (name != NULL)
+ {
+ len = _Jv_GetStringUTFLength (name);
+ lib_name = (char *) _Jv_AllocBytes(len + 1);
+ total = JvGetStringUTFRegion (name, 0,
+ name->length(), lib_name);
+ lib_name[total] = '\0';
+ // Don't append suffixes any more; we have the full file
+ // name.
+ do_search = false;
+ }
+ }
+ }
+
+ lt_dlhandle h;
+ // FIXME: make sure path is absolute.
+ {
+ // Synchronize on java.lang.Class. This is to protect the class chain from
+ // concurrent modification by class registration calls which may be run
+ // during the dlopen().
+ JvSynchronize sync (&java::lang::Class::class$);
+ h = do_search ? lt_dlopenext (lib_name) : lt_dlopen (lib_name);
+ }
+ if (h == NULL)
+ {
+ const char *msg = lt_dlerror ();
+ jstring str = JvNewStringLatin1 (lib_name);
+ str = str->concat (JvNewStringLatin1 (": "));
+ str = str->concat (JvNewStringLatin1 (msg));
+ throw new UnsatisfiedLinkError (str);
+ }
+
+ // Search for JNI_OnLoad function.
+ void *onload = NULL;
+ const char **name = onload_names;
+ while (*name != NULL)
+ {
+ onload = lt_dlsym (h, *name);
+ if (onload != NULL)
+ break;
+ ++name;
+ }
+
+ if (onload != NULL)
+ {
+ JavaVM *vm = _Jv_GetJavaVM ();
+ if (vm == NULL)
+ {
+ // FIXME: what?
+ return;
+ }
+
+ // Push a new frame so that JNI_OnLoad will get the right class
+ // loader if it calls FindClass.
+ ::java::lang::ClassLoader *loader
+ = _Jv_StackTrace::GetFirstNonSystemClassLoader();
+ JNIEnv *env = _Jv_GetJNIEnvNewFrameWithLoader (loader);
+ jint vers = ((jint (JNICALL *) (JavaVM *, void *)) onload) (vm, NULL);
+ _Jv_JNI_PopSystemFrame (env);
+ if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2
+ && vers != JNI_VERSION_1_4)
+ {
+ // FIXME: unload the library.
+ throw new UnsatisfiedLinkError (JvNewStringLatin1 ("unrecognized version from JNI_OnLoad"));
+ }
+ }
+#else
+ throw new UnknownError
+ (JvNewStringLatin1 (do_search
+ ? "Runtime.loadLibrary not implemented"
+ : "Runtime.load not implemented"));
+#endif /* USE_LTDL */
+}
+
+jboolean
+java::lang::Runtime::loadLibraryInternal (jstring lib)
+{
+ JvSynchronize sync (this);
+ using namespace java::lang;
+#ifdef USE_LTDL
+ jint len = _Jv_GetStringUTFLength (lib);
+ char buf[len + 1];
+ jsize total = JvGetStringUTFRegion (lib, 0, lib->length(), buf);
+ buf[total] = '\0';
+ // FIXME: make sure path is absolute.
+ lt_dlhandle h = lt_dlopenext (buf);
+ return h != NULL;
+#else
+ return false;
+#endif /* USE_LTDL */
+}
+
+void
+java::lang::Runtime::init (void)
+{
+#ifdef USE_LTDL
+ lt_dlinit ();
+ // Set module load path.
+ lt_dlsetsearchpath (_Jv_Module_Load_Path);
+ // Make sure self is opened.
+ lt_dlopen (NULL);
+#endif
+}
+
+void
+java::lang::Runtime::runFinalization (void)
+{
+ gnu::gcj::runtime::FinalizerThread::finalizerReady ();
+}
+
+jlong
+java::lang::Runtime::totalMemory (void)
+{
+ return _Jv_GCTotalMemory ();
+}
+
+jlong
+java::lang::Runtime::maxMemory (void)
+{
+ // We don't have a maximum. FIXME: we might if we ask the GC for
+ // one.
+ return Long::MAX_VALUE;
+}
+
+void
+java::lang::Runtime::traceInstructions (jboolean)
+{
+ // Do nothing.
+}
+
+void
+java::lang::Runtime::traceMethodCalls (jboolean)
+{
+ // Do nothing.
+}
+
+java::lang::Process *
+java::lang::Runtime::execInternal (jstringArray cmd,
+ jstringArray env,
+ java::io::File *dir)
+{
+ return new java::lang::ConcreteProcess (cmd, env, dir);
+}
+
+jint
+java::lang::Runtime::availableProcessors (void)
+{
+ // FIXME: find the real value.
+ return 1;
+}
+
+jstring
+java::lang::Runtime::nativeGetLibname (jstring pathname, jstring libname)
+{
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
+ sb->append(pathname);
+ if (pathname->length() > 0)
+ sb->append (_Jv_platform_file_separator);
+
+ sb->append (JvNewStringLatin1 (_Jv_platform_solib_prefix));
+ sb->append(libname);
+ sb->append (JvNewStringLatin1 (_Jv_platform_solib_suffix));
+
+ return sb->toString();
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natString.cc b/gcc-4.2.1/libjava/java/lang/natString.cc
new file mode 100644
index 000000000..495a356a1
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natString.cc
@@ -0,0 +1,1044 @@
+// natString.cc - Implementation of java.lang.String native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <java/lang/Character.h>
+#include <java/lang/CharSequence.h>
+#include <java/lang/String.h>
+#include <java/lang/IndexOutOfBoundsException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/StringIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/StringBuffer.h>
+#include <java/io/ByteArrayOutputStream.h>
+#include <java/io/OutputStreamWriter.h>
+#include <java/io/ByteArrayInputStream.h>
+#include <java/io/InputStreamReader.h>
+#include <java/util/Locale.h>
+#include <gnu/gcj/convert/UnicodeToBytes.h>
+#include <gnu/gcj/convert/BytesToUnicode.h>
+#include <gnu/gcj/runtime/StringBuffer.h>
+#include <jvm.h>
+
+static jstring* strhash = NULL;
+static int strhash_count = 0; /* Number of slots used in strhash. */
+static int strhash_size = 0; /* Number of slots available in strhash.
+ * Assumed be power of 2! */
+
+// Some defines used by toUpperCase / toLowerCase.
+#define ESSET 0x00df
+#define CAPITAL_S 0x0053
+#define SMALL_I 0x0069
+#define CAPITAL_I_WITH_DOT 0x0130
+#define SMALL_DOTLESS_I 0x0131
+#define CAPITAL_I 0x0049
+
+#define DELETED_STRING ((jstring)(~0))
+#define SET_STRING_IS_INTERNED(STR) /* nothing */
+
+#define UNMASK_PTR(Ptr) (((unsigned long) (Ptr)) & ~0x01)
+#define MASK_PTR(Ptr) (((unsigned long) (Ptr)) | 0x01)
+#define PTR_MASKED(Ptr) (((unsigned long) (Ptr)) & 0x01)
+
+/* Find a slot where the string with elements DATA, length LEN,
+ and hash HASH should go in the strhash table of interned strings. */
+jstring*
+_Jv_StringFindSlot (jchar* data, jint len, jint hash)
+{
+ JvSynchronize sync (&java::lang::String::class$);
+
+ int start_index = hash & (strhash_size - 1);
+ int deleted_index = -1;
+
+ int index = start_index;
+ /* step must be non-zero, and relatively prime with strhash_size. */
+ jint step = (hash ^ (hash >> 16)) | 1;
+ do
+ {
+ jstring* ptr = &strhash[index];
+ jstring value = (jstring) UNMASK_PTR (*ptr);
+ if (value == NULL)
+ {
+ if (deleted_index >= 0)
+ return (&strhash[deleted_index]);
+ else
+ return ptr;
+ }
+ else if (*ptr == DELETED_STRING)
+ deleted_index = index;
+ else if (value->length() == len
+ && memcmp(JvGetStringChars(value), data, 2*len) == 0)
+ return (ptr);
+ index = (index + step) & (strhash_size - 1);
+ }
+ while (index != start_index);
+ // Note that we can have INDEX == START_INDEX if the table has no
+ // NULL entries but does have DELETED_STRING entries.
+ JvAssert (deleted_index >= 0);
+ return &strhash[deleted_index];
+}
+
+/* Calculate a hash code for the string starting at PTR at given LENGTH.
+ This uses the same formula as specified for java.lang.String.hash. */
+
+static jint
+hashChars (jchar* ptr, jint length)
+{
+ jchar* limit = ptr + length;
+ jint hash = 0;
+ // Updated specification from
+ // http://www.javasoft.com/docs/books/jls/clarify.html.
+ while (ptr < limit)
+ hash = (31 * hash) + *ptr++;
+ return hash;
+}
+
+jint
+java::lang::String::hashCode()
+{
+ if (cachedHashCode == 0)
+ cachedHashCode = hashChars(JvGetStringChars(this), length());
+ return cachedHashCode;
+}
+
+jstring*
+_Jv_StringGetSlot (jstring str)
+{
+ jchar* data = JvGetStringChars(str);
+ int length = str->length();
+ return _Jv_StringFindSlot(data, length, hashChars (data, length));
+}
+
+static void
+rehash ()
+{
+ JvSynchronize sync (&java::lang::String::class$);
+
+ if (strhash == NULL)
+ {
+ strhash_size = 1024;
+ strhash = (jstring *) _Jv_AllocBytes (strhash_size * sizeof (jstring));
+ }
+ else
+ {
+ int i = strhash_size;
+ jstring* ptr = strhash + i;
+ int nsize = strhash_size * 2;
+ jstring *next = (jstring *) _Jv_AllocBytes (nsize * sizeof (jstring));
+
+ while (--i >= 0)
+ {
+ --ptr;
+ if (*ptr == NULL || *ptr == DELETED_STRING)
+ continue;
+
+ /* This is faster equivalent of
+ * *__JvGetInternSlot(*ptr) = *ptr; */
+ jstring val = (jstring) UNMASK_PTR (*ptr);
+ jint hash = val->hashCode();
+ jint index = hash & (nsize - 1);
+ jint step = (hash ^ (hash >> 16)) | 1;
+ for (;;)
+ {
+ if (next[index] == NULL)
+ {
+ next[index] = *ptr;
+ break;
+ }
+ index = (index + step) & (nsize - 1);
+ }
+ }
+
+ strhash_size = nsize;
+ strhash = next;
+ }
+}
+
+jstring
+java::lang::String::intern()
+{
+ JvSynchronize sync (&java::lang::String::class$);
+ if (3 * strhash_count >= 2 * strhash_size)
+ rehash();
+ jstring* ptr = _Jv_StringGetSlot(this);
+ if (*ptr != NULL && *ptr != DELETED_STRING)
+ {
+ // See description in _Jv_FinalizeString() to understand this.
+ *ptr = (jstring) MASK_PTR (*ptr);
+ return (jstring) UNMASK_PTR (*ptr);
+ }
+ jstring str = (this->data == this
+ ? this
+ : _Jv_NewString(JvGetStringChars(this), this->length()));
+ SET_STRING_IS_INTERNED(str);
+ strhash_count++;
+ *ptr = str;
+ // When string is GC'd, clear the slot in the hash table.
+ _Jv_RegisterStringFinalizer (str);
+ return str;
+}
+
+// The fake String finalizer. This is only used when the String has
+// been intern()d. However, we must check this case, as it might be
+// called by the Reference code for any String.
+void
+_Jv_FinalizeString (jobject obj)
+{
+ JvSynchronize sync (&java::lang::String::class$);
+
+ // We might not actually have intern()d any strings at all, if
+ // we're being called from Reference.
+ if (! strhash)
+ return;
+
+ jstring str = reinterpret_cast<jstring> (obj);
+ jstring *ptr = _Jv_StringGetSlot(str);
+ if (*ptr == NULL || *ptr == DELETED_STRING
+ || (jobject) UNMASK_PTR (*ptr) != obj)
+ return;
+
+ // We assume the lowest bit of the pointer is free for our nefarious
+ // manipulations. What we do is set it to `0' (implicitly) when
+ // interning the String. If we subsequently re-intern the same
+ // String, then we set the bit. When finalizing, if the bit is set
+ // then we clear it and re-register the finalizer. We know this is
+ // a safe approach because both intern() and _Jv_FinalizeString()
+ // acquire the class lock; this bit can't be manipulated when the
+ // lock is not held. So if we are finalizing and the bit is clear
+ // then we know all references are gone and we can clear the entry
+ // in the hash table. The naive approach of simply clearing the
+ // pointer here fails in the case where a request to intern a new
+ // string with the same contents is made between the time the
+ // intern()d string is found to be unreachable and when the
+ // finalizer is actually run. In this case we could clear a pointer
+ // to a valid string, and future intern() calls for that particular
+ // value would spuriously fail.
+ if (PTR_MASKED (*ptr))
+ {
+ *ptr = (jstring) UNMASK_PTR (*ptr);
+ _Jv_RegisterStringFinalizer (obj);
+ }
+ else
+ {
+ *ptr = DELETED_STRING;
+ strhash_count--;
+ }
+}
+
+jstring
+_Jv_NewStringUTF (const char *bytes)
+{
+ int size = strlen (bytes);
+ unsigned char *p = (unsigned char *) bytes;
+
+ int length = _Jv_strLengthUtf8 ((char *) p, size);
+ if (length < 0)
+ return NULL;
+
+ jstring jstr = JvAllocString (length);
+ jchar *chrs = JvGetStringChars (jstr);
+
+ p = (unsigned char *) bytes;
+ unsigned char *limit = p + size;
+ while (p < limit)
+ *chrs++ = UTF8_GET (p, limit);
+
+ return jstr;
+}
+
+jstring
+_Jv_NewStringUtf8Const (Utf8Const* str)
+{
+ jchar *chrs;
+ jchar buffer[100];
+ jstring jstr;
+ unsigned char* data = (unsigned char*) str->data;
+ unsigned char* limit = data + str->length;
+ int length = _Jv_strLengthUtf8(str->data, str->length);
+
+ if (length <= (int) (sizeof(buffer) / sizeof(jchar)))
+ {
+ jstr = NULL;
+ chrs = buffer;
+ }
+ else
+ {
+ jstr = JvAllocString(length);
+ chrs = JvGetStringChars(jstr);
+ }
+
+ jint hash = 0;
+ while (data < limit)
+ {
+ jchar ch = UTF8_GET(data, limit);
+ hash = (31 * hash) + ch;
+ *chrs++ = ch;
+ }
+ chrs -= length;
+
+ JvSynchronize sync (&java::lang::String::class$);
+ if (3 * strhash_count >= 2 * strhash_size)
+ rehash();
+ jstring* ptr = _Jv_StringFindSlot (chrs, length, hash);
+ if (*ptr != NULL && *ptr != DELETED_STRING)
+ return (jstring) UNMASK_PTR (*ptr);
+ strhash_count++;
+ if (jstr == NULL)
+ {
+ jstr = JvAllocString(length);
+ chrs = JvGetStringChars(jstr);
+ memcpy (chrs, buffer, sizeof(jchar)*length);
+ }
+ jstr->cachedHashCode = hash;
+ *ptr = jstr;
+ SET_STRING_IS_INTERNED(jstr);
+ // When string is GC'd, clear the slot in the hash table. Note that
+ // we don't have to call _Jv_RegisterStringFinalizer here, as we
+ // know the new object cannot be referred to by a Reference.
+ _Jv_RegisterFinalizer ((void *) jstr, _Jv_FinalizeString);
+ return jstr;
+}
+
+jsize
+_Jv_GetStringUTFLength (jstring string)
+{
+ jsize len = 0;
+ jchar *ptr = JvGetStringChars (string);
+ jsize i = string->length();
+ while (--i >= 0)
+ {
+ jchar ch = *ptr++;
+ if (ch > 0 && ch <= 0x7F)
+ len += 1;
+ else if (ch <= 0x7FF)
+ len += 2;
+ else
+ len += 3;
+ }
+ return len;
+}
+
+// Not sure this quite matches GetStringUTFRegion.
+// null-termination of result? len? throw exception?
+jsize
+_Jv_GetStringUTFRegion (jstring str, jsize start, jsize len, char *buf)
+{
+ jchar *sptr = JvGetStringChars (str) + start;
+ jsize i = len;
+ char *dptr = buf;
+ while (--i >= 0)
+ {
+ jchar ch = *sptr++;
+ if (ch > 0 && ch <= 0x7F)
+ *dptr++ = (char) ch;
+ else if (ch <= 0x7FF)
+ {
+ *dptr++ = (char) (0xC0 + ((ch >> 6) & 0x1F));
+ *dptr++ = (char) (0x80 + (ch & 0x3F));
+ }
+ else
+ {
+ *dptr++ = (char) (0xE0 + ((ch >> 12) & 0xF));
+ *dptr++ = (char) (0x80 + ((ch >> 6) & 0x3F));
+ *dptr++ = (char) (0x80 + (ch & 0x3F));
+ }
+ }
+ return dptr - buf;
+}
+
+/* Put printed (decimal) representation of NUM in a buffer.
+ BUFEND marks the end of the buffer, which must be at least 11 jchars long.
+ Returns the COUNT of jchars written. The result is in
+ (BUFEND - COUNT) (inclusive) upto (BUFEND) (exclusive). */
+
+jint
+_Jv_FormatInt (jchar* bufend, jint num)
+{
+ register jchar* ptr = bufend;
+ jboolean isNeg;
+ if (num < 0)
+ {
+ isNeg = true;
+ if (num != (jint) -2147483648U)
+ num = -(num);
+ else
+ {
+ // Handle special case of MIN_VALUE.
+ *--ptr = '8';
+ num = 214748364;
+ }
+ }
+ else
+ isNeg = false;
+
+ do
+ {
+ *--ptr = (jchar) ((int) '0' + (num % 10));
+ num /= 10;
+ }
+ while (num > 0);
+
+ if (isNeg)
+ *--ptr = '-';
+ return bufend - ptr;
+}
+
+jstring
+java::lang::String::valueOf (jint num)
+{
+ // Use an array large enough for "-2147483648"; i.e. 11 chars.
+ jchar buffer[11];
+ int i = _Jv_FormatInt (buffer+11, num);
+ return _Jv_NewString (buffer+11-i, i);
+}
+
+jstring
+_Jv_NewString(const jchar *chars, jsize len)
+{
+ jstring str = _Jv_AllocString(len);
+ jchar* data = JvGetStringChars (str);
+ memcpy (data, chars, len * sizeof (jchar));
+ return str;
+}
+
+jstring
+_Jv_NewStringLatin1(const char *bytes, jsize len)
+{
+ jstring str = JvAllocString(len);
+ jchar* data = JvGetStringChars (str);
+ while (--len >= 0)
+ *data++ = *(unsigned char*)bytes++;
+ return str;
+}
+
+void
+java::lang::String::init(jcharArray chars, jint offset, jint count,
+ jboolean dont_copy)
+{
+ if (! chars)
+ throw new NullPointerException;
+ jsize data_size = JvGetArrayLength (chars);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ throw new ArrayIndexOutOfBoundsException;
+ jcharArray array;
+ jchar *pdst;
+ if (! dont_copy)
+ {
+ array = JvNewCharArray(count);
+ pdst = elements (array);
+ memcpy (pdst, elements (chars) + offset, count * sizeof (jchar));
+ }
+ else
+ {
+ array = chars;
+ pdst = &(elements(array)[offset]);
+ }
+
+ data = array;
+ boffset = (char *) pdst - (char *) array;
+ this->count = count;
+}
+
+void
+java::lang::String::init(jbyteArray ascii, jint hibyte, jint offset,
+ jint count)
+{
+ if (! ascii)
+ throw new NullPointerException;
+ jsize data_size = JvGetArrayLength (ascii);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ throw new ArrayIndexOutOfBoundsException;
+ jcharArray array = JvNewCharArray(count);
+ jbyte *psrc = elements (ascii) + offset;
+ jchar *pdst = elements (array);
+ data = array;
+ boffset = (char *) pdst - (char *) array;
+ this->count = count;
+ hibyte = (hibyte & 0xff) << 8;
+ while (-- count >= 0)
+ {
+ *pdst++ = hibyte | (*psrc++ & 0xff);
+ }
+}
+
+void
+java::lang::String::init (jbyteArray bytes, jint offset, jint count,
+ jstring encoding)
+{
+ if (! bytes)
+ throw new NullPointerException;
+ jsize data_size = JvGetArrayLength (bytes);
+ if (offset < 0 || count < 0 || offset + count < 0
+ || offset + count > data_size)
+ throw new ArrayIndexOutOfBoundsException;
+ jcharArray array = JvNewCharArray (count);
+ gnu::gcj::convert::BytesToUnicode *converter
+ = gnu::gcj::convert::BytesToUnicode::getDecoder(encoding);
+ jint outpos = 0;
+ int avail = count;
+ converter->setInput(bytes, offset, offset+count);
+ while (converter->inpos < converter->inlength)
+ {
+ int done = converter->read(array, outpos, avail);
+ if (done == 0)
+ {
+ jint new_size = 2 * (outpos + avail);
+ jcharArray new_array = JvNewCharArray (new_size);
+ memcpy (elements (new_array), elements (array),
+ outpos * sizeof(jchar));
+ array = new_array;
+ avail = new_size - outpos;
+ }
+ else
+ {
+ outpos += done;
+ avail -= done;
+ }
+ }
+ converter->done ();
+ this->data = array;
+ this->boffset = (char *) elements (array) - (char *) array;
+ this->count = outpos;
+}
+
+void
+java::lang::String::init (gnu::gcj::runtime::StringBuffer *buffer)
+{
+ init (buffer->value, 0, buffer->count, true);
+}
+
+jboolean
+java::lang::String::equals(jobject anObject)
+{
+ if (anObject == NULL)
+ return false;
+ if (anObject == this)
+ return true;
+ if (anObject->getClass() != &java::lang::String::class$)
+ return false;
+ jstring other = (jstring) anObject;
+ if (count != other->count)
+ return false;
+
+ // If both have cached hash codes, check that. If the cached hash
+ // codes are zero, don't bother trying to compute them.
+ int myHash = cachedHashCode;
+ int otherHash = other->cachedHashCode;
+ if (myHash && otherHash && myHash != otherHash)
+ return false;
+
+ // We could see if both are interned, and return false. But that
+ // seems too expensive.
+
+ jchar *xptr = JvGetStringChars (this);
+ jchar *yptr = JvGetStringChars (other);
+ return ! memcmp (xptr, yptr, count * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::contentEquals(java::lang::StringBuffer* buffer)
+{
+ if (buffer == NULL)
+ throw new NullPointerException;
+ JvSynchronize sync(buffer);
+ if (count != buffer->count)
+ return false;
+ if (data == buffer->value)
+ return true; // Possible if shared.
+ jchar *xptr = JvGetStringChars(this);
+ jchar *yptr = elements(buffer->value);
+ return ! memcmp (xptr, yptr, count * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::contentEquals(java::lang::CharSequence *seq)
+{
+ if (seq->length() != count)
+ return false;
+ jchar *value = JvGetStringChars(this);
+ for (int i = 0; i < count; ++i)
+ if (value[i] != seq->charAt(i))
+ return false;
+ return true;
+}
+
+jchar
+java::lang::String::charAt(jint i)
+{
+ if (i < 0 || i >= count)
+ throw new java::lang::StringIndexOutOfBoundsException(i);
+ return JvGetStringChars(this)[i];
+}
+
+void
+java::lang::String::getChars(jint srcBegin, jint srcEnd,
+ jcharArray dst, jint dstBegin)
+{
+ jint dst_length = JvGetArrayLength (dst);
+ if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
+ throw new java::lang::StringIndexOutOfBoundsException;
+ // The 2nd part of the test below is equivalent to
+ // dstBegin + (srcEnd-srcBegin) > dst_length
+ // except that it does not overflow.
+ if (dstBegin < 0 || dstBegin > dst_length - (srcEnd-srcBegin))
+ throw new ArrayIndexOutOfBoundsException;
+ jchar *dPtr = elements (dst) + dstBegin;
+ jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ jint i = srcEnd - srcBegin;
+ memcpy (dPtr, sPtr, i * sizeof (jchar));
+}
+
+jbyteArray
+java::lang::String::getBytes (jstring enc)
+{
+ jint todo = length();
+ jint buflen = todo;
+ jbyteArray buffer = JvNewByteArray(todo);
+ jint bufpos = 0;
+ jint offset = 0;
+ gnu::gcj::convert::UnicodeToBytes *converter
+ = gnu::gcj::convert::UnicodeToBytes::getEncoder(enc);
+ while (todo > 0 || converter->havePendingBytes())
+ {
+ converter->setOutput(buffer, bufpos);
+ // We only really need to do a single write.
+ converter->setFinished();
+ int converted = converter->write(this, offset, todo, NULL);
+ bufpos = converter->count;
+ if (converted == 0 && bufpos == converter->count)
+ {
+ buflen *= 2;
+ jbyteArray newbuffer = JvNewByteArray(buflen);
+ memcpy (elements (newbuffer), elements (buffer), bufpos);
+ buffer = newbuffer;
+ }
+ else
+ bufpos = converter->count;
+
+ offset += converted;
+ todo -= converted;
+ }
+ converter->done ();
+ if (bufpos == buflen)
+ return buffer;
+ jbyteArray result = JvNewByteArray(bufpos);
+ memcpy (elements (result), elements (buffer), bufpos);
+ return result;
+}
+
+void
+java::lang::String::getBytes(jint srcBegin, jint srcEnd,
+ jbyteArray dst, jint dstBegin)
+{
+ jint dst_length = JvGetArrayLength (dst);
+ if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count)
+ throw new java::lang::StringIndexOutOfBoundsException;
+ // The 2nd part of the test below is equivalent to
+ // dstBegin + (srcEnd-srcBegin) > dst_length
+ // except that it does not overflow.
+ if (dstBegin < 0 || dstBegin > dst_length - (srcEnd-srcBegin))
+ throw new ArrayIndexOutOfBoundsException;
+ jbyte *dPtr = elements (dst) + dstBegin;
+ jchar *sPtr = JvGetStringChars (this) + srcBegin;
+ jint i = srcEnd-srcBegin;
+ while (--i >= 0)
+ *dPtr++ = (jbyte) *sPtr++;
+}
+
+jcharArray
+java::lang::String::toCharArray()
+{
+ jcharArray array = JvNewCharArray(count);
+ jchar *dPtr = elements (array);
+ jchar *sPtr = JvGetStringChars (this);
+ jint i = count;
+ memcpy (dPtr, sPtr, i * sizeof (jchar));
+ return array;
+}
+
+jboolean
+java::lang::String::equalsIgnoreCase (jstring anotherString)
+{
+ if (anotherString == NULL || count != anotherString->count)
+ return false;
+ jchar *tptr = JvGetStringChars (this);
+ jchar *optr = JvGetStringChars (anotherString);
+ jint i = count;
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if (tch != och
+ && (java::lang::Character::toLowerCase (tch)
+ != java::lang::Character::toLowerCase (och))
+ && (java::lang::Character::toUpperCase (tch)
+ != java::lang::Character::toUpperCase (och)))
+ return false;
+ }
+ return true;
+}
+
+jboolean
+java::lang::String::regionMatches (jint toffset,
+ jstring other, jint ooffset, jint len)
+{
+ if (toffset < 0 || ooffset < 0 || len < 0
+ || toffset > count - len
+ || ooffset > other->count - len)
+ return false;
+ jchar *tptr = JvGetStringChars (this) + toffset;
+ jchar *optr = JvGetStringChars (other) + ooffset;
+ jint i = len;
+ return ! memcmp (tptr, optr, i * sizeof (jchar));
+}
+
+jint
+java::lang::String::compareTo (jstring anotherString)
+{
+ jchar *tptr = JvGetStringChars (this);
+ jchar *optr = JvGetStringChars (anotherString);
+ jint tlen = this->count;
+ jint olen = anotherString->count;
+ jint i = tlen > olen ? olen : tlen;
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if (tch != och)
+ return (jint) tch - (jint) och;
+ }
+ return tlen - olen;
+}
+
+jboolean
+java::lang::String::regionMatches (jboolean ignoreCase, jint toffset,
+ jstring other, jint ooffset, jint len)
+{
+ if (toffset < 0 || ooffset < 0 || len < 0
+ || toffset > count - len
+ || ooffset > other->count - len)
+ return false;
+ jchar *tptr = JvGetStringChars (this) + toffset;
+ jchar *optr = JvGetStringChars (other) + ooffset;
+ jint i = len;
+ if (ignoreCase)
+ {
+ while (--i >= 0)
+ {
+ jchar tch = *tptr++;
+ jchar och = *optr++;
+ if ((java::lang::Character::toLowerCase (tch)
+ != java::lang::Character::toLowerCase (och))
+ && (java::lang::Character::toUpperCase (tch)
+ != java::lang::Character::toUpperCase (och)))
+ return false;
+ }
+ return true;
+ }
+ return ! memcmp (tptr, optr, i * sizeof (jchar));
+}
+
+jboolean
+java::lang::String::startsWith (jstring prefix, jint toffset)
+{
+ jint i = prefix->count;
+ if (toffset < 0 || toffset > count - i)
+ return false;
+ jchar *xptr = JvGetStringChars (this) + toffset;
+ jchar *yptr = JvGetStringChars (prefix);
+ return ! memcmp (xptr, yptr, i * sizeof (jchar));
+}
+
+jint
+java::lang::String::indexOf (jint ch, jint fromIndex)
+{
+ if (fromIndex < 0)
+ fromIndex = 0;
+ jchar *ptr = JvGetStringChars(this);
+ for (;; ++fromIndex)
+ {
+ if (fromIndex >= count)
+ return -1;
+ if (ptr[fromIndex] == ch)
+ return fromIndex;
+ }
+}
+
+jint
+java::lang::String::indexOf (jstring s, jint fromIndex)
+{
+ const jchar *const xchars = JvGetStringChars(s);
+ const jchar *const ychars = JvGetStringChars(this) + fromIndex;
+
+ const int xlength = s->length ();
+ const int ylength = length () - fromIndex;
+
+ int i = 0;
+ int j = 0;
+
+ while (i < ylength && j < xlength)
+ {
+ if (xchars[j] != ychars[i])
+ {
+ i = i - j + 1;
+ j = 0;
+ }
+ else
+ i++, j++;
+ }
+
+ if (j >= xlength)
+ return fromIndex + i - xlength;
+ else
+ return -1;
+}
+
+jint
+java::lang::String::lastIndexOf (jint ch, jint fromIndex)
+{
+ if (fromIndex >= count)
+ fromIndex = count - 1;
+ jchar *ptr = JvGetStringChars(this);
+ for (;; --fromIndex)
+ {
+ if (fromIndex < 0)
+ return -1;
+ if (ptr[fromIndex] == ch)
+ return fromIndex;
+ }
+}
+
+jstring
+java::lang::String::substring (jint beginIndex, jint endIndex)
+{
+ if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
+ throw new StringIndexOutOfBoundsException;
+ if (beginIndex == 0 && endIndex == count)
+ return this;
+ jint newCount = endIndex - beginIndex;
+ // For very small strings, just allocate a new one. For other
+ // substrings, allocate a new one unless the substring is over half
+ // of the original string.
+ if (newCount <= 8 || newCount < (count >> 1))
+ return JvNewString(JvGetStringChars(this) + beginIndex, newCount);
+ jstring s = new String();
+ s->data = data;
+ s->count = newCount;
+ s->boffset = boffset + sizeof(jchar) * beginIndex;
+ return s;
+}
+
+jstring
+java::lang::String::concat(jstring str)
+{
+ jint str_count = str->count;
+ if (str_count == 0)
+ return this;
+ jstring result = JvAllocString(count + str_count);
+ jchar *dstPtr = JvGetStringChars(result);
+ jchar *srcPtr = JvGetStringChars(this);
+ jint i = count;
+ memcpy (dstPtr, srcPtr, i * sizeof (jchar));
+ dstPtr += i;
+ srcPtr = JvGetStringChars(str);
+ i = str->count;
+ memcpy (dstPtr, srcPtr, i * sizeof (jchar));
+ return result;
+}
+
+jstring
+java::lang::String::replace (jchar oldChar, jchar newChar)
+{
+ jint i;
+ jchar* chrs = JvGetStringChars (this);
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ return this;
+ if (chrs[i] == oldChar)
+ break;
+ }
+ jstring result = JvAllocString (count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (int j = 0; j < i; j++)
+ *dPtr++ = chrs[j];
+ for (; i < count; i++)
+ {
+ jchar ch = chrs[i];
+ if (ch == oldChar)
+ ch = newChar;
+ *dPtr++ = ch;
+ }
+ return result;
+}
+
+jstring
+java::lang::String::toLowerCase (java::util::Locale *locale)
+{
+ jint i;
+ jchar* chrs = JvGetStringChars(this);
+ jchar ch = 0;
+
+ bool handle_tr = false;
+ if (locale != NULL)
+ {
+ String *lang = locale->getLanguage ();
+ if (lang->length () == 2
+ && lang->charAt (0) == 't'
+ && lang->charAt (1) == 'r')
+ handle_tr = true;
+ }
+
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ return this;
+ jchar origChar = chrs[i];
+
+ if (handle_tr && (origChar == CAPITAL_I
+ || origChar == CAPITAL_I_WITH_DOT))
+ break;
+
+ ch = java::lang::Character::toLowerCase(origChar);
+ if (ch != origChar)
+ break;
+ }
+ jstring result = JvAllocString(count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (int j = 0; j < i; j++)
+ *dPtr++ = chrs[j];
+ *dPtr++ = ch; i++;
+ for (; i < count; i++)
+ {
+ if (handle_tr && chrs[i] == CAPITAL_I)
+ *dPtr++ = SMALL_DOTLESS_I;
+ else if (handle_tr && chrs[i] == CAPITAL_I_WITH_DOT)
+ *dPtr++ = SMALL_I;
+ else
+ *dPtr++ = java::lang::Character::toLowerCase(chrs[i]);
+ }
+ return result;
+}
+
+jstring
+java::lang::String::toUpperCase (java::util::Locale *locale)
+{
+ jint i;
+ jchar* chrs = JvGetStringChars(this);
+ jchar ch;
+
+ // When handling a specific locale there might be special rules.
+ // Currently all existing rules are simply handled inline, as there
+ // are only two and they are documented in the online 1.2 docs.
+ bool handle_esset = locale != NULL;
+ bool handle_tr = false;
+ if (locale != NULL)
+ {
+ String *lang = locale->getLanguage ();
+ if (lang->length () == 2
+ && lang->charAt (0) == 't'
+ && lang->charAt (1) == 'r')
+ handle_tr = true;
+ }
+
+ int new_count = count;
+ bool new_string = false;
+ for (i = 0; ; i++)
+ {
+ if (i == count)
+ break;
+ jchar origChar = chrs[i];
+
+ if (handle_esset && origChar == ESSET)
+ {
+ ++new_count;
+ new_string = true;
+ }
+ else if (handle_tr && (origChar == SMALL_I
+ || origChar == SMALL_DOTLESS_I))
+ new_string = true;
+ else
+ {
+ ch = java::lang::Character::toUpperCase(origChar);
+ if (ch != origChar)
+ new_string = true;
+ }
+
+ if (new_string && ! handle_esset)
+ break;
+ }
+ if (! new_string)
+ return this;
+ jstring result = JvAllocString(new_count);
+ jchar *dPtr = JvGetStringChars (result);
+ for (i = 0; i < count; i++)
+ {
+ if (handle_esset && chrs[i] == ESSET)
+ {
+ *dPtr++ = CAPITAL_S;
+ *dPtr++ = CAPITAL_S;
+ }
+ else if (handle_tr && chrs[i] == SMALL_I)
+ *dPtr++ = CAPITAL_I_WITH_DOT;
+ else if (handle_tr && chrs[i] == SMALL_DOTLESS_I)
+ *dPtr++ = CAPITAL_I;
+ else
+ *dPtr++ = java::lang::Character::toUpperCase(chrs[i]);
+ }
+ return result;
+}
+
+jstring
+java::lang::String::trim ()
+{
+ jchar* chrs = JvGetStringChars(this);
+ if (count == 0 || (chrs[0] > ' ' && chrs[count-1] > ' '))
+ return this;
+ jint preTrim = 0;
+ for (;; preTrim++)
+ {
+ if (preTrim == count)
+ return new String();
+ if (chrs[preTrim] > ' ')
+ break;
+ }
+ jint endTrim = count;
+ while (chrs[endTrim-1] <= ' ')
+ endTrim--;
+ return substring(preTrim, endTrim);
+}
+
+jstring
+java::lang::String::valueOf(jcharArray data, jint offset, jint count)
+{
+ jint data_length = JvGetArrayLength (data);
+ if (offset < 0 || count < 0 || offset > data_length - count)
+ throw new ArrayIndexOutOfBoundsException;
+ jstring result = JvAllocString(count);
+ jchar *sPtr = elements (data) + offset;
+ jchar *dPtr = JvGetStringChars(result);
+ memcpy (dPtr, sPtr, count * sizeof (jchar));
+ return result;
+}
+
+jstring
+java::lang::String::valueOf(jchar c)
+{
+ jstring result = JvAllocString(1);
+ JvGetStringChars (result)[0] = c;
+ return result;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natStringBuffer.cc b/gcc-4.2.1/libjava/java/lang/natStringBuffer.cc
new file mode 100644
index 000000000..8fbb8dfbc
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natStringBuffer.cc
@@ -0,0 +1,42 @@
+// natStringBuffer.cc - Implementation of java.lang.StringBuffer native methods.
+
+/* Copyright (C) 2001, 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <gcj/cni.h>
+#include <java/lang/StringBuffer.h>
+
+java::lang::StringBuffer*
+java::lang::StringBuffer::append (jint num)
+{
+ // Use an array large enough for "-2147483648"; i.e. 11 chars.
+ jchar buffer[11];
+ int i = _Jv_FormatInt (buffer+11, num);
+ JvSynchronize dummy (this);
+ jint needed = count + i;
+ ensureCapacity_unsynchronized (needed);
+ jchar* dst = elements (value) + count;
+ jchar* src = buffer+11-i;
+ while (--i >= 0)
+ *dst++ = *src++;
+ count = needed;
+ return this;
+}
+
+jboolean
+java::lang::StringBuffer::regionMatches(jint toffset, jstring other)
+{
+ jint len = other->count;
+ jchar *tptr = elements(value) + toffset;
+ jchar *optr = JvGetStringChars(other);
+ while (--len >= 0)
+ if (*tptr++ != *optr++)
+ return false;
+ return true;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natStringBuilder.cc b/gcc-4.2.1/libjava/java/lang/natStringBuilder.cc
new file mode 100644
index 000000000..e2c8c29f6
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natStringBuilder.cc
@@ -0,0 +1,29 @@
+// Native methods for StringBuilder.
+
+/* Copyright (C) 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <gcj/cni.h>
+#include <java/lang/StringBuilder.h>
+#include <java/lang/String.h>
+
+jboolean
+java::lang::StringBuilder::regionMatches(jint offset, jstring other)
+{
+ int len = other->count;
+ int index = 0;
+ jchar *sc = elements (value);
+ jchar *oc = _Jv_GetStringChars (other);
+ while (--len >= 0)
+ {
+ if (sc[offset++] != oc[index++])
+ return false;
+ }
+ return true;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natSystem.cc b/gcc-4.2.1/libjava/java/lang/natSystem.cc
new file mode 100644
index 000000000..42a13258d
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natSystem.cc
@@ -0,0 +1,150 @@
+// natSystem.cc - Native code implementing System class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/System.h>
+#include <java/lang/Class.h>
+#include <java/lang/ArrayStoreException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/io/PrintStream.h>
+#include <java/io/InputStream.h>
+
+
+
+void
+java::lang::System::setErr0 (java::io::PrintStream *newErr)
+{
+ err = newErr;
+}
+
+void
+java::lang::System::setIn0 (java::io::InputStream *newIn)
+{
+ in = newIn;
+}
+
+void
+java::lang::System::setOut0 (java::io::PrintStream *newOut)
+{
+ out = newOut;
+}
+
+void
+java::lang::System::arraycopy (jobject src, jint src_offset,
+ jobject dst, jint dst_offset,
+ jint count)
+{
+ if (! src || ! dst)
+ throw new NullPointerException;
+
+ jclass src_c = src->getClass();
+ jclass dst_c = dst->getClass();
+ jclass src_comp = src_c->getComponentType();
+ jclass dst_comp = dst_c->getComponentType();
+
+ if (! src_c->isArray() || ! dst_c->isArray()
+ || src_comp->isPrimitive() != dst_comp->isPrimitive()
+ || (src_comp->isPrimitive() && src_comp != dst_comp))
+ throw new ArrayStoreException;
+
+ __JArray *src_a = (__JArray *) src;
+ __JArray *dst_a = (__JArray *) dst;
+ if (src_offset < 0 || dst_offset < 0 || count < 0
+ || (unsigned jint) src_offset > (unsigned jint) src_a->length
+ || (unsigned jint) (src_offset + count) > (unsigned jint) src_a->length
+ || (unsigned jint) dst_offset > (unsigned jint) dst_a->length
+ || (unsigned jint) (dst_offset + count) > (unsigned jint) dst_a->length)
+ throw new ArrayIndexOutOfBoundsException;
+
+ // Do-nothing cases.
+ if ((src == dst && src_offset == dst_offset)
+ || ! count)
+ return;
+
+ // If both are primitive, we can optimize trivially. If DST
+ // components are always assignable from SRC components, then we
+ // will never need to raise an error, and thus can do the
+ // optimization. If source and destinations are the same, then we
+ // know that the assignability premise always holds.
+ const bool prim = src_comp->isPrimitive();
+ if (prim || dst_comp->isAssignableFrom(src_comp) || src == dst)
+ {
+ const size_t size = (prim ? src_comp->size()
+ : sizeof elements((jobjectArray)src)[0]);
+
+ char *src_elts = _Jv_GetArrayElementFromElementType (src, src_comp);
+ src_elts += size * src_offset;
+
+ char *dst_elts = _Jv_GetArrayElementFromElementType (dst, dst_comp);
+ dst_elts += size * dst_offset;
+
+#if HAVE_MEMMOVE
+ // We don't bother trying memcpy. It can't be worth the cost of
+ // the check.
+ // Don't cast to (void*), as memmove may expect (char*)
+ memmove (dst_elts, src_elts, count * size);
+#else
+ bcopy (src_elts, dst_elts, count * size);
+#endif
+ }
+ else
+ {
+ jobject *src_elts = elements ((jobjectArray) src_a) + src_offset;
+ jobject *dst_elts = elements ((jobjectArray) dst_a) + dst_offset;
+
+ for (int i = 0; i < count; ++i)
+ {
+ if (*src_elts
+ && ! dst_comp->isAssignableFrom((*src_elts)->getClass()))
+ throw new ArrayStoreException;
+ *dst_elts++ = *src_elts++;
+ }
+ }
+}
+
+jlong
+java::lang::System::currentTimeMillis (void)
+{
+ return _Jv_platform_gettimeofday ();
+}
+
+jlong
+java::lang::System::nanoTime ()
+{
+ return _Jv_platform_nanotime ();
+}
+
+jint
+java::lang::System::identityHashCode (jobject obj)
+{
+ return _Jv_HashCode (obj);
+}
+
+jstring
+java::lang::System::getenv0 (jstring name)
+{
+ jint len = _Jv_GetStringUTFLength (name);
+ char buf[len + 1];
+ jsize total = JvGetStringUTFRegion (name, 0, name->length(), buf);
+ buf[total] = '\0';
+ const char *value = ::getenv (buf);
+ if (value == NULL)
+ return NULL;
+ return JvNewStringUTF (value);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natThread.cc b/gcc-4.2.1/libjava/java/lang/natThread.cc
new file mode 100644
index 000000000..facce30fa
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natThread.cc
@@ -0,0 +1,472 @@
+// natThread.cc - Native part of Thread class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-threads.h>
+
+#include <gnu/gcj/RawDataManaged.h>
+#include <java/lang/Thread.h>
+#include <java/lang/ThreadGroup.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+
+#include <jni.h>
+
+#ifdef ENABLE_JVMPI
+#include <jvmpi.h>
+#endif
+
+
+
+// This structure is used to represent all the data the native side
+// needs. An object of this type is assigned to the `data' member of
+// the Thread class.
+struct natThread
+{
+ // These are used to interrupt sleep and join calls. We can share a
+ // condition variable here since it only ever gets notified when the thread
+ // exits.
+ _Jv_Mutex_t join_mutex;
+ _Jv_ConditionVariable_t join_cond;
+
+ // This is private data for the thread system layer.
+ _Jv_Thread_t *thread;
+
+ // Each thread has its own JNI object.
+ JNIEnv *jni_env;
+};
+
+static void finalize_native (jobject ptr);
+
+// This is called from the constructor to initialize the native side
+// of the Thread.
+void
+java::lang::Thread::initialize_native (void)
+{
+ natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
+
+ data = (gnu::gcj::RawDataManaged *) nt;
+
+ // Register a finalizer to clean up the native thread resources.
+ _Jv_RegisterFinalizer (data, finalize_native);
+
+ _Jv_MutexInit (&nt->join_mutex);
+ _Jv_CondInit (&nt->join_cond);
+ nt->thread = _Jv_ThreadInitData (this);
+ // FIXME: if JNI_ENV is set we will want to free it. It is
+ // malloc()d.
+ nt->jni_env = NULL;
+}
+
+static void
+finalize_native (jobject ptr)
+{
+ natThread *nt = (natThread *) ptr;
+ _Jv_ThreadDestroyData (nt->thread);
+#ifdef _Jv_HaveCondDestroy
+ _Jv_CondDestroy (&nt->join_cond);
+#endif
+#ifdef _Jv_HaveMutexDestroy
+ _Jv_MutexDestroy (&nt->join_mutex);
+#endif
+ _Jv_FreeJNIEnv(nt->jni_env);
+}
+
+jint
+java::lang::Thread::countStackFrames (void)
+{
+ // NOTE: This is deprecated in JDK 1.2.
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+
+ return 0;
+}
+
+java::lang::Thread *
+java::lang::Thread::currentThread (void)
+{
+ return _Jv_ThreadCurrent ();
+}
+
+jboolean
+java::lang::Thread::holdsLock (jobject obj)
+{
+ if (!obj)
+ throw new NullPointerException;
+ return !_Jv_ObjectCheckMonitor (obj);
+}
+
+void
+java::lang::Thread::interrupt (void)
+{
+ checkAccess ();
+ natThread *nt = (natThread *) data;
+ JvSynchronize sync (this);
+ if (alive_flag)
+ _Jv_ThreadInterrupt (nt->thread);
+}
+
+void
+java::lang::Thread::join (jlong millis, jint nanos)
+{
+ if (millis < 0 || nanos < 0 || nanos > 999999)
+ throw new IllegalArgumentException;
+
+ Thread *current = currentThread ();
+
+ // Here `NT' is the native structure for the thread we are trying to join.
+ natThread *nt = (natThread *) data;
+
+ // Now wait for: (1) an interrupt, (2) the thread to exit, or (3)
+ // the timeout to occur.
+ _Jv_MutexLock (&nt->join_mutex);
+ if (! isAlive ())
+ {
+ _Jv_MutexUnlock (&nt->join_mutex);
+ return;
+ }
+ _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
+ _Jv_MutexUnlock (&nt->join_mutex);
+
+ if (current->isInterrupted (true))
+ throw new InterruptedException;
+}
+
+void
+java::lang::Thread::resume (void)
+{
+ checkAccess ();
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+}
+
+void
+java::lang::Thread::setPriority (jint newPriority)
+{
+ checkAccess ();
+ if (newPriority < MIN_PRIORITY || newPriority > MAX_PRIORITY)
+ throw new IllegalArgumentException;
+
+ jint gmax = group->getMaxPriority();
+ if (newPriority > gmax)
+ newPriority = gmax;
+
+ priority = newPriority;
+ natThread *nt = (natThread *) data;
+ _Jv_ThreadSetPriority (nt->thread, priority);
+}
+
+void
+java::lang::Thread::sleep (jlong millis, jint nanos)
+{
+ if (millis < 0 || nanos < 0 || nanos > 999999)
+ throw new IllegalArgumentException;
+
+ if (millis == 0 && nanos == 0)
+ ++nanos;
+
+ Thread *current = currentThread ();
+
+ // We use a condition variable to implement sleeping so that an
+ // interrupt can wake us up.
+ natThread *nt = (natThread *) current->data;
+ _Jv_MutexLock (&nt->join_mutex);
+ _Jv_CondWait (&nt->join_cond, &nt->join_mutex, millis, nanos);
+ _Jv_MutexUnlock (&nt->join_mutex);
+
+ if (current->isInterrupted (true))
+ throw new InterruptedException;
+}
+
+void
+java::lang::Thread::finish_ ()
+{
+ natThread *nt = (natThread *) data;
+
+ group->removeThread (this);
+
+#ifdef ENABLE_JVMPI
+ if (_Jv_JVMPI_Notify_THREAD_END)
+ {
+ JVMPI_Event event;
+
+ event.event_type = JVMPI_EVENT_THREAD_END;
+ event.env_id = _Jv_GetCurrentJNIEnv ();
+
+ _Jv_DisableGC ();
+ (*_Jv_JVMPI_Notify_THREAD_END) (&event);
+ _Jv_EnableGC ();
+ }
+#endif
+
+ // If a method cache was created, free it.
+ _Jv_FreeMethodCache();
+
+ // Clear out thread locals.
+ locals = NULL;
+
+ // Signal any threads that are waiting to join() us.
+ _Jv_MutexLock (&nt->join_mutex);
+
+ {
+ JvSynchronize sync (this);
+ alive_flag = false;
+ }
+
+ _Jv_CondNotifyAll (&nt->join_cond, &nt->join_mutex);
+ _Jv_MutexUnlock (&nt->join_mutex);
+}
+
+// Run once at thread startup, either when thread is attached or when
+// _Jv_ThreadRun is called.
+static void
+_Jv_NotifyThreadStart (java::lang::Thread* thread)
+{
+#ifdef ENABLE_JVMPI
+ if (_Jv_JVMPI_Notify_THREAD_START)
+ {
+ JVMPI_Event event;
+
+ jstring thread_name = thread->getName ();
+ jstring group_name = NULL, parent_name = NULL;
+ java::lang::ThreadGroup *group = thread->getThreadGroup ();
+
+ if (group)
+ {
+ group_name = group->getName ();
+ group = group->getParent ();
+
+ if (group)
+ parent_name = group->getName ();
+ }
+
+ int thread_len = thread_name ? JvGetStringUTFLength (thread_name) : 0;
+ int group_len = group_name ? JvGetStringUTFLength (group_name) : 0;
+ int parent_len = parent_name ? JvGetStringUTFLength (parent_name) : 0;
+
+ char thread_chars[thread_len + 1];
+ char group_chars[group_len + 1];
+ char parent_chars[parent_len + 1];
+
+ if (thread_name)
+ JvGetStringUTFRegion (thread_name, 0,
+ thread_name->length(), thread_chars);
+ if (group_name)
+ JvGetStringUTFRegion (group_name, 0,
+ group_name->length(), group_chars);
+ if (parent_name)
+ JvGetStringUTFRegion (parent_name, 0,
+ parent_name->length(), parent_chars);
+
+ thread_chars[thread_len] = '\0';
+ group_chars[group_len] = '\0';
+ parent_chars[parent_len] = '\0';
+
+ event.event_type = JVMPI_EVENT_THREAD_START;
+ event.env_id = NULL;
+ event.u.thread_start.thread_name = thread_chars;
+ event.u.thread_start.group_name = group_chars;
+ event.u.thread_start.parent_name = parent_chars;
+ event.u.thread_start.thread_id = (jobjectID) thread;
+ event.u.thread_start.thread_env_id = _Jv_GetCurrentJNIEnv ();
+
+ _Jv_DisableGC ();
+ (*_Jv_JVMPI_Notify_THREAD_START) (&event);
+ _Jv_EnableGC ();
+ }
+#endif
+}
+
+void
+_Jv_ThreadRun (java::lang::Thread* thread)
+{
+ try
+ {
+ _Jv_NotifyThreadStart (thread);
+ thread->run ();
+ }
+ catch (java::lang::Throwable *t)
+ {
+ // Uncaught exceptions are forwarded to the ThreadGroup. If
+ // this results in an uncaught exception, that is ignored.
+ try
+ {
+ thread->group->uncaughtException (thread, t);
+ }
+ catch (java::lang::Throwable *f)
+ {
+ // Nothing.
+ }
+ }
+
+ thread->finish_ ();
+}
+
+_Jv_Thread_t*
+_Jv_ThreadGetData (java::lang::Thread* thread)
+{
+ natThread* nt = (natThread*) thread->data;
+ return nt->thread;
+}
+
+void
+java::lang::Thread::start (void)
+{
+ JvSynchronize sync (this);
+
+ // Its illegal to re-start() a thread, even if its dead.
+ if (!startable_flag)
+ throw new IllegalThreadStateException;
+
+ alive_flag = true;
+ startable_flag = false;
+ natThread *nt = (natThread *) data;
+ _Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &_Jv_ThreadRun);
+}
+
+void
+java::lang::Thread::stop (java::lang::Throwable *)
+{
+ checkAccess ();
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+}
+
+void
+java::lang::Thread::suspend (void)
+{
+ checkAccess ();
+
+ // Old applets still call this method. Rather than throwing
+ // UnsupportedOperationException we simply fail silently.
+}
+
+static int nextThreadNumber = 0;
+
+jstring
+java::lang::Thread::gen_name (void)
+{
+ jint i;
+ jclass sync = &java::lang::Thread::class$;
+ {
+ JvSynchronize dummy(sync);
+ i = ++nextThreadNumber;
+ }
+
+ // Use an array large enough for "-2147483648"; i.e. 11 chars, + "Thread-".
+ jchar buffer[7+11];
+ jchar *bufend = (jchar *) ((char *) buffer + sizeof(buffer));
+ i = _Jv_FormatInt (bufend, i);
+ jchar *ptr = bufend - i;
+ // Prepend "Thread-".
+ *--ptr = '-';
+ *--ptr = 'd';
+ *--ptr = 'a';
+ *--ptr = 'e';
+ *--ptr = 'r';
+ *--ptr = 'h';
+ *--ptr = 'T';
+ return JvNewString (ptr, bufend - ptr);
+}
+
+void
+java::lang::Thread::yield (void)
+{
+ _Jv_ThreadYield ();
+}
+
+JNIEnv *
+_Jv_GetCurrentJNIEnv ()
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ if (t == NULL)
+ return NULL;
+ return ((natThread *) t->data)->jni_env;
+}
+
+void
+_Jv_SetCurrentJNIEnv (JNIEnv *env)
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ JvAssert (t != NULL);
+ ((natThread *) t->data)->jni_env = env;
+}
+
+// Attach the current native thread to an existing (but unstarted) Thread
+// object. Does not register thread with the garbage collector.
+// Returns -1 on failure, 0 upon success.
+jint
+_Jv_AttachCurrentThread(java::lang::Thread* thread)
+{
+ JvSynchronize sync (thread);
+ if (thread == NULL || thread->startable_flag == false)
+ return -1;
+ thread->startable_flag = false;
+ thread->alive_flag = true;
+ natThread *nt = (natThread *) thread->data;
+ _Jv_ThreadRegister (nt->thread);
+ return 0;
+}
+
+java::lang::Thread*
+_Jv_AttachCurrentThread(jstring name, java::lang::ThreadGroup* group)
+{
+ // Register thread with GC before attempting any allocations.
+ _Jv_GCAttachThread ();
+ java::lang::Thread *thread = _Jv_ThreadCurrent ();
+ if (thread != NULL)
+ return thread;
+ if (name == NULL)
+ name = java::lang::Thread::gen_name ();
+ thread = new java::lang::Thread (NULL, group, NULL, name);
+ _Jv_AttachCurrentThread (thread);
+ _Jv_NotifyThreadStart (thread);
+ return thread;
+}
+
+java::lang::Thread*
+_Jv_AttachCurrentThreadAsDaemon(jstring name, java::lang::ThreadGroup* group)
+{
+ java::lang::Thread *thread = _Jv_ThreadCurrent ();
+ if (thread != NULL)
+ return thread;
+ if (name == NULL)
+ name = java::lang::Thread::gen_name ();
+ thread = new java::lang::Thread (NULL, group, NULL, name);
+ thread->setDaemon (true);
+ _Jv_AttachCurrentThread (thread);
+ _Jv_NotifyThreadStart (thread);
+ return thread;
+}
+
+jint
+_Jv_DetachCurrentThread (void)
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ if (t == NULL)
+ return -1;
+
+ _Jv_ThreadUnRegister ();
+ _Jv_GCDetachThread ();
+ // Release the monitors.
+ t->finish_ ();
+
+ return 0;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natVMClassLoader.cc b/gcc-4.2.1/libjava/java/lang/natVMClassLoader.cc
new file mode 100644
index 000000000..95c1f1593
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natVMClassLoader.cc
@@ -0,0 +1,230 @@
+// natVMClassLoader.cc - VMClassLoader native methods
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+/* Author: Kresten Krab Thorup <krab@gnu.org> */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java-threads.h>
+#include <java-interp.h>
+
+#include <java/lang/VMClassLoader.h>
+#include <java/lang/VMCompiler.h>
+#include <gnu/gcj/runtime/ExtensionClassLoader.h>
+#include <gnu/gcj/runtime/SystemClassLoader.h>
+#include <gnu/gcj/runtime/BootClassLoader.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+#include <java/lang/Throwable.h>
+#include <java/security/ProtectionDomain.h>
+#include <java/lang/ClassFormatError.h>
+#include <java/lang/StringBuffer.h>
+#include <java/lang/Runtime.h>
+#include <java/util/HashSet.h>
+#include <java/lang/VirtualMachineError.h>
+
+java::lang::Class *
+java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
+ jstring name,
+ jbyteArray data,
+ jint offset,
+ jint length,
+ java::security::ProtectionDomain *pd)
+{
+ jclass klass = VMCompiler::compileClass(loader, name, data,
+ offset, length, pd);
+
+#ifdef INTERPRETER
+ if (klass == NULL)
+ {
+ klass = new java::lang::Class ();
+
+ // Synchronize on the class, so that it is not attempted initialized
+ // until we're done loading.
+ JvSynchronize sync (klass);
+
+ // Record the defining loader. For the bootstrap class loader,
+ // we record NULL.
+ if (loader != bootLoader)
+ klass->loader = loader;
+
+ if (name != 0)
+ {
+ _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
+
+ if (! _Jv_VerifyClassName (name2))
+ throw new java::lang::ClassFormatError
+ (JvNewStringLatin1 ("erroneous class name"));
+
+ klass->name = name2;
+ }
+
+ _Jv_Utf8Const *found_name = NULL;
+ try
+ {
+ _Jv_DefineClass (klass, data, offset, length, pd, &found_name);
+ }
+ catch (java::lang::Throwable *ex)
+ {
+ klass->state = JV_STATE_ERROR;
+ klass->notifyAll ();
+
+ if (found_name != NULL)
+ _Jv_UnregisterInitiatingLoader (klass, klass->loader);
+
+ // If EX is not a ClassNotFoundException, that's ok, because we
+ // account for the possibility in defineClass().
+ throw ex;
+ }
+
+ // if everything proceeded sucessfully, we're loaded.
+ JvAssert (klass->state == JV_STATE_LOADED);
+ }
+#endif // INTERPRETER
+
+ if (! klass)
+ {
+ StringBuffer *sb = new StringBuffer();
+ if (name)
+ {
+ sb->append(JvNewStringLatin1("found class file for class "));
+ sb->append(name);
+ }
+ else
+ sb->append(JvNewStringLatin1("found unnamed class file"));
+ sb->append(JvNewStringLatin1(", but no interpreter configured in this libgcj"));
+ throw new VirtualMachineError(sb->toString());
+ }
+
+ return klass;
+}
+
+java::lang::ClassLoader *
+java::lang::VMClassLoader::getSystemClassLoaderInternal()
+{
+ _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$);
+ _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance);
+ return gnu::gcj::runtime::ExtensionClassLoader::system_instance;
+}
+
+jclass
+java::lang::VMClassLoader::getPrimitiveClass (jchar type)
+{
+ char sig[2];
+ sig[0] = (char) type;
+ sig[1] = '\0';
+ // Note: this cannot return NULL, since the input is always correct.
+ return _Jv_FindClassFromSignature (sig, NULL);
+}
+
+void
+java::lang::VMClassLoader::initBootLoader(jstring libdir)
+{
+ bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir);
+}
+
+jclass
+java::lang::VMClassLoader::nativeFindClass (jstring name)
+{
+ jclass klass = NULL;
+
+ if (lib_control != LIB_NEVER)
+ {
+ // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for
+ // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
+ // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of
+ // these causes the class to appear in the cache, then use it.
+ java::lang::StringBuffer *sb
+ = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
+ // Skip inner classes
+ jstring cn;
+ jint ci = name->indexOf('$');
+ if (ci == -1)
+ cn = name;
+ else
+ cn = name->substring (0, ci);
+ jstring so_base_name
+ = (sb->append (cn)->toString ())->replace ('.', '-');
+
+ using namespace ::java::lang;
+ Runtime *rt = Runtime::getRuntime();
+
+ _Jv_Utf8Const *name_u = NULL;
+
+ // Compare against `3' because that is the length of "lib".
+ while (! klass && so_base_name && so_base_name->length() > 3)
+ {
+ if (lib_control == LIB_CACHE)
+ {
+ // If we've already tried this name, we're done.
+ if (tried_libraries->contains(so_base_name))
+ break;
+ tried_libraries->add(so_base_name);
+ }
+
+ jboolean loaded = rt->loadLibraryInternal (so_base_name);
+
+ jint nd = so_base_name->lastIndexOf ('-');
+ if (nd == -1)
+ so_base_name = NULL;
+ else
+ so_base_name = so_base_name->substring (0, nd);
+
+ if (loaded)
+ {
+ if (name_u == NULL)
+ name_u = _Jv_makeUtf8Const (name);
+ klass = _Jv_FindClassInCache (name_u);
+ }
+ }
+ }
+
+ if (klass)
+ definePackageForNative(name);
+
+ return klass;
+}
+
+jclass
+java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
+{
+ // We try the boot loader first, so that the endorsed directory
+ // overrides compiled-in classes.
+ jclass klass = NULL;
+ if (bootLoader)
+ klass = bootLoader->bootLoadClass(name);
+ if (! klass)
+ {
+ _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
+ klass = _Jv_FindClassInCache (utf);
+ }
+ if (! klass)
+ klass = nativeFindClass(name);
+ if (klass)
+ {
+ // We never want to return a class without its supers linked.
+ // It isn't clear from the spec, but this is what other
+ // implementations do in practice.
+ if (resolve)
+ resolveClass (klass);
+ else
+ _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
+
+ definePackageForNative(name);
+ }
+
+ return klass;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natVMSecurityManager.cc b/gcc-4.2.1/libjava/java/lang/natVMSecurityManager.cc
new file mode 100644
index 000000000..9d52c92c7
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natVMSecurityManager.cc
@@ -0,0 +1,29 @@
+/* Copyright (C) 2002 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/VMSecurityManager.h>
+#include <java/lang/SecurityManager.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+
+JArray<jclass> *
+java::lang::VMSecurityManager::getClassContext (jclass klass)
+{
+ JArray<jclass> *result =
+ _Jv_StackTrace::GetClassContext (klass);
+
+ return result;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natVMThrowable.cc b/gcc-4.2.1/libjava/java/lang/natVMThrowable.cc
new file mode 100644
index 000000000..b198f9073
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natVMThrowable.cc
@@ -0,0 +1,45 @@
+// natVMThrowable.cc - Native part of VMThrowable class.
+
+/* Copyright (C) 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/Throwable.h>
+#include <java/lang/VMThrowable.h>
+
+using namespace gnu::gcj;
+
+java::lang::VMThrowable *
+java::lang::VMThrowable::fillInStackTrace (java::lang::Throwable *)
+{
+ using namespace java::lang;
+
+ // Don't trace stack during initialization of the runtime.
+ if (! gcj::runtimeInitialized)
+ return NULL;
+
+ _Jv_StackTrace *trace = _Jv_StackTrace::GetStackTrace ();
+ VMThrowable *vmthrowable = new VMThrowable ();
+ vmthrowable->data = (RawDataManaged *) trace;
+ return vmthrowable;
+}
+
+
+JArray< ::java::lang::StackTraceElement *> *
+java::lang::VMThrowable::getStackTrace (java::lang::Throwable *throwable)
+{
+ _Jv_StackTrace *trace = reinterpret_cast <_Jv_StackTrace *> (data);
+ return _Jv_StackTrace::GetStackTraceElements (trace, throwable);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/natWin32Process.cc b/gcc-4.2.1/libjava/java/lang/natWin32Process.cc
new file mode 100644
index 000000000..1ac3a2abd
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/natWin32Process.cc
@@ -0,0 +1,351 @@
+// natWin32Process.cc - Native side of Win32 process code.
+
+/* Copyright (C) 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+// Conflicts with the definition in "java/lang/reflect/Modifier.h"
+#undef STRICT
+
+#include <java/lang/ConcreteProcess.h>
+#include <java/lang/IllegalThreadStateException.h>
+#include <java/lang/InterruptedException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Thread.h>
+#include <java/io/File.h>
+#include <java/io/FileDescriptor.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <java/io/IOException.h>
+#include <java/lang/OutOfMemoryError.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+
+using gnu::java::nio::channels::FileChannelImpl;
+
+void
+java::lang::ConcreteProcess::cleanup (void)
+{
+ // FIXME:
+ // We used to close the input, output and
+ // error streams here, but we can't do that
+ // because the caller also has the right
+ // to close these and FileInputStream and FileOutputStream
+ // scream if you attempt to close() them twice. Presently,
+ // we use _Jv_platform_close_on_exec, which is similar
+ // to the POSIX approach.
+ //
+ // What I wanted to do is have private nested
+ // classes in ConcreteProcess which extend FileInputStream
+ // and FileOutputStream, respectively, but override
+ // close() to permit multiple calls to close(). This
+ // led to class header and platform configury issues
+ // that I didn't feel like dealing with. However,
+ // this approach could conceivably be a good multiplatform
+ // one since delaying the pipe close until process
+ // termination could be wasteful if many child processes
+ // are spawned within the parent process' lifetime.
+ inputStream = NULL;
+ outputStream = NULL;
+ errorStream = NULL;
+
+ if (procHandle)
+ {
+ CloseHandle((HANDLE) procHandle);
+ procHandle = (jint) INVALID_HANDLE_VALUE;
+ }
+}
+
+void
+java::lang::ConcreteProcess::destroy (void)
+{
+ if (! hasExited ())
+ {
+ // Kill it forcibly and assign an (arbitrary) exit code of 0.
+ TerminateProcess ((HANDLE) procHandle, 0);
+ exitCode = 0;
+
+ cleanup ();
+ }
+}
+
+jboolean
+java::lang::ConcreteProcess::hasExited (void)
+{
+ DWORD exitStatus;
+
+ if (GetExitCodeProcess ((HANDLE) procHandle, &exitStatus) != 0)
+ {
+ // NOTE: STILL_ACTIVE is defined as "259" by Win32 - if the
+ // child actually exits with this return code, we have a
+ // problem here. See MSDN documentation on GetExitCodeProcess( ).
+
+ if (exitStatus == STILL_ACTIVE)
+ return false;
+ else
+ {
+ cleanup ();
+ exitCode = exitStatus;
+ return true;
+ }
+ }
+ else
+ return true;
+}
+
+jint
+java::lang::ConcreteProcess::waitFor (void)
+{
+ if (! hasExited ())
+ {
+ DWORD exitStatus = 0UL;
+
+ // Set up our waitable objects array
+ // - 0: the handle to the process we just launched
+ // - 1: our thread's interrupt event
+ HANDLE arh[2];
+ arh[0] = (HANDLE) procHandle;
+ arh[1] = _Jv_Win32GetInterruptEvent ();
+ DWORD rval = WaitForMultipleObjects (2, arh, 0, INFINITE);
+
+ // Use the returned value from WaitForMultipleObjects
+ // instead of our thread's interrupt_flag to test for
+ // thread interruption. See the comment for
+ // _Jv_Win32GetInterruptEvent().
+ bool bInterrupted = rval == (WAIT_OBJECT_0 + 1);
+
+ if (bInterrupted)
+ {
+ // Querying this forces a reset our thread's interrupt flag.
+ Thread::interrupted();
+
+ cleanup ();
+ throw new InterruptedException ();
+ }
+
+ GetExitCodeProcess ((HANDLE) procHandle, &exitStatus);
+ exitCode = exitStatus;
+
+ cleanup ();
+ }
+
+ return exitCode;
+}
+
+
+// Helper class for creating and managing the pipes
+// used for I/O redirection for child processes.
+class ChildProcessPipe
+{
+public:
+ // Indicates from the child process' point of view
+ // whether the pipe is for reading or writing.
+ enum EType {INPUT, OUTPUT};
+
+ ChildProcessPipe(EType eType);
+ ~ChildProcessPipe();
+
+ // Returns a pipe handle suitable for use by the parent process
+ HANDLE getParentHandle();
+
+ // Returns a pipe handle suitable for use by the child process.
+ HANDLE getChildHandle();
+
+private:
+ EType m_eType;
+ HANDLE m_hRead, m_hWrite;
+};
+
+ChildProcessPipe::ChildProcessPipe(EType eType):
+ m_eType(eType)
+{
+ SECURITY_ATTRIBUTES sAttrs;
+
+ // Explicitly allow the handles to the pipes to be inherited.
+ sAttrs.nLength = sizeof (SECURITY_ATTRIBUTES);
+ sAttrs.bInheritHandle = 1;
+ sAttrs.lpSecurityDescriptor = NULL;
+
+ if (CreatePipe (&m_hRead, &m_hWrite, &sAttrs, 0) == 0)
+ {
+ DWORD dwErrorCode = GetLastError ();
+ throw new java::io::IOException (
+ _Jv_WinStrError (_T("Error creating pipe"), dwErrorCode));
+ }
+
+ // If this is the read end of the child, we need
+ // to make the parent write end non-inheritable. Similarly,
+ // if this is the write end of the child, we need to make
+ // the parent read end non-inheritable. If we didn't
+ // do this, the child would inherit these ends and we wouldn't
+ // be able to close them from our end. For full details,
+ // do a Google search on "Q190351".
+ HANDLE& rhStd = m_eType==INPUT ? m_hWrite : m_hRead;
+ _Jv_platform_close_on_exec (rhStd);
+}
+
+ChildProcessPipe::~ChildProcessPipe()
+{
+ // Close the parent end of the pipe. This
+ // destructor is called after the child process
+ // has been spawned.
+ CloseHandle(getChildHandle());
+}
+
+HANDLE ChildProcessPipe::getParentHandle()
+{
+ return m_eType==INPUT ? m_hWrite : m_hRead;
+}
+
+HANDLE ChildProcessPipe::getChildHandle()
+{
+ return m_eType==INPUT ? m_hRead : m_hWrite;
+}
+
+void
+java::lang::ConcreteProcess::startProcess (jstringArray progarray,
+ jstringArray envp,
+ java::io::File *dir)
+{
+ using namespace java::io;
+
+ procHandle = (jint) INVALID_HANDLE_VALUE;
+
+ // Reconstruct the command line.
+ jstring *elts = elements (progarray);
+
+ int cmdLineLen = 0;
+
+ for (int i = 0; i < progarray->length; ++i)
+ cmdLineLen += (elts[i]->length() + 1);
+
+ LPTSTR cmdLine = (LPTSTR) _Jv_Malloc ((cmdLineLen + 1) * sizeof(TCHAR));
+ LPTSTR cmdLineCurPos = cmdLine;
+
+ for (int i = 0; i < progarray->length; ++i)
+ {
+ if (i > 0)
+ *cmdLineCurPos++ = _T(' ');
+
+ jint len = elts[i]->length();
+ JV_TEMP_STRING_WIN32(thiselt, elts[i]);
+ _tcscpy(cmdLineCurPos, thiselt);
+ cmdLineCurPos += len;
+ }
+ *cmdLineCurPos = _T('\0');
+
+ // Get the environment, if any. Unconditionally
+ // create a UNICODE environment, even on ANSI
+ // builds.
+ LPWSTR env = NULL;
+ if (envp)
+ {
+ elts = elements (envp);
+
+ int envLen = 0;
+ for (int i = 0; i < envp->length; ++i)
+ envLen += (elts[i]->length() + 1);
+
+ env = (LPWSTR) _Jv_Malloc ((envLen + 1) * sizeof(WCHAR));
+
+ int j = 0;
+ for (int i = 0; i < envp->length; ++i)
+ {
+ jstring elt = elts[i];
+ jint len = elt->length();
+
+ wcsncpy(env + j, (LPCWSTR) JvGetStringChars(elt), len);
+
+ j += len;
+
+ // Insert the null terminator and skip past it.
+ env[j++] = 0;
+ }
+ *(env + j) = 0;
+ }
+
+ // Get the working directory path, if specified.
+ JV_TEMP_STRING_WIN32 (wdir, dir ? dir->getPath () : 0);
+
+ errorStream = NULL;
+ inputStream = NULL;
+ outputStream = NULL;
+
+ java::lang::Throwable *exc = NULL;
+
+ try
+ {
+ // We create anonymous pipes to communicate with the child
+ // on each of standard streams.
+ ChildProcessPipe aChildStdIn(ChildProcessPipe::INPUT);
+ ChildProcessPipe aChildStdOut(ChildProcessPipe::OUTPUT);
+ ChildProcessPipe aChildStdErr(ChildProcessPipe::OUTPUT);
+
+ outputStream = new FileOutputStream (new FileChannelImpl (
+ (jint) aChildStdIn.getParentHandle (),
+ FileChannelImpl::WRITE));
+ inputStream = new FileInputStream (new FileChannelImpl (
+ (jint) aChildStdOut.getParentHandle (),
+ FileChannelImpl::READ));
+ errorStream = new FileInputStream (new FileChannelImpl (
+ (jint) aChildStdErr.getParentHandle (),
+ FileChannelImpl::READ));
+
+ // Now create the child process.
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+
+ ZeroMemory (&pi, sizeof (PROCESS_INFORMATION));
+
+ ZeroMemory (&si, sizeof (STARTUPINFO));
+ si.cb = sizeof (STARTUPINFO);
+
+ // Explicitly specify the handles to the standard streams.
+ si.dwFlags |= STARTF_USESTDHANDLES;
+
+ si.hStdInput = aChildStdIn.getChildHandle();
+ si.hStdOutput = aChildStdOut.getChildHandle();
+ si.hStdError = aChildStdErr.getChildHandle();
+
+ // Spawn the process. CREATE_NO_WINDOW only applies when
+ // starting a console application; it suppresses the
+ // creation of a console window. This flag is ignored on
+ // Win9X.
+
+ if (CreateProcess (NULL,
+ cmdLine,
+ NULL,
+ NULL,
+ 1,
+ CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
+ env,
+ wdir,
+ &si,
+ &pi) == 0)
+ {
+ DWORD dwErrorCode = GetLastError ();
+ throw new IOException (
+ _Jv_WinStrError (_T("Error creating child process"), dwErrorCode));
+ }
+
+ procHandle = (jint ) pi.hProcess;
+
+ _Jv_Free (cmdLine);
+ if (env != NULL)
+ _Jv_Free (env);
+ }
+ catch (java::lang::Throwable *thrown)
+ {
+ cleanup ();
+ exc = thrown;
+ }
+
+ if (exc != NULL)
+ throw exc;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/ref/Reference.java b/gcc-4.2.1/libjava/java/lang/ref/Reference.java
new file mode 100644
index 000000000..ab0c55c84
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/ref/Reference.java
@@ -0,0 +1,210 @@
+/* java.lang.ref.Reference
+ Copyright (C) 1999, 2002, 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.lang.ref;
+
+/**
+ * This is the base class of all references. A reference allows
+ * refering to an object without preventing the garbage collector to
+ * collect it. The only way to get the referred object is via the
+ * <code>get()</code>-method. This method will return
+ * <code>null</code> if the object was collected. <br>
+ *
+ * A reference may be registered with a queue. When a referred
+ * element gets collected the reference will be put on the queue, so
+ * that you will be notified. <br>
+ *
+ * There are currently three types of references: soft reference,
+ * weak reference and phantom reference. <br>
+ *
+ * Soft references will be cleared if the garbage collector is told
+ * to free some memory and there are no unreferenced or weakly referenced
+ * objects. It is useful for caches. <br>
+ *
+ * Weak references will be cleared as soon as the garbage collector
+ * determines that the refered object is only weakly reachable. They
+ * are useful as keys in hashtables (see <code>WeakHashtable</code>) as
+ * you get notified when nobody has the key anymore.
+ *
+ * Phantom references don't prevent finalization. If an object is only
+ * phantom reachable, it will be finalized, and the reference will be
+ * enqueued, but not cleared. Since you mustn't access an finalized
+ * object, the <code>get</code> method of a phantom reference will never
+ * work. It is useful to keep track, when an object is finalized.
+ *
+ * @author Jochen Hoenicke
+ * @see java.util.WeakHashtable
+ */
+public abstract class Reference
+{
+ /**
+ * The underlying object. This field is handled in a special way by
+ * the garbage collector.
+ * GCJ LOCAL:
+ * This is a RawData because it must be disguised from the GC.
+ * END GCJ LOCAL
+ */
+ gnu.gcj.RawData referent;
+
+ /**
+ * This is like REFERENT but is not scanned by the GC. We keep a
+ * copy around so that we can clean up our internal data structure
+ * even after clear() is called.
+ * GCJ LOCAL:
+ * This field doesn't exist in Classpath.
+ * END GCJ LOCAL
+ */
+ gnu.gcj.RawData copy;
+
+ /**
+ * Set to true if {@link #clear()} is called.
+ * GCJ LOCAL:
+ * This field doesn't exist in Classpath. It is used internally in
+ * natReference.cc, which enqueues the reference unless it is true
+ * (has been cleared).
+ * END GCJ LOCAL
+ */
+ boolean cleared = false;
+
+ /**
+ * The queue this reference is registered on. This is null, if this
+ * wasn't registered to any queue or reference was already enqueued.
+ */
+ ReferenceQueue queue;
+
+ /**
+ * Link to the next entry on the queue. If this is null, this
+ * reference is not enqueued. Otherwise it points to the next
+ * reference. The last reference on a queue will point to itself
+ * (not to null, that value is used to mark a not enqueued
+ * reference).
+ */
+ Reference nextOnQueue;
+
+ /**
+ * This lock should be taken by the garbage collector, before
+ * determining reachability. It will prevent the get()-method to
+ * return the reference so that reachability doesn't change.
+ */
+ static Object lock = new Object();
+
+ /**
+ * Creates a new reference that is not registered to any queue.
+ * Since it is package private, it is not possible to overload this
+ * class in a different package.
+ * @param referent the object we refer to.
+ */
+ Reference(Object ref)
+ {
+ create (ref);
+ }
+
+ /**
+ * Creates a reference that is registered to a queue. Since this is
+ * package private, it is not possible to overload this class in a
+ * different package.
+ * @param referent the object we refer to.
+ * @param q the reference queue to register on.
+ * @exception NullPointerException if q is null.
+ */
+ Reference(Object ref, ReferenceQueue q)
+ {
+ if (q == null)
+ throw new NullPointerException();
+ queue = q;
+ create (ref);
+ }
+
+ /**
+ * Notifies the VM that a new Reference has been created.
+ */
+ private native void create (Object o);
+
+ /**
+ * Returns the object, this reference refers to.
+ * @return the object, this reference refers to, or null if the
+ * reference was cleared.
+ */
+ public Object get()
+ {
+ synchronized (lock)
+ {
+ return referent;
+ }
+ }
+
+ /**
+ * Clears the reference, so that it doesn't refer to its object
+ * anymore. For soft and weak references this is called by the
+ * garbage collector. For phantom references you should call
+ * this when enqueuing the reference.
+ */
+ public void clear()
+ {
+ // Must synchronize so changes are visible in finalizer thread.
+ synchronized (lock)
+ {
+ referent = null;
+ cleared = true;
+ }
+ }
+
+ /**
+ * Tells if the object is enqueued on a reference queue.
+ * @return true if it is enqueued, false otherwise.
+ */
+ public boolean isEnqueued()
+ {
+ return nextOnQueue != null;
+ }
+
+ /**
+ * Enqueue an object on a reference queue. This is normally executed
+ * by the garbage collector.
+ */
+ public boolean enqueue()
+ {
+ if (queue != null && nextOnQueue == null)
+ {
+ queue.enqueue(this);
+ queue = null;
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/ref/natReference.cc b/gcc-4.2.1/libjava/java/lang/ref/natReference.cc
new file mode 100644
index 000000000..23f435f4d
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/ref/natReference.cc
@@ -0,0 +1,370 @@
+// natReference.cc - Native code for References
+
+/* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/lang/Throwable.h>
+#include <java/lang/ref/Reference.h>
+#include <java/lang/ref/SoftReference.h>
+#include <java/lang/ref/WeakReference.h>
+#include <java/lang/ref/PhantomReference.h>
+#include <java/lang/ref/ReferenceQueue.h>
+
+static void finalize_reference (jobject ref);
+static void finalize_referred_to_object (jobject obj);
+
+
+
+enum weight
+{
+ SOFT = 0,
+ WEAK = 1,
+ FINALIZE = 2,
+ PHANTOM = 3,
+
+ // This is used to mark the head of a list.
+ HEAD = 4,
+
+ // This is used to mark a deleted item.
+ DELETED = 5
+};
+
+// Objects of this type are used in the hash table to keep track of
+// the mapping between a finalizable object and the various References
+// which refer to it.
+struct object_list
+{
+ // The reference object. This is NULL for FINALIZE weight.
+ jobject reference;
+
+ // The weight of this object.
+ enum weight weight;
+
+ // Next in list.
+ object_list *next;
+};
+
+// Hash table used to hold mapping from object to References. The
+// object_list item in the hash holds the object itself in the
+// reference field; chained to it are all the references sorted in
+// order of weight (lowest first).
+static object_list *hash = NULL;
+
+// Number of slots used in HASH.
+static int hash_count = 0;
+
+// Number of slots total in HASH. Must be power of 2.
+static int hash_size = 0;
+
+#define DELETED_REFERENCE ((jobject) -1)
+
+static object_list *
+find_slot (jobject key)
+{
+ jint hcode = _Jv_HashCode (key);
+ /* step must be non-zero, and relatively prime with hash_size. */
+ jint step = (hcode ^ (hcode >> 16)) | 1;
+ int start_index = hcode & (hash_size - 1);
+ int index = start_index;
+ int deleted_index = -1;
+ do
+ {
+ object_list *ptr = &hash[index];
+ if (ptr->reference == key)
+ return ptr;
+ else if (ptr->reference == NULL)
+ {
+ if (deleted_index == -1)
+ return ptr;
+ else
+ return &hash[deleted_index];
+ }
+ else if (ptr->weight == DELETED)
+ {
+ deleted_index = index;
+ JvAssert (ptr->reference == DELETED_REFERENCE);
+ }
+ index = (index + step) & (hash_size - 1);
+ }
+ while (index != start_index);
+ // Note that we can have INDEX == START_INDEX if the table has no
+ // NULL entries but does have DELETED entries.
+ JvAssert (deleted_index >= 0);
+ return &hash[deleted_index];
+}
+
+static void
+rehash ()
+{
+ if (hash == NULL)
+ {
+ hash_size = 1024;
+ hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
+ memset (hash, 0, hash_size * sizeof (object_list));
+ }
+ else
+ {
+ object_list *old = hash;
+ int i = hash_size;
+
+ hash_size *= 2;
+ hash = (object_list *) _Jv_Malloc (hash_size * sizeof (object_list));
+ memset (hash, 0, hash_size * sizeof (object_list));
+
+ while (--i >= 0)
+ {
+ if (old[i].reference == NULL || old[i].weight == DELETED)
+ continue;
+ object_list *newslot = find_slot (old[i].reference);
+ *newslot = old[i];
+ }
+
+ _Jv_Free (old);
+ }
+}
+
+// Remove a Reference.
+static void
+remove_from_hash (jobject obj)
+{
+ java::lang::ref::Reference *ref
+ = reinterpret_cast<java::lang::ref::Reference *> (obj);
+ object_list *head = find_slot (ref->copy);
+
+ // We might have found a new slot. We can just ignore that here.
+ if (head->reference != ref->copy)
+ return;
+
+ object_list **link = &head->next;
+ head = head->next;
+
+ while (head && head->reference != ref)
+ {
+ link = &head->next;
+ head = head->next;
+ }
+
+ // Remove the slot.
+ if (head)
+ {
+ *link = head->next;
+ _Jv_Free (head);
+ }
+}
+
+// Return list head if object is in hash, NULL otherwise.
+object_list *
+in_hash (jobject obj)
+{
+ // The hash table might not yet be initialized.
+ if (hash == NULL)
+ return NULL;
+ object_list *head = find_slot (obj);
+ if (head->reference != obj)
+ return NULL;
+ return head;
+}
+
+// FIXME what happens if an object's finalizer creates a Reference to
+// the object, and the object has never before been added to the hash?
+// Madness!
+
+// Add an item to the hash table. If the item is new, we also add a
+// finalizer item. We keep items in the hash table until they are
+// completely collected; this lets us know when an item is new, even
+// if it has been resurrected after its finalizer has been run.
+static void
+add_to_hash (java::lang::ref::Reference *the_reference)
+{
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+
+ if (3 * hash_count >= 2 * hash_size)
+ rehash ();
+
+ // Use `copy' here because the `referent' field has been cleared.
+ jobject referent = the_reference->copy;
+ object_list *item = find_slot (referent);
+ if (item->reference == NULL || item->reference == DELETED_REFERENCE)
+ {
+ // New item, so make an entry for the finalizer.
+ item->reference = referent;
+ item->weight = HEAD;
+
+ item->next = (object_list *) _Jv_Malloc (sizeof (object_list));
+ item->next->reference = NULL;
+ item->next->weight = FINALIZE;
+ item->next->next = NULL;
+ ++hash_count;
+ }
+
+ object_list *n = (object_list *) _Jv_Malloc (sizeof (object_list));
+ n->reference = the_reference;
+
+ enum weight w = PHANTOM;
+ if (java::lang::ref::SoftReference::class$.isInstance (the_reference))
+ w = SOFT;
+ else if (java::lang::ref::WeakReference::class$.isInstance (the_reference))
+ w = WEAK;
+ n->weight = w;
+
+ object_list **link = &item->next;
+ object_list *iter = *link;
+ while (iter && iter->weight < n->weight)
+ {
+ link = &iter->next;
+ iter = *link;
+ }
+ n->next = *link;
+ *link = n;
+}
+
+// Add a FINALIZE entry if one doesn't exist.
+static void
+maybe_add_finalize (object_list *entry, jobject obj)
+{
+ object_list **link = &entry->next;
+ object_list *iter = *link;
+ while (iter && iter->weight < FINALIZE)
+ {
+ link = &iter->next;
+ iter = *link;
+ }
+
+ // We want at most one FINALIZE entry in the queue.
+ if (iter && iter->weight == FINALIZE)
+ return;
+
+ object_list *n = (object_list *) _Jv_Malloc (sizeof (object_list));
+ n->reference = obj;
+ n->weight = FINALIZE;
+ n->next = *link;
+ *link = n;
+}
+
+// This is called when an object is ready to be finalized. This
+// actually implements the appropriate Reference semantics.
+static void
+finalize_referred_to_object (jobject obj)
+{
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+
+ object_list *list = find_slot (obj);
+ object_list *head = list->next;
+ if (head == NULL)
+ {
+ // We have a truly dead object: the object's finalizer has been
+ // run, all the object's references have been processed, and the
+ // object is unreachable. There is, at long last, no way to
+ // resurrect it.
+ list->reference = DELETED_REFERENCE;
+ list->weight = DELETED;
+ --hash_count;
+ return;
+ }
+
+ enum weight w = head->weight;
+ if (w == FINALIZE)
+ {
+ // Update the list first, as _Jv_FinalizeString might end up
+ // looking at this data structure.
+ list->next = head->next;
+ _Jv_Free (head);
+
+ // If we have a Reference A to a Reference B, and B is
+ // finalized, then we have to take special care to make sure
+ // that B is properly deregistered. This is super gross. FIXME
+ // will it fail if B's finalizer resurrects B?
+ if (java::lang::ref::Reference::class$.isInstance (obj))
+ finalize_reference (obj);
+ else if (obj->getClass() == &java::lang::String::class$)
+ _Jv_FinalizeString (obj);
+ else
+ _Jv_FinalizeObject (obj);
+ }
+ else if (w != SOFT || _Jv_GCCanReclaimSoftReference (obj))
+ {
+ // If we just decided to reclaim a soft reference, we might as
+ // well do all the weak references at the same time.
+ if (w == SOFT)
+ w = WEAK;
+
+ while (head && head->weight <= w)
+ {
+ java::lang::ref::Reference *ref
+ = reinterpret_cast<java::lang::ref::Reference *> (head->reference);
+ if (! ref->cleared)
+ ref->enqueue ();
+
+ object_list *next = head->next;
+ _Jv_Free (head);
+ head = next;
+ }
+ list->next = head;
+ }
+
+ // Re-register this finalizer. We always re-register because we
+ // can't know until the next collection cycle whether or not the
+ // object is truly unreachable.
+ _Jv_RegisterFinalizer (obj, finalize_referred_to_object);
+}
+
+// This is called when a Reference object is finalized. If there is a
+// Reference pointing to this Reference then that case is handled by
+// finalize_referred_to_object.
+static void
+finalize_reference (jobject ref)
+{
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+ remove_from_hash (ref);
+ // The user might have a subclass of Reference with a finalizer.
+ _Jv_FinalizeObject (ref);
+}
+
+void
+_Jv_RegisterStringFinalizer (jobject str)
+{
+ // This function might be called before any other Reference method,
+ // so we must ensure the class is initialized.
+ _Jv_InitClass (&java::lang::ref::Reference::class$);
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+ // If the object is in our hash table, then we might need to add a
+ // new FINALIZE entry. Otherwise, we just register an ordinary
+ // finalizer.
+ object_list *entry = in_hash (str);
+ if (entry)
+ maybe_add_finalize (entry, str);
+ else
+ _Jv_RegisterFinalizer ((void *) str, _Jv_FinalizeString);
+}
+
+void
+::java::lang::ref::Reference::create (jobject ref)
+{
+ // Nothing says you can't make a Reference with a NULL referent.
+ // But there's nothing to do in such a case.
+ referent = reinterpret_cast<gnu::gcj::RawData *> (ref);
+ copy = referent;
+ if (referent != NULL)
+ {
+ JvSynchronize sync (java::lang::ref::Reference::lock);
+ // `this' is a new Reference object. We register a new
+ // finalizer for pointed-to object and we arrange a special
+ // finalizer for ourselves as well.
+ _Jv_RegisterFinalizer (this, finalize_reference);
+ _Jv_RegisterFinalizer (referent, finalize_referred_to_object);
+ gnu::gcj::RawData **p = &referent;
+ _Jv_GCRegisterDisappearingLink ((jobject *) p);
+ add_to_hash (this);
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/Array.java b/gcc-4.2.1/libjava/java/lang/reflect/Array.java
new file mode 100644
index 000000000..32bed06ee
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/Array.java
@@ -0,0 +1,458 @@
+/* java.lang.reflect.Array - manipulate arrays by reflection
+ Copyright (C) 1998, 1999, 2001, 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.lang.reflect;
+
+import gnu.classpath.Configuration;
+
+/**
+ * Array holds static helper functions that allow you to create and
+ * manipulate arrays by reflection. Operations know how to perform widening
+ * conversions, but throw {@link IllegalArgumentException} if you attempt
+ * a narrowing conversion. Also, when accessing primitive arrays, this
+ * class performs object wrapping and unwrapping as necessary.<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. Note also that the shorthand <code>Object[].class</code>
+ * is a convenient way to get array Classes.<p>
+ *
+ * <B>Performance note:</B> This class performs best when it does not have
+ * to convert primitive types. The further along the chain it has to convert,
+ * the worse performance will be. You're best off using the array as whatever
+ * type it already is, and then converting the result. You will do even
+ * worse if you do this and use the generic set() function.
+ *
+ * @author John Keiser
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Per Bothner (bothner@cygnus.com)
+ * @see java.lang.Boolean#TYPE
+ * @see java.lang.Byte#TYPE
+ * @see java.lang.Short#TYPE
+ * @see java.lang.Character#TYPE
+ * @see java.lang.Integer#TYPE
+ * @see java.lang.Long#TYPE
+ * @see java.lang.Float#TYPE
+ * @see java.lang.Double#TYPE
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Array
+{
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("javalangreflect");
+ }
+ }
+
+ /**
+ * This class is uninstantiable.
+ */
+ private Array()
+ {
+ }
+
+ /**
+ * Creates a new single-dimensioned array.
+ * @param componentType the type of the array to create
+ * @param length the length of the array to create
+ * @return the created array, cast to an Object
+ * @throws NullPointerException if <code>componentType</code> is null
+ * @throws IllegalArgumentException if <code>componentType</code> is
+ * <code>Void.TYPE</code>
+ * @throws NegativeArraySizeException when length is less than 0
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ public static native Object newInstance(Class componentType, int length);
+
+ /**
+ * Creates a new multi-dimensioned array. The new array has the same
+ * component type as the argument class, and the number of dimensions
+ * in the new array is the sum of the dimensions of the argument class
+ * and the length of the argument dimensions. Virtual Machine limitations
+ * forbid too many dimensions (usually 255 is the maximum); but even
+ * 50 dimensions of 2 elements in each dimension would exceed your memory
+ * long beforehand!
+ *
+ * @param componentType the type of the array to create.
+ * @param dimensions the dimensions of the array to create. Each element
+ * in <code>dimensions</code> makes another dimension of the new
+ * array. Thus, <code>Array.newInstance(java.lang.Boolean,
+ * new int[]{1,2,3})</code> is the same as
+ * <code>new java.lang.Boolean[1][2][3]</code>
+ * @return the created array, cast to an Object
+ * @throws NullPointerException if componentType or dimension is null
+ * @throws IllegalArgumentException if the the size of
+ * <code>dimensions</code> is 0 or exceeds the maximum number of
+ * array dimensions in the VM; or if componentType is Void.TYPE
+ * @throws NegativeArraySizeException when any of the dimensions is less
+ * than 0
+ * @throws OutOfMemoryError if memory allocation fails
+ */
+ public static native Object newInstance(Class elementType, int[] dimensions);
+
+ /**
+ * Gets the array length.
+ * @param array the array
+ * @return the length of the array
+ * @throws IllegalArgumentException if <code>array</code> is not an array
+ * @throws NullPointerException if <code>array</code> is null
+ */
+ public static native int getLength(Object array);
+
+ /**
+ * Gets an element of an array. Primitive elements will be wrapped in
+ * the corresponding class type.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not an array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #getBoolean(Object, int)
+ * @see #getByte(Object, int)
+ * @see #getChar(Object, int)
+ * @see #getShort(Object, int)
+ * @see #getInt(Object, int)
+ * @see #getLong(Object, int)
+ * @see #getFloat(Object, int)
+ * @see #getDouble(Object, int)
+ */
+ public static native Object get(Object array, int index);
+
+ /**
+ * Gets an element of a boolean array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the boolean element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a boolean
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native boolean getBoolean(Object array, int index);
+
+ /**
+ * Gets an element of a byte array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the byte element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native byte getByte(Object array, int index);
+
+ /**
+ * Gets an element of a char array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the char element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a char
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native char getChar(Object array, int index);
+
+ /**
+ * Gets an element of a short array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the short element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte
+ * or char array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native short getShort(Object array, int index);
+
+ /**
+ * Gets an element of an int array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the int element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, or int array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native int getInt(Object array, int index);
+
+ /**
+ * Gets an element of a long array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the long element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, or long array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native long getLong(Object array, int index);
+
+ /**
+ * Gets an element of a float array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the float element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, long, or float array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native float getFloat(Object array, int index);
+
+ /**
+ * Gets an element of a double array.
+ *
+ * @param array the array to access
+ * @param index the array index to access
+ * @return the double element at <code>array[index]</code>
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * char, short, int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #get(Object, int)
+ */
+ public static native double getDouble(Object array, int index);
+
+ private static native Class getElementType(Object array, int index);
+
+ private static native void set(Object array, int index,
+ Object value, Class elType);
+
+ /**
+ * Sets an element of an array. If the array is primitive, then the new
+ * value is unwrapped and widened.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not an array,
+ * or the array is primitive and unwrapping value fails, or the
+ * value is not assignable to the array component type
+ * @throws NullPointerException if array is null, or if array is primitive
+ * and value is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #setBoolean(Object, int, boolean)
+ * @see #setByte(Object, int, byte)
+ * @see #setChar(Object, int, char)
+ * @see #setShort(Object, int, short)
+ * @see #setInt(Object, int, int)
+ * @see #setLong(Object, int, long)
+ * @see #setFloat(Object, int, float)
+ * @see #setDouble(Object, int, double)
+ */
+ public static void set(Object array, int index, Object value)
+ {
+ Class elType = getElementType(array, index);
+ if (! elType.isPrimitive())
+ set(array, index, value, elType);
+ else if (value instanceof Byte)
+ setByte(array, index, ((Byte) value).byteValue());
+ else if (value instanceof Short)
+ setShort(array, index, ((Short) value).shortValue());
+ else if (value instanceof Integer)
+ setInt(array, index, ((Integer) value).intValue());
+ else if (value instanceof Long)
+ setLong(array, index, ((Long) value).longValue());
+ else if (value instanceof Float)
+ setFloat(array, index, ((Float) value).floatValue());
+ else if (value instanceof Double)
+ setDouble(array, index, ((Double) value).doubleValue());
+ else if (value instanceof Character)
+ setChar(array, index, ((Character) value).charValue());
+ else if (value instanceof Boolean)
+ setBoolean(array, index, ((Boolean) value).booleanValue());
+ else
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Sets an element of a boolean array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a boolean
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setBoolean(Object array, int index, boolean value);
+
+ /**
+ * Sets an element of a byte array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a byte,
+ * short, int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setByte(Object array, int index, byte value);
+
+ /**
+ * Sets an element of a char array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a char,
+ * int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setChar(Object array, int index, char value);
+
+ /**
+ * Sets an element of a short array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a short,
+ * int, long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setShort(Object array, int index, short value);
+
+ /**
+ * Sets an element of an int array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not an int,
+ * long, float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setInt(Object array, int index, int value);
+
+ /**
+ * Sets an element of a long array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a long,
+ * float, or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setLong(Object array, int index, long value);
+
+ /**
+ * Sets an element of a float array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a float
+ * or double array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setFloat(Object array, int index, float value);
+
+ /**
+ * Sets an element of a double array.
+ *
+ * @param array the array to set a value of
+ * @param index the array index to set the value to
+ * @param value the value to set
+ * @throws IllegalArgumentException if <code>array</code> is not a double
+ * array
+ * @throws NullPointerException if <code>array</code> is null
+ * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
+ * bounds
+ * @see #set(Object, int, Object)
+ */
+ public static native void setDouble(Object array, int index, double value);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/Constructor.java b/gcc-4.2.1/libjava/java/lang/reflect/Constructor.java
new file mode 100644
index 000000000..68b2d3985
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/Constructor.java
@@ -0,0 +1,398 @@
+/* java.lang.reflect.Constructor - reflection of Java constructors
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
+ 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 gnu.java.lang.reflect.MethodSignatureParser;
+
+/**
+ * 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>
+ * @author Tom Tromey <tromey@redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getConstructor(Class[])
+ * @see java.lang.Class#getDeclaredConstructor(Class[])
+ * @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, GenericDeclaration
+{
+ private static final int CONSTRUCTOR_MODIFIERS
+ = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
+
+ /**
+ * This class is uninstantiable except from native code.
+ */
+ private Constructor ()
+ {
+ }
+
+ /**
+ * Gets the class that declared this constructor.
+ * @return the class that declared this member
+ */
+ public Class getDeclaringClass()
+ {
+ return declaringClass;
+ }
+
+ /**
+ * 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 declaringClass.getName();
+ }
+
+ /**
+ * Return the raw modifiers for this constructor. In particular
+ * this will include the synthetic and varargs bits.
+ * @return the constructor's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * 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 int getModifiers ()
+ {
+ return getModifiersInternal() & CONSTRUCTOR_MODIFIERS;
+ }
+
+ /**
+ * Return true if this constructor is synthetic, false otherwise.
+ * A synthetic member is one which is created by the compiler,
+ * and which does not appear in the user's source code.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs constructor, that is if
+ * the constructor takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * 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 Class[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType ();
+ return (Class[]) parameter_types.clone();
+ }
+
+ /**
+ * 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 Class[] getExceptionTypes ()
+ {
+ if (exception_types == null)
+ getType();
+ return (Class[]) exception_types.clone();
+ }
+
+ /**
+ * 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.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not.
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Constructor))
+ return false;
+ Constructor c = (Constructor) obj;
+ return declaringClass == c.declaringClass && offset == c.offset;
+ }
+
+ /**
+ * 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 declaringClass.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()
+ {
+ if (parameter_types == null)
+ getType ();
+ StringBuffer b = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, b);
+ b.append(" ");
+ }
+ Method.appendClassName (b, declaringClass);
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ Method.appendClassName (b, parameter_types[i]);
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ return b.toString();
+ }
+
+ /* FIXME[GENERICS]: Add X extends GenericDeclaration and TypeVariable<X> */
+ static void addTypeParameters(StringBuilder sb, TypeVariable[] typeArgs)
+ {
+ if (typeArgs.length == 0)
+ return;
+ sb.append('<');
+ for (int i = 0; i < typeArgs.length; ++i)
+ {
+ if (i > 0)
+ sb.append(',');
+ sb.append(typeArgs[i]);
+ }
+ sb.append("> ");
+ }
+
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ addTypeParameters(sb, getTypeParameters());
+ sb.append(getDeclaringClass().getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; ++i)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ 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 native Object newInstance (Object[] args)
+ throws InstantiationException, IllegalAccessException,
+ IllegalArgumentException, InvocationTargetException;
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor has no type
+ * variables.
+ *
+ * @return the type variables associated with this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Add <Constructor<T>> */
+ public TypeVariable[] getTypeParameters()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this constructor. If there
+ * is no Signature attribute, return null.
+ */
+ private String getSignature()
+ {
+ // FIXME: libgcj doesn't record this information yet.
+ return null;
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this constructor, in declaration order.
+ * An array of size zero is returned if this constructor declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this constructor.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this constructor, in declaration order.
+ * An array of size zero is returned if this constructor takes no
+ * parameters.
+ *
+ * @return a list of the types of the constructor's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericParameterTypes();
+ }
+
+ // Update cached values from method descriptor in class.
+ private native void getType ();
+
+ // Declaring class.
+ private Class declaringClass;
+
+ // Exception types.
+ private Class[] exception_types;
+ // Parameter types.
+ private Class[] parameter_types;
+
+ // Offset in bytes from the start of declaringClass's methods array.
+ private int offset;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/Field.java b/gcc-4.2.1/libjava/java/lang/reflect/Field.java
new file mode 100644
index 000000000..134ff132e
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/Field.java
@@ -0,0 +1,801 @@
+/* java.lang.reflect.Field - reflection of Java fields
+ Copyright (C) 1998, 2001, 2005, 2006 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 gnu.java.lang.ClassHelper;
+
+import gnu.java.lang.reflect.FieldSignatureParser;
+
+/**
+ * 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>
+ * @author Per Bothner <bothner@cygnus.com>
+ * @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;
+
+ // Offset in bytes from the start of declaringClass's fields array.
+ private int offset;
+
+ // The Class (or primitive TYPE) of this field.
+ private Class type;
+
+ private static final int FIELD_MODIFIERS
+ = Modifier.FINAL | Modifier.PRIVATE | Modifier.PROTECTED
+ | Modifier.PUBLIC | Modifier.STATIC | Modifier.TRANSIENT
+ | Modifier.VOLATILE;
+
+ // This is instantiated by Class sometimes, but it uses C++ and
+ // avoids the Java protection check.
+ Field ()
+ {
+ }
+
+ /**
+ * 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 native String getName();
+
+ /**
+ * Return the raw modifiers for this field.
+ * @return the field's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * 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 int getModifiers()
+ {
+ return getModifiersInternal() & FIELD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this field is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this field represents an enum constant,
+ * false otherwise.
+ * @since 1.5
+ */
+ public boolean isEnumConstant()
+ {
+ return (getModifiersInternal() & Modifier.ENUM) != 0;
+ }
+
+ /**
+ * 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 fld)
+ {
+ if (! (fld instanceof Field))
+ return false;
+ Field f = (Field) fld;
+ return declaringClass == f.declaringClass && offset == f.offset;
+ }
+
+ /**
+ * 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 ()
+ {
+ StringBuffer sbuf = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, sbuf);
+ sbuf.append(' ');
+ }
+ Method.appendClassName (sbuf, getType ());
+ sbuf.append(' ');
+ Method.appendClassName (sbuf, getDeclaringClass());
+ sbuf.append('.');
+ sbuf.append(getName());
+ return sbuf.toString();
+ }
+
+ public String toGenericString()
+ {
+ StringBuilder sb = new StringBuilder(64);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ sb.append(getGenericType()).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 Object get(Object obj)
+ throws IllegalAccessException
+ {
+ return get(null, obj);
+ }
+
+ /**
+ * 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 boolean getBoolean(Object obj)
+ throws IllegalAccessException
+ {
+ return getBoolean(null, obj);
+ }
+
+ /**
+ * 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 byte getByte(Object obj)
+ throws IllegalAccessException
+ {
+ return getByte(null, obj);
+ }
+
+ /**
+ * 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 char getChar(Object obj)
+ throws IllegalAccessException
+ {
+ return getChar(null, obj);
+ }
+
+ /**
+ * 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 short getShort(Object obj)
+ throws IllegalAccessException
+ {
+ return getShort(null, obj);
+ }
+
+ /**
+ * 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 int getInt(Object obj)
+ throws IllegalAccessException
+ {
+ return getInt(null, obj);
+ }
+
+ /**
+ * 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 long getLong(Object obj)
+ throws IllegalAccessException
+ {
+ return getLong(null, obj);
+ }
+
+ /**
+ * 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 float getFloat(Object obj)
+ throws IllegalAccessException
+ {
+ return getFloat(null, obj);
+ }
+
+ /**
+ * 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 double getDouble(Object obj)
+ throws IllegalAccessException
+ {
+ return getDouble(null, obj);
+ }
+
+ private native boolean getBoolean (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native char getChar (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native byte getByte (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native short getShort (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native int getInt (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native long getLong (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native float getFloat (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native double getDouble (Class caller, Object obj)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private native Object get (Class caller, Object obj)
+ throws IllegalArgumentException, 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 void set(Object object, Object value)
+ throws IllegalAccessException
+ {
+ set(null, object, value);
+ }
+
+ /**
+ * 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 void setBoolean(Object obj, boolean b)
+ throws IllegalAccessException
+ {
+ setBoolean(null, obj, b, true);
+ }
+
+ /**
+ * 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 void setByte(Object obj, byte b)
+ throws IllegalAccessException
+ {
+ setByte(null, obj, b, true);
+ }
+
+ /**
+ * 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 void setChar(Object obj, char c)
+ throws IllegalAccessException
+ {
+ setChar(null, obj, c, true);
+ }
+
+ /**
+ * 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 void setShort(Object obj, short s)
+ throws IllegalAccessException
+ {
+ setShort(null, obj, s, true);
+ }
+
+ /**
+ * 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 void setInt(Object obj, int i)
+ throws IllegalAccessException
+ {
+ setInt(null, obj, i, true);
+ }
+
+ /**
+ * 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 void setLong(Object obj, long l)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ setLong(null, obj, l, true);
+ }
+
+ /**
+ * 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 void setFloat(Object obj, float f)
+ throws IllegalAccessException
+ {
+ setFloat(null, obj, f, true);
+ }
+
+ /**
+ * 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 void setDouble(Object obj, double d)
+ throws IllegalAccessException
+ {
+ setDouble(null, obj, d, true);
+ }
+
+ /**
+ * Return the generic type of the field. If the field type is not a generic
+ * type, the method returns the same as <code>getType()</code>.
+ *
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericType()
+ {
+ String signature = getSignature();
+ if (signature == null)
+ return getType();
+ FieldSignatureParser p = new FieldSignatureParser(getDeclaringClass(),
+ signature);
+ return p.getFieldType();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this field. If there
+ * is no Signature attribute, return null.
+ */
+ private String getSignature()
+ {
+ // FIXME: libgcj doesn't record Signature attributes yet.
+ return null;
+ }
+
+ native void setByte (Class caller, Object obj, byte b, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setShort (Class caller, Object obj, short s, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setInt (Class caller, Object obj, int i, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setLong (Class caller, Object obj, long l, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setFloat (Class caller, Object obj, float f, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setDouble (Class caller, Object obj, double d,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setChar (Class caller, Object obj, char c, boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void setBoolean (Class caller, Object obj, boolean b,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ native void set (Class caller, Object obj, Object val, Class type,
+ boolean checkFinal)
+ throws IllegalArgumentException, IllegalAccessException;
+
+ private void set (Class caller, Object object, Object value)
+ throws IllegalArgumentException, IllegalAccessException
+ {
+ Class type = getType();
+ if (! type.isPrimitive())
+ set(caller, object, value, type, true);
+ else if (value instanceof Byte)
+ setByte(caller, object, ((Byte) value).byteValue(), true);
+ else if (value instanceof Short)
+ setShort (caller, object, ((Short) value).shortValue(), true);
+ else if (value instanceof Integer)
+ setInt(caller, object, ((Integer) value).intValue(), true);
+ else if (value instanceof Long)
+ setLong(caller, object, ((Long) value).longValue(), true);
+ else if (value instanceof Float)
+ setFloat(caller, object, ((Float) value).floatValue(), true);
+ else if (value instanceof Double)
+ setDouble(caller, object, ((Double) value).doubleValue(), true);
+ else if (value instanceof Character)
+ setChar(caller, object, ((Character) value).charValue(), true);
+ else if (value instanceof Boolean)
+ setBoolean(caller, object, ((Boolean) value).booleanValue(), true);
+ else
+ throw new IllegalArgumentException();
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/Method.java b/gcc-4.2.1/libjava/java/lang/reflect/Method.java
new file mode 100644
index 000000000..3142d6494
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/Method.java
@@ -0,0 +1,444 @@
+// Method.java - Represent method of class or interface.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package java.lang.reflect;
+
+import gnu.gcj.RawData;
+import gnu.java.lang.reflect.MethodSignatureParser;
+
+/**
+ * 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>
+ * @author Tom Tromey <tromey@redhat.com>
+ * @see Member
+ * @see Class
+ * @see java.lang.Class#getMethod(String,Class[])
+ * @see java.lang.Class#getDeclaredMethod(String,Class[])
+ * @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, GenericDeclaration
+{
+ private static final int METHOD_MODIFIERS
+ = Modifier.ABSTRACT | Modifier.FINAL | Modifier.NATIVE
+ | Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC
+ | Modifier.STATIC | Modifier.STRICT | Modifier.SYNCHRONIZED;
+
+ /**
+ * This class is uninstantiable.
+ */
+ private Method ()
+ {
+ }
+
+ /**
+ * 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 native String getName ();
+
+ /**
+ * Return the raw modifiers for this method.
+ * @return the method's modifiers
+ */
+ private native int getModifiersInternal();
+
+ /**
+ * 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 int getModifiers()
+ {
+ return getModifiersInternal() & METHOD_MODIFIERS;
+ }
+
+ /**
+ * Return true if this method is a bridge method. A bridge method
+ * is generated by the compiler in some situations involving
+ * generics and inheritance.
+ * @since 1.5
+ */
+ public boolean isBridge()
+ {
+ return (getModifiersInternal() & Modifier.BRIDGE) != 0;
+ }
+
+ /**
+ * Return true if this method is synthetic, false otherwise.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return (getModifiersInternal() & Modifier.SYNTHETIC) != 0;
+ }
+
+ /**
+ * Return true if this is a varargs method, that is if
+ * the method takes a variable number of arguments.
+ * @since 1.5
+ */
+ public boolean isVarArgs()
+ {
+ return (getModifiersInternal() & Modifier.VARARGS) != 0;
+ }
+
+ /**
+ * Gets the return type of this method.
+ * @return the type of this method
+ */
+ public Class getReturnType ()
+ {
+ if (return_type == null)
+ getType();
+ return return_type;
+ }
+
+ /**
+ * 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 Class[] getParameterTypes ()
+ {
+ if (parameter_types == null)
+ getType();
+ return (Class[]) parameter_types.clone();
+ }
+
+ /**
+ * 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 Class[] getExceptionTypes ()
+ {
+ if (exception_types == null)
+ getType();
+ return (Class[]) exception_types.clone();
+ }
+
+ /**
+ * Compare two objects to see if they are semantically equivalent.
+ * Two Methods are semantically equivalent if they have the same declaring
+ * class, name, and parameter list. This ignores different exception
+ * clauses or return types.
+ *
+ * @param o the object to compare to
+ * @return <code>true</code> if they are equal; <code>false</code> if not
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Method))
+ return false;
+ Method m = (Method) obj;
+ return declaringClass == m.declaringClass && offset == m.offset;
+ }
+
+ /**
+ * 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()
+ {
+ if (parameter_types == null)
+ getType ();
+
+ StringBuffer b = new StringBuffer ();
+ int mods = getModifiers();
+ if (mods != 0)
+ {
+ Modifier.toString(mods, b);
+ b.append(" ");
+ }
+ appendClassName (b, return_type);
+ b.append(" ");
+ appendClassName (b, declaringClass);
+ b.append(".");
+ b.append(getName());
+ b.append("(");
+ for (int i = 0; i < parameter_types.length; ++i)
+ {
+ appendClassName (b, parameter_types[i]);
+ if (i < parameter_types.length - 1)
+ b.append(",");
+ }
+ b.append(")");
+ if (exception_types.length > 0)
+ {
+ b.append(" throws ");
+ for (int i = 0; i < exception_types.length; ++i)
+ {
+ appendClassName (b, exception_types[i]);
+ if (i < exception_types.length - 1)
+ b.append(",");
+ }
+ }
+ return b.toString();
+ }
+
+ public String toGenericString()
+ {
+ // 128 is a reasonable buffer initial size for constructor
+ StringBuilder sb = new StringBuilder(128);
+ Modifier.toString(getModifiers(), sb).append(' ');
+ Constructor.addTypeParameters(sb, getTypeParameters());
+ sb.append(getGenericReturnType()).append(' ');
+ sb.append(getDeclaringClass().getName()).append('.');
+ sb.append(getName()).append('(');
+ Type[] types = getGenericParameterTypes();
+ if (types.length > 0)
+ {
+ sb.append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ sb.append(')');
+ types = getGenericExceptionTypes();
+ if (types.length > 0)
+ {
+ sb.append(" throws ").append(types[0]);
+ for (int i = 1; i < types.length; i++)
+ sb.append(',').append(types[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 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 native Object invoke (Object obj, Object[] args)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException;
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this constructor, in declaration order.
+ * An array of size zero is returned if this class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should be TypeVariable<Method>[] */
+ public TypeVariable[] getTypeParameters()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return new TypeVariable[0];
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Return the String in the Signature attribute for this method. If there
+ * is no Signature attribute, return null.
+ */
+ private String getSignature()
+ {
+ // FIXME: libgcj doesn't record this information yet.
+ return null;
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the exception types declared by this method, in declaration order.
+ * An array of size zero is returned if this method declares no
+ * exceptions.
+ *
+ * @return the exception types declared by this method.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericExceptionTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getExceptionTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericExceptionTypes();
+ }
+
+ /**
+ * Returns an array of <code>Type</code> objects that represents
+ * the parameter list for this method, in declaration order.
+ * An array of size zero is returned if this method takes no
+ * parameters.
+ *
+ * @return a list of the types of the method's parameters
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type[] getGenericParameterTypes()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getParameterTypes();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericParameterTypes();
+ }
+
+ /**
+ * Returns the return type of this method.
+ *
+ * @return the return type of this method
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ public Type getGenericReturnType()
+ {
+ String sig = getSignature();
+ if (sig == null)
+ return getReturnType();
+ MethodSignatureParser p = new MethodSignatureParser(this, sig);
+ return p.getGenericReturnType();
+ }
+
+ private native void getType ();
+
+ // Append a class name to a string buffer. We try to print the
+ // fully-qualified name, the way that a Java programmer would expect
+ // it to be written. Weirdly, Class has no appropriate method for
+ // this.
+ static void appendClassName (StringBuffer buf, Class k)
+ {
+ if (k.isArray ())
+ {
+ appendClassName (buf, k.getComponentType ());
+ buf.append ("[]");
+ }
+ else
+ {
+ // This is correct for primitive and reference types. Really
+ // we'd like `Main$Inner' to be printed as `Main.Inner', I
+ // think, but that is a pain.
+ buf.append (k.getName ());
+ }
+ }
+
+ // Declaring class.
+ private Class declaringClass;
+
+ // Exception types.
+ private Class[] exception_types;
+ // Name cache. (Initially null.)
+ private String name;
+ // Parameter types.
+ private Class[] parameter_types;
+ // Return type.
+ private Class return_type;
+
+ // Offset in bytes from the start of declaringClass's methods array.
+ private int offset;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/Modifier.java b/gcc-4.2.1/libjava/java/lang/reflect/Modifier.java
new file mode 100644
index 000000000..f9a9ca2c9
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/Modifier.java
@@ -0,0 +1,375 @@
+/* java.lang.reflect.Modifier
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 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;
+
+/**
+ * Modifier is a helper class with static methods to determine whether an
+ * int returned from getModifiers() represents static, public, protected,
+ * native, final, etc... and provides an additional method to print
+ * out all of the modifiers in an int in order.
+ * <p>
+ * The methods in this class use the bitmask values in the VM spec to
+ * determine the modifiers of an int. This means that a VM must return a
+ * standard mask, conformant with the VM spec. I don't know if this is how
+ * Sun does it, but I'm willing to bet money that it is.
+ *
+ * @author John Keiser
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Member#getModifiers()
+ * @see Method#getModifiers()
+ * @see Field#getModifiers()
+ * @see Constructor#getModifiers()
+ * @see Class#getModifiers()
+ * @since 1.1
+ */
+public class Modifier
+{
+ /** <STRONG>This constructor really shouldn't be here ... there are no
+ * instance methods or variables of this class, so instantiation is
+ * worthless. However, this function is in the 1.1 spec, so it is added
+ * for completeness.</STRONG>
+ */
+ public Modifier()
+ {
+ }
+
+ /**
+ * Public: accessible from any other class.
+ */
+ public static final int PUBLIC = 0x0001;
+
+ /**
+ * Private: accessible only from the same enclosing class.
+ */
+ public static final int PRIVATE = 0x0002;
+
+ /**
+ * Protected: accessible only to subclasses, or within the package.
+ */
+ public static final int PROTECTED = 0x0004;
+
+ /**
+ * Static:<br><ul>
+ * <li>Class: no enclosing instance for nested class.</li>
+ * <li>Field or Method: can be accessed or invoked without an
+ * instance of the declaring class.</li>
+ * </ul>
+ */
+ public static final int STATIC = 0x0008;
+
+ /**
+ * Final:<br><ul>
+ * <li>Class: no subclasses allowed.</li>
+ * <li>Field: cannot be changed.</li>
+ * <li>Method: cannot be overriden.</li>
+ * </ul>
+ */
+ public static final int FINAL = 0x0010;
+
+ /**
+ * Synchronized: Method: lock the class while calling this method.
+ */
+ public static final int SYNCHRONIZED = 0x0020;
+
+ /**
+ * Volatile: Field: cannot be cached.
+ */
+ public static final int VOLATILE = 0x0040;
+
+ /**
+ * Transient: Field: not serialized or deserialized.
+ */
+ public static final int TRANSIENT = 0x0080;
+
+ /**
+ * Native: Method: use JNI to call this method.
+ */
+ public static final int NATIVE = 0x0100;
+
+ /**
+ * Interface: Class: is an interface.
+ */
+ public static final int INTERFACE = 0x0200;
+
+ /**
+ * Abstract:<br><ul>
+ * <li>Class: may not be instantiated.</li>
+ * <li>Method: may not be called.</li>
+ * </ul>
+ */
+ public static final int ABSTRACT = 0x0400;
+
+ /**
+ * Strictfp: Method: expressions are FP-strict.<p>
+ * Also used as a modifier for classes, to mean that all initializers
+ * and constructors are FP-strict, but does not show up in
+ * Class.getModifiers.
+ */
+ public static final int STRICT = 0x0800;
+
+
+ /**
+ * Super - treat invokespecial as polymorphic so that super.foo() works
+ * according to the JLS. This is a reuse of the synchronized constant
+ * to patch a hole in JDK 1.0. *shudder*.
+ */
+ static final int SUPER = 0x0020;
+
+ /**
+ * All the flags, only used by code in this package.
+ */
+ static final int ALL_FLAGS = 0xfff;
+
+ /**
+ * Flag indicating a bridge method.
+ */
+ static final int BRIDGE = 0x40;
+
+ /**
+ * Flag indicating a varargs method.
+ */
+ static final int VARARGS = 0x80;
+
+ /**
+ * Flag indicating a synthetic member.
+ */
+ static final int SYNTHETIC = 0x1000;
+
+ /**
+ * Flag indicating an enum constant or an enum class.
+ */
+ static final int ENUM = 0x4000;
+
+ /**
+ * GCJ-LOCAL: This access flag is set on methods we declare
+ * internally but which must not be visible to reflection.
+ */
+ static final int INVISIBLE = 0x8000;
+
+ /**
+ * GCJ-LOCAL: This access flag is set on interpreted classes.
+ */
+ static final int INTERPRETED = 0x1000;
+
+ /**
+ * Check whether the given modifier is abstract.
+ * @param mod the modifier.
+ * @return <code>true</code> if abstract, <code>false</code> otherwise.
+ */
+ public static boolean isAbstract(int mod)
+ {
+ return (mod & ABSTRACT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is final.
+ * @param mod the modifier.
+ * @return <code>true</code> if final, <code>false</code> otherwise.
+ */
+ public static boolean isFinal(int mod)
+ {
+ return (mod & FINAL) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is an interface.
+ * @param mod the modifier.
+ * @return <code>true</code> if an interface, <code>false</code> otherwise.
+ */
+ public static boolean isInterface(int mod)
+ {
+ return (mod & INTERFACE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is native.
+ * @param mod the modifier.
+ * @return <code>true</code> if native, <code>false</code> otherwise.
+ */
+ public static boolean isNative(int mod)
+ {
+ return (mod & NATIVE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is private.
+ * @param mod the modifier.
+ * @return <code>true</code> if private, <code>false</code> otherwise.
+ */
+ public static boolean isPrivate(int mod)
+ {
+ return (mod & PRIVATE) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is protected.
+ * @param mod the modifier.
+ * @return <code>true</code> if protected, <code>false</code> otherwise.
+ */
+ public static boolean isProtected(int mod)
+ {
+ return (mod & PROTECTED) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is public.
+ * @param mod the modifier.
+ * @return <code>true</code> if public, <code>false</code> otherwise.
+ */
+ public static boolean isPublic(int mod)
+ {
+ return (mod & PUBLIC) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is static.
+ * @param mod the modifier.
+ * @return <code>true</code> if static, <code>false</code> otherwise.
+ */
+ public static boolean isStatic(int mod)
+ {
+ return (mod & STATIC) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is strictfp.
+ * @param mod the modifier.
+ * @return <code>true</code> if strictfp, <code>false</code> otherwise.
+ */
+ public static boolean isStrict(int mod)
+ {
+ return (mod & STRICT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is synchronized.
+ * @param mod the modifier.
+ * @return <code>true</code> if synchronized, <code>false</code> otherwise.
+ */
+ public static boolean isSynchronized(int mod)
+ {
+ return (mod & SYNCHRONIZED) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is transient.
+ * @param mod the modifier.
+ * @return <code>true</code> if transient, <code>false</code> otherwise.
+ */
+ public static boolean isTransient(int mod)
+ {
+ return (mod & TRANSIENT) != 0;
+ }
+
+ /**
+ * Check whether the given modifier is volatile.
+ * @param mod the modifier.
+ * @return <code>true</code> if volatile, <code>false</code> otherwise.
+ */
+ public static boolean isVolatile(int mod)
+ {
+ return (mod & VOLATILE) != 0;
+ }
+
+ /**
+ * Get a string representation of all the modifiers represented by the
+ * given int. The keywords are printed in this order:
+ * <code>&lt;public|protected|private&gt; abstract static final transient
+ * volatile synchronized native strictfp interface</code>.
+ *
+ * @param mod the modifier.
+ * @return the String representing the modifiers.
+ */
+ public static String toString(int mod)
+ {
+ return toString(mod, new StringBuffer()).toString();
+ }
+
+ /**
+ * Package helper method that can take a StringBuilder.
+ * @param mod the modifier
+ * @param r the StringBuilder to which the String representation is appended
+ * @return r, with information appended
+ */
+ static StringBuilder toString(int mod, StringBuilder r)
+ {
+ r.append(toString(mod, new StringBuffer()));
+ return r;
+ }
+
+ /**
+ * Package helper method that can take a StringBuffer.
+ * @param mod the modifier
+ * @param r the StringBuffer to which the String representation is appended
+ * @return r, with information appended
+ */
+ static StringBuffer toString(int mod, StringBuffer r)
+ {
+ if (isPublic(mod))
+ r.append("public ");
+ if (isProtected(mod))
+ r.append("protected ");
+ if (isPrivate(mod))
+ r.append("private ");
+ if (isAbstract(mod))
+ r.append("abstract ");
+ if (isStatic(mod))
+ r.append("static ");
+ if (isFinal(mod))
+ r.append("final ");
+ if (isTransient(mod))
+ r.append("transient ");
+ if (isVolatile(mod))
+ r.append("volatile ");
+ if (isSynchronized(mod))
+ r.append("synchronized ");
+ if (isNative(mod))
+ r.append("native ");
+ if (isStrict(mod))
+ r.append("strictfp ");
+ if (isInterface(mod))
+ r.append("interface ");
+
+ // Trim trailing space.
+ if ((mod & ALL_FLAGS) != 0)
+ r.setLength(r.length() - 1);
+ return r;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/VMProxy.java b/gcc-4.2.1/libjava/java/lang/reflect/VMProxy.java
new file mode 100644
index 000000000..b3641cf17
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/VMProxy.java
@@ -0,0 +1,143 @@
+/* VMProxy.java -- VM interface for proxy class
+ 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.lang.reflect;
+
+final class VMProxy
+{
+ /**
+ * Set to true if the VM provides a native method to implement
+ * Proxy.getProxyClass completely, including argument verification.
+ * If this is true, HAVE_NATIVE_GET_PROXY_DATA and
+ * HAVE_NATIVE_GENERATE_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_CLASS = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the first part of Proxy.getProxyClass: generation of the array
+ * of methods to convert, and verification of the arguments.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GET_PROXY_DATA = false;
+
+ /**
+ * Set to true if the VM provides a native method to implement
+ * the second part of Proxy.getProxyClass: conversion of an array of
+ * methods into an actual proxy class.
+ * If this is true, HAVE_NATIVE_GET_PROXY_CLASS should be false.
+ * @see java.lang.reflect.Proxy
+ */
+ static boolean HAVE_NATIVE_GENERATE_PROXY_CLASS = false;
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyClass. Only needed if
+ * VMProxy.HAVE_NATIVE_GET_PROXY_CLASS is true, this does the
+ * work of both getProxyData and generateProxyClass with no
+ * intermediate form in Java. The native code may safely assume that
+ * this class must be created, and does not already exist.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return the generated proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see Configuration#HAVE_NATIVE_GET_PROXY_CLASS
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyData(ClassLoader, Class[])
+ * @see #generateProxyClass(ProxyData)
+ */
+ static Class getProxyClass(ClassLoader loader, Class[] interfaces)
+ {
+ return null;
+ }
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of getProxyData. Only needed if
+ * Configuration.HAVE_NATIVE_GET_PROXY_DATA is true. The native code
+ * may safely assume that a new ProxyData object must be created which
+ * does not duplicate any existing ones.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param interfaces the interfaces the class will extend
+ * @return all data that is required to make this proxy class
+ * @throws IllegalArgumentException if the constraints for getProxyClass
+ * were violated, except for problems with null
+ * @throws NullPointerException if `interfaces' is null or contains
+ * a null entry, or if handler is null
+ * @see Configuration.HAVE_NATIVE_GET_PROXY_DATA
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see ProxyType#getProxyData()
+ */
+ static Proxy.ProxyData getProxyData(ClassLoader loader, Class[] interfaces)
+ {
+ return null;
+ }
+
+ /**
+ * Optional native method to replace (and speed up) the pure Java
+ * implementation of generateProxyClass. Only needed if
+ * Configuration.HAVE_NATIVE_GENERATE_PROXY_CLASS is true. The native
+ * code may safely assume that a new Class must be created, and that
+ * the ProxyData object does not describe any existing class.
+ *
+ * @param loader the class loader to define the proxy class in; null
+ * implies the bootstrap class loader
+ * @param data the struct of information to convert to a Class. This
+ * has already been verified for all problems except exceeding
+ * VM limitations
+ * @return the newly generated class
+ * @throws IllegalArgumentException if VM limitations are exceeded
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see #getProxyClass(ClassLoader, Class[])
+ * @see ProxyData#generateProxyClass(ClassLoader)
+ */
+ static Class generateProxyClass(ClassLoader loader, Proxy.ProxyData data)
+ {
+ return null;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/natArray.cc b/gcc-4.2.1/libjava/java/lang/reflect/natArray.cc
new file mode 100644
index 000000000..b7bc8beff
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/natArray.cc
@@ -0,0 +1,360 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <gcj/cni.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Array.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType, jint length)
+{
+ if (componentType->isPrimitive())
+ {
+ // We could check for this in _Jv_NewPrimArray, but that seems
+ // like needless overhead when the only real route to this
+ // problem is here.
+ if (componentType == JvPrimClass (void))
+ throw new java::lang::IllegalArgumentException ();
+ return _Jv_NewPrimArray (componentType, length);
+ }
+ else
+ // FIXME: class loader?
+ return JvNewObjectArray (length, componentType, NULL);
+}
+
+jobject
+java::lang::reflect::Array::newInstance (jclass componentType,
+ jintArray dimensions)
+{
+ jint ndims = dimensions->length;
+ if (ndims == 0)
+ throw new java::lang::IllegalArgumentException ();
+ jint* dims = elements (dimensions);
+ if (ndims == 1)
+ return newInstance (componentType, dims[0]);
+
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Array::class$);
+ ClassLoader *caller_loader = NULL;
+ if (caller)
+ caller_loader = caller->getClassLoaderInternal();
+
+ jclass arrayType = componentType;
+ for (int i = 0; i < ndims; i++)
+ arrayType = _Jv_GetArrayClass (arrayType, caller_loader);
+
+ return _Jv_NewMultiArray (arrayType, ndims, dims);
+}
+
+jint
+java::lang::reflect::Array::getLength (jobject array)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ throw new java::lang::IllegalArgumentException;
+ return ((__JArray*) array)->length;
+}
+
+jclass
+java::lang::reflect::Array::getElementType (jobject array, jint index)
+{
+ jclass arrayType = array->getClass();
+ if (! arrayType->isArray ())
+ throw new java::lang::IllegalArgumentException;
+ jint length = ((__JArray*) array)->length;
+ if ((_Jv_uint) index >= (_Jv_uint) length)
+ _Jv_ThrowBadArrayIndex(index);
+ return arrayType->getComponentType ();
+}
+
+jboolean
+java::lang::reflect::Array::getBoolean (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ return elements ((jbooleanArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jchar
+java::lang::reflect::Array::getChar (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jbyte
+java::lang::reflect::Array::getByte (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jshort
+java::lang::reflect::Array::getShort (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jint
+java::lang::reflect::Array::getInt (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jlong
+java::lang::reflect::Array::getLong (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jfloat
+java::lang::reflect::Array::getFloat (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jdouble
+java::lang::reflect::Array::getDouble (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ return elements ((jdoubleArray) array) [index];
+ if (elementType == JvPrimClass (float))
+ return elements ((jfloatArray) array) [index];
+ if (elementType == JvPrimClass (long))
+ return elements ((jlongArray) array) [index];
+ if (elementType == JvPrimClass (int))
+ return elements ((jintArray) array) [index];
+ if (elementType == JvPrimClass (short))
+ return elements ((jshortArray) array) [index];
+ if (elementType == JvPrimClass (byte))
+ return elements ((jbyteArray) array) [index];
+ if (elementType == JvPrimClass (char))
+ return elements ((jcharArray) array) [index];
+ throw new java::lang::IllegalArgumentException;
+}
+
+jobject
+java::lang::reflect::Array::get (jobject array, jint index)
+{
+ jclass elementType = getElementType (array, index);
+ if (! elementType->isPrimitive ())
+ return elements ((jobjectArray) array) [index];
+ if (elementType == JvPrimClass (double))
+ return new java::lang::Double (elements ((jdoubleArray) array) [index]);
+ if (elementType == JvPrimClass (float))
+ return new java::lang::Float (elements ((jfloatArray) array) [index]);
+ if (elementType == JvPrimClass (long))
+ return new java::lang::Long (elements ((jlongArray) array) [index]);
+ if (elementType == JvPrimClass (int))
+ return new java::lang::Integer (elements ((jintArray) array) [index]);
+ if (elementType == JvPrimClass (short))
+ return new java::lang::Short (elements ((jshortArray) array) [index]);
+ if (elementType == JvPrimClass (byte))
+ return new java::lang::Byte (elements ((jbyteArray) array) [index]);
+ if (elementType == JvPrimClass (char))
+ return new java::lang::Character (elements ((jcharArray) array) [index]);
+ if (elementType == JvPrimClass (boolean))
+ {
+ _Jv_InitClass (&java::lang::Boolean::class$);
+ if (elements ((jbooleanArray) array) [index])
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ }
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setChar (jobject array, jint index, jchar value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (char))
+ elements ((jcharArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setByte (jobject array, jint index, jbyte value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (byte))
+ elements ((jbyteArray) array) [index] = value;
+ else if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setShort (jobject array, jint index, jshort value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (short))
+ elements ((jshortArray) array) [index] = value;
+ else if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setInt (jobject array, jint index, jint value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (int))
+ elements ((jintArray) array) [index] = value;
+ else if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setLong (jobject array, jint index, jlong value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (long))
+ elements ((jlongArray) array) [index] = value;
+ else if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setFloat (jobject array, jint index, jfloat value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (float))
+ elements ((jfloatArray) array) [index] = value;
+ else if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setDouble (jobject array, jint index, jdouble value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (double))
+ elements ((jdoubleArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::setBoolean (jobject array,
+ jint index, jboolean value)
+{
+ jclass elementType = getElementType (array, index);
+ if (elementType == JvPrimClass (boolean))
+ elements ((jbooleanArray) array) [index] = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Array::set (jobject array, jint index,
+ jobject value, jclass elType)
+{
+ // We don't have to call getElementType here, or check INDEX,
+ // because it was already done in the Java wrapper.
+ if (value != NULL && ! _Jv_IsInstanceOf (value, elType))
+ throw new java::lang::IllegalArgumentException;
+ elements ((jobjectArray) array) [index] = value;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/natConstructor.cc b/gcc-4.2.1/libjava/java/lang/reflect/natConstructor.cc
new file mode 100644
index 000000000..35cf7f817
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/natConstructor.cc
@@ -0,0 +1,72 @@
+// natConstructor.cc - Native code for Constructor class.
+
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/InstantiationException.h>
+#include <gcj/method.h>
+
+jint
+java::lang::reflect::Constructor::getModifiersInternal ()
+{
+ return _Jv_FromReflectedConstructor (this)->accflags;
+}
+
+void
+java::lang::reflect::Constructor::getType ()
+{
+ _Jv_GetTypesFromSignature (_Jv_FromReflectedConstructor (this),
+ declaringClass,
+ &parameter_types,
+ NULL);
+
+ // FIXME: for now we have no way to get exception information.
+ exception_types =
+ (JArray<jclass> *) JvNewObjectArray (0, &java::lang::Class::class$, NULL);
+}
+
+jobject
+java::lang::reflect::Constructor::newInstance (jobjectArray args)
+{
+ using namespace java::lang::reflect;
+
+ if (parameter_types == NULL)
+ getType ();
+
+ jmethodID meth = _Jv_FromReflectedConstructor (this);
+
+ // Check accessibility, if required.
+ if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Constructor::class$);
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+ throw new IllegalAccessException;
+ }
+
+ if (Modifier::isAbstract (declaringClass->getModifiers()))
+ throw new InstantiationException;
+
+ _Jv_InitClass (declaringClass);
+
+ // In the constructor case the return type is the type of the
+ // constructor.
+ return _Jv_CallAnyMethodA (NULL, declaringClass, meth, true,
+ parameter_types, args);
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/natField.cc b/gcc-4.2.1/libjava/java/lang/reflect/natField.cc
new file mode 100644
index 000000000..487f62ab0
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/natField.cc
@@ -0,0 +1,439 @@
+// natField.cc - Implementation of java.lang.reflect.Field native methods.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <stdlib.h>
+
+#include <jvm.h>
+#include <java-stack.h>
+#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Modifier.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+
+jint
+java::lang::reflect::Field::getModifiersInternal ()
+{
+ return _Jv_FromReflectedField (this)->flags;
+}
+
+jstring
+java::lang::reflect::Field::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
+ return name;
+}
+
+jclass
+java::lang::reflect::Field::getType ()
+{
+ if (type == NULL)
+ {
+ jfieldID fld = _Jv_FromReflectedField (this);
+ JvSynchronize sync (declaringClass);
+ _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
+ type = fld->type;
+ }
+ return type;
+}
+
+static void*
+getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
+ jboolean checkFinal)
+{
+ // FIXME: we know CALLER is NULL here. At one point we planned to
+ // have the compiler insert the caller as a hidden argument in some
+ // calls. However, we never implemented that, so we have to find
+ // the caller by hand instead.
+
+ using namespace java::lang::reflect;
+
+ jfieldID fld = _Jv_FromReflectedField (field);
+ _Jv_ushort flags = fld->getModifiers();
+
+ // Setting a final field is usually not allowed.
+ if (checkFinal
+ // As of 1.5, you can set a non-static final field if it is
+ // accessible.
+ && (! field->isAccessible()
+ || (field->getModifiers() & java::lang::reflect::Modifier::STATIC))
+ && (field->getModifiers() & java::lang::reflect::Modifier::FINAL))
+ throw new java::lang::IllegalAccessException(JvNewStringUTF
+ ("Field is final"));
+
+ // Check accessibility, if required.
+ if (! (Modifier::isPublic (flags) || field->isAccessible()))
+ {
+ caller = _Jv_StackTrace::GetCallingClass (&Field::class$);
+ if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
+ throw new java::lang::IllegalAccessException;
+ }
+
+ if (flags & Modifier::STATIC)
+ {
+ jclass fldClass = field->getDeclaringClass ();
+ JvInitClass(fldClass);
+ return fld->u.addr;
+ }
+ else
+ {
+ if (obj == NULL)
+ throw new java::lang::NullPointerException;
+ if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
+ throw new java::lang::IllegalArgumentException;
+ return (void*) ((char*) obj + fld->getOffset ());
+ }
+}
+
+static jboolean
+getBoolean (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (boolean))
+ return * (jboolean *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jchar
+getChar (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jbyte
+getByte (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jshort
+getShort (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jint
+getInt (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (int))
+ return * (jint *) addr;
+ if (cls == JvPrimClass (short))
+ return * (jshort *) addr;
+ if (cls == JvPrimClass (char))
+ return * (jchar *) addr;
+ if (cls == JvPrimClass (byte))
+ return * (jbyte *) addr;
+ throw new java::lang::IllegalArgumentException;
+}
+
+static jlong
+getLong (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jfloat
+getFloat (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+static jdouble
+getDouble (jclass cls, void* addr)
+{
+ if (cls == JvPrimClass (double))
+ return * (jdouble *) addr;
+ if (cls == JvPrimClass (float))
+ return * (jfloat *) addr;
+ if (cls == JvPrimClass (long))
+ return * (jlong *) addr;
+ return ::getInt(cls, addr);
+}
+
+jboolean
+java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
+{
+ return ::getBoolean (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jchar
+java::lang::reflect::Field::getChar (jclass caller, jobject obj)
+{
+ return ::getChar (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jbyte
+java::lang::reflect::Field::getByte (jclass caller, jobject obj)
+{
+ return ::getByte (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jshort
+java::lang::reflect::Field::getShort (jclass caller, jobject obj)
+{
+ return ::getShort (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jint
+java::lang::reflect::Field::getInt (jclass caller, jobject obj)
+{
+ return ::getInt (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jlong
+java::lang::reflect::Field::getLong (jclass caller, jobject obj)
+{
+ return ::getLong (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jfloat
+java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
+{
+ return ::getFloat (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jdouble
+java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
+{
+ return ::getDouble (this->getType(), getAddr (this, caller, obj, false));
+}
+
+jobject
+java::lang::reflect::Field::get (jclass caller, jobject obj)
+{
+ jclass type = this->getType();
+ void* addr = getAddr (this, caller, obj, false);
+ if (! type->isPrimitive ())
+ return * (jobject*) addr;
+ if (type == JvPrimClass (double))
+ return new java::lang::Double (* (jdouble*) addr);
+ if (type == JvPrimClass (float))
+ return new java::lang::Float (* (jfloat*) addr);
+ if (type == JvPrimClass (long))
+ return new java::lang::Long (* (jlong*) addr);
+ if (type == JvPrimClass (int))
+ return new java::lang::Integer (* (jint*) addr);
+ if (type == JvPrimClass (short))
+ return new java::lang::Short (* (jshort*) addr);
+ if (type == JvPrimClass (byte))
+ return new java::lang::Byte (* (jbyte*) addr);
+ if (type == JvPrimClass (char))
+ return new java::lang::Character (* (jchar*) addr);
+ if (type == JvPrimClass (boolean))
+ {
+ _Jv_InitClass (&java::lang::Boolean::class$);
+ if (* (jboolean*) addr)
+ return java::lang::Boolean::TRUE;
+ else
+ return java::lang::Boolean::FALSE;
+ }
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setBoolean (jclass type, void *addr, jboolean value)
+{
+ if (type == JvPrimClass (boolean))
+ * (jboolean *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setChar (jclass type, void *addr, jchar value)
+{
+ if (type == JvPrimClass (char))
+ * (jchar *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setByte (jclass type, void *addr, jbyte value)
+{
+ if (type == JvPrimClass (byte))
+ * (jbyte *) addr = value;
+ else if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setShort (jclass type, void *addr, jshort value)
+{
+ if (type == JvPrimClass (short))
+ * (jshort *) addr = value;
+ else if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setInt (jclass type, void *addr, jint value)
+{
+ if (type == JvPrimClass (int))
+ * (jint *) addr = value;
+ else if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setLong (jclass type, void *addr, jlong value)
+{
+ if (type == JvPrimClass (long))
+ * (jlong *) addr = value;
+ else if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setFloat (jclass type, void *addr, jfloat value)
+{
+ if (type == JvPrimClass (float))
+ * (jfloat *) addr = value;
+ else if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+static void
+setDouble (jclass type, void *addr, jdouble value)
+{
+ if (type == JvPrimClass (double))
+ * (jdouble *) addr = value;
+ else
+ throw new java::lang::IllegalArgumentException;
+}
+
+void
+java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b,
+ jboolean checkFinal)
+{
+ ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c,
+ jboolean checkFinal)
+{
+ ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c);
+}
+
+void
+java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b,
+ jboolean checkFinal)
+{
+ ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b);
+}
+
+void
+java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s,
+ jboolean checkFinal)
+{
+ ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s);
+}
+
+void
+java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i,
+ jboolean checkFinal)
+{
+ ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i);
+}
+
+void
+java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l,
+ jboolean checkFinal)
+{
+ ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l);
+}
+
+void
+java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f,
+ jboolean checkFinal)
+{
+ ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f);
+}
+
+void
+java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d,
+ jboolean checkFinal)
+{
+ ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d);
+}
+
+void
+java::lang::reflect::Field::set (jclass caller, jobject object, jobject value,
+ jclass type, jboolean checkFinal)
+{
+ void* addr = getAddr (this, caller, object, checkFinal);
+ if (value != NULL && ! _Jv_IsInstanceOf (value, type))
+ throw new java::lang::IllegalArgumentException;
+ * (jobject*) addr = value;
+}
diff --git a/gcc-4.2.1/libjava/java/lang/reflect/natMethod.cc b/gcc-4.2.1/libjava/java/lang/reflect/natMethod.cc
new file mode 100644
index 000000000..eb7170a02
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/lang/reflect/natMethod.cc
@@ -0,0 +1,654 @@
+// natMethod.cc - Native code for Method class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <jni.h>
+#include <java-stack.h>
+
+#include <java/lang/reflect/Method.h>
+#include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/InvocationTargetException.h>
+#include <java/lang/reflect/Modifier.h>
+
+#include <java/lang/Void.h>
+#include <java/lang/Byte.h>
+#include <java/lang/Boolean.h>
+#include <java/lang/Character.h>
+#include <java/lang/Short.h>
+#include <java/lang/Integer.h>
+#include <java/lang/Long.h>
+#include <java/lang/Float.h>
+#include <java/lang/Double.h>
+#include <java/lang/IllegalAccessException.h>
+#include <java/lang/IllegalArgumentException.h>
+#include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/VirtualMachineError.h>
+#include <java/lang/Class.h>
+#include <gcj/method.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/NoClassDefFoundError.h>
+
+#include <stdlib.h>
+
+#if USE_LIBFFI
+#include <ffi.h>
+#else
+#include <java/lang/UnsupportedOperationException.h>
+#endif
+
+struct cpair
+{
+ jclass prim;
+ jclass wrap;
+};
+
+// This is used to determine when a primitive widening conversion is
+// allowed.
+static cpair primitives[] =
+{
+#define BOOLEAN 0
+ { JvPrimClass (boolean), &java::lang::Boolean::class$ },
+ { JvPrimClass (byte), &java::lang::Byte::class$ },
+#define SHORT 2
+ { JvPrimClass (short), &java::lang::Short::class$ },
+#define CHAR 3
+ { JvPrimClass (char), &java::lang::Character::class$ },
+ { JvPrimClass (int), &java::lang::Integer::class$ },
+ { JvPrimClass (long), &java::lang::Long::class$ },
+ { JvPrimClass (float), &java::lang::Float::class$ },
+ { JvPrimClass (double), &java::lang::Double::class$ },
+ { NULL, NULL }
+};
+
+static inline jboolean
+can_widen (jclass from, jclass to)
+{
+ int fromx = -1, tox = -1;
+
+ for (int i = 0; primitives[i].prim; ++i)
+ {
+ if (primitives[i].wrap == from)
+ fromx = i;
+ if (primitives[i].prim == to)
+ tox = i;
+ }
+
+ // Can't handle a miss.
+ if (fromx == -1 || tox == -1)
+ return false;
+ // Boolean arguments may not be widened.
+ if (fromx == BOOLEAN && tox != BOOLEAN)
+ return false;
+ // Nothing promotes to char.
+ if (tox == CHAR && fromx != CHAR)
+ return false;
+
+ return fromx <= tox;
+}
+
+#ifdef USE_LIBFFI
+static inline ffi_type *
+get_ffi_type (jclass klass)
+{
+ // A special case.
+ if (klass == NULL)
+ return &ffi_type_pointer;
+
+ ffi_type *r;
+ if (klass == JvPrimClass (byte))
+ r = &ffi_type_sint8;
+ else if (klass == JvPrimClass (short))
+ r = &ffi_type_sint16;
+ else if (klass == JvPrimClass (int))
+ r = &ffi_type_sint32;
+ else if (klass == JvPrimClass (long))
+ r = &ffi_type_sint64;
+ else if (klass == JvPrimClass (float))
+ r = &ffi_type_float;
+ else if (klass == JvPrimClass (double))
+ r = &ffi_type_double;
+ else if (klass == JvPrimClass (boolean))
+ {
+ // On some platforms a bool is a byte, on others an int.
+ if (sizeof (jboolean) == sizeof (jbyte))
+ r = &ffi_type_sint8;
+ else
+ {
+ JvAssert (sizeof (jboolean) == sizeof (jint));
+ r = &ffi_type_sint32;
+ }
+ }
+ else if (klass == JvPrimClass (char))
+ r = &ffi_type_uint16;
+ else
+ {
+ JvAssert (! klass->isPrimitive());
+ r = &ffi_type_pointer;
+ }
+
+ return r;
+}
+#endif // USE_LIBFFI
+
+jobject
+java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
+{
+ using namespace java::lang::reflect;
+ jclass iface = NULL;
+
+ if (parameter_types == NULL)
+ getType ();
+
+ jmethodID meth = _Jv_FromReflectedMethod (this);
+
+ if (Modifier::isStatic(meth->accflags))
+ {
+ // We have to initialize a static class. It is safe to do this
+ // here and not in _Jv_CallAnyMethodA because JNI initializes a
+ // class whenever a method lookup is done.
+ _Jv_InitClass (declaringClass);
+ }
+ else
+ {
+ jclass objClass = JV_CLASS (obj);
+ if (! _Jv_IsAssignableFrom (objClass, declaringClass))
+ throw new java::lang::IllegalArgumentException;
+ }
+
+ // Check accessibility, if required.
+ if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
+ {
+ Class *caller = _Jv_StackTrace::GetCallingClass (&Method::class$);
+ if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
+ throw new IllegalAccessException;
+ }
+
+ if (declaringClass->isInterface())
+ iface = declaringClass;
+
+ return _Jv_CallAnyMethodA (obj, return_type, meth, false,
+ parameter_types, args, iface);
+}
+
+jint
+java::lang::reflect::Method::getModifiersInternal ()
+{
+ return _Jv_FromReflectedMethod (this)->accflags;
+}
+
+jstring
+java::lang::reflect::Method::getName ()
+{
+ if (name == NULL)
+ name = _Jv_NewStringUtf8Const (_Jv_FromReflectedMethod (this)->name);
+ return name;
+}
+
+/* Internal method to set return_type and parameter_types fields. */
+
+void
+java::lang::reflect::Method::getType ()
+{
+ _Jv_Method *method = _Jv_FromReflectedMethod (this);
+ _Jv_GetTypesFromSignature (method,
+ declaringClass,
+ &parameter_types,
+ &return_type);
+
+ int count = 0;
+ if (method->throws != NULL)
+ {
+ while (method->throws[count] != NULL)
+ ++count;
+ }
+
+ exception_types
+ = (JArray<jclass> *) JvNewObjectArray (count, &java::lang::Class::class$,
+ NULL);
+ jclass *elts = elements (exception_types);
+ for (int i = 0; i < count; ++i)
+ elts[i] = _Jv_FindClass (method->throws[i],
+ declaringClass->getClassLoaderInternal ());
+}
+
+void
+_Jv_GetTypesFromSignature (jmethodID method,
+ jclass declaringClass,
+ JArray<jclass> **arg_types_out,
+ jclass *return_type_out)
+{
+
+ _Jv_Utf8Const* sig = method->signature;
+ java::lang::ClassLoader *loader = declaringClass->getClassLoaderInternal();
+ char *ptr = sig->chars();
+ int numArgs = 0;
+ /* First just count the number of parameters. */
+ // FIXME: should do some validation here, e.g., that there is only
+ // one return type.
+ for (; ; ptr++)
+ {
+ switch (*ptr)
+ {
+ case 0:
+ case ')':
+ case 'V':
+ break;
+ case '[':
+ case '(':
+ continue;
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'S':
+ case 'I':
+ case 'J':
+ case 'Z':
+ numArgs++;
+ continue;
+ case 'L':
+ numArgs++;
+ do
+ ptr++;
+ while (*ptr != ';' && ptr[1] != '\0');
+ continue;
+ }
+ break;
+ }
+
+ JArray<jclass> *args = (JArray<jclass> *)
+ JvNewObjectArray (numArgs, &java::lang::Class::class$, NULL);
+ jclass* argPtr = elements (args);
+ for (ptr = sig->chars(); *ptr != '\0'; ptr++)
+ {
+ if (*ptr == '(')
+ continue;
+ if (*ptr == ')')
+ {
+ argPtr = return_type_out;
+ continue;
+ }
+
+ char *end_ptr;
+ jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);
+ if (type == NULL)
+ // FIXME: This isn't ideal.
+ throw new java::lang::NoClassDefFoundError (sig->toString());
+
+ // ARGPTR can be NULL if we are processing the return value of a
+ // call from Constructor.
+ if (argPtr)
+ *argPtr++ = type;
+
+ ptr = end_ptr;
+ }
+ *arg_types_out = args;
+}
+
+// This is a very rough analog of the JNI CallNonvirtual<type>MethodA
+// functions. It handles both Methods and Constructors, and it can
+// handle any return type. In the Constructor case, the `obj'
+// argument is unused and should be NULL; also, the `return_type' is
+// the class that the constructor will construct. RESULT is a pointer
+// to a `jvalue' (see jni.h); for a void method this should be NULL.
+// This function returns an exception (if one was thrown), or NULL if
+// the call went ok.
+void
+_Jv_CallAnyMethodA (jobject obj,
+ jclass return_type,
+ jmethodID meth,
+ jboolean is_constructor,
+ jboolean is_virtual_call,
+ JArray<jclass> *parameter_types,
+ jvalue *args,
+ jvalue *result,
+ jboolean is_jni_call,
+ jclass iface)
+{
+ using namespace java::lang::reflect;
+
+#ifdef USE_LIBFFI
+ JvAssert (! is_constructor || ! obj);
+ JvAssert (! is_constructor || return_type);
+
+ // See whether call needs an object as the first argument. A
+ // constructor does need a `this' argument, but it is one we create.
+ jboolean needs_this = false;
+ if (is_constructor
+ || ! Modifier::isStatic(meth->accflags))
+ needs_this = true;
+
+ int param_count = parameter_types->length;
+ if (needs_this)
+ ++param_count;
+
+ ffi_type *rtype;
+ // A constructor itself always returns void.
+ if (is_constructor || return_type == JvPrimClass (void))
+ rtype = &ffi_type_void;
+ else
+ rtype = get_ffi_type (return_type);
+ ffi_type **argtypes = (ffi_type **) __builtin_alloca (param_count
+ * sizeof (ffi_type *));
+
+ jclass *paramelts = elements (parameter_types);
+
+ // Special case for the `this' argument of a constructor. Note that
+ // the JDK 1.2 docs specify that the new object must be allocated
+ // before argument conversions are done.
+ if (is_constructor)
+ obj = _Jv_AllocObject (return_type);
+
+ const int size_per_arg = sizeof(jvalue);
+ ffi_cif cif;
+
+ char *p = (char *) __builtin_alloca (param_count * size_per_arg);
+ // Overallocate to get correct alignment.
+ void **values = (void **)
+ __builtin_alloca (param_count * sizeof (void *));
+
+ int i = 0;
+ if (needs_this)
+ {
+ // The `NULL' type is `Object'.
+ argtypes[i] = get_ffi_type (NULL);
+ values[i] = p;
+ memcpy (p, &obj, sizeof (jobject));
+ p += size_per_arg;
+ ++i;
+ }
+
+ for (int arg = 0; i < param_count; ++i, ++arg)
+ {
+ int tsize;
+
+ argtypes[i] = get_ffi_type (paramelts[arg]);
+ if (paramelts[arg]->isPrimitive())
+ tsize = paramelts[arg]->size();
+ else
+ tsize = sizeof (jobject);
+
+ // Copy appropriate bits from the jvalue into the ffi array.
+ // FIXME: we could do this copying all in one loop, above, by
+ // over-allocating a bit.
+ // How do we do this without breaking big-endian platforms?
+ values[i] = p;
+ memcpy (p, &args[arg], tsize);
+ p += size_per_arg;
+ }
+
+ if (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, param_count,
+ rtype, argtypes) != FFI_OK)
+ throw new java::lang::VirtualMachineError(JvNewStringLatin1("internal error: ffi_prep_cif failed"));
+
+ using namespace java::lang;
+ using namespace java::lang::reflect;
+
+ union
+ {
+ ffi_arg i;
+ jobject o;
+ jlong l;
+ jfloat f;
+ jdouble d;
+ } ffi_result;
+
+ switch (rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ break;
+ case FFI_TYPE_SINT8:
+ result->b = 0;
+ break;
+ case FFI_TYPE_SINT16:
+ result->s = 0;
+ break;
+ case FFI_TYPE_UINT16:
+ result->c = 0;
+ break;
+ case FFI_TYPE_SINT32:
+ result->i = 0;
+ break;
+ case FFI_TYPE_SINT64:
+ result->j = 0;
+ break;
+ case FFI_TYPE_FLOAT:
+ result->f = 0;
+ break;
+ case FFI_TYPE_DOUBLE:
+ result->d = 0;
+ break;
+ case FFI_TYPE_POINTER:
+ result->l = 0;
+ break;
+ default:
+ JvFail ("Unknown ffi_call return type");
+ break;
+ }
+
+ void *ncode;
+
+ // FIXME: If a vtable index is -1 at this point it is invalid, so we
+ // have to use the ncode.
+ //
+ // This can happen because methods in final classes don't have
+ // vtable entries, but _Jv_isVirtualMethod() doesn't know that. We
+ // could solve this problem by allocating a vtable index for methods
+ // in final classes.
+ if (is_virtual_call
+ && ! Modifier::isFinal (meth->accflags)
+ && (_Jv_ushort)-1 != meth->index)
+ {
+ _Jv_VTable *vtable = *(_Jv_VTable **) obj;
+ if (iface == NULL)
+ {
+ if (is_jni_call && Modifier::isAbstract (meth->accflags))
+ {
+ // With JNI we don't know if this is an interface call
+ // or a call to an abstract method. Look up the method
+ // by name, the slow way.
+ _Jv_Method *concrete_meth
+ = _Jv_LookupDeclaredMethod (vtable->clas,
+ meth->name,
+ meth->signature,
+ NULL);
+ if (concrete_meth == NULL
+ || concrete_meth->ncode == NULL
+ || Modifier::isAbstract(concrete_meth->accflags))
+ throw new java::lang::IncompatibleClassChangeError
+ (_Jv_GetMethodString (vtable->clas, meth));
+ ncode = concrete_meth->ncode;
+ }
+ else
+ ncode = vtable->get_method (meth->index);
+ }
+ else
+ ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface,
+ meth->index);
+ }
+ else
+ {
+ ncode = meth->ncode;
+ }
+
+ try
+ {
+ ffi_call (&cif, (void (*)()) ncode, &ffi_result, values);
+ }
+ catch (Throwable *ex)
+ {
+ // For JNI we just throw the real error. For reflection, we
+ // wrap the underlying method's exception in an
+ // InvocationTargetException.
+ if (! is_jni_call)
+ ex = new InvocationTargetException (ex);
+ throw ex;
+ }
+
+ // Since ffi_call returns integer values promoted to a word, use
+ // a narrowing conversion for jbyte, jchar, etc. results.
+ // Note that boolean is handled either by the FFI_TYPE_SINT8 or
+ // FFI_TYPE_SINT32 case.
+ if (is_constructor)
+ result->l = obj;
+ else
+ {
+ switch (rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ break;
+ case FFI_TYPE_SINT8:
+ result->b = (jbyte)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT16:
+ result->s = (jshort)ffi_result.i;
+ break;
+ case FFI_TYPE_UINT16:
+ result->c = (jchar)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT32:
+ result->i = (jint)ffi_result.i;
+ break;
+ case FFI_TYPE_SINT64:
+ result->j = (jlong)ffi_result.l;
+ break;
+ case FFI_TYPE_FLOAT:
+ result->f = (jfloat)ffi_result.f;
+ break;
+ case FFI_TYPE_DOUBLE:
+ result->d = (jdouble)ffi_result.d;
+ break;
+ case FFI_TYPE_POINTER:
+ result->l = (jobject)ffi_result.o;
+ break;
+ default:
+ JvFail ("Unknown ffi_call return type");
+ break;
+ }
+ }
+#else
+ throw new java::lang::UnsupportedOperationException(JvNewStringLatin1("reflection not available in this build"));
+#endif // USE_LIBFFI
+}
+
+// This is another version of _Jv_CallAnyMethodA, but this one does
+// more checking and is used by the reflection (and not JNI) code.
+jobject
+_Jv_CallAnyMethodA (jobject obj,
+ jclass return_type,
+ jmethodID meth,
+ jboolean is_constructor,
+ JArray<jclass> *parameter_types,
+ jobjectArray args,
+ jclass iface)
+{
+ if (parameter_types->length == 0 && args == NULL)
+ {
+ // The JDK accepts this, so we do too.
+ }
+ else if (parameter_types->length != args->length)
+ throw new java::lang::IllegalArgumentException;
+
+ int param_count = parameter_types->length;
+
+ jclass *paramelts = elements (parameter_types);
+ jobject *argelts = args == NULL ? NULL : elements (args);
+ jvalue argvals[param_count];
+
+#define COPY(Where, What, Type) \
+ do { \
+ Type val = (What); \
+ memcpy ((Where), &val, sizeof (Type)); \
+ } while (0)
+
+ for (int i = 0; i < param_count; ++i)
+ {
+ jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
+ if (paramelts[i]->isPrimitive())
+ {
+ if (! argelts[i]
+ || ! k
+ || ! can_widen (k, paramelts[i]))
+ throw new java::lang::IllegalArgumentException;
+
+ if (paramelts[i] == JvPrimClass (boolean))
+ COPY (&argvals[i],
+ ((java::lang::Boolean *) argelts[i])->booleanValue(),
+ jboolean);
+ else if (paramelts[i] == JvPrimClass (char))
+ COPY (&argvals[i],
+ ((java::lang::Character *) argelts[i])->charValue(),
+ jchar);
+ else
+ {
+ java::lang::Number *num = (java::lang::Number *) argelts[i];
+ if (paramelts[i] == JvPrimClass (byte))
+ COPY (&argvals[i], num->byteValue(), jbyte);
+ else if (paramelts[i] == JvPrimClass (short))
+ COPY (&argvals[i], num->shortValue(), jshort);
+ else if (paramelts[i] == JvPrimClass (int))
+ COPY (&argvals[i], num->intValue(), jint);
+ else if (paramelts[i] == JvPrimClass (long))
+ COPY (&argvals[i], num->longValue(), jlong);
+ else if (paramelts[i] == JvPrimClass (float))
+ COPY (&argvals[i], num->floatValue(), jfloat);
+ else if (paramelts[i] == JvPrimClass (double))
+ COPY (&argvals[i], num->doubleValue(), jdouble);
+ }
+ }
+ else
+ {
+ if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
+ throw new java::lang::IllegalArgumentException;
+ COPY (&argvals[i], argelts[i], jobject);
+ }
+ }
+
+ jvalue ret_value;
+ _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
+ _Jv_isVirtualMethod (meth),
+ parameter_types, argvals, &ret_value,
+ false, iface);
+
+ jobject r;
+#define VAL(Wrapper, Field) (new Wrapper (ret_value.Field))
+ if (is_constructor)
+ r = ret_value.l;
+ else if (return_type == JvPrimClass (byte))
+ r = VAL (java::lang::Byte, b);
+ else if (return_type == JvPrimClass (short))
+ r = VAL (java::lang::Short, s);
+ else if (return_type == JvPrimClass (int))
+ r = VAL (java::lang::Integer, i);
+ else if (return_type == JvPrimClass (long))
+ r = VAL (java::lang::Long, j);
+ else if (return_type == JvPrimClass (float))
+ r = VAL (java::lang::Float, f);
+ else if (return_type == JvPrimClass (double))
+ r = VAL (java::lang::Double, d);
+ else if (return_type == JvPrimClass (boolean))
+ r = VAL (java::lang::Boolean, z);
+ else if (return_type == JvPrimClass (char))
+ r = VAL (java::lang::Character, c);
+ else if (return_type == JvPrimClass (void))
+ r = NULL;
+ else
+ {
+ JvAssert (return_type == NULL || ! return_type->isPrimitive());
+ r = ret_value.l;
+ }
+
+ return r;
+}
diff --git a/gcc-4.2.1/libjava/java/net/InetAddress.java b/gcc-4.2.1/libjava/java/net/InetAddress.java
new file mode 100644
index 000000000..640750d63
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/InetAddress.java
@@ -0,0 +1,819 @@
+/* InetAddress.java -- Class to model an Internet address
+ Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
+ 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 java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * This class models an Internet address. It does not have a public
+ * constructor. Instead, new instances of this objects are created
+ * using the static methods getLocalHost(), getByName(), and
+ * getAllByName().
+ *
+ * <p>This class fulfills the function of the C style functions gethostname(),
+ * gethostbyname(), and gethostbyaddr(). It resolves Internet DNS names
+ * into their corresponding numeric addresses and vice versa.</p>
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Per Bothner
+ * @author Gary Benson (gbenson@redhat.com)
+ *
+ * @specnote This class is not final since JK 1.4
+ */
+public class InetAddress implements Serializable
+{
+ private static final long serialVersionUID = 3286316764910316507L;
+
+ /**
+ * Stores static localhost address object.
+ */
+ static InetAddress LOCALHOST;
+ static
+ {
+ try
+ {
+ LOCALHOST = getByAddress("localhost", new byte[] {127, 0, 0, 1});
+ // Some soon-to-be-removed native code synchronizes on this.
+ loopbackAddress = LOCALHOST;
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Dummy InetAddress, used to bind socket to any (all) network interfaces.
+ */
+ static InetAddress ANY_IF;
+ static
+ {
+ byte[] addr;
+ try
+ {
+ addr = VMInetAddress.lookupInaddrAny();
+ }
+ catch (UnknownHostException e)
+ {
+ // Make one up and hope it works.
+ addr = new byte[] {0, 0, 0, 0};
+ }
+ try
+ {
+ ANY_IF = getByAddress(addr);
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ ANY_IF.hostName = ANY_IF.getHostName();
+ }
+
+ /**
+ * The Serialized Form specifies that an int 'address' is saved/restored.
+ * This class uses a byte array internally so we'll just do the conversion
+ * at serialization time and leave the rest of the algorithm as is.
+ */
+ private int address;
+
+ /**
+ * An array of octets representing an IP address.
+ */
+ transient byte[] addr;
+
+ /**
+ * The name of the host for this address.
+ */
+ String hostName;
+
+ /**
+ * Needed for serialization.
+ */
+ private int family;
+
+ /**
+ * Constructor. Prior to the introduction of IPv6 support in 1.4,
+ * methods such as InetAddress.getByName() would return InetAddress
+ * objects. From 1.4 such methods returned either Inet4Address or
+ * Inet6Address objects, but for compatibility Inet4Address objects
+ * are serialized as InetAddresses. As such, there are only two
+ * places where it is appropriate to invoke this constructor: within
+ * subclasses constructors and within Inet4Address.writeReplace().
+ *
+ * @param ipaddr The IP number of this address as an array of bytes
+ * @param hostname The hostname of this IP address.
+ * @param family The address family of this IP address.
+ */
+ InetAddress(byte[] ipaddr, String hostname, int family)
+ {
+ addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
+ hostName = hostname;
+ this.family = family;
+ }
+
+ /**
+ * Returns true if this address is a multicast address, false otherwise.
+ * An address is multicast if the high four bits are "1110". These are
+ * also known as "Class D" addresses.
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @return true if mulitcast, false if not
+ *
+ * @since 1.1
+ */
+ public boolean isMulticastAddress()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMulticastAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if the InetAddress in a wildcard address
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isAnyLocalAddress()
+ {
+ // This is inefficient, but certain methods on Win32 create
+ // InetAddress objects using "new InetAddress" rather than
+ // "InetAddress.getByAddress" so we provide a method body.
+ // This code is never executed on Posix systems.
+ try
+ {
+ return getByAddress(hostName, addr).isAnyLocalAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is a loopback address
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isLoopbackAddress()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isLoopbackAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if InetAddress is a link local address
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isLinkLocalAddress()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isLinkLocalAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if InetAddress is a site local address
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isSiteLocalAddress()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isSiteLocalAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if InetAddress is a global multicast address
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isMCGlobal()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCGlobal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if InetAddress is a node local multicast address.
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isMCNodeLocal()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCNodeLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if InetAddress is a link local multicast address.
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isMCLinkLocal()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCLinkLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if InetAddress is a site local multicast address.
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isMCSiteLocal()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCSiteLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Utility routine to check if InetAddress is a organization local
+ * multicast address.
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @since 1.4
+ */
+ public boolean isMCOrgLocal()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).isMCOrgLocal();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Returns the hostname for this address. This will return the IP address
+ * as a String if there is no hostname available for this address
+ *
+ * @return The hostname for this address
+ */
+ public String getHostName()
+ {
+ if (hostName == null)
+ hostName = getCanonicalHostName();
+
+ return hostName;
+ }
+
+ /**
+ * Returns the canonical hostname represented by this InetAddress
+ */
+ String internalGetCanonicalHostName()
+ {
+ try
+ {
+ return ResolverCache.getHostByAddr(addr);
+ }
+ catch (UnknownHostException e)
+ {
+ return getHostAddress();
+ }
+ }
+
+ /**
+ * Returns the canonical hostname represented by this InetAddress
+ *
+ * @since 1.4
+ */
+ public String getCanonicalHostName()
+ {
+ String hostname = internalGetCanonicalHostName();
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ try
+ {
+ sm.checkConnect(hostname, -1);
+ }
+ catch (SecurityException e)
+ {
+ return getHostAddress();
+ }
+ }
+
+ return hostname;
+ }
+
+ /**
+ * Returns the IP address of this object as a byte array.
+ *
+ * @return IP address
+ */
+ public byte[] getAddress()
+ {
+ // An experiment shows that JDK1.2 returns a different byte array each
+ // time. This makes sense, in terms of security.
+ return (byte[]) addr.clone();
+ }
+
+ /**
+ * Returns the IP address of this object as a String.
+ *
+ * <p>This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.</p>
+ *
+ * @return The IP address of this object in String form
+ *
+ * @since 1.0.2
+ */
+ public String getHostAddress()
+ {
+ // This method is masked on Posix systems, where all InetAddress
+ // objects are created using InetAddress.getByAddress() which
+ // returns either Inet4Address or Inet6Address objects. Certain
+ // native methods on Win32 use "new InetAddress" in which case
+ // this method will be visible.
+ try
+ {
+ return getByAddress(hostName, addr).getHostAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Returns a hash value for this address. Useful for creating hash
+ * tables. Overrides Object.hashCode()
+ *
+ * @return A hash value for this address.
+ */
+ public int hashCode()
+ {
+ // There hashing algorithm is not specified, but a simple experiment
+ // shows that it is equal to the address, as a 32-bit big-endian integer.
+ int hash = 0;
+ int len = addr.length;
+ int i = len > 4 ? len - 4 : 0;
+
+ for (; i < len; i++)
+ hash = (hash << 8) | (addr[i] & 0xff);
+
+ return hash;
+ }
+
+ /**
+ * Tests this address for equality against another InetAddress. The two
+ * addresses are considered equal if they contain the exact same octets.
+ * This implementation overrides Object.equals()
+ *
+ * @param obj The address to test for equality
+ *
+ * @return true if the passed in object's address is equal to this one's,
+ * false otherwise
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof InetAddress))
+ return false;
+
+ // "The Java Class Libraries" 2nd edition says "If a machine has
+ // multiple names instances of InetAddress for different name of
+ // that same machine are not equal. This is because they have
+ // different host names." This violates the description in the
+ // JDK 1.2 API documentation. A little experimentation
+ // shows that the latter is correct.
+ byte[] addr2 = ((InetAddress) obj).addr;
+
+ if (addr.length != addr2.length)
+ return false;
+
+ for (int i = 0; i < addr.length; i++)
+ if (addr[i] != addr2[i])
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Converts this address to a String. This string contains the IP in
+ * dotted decimal form. For example: "127.0.0.1" This method is equivalent
+ * to getHostAddress() and overrides Object.toString()
+ *
+ * @return This address in String form
+ */
+ public String toString()
+ {
+ String addr = getHostAddress();
+ String host = (hostName != null) ? hostName : "";
+ return host + "/" + addr;
+ }
+
+ /**
+ * Returns an InetAddress object given the raw IP address.
+ *
+ * The argument is in network byte order: the highest order byte of the
+ * address is in getAddress()[0].
+ *
+ * @param addr The IP address to create the InetAddress object from
+ *
+ * @exception UnknownHostException If IP address has illegal length
+ *
+ * @since 1.4
+ */
+ public static InetAddress getByAddress(byte[] addr)
+ throws UnknownHostException
+ {
+ return getByAddress(null, addr);
+ }
+
+ /**
+ * Creates an InetAddress based on the provided host name and IP address.
+ * No name service is checked for the validity of the address.
+ *
+ * @param host The hostname of the InetAddress object to create
+ * @param addr The IP address to create the InetAddress object from
+ *
+ * @exception UnknownHostException If IP address is of illegal length
+ *
+ * @since 1.4
+ */
+ public static InetAddress getByAddress(String host, byte[] addr)
+ throws UnknownHostException
+ {
+ if (addr.length == 4)
+ return new Inet4Address(addr, host);
+
+ if (addr.length == 16)
+ {
+ for (int i = 0; i < 12; i++)
+ {
+ if (addr[i] != (i < 10 ? 0 : (byte) 0xFF))
+ return new Inet6Address(addr, host);
+ }
+
+ byte[] ip4addr = new byte[4];
+ ip4addr[0] = addr[12];
+ ip4addr[1] = addr[13];
+ ip4addr[2] = addr[14];
+ ip4addr[3] = addr[15];
+ return new Inet4Address(ip4addr, host);
+ }
+
+ throw new UnknownHostException("IP address has illegal length");
+ }
+
+ /**
+ * Returns an InetAddress object representing the IP address of
+ * the given literal IP address in dotted decimal format such as
+ * "127.0.0.1". This is used by SocketPermission.setHostPort()
+ * to parse literal IP addresses without performing a DNS lookup.
+ *
+ * @param literal The literal IP address to create the InetAddress
+ * object from
+ *
+ * @return The address of the host as an InetAddress object, or
+ * null if the IP address is invalid.
+ */
+ static InetAddress getByLiteral(String literal)
+ {
+ byte[] address = VMInetAddress.aton(literal);
+ if (address == null)
+ return null;
+
+ try
+ {
+ return getByAddress(address);
+ }
+ catch (UnknownHostException e)
+ {
+ throw new RuntimeException("should never happen", e);
+ }
+ }
+
+ /**
+ * Returns an InetAddress object representing the IP address of the given
+ * hostname. This name can be either a hostname such as "www.urbanophile.com"
+ * or an IP address in dotted decimal format such as "127.0.0.1". If the
+ * hostname is null or "", the hostname of the local machine is supplied by
+ * default. This method is equivalent to returning the first element in
+ * the InetAddress array returned from GetAllByName.
+ *
+ * @param hostname The name of the desired host, or null for the local
+ * loopback address.
+ *
+ * @return The address of the host as an InetAddress object.
+ *
+ * @exception UnknownHostException If no IP address for the host could
+ * be found
+ * @exception SecurityException If a security manager exists and its
+ * checkConnect method doesn't allow the operation
+ */
+ public static InetAddress getByName(String hostname)
+ throws UnknownHostException
+ {
+ InetAddress[] addresses = getAllByName(hostname);
+ return addresses[0];
+ }
+
+ /**
+ * Returns an array of InetAddress objects representing all the host/ip
+ * addresses of a given host, given the host's name. This name can be
+ * either a hostname such as "www.urbanophile.com" or an IP address in
+ * dotted decimal format such as "127.0.0.1". If the value is null, the
+ * hostname of the local machine is supplied by default.
+ *
+ * @param hostname The name of the desired host, or null for the
+ * local loopback address.
+ *
+ * @return All addresses of the host as an array of InetAddress objects.
+ *
+ * @exception UnknownHostException If no IP address for the host could
+ * be found
+ * @exception SecurityException If a security manager exists and its
+ * checkConnect method doesn't allow the operation
+ */
+ public static InetAddress[] getAllByName(String hostname)
+ throws UnknownHostException
+ {
+ // If null or the empty string is supplied, the loopback address
+ // is returned.
+ if (hostname == null || hostname.length() == 0)
+ return new InetAddress[] {LOCALHOST};
+
+ // Check if hostname is an IP address
+ InetAddress address = getByLiteral(hostname);
+ if (address != null)
+ return new InetAddress[] {address};
+
+ // Perform security check before resolving
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(hostname, -1);
+
+ // Resolve the hostname
+ byte[][] iplist = ResolverCache.getHostByName(hostname);
+ if (iplist.length == 0)
+ throw new UnknownHostException(hostname);
+
+ InetAddress[] addresses = new InetAddress[iplist.length];
+ for (int i = 0; i < iplist.length; i++)
+ addresses[i] = getByAddress(hostname, iplist[i]);
+
+ return addresses;
+ }
+
+ /**
+ * Returns an InetAddress object representing the address of the current
+ * host.
+ *
+ * @return The local host's address
+ *
+ * @exception UnknownHostException If no IP address for the host could
+ * be found
+ */
+ public static InetAddress getLocalHost() throws UnknownHostException
+ {
+ String hostname = VMInetAddress.getLocalHostname();
+ try
+ {
+ return getByName(hostname);
+ }
+ catch (SecurityException e)
+ {
+ return LOCALHOST;
+ }
+ }
+
+ /**
+ * Inet4Address objects are serialized as InetAddress objects.
+ * This deserializes them back into Inet4Address objects.
+ */
+ private Object readResolve() throws ObjectStreamException
+ {
+ return new Inet4Address(addr, hostName);
+ }
+
+ private void readObject(ObjectInputStream ois)
+ throws IOException, ClassNotFoundException
+ {
+ ois.defaultReadObject();
+ addr = new byte[4];
+ addr[3] = (byte) address;
+
+ for (int i = 2; i >= 0; --i)
+ addr[i] = (byte) (address >>= 8);
+ }
+
+ private void writeObject(ObjectOutputStream oos) throws IOException
+ {
+ // Build a 32 bit address from the last 4 bytes of a 4 byte IPv4 address
+ // or a 16 byte IPv6 address.
+ int len = addr.length;
+ int i = len - 4;
+
+ for (; i < len; i++)
+ address = address << 8 | (addr[i] & 0xff);
+
+ oos.defaultWriteObject();
+ }
+
+ // The native methods remain here for now;
+ // methods in VMInetAddress map onto them.
+ static native byte[] aton(String hostname);
+ static native InetAddress[] lookup (String hostname,
+ InetAddress ipaddr, boolean all);
+ static native int getFamily (byte[] ipaddr);
+ static native String getLocalHostname();
+
+ // Some soon-to-be-removed native code synchronizes on this.
+ static InetAddress loopbackAddress;
+
+ // Some soon-to-be-removed code uses this old and broken method.
+ InetAddress(byte[] ipaddr, String hostname)
+ {
+ addr = (null == ipaddr) ? null : (byte[]) ipaddr.clone();
+ hostName = hostname;
+
+ if (ipaddr != null)
+ family = getFamily(ipaddr);
+ }
+
+ // Some soon-to-be-removed native code uses these old methods.
+ private static InetAddress[] allocArray (int count)
+ {
+ return new InetAddress [count];
+ }
+ private static SecurityException checkConnect (String hostname)
+ {
+ return null;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/net/URL.java b/gcc-4.2.1/libjava/java/net/URL.java
new file mode 100644
index 000000000..0ae7c1cfb
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/URL.java
@@ -0,0 +1,974 @@
+/* URL.java -- Uniform Resource Locator Class
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 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.net;
+
+import gnu.java.net.URLParseError;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This final class represents an Internet Uniform Resource Locator (URL).
+ * For details on the syntax of URL's and what they can be used for,
+ * refer to RFC 1738, available from <a
+ * href="http://ds.internic.net/rfcs/rfc1738.txt">
+ * http://ds.internic.net/rfcs/rfc1738.txt</a>
+ * <p>
+ * There are a great many protocols supported by URL's such as "http",
+ * "ftp", and "file". This object can handle any arbitrary URL for which
+ * a URLStreamHandler object can be written. Default protocol handlers
+ * are provided for the "http" and "ftp" protocols. Additional protocols
+ * handler implementations may be provided in the future. In any case,
+ * an application or applet can install its own protocol handlers that
+ * can be "chained" with other protocol hanlders in the system to extend
+ * the base functionality provided with this class. (Note, however, that
+ * unsigned applets cannot access properties by default or install their
+ * own protocol handlers).
+ * <p>
+ * This chaining is done via the system property java.protocol.handler.pkgs
+ * If this property is set, it is assumed to be a "|" separated list of
+ * package names in which to attempt locating protocol handlers. The
+ * protocol handler is searched for by appending the string
+ * ".&lt;protocol&gt;.Handler" to each packed in the list until a hander is
+ * found. If a protocol handler is not found in this list of packages, or if
+ * the property does not exist, then the default protocol handler of
+ * "gnu.java.net.&lt;protocol&gt;.Handler" is tried. If this is
+ * unsuccessful, a MalformedURLException is thrown.
+ * <p>
+ * All of the constructor methods of URL attempt to load a protocol
+ * handler and so any needed protocol handlers must be installed when
+ * the URL is constructed.
+ * <p>
+ * Here is an example of how URL searches for protocol handlers. Assume
+ * the value of java.protocol.handler.pkgs is "com.foo|com.bar" and the
+ * URL is "news://comp.lang.java.programmer". URL would looking the
+ * following places for protocol handlers:
+ * <p><pre>
+ * com.foo.news.Handler
+ * com.bar.news.Handler
+ * gnu.java.net.news.Handler
+ * </pre><p>
+ * If the protocol handler is not found in any of those locations, a
+ * MalformedURLException would be thrown.
+ * <p>
+ * Please note that a protocol handler must be a subclass of
+ * URLStreamHandler.
+ * <p>
+ * Normally, this class caches protocol handlers. Once it finds a handler
+ * for a particular protocol, it never tries to look up a new handler
+ * again. However, if the system property
+ * gnu.java.net.nocache_protocol_handlers is set, then this
+ * caching behavior is disabled. This property is specific to this
+ * implementation. Sun's JDK may or may not do protocol caching, but it
+ * almost certainly does not examine this property.
+ * <p>
+ * Please also note that an application can install its own factory for
+ * loading protocol handlers (see setURLStreamHandlerFactory). If this is
+ * done, then the above information is superseded and the behavior of this
+ * class in loading protocol handlers is dependent on that factory.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ *
+ * @see URLStreamHandler
+ */
+public final class URL implements Serializable
+{
+ private static final String DEFAULT_SEARCH_PATH =
+ "gnu.java.net.protocol|gnu.inet";
+
+ // Cached System ClassLoader
+ private static ClassLoader systemClassLoader;
+
+ /**
+ * The name of the protocol for this URL.
+ * The protocol is always stored in lower case.
+ */
+ private String protocol;
+
+ /**
+ * The "authority" portion of the URL.
+ */
+ private String authority;
+
+ /**
+ * The hostname or IP address of this protocol.
+ * This includes a possible user. For example <code>joe@some.host.net</code>.
+ */
+ private String host;
+
+ /**
+ * The user information necessary to establish the connection.
+ */
+ private String userInfo;
+
+ /**
+ * The port number of this protocol or -1 if the port number used is
+ * the default for this protocol.
+ */
+ private int port = -1; // Initialize for constructor using context.
+
+ /**
+ * The "file" portion of the URL. It is defined as <code>path[?query]</code>.
+ */
+ private String file;
+
+ /**
+ * The anchor portion of the URL.
+ */
+ private String ref;
+
+ /**
+ * This is the hashCode for this URL
+ */
+ private int hashCode;
+
+ /**
+ * The protocol handler in use for this URL
+ */
+ transient URLStreamHandler ph;
+
+ /**
+ * If an application installs its own protocol handler factory, this is
+ * where we keep track of it.
+ */
+ private static URLStreamHandlerFactory factory;
+ private static final long serialVersionUID = -7627629688361524110L;
+
+ /**
+ * This a table where we cache protocol handlers to avoid the overhead
+ * of looking them up each time.
+ */
+ private static HashMap ph_cache = new HashMap();
+
+ /**
+ * Whether or not to cache protocol handlers.
+ */
+ private static boolean cache_handlers;
+
+ static
+ {
+ String s = System.getProperty("gnu.java.net.nocache_protocol_handlers");
+
+ if (s == null)
+ cache_handlers = true;
+ else
+ cache_handlers = false;
+ }
+
+ /**
+ * Constructs a URL and loads a protocol handler for the values passed as
+ * arguments.
+ *
+ * @param protocol The protocol for this URL ("http", "ftp", etc)
+ * @param host The hostname or IP address to connect to
+ * @param port The port number to use, or -1 to use the protocol's
+ * default port
+ * @param file The "file" portion of the URL.
+ *
+ * @exception MalformedURLException If a protocol handler cannot be loaded or
+ * a parse error occurs.
+ */
+ public URL(String protocol, String host, int port, String file)
+ throws MalformedURLException
+ {
+ this(protocol, host, port, file, null);
+ }
+
+ /**
+ * Constructs a URL and loads a protocol handler for the values passed in
+ * as arugments. Uses the default port for the protocol.
+ *
+ * @param protocol The protocol for this URL ("http", "ftp", etc)
+ * @param host The hostname or IP address for this URL
+ * @param file The "file" portion of this URL.
+ *
+ * @exception MalformedURLException If a protocol handler cannot be loaded or
+ * a parse error occurs.
+ */
+ public URL(String protocol, String host, String file)
+ throws MalformedURLException
+ {
+ this(protocol, host, -1, file, null);
+ }
+
+ /**
+ * This method initializes a new instance of <code>URL</code> with the
+ * specified protocol, host, port, and file. Additionally, this method
+ * allows the caller to specify a protocol handler to use instead of
+ * the default. If this handler is specified, the caller must have
+ * the "specifyStreamHandler" permission (see <code>NetPermission</code>)
+ * or a <code>SecurityException</code> will be thrown.
+ *
+ * @param protocol The protocol for this URL ("http", "ftp", etc)
+ * @param host The hostname or IP address to connect to
+ * @param port The port number to use, or -1 to use the protocol's default
+ * port
+ * @param file The "file" portion of the URL.
+ * @param ph The protocol handler to use with this URL.
+ *
+ * @exception MalformedURLException If no protocol handler can be loaded
+ * for the specified protocol.
+ * @exception SecurityException If the <code>SecurityManager</code> exists
+ * and does not allow the caller to specify its own protocol handler.
+ *
+ * @since 1.2
+ */
+ public URL(String protocol, String host, int port, String file,
+ URLStreamHandler ph) throws MalformedURLException
+ {
+ if (protocol == null)
+ throw new MalformedURLException("null protocol");
+ protocol = protocol.toLowerCase();
+ this.protocol = protocol;
+
+ if (ph != null)
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkPermission(new NetPermission("specifyStreamHandler"));
+
+ this.ph = ph;
+ }
+ else
+ this.ph = getURLStreamHandler(protocol);
+
+ if (this.ph == null)
+ throw new MalformedURLException("Protocol handler not found: "
+ + protocol);
+
+ this.host = host;
+ this.port = port;
+ this.authority = (host != null) ? host : "";
+ if (port >= 0 && host != null)
+ this.authority += ":" + port;
+
+ int hashAt = file.indexOf('#');
+ if (hashAt < 0)
+ {
+ this.file = file;
+ this.ref = null;
+ }
+ else
+ {
+ this.file = file.substring(0, hashAt);
+ this.ref = file.substring(hashAt + 1);
+ }
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Initializes a URL from a complete string specification such as
+ * "http://www.urbanophile.com/arenn/". First the protocol name is parsed
+ * out of the string. Then a handler is located for that protocol and
+ * the parseURL() method of that protocol handler is used to parse the
+ * remaining fields.
+ *
+ * @param spec The complete String representation of a URL
+ *
+ * @exception MalformedURLException If a protocol handler cannot be found
+ * or the URL cannot be parsed
+ */
+ public URL(String spec) throws MalformedURLException
+ {
+ this((URL) null, spec != null ? spec : "", (URLStreamHandler) null);
+ }
+
+ /**
+ * This method parses a String representation of a URL within the
+ * context of an existing URL. Principally this means that any
+ * fields not present the URL are inheritied from the context URL.
+ * This allows relative URL's to be easily constructed. If the
+ * context argument is null, then a complete URL must be specified
+ * in the URL string. If the protocol parsed out of the URL is
+ * different from the context URL's protocol, then then URL String
+ * is also expected to be a complete URL.
+ *
+ * @param context The context on which to parse the specification
+ * @param spec The string to parse an URL
+ *
+ * @exception MalformedURLException If a protocol handler cannot be found
+ * for the URL cannot be parsed
+ */
+ public URL(URL context, String spec) throws MalformedURLException
+ {
+ this(context, spec, (URLStreamHandler) null);
+ }
+
+ /**
+ * Creates an URL from given arguments
+ * This method parses a String representation of a URL within the
+ * context of an existing URL. Principally this means that any fields
+ * not present the URL are inheritied from the context URL. This allows
+ * relative URL's to be easily constructed. If the context argument is
+ * null, then a complete URL must be specified in the URL string.
+ * If the protocol parsed out of the URL is different
+ * from the context URL's protocol, then then URL String is also
+ * expected to be a complete URL.
+ * <p>
+ * Additionally, this method allows the caller to specify a protocol handler
+ * to use instead of the default. If this handler is specified, the caller
+ * must have the "specifyStreamHandler" permission
+ * (see <code>NetPermission</code>) or a <code>SecurityException</code>
+ * will be thrown.
+ *
+ * @param context The context in which to parse the specification
+ * @param spec The string to parse as an URL
+ * @param ph The stream handler for the URL
+ *
+ * @exception MalformedURLException If a protocol handler cannot be found
+ * or the URL cannot be parsed
+ * @exception SecurityException If the <code>SecurityManager</code> exists
+ * and does not allow the caller to specify its own protocol handler.
+ *
+ * @since 1.2
+ */
+ public URL(URL context, String spec, URLStreamHandler ph)
+ throws MalformedURLException
+ {
+ /* A protocol is defined by the doc as the substring before a ':'
+ * as long as the ':' occurs before any '/'.
+ *
+ * If context is null, then spec must be an absolute URL.
+ *
+ * The relative URL need not specify all the components of a URL.
+ * If the protocol, host name, or port number is missing, the value
+ * is inherited from the context. A bare file component is appended
+ * to the context's file. The optional anchor is not inherited.
+ */
+
+ // If this is an absolute URL, then ignore context completely.
+ // An absolute URL must have chars prior to "://" but cannot have a colon
+ // right after the "://". The second colon is for an optional port value
+ // and implies that the host from the context is used if available.
+ int colon;
+ int slash = spec.indexOf('/');
+ if ((colon = spec.indexOf("://", 1)) > 0
+ && ((colon < slash || slash < 0))
+ && ! spec.regionMatches(colon, "://:", 0, 4))
+ context = null;
+
+ if ((colon = spec.indexOf(':')) > 0
+ && (colon < slash || slash < 0))
+ {
+ // Protocol specified in spec string.
+ protocol = spec.substring(0, colon).toLowerCase();
+ if (context != null && context.protocol.equals(protocol))
+ {
+ // The 1.2 doc specifically says these are copied to the new URL.
+ host = context.host;
+ port = context.port;
+ userInfo = context.userInfo;
+ authority = context.authority;
+ }
+ }
+ else if (context != null)
+ {
+ // Protocol NOT specified in spec string.
+ // Use context fields (except ref) as a foundation for relative URLs.
+ colon = -1;
+ protocol = context.protocol;
+ host = context.host;
+ port = context.port;
+ userInfo = context.userInfo;
+ if (spec.indexOf(":/", 1) < 0)
+ {
+ file = context.file;
+ if (file == null || file.length() == 0)
+ file = "/";
+ }
+ authority = context.authority;
+ }
+ else // Protocol NOT specified in spec. and no context available.
+ throw new MalformedURLException("Absolute URL required with null"
+ + " context: " + spec);
+
+ protocol = protocol.trim();
+
+ if (ph != null)
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkPermission(new NetPermission("specifyStreamHandler"));
+
+ this.ph = ph;
+ }
+ else
+ this.ph = getURLStreamHandler(protocol);
+
+ if (this.ph == null)
+ throw new MalformedURLException("Protocol handler not found: "
+ + protocol);
+
+ // JDK 1.2 doc for parseURL specifically states that any '#' ref
+ // is to be excluded by passing the 'limit' as the indexOf the '#'
+ // if one exists, otherwise pass the end of the string.
+ int hashAt = spec.indexOf('#', colon + 1);
+
+ try
+ {
+ this.ph.parseURL(this, spec, colon + 1,
+ hashAt < 0 ? spec.length() : hashAt);
+ }
+ catch (URLParseError e)
+ {
+ throw new MalformedURLException(e.getMessage());
+ }
+
+ if (hashAt >= 0)
+ ref = spec.substring(hashAt + 1);
+
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Test another URL for equality with this one. This will be true only if
+ * the argument is non-null and all of the fields in the URL's match
+ * exactly (ie, protocol, host, port, file, and ref). Overrides
+ * Object.equals(), implemented by calling the equals method of the handler.
+ *
+ * @param obj The URL to compare with
+ *
+ * @return true if the URL is equal, false otherwise
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof URL))
+ return false;
+
+ return ph.equals(this, (URL) obj);
+ }
+
+ /**
+ * Returns the contents of this URL as an object by first opening a
+ * connection, then calling the getContent() method against the connection
+ *
+ * @return A content object for this URL
+ * @exception IOException If opening the connection or getting the
+ * content fails.
+ *
+ * @since 1.3
+ */
+ public Object getContent() throws IOException
+ {
+ return openConnection().getContent();
+ }
+
+ /**
+ * Gets the contents of this URL
+ *
+ * @param classes The allow classes for the content object.
+ *
+ * @return a context object for this URL.
+ *
+ * @exception IOException If an error occurs
+ */
+ public Object getContent(Class[] classes) throws IOException
+ {
+ // FIXME: implement this
+ return getContent();
+ }
+
+ /**
+ * Returns the file portion of the URL.
+ * Defined as <code>path[?query]</code>.
+ * Returns the empty string if there is no file portion.
+ *
+ * @return The filename specified in this URL, or an empty string if empty.
+ */
+ public String getFile()
+ {
+ return file == null ? "" : file;
+ }
+
+ /**
+ * Returns the path of the URL. This is the part of the file before any '?'
+ * character.
+ *
+ * @return The path specified in this URL, or null if empty.
+ *
+ * @since 1.3
+ */
+ public String getPath()
+ {
+ // The spec says we need to return an empty string, but some
+ // applications depends on receiving null when the path is empty.
+ if (file == null)
+ return null;
+ int quest = file.indexOf('?');
+ return quest < 0 ? getFile() : file.substring(0, quest);
+ }
+
+ /**
+ * Returns the authority of the URL
+ *
+ * @return The authority specified in this URL.
+ *
+ * @since 1.3
+ */
+ public String getAuthority()
+ {
+ return authority;
+ }
+
+ /**
+ * Returns the host of the URL
+ *
+ * @return The host specified in this URL.
+ */
+ public String getHost()
+ {
+ int at = (host == null) ? -1 : host.indexOf('@');
+ return at < 0 ? host : host.substring(at + 1, host.length());
+ }
+
+ /**
+ * Returns the port number of this URL or -1 if the default port number is
+ * being used.
+ *
+ * @return The port number
+ *
+ * @see #getDefaultPort()
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Returns the default port of the URL. If the StreamHandler for the URL
+ * protocol does not define a default port it returns -1.
+ *
+ * @return The default port of the current protocol.
+ */
+ public int getDefaultPort()
+ {
+ return ph.getDefaultPort();
+ }
+
+ /**
+ * Returns the protocol of the URL
+ *
+ * @return The specified protocol.
+ */
+ public String getProtocol()
+ {
+ return protocol;
+ }
+
+ /**
+ * Returns the ref (sometimes called the "# reference" or "anchor") portion
+ * of the URL.
+ *
+ * @return The ref
+ */
+ public String getRef()
+ {
+ return ref;
+ }
+
+ /**
+ * Returns the user information of the URL. This is the part of the host
+ * name before the '@'.
+ *
+ * @return the user at a particular host or null when no user defined.
+ */
+ public String getUserInfo()
+ {
+ if (userInfo != null)
+ return userInfo;
+ int at = (host == null) ? -1 : host.indexOf('@');
+ return at < 0 ? null : host.substring(0, at);
+ }
+
+ /**
+ * Returns the query of the URL. This is the part of the file before the
+ * '?'.
+ *
+ * @return the query part of the file, or null when there is no query part.
+ */
+ public String getQuery()
+ {
+ int quest = (file == null) ? -1 : file.indexOf('?');
+ return quest < 0 ? null : file.substring(quest + 1, file.length());
+ }
+
+ /**
+ * Returns a hashcode computed by the URLStreamHandler of this URL
+ *
+ * @return The hashcode for this URL.
+ */
+ public int hashCode()
+ {
+ if (hashCode != 0)
+ return hashCode; // Use cached value if available.
+ else
+ return ph.hashCode(this);
+ }
+
+ /**
+ * Returns a URLConnection object that represents a connection to the remote
+ * object referred to by the URL. The URLConnection is created by calling the
+ * openConnection() method of the protocol handler
+ *
+ * @return A URLConnection for this URL
+ *
+ * @exception IOException If an error occurs
+ */
+ public URLConnection openConnection() throws IOException
+ {
+ return ph.openConnection(this);
+ }
+
+ /**
+ * Opens a connection to this URL and returns an InputStream for reading
+ * from that connection
+ *
+ * @return An <code>InputStream</code> for this URL.
+ *
+ * @exception IOException If an error occurs
+ */
+ public InputStream openStream() throws IOException
+ {
+ return openConnection().getInputStream();
+ }
+
+ /**
+ * Tests whether or not another URL refers to the same "file" as this one.
+ * This will be true if and only if the passed object is not null, is a
+ * URL, and matches all fields but the ref (ie, protocol, host, port,
+ * and file);
+ *
+ * @param url The URL object to test with
+ *
+ * @return true if URL matches this URL's file, false otherwise
+ */
+ public boolean sameFile(URL url)
+ {
+ return ph.sameFile(this, url);
+ }
+
+ /**
+ * Sets the specified fields of the URL. This is not a public method so
+ * that only URLStreamHandlers can modify URL fields. This might be called
+ * by the <code>parseURL()</code> method in that class. URLs are otherwise
+ * constant. If the given protocol does not exist, it will keep the previously
+ * set protocol.
+ *
+ * @param protocol The protocol name for this URL
+ * @param host The hostname or IP address for this URL
+ * @param port The port number of this URL
+ * @param file The "file" portion of this URL.
+ * @param ref The anchor portion of this URL.
+ */
+ protected void set(String protocol, String host, int port, String file,
+ String ref)
+ {
+ URLStreamHandler protocolHandler = null;
+ protocol = protocol.toLowerCase();
+ if (! this.protocol.equals(protocol))
+ protocolHandler = getURLStreamHandler(protocol);
+
+ // It is an hidden feature of the JDK. If the protocol does not exist,
+ // we keep the previously initialized protocol.
+ if (protocolHandler != null)
+ {
+ this.ph = protocolHandler;
+ this.protocol = protocol;
+ }
+ this.authority = "";
+ this.port = port;
+ this.host = host;
+ this.file = file;
+ this.ref = ref;
+
+ if (host != null)
+ this.authority += host;
+ if (port >= 0)
+ this.authority += ":" + port;
+
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Sets the specified fields of the URL. This is not a public method so
+ * that only URLStreamHandlers can modify URL fields. URLs are otherwise
+ * constant. If the given protocol does not exist, it will keep the previously
+ * set protocol.
+ *
+ * @param protocol The protocol name for this URL.
+ * @param host The hostname or IP address for this URL.
+ * @param port The port number of this URL.
+ * @param authority The authority of this URL.
+ * @param userInfo The user and password (if needed) of this URL.
+ * @param path The "path" portion of this URL.
+ * @param query The query of this URL.
+ * @param ref The anchor portion of this URL.
+ *
+ * @since 1.3
+ */
+ protected void set(String protocol, String host, int port, String authority,
+ String userInfo, String path, String query, String ref)
+ {
+ URLStreamHandler protocolHandler = null;
+ protocol = protocol.toLowerCase();
+ if (! this.protocol.equals(protocol))
+ protocolHandler = getURLStreamHandler(protocol);
+
+ // It is an hidden feature of the JDK. If the protocol does not exist,
+ // we keep the previously initialized protocol.
+ if (protocolHandler != null)
+ {
+ this.ph = protocolHandler;
+ this.protocol = protocol;
+ }
+ this.host = host;
+ this.userInfo = userInfo;
+ this.port = port;
+ this.authority = authority;
+ if (query == null)
+ this.file = path;
+ else
+ this.file = path + "?" + query;
+ this.ref = ref;
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Sets the URLStreamHandlerFactory for this class. This factory is
+ * responsible for returning the appropriate protocol handler for
+ * a given URL.
+ *
+ * @param fac The URLStreamHandlerFactory class to use
+ *
+ * @exception Error If the factory is alread set.
+ * @exception SecurityException If a security manager exists and its
+ * checkSetFactory method doesn't allow the operation
+ */
+ public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
+ {
+ if (factory != null)
+ throw new Error("URLStreamHandlerFactory already set");
+
+ // Throw an exception if an extant security mgr precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+ factory = fac;
+ }
+
+ /**
+ * Returns a String representing this URL. The String returned is
+ * created by calling the protocol handler's toExternalForm() method.
+ *
+ * @return A string for this URL
+ */
+ public String toExternalForm()
+ {
+ // Identical to toString().
+ return ph.toExternalForm(this);
+ }
+
+ /**
+ * Returns a String representing this URL. Identical to toExternalForm().
+ * The value returned is created by the protocol handler's
+ * toExternalForm method. Overrides Object.toString()
+ *
+ * @return A string for this URL
+ */
+ public String toString()
+ {
+ // Identical to toExternalForm().
+ return ph.toExternalForm(this);
+ }
+
+ /**
+ * This internal method is used in two different constructors to load
+ * a protocol handler for this URL.
+ *
+ * @param protocol The protocol to load a handler for
+ *
+ * @return A URLStreamHandler for this protocol, or null when not found.
+ */
+ private static synchronized URLStreamHandler getURLStreamHandler(String protocol)
+ {
+ URLStreamHandler ph = null;
+
+ // First, see if a protocol handler is in our cache.
+ if (cache_handlers)
+ {
+ if ((ph = (URLStreamHandler) ph_cache.get(protocol)) != null)
+ return ph;
+ }
+
+ // If a non-default factory has been set, use it to find the protocol.
+ if (factory != null)
+ {
+ ph = factory.createURLStreamHandler(protocol);
+ }
+ else if (protocol.equals("core"))
+ {
+ ph = new gnu.java.net.protocol.core.Handler();
+ }
+ else if (protocol.equals("file"))
+ {
+ // This is an interesting case. It's tempting to think that we
+ // could call Class.forName ("gnu.java.net.protocol.file.Handler") to
+ // get the appropriate class. Unfortunately, if we do that the
+ // program will never terminate, because getURLStreamHandler is
+ // eventually called by Class.forName.
+ //
+ // Treating "file" as a special case is the minimum that will
+ // fix this problem. If other protocols are required in a
+ // statically linked application they will need to be handled in
+ // the same way as "file".
+ ph = new gnu.java.net.protocol.file.Handler();
+ }
+
+ // Non-default factory may have returned null or a factory wasn't set.
+ // Use the default search algorithm to find a handler for this protocol.
+ if (ph == null)
+ {
+ // Get the list of packages to check and append our default handler
+ // to it, along with the JDK specified default as a last resort.
+ // Except in very unusual environments the JDK specified one shouldn't
+ // ever be needed (or available).
+ String ph_search_path =
+ System.getProperty("java.protocol.handler.pkgs");
+
+ // Tack our default package on at the ends.
+ if (ph_search_path != null)
+ ph_search_path += "|" + DEFAULT_SEARCH_PATH;
+ else
+ ph_search_path = DEFAULT_SEARCH_PATH;
+
+ // Finally loop through our search path looking for a match.
+ StringTokenizer pkgPrefix = new StringTokenizer(ph_search_path, "|");
+
+ // Cache the systemClassLoader
+ if (systemClassLoader == null)
+ {
+ systemClassLoader = (ClassLoader) AccessController.doPrivileged
+ (new PrivilegedAction() {
+ public Object run()
+ {
+ return ClassLoader.getSystemClassLoader();
+ }
+ });
+ }
+
+ do
+ {
+ try
+ {
+ // Try to get a class from the system/application
+ // classloader, initialize it, make an instance
+ // and try to cast it to a URLStreamHandler.
+ String clsName =
+ (pkgPrefix.nextToken() + "." + protocol + ".Handler");
+ Class c = Class.forName(clsName, true, systemClassLoader);
+ ph = (URLStreamHandler) c.newInstance();
+ }
+ catch (ThreadDeath death)
+ {
+ throw death;
+ }
+ catch (Throwable t)
+ {
+ // Ignored.
+ }
+ }
+ while (ph == null && pkgPrefix.hasMoreTokens());
+ }
+
+ // Update the hashtable with the new protocol handler.
+ if (ph != null && cache_handlers)
+ ph_cache.put(protocol, ph);
+ else
+ ph = null;
+
+ return ph;
+ }
+
+ private void readObject(ObjectInputStream ois)
+ throws IOException, ClassNotFoundException
+ {
+ ois.defaultReadObject();
+ this.ph = getURLStreamHandler(protocol);
+ if (this.ph == null)
+ throw new IOException("Handler for protocol " + protocol + " not found");
+ }
+
+ private void writeObject(ObjectOutputStream oos) throws IOException
+ {
+ oos.defaultWriteObject();
+ }
+
+ /**
+ * Returns the equivalent <code>URI</code> object for this <code>URL</code>.
+ * This is the same as calling <code>new URI(this.toString())</code>.
+ * RFC2396-compliant URLs are guaranteed a successful conversion to
+ * a <code>URI</code> instance. However, there are some values which
+ * form valid URLs, but which do not also form RFC2396-compliant URIs.
+ *
+ * @throws URISyntaxException if this URL is not RFC2396-compliant,
+ * and thus can not be successfully converted to a URI.
+ */
+ public URI toURI()
+ throws URISyntaxException
+ {
+ return new URI(toString());
+ }
+
+}
diff --git a/gcc-4.2.1/libjava/java/net/URLClassLoader.java b/gcc-4.2.1/libjava/java/net/URLClassLoader.java
new file mode 100644
index 000000000..06db7d582
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/URLClassLoader.java
@@ -0,0 +1,1452 @@
+/* URLClassLoader.java -- ClassLoader that loads classes from one or more URLs
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 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 java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.SecureClassLoader;
+import java.security.cert.Certificate;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import gnu.gcj.runtime.SharedLibHelper;
+import gnu.gcj.Core;
+import gnu.java.net.protocol.core.CoreInputStream;
+
+/**
+ * A secure class loader that can load classes and resources from
+ * multiple locations. Given an array of <code>URL</code>s this class
+ * loader will retrieve classes and resources by fetching them from
+ * possible remote locations. Each <code>URL</code> is searched in
+ * order in which it was added. If the file portion of the
+ * <code>URL</code> ends with a '/' character then it is interpreted
+ * as a base directory, otherwise it is interpreted as a jar file from
+ * which the classes/resources are resolved.
+ *
+ * <p>New instances can be created by two static
+ * <code>newInstance()</code> methods or by three public
+ * contructors. Both ways give the option to supply an initial array
+ * of <code>URL</code>s and (optionally) a parent classloader (that is
+ * different from the standard system class loader).</p>
+ *
+ * <p>Normally creating a <code>URLClassLoader</code> throws a
+ * <code>SecurityException</code> if a <code>SecurityManager</code> is
+ * installed and the <code>checkCreateClassLoader()</code> method does
+ * not return true. But the <code>newInstance()</code> methods may be
+ * used by any code as long as it has permission to acces the given
+ * <code>URL</code>s. <code>URLClassLoaders</code> created by the
+ * <code>newInstance()</code> methods also explicitly call the
+ * <code>checkPackageAccess()</code> method of
+ * <code>SecurityManager</code> if one is installed before trying to
+ * load a class. Note that only subclasses of
+ * <code>URLClassLoader</code> can add new URLs after the
+ * URLClassLoader had been created. But it is always possible to get
+ * an array of all URLs that the class loader uses to resolve classes
+ * and resources by way of the <code>getURLs()</code> method.</p>
+ *
+ * <p>Open issues:
+ * <ul>
+ *
+ * <li>Should the URLClassLoader actually add the locations found in
+ * the manifest or is this the responsibility of some other
+ * loader/(sub)class? (see <a
+ * href="http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html">
+ * Extension Mechanism Architecture - Bundles Extensions</a>)</li>
+ *
+ * <li>How does <code>definePackage()</code> and sealing work
+ * precisely?</li>
+ *
+ * <li>We save and use the security context (when a created by
+ * <code>newInstance()</code> but do we have to use it in more
+ * places?</li>
+ *
+ * <li>The use of <code>URLStreamHandler</code>s has not been tested.</li>
+ *
+ * </ul>
+ * </p>
+ *
+ * @since 1.2
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ * @author Wu Gansha (gansha.wu@intel.com)
+ */
+public class URLClassLoader extends SecureClassLoader
+{
+ // Class Variables
+
+ /**
+ * A global cache to store mappings between URLLoader and URL,
+ * so we can avoid do all the homework each time the same URL
+ * comes.
+ * XXX - Keeps these loaders forever which prevents garbage collection.
+ */
+ private static HashMap urlloaders = new HashMap();
+
+ /**
+ * A cache to store mappings between handler factory and its
+ * private protocol handler cache (also a HashMap), so we can avoid
+ * create handlers each time the same protocol comes.
+ */
+ private static HashMap factoryCache = new HashMap(5);
+
+ // Instance variables
+
+ /** Locations to load classes from */
+ private final Vector urls = new Vector();
+
+ /**
+ * Store pre-parsed information for each url into this vector: each
+ * element is a URL loader. A jar file has its own class-path
+ * attribute which adds to the URLs that will be searched, but this
+ * does not add to the list of urls.
+ */
+ private final Vector urlinfos = new Vector();
+
+ /** Factory used to get the protocol handlers of the URLs */
+ private final URLStreamHandlerFactory factory;
+
+ /**
+ * The security context when created from <code>newInstance()</code>
+ * or null when created through a normal constructor or when no
+ * <code>SecurityManager</code> was installed.
+ */
+ private final AccessControlContext securityContext;
+
+ // Helper classes
+
+ /**
+ * A <code>URLLoader</code> contains all logic to load resources from a
+ * given base <code>URL</code>.
+ */
+ abstract static class URLLoader
+ {
+ /**
+ * Our classloader to get info from if needed.
+ */
+ final URLClassLoader classloader;
+
+ /**
+ * The base URL from which all resources are loaded.
+ */
+ final URL baseURL;
+
+ /**
+ * A <code>CodeSource</code> without any associated certificates.
+ * It is common for classes to not have certificates associated
+ * with them. If they come from the same <code>URLLoader</code>
+ * then it is safe to share the associated <code>CodeSource</code>
+ * between them since <code>CodeSource</code> is immutable.
+ */
+ final CodeSource noCertCodeSource;
+
+ URLLoader(URLClassLoader classloader, URL baseURL)
+ {
+ this(classloader, baseURL, baseURL);
+ }
+
+ URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
+ {
+ this.classloader = classloader;
+ this.baseURL = baseURL;
+ this.noCertCodeSource = new CodeSource(overrideURL, null);
+ }
+
+ /**
+ * Returns a <code>Class</code> loaded by this
+ * <code>URLLoader</code>, or <code>null</code> when this loader
+ * either can't load the class or doesn't know how to load classes
+ * at all.
+ */
+ Class getClass(String className)
+ {
+ return null;
+ }
+
+ /**
+ * Returns a <code>Resource</code> loaded by this
+ * <code>URLLoader</code>, or <code>null</code> when no
+ * <code>Resource</code> with the given name exists.
+ */
+ abstract Resource getResource(String s);
+
+ /**
+ * Returns the <code>Manifest</code> associated with the
+ * <code>Resource</code>s loaded by this <code>URLLoader</code> or
+ * <code>null</code> there is no such <code>Manifest</code>.
+ */
+ Manifest getManifest()
+ {
+ return null;
+ }
+
+ Vector getClassPath()
+ {
+ return null;
+ }
+ }
+
+ /**
+ * A <code>Resource</code> represents a resource in some
+ * <code>URLLoader</code>. It also contains all information (e.g.,
+ * <code>URL</code>, <code>CodeSource</code>, <code>Manifest</code> and
+ * <code>InputStream</code>) that is necessary for loading resources
+ * and creating classes from a <code>URL</code>.
+ */
+ abstract static class Resource
+ {
+ final URLLoader loader;
+
+ Resource(URLLoader loader)
+ {
+ this.loader = loader;
+ }
+
+ /**
+ * Returns the non-null <code>CodeSource</code> associated with
+ * this resource.
+ */
+ CodeSource getCodeSource()
+ {
+ Certificate[] certs = getCertificates();
+ if (certs == null)
+ return loader.noCertCodeSource;
+ else
+ return new CodeSource(loader.baseURL, certs);
+ }
+
+ /**
+ * Returns <code>Certificates</code> associated with this
+ * resource, or null when there are none.
+ */
+ Certificate[] getCertificates()
+ {
+ return null;
+ }
+
+ /**
+ * Return a <code>URL</code> that can be used to access this resource.
+ */
+ abstract URL getURL();
+
+ /**
+ * Returns the size of this <code>Resource</code> in bytes or
+ * <code>-1</code> when unknown.
+ */
+ abstract int getLength();
+
+ /**
+ * Returns the non-null <code>InputStream</code> through which
+ * this resource can be loaded.
+ */
+ abstract InputStream getInputStream() throws IOException;
+ }
+
+ /**
+ * A <code>JarURLLoader</code> is a type of <code>URLLoader</code>
+ * only loading from jar url.
+ */
+ static final class JarURLLoader extends URLLoader
+ {
+ final JarFile jarfile; // The jar file for this url
+ final URL baseJarURL; // Base jar: url for all resources loaded from jar
+
+ Vector classPath; // The "Class-Path" attribute of this Jar's manifest
+
+ public JarURLLoader(URLClassLoader classloader, URL baseURL,
+ URL absoluteUrl)
+ {
+ super(classloader, baseURL, absoluteUrl);
+
+ // Cache url prefix for all resources in this jar url.
+ String external = baseURL.toExternalForm();
+ StringBuffer sb = new StringBuffer(external.length() + 6);
+ sb.append("jar:");
+ sb.append(external);
+ sb.append("!/");
+ String jarURL = sb.toString();
+
+ this.classPath = null;
+ URL baseJarURL = null;
+ JarFile jarfile = null;
+ try
+ {
+ baseJarURL =
+ new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
+
+ jarfile =
+ ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
+
+ Manifest manifest;
+ Attributes attributes;
+ String classPathString;
+
+ if ((manifest = jarfile.getManifest()) != null
+ && (attributes = manifest.getMainAttributes()) != null
+ && ((classPathString
+ = attributes.getValue(Attributes.Name.CLASS_PATH))
+ != null))
+ {
+ this.classPath = new Vector();
+
+ StringTokenizer st = new StringTokenizer(classPathString, " ");
+ while (st.hasMoreElements ())
+ {
+ String e = st.nextToken ();
+ try
+ {
+ URL url = new URL(baseURL, e);
+ this.classPath.add(url);
+ }
+ catch (java.net.MalformedURLException xx)
+ {
+ // Give up
+ }
+ }
+ }
+ }
+ catch (IOException ioe)
+ {
+ /* ignored */
+ }
+
+ this.baseJarURL = baseJarURL;
+ this.jarfile = jarfile;
+ }
+
+ /** get resource with the name "name" in the jar url */
+ Resource getResource(String name)
+ {
+ if (jarfile == null)
+ return null;
+
+ if (name.startsWith("/"))
+ name = name.substring(1);
+
+ JarEntry je = jarfile.getJarEntry(name);
+ if (je != null)
+ return new JarURLResource(this, name, je);
+ else
+ return null;
+ }
+
+ Manifest getManifest()
+ {
+ try
+ {
+ return (jarfile == null) ? null : jarfile.getManifest();
+ }
+ catch (IOException ioe)
+ {
+ return null;
+ }
+ }
+
+ Vector getClassPath()
+ {
+ return classPath;
+ }
+ }
+
+ static final class JarURLResource extends Resource
+ {
+ private final JarEntry entry;
+ private final String name;
+
+ JarURLResource(JarURLLoader loader, String name, JarEntry entry)
+ {
+ super(loader);
+ this.entry = entry;
+ this.name = name;
+ }
+
+ InputStream getInputStream() throws IOException
+ {
+ return ((JarURLLoader) loader).jarfile.getInputStream(entry);
+ }
+
+ int getLength()
+ {
+ return (int) entry.getSize();
+ }
+
+ Certificate[] getCertificates()
+ {
+ // We have to get the entry from the jar file again, because the
+ // certificates will not be available until the entire entry has
+ // been read.
+ return ((JarEntry) ((JarURLLoader) loader).jarfile.getEntry(name))
+ .getCertificates();
+ }
+
+ URL getURL()
+ {
+ try
+ {
+ return new URL(((JarURLLoader) loader).baseJarURL, name,
+ loader.classloader.getURLStreamHandler("jar"));
+ }
+ catch (MalformedURLException e)
+ {
+ InternalError ie = new InternalError();
+ ie.initCause(e);
+ throw ie;
+ }
+ }
+ }
+
+ /**
+ * Loader for remote directories.
+ */
+ static final class RemoteURLLoader extends URLLoader
+ {
+ private final String protocol;
+
+ RemoteURLLoader(URLClassLoader classloader, URL url)
+ {
+ super(classloader, url);
+ protocol = url.getProtocol();
+ }
+
+ /**
+ * Get a remote resource.
+ * Returns null if no such resource exists.
+ */
+ Resource getResource(String name)
+ {
+ try
+ {
+ URL url =
+ new URL(baseURL, name, classloader.getURLStreamHandler(protocol));
+ URLConnection connection = url.openConnection();
+
+ // Open the connection and check the stream
+ // just to be sure it exists.
+ int length = connection.getContentLength();
+ InputStream stream = connection.getInputStream();
+
+ // We can do some extra checking if it is a http request
+ if (connection instanceof HttpURLConnection)
+ {
+ int response =
+ ((HttpURLConnection) connection).getResponseCode();
+ if (response / 100 != 2)
+ return null;
+ }
+
+ if (stream != null)
+ return new RemoteResource(this, name, url, stream, length);
+ else
+ return null;
+ }
+ catch (IOException ioe)
+ {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * A resource from some remote location.
+ */
+ static final class RemoteResource extends Resource
+ {
+ private final URL url;
+ private final InputStream stream;
+ private final int length;
+
+ RemoteResource(RemoteURLLoader loader, String name, URL url,
+ InputStream stream, int length)
+ {
+ super(loader);
+ this.url = url;
+ this.stream = stream;
+ this.length = length;
+ }
+
+ InputStream getInputStream() throws IOException
+ {
+ return stream;
+ }
+
+ public int getLength()
+ {
+ return length;
+ }
+
+ public URL getURL()
+ {
+ return url;
+ }
+ }
+
+ /**
+ * A <code>SoURLLoader</code> is a type of <code>URLLoader</code>
+ * that loads classes and resources from a shared library.
+ */
+ final static class SoURLLoader extends URLLoader
+ {
+ SharedLibHelper helper;
+
+ SoURLLoader(URLClassLoader classloader, URL url)
+ {
+ this(classloader, url, url);
+ }
+
+ SoURLLoader(URLClassLoader classloader, URL url, URL overrideURL)
+ {
+ super(classloader, url, overrideURL);
+ helper = SharedLibHelper.findHelper(classloader, url.getFile(),
+ noCertCodeSource, true);
+ }
+
+ Class getClass(String className)
+ {
+ return helper.findClass(className);
+ }
+
+ Resource getResource(String name)
+ {
+ URL url = helper.findResource(name);
+ if (url == null)
+ return null;
+ return new SoResource(this, url);
+ }
+ }
+
+ final static class SoResource extends Resource
+ {
+ SoResource(SoURLLoader loader, URL url)
+ {
+ super(loader);
+ this.url = url;
+ }
+
+ InputStream getInputStream() throws IOException
+ {
+ URLConnection conn = url.openConnection();
+ return conn.getInputStream();
+ }
+
+ public int getLength()
+ {
+ // FIXME we could find this by asking the core object.
+ return -1;
+ }
+
+ public URL getURL ()
+ {
+ return url;
+ }
+
+ final URL url;
+ }
+
+ /**
+ * A <code>FileURLLoader</code> is a type of <code>URLLoader</code>
+ * only loading from file url.
+ */
+ static final class FileURLLoader extends URLLoader
+ {
+ File dir; //the file for this file url
+
+ FileURLLoader(URLClassLoader classloader, URL url, URL absoluteUrl)
+ {
+ super(classloader, url, absoluteUrl);
+ dir = new File(absoluteUrl.getFile());
+ }
+
+ /** get resource with the name "name" in the file url */
+ Resource getResource(String name)
+ {
+ try
+ {
+ File file = new File(dir, name).getCanonicalFile();
+ if (file.exists() && !file.isDirectory())
+ return new FileResource(this, file);
+ }
+ catch (IOException e)
+ {
+ // Fall through...
+ }
+ return null;
+ }
+ }
+
+ static final class FileResource extends Resource
+ {
+ final File file;
+
+ FileResource(FileURLLoader loader, File file)
+ {
+ super(loader);
+ this.file = file;
+ }
+
+ InputStream getInputStream() throws IOException
+ {
+ // Delegate to the URL content handler mechanism to retrieve an
+ // HTML representation of the directory listing if a directory
+ if (file.isDirectory())
+ {
+ URL url = getURL();
+ return url.openStream();
+ }
+ // Otherwise simply return a FileInputStream
+ return new FileInputStream(file);
+ }
+
+ public int getLength()
+ {
+ // Delegate to the URL content handler mechanism to retrieve the
+ // length of the HTML representation of the directory listing if
+ // a directory, or -1 if an exception occurs opening the directory.
+ if (file.isDirectory())
+ {
+ URL url = getURL();
+ try
+ {
+ URLConnection connection = url.openConnection();
+ return connection.getContentLength();
+ }
+ catch (IOException e)
+ {
+ return -1;
+ }
+ }
+ // Otherwise simply return the file length
+ return (int) file.length();
+ }
+
+ public URL getURL()
+ {
+ try
+ {
+ return file.toURL();
+ }
+ catch (MalformedURLException e)
+ {
+ InternalError ie = new InternalError();
+ ie.initCause(e);
+ throw ie;
+ }
+ }
+ }
+
+ /**
+ * A <code>CoreURLLoader</code> is a type of <code>URLLoader</code>
+ * only loading from core url.
+ */
+ static final class CoreURLLoader extends URLLoader
+ {
+ private String dir;
+
+ CoreURLLoader(URLClassLoader classloader, URL url)
+ {
+ super(classloader, url);
+ dir = baseURL.getFile();
+ }
+
+ /** get resource with the name "name" in the core url */
+ Resource getResource(String name)
+ {
+ Core core = Core.find (dir + name);
+ if (core != null)
+ return new CoreResource(this, name, core);
+ return null;
+ }
+ }
+
+ static final class CoreResource extends Resource
+ {
+ private final Core core;
+ private final String name;
+
+ CoreResource(CoreURLLoader loader, String name, Core core)
+ {
+ super(loader);
+ this.core = core;
+ this.name = name;
+ }
+
+ InputStream getInputStream() throws IOException
+ {
+ return new CoreInputStream(core);
+ }
+
+ public int getLength()
+ {
+ return core.length;
+ }
+
+ public URL getURL()
+ {
+ try
+ {
+ return new URL(loader.baseURL, name,
+ loader.classloader.getURLStreamHandler("core"));
+ }
+ catch (MalformedURLException e)
+ {
+ InternalError ie = new InternalError();
+ ie.initCause(e);
+ throw ie;
+ }
+ }
+ }
+
+ // Constructors
+
+ /**
+ * Creates a URLClassLoader that gets classes from the supplied URLs.
+ * To determine if this classloader may be created the constructor of
+ * the super class (<code>SecureClassLoader</code>) is called first, which
+ * can throw a SecurityException. Then the supplied URLs are added
+ * in the order given to the URLClassLoader which uses these URLs to
+ * load classes and resources (after using the default parent ClassLoader).
+ *
+ * @param urls Locations that should be searched by this ClassLoader when
+ * resolving Classes or Resources.
+ * @exception SecurityException if the SecurityManager disallows the
+ * creation of a ClassLoader.
+ * @see SecureClassLoader
+ */
+ public URLClassLoader(URL[] urls) throws SecurityException
+ {
+ super();
+ this.factory = null;
+ this.securityContext = null;
+ addURLs(urls);
+ }
+
+ /**
+ * Creates a <code>URLClassLoader</code> that gets classes from the supplied
+ * <code>URL</code>s.
+ * To determine if this classloader may be created the constructor of
+ * the super class (<code>SecureClassLoader</code>) is called first, which
+ * can throw a SecurityException. Then the supplied URLs are added
+ * in the order given to the URLClassLoader which uses these URLs to
+ * load classes and resources (after using the supplied parent ClassLoader).
+ * @param urls Locations that should be searched by this ClassLoader when
+ * resolving Classes or Resources.
+ * @param parent The parent class loader used before trying this class
+ * loader.
+ * @exception SecurityException if the SecurityManager disallows the
+ * creation of a ClassLoader.
+ * @exception SecurityException
+ * @see SecureClassLoader
+ */
+ public URLClassLoader(URL[] urls, ClassLoader parent)
+ throws SecurityException
+ {
+ super(parent);
+ this.factory = null;
+ this.securityContext = null;
+ addURLs(urls);
+ }
+
+ // Package-private to avoid a trampoline constructor.
+ /**
+ * Package-private constructor used by the static
+ * <code>newInstance(URL[])</code> method. Creates an
+ * <code>URLClassLoader</code> with the given parent but without any
+ * <code>URL</code>s yet. This is used to bypass the normal security
+ * check for creating classloaders, but remembers the security
+ * context which will be used when defining classes. The
+ * <code>URL</code>s to load from must be added by the
+ * <code>newInstance()</code> method in the security context of the
+ * caller.
+ *
+ * @param securityContext the security context of the unprivileged code.
+ */
+ URLClassLoader(ClassLoader parent, AccessControlContext securityContext)
+ {
+ super(parent);
+ this.factory = null;
+ this.securityContext = securityContext;
+ }
+
+ /**
+ * Creates a URLClassLoader that gets classes from the supplied URLs.
+ * To determine if this classloader may be created the constructor of
+ * the super class (<CODE>SecureClassLoader</CODE>) is called first, which
+ * can throw a SecurityException. Then the supplied URLs are added
+ * in the order given to the URLClassLoader which uses these URLs to
+ * load classes and resources (after using the supplied parent ClassLoader).
+ * It will use the supplied <CODE>URLStreamHandlerFactory</CODE> to get the
+ * protocol handlers of the supplied URLs.
+ * @param urls Locations that should be searched by this ClassLoader when
+ * resolving Classes or Resources.
+ * @param parent The parent class loader used before trying this class
+ * loader.
+ * @param factory Used to get the protocol handler for the URLs.
+ * @exception SecurityException if the SecurityManager disallows the
+ * creation of a ClassLoader.
+ * @exception SecurityException
+ * @see SecureClassLoader
+ */
+ public URLClassLoader(URL[] urls, ClassLoader parent,
+ URLStreamHandlerFactory factory)
+ throws SecurityException
+ {
+ super(parent);
+ this.securityContext = null;
+ this.factory = factory;
+ addURLs(urls);
+
+ // If this factory is still not in factoryCache, add it,
+ // since we only support three protocols so far, 5 is enough
+ // for cache initial size
+ synchronized (factoryCache)
+ {
+ if (factory != null && factoryCache.get(factory) == null)
+ factoryCache.put(factory, new HashMap(5));
+ }
+ }
+
+ // Methods
+
+ /**
+ * Adds a new location to the end of the internal URL store.
+ * @param newUrl the location to add
+ */
+ protected void addURL(URL newUrl)
+ {
+ urls.add(newUrl);
+ addURLImpl(newUrl);
+ }
+
+ private void addURLImpl(URL newUrl)
+ {
+ synchronized (this)
+ {
+ if (newUrl == null)
+ return; // Silently ignore...
+
+ // Reset the toString() value.
+ thisString = null;
+
+ // Check global cache to see if there're already url loader
+ // for this url.
+ URLLoader loader = (URLLoader) urlloaders.get(newUrl);
+ if (loader == null)
+ {
+ String file = newUrl.getFile();
+ String protocol = newUrl.getProtocol();
+
+ // If we have a file: URL, we want to make it absolute
+ // here, before we decide whether it is really a jar.
+ URL absoluteURL;
+ if ("file".equals (protocol))
+ {
+ File dir = new File(file);
+ URL absUrl;
+ try
+ {
+ absoluteURL = dir.getCanonicalFile().toURL();
+ }
+ catch (IOException ignore)
+ {
+ try
+ {
+ absoluteURL = dir.getAbsoluteFile().toURL();
+ }
+ catch (MalformedURLException _)
+ {
+ // This really should not happen.
+ absoluteURL = newUrl;
+ }
+ }
+ }
+ else
+ {
+ // This doesn't hurt, and it simplifies the logic a
+ // little.
+ absoluteURL = newUrl;
+ }
+
+ // Check that it is not a directory
+ if ("gcjlib".equals(protocol))
+ loader = new SoURLLoader(this, newUrl);
+ else if (! (file.endsWith("/") || file.endsWith(File.separator)))
+ loader = new JarURLLoader(this, newUrl, absoluteURL);
+ else if ("file".equals(protocol))
+ loader = new FileURLLoader(this, newUrl, absoluteURL);
+ else if ("core".equals(protocol))
+ loader = new CoreURLLoader(this, newUrl);
+ else
+ loader = new RemoteURLLoader(this, newUrl);
+
+ // Cache it.
+ urlloaders.put(newUrl, loader);
+ }
+
+ urlinfos.add(loader);
+
+ Vector extraUrls = loader.getClassPath();
+ if (extraUrls != null)
+ {
+ Iterator it = extraUrls.iterator();
+ while (it.hasNext())
+ {
+ URL url = (URL)it.next();
+ URLLoader extraLoader = (URLLoader) urlloaders.get(url);
+ if (! urlinfos.contains (extraLoader))
+ addURLImpl(url);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Adds an array of new locations to the end of the internal URL
+ * store. Called from the the constructors. Should not call to the
+ * protected addURL() method since that can be overridden and
+ * subclasses are not yet in a good state at this point.
+ * jboss 4.0.3 for example depends on this.
+ *
+ * @param newUrls the locations to add
+ */
+ private void addURLs(URL[] newUrls)
+ {
+ for (int i = 0; i < newUrls.length; i++)
+ {
+ urls.add(newUrls[i]);
+ addURLImpl(newUrls[i]);
+ }
+ }
+
+ /**
+ * Look in both Attributes for a given value. The first Attributes
+ * object, if not null, has precedence.
+ */
+ private String getAttributeValue(Attributes.Name name, Attributes first,
+ Attributes second)
+ {
+ String result = null;
+ if (first != null)
+ result = first.getValue(name);
+ if (result == null)
+ result = second.getValue(name);
+ return result;
+ }
+
+ /**
+ * Defines a Package based on the given name and the supplied manifest
+ * information. The manifest indicates the title, version and
+ * vendor information of the specification and implementation and whether the
+ * package is sealed. If the Manifest indicates that the package is sealed
+ * then the Package will be sealed with respect to the supplied URL.
+ *
+ * @param name The name of the package
+ * @param manifest The manifest describing the specification,
+ * implementation and sealing details of the package
+ * @param url the code source url to seal the package
+ * @return the defined Package
+ * @throws IllegalArgumentException If this package name already exists
+ * in this class loader
+ */
+ protected Package definePackage(String name, Manifest manifest, URL url)
+ throws IllegalArgumentException
+ {
+ // Compute the name of the package as it may appear in the
+ // Manifest.
+ StringBuffer xform = new StringBuffer(name);
+ for (int i = xform.length () - 1; i >= 0; --i)
+ if (xform.charAt(i) == '.')
+ xform.setCharAt(i, '/');
+ xform.append('/');
+ String xformName = xform.toString();
+
+ Attributes entryAttr = manifest.getAttributes(xformName);
+ Attributes attr = manifest.getMainAttributes();
+
+ String specTitle
+ = getAttributeValue(Attributes.Name.SPECIFICATION_TITLE,
+ entryAttr, attr);
+ String specVersion
+ = getAttributeValue(Attributes.Name.SPECIFICATION_VERSION,
+ entryAttr, attr);
+ String specVendor
+ = getAttributeValue(Attributes.Name.SPECIFICATION_VENDOR,
+ entryAttr, attr);
+ String implTitle
+ = getAttributeValue(Attributes.Name.IMPLEMENTATION_TITLE,
+ entryAttr, attr);
+ String implVersion
+ = getAttributeValue(Attributes.Name.IMPLEMENTATION_VERSION,
+ entryAttr, attr);
+ String implVendor
+ = getAttributeValue(Attributes.Name.IMPLEMENTATION_VENDOR,
+ entryAttr, attr);
+
+ // Look if the Manifest indicates that this package is sealed
+ // XXX - most likely not completely correct!
+ // Shouldn't we also check the sealed attribute of the complete jar?
+ // http://java.sun.com/products/jdk/1.4/docs/guide/extensions/spec.html#bundled
+ // But how do we get that jar manifest here?
+ String sealed = attr.getValue(Attributes.Name.SEALED);
+ if ("false".equals(sealed))
+ // make sure that the URL is null so the package is not sealed
+ url = null;
+
+ return definePackage(name,
+ specTitle, specVendor, specVersion,
+ implTitle, implVendor, implVersion,
+ url);
+ }
+
+ /**
+ * Finds (the first) class by name from one of the locations. The locations
+ * are searched in the order they were added to the URLClassLoader.
+ *
+ * @param className the classname to find
+ * @exception ClassNotFoundException when the class could not be found or
+ * loaded
+ * @return a Class object representing the found class
+ */
+ protected Class findClass(final String className)
+ throws ClassNotFoundException
+ {
+ // Just try to find the resource by the (almost) same name
+ String resourceName = className.replace('.', '/') + ".class";
+ int max = urlinfos.size();
+ Resource resource = null;
+ for (int i = 0; i < max && resource == null; i++)
+ {
+ URLLoader loader = (URLLoader)urlinfos.elementAt(i);
+ if (loader == null)
+ continue;
+
+ Class k = loader.getClass(className);
+ if (k != null)
+ return k;
+
+ resource = loader.getResource(resourceName);
+ }
+ if (resource == null)
+ {
+ String message = className + " not found";
+ if (runtimeInitialized())
+ message += " in " + this;
+ throw new ClassNotFoundException(message);
+ }
+
+ // Try to read the class data, create the CodeSource, Package and
+ // construct the class (and watch out for those nasty IOExceptions)
+ try
+ {
+ byte[] data;
+ InputStream in = resource.getInputStream();
+ try
+ {
+ int length = resource.getLength();
+ if (length != -1)
+ {
+ // We know the length of the data.
+ // Just try to read it in all at once
+ data = new byte[length];
+ int pos = 0;
+ while (length - pos > 0)
+ {
+ int len = in.read(data, pos, length - pos);
+ if (len == -1)
+ throw new EOFException("Not enough data reading from: "
+ + in);
+ pos += len;
+ }
+ }
+ else
+ {
+ // We don't know the data length.
+ // Have to read it in chunks.
+ ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+ byte[] b = new byte[4096];
+ int l = 0;
+ while (l != -1)
+ {
+ l = in.read(b);
+ if (l != -1)
+ out.write(b, 0, l);
+ }
+ data = out.toByteArray();
+ }
+ }
+ finally
+ {
+ in.close();
+ }
+ final byte[] classData = data;
+
+ // Now get the CodeSource
+ final CodeSource source = resource.getCodeSource();
+
+ // Find out package name
+ String packageName = null;
+ int lastDot = className.lastIndexOf('.');
+ if (lastDot != -1)
+ packageName = className.substring(0, lastDot);
+
+ if (packageName != null && getPackage(packageName) == null)
+ {
+ // define the package
+ Manifest manifest = resource.loader.getManifest();
+ if (manifest == null)
+ definePackage(packageName, null, null, null, null, null, null,
+ null);
+ else
+ definePackage(packageName, manifest, resource.loader.baseURL);
+ }
+
+ // And finally construct the class!
+ SecurityManager sm = System.getSecurityManager();
+ Class result = null;
+ if (sm != null && securityContext != null)
+ {
+ result = (Class)AccessController.doPrivileged
+ (new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return defineClass(className, classData,
+ 0, classData.length,
+ source);
+ }
+ }, securityContext);
+ }
+ else
+ result = defineClass(className, classData, 0, classData.length, source);
+
+ // Avoid NullPointerExceptions.
+ Certificate[] resourceCertificates = resource.getCertificates();
+ if(resourceCertificates != null)
+ super.setSigners(result, resourceCertificates);
+
+ return result;
+ }
+ catch (IOException ioe)
+ {
+ ClassNotFoundException cnfe;
+ cnfe = new ClassNotFoundException(className + " not found in " + this);
+ cnfe.initCause(ioe);
+ throw cnfe;
+ }
+ }
+
+ // Cached String representation of this URLClassLoader
+ private String thisString;
+
+ /**
+ * Returns a String representation of this URLClassLoader giving the
+ * actual Class name, the URLs that are searched and the parent
+ * ClassLoader.
+ */
+ public String toString()
+ {
+ synchronized (this)
+ {
+ if (thisString == null)
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(this.getClass().getName());
+ sb.append("{urls=[" );
+ URL[] thisURLs = getURLs();
+ for (int i = 0; i < thisURLs.length; i++)
+ {
+ sb.append(thisURLs[i]);
+ if (i < thisURLs.length - 1)
+ sb.append(',');
+ }
+ sb.append(']');
+ sb.append(", parent=");
+ sb.append(getParent());
+ sb.append('}');
+ thisString = sb.toString();
+ }
+ return thisString;
+ }
+ }
+
+ /**
+ * Finds the first occurrence of a resource that can be found. The locations
+ * are searched in the order they were added to the URLClassLoader.
+ *
+ * @param resourceName the resource name to look for
+ * @return the URLResource for the resource if found, null otherwise
+ */
+ private Resource findURLResource(String resourceName)
+ {
+ int max = urlinfos.size();
+ for (int i = 0; i < max; i++)
+ {
+ URLLoader loader = (URLLoader) urlinfos.elementAt(i);
+ if (loader == null)
+ continue;
+
+ Resource resource = loader.getResource(resourceName);
+ if (resource != null)
+ return resource;
+ }
+ return null;
+ }
+
+ /**
+ * Finds the first occurrence of a resource that can be found.
+ *
+ * @param resourceName the resource name to look for
+ * @return the URL if found, null otherwise
+ */
+ public URL findResource(String resourceName)
+ {
+ Resource resource = findURLResource(resourceName);
+ if (resource != null)
+ return resource.getURL();
+
+ // Resource not found
+ return null;
+ }
+
+ /**
+ * If the URLStreamHandlerFactory has been set this return the appropriate
+ * URLStreamHandler for the given protocol, if not set returns null.
+ *
+ * @param protocol the protocol for which we need a URLStreamHandler
+ * @return the appropriate URLStreamHandler or null
+ */
+ URLStreamHandler getURLStreamHandler(String protocol)
+ {
+ if (factory == null)
+ return null;
+
+ URLStreamHandler handler;
+ synchronized (factoryCache)
+ {
+ // Check if there're handler for the same protocol in cache.
+ HashMap cache = (HashMap) factoryCache.get(factory);
+ handler = (URLStreamHandler) cache.get(protocol);
+ if (handler == null)
+ {
+ // Add it to cache.
+ handler = factory.createURLStreamHandler(protocol);
+ cache.put(protocol, handler);
+ }
+ }
+ return handler;
+ }
+
+ /**
+ * Finds all the resources with a particular name from all the locations.
+ *
+ * @param resourceName the name of the resource to lookup
+ * @return a (possible empty) enumeration of URLs where the resource can be
+ * found
+ * @exception IOException when an error occurs accessing one of the
+ * locations
+ */
+ public Enumeration findResources(String resourceName)
+ throws IOException
+ {
+ Vector resources = new Vector();
+ int max = urlinfos.size();
+ for (int i = 0; i < max; i++)
+ {
+ URLLoader loader = (URLLoader) urlinfos.elementAt(i);
+ Resource resource = loader.getResource(resourceName);
+ if (resource != null)
+ resources.add(resource.getURL());
+ }
+ return resources.elements();
+ }
+
+ /**
+ * Returns the permissions needed to access a particular code
+ * source. These permissions includes those returned by
+ * <code>SecureClassLoader.getPermissions()</code> and the actual
+ * permissions to access the objects referenced by the URL of the
+ * code source. The extra permissions added depend on the protocol
+ * and file portion of the URL in the code source. If the URL has
+ * the "file" protocol ends with a '/' character then it must be a
+ * directory and a file Permission to read everything in that
+ * directory and all subdirectories is added. If the URL had the
+ * "file" protocol and doesn't end with a '/' character then it must
+ * be a normal file and a file permission to read that file is
+ * added. If the <code>URL</code> has any other protocol then a
+ * socket permission to connect and accept connections from the host
+ * portion of the URL is added.
+ *
+ * @param source The codesource that needs the permissions to be accessed
+ * @return the collection of permissions needed to access the code resource
+ * @see java.security.SecureClassLoader#getPermissions(CodeSource)
+ */
+ protected PermissionCollection getPermissions(CodeSource source)
+ {
+ // XXX - This implementation does exactly as the Javadoc describes.
+ // But maybe we should/could use URLConnection.getPermissions()?
+ // First get the permissions that would normally be granted
+ PermissionCollection permissions = super.getPermissions(source);
+
+ // Now add any extra permissions depending on the URL location.
+ URL url = source.getLocation();
+ String protocol = url.getProtocol();
+ if (protocol.equals("file"))
+ {
+ String file = url.getFile();
+
+ // If the file end in / it must be an directory.
+ if (file.endsWith("/") || file.endsWith(File.separator))
+ {
+ // Grant permission to read everything in that directory and
+ // all subdirectories.
+ permissions.add(new FilePermission(file + "-", "read"));
+ }
+ else
+ {
+ // It is a 'normal' file.
+ // Grant permission to access that file.
+ permissions.add(new FilePermission(file, "read"));
+ }
+ }
+ else
+ {
+ // Grant permission to connect to and accept connections from host
+ String host = url.getHost();
+ if (host != null)
+ permissions.add(new SocketPermission(host, "connect,accept"));
+ }
+
+ return permissions;
+ }
+
+ /**
+ * Returns all the locations that this class loader currently uses the
+ * resolve classes and resource. This includes both the initially supplied
+ * URLs as any URLs added later by the loader.
+ * @return All the currently used URLs
+ */
+ public URL[] getURLs()
+ {
+ return (URL[]) urls.toArray(new URL[urls.size()]);
+ }
+
+ /**
+ * Creates a new instance of a <code>URLClassLoader</code> that gets
+ * classes from the supplied <code>URL</code>s. This class loader
+ * will have as parent the standard system class loader.
+ *
+ * @param urls the initial URLs used to resolve classes and
+ * resources
+ *
+ * @return the class loader
+ *
+ * @exception SecurityException when the calling code does not have
+ * permission to access the given <code>URL</code>s
+ */
+ public static URLClassLoader newInstance(URL[] urls)
+ throws SecurityException
+ {
+ return newInstance(urls, null);
+ }
+
+ /**
+ * Creates a new instance of a <code>URLClassLoader</code> that gets
+ * classes from the supplied <code>URL</code>s and with the supplied
+ * loader as parent class loader.
+ *
+ * @param urls the initial URLs used to resolve classes and
+ * resources
+ * @param parent the parent class loader
+ *
+ * @return the class loader
+ *
+ * @exception SecurityException when the calling code does not have
+ * permission to access the given <code>URL</code>s
+ */
+ public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
+ throws SecurityException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null)
+ return new URLClassLoader(urls, parent);
+ else
+ {
+ final Object securityContext = sm.getSecurityContext();
+
+ // XXX - What to do with anything else then an AccessControlContext?
+ if (! (securityContext instanceof AccessControlContext))
+ throw new SecurityException("securityContext must be AccessControlContext: "
+ + securityContext);
+
+ URLClassLoader loader =
+ (URLClassLoader) AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return new URLClassLoader(parent,
+ (AccessControlContext) securityContext);
+ }
+ });
+ loader.addURLs(urls);
+ return loader;
+ }
+ }
+
+ /**
+ * Tell whether runtime initialization is complete.
+ *
+ * @return whether runtime initialization is complete.
+ */
+ private static native boolean runtimeInitialized();
+}
diff --git a/gcc-4.2.1/libjava/java/net/VMInetAddress.java b/gcc-4.2.1/libjava/java/net/VMInetAddress.java
new file mode 100644
index 000000000..b10cf2528
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/VMInetAddress.java
@@ -0,0 +1,117 @@
+/* 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.Serializable;
+
+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 String getLocalHostname()
+ {
+ return InetAddress.getLocalHostname();
+ }
+
+ /**
+ * Returns the value of the special address INADDR_ANY
+ */
+ public static byte[] lookupInaddrAny() throws UnknownHostException
+ {
+ return new byte[] {0, 0, 0, 0};
+ }
+
+ /**
+ * 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 String getHostByAddr(byte[] ip) throws UnknownHostException
+ {
+ InetAddress addr = InetAddress.getByAddress(ip);
+ InetAddress.lookup(null, addr, false);
+ return addr.getHostName();
+ }
+
+ /**
+ * Returns a list of all IP addresses for a given hostname. Will throw
+ * an UnknownHostException if the hostname cannot be resolved.
+ */
+ public static byte[][] getHostByName(String hostname)
+ throws UnknownHostException
+ {
+ InetAddress[] iaddrs = InetAddress.lookup(hostname, null, true);
+ byte[][] addrs = new byte[iaddrs.length][];
+ for (int i = 0; i < iaddrs.length; i++)
+ addrs[i] = iaddrs[i].getAddress();
+ return addrs;
+ }
+
+ /**
+ * Return the IP address represented by a literal address.
+ * Will return null if the literal address is not valid.
+ *
+ * @param address the name of the host
+ *
+ * @return The IP address as a byte array
+ */
+ public static byte[] aton(String address)
+ {
+ return InetAddress.aton(address);
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/net/VMNetworkInterface.java b/gcc-4.2.1/libjava/java/net/VMNetworkInterface.java
new file mode 100644
index 000000000..af71ce294
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/VMNetworkInterface.java
@@ -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;
+}
diff --git a/gcc-4.2.1/libjava/java/net/VMURLConnection.java b/gcc-4.2.1/libjava/java/net/VMURLConnection.java
new file mode 100644
index 000000000..6555e8cba
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/VMURLConnection.java
@@ -0,0 +1,76 @@
+/* VMURLConnection - VM code for URLConnection
+ Copyright (C) 2006 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.InputStream;
+
+final class VMURLConnection
+{
+ public static final int LENGTH = 1024;
+
+ // private static native void init();
+
+ private static String guessContentTypeFromBuffer(byte[] b, int valid)
+ {
+ // FIXME - write real implementation
+ return null;
+ }
+
+ /**
+ * This is called from URLConnection to guess the mime type of a
+ * stream. This method may return null to indicate that it could
+ * not guess a type.
+ */
+ static String guessContentTypeFromStream(InputStream is)
+ throws IOException
+ {
+ if (! is.markSupported())
+ return null;
+ is.mark(LENGTH);
+ byte[] bytes = new byte[LENGTH];
+ int r = is.read(bytes);
+ if (r < 0)
+ return null;
+ is.reset();
+ return guessContentTypeFromBuffer(bytes, r);
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/net/natInetAddressNoNet.cc b/gcc-4.2.1/libjava/java/net/natInetAddressNoNet.cc
new file mode 100644
index 000000000..0374af18f
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/natInetAddressNoNet.cc
@@ -0,0 +1,36 @@
+/* Copyright (C) 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <stddef.h>
+
+#include <java/net/InetAddress.h>
+
+jbyteArray
+java::net::InetAddress::aton (jstring)
+{
+ return NULL;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+ return 0;
+}
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
+{
+ return NULL;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+ return NULL;
+}
diff --git a/gcc-4.2.1/libjava/java/net/natInetAddressPosix.cc b/gcc-4.2.1/libjava/java/net/natInetAddressPosix.cc
new file mode 100644
index 000000000..d343f2332
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/natInetAddressPosix.cc
@@ -0,0 +1,304 @@
+/* Copyright (C) 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/InetAddress.h>
+#include <java/net/UnknownHostException.h>
+#include <java/lang/SecurityException.h>
+
+#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
+#include <sys/utsname.h>
+#endif
+
+#ifndef HAVE_GETHOSTNAME_DECL
+extern "C" int gethostname (char *name, int namelen);
+#endif
+
+jbyteArray
+java::net::InetAddress::aton (jstring host)
+{
+ char *hostname;
+ char buf[100];
+ int len = JvGetStringUTFLength(host);
+ if (len < 100)
+ hostname = buf;
+ else
+ hostname = (char*) _Jv_AllocBytes (len+1);
+ JvGetStringUTFRegion (host, 0, host->length(), hostname);
+ buf[len] = '\0';
+ char* bytes = NULL;
+ int blen = 0;
+#ifdef HAVE_INET_ATON
+ struct in_addr laddr;
+ if (inet_aton (hostname, &laddr))
+ {
+ bytes = (char*) &laddr;
+ blen = 4;
+ }
+#elif defined(HAVE_INET_ADDR)
+#if ! HAVE_IN_ADDR_T
+ typedef jint in_addr_t;
+#endif
+ in_addr_t laddr = inet_addr (hostname);
+ if (laddr != (in_addr_t)(-1))
+ {
+ bytes = (char*) &laddr;
+ blen = 4;
+ }
+#endif
+#if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
+ char inet6_addr[16];
+ if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
+ {
+ bytes = inet6_addr;
+ blen = 16;
+ }
+#endif
+ if (blen == 0)
+ return NULL;
+ jbyteArray result = JvNewByteArray (blen);
+ memcpy (elements (result), bytes, blen);
+ return result;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+ int len = bytes->length;
+ if (len == 4)
+ return AF_INET;
+#ifdef HAVE_INET6
+ else if (len == 16)
+ return AF_INET6;
+#endif /* HAVE_INET6 */
+ else
+ JvFail ("unrecognized size");
+}
+
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
+ jboolean all)
+{
+ struct hostent *hptr = NULL;
+#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
+ struct hostent hent_r;
+#if HAVE_STRUCT_HOSTENT_DATA
+ struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
+#else
+#if defined (__GLIBC__)
+ // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
+ // ERANGE to errno if the buffer size is too small, rather than what is
+ // expected here. We work around this by setting a bigger buffer size and
+ // hoping that it is big enough.
+ char fixed_buffer[1024];
+#else
+ char fixed_buffer[200];
+#endif
+ char *buffer_r = fixed_buffer;
+ int size_r = sizeof (fixed_buffer);
+#endif
+#endif
+
+ if (host != NULL)
+ {
+ char *hostname;
+ char buf[100];
+ int len = JvGetStringUTFLength(host);
+ if (len < 100)
+ hostname = buf;
+ else
+ hostname = (char*) _Jv_AllocBytes (len+1);
+ JvGetStringUTFRegion (host, 0, host->length(), hostname);
+ buf[len] = '\0';
+#ifdef HAVE_GETHOSTBYNAME_R
+ while (true)
+ {
+ int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+ ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
+#else
+ int herr = 0;
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+ ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
+ &hptr, &herr);
+#else
+ hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
+ ok = hptr != NULL;
+#endif /* GETHOSTNAME_R_RETURNS_INT */
+ if (! ok && herr == ERANGE)
+ {
+ size_r *= 2;
+ buffer_r = (char *) _Jv_AllocBytes (size_r);
+ }
+ else
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+ break;
+ }
+#else
+ // FIXME: this is insufficient if some other piece of code calls
+ // this gethostbyname.
+ JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+ hptr = gethostbyname (hostname);
+#endif /* HAVE_GETHOSTBYNAME_R */
+ }
+ else
+ {
+ jbyteArray bytes = iaddr->addr;
+ char *chars = (char*) elements (bytes);
+ int len = bytes->length;
+ int type;
+ char *val;
+ if (len == 4)
+ {
+ val = chars;
+ type = iaddr->family = AF_INET;
+ }
+#ifdef HAVE_INET6
+ else if (len == 16)
+ {
+ val = (char *) &chars;
+ type = iaddr->family = AF_INET6;
+ }
+#endif /* HAVE_INET6 */
+ else
+ JvFail ("unrecognized size");
+
+#ifdef HAVE_GETHOSTBYADDR_R
+ while (true)
+ {
+ int ok;
+#if HAVE_STRUCT_HOSTENT_DATA
+ ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
+#else
+ int herr = 0;
+#ifdef GETHOSTBYADDR_R_RETURNS_INT
+ ok = ! gethostbyaddr_r (val, len, type, &hent_r,
+ buffer_r, size_r, &hptr, &herr);
+#else
+ hptr = gethostbyaddr_r (val, len, type, &hent_r,
+ buffer_r, size_r, &herr);
+ ok = hptr != NULL;
+#endif /* GETHOSTBYADDR_R_RETURNS_INT */
+ if (! ok && herr == ERANGE)
+ {
+ size_r *= 2;
+ buffer_r = (char *) _Jv_AllocBytes (size_r);
+ }
+ else
+#endif /* HAVE_STRUCT_HOSTENT_DATA */
+ break;
+ }
+#else /* HAVE_GETHOSTBYADDR_R */
+ // FIXME: this is insufficient if some other piece of code calls
+ // this gethostbyaddr.
+ JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+ hptr = gethostbyaddr (val, len, type);
+#endif /* HAVE_GETHOSTBYADDR_R */
+ }
+ if (hptr != NULL)
+ {
+ if (!all)
+ host = JvNewStringUTF (hptr->h_name);
+ }
+ if (hptr == NULL)
+ {
+ if (iaddr != NULL && iaddr->addr != NULL)
+ {
+ iaddr->hostName = iaddr->getHostAddress();
+ return NULL;
+ }
+ else
+ throw new java::net::UnknownHostException(host);
+ }
+ int count;
+ if (all)
+ {
+ char** ptr = hptr->h_addr_list;
+ count = 0;
+ while (*ptr++) count++;
+ }
+ else
+ count = 1;
+ JArray<java::net::InetAddress*> *result;
+ java::net::InetAddress** iaddrs;
+ if (all)
+ {
+ result = java::net::InetAddress::allocArray (count);
+ iaddrs = elements (result);
+ }
+ else
+ {
+ result = NULL;
+ iaddrs = &iaddr;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ if (iaddrs[i] == NULL)
+ iaddrs[i] = new java::net::InetAddress (NULL, NULL);
+ if (iaddrs[i]->hostName == NULL)
+ iaddrs[i]->hostName = host;
+ if (iaddrs[i]->addr == NULL)
+ {
+ char *bytes = hptr->h_addr_list[i];
+ iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
+ iaddrs[i]->family = getFamily (iaddrs[i]->addr);
+ memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
+ }
+ }
+ return result;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+ char *chars;
+#ifdef HAVE_GETHOSTNAME
+ char buffer[MAXHOSTNAMELEN];
+ if (gethostname (buffer, MAXHOSTNAMELEN))
+ return NULL;
+ chars = buffer;
+#elif HAVE_UNAME
+ struct utsname stuff;
+ if (uname (&stuff) != 0)
+ return NULL;
+ chars = stuff.nodename;
+#else
+ return NULL;
+#endif
+ // It is admittedly non-optimal to convert the hostname to Unicode
+ // only to convert it back in getByName, but simplicity wins. Note
+ // that unless there is a SecurityManager, we only get called once
+ // anyway, thanks to the InetAddress.localhost cache.
+ return JvNewStringUTF (chars);
+}
diff --git a/gcc-4.2.1/libjava/java/net/natInetAddressWin32.cc b/gcc-4.2.1/libjava/java/net/natInetAddressWin32.cc
new file mode 100644
index 000000000..82c1e6f70
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/natInetAddressWin32.cc
@@ -0,0 +1,168 @@
+/* Copyright (C) 2003 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#undef STRICT
+
+#include <java/net/InetAddress.h>
+#include <java/net/UnknownHostException.h>
+#include <java/lang/SecurityException.h>
+
+jbyteArray
+java::net::InetAddress::aton (jstring host)
+{
+ JV_TEMP_UTF_STRING (hostname, host);
+ char* bytes = NULL;
+ int blen = 0;
+ unsigned long laddr = inet_addr (hostname);
+ if (laddr != INADDR_NONE)
+ {
+ bytes = (char*) &laddr;
+ blen = 4;
+ }
+ if (blen == 0)
+ return NULL;
+ jbyteArray result = JvNewByteArray (blen);
+ memcpy (elements (result), bytes, blen);
+ return result;
+}
+
+jint
+java::net::InetAddress::getFamily (jbyteArray bytes)
+{
+ int len = bytes->length;
+ if (len == 4)
+ return AF_INET;
+#ifdef HAVE_INET6
+ else if (len == 16)
+ return AF_INET6;
+#endif /* HAVE_INET6 */
+ else
+ JvFail ("unrecognized size");
+}
+
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
+ jboolean all)
+{
+ struct hostent *hptr = NULL;
+ if (host != NULL)
+ {
+ JV_TEMP_UTF_STRING (hostname, host);
+
+ // FIXME: this is insufficient if some other piece of code calls
+ // this gethostbyname.
+ JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+ hptr = gethostbyname (hostname);
+ }
+ else
+ {
+ jbyteArray bytes = iaddr->addr;
+ char *chars = (char*) elements (bytes);
+ int len = bytes->length;
+ int type;
+ char *val;
+ if (len == 4)
+ {
+ val = chars;
+ type = iaddr->family = AF_INET;
+ }
+#ifdef HAVE_INET6
+ else if (len == 16)
+ {
+ val = (char *) &chars;
+ type = iaddr->family = AF_INET6;
+ }
+#endif /* HAVE_INET6 */
+ else
+ JvFail ("unrecognized size");
+
+ // FIXME: this is insufficient if some other piece of code calls
+ // this gethostbyaddr.
+ JvSynchronize sync (java::net::InetAddress::loopbackAddress);
+ hptr = gethostbyaddr (val, len, type);
+ }
+ if (hptr != NULL)
+ {
+ if (!all)
+ host = JvNewStringUTF (hptr->h_name);
+ java::lang::SecurityException *ex = checkConnect (host);
+ if (ex != NULL)
+ {
+ if (iaddr == NULL || iaddr->addr == NULL)
+ throw ex;
+ hptr = NULL;
+ }
+ }
+ if (hptr == NULL)
+ {
+ if (iaddr != NULL && iaddr->addr != NULL)
+ {
+ iaddr->hostName = iaddr->getHostAddress();
+ return NULL;
+ }
+ else
+ throw new java::net::UnknownHostException(host);
+ }
+
+ int count;
+ if (all)
+ {
+ char** ptr = hptr->h_addr_list;
+ count = 0;
+ while (*ptr++) count++;
+ }
+ else
+ count = 1;
+
+ JArray<java::net::InetAddress*> *result;
+ java::net::InetAddress** iaddrs;
+ if (all)
+ {
+ result = java::net::InetAddress::allocArray (count);
+ iaddrs = elements (result);
+ }
+ else
+ {
+ result = NULL;
+ iaddrs = &iaddr;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ if (iaddrs[i] == NULL)
+ iaddrs[i] = new java::net::InetAddress (NULL, NULL);
+ if (iaddrs[i]->hostName == NULL)
+ iaddrs[i]->hostName = host;
+ if (iaddrs[i]->addr == NULL)
+ {
+ char *bytes = hptr->h_addr_list[i];
+ iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
+ iaddrs[i]->family = getFamily (iaddrs[i]->addr);
+ memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
+ }
+ }
+
+ return result;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+ char buffer[400];
+ if (gethostname (buffer, sizeof(buffer)))
+ return NULL;
+ // It is admittedly non-optimal to convert the hostname to Unicode
+ // only to convert it back in getByName, but simplicity wins. Note
+ // that unless there is a SecurityManager, we only get called once
+ // anyway, thanks to the InetAddress.localhost cache.
+ return JvNewStringUTF (buffer);
+}
diff --git a/gcc-4.2.1/libjava/java/net/natURLClassLoader.cc b/gcc-4.2.1/libjava/java/net/natURLClassLoader.cc
new file mode 100644
index 000000000..ead0db44a
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/natURLClassLoader.cc
@@ -0,0 +1,22 @@
+// natURLClassLoader.cc -- Native part of the URLClassLoader class.
+
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/net/URLClassLoader.h>
+
+jboolean
+java::net::URLClassLoader::runtimeInitialized ()
+{
+ return gcj::runtimeInitialized;
+}
diff --git a/gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceNoNet.cc b/gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceNoNet.cc
new file mode 100644
index 000000000..eda7f99f0
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceNoNet.cc
@@ -0,0 +1,21 @@
+/* Copyright (C) 2003, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <java/net/SocketException.h>
+#include <java/net/VMNetworkInterface.h>
+#include <java/util/Vector.h>
+
+::java::util::Vector*
+java::net::VMNetworkInterface::getInterfaces ()
+{
+ throw new SocketException (
+ JvNewStringLatin1 ("VMNetworkInterface.getInterfaces: unimplemented"));
+}
diff --git a/gcc-4.2.1/libjava/java/net/natVMNetworkInterfacePosix.cc b/gcc-4.2.1/libjava/java/net/natVMNetworkInterfacePosix.cc
new file mode 100644
index 000000000..bfb11d21c
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/natVMNetworkInterfacePosix.cc
@@ -0,0 +1,163 @@
+/* Copyright (C) 2003, 2005, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#define BSD_COMP /* Get FIONREAD on Solaris2. */
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java/net/InetAddress.h>
+#include <java/net/NetworkInterface.h>
+#include <java/net/SocketException.h>
+#include <java/net/VMNetworkInterface.h>
+#include <java/util/Vector.h>
+
+::java::util::Vector*
+java::net::VMNetworkInterface::getInterfaces ()
+{
+ ::java::util::Vector* ht = new ::java::util::Vector ();
+
+#ifdef HAVE_GETIFADDRS
+
+ struct ifaddrs *addrs;
+ if (::getifaddrs (&addrs) == -1)
+ throw new ::java::net::SocketException(JvNewStringUTF (strerror (errno)));
+
+ for (struct ifaddrs *work = addrs; work != NULL; work = work->ifa_next)
+ {
+ // Sometimes the address can be NULL; I don't know why but
+ // there's nothing we can do with this.
+ if (! work->ifa_addr)
+ continue;
+ // We only return Inet4 or Inet6 addresses.
+ jbyteArray laddr;
+ if (work->ifa_addr->sa_family == AF_INET)
+ {
+ sockaddr_in *real = reinterpret_cast<sockaddr_in *> (work->ifa_addr);
+ laddr = JvNewByteArray(4);
+ memcpy (elements (laddr), &real->sin_addr, 4);
+ }
+#ifdef HAVE_INET6
+ else if (work->ifa_addr->sa_family == AF_INET6)
+ {
+ sockaddr_in6 *real
+ = reinterpret_cast<sockaddr_in6 *> (work->ifa_addr);
+ laddr = JvNewByteArray(16);
+ memcpy (elements (laddr), &real->sin6_addr, 16);
+ }
+#endif
+ else
+ continue;
+
+ ::java::net::InetAddress *inaddr
+ = ::java::net::InetAddress::getByAddress(laddr);
+
+ // It is ok to make a new NetworkInterface for each struct; the
+ // java code will unify these as necessary; see
+ // NetworkInterface.condense().
+ jstring name = JvNewStringUTF (work->ifa_name);
+
+ ht->add (new NetworkInterface (name, inaddr));
+ }
+
+ freeifaddrs (addrs);
+
+#else /* ! HAVE_GETIFADDRS */
+
+ int fd;
+ int num_interfaces = 0;
+ struct ifconf if_data;
+ struct ifreq* if_record;
+
+ if_data.ifc_len = 0;
+ if_data.ifc_buf = NULL;
+
+ // Open a (random) socket to have a file descriptor for the ioctl calls.
+ fd = _Jv_socket (PF_INET, SOCK_DGRAM, htons (IPPROTO_IP));
+
+ if (fd < 0)
+ throw new ::java::net::SocketException;
+
+ // Get all interfaces. If not enough buffers are available try it
+ // with a bigger buffer size.
+ do
+ {
+ num_interfaces += 16;
+
+ if_data.ifc_len = sizeof (struct ifreq) * num_interfaces;
+ if_data.ifc_buf =
+ (char*) _Jv_Realloc (if_data.ifc_buf, if_data.ifc_len);
+
+ // Try to get all local interfaces.
+ if (::ioctl (fd, SIOCGIFCONF, &if_data) < 0)
+ throw new java::net::SocketException;
+ }
+ while (if_data.ifc_len >= (int) (sizeof (struct ifreq) * num_interfaces));
+
+ // Get addresses of all interfaces.
+ if_record = if_data.ifc_req;
+
+ for (int n = 0; n < if_data.ifc_len; n += sizeof (struct ifreq))
+ {
+ struct ifreq ifr;
+
+ memset (&ifr, 0, sizeof (ifr));
+ strcpy (ifr.ifr_name, if_record->ifr_name);
+
+ // Try to get the IPv4-address of the local interface
+ if (::ioctl (fd, SIOCGIFADDR, &ifr) < 0)
+ throw new java::net::SocketException;
+
+ int len = 4;
+ struct sockaddr_in sa = *((sockaddr_in*) &(ifr.ifr_addr));
+
+ jbyteArray baddr = JvNewByteArray (len);
+ memcpy (elements (baddr), &(sa.sin_addr), len);
+ jstring if_name = JvNewStringLatin1 (if_record->ifr_name);
+ InetAddress* address = java::net::InetAddress::getByAddress (baddr);
+ ht->add (new NetworkInterface (if_name, address));
+ if_record++;
+ }
+
+ _Jv_Free (if_data.ifc_buf);
+
+ if (fd >= 0)
+ _Jv_close (fd);
+#endif /* HAVE_GETIFADDRS */
+
+ return ht;
+}
diff --git a/gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceWin32.cc b/gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceWin32.cc
new file mode 100644
index 000000000..d42f33de9
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/net/natVMNetworkInterfaceWin32.cc
@@ -0,0 +1,144 @@
+/* Copyright (C) 2003, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#undef STRICT
+
+#include <java/net/NetworkInterface.h>
+#include <java/net/Inet4Address.h>
+#include <java/net/SocketException.h>
+#include <java/net/VMNetworkInterface.h>
+#include <java/util/Vector.h>
+
+/* As of this writing, NetworkInterface.java has
+ getName() == getDisplayName() and only one IP address
+ per interface. If this changes, we'll need to use
+ iphlpapi (not supported on Win95) to retrieve richer
+ adapter information via GetAdaptersInfo(). In this
+ module, we provide the necessary hooks to detect the
+ presence of iphlpapi and use it if necessary, but
+ comment things out for now to avoid compiler warnings. */
+
+enum {MAX_INTERFACES = 50};
+
+typedef int
+(*PfnGetRealNetworkInterfaces) (jstring* pjstrName,
+ java::net::InetAddress** ppAddress);
+
+static int
+winsock2GetRealNetworkInterfaces (jstring* pjstrName,
+ java::net::InetAddress** ppAddress)
+{
+ // FIXME: Add IPv6 support.
+
+ INTERFACE_INFO arInterfaceInfo[MAX_INTERFACES];
+
+ // Open a (random) socket to have a file descriptor for the WSAIoctl call.
+ SOCKET skt = ::socket (AF_INET, SOCK_DGRAM, 0);
+ if (skt == INVALID_SOCKET)
+ _Jv_ThrowSocketException ();
+
+ DWORD dwOutBufSize;
+ int nRetCode = ::WSAIoctl (skt, SIO_GET_INTERFACE_LIST,
+ NULL, 0, &arInterfaceInfo, sizeof(arInterfaceInfo),
+ &dwOutBufSize, NULL, NULL);
+
+ if (nRetCode == SOCKET_ERROR)
+ {
+ DWORD dwLastErrorCode = WSAGetLastError ();
+ ::closesocket (skt);
+ _Jv_ThrowSocketException (dwLastErrorCode);
+ }
+
+ // Get addresses of all interfaces.
+ int nNbInterfaces = dwOutBufSize / sizeof(INTERFACE_INFO);
+ int nCurETHInterface = 0;
+ for (int i=0; i < nNbInterfaces; ++i)
+ {
+ int len = 4;
+ jbyteArray baddr = JvNewByteArray (len);
+ SOCKADDR_IN* pAddr = (SOCKADDR_IN*) &arInterfaceInfo[i].iiAddress;
+ memcpy (elements (baddr), &(pAddr->sin_addr), len);
+
+ // Concoct a name for this interface. Since we don't
+ // have access to the real name under Winsock 2, we use
+ // "lo" for the loopback interface and ethX for the
+ // real ones.
+ TCHAR szName[30];
+ u_long lFlags = arInterfaceInfo[i].iiFlags;
+
+ if (lFlags & IFF_LOOPBACK)
+ _tcscpy (szName, _T("lo"));
+ else
+ {
+ _tcscpy (szName, _T("eth"));
+ wsprintf(szName+3, _T("%d"), nCurETHInterface++);
+ }
+
+ jstring if_name = _Jv_Win32NewString (szName);
+ java::net::Inet4Address* address =
+ new java::net::Inet4Address (baddr, JvNewStringLatin1 (""));
+ pjstrName[i] = if_name;
+ ppAddress[i] = address;
+ }
+
+ ::closesocket (skt);
+
+ return nNbInterfaces;
+}
+
+/*
+static int
+iphlpapiGetRealNetworkInterfaces (jstring* pjstrName,
+ java::net::InetAddress** ppAddress)
+{
+ return 0;
+}
+*/
+
+static PfnGetRealNetworkInterfaces
+determineGetRealNetworkInterfacesFN ()
+{
+ /* FIXME: Try to dynamically load iphlpapi.dll and
+ detect the presence of GetAdaptersInfo() using
+ GetProcAddress(). If successful, return
+ iphlpapiGetRealNetworkInterfaces; if not,
+ return winsock2GetRealNetworkInterfaces */
+ return &winsock2GetRealNetworkInterfaces;
+}
+
+::java::util::Vector*
+java::net::VMNetworkInterface::getInterfaces ()
+{
+ // This next declaration used to be a static local,
+ // but this introduced a dependency on libsupc++ due
+ // to _cxa_guard_acquire and _cxa_guard_release.
+ // When Win95 is gone and we eventually get rid of
+ // winsock2GetRealNetworkInterfaces, we can rework
+ // all of this. Alternatively, we could move this all
+ // to win32.cc and initialize this at startup time,
+ // but that seems more trouble than it's worth at
+ // the moment.
+ PfnGetRealNetworkInterfaces pfn =
+ determineGetRealNetworkInterfacesFN ();
+
+ jstring arIFName[MAX_INTERFACES];
+ InetAddress* arpInetAddress[MAX_INTERFACES];
+ ::java::util::Vector* ht = new ::java::util::Vector ();
+
+ int nNbInterfaces = (*pfn) (arIFName, arpInetAddress);
+ for (int i=0; i < nNbInterfaces; ++i)
+ {
+ ht->add (new java::net::NetworkInterface (arIFName[i],
+ arpInetAddress[i]));
+ }
+
+ return ht;
+}
diff --git a/gcc-4.2.1/libjava/java/nio/Buffer.java b/gcc-4.2.1/libjava/java/nio/Buffer.java
new file mode 100644
index 000000000..f369b9622
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/Buffer.java
@@ -0,0 +1,361 @@
+/* Buffer.java --
+ Copyright (C) 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.nio;
+
+import gnu.gcj.RawData;
+
+/**
+ * @since 1.4
+ */
+public abstract class Buffer
+{
+ int cap = 0;
+ int limit = 0;
+ int pos = 0;
+ int mark = -1;
+ RawData address;
+
+ /**
+ * Creates a new Buffer.
+ *
+ * Should be package private.
+ */
+ Buffer (int capacity, int limit, int position, int mark)
+ {
+ if (capacity < 0)
+ throw new IllegalArgumentException ();
+
+ cap = capacity;
+ limit (limit);
+ position (position);
+
+ if (mark >= 0)
+ {
+ if (mark > pos)
+ throw new IllegalArgumentException ();
+
+ this.mark = mark;
+ }
+ }
+
+ /**
+ * Retrieves the capacity of the buffer.
+ *
+ * @return the capacity of the buffer
+ */
+ public final int capacity ()
+ {
+ return cap;
+ }
+
+ /**
+ * Clears the buffer.
+ *
+ * @return this buffer
+ */
+ public final Buffer clear ()
+ {
+ limit = cap;
+ pos = 0;
+ mark = -1;
+ return this;
+ }
+
+ /**
+ * Flips the buffer.
+ *
+ * @return this buffer
+ */
+ public final Buffer flip ()
+ {
+ limit = pos;
+ pos = 0;
+ mark = -1;
+ return this;
+ }
+
+ /**
+ * Tells whether the buffer has remaining data to read or not.
+ *
+ * @return true if the buffer contains remaining data to read,
+ * false otherwise
+ */
+ public final boolean hasRemaining ()
+ {
+ return remaining() > 0;
+ }
+
+ /**
+ * Tells whether this buffer is read only or not.
+ *
+ * @return true if the buffer is read only, false otherwise
+ */
+ public abstract boolean isReadOnly ();
+
+ /**
+ * Retrieves the current limit of the buffer.
+ *
+ * @return the limit of the buffer
+ */
+ public final int limit ()
+ {
+ return limit;
+ }
+
+ /**
+ * Sets this buffer's limit.
+ *
+ * @param newLimit The new limit value; must be non-negative and no larger
+ * than this buffer's capacity.
+ *
+ * @return this buffer
+ *
+ * @exception IllegalArgumentException If the preconditions on newLimit
+ * do not hold.
+ */
+ public final Buffer limit (int newLimit)
+ {
+ if ((newLimit < 0) || (newLimit > cap))
+ throw new IllegalArgumentException ();
+
+ if (newLimit < mark)
+ mark = -1;
+
+ if (pos > newLimit)
+ pos = newLimit;
+
+ limit = newLimit;
+ return this;
+ }
+
+ /**
+ * Sets this buffer's mark at its position.
+ *
+ * @return this buffer
+ */
+ public final Buffer mark ()
+ {
+ mark = pos;
+ return this;
+ }
+
+ /**
+ * Retrieves the current position of this buffer.
+ *
+ * @return the current position of this buffer
+ */
+ public final int position ()
+ {
+ return pos;
+ }
+
+ /**
+ * Sets this buffer's position. If the mark is defined and larger than the
+ * new position then it is discarded.
+ *
+ * @param newPosition The new position value; must be non-negative and no
+ * larger than the current limit.
+ *
+ * @return this buffer
+ *
+ * @exception IllegalArgumentException If the preconditions on newPosition
+ * do not hold
+ */
+ public final Buffer position (int newPosition)
+ {
+ if ((newPosition < 0) || (newPosition > limit))
+ throw new IllegalArgumentException ();
+
+ if (newPosition <= mark)
+ mark = -1;
+
+ pos = newPosition;
+ return this;
+ }
+
+ /**
+ * Returns the number of elements between the current position and the limit.
+ *
+ * @return the number of remaining elements
+ */
+ public final int remaining()
+ {
+ return limit - pos;
+ }
+
+ /**
+ * Resets this buffer's position to the previously-marked position.
+ *
+ * @return this buffer
+ *
+ * @exception InvalidMarkException If the mark has not been set.
+ */
+ public final Buffer reset()
+ {
+ if (mark == -1)
+ throw new InvalidMarkException ();
+
+ pos = mark;
+ return this;
+ }
+
+ /**
+ * Rewinds this buffer. The position is set to zero and the mark
+ * is discarded.
+ *
+ * @return this buffer
+ */
+ public final Buffer rewind()
+ {
+ pos = 0;
+ mark = -1;
+ return this;
+ }
+
+ /**
+ * Checks for underflow. This method is used internally to check
+ * whether a buffer has enough elements left to satisfy a read
+ * request.
+ *
+ * @exception BufferUnderflowException If there are no remaining
+ * elements in this buffer.
+ */
+ final void checkForUnderflow()
+ {
+ if (!hasRemaining())
+ throw new BufferUnderflowException();
+ }
+
+ /**
+ * Checks for underflow. This method is used internally to check
+ * whether a buffer has enough elements left to satisfy a read
+ * request for a given number of elements.
+ *
+ * @param length The length of a sequence of elements.
+ *
+ * @exception BufferUnderflowException If there are not enough
+ * remaining elements in this buffer.
+ */
+ final void checkForUnderflow(int length)
+ {
+ if (remaining() < length)
+ throw new BufferUnderflowException();
+ }
+
+ /**
+ * Checks for overflow. This method is used internally to check
+ * whether a buffer has enough space left to satisfy a write
+ * request.
+ *
+ * @exception BufferOverflowException If there is no remaining
+ * space in this buffer.
+ */
+ final void checkForOverflow()
+ {
+ if (!hasRemaining())
+ throw new BufferOverflowException();
+ }
+
+ /**
+ * Checks for overflow. This method is used internally to check
+ * whether a buffer has enough space left to satisfy a write
+ * request for a given number of elements.
+ *
+ * @param length The length of a sequence of elements.
+ *
+ * @exception BufferUnderflowException If there is not enough
+ * remaining space in this buffer.
+ */
+ final void checkForOverflow(int length)
+ {
+ if (remaining() < length)
+ throw new BufferOverflowException();
+ }
+
+ /**
+ * Checks if index is negative or not smaller than the buffer's
+ * limit. This method is used internally to check whether
+ * an indexed request can be fulfilled.
+ *
+ * @param index The requested position in the buffer.
+ *
+ * @exception IndexOutOfBoundsException If index is negative or not smaller
+ * than the buffer's limit.
+ */
+ final void checkIndex(int index)
+ {
+ if (index < 0
+ || index >= limit ())
+ throw new IndexOutOfBoundsException ();
+ }
+
+ /**
+ * Checks if buffer is read-only. This method is used internally to
+ * check if elements can be put into a buffer.
+ *
+ * @exception ReadOnlyBufferException If this buffer is read-only.
+ */
+ final void checkIfReadOnly()
+ {
+ if (isReadOnly())
+ throw new ReadOnlyBufferException ();
+ }
+
+ /**
+ * Checks whether an array is large enough to hold the given number of
+ * elements at the given offset. This method is used internally to
+ * check if an array is big enough.
+ *
+ * @param arraylength The length of the array.
+ * @param offset The offset within the array of the first byte to be read;
+ * must be non-negative and no larger than arraylength.
+ * @param length The number of bytes to be read from the given array;
+ * must be non-negative and no larger than arraylength - offset.
+ *
+ * @exception IndexOutOfBoundsException If the preconditions on the offset
+ * and length parameters do not hold
+ */
+ static final void checkArraySize(int arraylength, int offset, int length)
+ {
+ if ((offset < 0) ||
+ (length < 0) ||
+ (arraylength < length + offset))
+ throw new IndexOutOfBoundsException ();
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/nio/DirectByteBufferImpl.java b/gcc-4.2.1/libjava/java/nio/DirectByteBufferImpl.java
new file mode 100644
index 000000000..e448ea97c
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/DirectByteBufferImpl.java
@@ -0,0 +1,431 @@
+/* DirectByteBufferImpl.java --
+ Copyright (C) 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.nio;
+
+import gnu.gcj.RawData;
+
+abstract class DirectByteBufferImpl extends ByteBuffer
+{
+ /**
+ * The owner is used to keep alive the object that actually owns the
+ * memory. There are three possibilities:
+ * 1) owner == this: We allocated the memory and we should free it,
+ * but *only* in finalize (if we've been sliced
+ * other objects will also have access to the
+ * memory).
+ * 2) owner == null: The byte buffer was created thru
+ * JNI.NewDirectByteBuffer. The JNI code is
+ * responsible for freeing the memory.
+ * 3) owner == some other object: The other object allocated the
+ * memory and should free it.
+ */
+ private final Object owner;
+
+ static final class ReadOnly extends DirectByteBufferImpl
+ {
+ ReadOnly(Object owner, RawData address,
+ int capacity, int limit,
+ int position)
+ {
+ super(owner, address, capacity, limit, position);
+ }
+
+ public ByteBuffer put(byte value)
+ {
+ throw new ReadOnlyBufferException ();
+ }
+
+ public ByteBuffer put(int index, byte value)
+ {
+ throw new ReadOnlyBufferException ();
+ }
+
+ public boolean isReadOnly()
+ {
+ return true;
+ }
+ }
+
+ static final class ReadWrite extends DirectByteBufferImpl
+ {
+ ReadWrite(int capacity)
+ {
+ super(capacity);
+ }
+
+ ReadWrite(RawData address, int capacity)
+ {
+ super(address, capacity);
+ }
+
+ ReadWrite(Object owner, RawData address,
+ int capacity, int limit,
+ int position)
+ {
+ super(owner, address, capacity, limit, position);
+ }
+
+ public boolean isReadOnly()
+ {
+ return false;
+ }
+ }
+
+ DirectByteBufferImpl(int capacity)
+ {
+ super(capacity, capacity, 0, -1);
+ this.owner = this;
+ this.address = VMDirectByteBuffer.allocate(capacity);
+ }
+
+ DirectByteBufferImpl(RawData address, int capacity)
+ {
+ super(capacity, capacity, 0, -1);
+ this.owner = null;
+ this.address = address;
+ }
+
+ DirectByteBufferImpl(Object owner, RawData address,
+ int capacity, int limit,
+ int position)
+ {
+ super(capacity, limit, position, -1);
+ this.owner = owner;
+ this.address = address;
+ }
+
+ /**
+ * Allocates a new direct byte buffer.
+ */
+ public static ByteBuffer allocate(int capacity)
+ {
+ return new DirectByteBufferImpl.ReadWrite(capacity);
+ }
+
+ protected void finalize() throws Throwable
+ {
+ if (owner == this)
+ VMDirectByteBuffer.free(address);
+ }
+
+ public byte get()
+ {
+ checkForUnderflow();
+
+ int pos = position();
+ byte result = VMDirectByteBuffer.get(address, pos);
+ position(pos + 1);
+ return result;
+ }
+
+ public byte get(int index)
+ {
+ checkIndex(index);
+
+ return VMDirectByteBuffer.get(address, index);
+ }
+
+ public ByteBuffer get(byte[] dst, int offset, int length)
+ {
+ checkArraySize(dst.length, offset, length);
+ checkForUnderflow(length);
+
+ int index = position();
+ VMDirectByteBuffer.get(address, index, dst, offset, length);
+ position(index+length);
+
+ return this;
+ }
+
+ public ByteBuffer put(byte value)
+ {
+ checkForOverflow();
+
+ int pos = position();
+ VMDirectByteBuffer.put(address, pos, value);
+ position(pos + 1);
+ return this;
+ }
+
+ public ByteBuffer put(int index, byte value)
+ {
+ checkIndex(index);
+
+ VMDirectByteBuffer.put(address, index, value);
+ return this;
+ }
+
+ void shiftDown(int dst_offset, int src_offset, int count)
+ {
+ VMDirectByteBuffer.shiftDown(address, dst_offset, src_offset, count);
+ }
+
+ public ByteBuffer compact()
+ {
+ checkIfReadOnly();
+ mark = -1;
+ int pos = position();
+ if (pos > 0)
+ {
+ int count = remaining();
+ VMDirectByteBuffer.shiftDown(address, 0, pos, count);
+ position(count);
+ limit(capacity());
+ }
+ else
+ {
+ position(limit());
+ limit(capacity());
+ }
+ return this;
+ }
+
+ public ByteBuffer slice()
+ {
+ int rem = remaining();
+ if (isReadOnly())
+ return new DirectByteBufferImpl.ReadOnly
+ (owner, VMDirectByteBuffer.adjustAddress(address, position()),
+ rem, rem, 0);
+ else
+ return new DirectByteBufferImpl.ReadWrite
+ (owner, VMDirectByteBuffer.adjustAddress(address, position()),
+ rem, rem, 0);
+ }
+
+ private ByteBuffer duplicate(boolean readOnly)
+ {
+ int pos = position();
+ reset();
+ int mark = position();
+ position(pos);
+ DirectByteBufferImpl result;
+ if (readOnly)
+ result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(),
+ limit(), pos);
+ else
+ result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(),
+ limit(), pos);
+
+ if (mark != pos)
+ {
+ result.position(mark);
+ result.mark();
+ result.position(pos);
+ }
+ return result;
+ }
+
+ public ByteBuffer duplicate()
+ {
+ return duplicate(isReadOnly());
+ }
+
+ public ByteBuffer asReadOnlyBuffer()
+ {
+ return duplicate(true);
+ }
+
+ public boolean isDirect()
+ {
+ return true;
+ }
+
+ public CharBuffer asCharBuffer()
+ {
+ return new CharViewBufferImpl(this, remaining() >> 1);
+ }
+
+ public ShortBuffer asShortBuffer()
+ {
+ return new ShortViewBufferImpl(this, remaining() >> 1);
+ }
+
+ public IntBuffer asIntBuffer()
+ {
+ return new IntViewBufferImpl(this, remaining() >> 2);
+ }
+
+ public LongBuffer asLongBuffer()
+ {
+ return new LongViewBufferImpl(this, remaining() >> 3);
+ }
+
+ public FloatBuffer asFloatBuffer()
+ {
+ return new FloatViewBufferImpl(this, remaining() >> 2);
+ }
+
+ public DoubleBuffer asDoubleBuffer()
+ {
+ return new DoubleViewBufferImpl(this, remaining() >> 3);
+ }
+
+ public char getChar()
+ {
+ return ByteBufferHelper.getChar(this, order());
+ }
+
+ public ByteBuffer putChar(char value)
+ {
+ ByteBufferHelper.putChar(this, value, order());
+ return this;
+ }
+
+ public char getChar(int index)
+ {
+ return ByteBufferHelper.getChar(this, index, order());
+ }
+
+ public ByteBuffer putChar(int index, char value)
+ {
+ ByteBufferHelper.putChar(this, index, value, order());
+ return this;
+ }
+
+ public short getShort()
+ {
+ return ByteBufferHelper.getShort(this, order());
+ }
+
+ public ByteBuffer putShort(short value)
+ {
+ ByteBufferHelper.putShort(this, value, order());
+ return this;
+ }
+
+ public short getShort(int index)
+ {
+ return ByteBufferHelper.getShort(this, index, order());
+ }
+
+ public ByteBuffer putShort(int index, short value)
+ {
+ ByteBufferHelper.putShort(this, index, value, order());
+ return this;
+ }
+
+ public int getInt()
+ {
+ return ByteBufferHelper.getInt(this, order());
+ }
+
+ public ByteBuffer putInt(int value)
+ {
+ ByteBufferHelper.putInt(this, value, order());
+ return this;
+ }
+
+ public int getInt(int index)
+ {
+ return ByteBufferHelper.getInt(this, index, order());
+ }
+
+ public ByteBuffer putInt(int index, int value)
+ {
+ ByteBufferHelper.putInt(this, index, value, order());
+ return this;
+ }
+
+ public long getLong()
+ {
+ return ByteBufferHelper.getLong(this, order());
+ }
+
+ public ByteBuffer putLong(long value)
+ {
+ ByteBufferHelper.putLong(this, value, order());
+ return this;
+ }
+
+ public long getLong(int index)
+ {
+ return ByteBufferHelper.getLong(this, index, order());
+ }
+
+ public ByteBuffer putLong(int index, long value)
+ {
+ ByteBufferHelper.putLong(this, index, value, order());
+ return this;
+ }
+
+ public float getFloat()
+ {
+ return ByteBufferHelper.getFloat(this, order());
+ }
+
+ public ByteBuffer putFloat(float value)
+ {
+ ByteBufferHelper.putFloat(this, value, order());
+ return this;
+ }
+
+ public float getFloat(int index)
+ {
+ return ByteBufferHelper.getFloat(this, index, order());
+ }
+
+ public ByteBuffer putFloat(int index, float value)
+ {
+ ByteBufferHelper.putFloat(this, index, value, order());
+ return this;
+ }
+
+ public double getDouble()
+ {
+ return ByteBufferHelper.getDouble(this, order());
+ }
+
+ public ByteBuffer putDouble(double value)
+ {
+ ByteBufferHelper.putDouble(this, value, order());
+ return this;
+ }
+
+ public double getDouble(int index)
+ {
+ return ByteBufferHelper.getDouble(this, index, order());
+ }
+
+ public ByteBuffer putDouble(int index, double value)
+ {
+ ByteBufferHelper.putDouble(this, index, value, order());
+ return this;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/nio/MappedByteBuffer.java b/gcc-4.2.1/libjava/java/nio/MappedByteBuffer.java
new file mode 100644
index 000000000..9b6df1715
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/MappedByteBuffer.java
@@ -0,0 +1,89 @@
+/* MappedByteBuffer.java --
+ Copyright (C) 2002, 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;
+
+/**
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.4
+ */
+public abstract class MappedByteBuffer extends ByteBuffer
+{
+ MappedByteBuffer (int capacity, int limit, int position, int mark)
+ {
+ super (capacity, limit, position, mark);
+ }
+
+ void forceImpl()
+ {
+ }
+
+ public final MappedByteBuffer force ()
+ {
+ forceImpl();
+ return this;
+ }
+
+ boolean isLoadedImpl()
+ {
+ load();
+ return true;
+ }
+
+ public final boolean isLoaded ()
+ {
+ return isLoadedImpl();
+ }
+
+ void loadImpl()
+ {
+ }
+
+ public final MappedByteBuffer load ()
+ {
+ loadImpl();
+ return this;
+ }
+
+ void unmapImpl ()
+ {
+ forceImpl();
+ }
+
+ public void finalize () { unmapImpl(); }
+}
diff --git a/gcc-4.2.1/libjava/java/nio/MappedByteBufferImpl.java b/gcc-4.2.1/libjava/java/nio/MappedByteBufferImpl.java
new file mode 100644
index 000000000..444eeea91
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/MappedByteBufferImpl.java
@@ -0,0 +1,360 @@
+/* MappedByteBufferImpl.java --
+ Copyright (C) 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.nio;
+
+import gnu.gcj.RawData;
+
+import java.io.IOException;
+
+final class MappedByteBufferImpl extends MappedByteBuffer
+{
+ boolean readOnly;
+
+ /** Posix uses this for the pointer returned by mmap;
+ * Win32 uses it for the pointer returned by MapViewOfFile. */
+ public RawData implPtr;
+ /** Posix uses this for the actual length passed to mmap;
+ * Win32 uses it for the pointer returned by CreateFileMapping. */
+ public long implLen;
+
+ public MappedByteBufferImpl(RawData address, int size, boolean readOnly)
+ throws IOException
+ {
+ super(size, size, 0, -1);
+ this.address = address;
+ this.readOnly = readOnly;
+ }
+
+ public boolean isReadOnly()
+ {
+ return readOnly;
+ }
+
+ public byte get()
+ {
+ checkForUnderflow();
+
+ int pos = position();
+ byte result = VMDirectByteBuffer.get(address, pos);
+ position(pos + 1);
+ return result;
+ }
+
+ public ByteBuffer put(byte value)
+ {
+ checkIfReadOnly();
+ checkForOverflow();
+
+ int pos = position();
+ VMDirectByteBuffer.put(address, pos, value);
+ position(pos + 1);
+ return this;
+ }
+
+ public byte get(int index)
+ {
+ checkIndex(index);
+
+ return VMDirectByteBuffer.get(address, index);
+ }
+
+ public ByteBuffer get(byte[] dst, int offset, int length)
+ {
+ checkArraySize(dst.length, offset, length);
+ checkForUnderflow(length);
+
+ int index = position();
+ VMDirectByteBuffer.get(address, index, dst, offset, length);
+ position(index+length);
+
+ return this;
+ }
+
+ public ByteBuffer put(int index, byte value)
+ {
+ checkIfReadOnly();
+ checkIndex(index);
+
+ VMDirectByteBuffer.put(address, index, value);
+ return this;
+ }
+
+ public ByteBuffer compact()
+ {
+ checkIfReadOnly();
+ mark = -1;
+ int pos = position();
+ if (pos > 0)
+ {
+ int count = remaining();
+ // Call shiftDown method optimized for direct buffers.
+ VMDirectByteBuffer.shiftDown(address, 0, pos, count);
+ position(count);
+ limit(capacity());
+ }
+ else
+ {
+ position(limit());
+ limit(capacity());
+ }
+ return this;
+ }
+
+ public boolean isDirect()
+ {
+ return true;
+ }
+
+ public ByteBuffer slice()
+ {
+ int rem = remaining();
+ if (isReadOnly())
+ return new DirectByteBufferImpl.ReadOnly
+ (this, VMDirectByteBuffer.adjustAddress(address, position()),
+ rem, rem, 0);
+ else
+ return new DirectByteBufferImpl.ReadWrite
+ (this, VMDirectByteBuffer.adjustAddress(address, position()),
+ rem, rem, 0);
+ }
+
+ private ByteBuffer duplicate(boolean readOnly)
+ {
+ int pos = position();
+ reset();
+ int mark = position();
+ position(pos);
+ DirectByteBufferImpl result;
+ if (readOnly)
+ result = new DirectByteBufferImpl.ReadOnly(this, address, capacity(),
+ limit(), pos);
+ else
+ result = new DirectByteBufferImpl.ReadWrite(this, address, capacity(),
+ limit(), pos);
+
+ if (mark != pos)
+ {
+ result.position(mark);
+ result.mark();
+ result.position(pos);
+ }
+ return result;
+ }
+
+ public ByteBuffer duplicate()
+ {
+ return duplicate(isReadOnly());
+ }
+
+ public ByteBuffer asReadOnlyBuffer()
+ {
+ return duplicate(true);
+ }
+
+ public CharBuffer asCharBuffer()
+ {
+ return new CharViewBufferImpl(this, remaining() >> 1);
+ }
+
+ public ShortBuffer asShortBuffer()
+ {
+ return new ShortViewBufferImpl(this, remaining() >> 1);
+ }
+
+ public IntBuffer asIntBuffer()
+ {
+ return new IntViewBufferImpl(this, remaining() >> 2);
+ }
+
+ public LongBuffer asLongBuffer()
+ {
+ return new LongViewBufferImpl(this, remaining() >> 3);
+ }
+
+ public FloatBuffer asFloatBuffer()
+ {
+ return new FloatViewBufferImpl(this, remaining() >> 2);
+ }
+
+ public DoubleBuffer asDoubleBuffer()
+ {
+ return new DoubleViewBufferImpl(this, remaining() >> 3);
+ }
+
+ public char getChar()
+ {
+ return ByteBufferHelper.getChar(this, order());
+ }
+
+ public ByteBuffer putChar(char value)
+ {
+ ByteBufferHelper.putChar(this, value, order());
+ return this;
+ }
+
+ public char getChar(int index)
+ {
+ return ByteBufferHelper.getChar(this, index, order());
+ }
+
+ public ByteBuffer putChar(int index, char value)
+ {
+ ByteBufferHelper.putChar(this, index, value, order());
+ return this;
+ }
+
+ public short getShort()
+ {
+ return ByteBufferHelper.getShort(this, order());
+ }
+
+ public ByteBuffer putShort(short value)
+ {
+ ByteBufferHelper.putShort(this, value, order());
+ return this;
+ }
+
+ public short getShort(int index)
+ {
+ return ByteBufferHelper.getShort(this, index, order());
+ }
+
+ public ByteBuffer putShort(int index, short value)
+ {
+ ByteBufferHelper.putShort(this, index, value, order());
+ return this;
+ }
+
+ public int getInt()
+ {
+ return ByteBufferHelper.getInt(this, order());
+ }
+
+ public ByteBuffer putInt(int value)
+ {
+ ByteBufferHelper.putInt(this, value, order());
+ return this;
+ }
+
+ public int getInt(int index)
+ {
+ return ByteBufferHelper.getInt(this, index, order());
+ }
+
+ public ByteBuffer putInt(int index, int value)
+ {
+ ByteBufferHelper.putInt(this, index, value, order());
+ return this;
+ }
+
+ public long getLong()
+ {
+ return ByteBufferHelper.getLong(this, order());
+ }
+
+ public ByteBuffer putLong(long value)
+ {
+ ByteBufferHelper.putLong(this, value, order());
+ return this;
+ }
+
+ public long getLong(int index)
+ {
+ return ByteBufferHelper.getLong(this, index, order());
+ }
+
+ public ByteBuffer putLong(int index, long value)
+ {
+ ByteBufferHelper.putLong(this, index, value, order());
+ return this;
+ }
+
+ public float getFloat()
+ {
+ return ByteBufferHelper.getFloat(this, order());
+ }
+
+ public ByteBuffer putFloat(float value)
+ {
+ ByteBufferHelper.putFloat(this, value, order());
+ return this;
+ }
+
+ public float getFloat(int index)
+ {
+ return ByteBufferHelper.getFloat(this, index, order());
+ }
+
+ public ByteBuffer putFloat(int index, float value)
+ {
+ ByteBufferHelper.putFloat(this, index, value, order());
+ return this;
+ }
+
+ public double getDouble()
+ {
+ return ByteBufferHelper.getDouble(this, order());
+ }
+
+ public ByteBuffer putDouble(double value)
+ {
+ ByteBufferHelper.putDouble(this, value, order());
+ return this;
+ }
+
+ public double getDouble(int index)
+ {
+ return ByteBufferHelper.getDouble(this, index, order());
+ }
+
+ public ByteBuffer putDouble(int index, double value)
+ {
+ ByteBufferHelper.putDouble(this, index, value, order());
+ return this;
+ }
+
+ // NOTE: In libgcj these methods are implemented in natFileChannelXxx.cc,
+ // because they're small, and to put them next to FileChannelImpl::mapImpl.
+ native void unmapImpl();
+ native boolean isLoadedImpl();
+ // FIXME: Try to load all pages into memory.
+ native void loadImpl();
+
+ native void forceImpl();
+}
diff --git a/gcc-4.2.1/libjava/java/nio/VMDirectByteBuffer.java b/gcc-4.2.1/libjava/java/nio/VMDirectByteBuffer.java
new file mode 100644
index 000000000..2aefaeb4b
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/VMDirectByteBuffer.java
@@ -0,0 +1,53 @@
+/* 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.gcj.RawData;
+
+final class VMDirectByteBuffer
+{
+ 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);
+}
diff --git a/gcc-4.2.1/libjava/java/nio/channels/VMChannels.java b/gcc-4.2.1/libjava/java/nio/channels/VMChannels.java
new file mode 100644
index 000000000..4f43a42ad
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/channels/VMChannels.java
@@ -0,0 +1,85 @@
+/* VMChannels.java --
+ Copyright (C) 2005, 2006 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.
+ }
+
+ static native FileInputStream newInputStream(FileChannelImpl ch);
+
+ static native FileOutputStream newOutputStream(FileChannelImpl ch);
+
+ /**
+ * Constructs a stream that reads bytes from the given channel.
+ */
+ static InputStream newInputStream(ReadableByteChannel ch)
+ {
+ if (ch instanceof FileChannelImpl)
+ return newInputStream((FileChannelImpl) 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 newOutputStream((FileChannelImpl) ch);
+ return new ChannelOutputStream(ch);
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/nio/channels/natVMChannels.cc b/gcc-4.2.1/libjava/java/nio/channels/natVMChannels.cc
new file mode 100644
index 000000000..d40a51653
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/channels/natVMChannels.cc
@@ -0,0 +1,37 @@
+// natVMChannels.cc - Native part of VMChannels class.
+
+/* Copyright (C) 2004, 2006 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <gcj/cni.h>
+
+#include <java/nio/channels/VMChannels.h>
+#include <java/nio/channels/Channels.h>
+#include <java/io/FileInputStream.h>
+#include <java/io/FileOutputStream.h>
+#include <gnu/java/nio/channels/FileChannelImpl.h>
+
+using java::nio::channels::VMChannels;
+using java::io::FileInputStream;
+using java::io::FileOutputStream;
+using gnu::java::nio::channels::FileChannelImpl;
+
+FileInputStream*
+VMChannels::newInputStream(FileChannelImpl* ch)
+{
+ // Needs to be native to bypass Java access protection.
+ return new FileInputStream (ch);
+}
+
+FileOutputStream*
+VMChannels::newOutputStream(FileChannelImpl* ch)
+{
+ // Needs to be native to bypass Java access protection.
+ return new FileOutputStream (ch);
+}
diff --git a/gcc-4.2.1/libjava/java/nio/charset/Charset.java b/gcc-4.2.1/libjava/java/nio/charset/Charset.java
new file mode 100644
index 000000000..48093bc9d
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/charset/Charset.java
@@ -0,0 +1,412 @@
+/* Charset.java --
+ Copyright (C) 2002, 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.nio.charset;
+
+import gnu.classpath.ServiceFactory;
+import gnu.classpath.SystemProperties;
+import gnu.java.nio.charset.Provider;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.spi.CharsetProvider;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * @author Jesse Rosenstock
+ * @since 1.4
+ */
+public abstract class Charset implements Comparable
+{
+ private CharsetEncoder cachedEncoder;
+ private CharsetDecoder cachedDecoder;
+
+ /**
+ * Charset providers.
+ */
+ private static CharsetProvider[] providers;
+
+ private final String canonicalName;
+ private final String[] aliases;
+
+ protected Charset (String canonicalName, String[] aliases)
+ {
+ checkName (canonicalName);
+ if (aliases != null)
+ {
+ int n = aliases.length;
+ for (int i = 0; i < n; ++i)
+ checkName (aliases[i]);
+ }
+
+ cachedEncoder = null;
+ cachedDecoder = null;
+ this.canonicalName = canonicalName;
+ this.aliases = aliases;
+ }
+
+ /**
+ * @throws IllegalCharsetNameException if the name is illegal
+ */
+ private static void checkName (String name)
+ {
+ int n = name.length ();
+
+ if (n == 0)
+ throw new IllegalCharsetNameException (name);
+
+ char ch = name.charAt (0);
+ if (!(('A' <= ch && ch <= 'Z')
+ || ('a' <= ch && ch <= 'z')
+ || ('0' <= ch && ch <= '9')))
+ throw new IllegalCharsetNameException (name);
+
+ for (int i = 1; i < n; ++i)
+ {
+ ch = name.charAt (i);
+ if (!(('A' <= ch && ch <= 'Z')
+ || ('a' <= ch && ch <= 'z')
+ || ('0' <= ch && ch <= '9')
+ || ch == '-' || ch == '.' || ch == ':' || ch == '_'))
+ throw new IllegalCharsetNameException (name);
+ }
+ }
+
+ /**
+ * Returns the system default charset.
+ *
+ * This may be set by the user or VM with the file.encoding
+ * property.
+ *
+ * @since 1.5
+ */
+ public static Charset defaultCharset()
+ {
+ String encoding;
+
+ try
+ {
+ encoding = SystemProperties.getProperty("file.encoding");
+ }
+ catch(SecurityException e)
+ {
+ // Use fallback.
+ encoding = "ISO-8859-1";
+ }
+ catch(IllegalArgumentException e)
+ {
+ // Use fallback.
+ encoding = "ISO-8859-1";
+ }
+
+ try
+ {
+ return forName(encoding);
+ }
+ catch(UnsupportedCharsetException e)
+ {
+ // Ignore.
+ }
+ catch(IllegalCharsetNameException e)
+ {
+ // Ignore.
+ }
+ catch(IllegalArgumentException e)
+ {
+ // Ignore.
+ }
+
+ throw new IllegalStateException("Can't get default charset!");
+ }
+
+ public static boolean isSupported (String charsetName)
+ {
+ return charsetForName (charsetName) != null;
+ }
+
+ /**
+ * Returns the Charset instance for the charset of the given name.
+ *
+ * @param charsetName
+ * @return
+ * @throws UnsupportedCharsetException if this VM does not support
+ * the charset of the given name.
+ * @throws IllegalCharsetNameException if the given charset name is
+ * legal.
+ * @throws IllegalArgumentException if <code>charsetName</code> is null.
+ */
+ public static Charset forName (String charsetName)
+ {
+ // Throws IllegalArgumentException as the JDK does.
+ if(charsetName == null)
+ throw new IllegalArgumentException("Charset name must not be null.");
+
+ Charset cs = charsetForName (charsetName);
+ if (cs == null)
+ throw new UnsupportedCharsetException (charsetName);
+ return cs;
+ }
+
+ /**
+ * Retrieves a charset for the given charset name.
+ *
+ * @return A charset object for the charset with the specified name, or
+ * <code>null</code> if no such charset exists.
+ *
+ * @throws IllegalCharsetNameException if the name is illegal
+ */
+ private static Charset charsetForName(String charsetName)
+ {
+ checkName (charsetName);
+ // Try the default provider first
+ // (so we don't need to load external providers unless really necessary)
+ // if it is an exotic charset try loading the external providers.
+ Charset cs = provider().charsetForName(charsetName);
+ if (cs == null)
+ {
+ CharsetProvider[] providers = providers2();
+ for (int i = 0; i < providers.length; i++)
+ {
+ cs = providers[i].charsetForName(charsetName);
+ if (cs != null)
+ break;
+ }
+ }
+ return cs;
+ }
+
+ public static SortedMap availableCharsets()
+ {
+ TreeMap charsets = new TreeMap(String.CASE_INSENSITIVE_ORDER);
+ for (Iterator i = provider().charsets(); i.hasNext(); )
+ {
+ Charset cs = (Charset) i.next();
+ charsets.put(cs.name(), cs);
+ }
+
+ CharsetProvider[] providers = providers2();
+ for (int j = 0; j < providers.length; j++)
+ {
+ for (Iterator i = providers[j].charsets(); i.hasNext(); )
+ {
+ Charset cs = (Charset) i.next();
+ charsets.put(cs.name(), cs);
+ }
+ }
+
+ return Collections.unmodifiableSortedMap(charsets);
+ }
+
+ private static CharsetProvider provider()
+ {
+ try
+ {
+ String s = System.getProperty("charset.provider");
+ if (s != null)
+ {
+ CharsetProvider p =
+ (CharsetProvider) ((Class.forName(s)).newInstance());
+ return p;
+ }
+ }
+ catch (Exception e)
+ {
+ // Ignore.
+ }
+
+ return Provider.provider();
+ }
+
+ /**
+ * We need to support multiple providers, reading them from
+ * java.nio.charset.spi.CharsetProvider in the resource directory
+ * META-INF/services. This returns the "extra" charset providers.
+ */
+ private static CharsetProvider[] providers2()
+ {
+ if (providers == null)
+ {
+ try
+ {
+ Iterator i = ServiceFactory.lookupProviders(CharsetProvider.class);
+ LinkedHashSet set = new LinkedHashSet();
+ while (i.hasNext())
+ set.add(i.next());
+
+ providers = new CharsetProvider[set.size()];
+ set.toArray(providers);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ return providers;
+ }
+
+ public final String name ()
+ {
+ return canonicalName;
+ }
+
+ public final Set aliases ()
+ {
+ if (aliases == null)
+ return Collections.EMPTY_SET;
+
+ // should we cache the aliasSet instead?
+ int n = aliases.length;
+ HashSet aliasSet = new HashSet (n);
+ for (int i = 0; i < n; ++i)
+ aliasSet.add (aliases[i]);
+ return Collections.unmodifiableSet (aliasSet);
+ }
+
+ public String displayName ()
+ {
+ return canonicalName;
+ }
+
+ public String displayName (Locale locale)
+ {
+ return canonicalName;
+ }
+
+ public final boolean isRegistered ()
+ {
+ return (!canonicalName.startsWith ("x-")
+ && !canonicalName.startsWith ("X-"));
+ }
+
+ public abstract boolean contains (Charset cs);
+
+ public abstract CharsetDecoder newDecoder ();
+
+ public abstract CharsetEncoder newEncoder ();
+
+ public boolean canEncode ()
+ {
+ return true;
+ }
+
+ // NB: This implementation serializes different threads calling
+ // Charset.encode(), a potential performance problem. It might
+ // be better to remove the cache, or use ThreadLocal to cache on
+ // a per-thread basis.
+ public final synchronized ByteBuffer encode (CharBuffer cb)
+ {
+ try
+ {
+ if (cachedEncoder == null)
+ {
+ cachedEncoder = newEncoder ()
+ .onMalformedInput (CodingErrorAction.REPLACE)
+ .onUnmappableCharacter (CodingErrorAction.REPLACE);
+ } else
+ cachedEncoder.reset();
+ return cachedEncoder.encode (cb);
+ }
+ catch (CharacterCodingException e)
+ {
+ throw new AssertionError (e);
+ }
+ }
+
+ public final ByteBuffer encode (String str)
+ {
+ return encode (CharBuffer.wrap (str));
+ }
+
+ // NB: This implementation serializes different threads calling
+ // Charset.decode(), a potential performance problem. It might
+ // be better to remove the cache, or use ThreadLocal to cache on
+ // a per-thread basis.
+ public final synchronized CharBuffer decode (ByteBuffer bb)
+ {
+ try
+ {
+ if (cachedDecoder == null)
+ {
+ cachedDecoder = newDecoder ()
+ .onMalformedInput (CodingErrorAction.REPLACE)
+ .onUnmappableCharacter (CodingErrorAction.REPLACE);
+ } else
+ cachedDecoder.reset();
+
+ return cachedDecoder.decode (bb);
+ }
+ catch (CharacterCodingException e)
+ {
+ throw new AssertionError (e);
+ }
+ }
+
+ public final int compareTo (Object ob)
+ {
+ return canonicalName.compareToIgnoreCase (((Charset) ob).canonicalName);
+ }
+
+ public final int hashCode ()
+ {
+ return canonicalName.hashCode ();
+ }
+
+ public final boolean equals (Object ob)
+ {
+ if (ob instanceof Charset)
+ return canonicalName.equalsIgnoreCase (((Charset) ob).canonicalName);
+ else
+ return false;
+ }
+
+ public final String toString ()
+ {
+ return canonicalName;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/nio/charset/spi/CharsetProvider.java b/gcc-4.2.1/libjava/java/nio/charset/spi/CharsetProvider.java
new file mode 100644
index 000000000..e15153fe9
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/charset/spi/CharsetProvider.java
@@ -0,0 +1,96 @@
+/* CharsetProvider.java -- charset service provider interface
+ Copyright (C) 2002, 2006 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.nio.charset.spi;
+
+import java.nio.charset.Charset;
+import java.util.Iterator;
+
+
+/**
+ * This class allows an implementor to provide additional character sets. The
+ * subclass must have a nullary constructor, and be attached to charset
+ * implementation classes. These extensions are loaded via the context class
+ * loader. To provide the charset extension, all files named
+ * <code>META-INF/services/java.nio.charset.spi.CharsetProvider</code> are
+ * read from the classpath. Each one should be a UTF-8 encoded list of
+ * fully-qualified names of concrete subclasses of this class; whitespace is
+ * ignored, and '#' starts comments. Duplicates are ignored. The
+ * implementations must be accessible to the classloader that requests them.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Charset
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public abstract class CharsetProvider
+{
+ /**
+ * Initialize a new charset provider. This performs a security check on
+ * RuntimePermission("charsetProvider").
+ *
+ * @throws SecurityException if building a new set is not allowed
+ */
+ protected CharsetProvider()
+ {
+ // We only do the security check for custom providers, not for the
+ // built in ones.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null &&
+ ! (this instanceof gnu.java.nio.charset.Provider))
+ // GCJ LOCAL - We have the iconv provider in standard.omit
+ // || this instanceof gnu.java.nio.charset.iconv.IconvProvider))
+ s.checkPermission(new RuntimePermission("charsetProvider"));
+ }
+
+ /**
+ * Returns an iterator over the charsets defined by this provider.
+ *
+ * @return the iterator
+ * @see Charset#availableCharsets()
+ */
+ public abstract Iterator charsets();
+
+ /**
+ * Returns the named charset, by canonical name or alias.
+ *
+ * @param name the name of the character
+ *
+ * @return the charset, or null if not supported
+ */
+ public abstract Charset charsetForName(String name);
+} // class CharsetProvider
diff --git a/gcc-4.2.1/libjava/java/nio/natDirectByteBufferImpl.cc b/gcc-4.2.1/libjava/java/nio/natDirectByteBufferImpl.cc
new file mode 100644
index 000000000..3119fdea3
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/nio/natDirectByteBufferImpl.cc
@@ -0,0 +1,72 @@
+// natDirectByteBufferImpl.cc
+
+/* Copyright (C) 2003, 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <stdlib.h>
+
+#include <gnu/gcj/RawData.h>
+#include <java/nio/VMDirectByteBuffer.h>
+
+using gnu::gcj::RawData;
+
+RawData*
+java::nio::VMDirectByteBuffer::allocate (jint capacity)
+{
+ return reinterpret_cast<gnu::gcj::RawData*> (::malloc (capacity));
+}
+
+void
+java::nio::VMDirectByteBuffer::free (gnu::gcj::RawData* address)
+{
+ ::free (reinterpret_cast<void*> (address));
+}
+
+jbyte
+java::nio::VMDirectByteBuffer::get (RawData* address, jint index)
+{
+ jbyte* pointer = reinterpret_cast<jbyte*> (address) + index;
+ return *pointer;
+}
+
+void
+java::nio::VMDirectByteBuffer::get (RawData* address, jint index,
+ jbyteArray dst, jint offset, jint length)
+{
+ jbyte* src = reinterpret_cast<jbyte*> (address) + index;
+ memcpy (elements (dst) + offset, src, length);
+}
+
+void
+java::nio::VMDirectByteBuffer::put (gnu::gcj::RawData* address,
+ jint index, jbyte value)
+{
+ jbyte* pointer = reinterpret_cast<jbyte*> (address) + index;
+ *pointer = value;
+}
+
+RawData*
+java::nio::VMDirectByteBuffer::adjustAddress (RawData* address, jint offset)
+{
+ jbyte* start = reinterpret_cast<jbyte*> (address) + offset;
+ return reinterpret_cast<RawData*>(start);
+}
+
+void
+java::nio::VMDirectByteBuffer::shiftDown (RawData* address, jint dst_offset,
+ jint src_offset, jint count)
+{
+ jbyte* dst = reinterpret_cast<jbyte*> (address) + dst_offset;
+ jbyte* src = reinterpret_cast<jbyte*> (address) + src_offset;
+ ::memmove(dst, src, count);
+}
diff --git a/gcc-4.2.1/libjava/java/security/Security.java b/gcc-4.2.1/libjava/java/security/Security.java
new file mode 100644
index 000000000..630a55412
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/security/Security.java
@@ -0,0 +1,714 @@
+/* Security.java --- Java base security class implementation
+ Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006
+ 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.security;
+
+import gnu.classpath.SystemProperties;
+
+import gnu.classpath.Configuration;
+// GCJ LOCAL - We don't have VMStackWalker yet.
+// import gnu.classpath.VMStackWalker;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * This class centralizes all security properties and common security methods.
+ * One of its primary uses is to manage security providers.
+ *
+ * @author Mark Benvenuto (ivymccough@worldnet.att.net)
+ */
+public final class Security
+{
+ private static final String ALG_ALIAS = "Alg.Alias.";
+
+ private static Vector providers = new Vector();
+ private static Properties secprops = new Properties();
+
+ static
+ {
+ String base = SystemProperties.getProperty("gnu.classpath.home.url");
+ String vendor = SystemProperties.getProperty("gnu.classpath.vm.shortname");
+
+ // Try VM specific security file
+ boolean loaded = loadProviders (base, vendor);
+
+ // Append classpath standard provider if possible
+ if (!loadProviders (base, "classpath")
+ && !loaded
+ && providers.size() == 0)
+ {
+ if (Configuration.DEBUG)
+ {
+ /* No providers found and both security files failed to
+ * load properly. Give a warning in case of DEBUG is
+ * enabled. Could be done with java.util.logging later.
+ */
+ System.err.println
+ ("WARNING: could not properly read security provider files:");
+ System.err.println
+ (" " + base + "/security/" + vendor
+ + ".security");
+ System.err.println
+ (" " + base + "/security/" + "classpath"
+ + ".security");
+ System.err.println
+ (" Falling back to standard GNU security provider");
+ }
+ // Note that this matches our classpath.security file.
+ providers.addElement (new gnu.java.security.provider.Gnu());
+ providers.addElement(new gnu.javax.crypto.jce.GnuCrypto());
+ providers.addElement(new gnu.javax.crypto.jce.GnuSasl());
+ providers.addElement(new gnu.javax.net.ssl.provider.Jessie());
+ providers.addElement(new gnu.javax.security.auth.callback.GnuCallbacks());
+ }
+ }
+ // This class can't be instantiated.
+ private Security()
+ {
+ }
+
+ /**
+ * Tries to load the vender specific security providers from the given base
+ * URL. Returns true if the resource could be read and completely parsed
+ * successfully, false otherwise.
+ */
+ private static boolean loadProviders(String baseUrl, String vendor)
+ {
+ if (baseUrl == null || vendor == null)
+ return false;
+
+ boolean result = true;
+ String secfilestr = baseUrl + "/security/" + vendor + ".security";
+ try
+ {
+ InputStream fin = new URL(secfilestr).openStream();
+ secprops.load(fin);
+
+ int i = 1;
+ String name;
+ while ((name = secprops.getProperty("security.provider." + i)) != null)
+ {
+ Exception exception = null;
+ try
+ {
+ ClassLoader sys = ClassLoader.getSystemClassLoader();
+ providers.addElement(Class.forName(name, true, sys).newInstance());
+ }
+ catch (ClassNotFoundException x)
+ {
+ exception = x;
+ }
+ catch (InstantiationException x)
+ {
+ exception = x;
+ }
+ catch (IllegalAccessException x)
+ {
+ exception = x;
+ }
+
+ if (exception != null)
+ {
+ System.err.println ("WARNING: Error loading security provider "
+ + name + ": " + exception);
+ result = false;
+ }
+ i++;
+ }
+ }
+ catch (IOException ignored)
+ {
+ result = false;
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns the value associated to a designated property name for a given
+ * algorithm.
+ *
+ * @param algName
+ * the algorithm name.
+ * @param propName
+ * the name of the property to return.
+ * @return the value of the specified property or <code>null</code> if none
+ * found.
+ * @deprecated Use the provider-based and algorithm-independent
+ * {@link AlgorithmParameters} and {@link KeyFactory} engine
+ * classes instead.
+ */
+ public static String getAlgorithmProperty(String algName, String propName)
+ {
+ if (algName == null || propName == null)
+ return null;
+
+ String property = String.valueOf(propName) + "." + String.valueOf(algName);
+ Provider p;
+ for (Iterator i = providers.iterator(); i.hasNext(); )
+ {
+ p = (Provider) i.next();
+ for (Iterator j = p.keySet().iterator(); j.hasNext(); )
+ {
+ String key = (String) j.next();
+ if (key.equalsIgnoreCase(property))
+ return p.getProperty(key);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Inserts a new designated {@link Provider} at a designated (1-based)
+ * position in the current list of installed {@link Provider}s,
+ *
+ * @param provider
+ * the new {@link Provider} to add.
+ * @param position
+ * the position (starting from 1) of where to install
+ * <code>provider</code>.
+ * @return the actual position, in the list of installed Providers. Returns
+ * <code>-1</code> if <code>provider</code> was laready in the
+ * list. The actual position may be different than the desired
+ * <code>position</code>.
+ * @throws SecurityException
+ * if a {@link SecurityManager} is installed and it disallows this
+ * operation.
+ * @see #getProvider(String)
+ * @see #removeProvider(String)
+ * @see SecurityPermission
+ */
+ public static int insertProviderAt(Provider provider, int position)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkSecurityAccess("insertProvider." + provider.getName());
+
+ position--;
+ int max = providers.size ();
+ for (int i = 0; i < max; i++)
+ {
+ if (((Provider) providers.elementAt(i)).getName().equals(provider.getName()))
+ return -1;
+ }
+
+ if (position < 0)
+ position = 0;
+ if (position > max)
+ position = max;
+
+ providers.insertElementAt(provider, position);
+
+ return position + 1;
+ }
+
+ /**
+ * Appends the designated new {@link Provider} to the current list of
+ * installed {@link Provider}s.
+ *
+ * @param provider
+ * the new {@link Provider} to append.
+ * @return the position (starting from 1) of <code>provider</code> in the
+ * current list of {@link Provider}s, or <code>-1</code> if
+ * <code>provider</code> was already there.
+ * @throws SecurityException
+ * if a {@link SecurityManager} is installed and it disallows this
+ * operation.
+ * @see #getProvider(String)
+ * @see #removeProvider(String)
+ * @see SecurityPermission
+ */
+ public static int addProvider(Provider provider)
+ {
+ return insertProviderAt (provider, providers.size () + 1);
+ }
+
+ /**
+ * Removes an already installed {@link Provider}, given its name, from the
+ * current list of installed {@link Provider}s.
+ *
+ * @param name
+ * the name of an already installed {@link Provider} to remove.
+ * @throws SecurityException
+ * if a {@link SecurityManager} is installed and it disallows this
+ * operation.
+ * @see #getProvider(String)
+ * @see #addProvider(Provider)
+ */
+ public static void removeProvider(String name)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkSecurityAccess("removeProvider." + name);
+
+ int max = providers.size ();
+ for (int i = 0; i < max; i++)
+ {
+ if (((Provider) providers.elementAt(i)).getName().equals(name))
+ {
+ providers.remove(i);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Returns the current list of installed {@link Provider}s as an array
+ * ordered according to their installation preference order.
+ *
+ * @return an array of all the installed providers.
+ */
+ public static Provider[] getProviders()
+ {
+ Provider[] array = new Provider[providers.size ()];
+ providers.copyInto (array);
+ return array;
+ }
+
+ /**
+ * Returns an already installed {@link Provider} given its name.
+ *
+ * @param name
+ * the name of an already installed {@link Provider}.
+ * @return the {@link Provider} known by <code>name</code>. Returns
+ * <code>null</code> if the current list of {@link Provider}s does
+ * not include one named <code>name</code>.
+ * @see #removeProvider(String)
+ * @see #addProvider(Provider)
+ */
+ public static Provider getProvider(String name)
+ {
+ if (name == null)
+ return null;
+ else
+ {
+ name = name.trim();
+ if (name.length() == 0)
+ return null;
+ }
+ Provider p;
+ int max = providers.size ();
+ for (int i = 0; i < max; i++)
+ {
+ p = (Provider) providers.elementAt(i);
+ if (p.getName().equals(name))
+ return p;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the value associated with a Security propery.
+ *
+ * @param key
+ * the key of the property to fetch.
+ * @return the value of the Security property associated with
+ * <code>key</code>. Returns <code>null</code> if no such property
+ * was found.
+ * @throws SecurityException
+ * if a {@link SecurityManager} is installed and it disallows this
+ * operation.
+ * @see #setProperty(String, String)
+ * @see SecurityPermission
+ */
+ public static String getProperty(String key)
+ {
+ // GCJ LOCAL - We don't have VMStackWalker yet.
+ // XXX To prevent infinite recursion when the SecurityManager calls us,
+ // don't do a security check if the caller is trusted (by virtue of having
+ // been loaded by the bootstrap class loader).
+ SecurityManager sm = System.getSecurityManager();
+ // if (sm != null && VMStackWalker.getCallingClassLoader() != null)
+ if (sm != null)
+ sm.checkSecurityAccess("getProperty." + key);
+
+ return secprops.getProperty(key);
+ }
+
+ /**
+ * Sets or changes a designated Security property to a designated value.
+ *
+ * @param key
+ * the name of the property to set.
+ * @param datum
+ * the new value of the property.
+ * @throws SecurityException
+ * if a {@link SecurityManager} is installed and it disallows this
+ * operation.
+ * @see #getProperty(String)
+ * @see SecurityPermission
+ */
+ public static void setProperty(String key, String datum)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkSecurityAccess("setProperty." + key);
+
+ if (datum == null)
+ secprops.remove(key);
+ else
+ secprops.put(key, datum);
+ }
+
+ /**
+ * For a given <i>service</i> (e.g. Signature, MessageDigest, etc...) this
+ * method returns the {@link Set} of all available algorithm names (instances
+ * of {@link String}, from all currently installed {@link Provider}s.
+ *
+ * @param serviceName
+ * the case-insensitive name of a service (e.g. Signature,
+ * MessageDigest, etc).
+ * @return a {@link Set} of {@link String}s containing the names of all
+ * algorithm names provided by all of the currently installed
+ * {@link Provider}s.
+ * @since 1.4
+ */
+ public static Set getAlgorithms(String serviceName)
+ {
+ HashSet result = new HashSet();
+ if (serviceName == null || serviceName.length() == 0)
+ return result;
+
+ serviceName = serviceName.trim();
+ if (serviceName.length() == 0)
+ return result;
+
+ serviceName = serviceName.toUpperCase()+".";
+ Provider[] providers = getProviders();
+ int ndx;
+ for (int i = 0; i < providers.length; i++)
+ for (Enumeration e = providers[i].propertyNames(); e.hasMoreElements(); )
+ {
+ String service = ((String) e.nextElement()).trim();
+ if (service.toUpperCase().startsWith(serviceName))
+ {
+ service = service.substring(serviceName.length()).trim();
+ ndx = service.indexOf(' '); // get rid of attributes
+ if (ndx != -1)
+ service = service.substring(0, ndx);
+ result.add(service);
+ }
+ }
+ return Collections.unmodifiableSet(result);
+ }
+
+ /**
+ * Returns an array of currently installed {@link Provider}s, ordered
+ * according to their installation preference order, which satisfy a given
+ * <i>selection</i> criterion.
+ *
+ * <p>This implementation recognizes a <i>selection</i> criterion written in
+ * one of two following forms:</p>
+ *
+ * <ul>
+ * <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;: Where
+ * <i>crypto_service</i> is a case-insensitive string, similar to what has
+ * been described in the {@link #getAlgorithms(String)} method, and
+ * <i>algorithm_or_type</i> is a known case-insensitive name of an
+ * Algorithm, or one of its aliases.
+ *
+ * <p>For example, "CertificateFactory.X.509" would return all the installed
+ * {@link Provider}s which provide a <i>CertificateFactory</i>
+ * implementation of <i>X.509</i>.</p></li>
+ *
+ * <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;:&lt;value&gt;:
+ * Where <i>crypto_service</i> is a case-insensitive string, similar to what
+ * has been described in the {@link #getAlgorithms(String)} method,
+ * <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm
+ * or one of its aliases, <i>attribute_name</i> is a case-insensitive
+ * property name with no whitespace characters, and no dots, in-between, and
+ * <i>value</i> is a {@link String} with no whitespace characters in-between.
+ *
+ * <p>For example, "Signature.Sha1WithDSS KeySize:1024" would return all the
+ * installed {@link Provider}s which declared their ability to provide
+ * <i>Signature</i> services, using the <i>Sha1WithDSS</i> algorithm with
+ * key sizes of <i>1024</i>.</p></li>
+ * </ul>
+ *
+ * @param filter
+ * the <i>selection</i> criterion for selecting among the installed
+ * {@link Provider}s.
+ * @return all the installed {@link Provider}s which satisfy the <i>selection</i>
+ * criterion. Returns <code>null</code> if no installed
+ * {@link Provider}s were found which satisfy the <i>selection</i>
+ * criterion. Returns ALL installed {@link Provider}s if
+ * <code>filter</code> is <code>null</code> or is an empty string.
+ * @throws InvalidParameterException
+ * if an exception occurs while parsing the <code>filter</code>.
+ * @see #getProviders(Map)
+ */
+ public static Provider[] getProviders(String filter)
+ {
+ if (providers == null || providers.isEmpty())
+ return null;
+
+ if (filter == null || filter.length() == 0)
+ return getProviders();
+
+ HashMap map = new HashMap(1);
+ int i = filter.indexOf(':');
+ if (i == -1) // <service>.<algorithm>
+ map.put(filter, "");
+ else // <service>.<algorithm> <attribute>:<value>
+ map.put(filter.substring(0, i), filter.substring(i+1));
+
+ return getProviders(map);
+ }
+
+ /**
+ * Returns an array of currently installed {@link Provider}s which satisfy a
+ * set of <i>selection</i> criteria.
+ *
+ * <p>The <i>selection</i> criteria are defined in a {@link Map} where each
+ * element specifies a <i>selection</i> querry. The <i>Keys</i> in this
+ * {@link Map} must be in one of the two following forms:</p>
+ *
+ * <ul>
+ * <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt;: Where
+ * <i>crypto_service</i> is a case-insensitive string, similar to what has
+ * been described in the {@link #getAlgorithms(String)} method, and
+ * <i>algorithm_or_type</i> is a case-insensitive known name of an
+ * Algorithm, or one of its aliases. The <i>value</i> of the entry in the
+ * {@link Map} for such a <i>Key</i> MUST be the empty string.
+ * {@link Provider}s which provide an implementation for the designated
+ * <i>service algorithm</i> are included in the result.</li>
+ *
+ * <li>&lt;crypto_service&gt;.&lt;algorithm_or_type&gt; &lt;attribute_name&gt;:
+ * Where <i>crypto_service</i> is a case-insensitive string, similar to what
+ * has been described in the {@link #getAlgorithms(String)} method,
+ * <i>algorithm_or_type</i> is a case-insensitive known name of an Algorithm
+ * or one of its aliases, and <i>attribute_name</i> is a case-insensitive
+ * property name with no whitespace characters, and no dots, in-between. The
+ * <i>value</i> of the entry in this {@link Map} for such a <i>Key</i> MUST
+ * NOT be <code>null</code> or an empty string. {@link Provider}s which
+ * declare the designated <i>attribute_name</i> and <i>value</i> for the
+ * designated <i>service algorithm</i> are included in the result.</li>
+ * </ul>
+ *
+ * @param filter
+ * a {@link Map} of <i>selection querries</i>.
+ * @return all currently installed {@link Provider}s which satisfy ALL the
+ * <i>selection</i> criteria defined in <code>filter</code>.
+ * Returns ALL installed {@link Provider}s if <code>filter</code>
+ * is <code>null</code> or empty.
+ * @throws InvalidParameterException
+ * if an exception is encountered while parsing the syntax of the
+ * {@link Map}'s <i>keys</i>.
+ * @see #getProviders(String)
+ */
+ public static Provider[] getProviders(Map filter)
+ {
+ if (providers == null || providers.isEmpty())
+ return null;
+
+ if (filter == null)
+ return getProviders();
+
+ Set querries = filter.keySet();
+ if (querries == null || querries.isEmpty())
+ return getProviders();
+
+ LinkedHashSet result = new LinkedHashSet(providers); // assume all
+ int dot, ws;
+ String querry, service, algorithm, attribute, value;
+ LinkedHashSet serviceProviders = new LinkedHashSet(); // preserve insertion order
+ for (Iterator i = querries.iterator(); i.hasNext(); )
+ {
+ querry = (String) i.next();
+ if (querry == null) // all providers
+ continue;
+
+ querry = querry.trim();
+ if (querry.length() == 0) // all providers
+ continue;
+
+ dot = querry.indexOf('.');
+ if (dot == -1) // syntax error
+ throw new InvalidParameterException(
+ "missing dot in '" + String.valueOf(querry)+"'");
+
+ value = (String) filter.get(querry);
+ // deconstruct querry into [service, algorithm, attribute]
+ if (value == null || value.trim().length() == 0) // <service>.<algorithm>
+ {
+ value = null;
+ attribute = null;
+ service = querry.substring(0, dot).trim();
+ algorithm = querry.substring(dot+1).trim();
+ }
+ else // <service>.<algorithm> <attribute>
+ {
+ ws = querry.indexOf(' ');
+ if (ws == -1)
+ throw new InvalidParameterException(
+ "value (" + String.valueOf(value) +
+ ") is not empty, but querry (" + String.valueOf(querry) +
+ ") is missing at least one space character");
+ value = value.trim();
+ attribute = querry.substring(ws+1).trim();
+ // was the dot in the attribute?
+ if (attribute.indexOf('.') != -1)
+ throw new InvalidParameterException(
+ "attribute_name (" + String.valueOf(attribute) +
+ ") in querry (" + String.valueOf(querry) + ") contains a dot");
+
+ querry = querry.substring(0, ws).trim();
+ service = querry.substring(0, dot).trim();
+ algorithm = querry.substring(dot+1).trim();
+ }
+
+ // service and algorithm must not be empty
+ if (service.length() == 0)
+ throw new InvalidParameterException(
+ "<crypto_service> in querry (" + String.valueOf(querry) +
+ ") is empty");
+
+ if (algorithm.length() == 0)
+ throw new InvalidParameterException(
+ "<algorithm_or_type> in querry (" + String.valueOf(querry) +
+ ") is empty");
+
+ selectProviders(service, algorithm, attribute, value, result, serviceProviders);
+ result.retainAll(serviceProviders); // eval next retaining found providers
+ if (result.isEmpty()) // no point continuing
+ break;
+ }
+
+ if (result.isEmpty())
+ return null;
+
+ return (Provider[]) result.toArray(new Provider[result.size()]);
+ }
+
+ private static void selectProviders(String svc, String algo, String attr,
+ String val, LinkedHashSet providerSet,
+ LinkedHashSet result)
+ {
+ result.clear(); // ensure we start with an empty result set
+ for (Iterator i = providerSet.iterator(); i.hasNext(); )
+ {
+ Provider p = (Provider) i.next();
+ if (provides(p, svc, algo, attr, val))
+ result.add(p);
+ }
+ }
+
+ private static boolean provides(Provider p, String svc, String algo,
+ String attr, String val)
+ {
+ Iterator it;
+ String serviceDotAlgorithm = null;
+ String key = null;
+ String realVal;
+ boolean found = false;
+ // if <svc>.<algo> <attr> is in the set then so is <svc>.<algo>
+ // but it may be stored under an alias <algo>. resolve
+ outer: for (int r = 0; r < 3; r++) // guard against circularity
+ {
+ serviceDotAlgorithm = (svc+"."+String.valueOf(algo)).trim();
+ for (it = p.keySet().iterator(); it.hasNext(); )
+ {
+ key = (String) it.next();
+ if (key.equalsIgnoreCase(serviceDotAlgorithm)) // eureka
+ {
+ found = true;
+ break outer;
+ }
+ // it may be there but as an alias
+ if (key.equalsIgnoreCase(ALG_ALIAS + serviceDotAlgorithm))
+ {
+ algo = p.getProperty(key);
+ continue outer;
+ }
+ // else continue inner
+ }
+ }
+
+ if (!found)
+ return false;
+
+ // found a candidate for the querry. do we have an attr to match?
+ if (val == null) // <service>.<algorithm> querry
+ return true;
+
+ // <service>.<algorithm> <attribute>; find the key entry that match
+ String realAttr;
+ int limit = serviceDotAlgorithm.length() + 1;
+ for (it = p.keySet().iterator(); it.hasNext(); )
+ {
+ key = (String) it.next();
+ if (key.length() <= limit)
+ continue;
+
+ if (key.substring(0, limit).equalsIgnoreCase(serviceDotAlgorithm+" "))
+ {
+ realAttr = key.substring(limit).trim();
+ if (! realAttr.equalsIgnoreCase(attr))
+ continue;
+
+ // eveything matches so far. do the value
+ realVal = p.getProperty(key);
+ if (realVal == null)
+ return false;
+
+ realVal = realVal.trim();
+ // is it a string value?
+ if (val.equalsIgnoreCase(realVal))
+ return true;
+
+ // assume value is a number. cehck for greater-than-or-equal
+ return (new Integer(val).intValue() >= new Integer(realVal).intValue());
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/security/VMAccessControlState.java b/gcc-4.2.1/libjava/java/security/VMAccessControlState.java
new file mode 100644
index 000000000..360f08a5b
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/security/VMAccessControlState.java
@@ -0,0 +1,103 @@
+/* VMAccessControlState.java -- per-thread state for the access controller.
+ Copyright (C) 2006 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.LinkedList;
+
+class VMAccessControlState
+{
+ /**
+ * A list of {@link AccessControlContext} objects (which can be
+ * null) for each call to {@link AccessController#doPrivileged()} in
+ * the thread's call stack.
+ */
+ private LinkedList contexts = new LinkedList();
+
+ /**
+ * A flag indicating that we are within a call to {@link
+ * VMAccessController#getContext()}.
+ */
+ private boolean inGetContext = false;
+
+ /**
+ * Not directly instantiable: use getThreadState() instead.
+ */
+ private VMAccessControlState() {}
+
+ /**
+ * Return an object representing the access control state of this
+ * thread.
+ *
+ * @return The access control state of this thread, or
+ * <code>null</code> if the VM is not initialized to the point of
+ * being able to return this.
+ */
+ static native VMAccessControlState getThreadState();
+
+ /**
+ * Indicate whether this thread is within a call to {@link
+ * VMAccessController#getContext()}.
+ *
+ * @return <code>true</code> if this thread is within a call to
+ * {@link VMAccessController#getContext()}.
+ */
+ boolean isInGetContext()
+ {
+ return inGetContext;
+ }
+
+ /**
+ * Specify whether this thread is within a call to {@link
+ * VMAccessController#getContext()}.
+ */
+ void setInGetContext(boolean inGetContext)
+ {
+ this.inGetContext = inGetContext;
+ }
+
+ /**
+ * Return a list of {@link AccessControlContext} objects (which can
+ * be null) for each call to {@link AccessController#doPrivileged()}
+ * in the thread's call stack.
+ *
+ * @return a list of {@link AccessControlContext} objects.
+ */
+ LinkedList getContexts()
+ {
+ return contexts;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/security/VMAccessController.java b/gcc-4.2.1/libjava/java/security/VMAccessController.java
new file mode 100644
index 000000000..8436c9ccb
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/security/VMAccessController.java
@@ -0,0 +1,255 @@
+/* VMAccessController.java -- VM-specific access controller methods.
+ Copyright (C) 2004, 2005, 2006 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.
+ // -------------------------------------------------------------------------
+
+ /**
+ * 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 = gnu.classpath.Configuration.DEBUG;
+ 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)
+ {
+ // Can't really do anything while the VM is initializing.
+ VMAccessControlState state = VMAccessControlState.getThreadState();
+ if (state == null)
+ return;
+
+ if (DEBUG)
+ debug("pushing " + acc);
+
+ LinkedList stack = state.getContexts();
+ 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()
+ {
+ // Can't really do anything while the VM is initializing.
+ VMAccessControlState state = VMAccessControlState.getThreadState();
+ if (state == null)
+ return;
+
+ 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 = state.getContexts();
+ if (!stack.isEmpty())
+ {
+ stack.removeFirst();
+ }
+ else if (DEBUG)
+ {
+ debug("no stack during pop?????");
+ }
+ }
+
+ /**
+ * 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 the VM is initializing return the all-permissive context
+ // so that any security checks succeed.
+ VMAccessControlState state = VMAccessControlState.getThreadState();
+ if (state == null)
+ return DEFAULT_CONTEXT;
+
+ // 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.
+ if (state.isInGetContext())
+ {
+ if (DEBUG)
+ debug("already in getContext");
+ return DEFAULT_CONTEXT;
+ }
+
+ state.setInGetContext(true);
+
+ Object[] stack = getStack();
+ Class[] classes = (Class[]) stack[0];
+ boolean privileged = ((Boolean) stack[1]).booleanValue();
+
+ if (DEBUG)
+ debug("got trace of length " + classes.length);
+
+ HashSet domains = new HashSet();
+ HashSet seenDomains = new HashSet();
+ AccessControlContext context = null;
+
+ // 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; i++)
+ {
+ Class clazz = classes[i];
+
+ if (DEBUG)
+ {
+ debug("checking " + clazz);
+ // subject to getClassLoader RuntimePermission
+ debug("loader = " + clazz.getClassLoader());
+ }
+
+ if (privileged && i == classes.length - 2)
+ {
+ // If there was a call to doPrivileged with a supplied context,
+ // return that context. If using JAAS doAs*, it should be
+ // a context with a SubjectDomainCombiner
+ LinkedList l = state.getContexts();
+ if (!l.isEmpty())
+ context = (AccessControlContext) l.getFirst();
+ }
+
+ // subject to getProtectionDomain RuntimePermission
+ 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()]);
+
+ if (context != null)
+ {
+ DomainCombiner dc = context.getDomainCombiner ();
+ // If the supplied context had no explicit DomainCombiner, use
+ // our private version, which computes the intersection of the
+ // context's domains with the derived set.
+ if (dc == null)
+ context = new AccessControlContext
+ (IntersectingDomainCombiner.SINGLETON.combine
+ (result, context.getProtectionDomains ()));
+ // Use the supplied DomainCombiner. This should be secure,
+ // because only trusted code may create an
+ // AccessControlContext with a custom DomainCombiner.
+ else
+ context = new AccessControlContext (result, context, dc);
+ }
+ // No context was supplied. Return the derived one.
+ else
+ context = new AccessControlContext (result);
+
+ state.setInGetContext(false);
+ return context;
+ }
+
+ /**
+ * Returns a snapshot of the current call stack as a two-element
+ * array. The first element is an array of classes in the call
+ * stack, and the second element is a boolean value indicating
+ * whether the trace stopped early because a call to doPrivileged
+ * was encountered. If this boolean value is true then the call to
+ * doPrivileged will be the second-last frame in the returned trace.
+ *
+ * @return A snapshot of the current call stack.
+ */
+ private static native Object[] getStack();
+}
diff --git a/gcc-4.2.1/libjava/java/security/VMSecureRandom.java b/gcc-4.2.1/libjava/java/security/VMSecureRandom.java
new file mode 100644
index 000000000..dc67d8719
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/security/VMSecureRandom.java
@@ -0,0 +1,134 @@
+/* VMSecureRandom.java -- random seed generator.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a 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 of the License, 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; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, 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 gnu.classpath.SystemProperties;
+import gnu.java.security.action.GetSecurityPropertyAction;
+
+import java.net.URL;
+
+/**
+ * VM-specific methods for generating real (or almost real) random
+ * seeds. VM implementors should write a version of this class that
+ * reads random bytes from some system source.
+ *
+ * <p>The default implementation of this class runs eight threads that
+ * increment counters in a tight loop, and XORs each counter to
+ * produce one byte of seed data. This is not very efficient, and is
+ * not guaranteed to be random (the thread scheduler is probably
+ * deterministic, after all). If possible, VM implementors should
+ * reimplement this class so it obtains a random seed from a system
+ * facility, such as a system entropy gathering device or hardware
+ * random number generator.
+ */
+final class VMSecureRandom
+{
+
+ /**
+ * Generate a random seed. Implementations are free to generate
+ * fewer random bytes than are requested, and leave the remaining
+ * bytes of the destination buffer as zeros. Implementations SHOULD,
+ * however, make a best-effort attempt to satisfy the request.
+ *
+ * @param buffer The destination buffer.
+ * @param offset The offset in the buffer to start putting bytes.
+ * @param length The number of random bytes to generate.
+ */
+ static int generateSeed(byte[] buffer, int offset, int length)
+ {
+ if (length < 0)
+ throw new IllegalArgumentException("length must be nonnegative");
+ if (offset < 0 || offset + length > buffer.length)
+ throw new IndexOutOfBoundsException();
+
+ Spinner[] spinners = new Spinner[8];
+ int n = 0x1;
+ for (int i = 0; i < spinners.length; i++)
+ {
+ spinners[i] = new Spinner((byte) n);
+ Thread t = new Thread(spinners[i]);
+ t.start();
+ n <<= 1;
+ }
+
+ // Wait until at least one spinner has started.
+ while (!(spinners[0].running || spinners[1].running || spinners[2].running
+ || spinners[3].running || spinners[4].running || spinners[5].running
+ || spinners[6].running || spinners[7].running))
+ {
+ Thread.yield();
+ }
+
+ for (int i = offset; i < length; i++)
+ {
+ buffer[i] = (byte) (spinners[0].value ^ spinners[1].value ^ spinners[2].value
+ ^ spinners[3].value ^ spinners[4].value ^ spinners[5].value
+ ^ spinners[6].value ^ spinners[7].value);
+ Thread.yield();
+ }
+
+ for (int i = 0; i < spinners.length; i++)
+ spinners[i].stop();
+
+ return length;
+ }
+
+ static class Spinner implements Runnable
+ {
+ volatile byte value;
+ volatile boolean running;
+
+ Spinner(final byte initial)
+ {
+ value = initial;
+ }
+
+ public void run()
+ {
+ running = true;
+ while (running)
+ value++;
+ }
+
+ private void stop()
+ {
+ running = false;
+ }
+ }
+} \ No newline at end of file
diff --git a/gcc-4.2.1/libjava/java/security/natVMAccessControlState.cc b/gcc-4.2.1/libjava/java/security/natVMAccessControlState.cc
new file mode 100644
index 000000000..a4c14cdd4
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/security/natVMAccessControlState.cc
@@ -0,0 +1,32 @@
+// natVMAccessControlState.cc -- Native part of the VMAccessControlState class.
+
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/lang/Thread.h>
+#include <java/security/VMAccessControlState.h>
+
+java::security::VMAccessControlState *
+java::security::VMAccessControlState::getThreadState ()
+{
+ java::lang::Thread *thread = java::lang::Thread::currentThread ();
+ if (thread == NULL)
+ return NULL;
+
+ VMAccessControlState *state =
+ reinterpret_cast<VMAccessControlState *> (thread->accessControlState);
+ if (state == NULL)
+ thread->accessControlState = state = new VMAccessControlState ();
+
+ return state;
+}
diff --git a/gcc-4.2.1/libjava/java/security/natVMAccessController.cc b/gcc-4.2.1/libjava/java/security/natVMAccessController.cc
new file mode 100644
index 000000000..9a0ae489e
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/security/natVMAccessController.cc
@@ -0,0 +1,23 @@
+// natVMAccessController.cc -- Native part of the VMAccessController class.
+
+/* Copyright (C) 2006 Free Software Foundation, Inc.
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/security/VMAccessController.h>
+
+jobjectArray
+java::security::VMAccessController::getStack ()
+{
+ return _Jv_StackTrace::GetAccessControlStack ();
+}
diff --git a/gcc-4.2.1/libjava/java/text/Collator.java b/gcc-4.2.1/libjava/java/text/Collator.java
new file mode 100644
index 000000000..c1ba87e93
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/text/Collator.java
@@ -0,0 +1,395 @@
+/* Collator.java -- Perform locale dependent String comparisons.
+ Copyright (C) 1998, 1999, 2000, 2001, 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.text;
+
+import java.util.Comparator;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class is the abstract superclass of classes which perform
+ * locale dependent <code>String</code> comparisons. A caller requests
+ * an instance of <code>Collator</code> for a particular locale using
+ * the <code>getInstance()</code> static method in this class. That method
+ * will return a locale specific subclass of <code>Collator</code> which
+ * can be used to perform <code>String</code> comparisons for that locale.
+ * If a subclass of <code>Collator</code> cannot be located for a particular
+ * locale, a default instance for the current locale will be returned.
+ *
+ * In addition to setting the correct locale, there are two additional
+ * settings that can be adjusted to affect <code>String</code> comparisons:
+ * strength and decomposition. The strength value determines the level
+ * of signficance of character differences required for them to sort
+ * differently. (For example, whether or not capital letters are considered
+ * different from lower case letters). The decomposition value affects how
+ * variants of the same character are treated for sorting purposes. (For
+ * example, whether or not an accent is signficant or not). These settings
+ * are described in detail in the documentation for the methods and values
+ * that are related to them.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @date March 18, 1999
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 from http://www.javasoft.com.
+ * Status: Mostly complete, but parts stubbed out. Look for FIXME.
+ */
+public abstract class Collator implements Comparator, Cloneable
+{
+ /**
+ * This constant is a strength value which indicates that only primary
+ * differences between characters will be considered signficant. As an
+ * example, two completely different English letters such as 'a' and 'b'
+ * are considered to have a primary difference.
+ */
+ public static final int PRIMARY = 0;
+
+ /**
+ * This constant is a strength value which indicates that only secondary
+ * or primary differences between characters will be considered
+ * significant. An example of a secondary difference between characters
+ * are instances of the same letter with different accented forms.
+ */
+ public static final int SECONDARY = 1;
+
+ /**
+ * This constant is a strength value which indicates that tertiary,
+ * secondary, and primary differences will be considered during sorting.
+ * An example of a tertiary difference is capitalization of a given letter.
+ * This is the default value for the strength setting.
+ */
+ public static final int TERTIARY = 2;
+
+ /**
+ * This constant is a strength value which indicates that any difference
+ * at all between character values are considered significant.
+ */
+ public static final int IDENTICAL = 3;
+
+ /**
+ * This constant indicates that accented characters won't be decomposed
+ * when performing comparisons. This will yield the fastest results, but
+ * will only work correctly in call cases for languages which do not
+ * use accents such as English.
+ */
+ public static final int NO_DECOMPOSITION = 0;
+
+ /**
+ * This constant indicates that only characters which are canonical variants
+ * in Unicode 2.0 will be decomposed prior to performing comparisons. This
+ * will cause accented languages to be sorted correctly. This is the
+ * default decomposition value.
+ */
+ public static final int CANONICAL_DECOMPOSITION = 1;
+
+ /**
+ * This constant indicates that both canonical variants and compatibility
+ * variants in Unicode 2.0 will be decomposed prior to performing
+ * comparisons. This is the slowest mode, but is required to get the
+ * correct sorting for certain languages with certain special formats.
+ */
+ public static final int FULL_DECOMPOSITION = 2;
+
+ /**
+ * This method initializes a new instance of <code>Collator</code> to have
+ * the default strength (TERTIARY) and decomposition
+ * (CANONICAL_DECOMPOSITION) settings. This constructor is protected and
+ * is for use by subclasses only. Non-subclass callers should use the
+ * static <code>getInstance()</code> methods of this class to instantiate
+ * <code>Collation</code> objects for the desired locale.
+ */
+ protected Collator ()
+ {
+ strength = TERTIARY;
+ decmp = CANONICAL_DECOMPOSITION;
+ }
+
+ /**
+ * This method compares the two <code>String</code>'s and returns an
+ * integer indicating whether or not the first argument is less than,
+ * equal to, or greater than the second argument. The comparison is
+ * performed according to the rules of the locale for this
+ * <code>Collator</code> and the strength and decomposition rules in
+ * effect.
+ *
+ * @param source The first object to compare
+ * @param target The second object to compare
+ *
+ * @return A negative integer if str1 &lt; str2, 0 if str1 == str2, or
+ * a positive integer if str1 &gt; str2.
+ */
+ public abstract int compare (String source, String target);
+
+ /**
+ * This method compares the two <code>Object</code>'s and returns an
+ * integer indicating whether or not the first argument is less than,
+ * equal to, or greater than the second argument. These two objects
+ * must be <code>String</code>'s or an exception will be thrown.
+ *
+ * @param o1 The first object to compare
+ * @param o2 The second object to compare
+ *
+ * @return A negative integer if obj1 &lt; obj2, 0 if obj1 == obj2, or
+ * a positive integer if obj1 &gt; obj2.
+ *
+ * @exception ClassCastException If the arguments are not instances
+ * of <code>String</code>.
+ */
+ public int compare (Object o1, Object o2)
+ {
+ return compare ((String) o1, (String) o2);
+ }
+
+ /**
+ * This method tests the specified object for equality against this
+ * object. This will be true if and only if the following conditions are
+ * met:
+ * <ul>
+ * <li>The specified object is not <code>null</code>.</li>
+ * <li>The specified object is an instance of <code>Collator</code>.</li>
+ * <li>The specified object has the same strength and decomposition
+ * settings as this object.</li>
+ * </ul>
+ *
+ * @param obj The <code>Object</code> to test for equality against
+ * this object.
+ *
+ * @return <code>true</code> if the specified object is equal to
+ * this one, <code>false</code> otherwise.
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof Collator))
+ return false;
+ Collator c = (Collator) obj;
+ return decmp == c.decmp && strength == c.strength;
+ }
+
+ /**
+ * This method tests whether the specified <code>String</code>'s are equal
+ * according to the collation rules for the locale of this object and
+ * the current strength and decomposition settings.
+ *
+ * @param source The first <code>String</code> to compare
+ * @param target The second <code>String</code> to compare
+ *
+ * @return <code>true</code> if the two strings are equal,
+ * <code>false</code> otherwise.
+ */
+ public boolean equals (String source, String target)
+ {
+ return compare (source, target) == 0;
+ }
+
+ /**
+ * This method returns a copy of this <code>Collator</code> object.
+ *
+ * @return A duplicate of this object.
+ */
+ public Object clone ()
+ {
+ try
+ {
+ return super.clone ();
+ }
+ catch (CloneNotSupportedException _)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * This method returns an array of <code>Locale</code> objects which is
+ * the list of locales for which <code>Collator</code> objects exist.
+ *
+ * @return The list of locales for which <code>Collator</code>'s exist.
+ */
+ public static synchronized Locale[] getAvailableLocales ()
+ {
+ // FIXME
+ Locale[] l = new Locale[1];
+ l[0] = Locale.US;
+ return l;
+ }
+
+ /**
+ * This method transforms the specified <code>String</code> into a
+ * <code>CollationKey</code> for faster comparisons. This is useful when
+ * comparisons against a string might be performed multiple times, such
+ * as during a sort operation.
+ *
+ * @param source The <code>String</code> to convert.
+ *
+ * @return A <code>CollationKey</code> for the specified <code>String</code>.
+ */
+ public abstract CollationKey getCollationKey (String source);
+
+ /**
+ * This method returns the current decomposition setting for this
+ * object. This * will be one of NO_DECOMPOSITION,
+ * CANONICAL_DECOMPOSITION, or * FULL_DECOMPOSITION. See the
+ * documentation for those constants for an * explanation of this
+ * setting.
+ *
+ * @return The current decomposition setting.
+ */
+ public synchronized int getDecomposition ()
+ {
+ return decmp;
+ }
+
+ /**
+ * This method returns an instance of <code>Collator</code> for the
+ * default locale.
+ *
+ * @return A <code>Collator</code> for the default locale.
+ */
+ public static Collator getInstance ()
+ {
+ return getInstance (Locale.getDefault());
+ }
+
+ /**
+ * This method returns an instance of <code>Collator</code> for the
+ * specified locale. If no <code>Collator</code> exists for the desired
+ * locale, a <code>Collator</code> for the default locale will be returned.
+ *
+ * @param loc The desired localed to load a <code>Collator</code> for.
+ *
+ * @return A <code>Collator</code> for the requested locale
+ */
+ public static Collator getInstance (Locale loc)
+ {
+ ResourceBundle res;
+ String pattern;
+ try
+ {
+ res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
+ loc, ClassLoader.getSystemClassLoader());
+ pattern = res.getString("collation_rules");
+ }
+ catch (MissingResourceException x)
+ {
+ pattern = "<0<1<2<3<4<5<6<7<8<9<A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<k,K" +
+ "<l,L<m,M<n,N<o,O<p,P<q,Q<r,R<s,S<t,T<u,U<v,V<w,W<x,X<y,Y<z,Z";
+ }
+ try
+ {
+ return new RuleBasedCollator (pattern);
+ }
+ catch (ParseException x)
+ {
+ throw (InternalError)new InternalError().initCause(x);
+ }
+ }
+
+ /**
+ * This method returns the current strength setting for this object. This
+ * will be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL. See the
+ * documentation for those constants for an explanation of this setting.
+ *
+ * @return The current strength setting.
+ */
+ public synchronized int getStrength ()
+ {
+ return strength;
+ }
+
+ /**
+ * This method returns a hash code value for this object.
+ *
+ * @return A hash value for this object.
+ */
+ public abstract int hashCode ();
+
+ /**
+ * This method sets the decomposition setting for this object to the
+ * specified value. This must be one of NO_DECOMPOSITION,
+ * CANONICAL_DECOMPOSITION, or FULL_DECOMPOSITION. Otherwise an
+ * exception will be thrown. See the documentation for those
+ * contants for an explanation of this setting.
+ *
+ * @param mode The new decomposition setting.
+ *
+ * @exception IllegalArgumentException If the requested
+ * decomposition setting is not valid.
+ */
+ public synchronized void setDecomposition (int mode)
+ {
+ if (mode != NO_DECOMPOSITION
+ && mode != CANONICAL_DECOMPOSITION
+ && mode != FULL_DECOMPOSITION)
+ throw new IllegalArgumentException ();
+ decmp = mode;
+ }
+
+ /**
+ * This method sets the strength setting for this object to the specified
+ * value. This must be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL.
+ * Otherwise an exception is thrown. See the documentation for these
+ * constants for an explanation of this setting.
+ *
+ * @param strength The new strength setting.
+ *
+ * @exception IllegalArgumentException If the requested strength
+ * setting value is not valid.
+ */
+ public synchronized void setStrength (int strength)
+ {
+ if (strength != PRIMARY && strength != SECONDARY
+ && strength != TERTIARY && strength != IDENTICAL)
+ throw new IllegalArgumentException ();
+ this.strength = strength;
+ }
+
+ // Decompose a single character and append results to the buffer.
+ native final void decomposeCharacter (char c, StringBuffer buf);
+
+ /**
+ * This is the current collation decomposition setting.
+ */
+ int decmp;
+
+ /**
+ * This is the current collation strength setting.
+ */
+ int strength;
+}
diff --git a/gcc-4.2.1/libjava/java/text/DateFormatSymbols.java b/gcc-4.2.1/libjava/java/text/DateFormatSymbols.java
new file mode 100644
index 000000000..27a806df1
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/text/DateFormatSymbols.java
@@ -0,0 +1,502 @@
+/* DateFormatSymbols.java -- Format over a range of numbers
+ Copyright (C) 1998, 1999, 2000, 2001, 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.text;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class acts as container for locale specific date/time formatting
+ * information such as the days of the week and the months of the year.
+ * @author Per Bothner (bothner@cygnus.com)
+ * @date October 24, 1998.
+ */
+/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3.
+ * Status: Believed complete and correct.
+ */
+public class DateFormatSymbols implements java.io.Serializable, Cloneable
+{
+ String[] ampms;
+ String[] eras;
+ private String localPatternChars;
+ String[] months;
+ String[] shortMonths;
+ String[] shortWeekdays;
+ String[] weekdays;
+ private String[][] zoneStrings;
+
+ private static final long serialVersionUID = -5987973545549424702L;
+
+ // The order of these prefixes must be the same as in DateFormat
+ private static final String[] formatPrefixes =
+ {
+ "full", "long", "medium", "short"
+ };
+
+ // These are each arrays with a value for SHORT, MEDIUM, LONG, FULL,
+ // and DEFAULT (constants defined in java.text.DateFormat). While
+ // not part of the official spec, we need a way to get at locale-specific
+ // default formatting patterns. They are declared package scope so
+ // as to be easily accessible where needed (DateFormat, SimpleDateFormat).
+ transient String[] dateFormats;
+ transient String[] timeFormats;
+
+ private String[] formatsForKey(ResourceBundle res, String key)
+ {
+ String[] values = new String [formatPrefixes.length];
+ for (int i = 0; i < formatPrefixes.length; i++)
+ {
+ values[i] = res.getString(formatPrefixes[i]+key);
+ }
+ return values;
+ }
+
+ /**
+ * This method initializes a new instance of <code>DateFormatSymbols</code>
+ * by loading the date format information for the specified locale.
+ *
+ * @param locale The locale for which date formatting symbols should
+ * be loaded.
+ */
+ public DateFormatSymbols (Locale locale) throws MissingResourceException
+ {
+ ResourceBundle res
+ = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale,
+ ClassLoader.getSystemClassLoader());
+
+ ampms = res.getStringArray ("ampms");
+ eras = res.getStringArray ("eras");
+ localPatternChars = res.getString ("localPatternChars");
+ months = res.getStringArray ("months");
+ shortMonths = res.getStringArray ("shortMonths");
+ shortWeekdays = res.getStringArray ("shortWeekdays");
+ weekdays = res.getStringArray ("weekdays");
+ zoneStrings = (String[][]) res.getObject ("zoneStrings");
+
+ dateFormats = formatsForKey(res, "DateFormat");
+ timeFormats = formatsForKey(res, "TimeFormat");
+ }
+
+ /**
+ * This method loads the format symbol information for the default
+ * locale.
+ */
+ public DateFormatSymbols () throws MissingResourceException
+ {
+ this (Locale.getDefault());
+ }
+
+ /**
+ * This method returns the list of strings used for displaying AM or PM.
+ * This is a two element <code>String</code> array indexed by
+ * <code>Calendar.AM</code> and <code>Calendar.PM</code>
+ *
+ * @return The list of AM/PM display strings.
+ */
+ public String[] getAmPmStrings()
+ {
+ return ampms;
+ }
+
+ /**
+ * This method returns the list of strings used for displaying eras
+ * (e.g., "BC" and "AD"). This is a two element <code>String</code>
+ * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
+ *
+ * @return The list of era disply strings.
+ */
+ public String[] getEras()
+ {
+ return eras;
+ }
+
+ /**
+ * This method returns the pattern character information for this
+ * object. This is an 18 character string that contains the characters
+ * that are used in creating the date formatting strings in
+ * <code>SimpleDateFormat</code>. The following are the character
+ * positions in the string and which format character they correspond
+ * to (the character in parentheses is the default value in the US English
+ * locale):
+ * <p>
+ * <ul>
+ * <li>0 - era (G)</li>
+ * <li>1 - year (y)</li>
+ * <li>2 - month (M)</li>
+ * <li>3 - day of month (d)</li>
+ * <li>4 - hour out of 12, from 1-12 (h)</li>
+ * <li>5 - hour out of 24, from 0-23 (H)</li>
+ * <li>6 - minute (m)</li>
+ * <li>7 - second (s)</li>
+ * <li>8 - millisecond (S)</li>
+ * <li>9 - date of week (E)</li>
+ * <li>10 - date of year (D)</li>
+ * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
+ * <li>12 - week in year (w)</li>
+ * <li>13 - week in month (W)</li>
+ * <li>14 - am/pm (a)</li>
+ * <li>15 - hour out of 24, from 1-24 (k)</li>
+ * <li>16 - hour out of 12, from 0-11 (K)</li>
+ * <li>17 - time zone (z)</li>
+ * </ul>
+ *
+ * @return The format patter characters
+ */
+ public String getLocalPatternChars()
+ {
+ return localPatternChars;
+ }
+
+ /**
+ * This method returns the list of strings used for displaying month
+ * names (e.g., "January" and "February"). This is a thirteen element
+ * string array indexed by <code>Calendar.JANUARY</code> through
+ * <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
+ * elements because some calendars have thriteen months.
+ *
+ * @return The list of month display strings.
+ */
+ public String[] getMonths ()
+ {
+ return months;
+ }
+
+ /**
+ * This method returns the list of strings used for displaying abbreviated
+ * month names (e.g., "Jan" and "Feb"). This is a thirteen element
+ * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
+ * through <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
+ * elements because some calendars have thirteen months.
+ *
+ * @return The list of abbreviated month display strings.
+ */
+ public String[] getShortMonths ()
+ {
+ return shortMonths;
+ }
+
+ /**
+ * This method returns the list of strings used for displaying abbreviated
+ * weekday names (e.g., "Sun" and "Mon"). This is an eight element
+ * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+ * through <code>Calendar.SATURDAY</code>. Note that the first element
+ * of this array is ignored.
+ *
+ * @return This list of abbreviated weekday display strings.
+ */
+ public String[] getShortWeekdays ()
+ {
+ return shortWeekdays;
+ }
+
+ /**
+ * This method returns the list of strings used for displaying weekday
+ * names (e.g., "Sunday" and "Monday"). This is an eight element
+ * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+ * through <code>Calendar.SATURDAY</code>. Note that the first element
+ * of this array is ignored.
+ *
+ * @return This list of weekday display strings.
+ */
+ public String[] getWeekdays ()
+ {
+ return weekdays;
+ }
+
+ /**
+ * This method returns this list of localized timezone display strings.
+ * This is a two dimensional <code>String</code> array where each row in
+ * the array contains five values:
+ * <P>
+ * <ul>
+ * <li>0 - The non-localized time zone id string.</li>
+ * <li>1 - The long name of the time zone (standard time).</li>
+ * <li>2 - The short name of the time zone (standard time).</li>
+ * <li>3 - The long name of the time zone (daylight savings time).</li>
+ * <li>4 - the short name of the time zone (daylight savings time).</li>
+ * </ul>
+ *
+ * @return The list of time zone display strings.
+ */
+ public String[] [] getZoneStrings ()
+ {
+ return zoneStrings;
+ }
+
+ /**
+ * This method sets the list of strings used to display AM/PM values to
+ * the specified list.
+ * This is a two element <code>String</code> array indexed by
+ * <code>Calendar.AM</code> and <code>Calendar.PM</code>
+ *
+ * @param value The new list of AM/PM display strings.
+ */
+ public void setAmPmStrings (String[] value)
+ {
+ ampms = value;
+ }
+
+ /**
+ * This method sets the list of strings used to display time eras to
+ * to the specified list.
+ * This is a two element <code>String</code>
+ * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
+ *
+ * @param labels The new list of era display strings.
+ */
+ public void setEras (String[] labels)
+ {
+ eras = labels;
+ }
+
+ /**
+ * This method sets the list of characters used to specific date/time
+ * formatting strings.
+ * This is an 18 character string that contains the characters
+ * that are used in creating the date formatting strings in
+ * <code>SimpleDateFormat</code>. The following are the character
+ * positions in the string and which format character they correspond
+ * to (the character in parentheses is the default value in the US English
+ * locale):
+ * <p>
+ * <ul>
+ * <li>0 - era (G)</li>
+ * <li>1 - year (y)</li>
+ * <li>2 - month (M)</li>
+ * <li>3 - day of month (d)</li>
+ * <li>4 - hour out of 12, from 1-12 (h)</li>
+ * <li>5 - hour out of 24, from 0-23 (H)</li>
+ * <li>6 - minute (m)</li>
+ * <li>7 - second (s)</li>
+ * <li>8 - millisecond (S)</li>
+ * <li>9 - date of week (E)</li>
+ * <li>10 - date of year (D)</li>
+ * <li>11 - day of week in month, eg. "4th Thur in Nov" (F)</li>
+ * <li>12 - week in year (w)</li>
+ * <li>13 - week in month (W)</li>
+ * <li>14 - am/pm (a)</li>
+ * <li>15 - hour out of 24, from 1-24 (k)</li>
+ * <li>16 - hour out of 12, from 0-11 (K)</li>
+ * <li>17 - time zone (z)</li>
+ * </ul>
+ *
+ * @param chars The new format pattern characters
+ */
+ public void setLocalPatternChars (String chars)
+ {
+ localPatternChars = chars;
+ }
+
+ /**
+ * This method sets the list of strings used to display month names.
+ * This is a thirteen element
+ * string array indexed by <code>Calendar.JANUARY</code> through
+ * <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
+ * elements because some calendars have thriteen months.
+ *
+ * @param labels The list of month display strings.
+ */
+ public void setMonths (String[] labels)
+ {
+ months = labels;
+ }
+
+ /**
+ * This method sets the list of strings used to display abbreviated month
+ * names.
+ * This is a thirteen element
+ * <code>String</code> array indexed by <code>Calendar.JANUARY</code>
+ * through <code>Calendar.UNDECEMBER</code>. Note that there are thirteen
+ * elements because some calendars have thirteen months.
+ *
+ * @param labels The new list of abbreviated month display strings.
+ */
+ public void setShortMonths (String[] labels)
+ {
+ shortMonths = labels;
+ }
+
+ /**
+ * This method sets the list of strings used to display abbreviated
+ * weekday names.
+ * This is an eight element
+ * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+ * through <code>Calendar.SATURDAY</code>. Note that the first element
+ * of this array is ignored.
+ *
+ * @param labels This list of abbreviated weekday display strings.
+ */
+ public void setShortWeekdays (String[] labels)
+ {
+ shortWeekdays = labels;
+ }
+
+ /**
+ * This method sets the list of strings used to display weekday names.
+ * This is an eight element
+ * <code>String</code> array indexed by <code>Calendar.SUNDAY</code>
+ * through <code>Calendar.SATURDAY</code>. Note that the first element
+ * of this array is ignored.
+ *
+ * @param labels This list of weekday display strings.
+ */
+ public void setWeekdays (String[] labels)
+ {
+ weekdays = labels;
+ }
+
+ /**
+ * This method sets the list of display strings for time zones.
+ * This is a two dimensional <code>String</code> array where each row in
+ * the array contains five values:
+ * <P>
+ * <ul>
+ * <li>0 - The non-localized time zone id string.</li>
+ * <li>1 - The long name of the time zone (standard time).</li>
+ * <li>2 - The short name of the time zone (standard time).</li>
+ * <li>3 - The long name of the time zone (daylight savings time).</li>
+ * <li>4 - the short name of the time zone (daylight savings time).</li>
+ * </ul>
+ *
+ * @params zones The list of time zone display strings.
+ */
+ public void setZoneStrings (String[][] zones)
+ {
+ zoneStrings = zones;
+ }
+
+ /* Does a "deep" equality test - recurses into arrays. */
+ private static boolean equals (Object x, Object y)
+ {
+ if (x == y)
+ return true;
+ if (x == null || y == null)
+ return false;
+ if (! (x instanceof Object[]) || ! (y instanceof Object[]))
+ return x.equals(y);
+ Object[] xa = (Object[]) x;
+ Object[] ya = (Object[]) y;
+ if (xa.length != ya.length)
+ return false;
+ for (int i = xa.length; --i >= 0; )
+ {
+ if (! equals(xa[i], ya[i]))
+ return false;
+ }
+ return true;
+ }
+
+ private static int hashCode (Object x)
+ {
+ if (x == null)
+ return 0;
+ if (! (x instanceof Object[]))
+ return x.hashCode();
+ Object[] xa = (Object[]) x;
+ int hash = 0;
+ for (int i = 0; i < xa.length; i++)
+ hash = 37 * hashCode(xa[i]);
+ return hash;
+ }
+
+ /**
+ * This method tests a specified object for equality against this object.
+ * This will be true if and only if the specified object:
+ * <p>
+ * <ul>
+ * <li> Is not <code>null</code>.</li>
+ * <li> Is an instance of <code>DateFormatSymbols</code>.</li>
+ * <li> Contains identical formatting symbols to this object.</li>
+ * </ul>
+ *
+ * @param obj The <code>Object</code> to test for equality against.
+ *
+ * @return <code>true</code> if the specified object is equal to this one,
+ * <code>false</code> otherwise.
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof DateFormatSymbols))
+ return false;
+ DateFormatSymbols other = (DateFormatSymbols) obj;
+ return (equals(ampms, other.ampms)
+ && equals(eras, other.eras)
+ && equals(localPatternChars, other.localPatternChars)
+ && equals(months, other.months)
+ && equals(shortMonths, other.shortMonths)
+ && equals(shortWeekdays, other.shortWeekdays)
+ && equals(weekdays, other.weekdays)
+ && equals(zoneStrings, other.zoneStrings));
+ }
+
+ /**
+ * Returns a new copy of this object.
+ *
+ * @return A copy of this object
+ */
+ public Object clone ()
+ {
+ try
+ {
+ return super.clone ();
+ }
+ catch (CloneNotSupportedException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * This method returns a hash value for this object.
+ *
+ * @return A hash value for this object.
+ */
+ public int hashCode ()
+ {
+ return (hashCode(ampms)
+ ^ hashCode(eras)
+ ^ hashCode(localPatternChars)
+ ^ hashCode(months)
+ ^ hashCode(shortMonths)
+ ^ hashCode(shortWeekdays)
+ ^ hashCode(weekdays)
+ ^ hashCode(zoneStrings));
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/text/DecimalFormatSymbols.java b/gcc-4.2.1/libjava/java/text/DecimalFormatSymbols.java
new file mode 100644
index 000000000..c58530fc5
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/text/DecimalFormatSymbols.java
@@ -0,0 +1,613 @@
+/* DecimalFormatSymbols.java -- Format symbols used by DecimalFormat
+ Copyright (C) 1999, 2000, 2001, 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.text;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.util.Currency;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * This class is a container for the symbols used by
+ * <code>DecimalFormat</code> to format numbers and currency. These are
+ * normally handled automatically, but an application can override
+ * values as desired using this class.
+ *
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @date February 24, 1999
+ */
+/* Written using "Java Class Libraries", 2nd edition, plus online
+ * API docs for JDK 1.2 from http://www.javasoft.com.
+ * Status: Believed complete and correct to 1.2.
+ */
+public final class DecimalFormatSymbols implements Cloneable, Serializable
+{
+ public Object clone ()
+ {
+ try
+ {
+ return super.clone ();
+ }
+ catch(CloneNotSupportedException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * This method initializes a new instance of
+ * <code>DecimalFormatSymbols</code> for the default locale.
+ */
+ public DecimalFormatSymbols ()
+ {
+ this (Locale.getDefault());
+ }
+
+ private String safeGetString(ResourceBundle bundle,
+ String name, String def)
+ {
+ if (bundle != null)
+ {
+ try
+ {
+ return bundle.getString(name);
+ }
+ catch (MissingResourceException x)
+ {
+ }
+ }
+ return def;
+ }
+
+ private char safeGetChar(ResourceBundle bundle,
+ String name, char def)
+ {
+ String r = null;
+ if (bundle != null)
+ {
+ try
+ {
+ r = bundle.getString(name);
+ }
+ catch (MissingResourceException x)
+ {
+ }
+ }
+ if (r == null || r.length() < 1)
+ return def;
+ return r.charAt(0);
+ }
+
+ /**
+ * This method initializes a new instance of
+ * <code>DecimalFormatSymbols</code> for the specified locale.
+ *
+ * @param loc The local to load symbols for.
+ */
+ public DecimalFormatSymbols (Locale loc)
+ {
+ ResourceBundle res;
+ try
+ {
+ res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation",
+ loc, ClassLoader.getSystemClassLoader());
+ }
+ catch (MissingResourceException x)
+ {
+ res = null;
+ }
+ currencySymbol = safeGetString (res, "currencySymbol", "$");
+ decimalSeparator = safeGetChar (res, "decimalSeparator", '.');
+ digit = safeGetChar (res, "digit", '#');
+ exponential = safeGetChar (res, "exponential", 'E');
+ groupingSeparator = safeGetChar (res, "groupingSeparator", ',');
+ infinity = safeGetString (res, "infinity", "\u221e");
+ // FIXME: default?
+ intlCurrencySymbol = safeGetString (res, "intlCurrencySymbol", "$");
+ try
+ {
+ monetarySeparator = safeGetChar (res, "monetarySeparator", '.');
+ }
+ catch (MissingResourceException x)
+ {
+ monetarySeparator = decimalSeparator;
+ }
+ minusSign = safeGetChar (res, "minusSign", '-');
+ NaN = safeGetString (res, "NaN", "\ufffd");
+ patternSeparator = safeGetChar (res, "patternSeparator", ';');
+ percent = safeGetChar (res, "percent", '%');
+ perMill = safeGetChar (res, "perMill", '\u2030');
+ zeroDigit = safeGetChar (res, "zeroDigit", '0');
+ locale = loc;
+ }
+
+ /**
+ * This method this this object for equality against the specified object.
+ * This will be true if and only if the following criteria are met with
+ * regard to the specified object:
+ * <p>
+ * <ul>
+ * <li>It is not <code>null</code>.</li>
+ * <li>It is an instance of <code>DecimalFormatSymbols</code>.</li>
+ * <li>All of its symbols are identical to the symbols in this object.</li>
+ * </ul>
+ *
+ * @return <code>true</code> if the specified object is equal to this
+ * object, <code>false</code> otherwise.
+ */
+ public boolean equals (Object obj)
+ {
+ if (! (obj instanceof DecimalFormatSymbols))
+ return false;
+ DecimalFormatSymbols dfs = (DecimalFormatSymbols) obj;
+ return (currencySymbol.equals(dfs.currencySymbol)
+ && decimalSeparator == dfs.decimalSeparator
+ && digit == dfs.digit
+ && exponential == dfs.exponential
+ && groupingSeparator == dfs.groupingSeparator
+ && infinity.equals(dfs.infinity)
+ && intlCurrencySymbol.equals(dfs.intlCurrencySymbol)
+ && minusSign == dfs.minusSign
+ && monetarySeparator == dfs.monetarySeparator
+ && NaN.equals(dfs.NaN)
+ && patternSeparator == dfs.patternSeparator
+ && percent == dfs.percent
+ && perMill == dfs.perMill
+ && zeroDigit == dfs.zeroDigit);
+ }
+
+ /**
+ * Returns the currency corresponding to the currency symbol stored
+ * in the instance of <code>DecimalFormatSymbols</code>.
+ *
+ * @return A new instance of <code>Currency</code> if
+ * the currency code matches a known one.
+ */
+ public Currency getCurrency ()
+ {
+ return Currency.getInstance (currencySymbol);
+ }
+
+ /**
+ * This method returns the currency symbol in local format. For example,
+ * "$" for Canadian dollars.
+ *
+ * @return The currency symbol in local format.
+ */
+ public String getCurrencySymbol ()
+ {
+ return currencySymbol;
+ }
+
+ /**
+ * This method returns the character used as the decimal point.
+ *
+ * @return The character used as the decimal point.
+ */
+ public char getDecimalSeparator ()
+ {
+ return decimalSeparator;
+ }
+
+ /**
+ * This method returns the character used to represent a digit in a
+ * format pattern string.
+ *
+ * @return The character used to represent a digit in a format
+ * pattern string.
+ */
+ public char getDigit ()
+ {
+ return digit;
+ }
+
+ // This is our own extension.
+ char getExponential ()
+ {
+ return exponential;
+ }
+
+ /**
+ * This method sets the character used to separate groups of digits. For
+ * example, the United States uses a comma (,) to separate thousands in
+ * a number.
+ *
+ * @return The character used to separate groups of digits.
+ */
+ public char getGroupingSeparator ()
+ {
+ return groupingSeparator;
+ }
+
+ /**
+ * This method returns the character used to represent infinity.
+ *
+ * @return The character used to represent infinity.
+ */
+ public String getInfinity ()
+ {
+ return infinity;
+ }
+
+ /**
+ * This method returns the currency symbol in international format. For
+ * example, "C$" for Canadian dollars.
+ *
+ * @return The currency symbol in international format.
+ */
+ public String getInternationalCurrencySymbol ()
+ {
+ return intlCurrencySymbol;
+ }
+
+ /**
+ * This method returns the character used to represent the minus sign.
+ *
+ * @return The character used to represent the minus sign.
+ */
+ public char getMinusSign ()
+ {
+ return minusSign;
+ }
+
+ /**
+ * This method returns the character used to represent the decimal
+ * point for currency values.
+ *
+ * @return The decimal point character used in currency values.
+ */
+ public char getMonetaryDecimalSeparator ()
+ {
+ return monetarySeparator;
+ }
+
+ /**
+ * This method returns the string used to represent the NaN (not a number)
+ * value.
+ *
+ * @return The string used to represent NaN
+ */
+ public String getNaN ()
+ {
+ return NaN;
+ }
+
+ /**
+ * This method returns the character used to separate positive and negative
+ * subpatterns in a format pattern.
+ *
+ * @return The character used to separate positive and negative subpatterns
+ * in a format pattern.
+ */
+ public char getPatternSeparator ()
+ {
+ return patternSeparator;
+ }
+
+ /**
+ * This method returns the character used as the percent sign.
+ *
+ * @return The character used as the percent sign.
+ */
+ public char getPercent ()
+ {
+ return percent;
+ }
+
+ /**
+ * This method returns the character used as the per mille character.
+ *
+ * @return The per mille character.
+ */
+ public char getPerMill ()
+ {
+ return perMill;
+ }
+
+ /**
+ * This method returns the character used to represent the digit zero.
+ *
+ * @return The character used to represent the digit zero.
+ */
+ public char getZeroDigit ()
+ {
+ return zeroDigit;
+ }
+
+ /**
+ * This method returns a hash value for this object.
+ *
+ * @return A hash value for this object.
+ */
+ public int hashCode ()
+ {
+ // Compute based on zero digit, grouping separator, and decimal
+ // separator -- JCL book. This probably isn't a very good hash
+ // code.
+ return zeroDigit << 16 + groupingSeparator << 8 + decimalSeparator;
+ }
+
+ /**
+ * This method sets the currency to the specified value.
+ *
+ * @param currency The new currency
+ */
+ public void setCurrency (Currency currency)
+ {
+ setCurrencySymbol (currency.getSymbol());
+ }
+
+ /**
+ * This method sets the currency symbol to the specified value.
+ *
+ * @param currency The new currency symbol
+ */
+ public void setCurrencySymbol (String currency)
+ {
+ currencySymbol = currency;
+ }
+
+ /**
+ * This method sets the decimal point character to the specified value.
+ *
+ * @param decimalSep The new decimal point character
+ */
+ public void setDecimalSeparator (char decimalSep)
+ {
+ decimalSeparator = decimalSep;
+ }
+
+ /**
+ * This method sets the character used to represents a digit in a format
+ * string to the specified value.
+ *
+ * @param digit The character used to represent a digit in a format pattern.
+ */
+ public void setDigit (char digit)
+ {
+ this.digit = digit;
+ }
+
+ // This is our own extension.
+ void setExponential (char exp)
+ {
+ exponential = exp;
+ }
+
+ /**
+ * This method sets the character used to separate groups of digits.
+ *
+ * @param groupSep The character used to separate groups of digits.
+ */
+ public void setGroupingSeparator (char groupSep)
+ {
+ groupingSeparator = groupSep;
+ }
+
+ /**
+ * This method sets the string used to represents infinity.
+ *
+ * @param infinity The string used to represent infinity.
+ */
+ public void setInfinity (String infinity)
+ {
+ this.infinity = infinity;
+ }
+
+ /**
+ * This method sets the international currency symbols to the
+ * specified value.
+ *
+ * @param intlCurrencySymbol The new international currency symbol.
+ */
+ public void setInternationalCurrencySymbol (String currency)
+ {
+ intlCurrencySymbol = currency;
+ }
+
+ /**
+ * This method sets the character used to represent the minus sign.
+ *
+ * @param minusSign The character used to represent the minus sign.
+ */
+ public void setMinusSign (char minusSign)
+ {
+ this.minusSign = minusSign;
+ }
+
+ /**
+ * This method sets the character used for the decimal point in currency
+ * values.
+ *
+ * @param decimalSep The decimal point character used in currency values.
+ */
+ public void setMonetaryDecimalSeparator (char decimalSep)
+ {
+ monetarySeparator = decimalSep;
+ }
+
+ /**
+ * This method sets the string used to represent the NaN (not a
+ * number) value.
+ *
+ * @param nan The string used to represent NaN
+ */
+ public void setNaN (String nan)
+ {
+ NaN = nan;
+ }
+
+ /**
+ * This method sets the character used to separate positive and negative
+ * subpatterns in a format pattern.
+ *
+ * @param patternSep The character used to separate positive and
+ * negative subpatterns in a format pattern.
+ */
+ public void setPatternSeparator (char patternSep)
+ {
+ patternSeparator = patternSep;
+ }
+
+ /**
+ * This method sets the character used as the percent sign.
+ *
+ * @param percent The character used as the percent sign.
+ */
+ public void setPercent (char percent)
+ {
+ this.percent = percent;
+ }
+
+ /**
+ * This method sets the character used as the per mille character.
+ *
+ * @param perMill The per mille character.
+ */
+ public void setPerMill (char perMill)
+ {
+ this.perMill = perMill;
+ }
+
+ /**
+ * This method sets the character used to represent the digit zero.
+ *
+ * @param zeroDigit The character used to represent the digit zero.
+ */
+ public void setZeroDigit (char zeroDigit)
+ {
+ this.zeroDigit = zeroDigit;
+ }
+
+ /**
+ * @serial A string used for the local currency
+ */
+ private String currencySymbol;
+ /**
+ * @serial The <code>char</code> used to separate decimals in a number.
+ */
+ private char decimalSeparator;
+ /**
+ * @serial This is the <code>char</code> used to represent a digit in
+ * a format specification.
+ */
+ private char digit;
+ /**
+ * @serial This is the <code>char</code> used to represent the exponent
+ * separator in exponential notation.
+ */
+ private char exponential;
+ /**
+ * @serial This separates groups of thousands in numbers.
+ */
+ private char groupingSeparator;
+ /**
+ * @serial This string represents infinity.
+ */
+ private String infinity;
+ /**
+ * @serial This string represents the local currency in an international
+ * context, eg, "C$" for Canadian dollars.
+ */
+ private String intlCurrencySymbol;
+ /**
+ * @serial This is the character used to represent the minus sign.
+ */
+ private char minusSign;
+ /**
+ * @serial This character is used to separate decimals when formatting
+ * currency values.
+ */
+ private char monetarySeparator;
+ /**
+ * @serial This string is used the represent the Java NaN value for
+ * "not a number".
+ */
+ private String NaN;
+ /**
+ * @serial This is the character used to separate positive and negative
+ * subpatterns in a format pattern.
+ */
+ private char patternSeparator;
+ /**
+ * @serial This is the percent symbols
+ */
+ private char percent;
+ /**
+ * @serial This character is used for the mille percent sign.
+ */
+ private char perMill;
+ /**
+ * @serial This value represents the type of object being de-serialized.
+ * 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later.
+ * 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later,
+ * 2 indicates 1.4 or later
+ */
+ private int serialVersionOnStream = 2;
+ /**
+ * @serial This is the character used to represent 0.
+ */
+ private char zeroDigit;
+
+ /**
+ * @serial The locale of these currency symbols.
+ */
+ private Locale locale;
+
+ private static final long serialVersionUID = 5772796243397350300L;
+
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException
+ {
+ stream.defaultReadObject();
+ if (serialVersionOnStream < 1)
+ {
+ monetarySeparator = decimalSeparator;
+ exponential = 'E';
+ }
+ if (serialVersionOnStream < 2)
+ locale = Locale.getDefault();
+
+ serialVersionOnStream = 2;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/text/natCollator.cc b/gcc-4.2.1/libjava/java/text/natCollator.cc
new file mode 100644
index 000000000..676a4a41a
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/text/natCollator.cc
@@ -0,0 +1,74 @@
+// natCollator.cc - Native code for collation.
+
+/* Copyright (C) 1999 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@cygnus.com>.
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/text/Collator.h>
+#include <java/lang/StringBuffer.h>
+
+#include <java-chardecomp.h>
+
+void
+java::text::Collator::decomposeCharacter (jchar c,
+ java::lang::StringBuffer *buf)
+{
+ if (decmp == NO_DECOMPOSITION)
+ {
+ buf->append(c);
+ return;
+ }
+
+ const struct decomp_entry *base;
+ int high;
+
+ if (decmp == FULL_DECOMPOSITION)
+ {
+ base = full_decomposition;
+ high = sizeof (full_decomposition) / sizeof (struct decomp_entry);
+ }
+ else
+ {
+ base = canonical_decomposition;
+ high = sizeof (canonical_decomposition) / sizeof (struct decomp_entry);
+ }
+
+ // FIXME: this is probably a bit slow for the task at hand.
+ int i = high / 2;
+ int low = 0;
+ while (true)
+ {
+ if (c < base[i].key)
+ high = i;
+ else if (c > base[i].key)
+ low = i;
+ else
+ break;
+
+ int old = i;
+ i = (high + low) / 2;
+ if (i == old)
+ {
+ // Not in table, so it expands to itself.
+ buf->append(c);
+ return;
+ }
+ }
+
+ for (int j = 0; base[i].value[j] != '\0'; j += 2)
+ {
+ jchar x = (base[i].value[j] << 8) | (base[i].value[j + 1]);
+ buf->append (x);
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/util/Calendar.java b/gcc-4.2.1/libjava/java/util/Calendar.java
new file mode 100644
index 000000000..5559d8c53
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/Calendar.java
@@ -0,0 +1,1277 @@
+/* Calendar.java --
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 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.util;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * This class is an abstract base class for Calendars, which can be
+ * used to convert between <code>Date</code> objects and a set of
+ * integer fields which represent <code>YEAR</code>,
+ * <code>MONTH</code>, <code>DAY</code>, etc. The <code>Date</code>
+ * object represents a time in milliseconds since the Epoch. <br>
+ *
+ * This class is locale sensitive. To get the Object matching the
+ * current locale you can use <code>getInstance</code>. You can even provide
+ * a locale or a timezone. <code>getInstance</code> returns currently
+ * a <code>GregorianCalendar</code> for the current date. <br>
+ *
+ * If you want to convert a date from the Year, Month, Day, DayOfWeek,
+ * etc. Representation to a <code>Date</code>-Object, you can create
+ * a new Calendar with <code>getInstance()</code>,
+ * <code>clear()</code> all fields, <code>set(int,int)</code> the
+ * fields you need and convert it with <code>getTime()</code>. <br>
+ *
+ * If you want to convert a <code>Date</code>-object to the Calendar
+ * representation, create a new Calendar, assign the
+ * <code>Date</code>-Object with <code>setTime()</code>, and read the
+ * fields with <code>get(int)</code>. <br>
+ *
+ * When computing the date from time fields, it may happen, that there
+ * are either two few fields set, or some fields are inconsistent. This
+ * cases will handled in a calendar specific way. Missing fields are
+ * replaced by the fields of the epoch: 1970 January 1 00:00. <br>
+ *
+ * To understand, how the day of year is computed out of the fields
+ * look at the following table. It is traversed from top to bottom,
+ * and for the first line all fields are set, that line is used to
+ * compute the day. <br>
+ *
+ *
+<pre>month + day_of_month
+month + week_of_month + day_of_week
+month + day_of_week_of_month + day_of_week
+day_of_year
+day_of_week + week_of_year</pre>
+ *
+ * The hour_of_day-field takes precedence over the ampm and
+ * hour_of_ampm fields. <br>
+ *
+ * <STRONG>Note:</STRONG> This can differ for non-Gregorian calendar. <br>
+ *
+ * To convert a calendar to a human readable form and vice versa, use
+ * the <code>java.text.DateFormat</code> class. <br>
+ *
+ * Other useful things you can do with an calendar, is
+ * <code>roll</code>ing fields (that means increase/decrease a
+ * specific field by one, propagating overflows), or
+ * <code>add</code>ing/substracting a fixed amount to a field.
+ *
+ * @see Date
+ * @see GregorianCalendar
+ * @see TimeZone
+ * @see java.text.DateFormat
+ */
+public abstract class Calendar implements Serializable, Cloneable
+{
+ /**
+ * Constant representing the era time field.
+ */
+ public static final int ERA = 0;
+
+ /**
+ * Constant representing the year time field.
+ */
+ public static final int YEAR = 1;
+
+ /**
+ * Constant representing the month time field. This field
+ * should contain one of the JANUARY,...,DECEMBER constants below.
+ */
+ public static final int MONTH = 2;
+
+ /**
+ * Constant representing the week of the year field.
+ * @see #setFirstDayOfWeek(int)
+ */
+ public static final int WEEK_OF_YEAR = 3;
+
+ /**
+ * Constant representing the week of the month time field.
+ * @see #setFirstDayOfWeek(int)
+ */
+ public static final int WEEK_OF_MONTH = 4;
+
+ /**
+ * Constant representing the day time field, synonym for DAY_OF_MONTH.
+ */
+ public static final int DATE = 5;
+
+ /**
+ * Constant representing the day time field.
+ */
+ public static final int DAY_OF_MONTH = 5;
+
+ /**
+ * Constant representing the day of year time field. This is
+ * 1 for the first day in month.
+ */
+ public static final int DAY_OF_YEAR = 6;
+
+ /**
+ * Constant representing the day of week time field. This field
+ * should contain one of the SUNDAY,...,SATURDAY constants below.
+ */
+ public static final int DAY_OF_WEEK = 7;
+
+ /**
+ * Constant representing the day-of-week-in-month field. For
+ * instance this field contains 2 for the second thursday in a
+ * month. If you give a negative number here, the day will count
+ * from the end of the month.
+ */
+ public static final int DAY_OF_WEEK_IN_MONTH = 8;
+
+ /**
+ * Constant representing the part of the day for 12-hour clock. This
+ * should be one of AM or PM.
+ */
+ public static final int AM_PM = 9;
+
+ /**
+ * Constant representing the hour time field for 12-hour clock.
+ */
+ public static final int HOUR = 10;
+
+ /**
+ * Constant representing the hour of day time field for 24-hour clock.
+ */
+ public static final int HOUR_OF_DAY = 11;
+
+ /**
+ * Constant representing the minute of hour time field.
+ */
+ public static final int MINUTE = 12;
+
+ /**
+ * Constant representing the second time field.
+ */
+ public static final int SECOND = 13;
+
+ /**
+ * Constant representing the millisecond time field.
+ */
+ public static final int MILLISECOND = 14;
+
+ /**
+ * Constant representing the time zone offset time field for the
+ * time given in the other fields. It is measured in
+ * milliseconds. The default is the offset of the time zone.
+ */
+ public static final int ZONE_OFFSET = 15;
+
+ /**
+ * Constant representing the daylight saving time offset in
+ * milliseconds. The default is the value given by the time zone.
+ */
+ public static final int DST_OFFSET = 16;
+
+ /**
+ * Number of time fields.
+ */
+ public static final int FIELD_COUNT = 17;
+
+ /**
+ * Constant representing Sunday.
+ */
+ public static final int SUNDAY = 1;
+
+ /**
+ * Constant representing Monday.
+ */
+ public static final int MONDAY = 2;
+
+ /**
+ * Constant representing Tuesday.
+ */
+ public static final int TUESDAY = 3;
+
+ /**
+ * Constant representing Wednesday.
+ */
+ public static final int WEDNESDAY = 4;
+
+ /**
+ * Constant representing Thursday.
+ */
+ public static final int THURSDAY = 5;
+
+ /**
+ * Constant representing Friday.
+ */
+ public static final int FRIDAY = 6;
+
+ /**
+ * Constant representing Saturday.
+ */
+ public static final int SATURDAY = 7;
+
+ /**
+ * Constant representing January.
+ */
+ public static final int JANUARY = 0;
+
+ /**
+ * Constant representing February.
+ */
+ public static final int FEBRUARY = 1;
+
+ /**
+ * Constant representing March.
+ */
+ public static final int MARCH = 2;
+
+ /**
+ * Constant representing April.
+ */
+ public static final int APRIL = 3;
+
+ /**
+ * Constant representing May.
+ */
+ public static final int MAY = 4;
+
+ /**
+ * Constant representing June.
+ */
+ public static final int JUNE = 5;
+
+ /**
+ * Constant representing July.
+ */
+ public static final int JULY = 6;
+
+ /**
+ * Constant representing August.
+ */
+ public static final int AUGUST = 7;
+
+ /**
+ * Constant representing September.
+ */
+ public static final int SEPTEMBER = 8;
+
+ /**
+ * Constant representing October.
+ */
+ public static final int OCTOBER = 9;
+
+ /**
+ * Constant representing November.
+ */
+ public static final int NOVEMBER = 10;
+
+ /**
+ * Constant representing December.
+ */
+ public static final int DECEMBER = 11;
+
+ /**
+ * Constant representing Undecimber. This is an artificial name useful
+ * for lunar calendars.
+ */
+ public static final int UNDECIMBER = 12;
+
+ /**
+ * Useful constant for 12-hour clock.
+ */
+ public static final int AM = 0;
+
+ /**
+ * Useful constant for 12-hour clock.
+ */
+ public static final int PM = 1;
+
+ /**
+ * The time fields. The array is indexed by the constants YEAR to
+ * DST_OFFSET.
+ * @serial
+ */
+ protected int[] fields = new int[FIELD_COUNT];
+
+ /**
+ * The flags which tell if the fields above have a value.
+ * @serial
+ */
+ protected boolean[] isSet = new boolean[FIELD_COUNT];
+
+ /**
+ * The time in milliseconds since the epoch.
+ * @serial
+ */
+ protected long time;
+
+ /**
+ * Tells if the above field has a valid value.
+ * @serial
+ */
+ protected boolean isTimeSet;
+
+ /**
+ * Tells if the fields have a valid value. This superseeds the isSet
+ * array.
+ * @serial
+ */
+ protected boolean areFieldsSet;
+
+ /**
+ * The time zone of this calendar. Used by sub classes to do UTC / local
+ * time conversion. Sub classes can access this field with getTimeZone().
+ * @serial
+ */
+ private TimeZone zone;
+
+ /**
+ * Specifies if the date/time interpretation should be lenient.
+ * If the flag is set, a date such as "February 30, 1996" will be
+ * treated as the 29th day after the February 1. If this flag
+ * is false, such dates will cause an exception.
+ * @serial
+ */
+ private boolean lenient;
+
+ /**
+ * Sets what the first day of week is. This is used for
+ * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
+ * @serial
+ */
+ private int firstDayOfWeek;
+
+ /**
+ * Sets how many days are required in the first week of the year.
+ * If the first day of the year should be the first week you should
+ * set this value to 1. If the first week must be a full week, set
+ * it to 7.
+ * @serial
+ */
+ private int minimalDaysInFirstWeek;
+
+ /**
+ * Is set to true if DST_OFFSET is explicitly set. In that case
+ * it's value overrides the value computed from the current
+ * time and the timezone.
+ */
+ private boolean explicitDSTOffset = false;
+
+ /**
+ * The version of the serialized data on the stream.
+ * <dl><dt>0 or not present</dt>
+ * <dd> JDK 1.1.5 or later.</dd>
+ * <dt>1</dt>
+ * <dd>JDK 1.1.6 or later. This always writes a correct `time' value
+ * on the stream, as well as the other fields, to be compatible with
+ * earlier versions</dd></dl>
+ * @since JDK1.1.6
+ * @serial
+ */
+ private int serialVersionOnStream = 1;
+
+ /**
+ * XXX - I have not checked the compatibility. The documentation of
+ * the serialized-form is quite hairy...
+ */
+ static final long serialVersionUID = -1807547505821590642L;
+
+ /**
+ * The name of the resource bundle. Used only by getBundle()
+ */
+ private static final String bundleName = "gnu.java.locale.Calendar";
+
+ /**
+ * get resource bundle:
+ * The resources should be loaded via this method only. Iff an application
+ * uses this method, the resourcebundle is required.
+ */
+ private static ResourceBundle getBundle(Locale locale)
+ {
+ return ResourceBundle.getBundle(bundleName, locale,
+ ClassLoader.getSystemClassLoader());
+ }
+
+ /**
+ * Constructs a new Calendar with the default time zone and the default
+ * locale.
+ */
+ protected Calendar()
+ {
+ this(TimeZone.getDefault(), Locale.getDefault());
+ }
+
+ /**
+ * Constructs a new Calendar with the given time zone and the given
+ * locale.
+ * @param zone a time zone.
+ * @param locale a locale.
+ */
+ protected Calendar(TimeZone zone, Locale locale)
+ {
+ this.zone = zone;
+ lenient = true;
+
+ ResourceBundle rb = getBundle(locale);
+
+ firstDayOfWeek = ((Integer) rb.getObject("firstDayOfWeek")).intValue();
+ minimalDaysInFirstWeek = ((Integer) rb.getObject("minimalDaysInFirstWeek"))
+ .intValue();
+ clear();
+ }
+
+ /**
+ * Creates a calendar representing the actual time, using the default
+ * time zone and locale.
+ */
+ public static synchronized Calendar getInstance()
+ {
+ return getInstance(TimeZone.getDefault(), Locale.getDefault());
+ }
+
+ /**
+ * Creates a calendar representing the actual time, using the given
+ * time zone and the default locale.
+ * @param zone a time zone.
+ */
+ public static synchronized Calendar getInstance(TimeZone zone)
+ {
+ return getInstance(zone, Locale.getDefault());
+ }
+
+ /**
+ * Creates a calendar representing the actual time, using the default
+ * time zone and the given locale.
+ * @param locale a locale.
+ */
+ public static synchronized Calendar getInstance(Locale locale)
+ {
+ return getInstance(TimeZone.getDefault(), locale);
+ }
+
+ /**
+ * Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle
+ * lookup for every getInstance call.
+ */
+ private static HashMap cache = new HashMap();
+
+ /** Preset argument types for calendar-class constructor lookup. */
+ private static Class[] ctorArgTypes = new Class[]
+ {
+ TimeZone.class, Locale.class
+ };
+
+ /**
+ * Creates a calendar representing the actual time, using the given
+ * time zone and locale.
+ * @param zone a time zone.
+ * @param locale a locale.
+ */
+ public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
+ {
+ Class calendarClass = (Class) cache.get(locale);
+ Throwable exception = null;
+
+ try
+ {
+ if (calendarClass == null)
+ {
+ ResourceBundle rb = getBundle(locale);
+ String calendarClassName = rb.getString("calendarClass");
+
+ if (calendarClassName != null)
+ {
+ calendarClass = Class.forName(calendarClassName);
+ if (Calendar.class.isAssignableFrom(calendarClass))
+ cache.put(locale, calendarClass);
+ }
+ }
+
+ // GregorianCalendar is by far the most common case. Optimize by
+ // avoiding reflection.
+ if (calendarClass == GregorianCalendar.class)
+ return new GregorianCalendar(zone, locale);
+
+ if (Calendar.class.isAssignableFrom(calendarClass))
+ {
+ Constructor ctor = calendarClass.getConstructor(ctorArgTypes);
+ return (Calendar) ctor.newInstance(new Object[] { zone, locale });
+ }
+ }
+ catch (ClassNotFoundException ex)
+ {
+ exception = ex;
+ }
+ catch (IllegalAccessException ex)
+ {
+ exception = ex;
+ }
+ catch (NoSuchMethodException ex)
+ {
+ exception = ex;
+ }
+ catch (InstantiationException ex)
+ {
+ exception = ex;
+ }
+ catch (InvocationTargetException ex)
+ {
+ exception = ex;
+ }
+
+ throw new RuntimeException("Error instantiating calendar for locale "
+ + locale, exception);
+ }
+
+ /**
+ * Gets the set of locales for which a Calendar is available.
+ * @exception MissingResourceException if locale data couldn't be found.
+ * @return the set of locales.
+ */
+ public static synchronized Locale[] getAvailableLocales()
+ {
+ ResourceBundle rb = getBundle(new Locale("", ""));
+ return (Locale[]) rb.getObject("availableLocales");
+ }
+
+ /**
+ * Converts the time field values (<code>fields</code>) to
+ * milliseconds since the epoch UTC (<code>time</code>). Override
+ * this method if you write your own Calendar. */
+ protected abstract void computeTime();
+
+ /**
+ * Converts the milliseconds since the epoch UTC
+ * (<code>time</code>) to time fields
+ * (<code>fields</code>). Override this method if you write your
+ * own Calendar.
+ */
+ protected abstract void computeFields();
+
+ /**
+ * Converts the time represented by this object to a
+ * <code>Date</code>-Object.
+ * @return the Date.
+ */
+ public final Date getTime()
+ {
+ if (! isTimeSet)
+ computeTime();
+ return new Date(time);
+ }
+
+ /**
+ * Sets this Calendar's time to the given Date. All time fields
+ * are invalidated by this method.
+ */
+ public final void setTime(Date date)
+ {
+ setTimeInMillis(date.getTime());
+ }
+
+ /**
+ * Returns the time represented by this Calendar.
+ * @return the time in milliseconds since the epoch.
+ * @specnote This was made public in 1.4.
+ */
+ public long getTimeInMillis()
+ {
+ if (! isTimeSet)
+ computeTime();
+ return time;
+ }
+
+ /**
+ * Sets this Calendar's time to the given Time. All time fields
+ * are invalidated by this method.
+ * @param time the time in milliseconds since the epoch
+ * @specnote This was made public in 1.4.
+ */
+ public void setTimeInMillis(long time)
+ {
+ clear();
+ this.time = time;
+ isTimeSet = true;
+ computeFields();
+ }
+
+ /**
+ * Gets the value of the specified field. They are recomputed
+ * if they are invalid.
+ * @param field the time field. One of the time field constants.
+ * @return the value of the specified field
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ * @specnote Not final since JDK 1.4
+ */
+ public int get(int field)
+ {
+ // If the requested field is invalid, force all fields to be recomputed.
+ if (! isSet[field])
+ areFieldsSet = false;
+ complete();
+ return fields[field];
+ }
+
+ /**
+ * Gets the value of the specified field. This method doesn't
+ * recompute the fields, if they are invalid.
+ * @param field the time field. One of the time field constants.
+ * @return the value of the specified field, undefined if
+ * <code>areFieldsSet</code> or <code>isSet[field]</code> is false.
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ */
+ protected final int internalGet(int field)
+ {
+ return fields[field];
+ }
+
+ /**
+ * Sets the time field with the given value. This does invalidate
+ * the time in milliseconds.
+ * @param field the time field. One of the time field constants
+ * @param value the value to be set.
+ * @throws ArrayIndexOutOfBoundsException if field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ * @specnote Not final since JDK 1.4
+ */
+ public void set(int field, int value)
+ {
+ if (isTimeSet)
+ for (int i = 0; i < FIELD_COUNT; i++)
+ isSet[i] = false;
+ isTimeSet = false;
+ fields[field] = value;
+ isSet[field] = true;
+
+ // The five valid date patterns, in order of priority
+ // 1 YEAR + MONTH + DAY_OF_MONTH
+ // 2 YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
+ // 3 YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
+ // 4 YEAR + DAY_OF_YEAR
+ // 5 YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
+ switch (field)
+ {
+ case MONTH: // pattern 1,2 or 3
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ break;
+ case DAY_OF_MONTH: // pattern 1
+ isSet[YEAR] = true;
+ isSet[MONTH] = true;
+ isSet[WEEK_OF_MONTH] = true;
+ isSet[DAY_OF_WEEK] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ break;
+ case WEEK_OF_MONTH: // pattern 2
+ if (! isSet[DAY_OF_WEEK])
+ fields[DAY_OF_WEEK] = getFirstDayOfWeek();
+ isSet[YEAR] = true;
+ isSet[MONTH] = true;
+ isSet[DAY_OF_WEEK] = true;
+ isSet[DAY_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ break;
+ case DAY_OF_WEEK_IN_MONTH: // pattern 3
+ if (! isSet[DAY_OF_WEEK])
+ fields[DAY_OF_WEEK] = getFirstDayOfWeek();
+ isSet[YEAR] = true;
+ isSet[MONTH] = true;
+ isSet[DAY_OF_WEEK] = true;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[DAY_OF_MONTH] = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ break;
+ case DAY_OF_YEAR: // pattern 4
+ isSet[YEAR] = true;
+ isSet[MONTH] = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ break;
+ case WEEK_OF_YEAR: // pattern 5
+ if (! isSet[DAY_OF_WEEK])
+ fields[DAY_OF_WEEK] = getFirstDayOfWeek();
+ isSet[YEAR] = true;
+ isSet[DAY_OF_WEEK] = true;
+ isSet[MONTH] = false;
+ isSet[DAY_OF_MONTH] = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ break;
+ case AM_PM:
+ isSet[HOUR] = true;
+ isSet[HOUR_OF_DAY] = false;
+ break;
+ case HOUR_OF_DAY:
+ isSet[AM_PM] = false;
+ isSet[HOUR] = false;
+ break;
+ case HOUR:
+ isSet[AM_PM] = true;
+ isSet[HOUR_OF_DAY] = false;
+ break;
+ case DST_OFFSET:
+ explicitDSTOffset = true;
+ }
+
+ // May have crossed over a DST boundary.
+ if (! explicitDSTOffset && (field != DST_OFFSET && field != ZONE_OFFSET))
+ isSet[DST_OFFSET] = false;
+ }
+
+ /**
+ * Sets the fields for year, month, and date
+ * @param year the year.
+ * @param month the month, one of the constants JANUARY..UNDICEMBER.
+ * @param date the day of the month
+ */
+ public final void set(int year, int month, int date)
+ {
+ isTimeSet = false;
+ fields[YEAR] = year;
+ fields[MONTH] = month;
+ fields[DATE] = date;
+ isSet[YEAR] = isSet[MONTH] = isSet[DATE] = true;
+ isSet[WEEK_OF_YEAR] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[ERA] = false;
+
+ if (! explicitDSTOffset)
+ isSet[DST_OFFSET] = false; // May have crossed a DST boundary.
+ }
+
+ /**
+ * Sets the fields for year, month, date, hour, and minute
+ * @param year the year.
+ * @param month the month, one of the constants JANUARY..UNDICEMBER.
+ * @param date the day of the month
+ * @param hour the hour of day.
+ * @param minute the minute.
+ */
+ public final void set(int year, int month, int date, int hour, int minute)
+ {
+ set(year, month, date);
+ fields[HOUR_OF_DAY] = hour;
+ fields[MINUTE] = minute;
+ isSet[HOUR_OF_DAY] = isSet[MINUTE] = true;
+ isSet[AM_PM] = false;
+ isSet[HOUR] = false;
+ }
+
+ /**
+ * Sets the fields for year, month, date, hour, and minute
+ * @param year the year.
+ * @param month the month, one of the constants JANUARY..UNDICEMBER.
+ * @param date the day of the month
+ * @param hour the hour of day.
+ * @param minute the minute.
+ * @param second the second.
+ */
+ public final void set(int year, int month, int date, int hour, int minute,
+ int second)
+ {
+ set(year, month, date, hour, minute);
+ fields[SECOND] = second;
+ isSet[SECOND] = true;
+ }
+
+ /**
+ * Clears the values of all the time fields.
+ */
+ public final void clear()
+ {
+ isTimeSet = false;
+ areFieldsSet = false;
+ int zoneOffs = zone.getRawOffset();
+ int[] tempFields =
+ {
+ 1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0,
+ 0, 0, zoneOffs, 0
+ };
+ fields = tempFields;
+ for (int i = 0; i < FIELD_COUNT; i++)
+ isSet[i] = false;
+ }
+
+ /**
+ * Clears the values of the specified time field.
+ * @param field the time field. One of the time field constants.
+ * @throws ArrayIndexOutOfBoundsException if field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ */
+ public final void clear(int field)
+ {
+ int[] tempFields =
+ {
+ 1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0,
+ 0, 0, zone.getRawOffset(), 0
+ };
+ isTimeSet = false;
+ areFieldsSet = false;
+ isSet[field] = false;
+ fields[field] = tempFields[field];
+ }
+
+ /**
+ * Determines if the specified field has a valid value.
+ * @return true if the specified field has a value.
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ */
+ public final boolean isSet(int field)
+ {
+ return isSet[field];
+ }
+
+ /**
+ * Fills any unset fields in the time field list
+ */
+ protected void complete()
+ {
+ if (! isTimeSet)
+ computeTime();
+ if (! areFieldsSet)
+ computeFields();
+ }
+
+ /**
+ * Compares the given calendar with this.
+ * @param o the object to that we should compare.
+ * @return true, if the given object is a calendar, that represents
+ * the same time (but doesn't necessary have the same fields).
+ */
+ public boolean equals(Object o)
+ {
+ if (! (o instanceof Calendar))
+ return false;
+ Calendar cal = (Calendar) o;
+ if (getTimeInMillis() == ((Calendar) o).getTimeInMillis()
+ && cal.getFirstDayOfWeek() == getFirstDayOfWeek()
+ && cal.isLenient() == isLenient()
+ && cal.getMinimalDaysInFirstWeek() == getMinimalDaysInFirstWeek())
+ {
+ TimeZone self = getTimeZone();
+ TimeZone oth = cal.getTimeZone();
+ return self == null ? oth == null : self.equals(oth);
+ }
+ return false;
+ }
+
+ /**
+ * Returns a hash code for this calendar.
+ * @return a hash code, which fullfits the general contract of
+ * <code>hashCode()</code>
+ */
+ public int hashCode()
+ {
+ long time = getTimeInMillis();
+ int val = (int) ((time & 0xffffffffL) ^ (time >> 32));
+ val += (getFirstDayOfWeek() + (isLenient() ? 1230 : 1237)
+ + getMinimalDaysInFirstWeek());
+ TimeZone self = getTimeZone();
+ if (self != null)
+ val ^= self.hashCode();
+ return val;
+ }
+
+ /**
+ * Compares the given calendar with this.
+ * @param o the object to that we should compare.
+ * @return true, if the given object is a calendar, and this calendar
+ * represents a smaller time than the calendar o.
+ * @exception ClassCastException if o is not an calendar.
+ * @since JDK1.2 you don't need to override this method
+ */
+ public boolean before(Object o)
+ {
+ return getTimeInMillis() < ((Calendar) o).getTimeInMillis();
+ }
+
+ /**
+ * Compares the given calendar with this.
+ * @param o the object to that we should compare.
+ * @return true, if the given object is a calendar, and this calendar
+ * represents a bigger time than the calendar o.
+ * @exception ClassCastException if o is not an calendar.
+ * @since JDK1.2 you don't need to override this method
+ */
+ public boolean after(Object o)
+ {
+ return getTimeInMillis() > ((Calendar) o).getTimeInMillis();
+ }
+
+ /**
+ * Adds the specified amount of time to the given time field. The
+ * amount may be negative to subtract the time. If the field overflows
+ * it does what you expect: Jan, 25 + 10 Days is Feb, 4.
+ * @param field the time field. One of the time field constants.
+ * @param amount the amount of time.
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ */
+ public abstract void add(int field, int amount);
+
+ /**
+ * Rolls the specified time field up or down. This means add one
+ * to the specified field, but don't change the other fields. If
+ * the maximum for this field is reached, start over with the
+ * minimum value. <br>
+ *
+ * <strong>Note:</strong> There may be situation, where the other
+ * fields must be changed, e.g rolling the month on May, 31.
+ * The date June, 31 is automatically converted to July, 1.
+ * @param field the time field. One of the time field constants.
+ * @param up the direction, true for up, false for down.
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ */
+ public abstract void roll(int field, boolean up);
+
+ /**
+ * Rolls up or down the specified time field by the given amount.
+ * A negative amount rolls down. The default implementation is
+ * call <code>roll(int, boolean)</code> for the specified amount.
+ *
+ * Subclasses should override this method to do more intuitiv things.
+ *
+ * @param field the time field. One of the time field constants.
+ * @param amount the amount to roll by, positive for rolling up,
+ * negative for rolling down.
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ * @since JDK1.2
+ */
+ public void roll(int field, int amount)
+ {
+ while (amount > 0)
+ {
+ roll(field, true);
+ amount--;
+ }
+ while (amount < 0)
+ {
+ roll(field, false);
+ amount++;
+ }
+ }
+
+ /**
+ * Sets the time zone to the specified value.
+ * @param zone the new time zone
+ */
+ public void setTimeZone(TimeZone zone)
+ {
+ this.zone = zone;
+ }
+
+ /**
+ * Gets the time zone of this calendar
+ * @return the current time zone.
+ */
+ public TimeZone getTimeZone()
+ {
+ return zone;
+ }
+
+ /**
+ * Specifies if the date/time interpretation should be lenient.
+ * If the flag is set, a date such as "February 30, 1996" will be
+ * treated as the 29th day after the February 1. If this flag
+ * is false, such dates will cause an exception.
+ * @param lenient true, if the date should be interpreted linient,
+ * false if it should be interpreted strict.
+ */
+ public void setLenient(boolean lenient)
+ {
+ this.lenient = lenient;
+ }
+
+ /**
+ * Tells if the date/time interpretation is lenient.
+ * @return true, if the date should be interpreted linient,
+ * false if it should be interpreted strict.
+ */
+ public boolean isLenient()
+ {
+ return lenient;
+ }
+
+ /**
+ * Sets what the first day of week is. This is used for
+ * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
+ * @param value the first day of week. One of SUNDAY to SATURDAY.
+ */
+ public void setFirstDayOfWeek(int value)
+ {
+ firstDayOfWeek = value;
+ }
+
+ /**
+ * Gets what the first day of week is. This is used for
+ * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
+ * @return the first day of week. One of SUNDAY to SATURDAY.
+ */
+ public int getFirstDayOfWeek()
+ {
+ return firstDayOfWeek;
+ }
+
+ /**
+ * Sets how many days are required in the first week of the year.
+ * If the first day of the year should be the first week you should
+ * set this value to 1. If the first week must be a full week, set
+ * it to 7.
+ * @param value the minimal days required in the first week.
+ */
+ public void setMinimalDaysInFirstWeek(int value)
+ {
+ minimalDaysInFirstWeek = value;
+ }
+
+ /**
+ * Gets how many days are required in the first week of the year.
+ * @return the minimal days required in the first week.
+ * @see #setMinimalDaysInFirstWeek
+ */
+ public int getMinimalDaysInFirstWeek()
+ {
+ return minimalDaysInFirstWeek;
+ }
+
+ /**
+ * Gets the smallest value that is allowed for the specified field.
+ * @param field the time field. One of the time field constants.
+ * @return the smallest value.
+ */
+ public abstract int getMinimum(int field);
+
+ /**
+ * Gets the biggest value that is allowed for the specified field.
+ * @param field the time field. One of the time field constants.
+ * @return the biggest value.
+ */
+ public abstract int getMaximum(int field);
+
+ /**
+ * Gets the greatest minimum value that is allowed for the specified field.
+ * @param field the time field. One of the time field constants.
+ * @return the greatest minimum value.
+ */
+ public abstract int getGreatestMinimum(int field);
+
+ /**
+ * Gets the smallest maximum value that is allowed for the
+ * specified field. For example this is 28 for DAY_OF_MONTH.
+ * @param field the time field. One of the time field constants.
+ * @return the least maximum value.
+ */
+ public abstract int getLeastMaximum(int field);
+
+ /**
+ * Gets the actual minimum value that is allowed for the specified field.
+ * This value is dependent on the values of the other fields.
+ * @param field the time field. One of the time field constants.
+ * @return the actual minimum value.
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ * @since jdk1.2
+ */
+ public int getActualMinimum(int field)
+ {
+ Calendar tmp = (Calendar) clone(); // To avoid restoring state
+ int min = tmp.getGreatestMinimum(field);
+ int end = tmp.getMinimum(field);
+ tmp.set(field, min);
+ for (; min > end; min--)
+ {
+ tmp.add(field, -1); // Try to get smaller
+ if (tmp.get(field) != min - 1)
+ break; // Done if not successful
+ }
+ return min;
+ }
+
+ /**
+ * Gets the actual maximum value that is allowed for the specified field.
+ * This value is dependent on the values of the other fields.
+ * @param field the time field. One of the time field constants.
+ * @return the actual maximum value.
+ * @throws ArrayIndexOutOfBoundsException if the field is outside
+ * the valid range. The value of field must be >= 0 and
+ * <= <code>FIELD_COUNT</code>.
+ * @since jdk1.2
+ */
+ public int getActualMaximum(int field)
+ {
+ Calendar tmp = (Calendar) clone(); // To avoid restoring state
+ int max = tmp.getLeastMaximum(field);
+ int end = tmp.getMaximum(field);
+ tmp.set(field, max);
+ for (; max < end; max++)
+ {
+ tmp.add(field, 1);
+ if (tmp.get(field) != max + 1)
+ break;
+ }
+ return max;
+ }
+
+ /**
+ * Return a clone of this object.
+ */
+ public Object clone()
+ {
+ try
+ {
+ Calendar cal = (Calendar) super.clone();
+ cal.fields = (int[]) fields.clone();
+ cal.isSet = (boolean[]) isSet.clone();
+ return cal;
+ }
+ catch (CloneNotSupportedException ex)
+ {
+ return null;
+ }
+ }
+
+ private static final String[] fieldNames =
+ {
+ ",ERA=", ",YEAR=", ",MONTH=",
+ ",WEEK_OF_YEAR=",
+ ",WEEK_OF_MONTH=",
+ ",DAY_OF_MONTH=",
+ ",DAY_OF_YEAR=", ",DAY_OF_WEEK=",
+ ",DAY_OF_WEEK_IN_MONTH=",
+ ",AM_PM=", ",HOUR=",
+ ",HOUR_OF_DAY=", ",MINUTE=",
+ ",SECOND=", ",MILLISECOND=",
+ ",ZONE_OFFSET=", ",DST_OFFSET="
+ };
+
+ /**
+ * Returns a string representation of this object. It is mainly
+ * for debugging purposes and its content is implementation
+ * specific.
+ */
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName()).append('[');
+ sb.append("time=");
+ if (isTimeSet)
+ sb.append(time);
+ else
+ sb.append("?");
+ sb.append(",zone=" + zone);
+ sb.append(",areFieldsSet=" + areFieldsSet);
+ for (int i = 0; i < FIELD_COUNT; i++)
+ {
+ sb.append(fieldNames[i]);
+ if (isSet[i])
+ sb.append(fields[i]);
+ else
+ sb.append("?");
+ }
+ sb.append(",lenient=").append(lenient);
+ sb.append(",firstDayOfWeek=").append(firstDayOfWeek);
+ sb.append(",minimalDaysInFirstWeek=").append(minimalDaysInFirstWeek);
+ sb.append("]");
+ return sb.toString();
+ }
+
+ /**
+ * Saves the state of the object to the stream. Ideally we would
+ * only write the time field, but we need to be compatible with
+ * earlier versions. <br>
+ *
+ * This doesn't write the JDK1.1 field nextStamp to the stream, as
+ * I don't know what it is good for, and because the documentation
+ * says, that it could be omitted. */
+ private void writeObject(ObjectOutputStream stream) throws IOException
+ {
+ if (! isTimeSet)
+ computeTime();
+ stream.defaultWriteObject();
+ }
+
+ /**
+ * Reads the object back from stream (deserialization).
+ */
+ private void readObject(ObjectInputStream stream)
+ throws IOException, ClassNotFoundException
+ {
+ stream.defaultReadObject();
+ if (! isTimeSet)
+ computeTime();
+
+ if (serialVersionOnStream > 1)
+ {
+ // This is my interpretation of the serial number:
+ // Sun wants to remove all fields from the stream someday
+ // and will then increase the serialVersion number again.
+ // We prepare to be compatible.
+ fields = new int[FIELD_COUNT];
+ isSet = new boolean[FIELD_COUNT];
+ areFieldsSet = false;
+ }
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/util/Currency.java b/gcc-4.2.1/libjava/java/util/Currency.java
new file mode 100644
index 000000000..e1a28e0b8
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/Currency.java
@@ -0,0 +1,355 @@
+/* Currency.java -- Representation of a currency
+ Copyright (C) 2003, 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.util;
+
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.text.NumberFormat;
+
+/**
+ * Representation of a currency for a particular locale. Each currency
+ * is identified by its ISO 4217 code, and only one instance of this
+ * class exists per currency. As a result, instances are created
+ * via the <code>getInstance()</code> methods rather than by using
+ * a constructor.
+ *
+ * @see java.util.Locale
+ * @author Guilhem Lavaux (guilhem.lavaux@free.fr)
+ * @author Dalibor Topic (robilad@kaffe.org)
+ * @author Bryce McKinlay (mckinlay@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.4
+ */
+public final class Currency
+ implements Serializable
+{
+ /**
+ * For compatability with Sun's JDK
+ */
+ static final long serialVersionUID = -158308464356906721L;
+
+ /**
+ * The locale associated with this currency.
+ *
+ * @see #Currency(java.util.Locale)
+ * @see #getInstance(java.util.Locale)
+ * @see #getSymbol(java.util.Locale)
+ * @serial ignored.
+ */
+ private transient Locale locale;
+
+ /**
+ * The resource bundle which maps the currency to
+ * a ISO 4217 currency code.
+ *
+ * @see #getCurrencyCode()
+ * @serial ignored.
+ */
+ private transient ResourceBundle res;
+
+ /**
+ * The ISO 4217 currency code associated with this
+ * particular instance.
+ *
+ * @see #getCurrencyCode()
+ * @serial the ISO 4217 currency code
+ */
+ private String currencyCode;
+
+ /**
+ * A cache of <code>Currency</code> instances to
+ * ensure the singleton nature of this class. The key
+ * is the locale of the currency.
+ *
+ * @see #getInstance(java.util.Locale)
+ * @see #readResolve()
+ * @serial ignored.
+ */
+ private static transient Map cache;
+
+ /**
+ * Instantiates the cache.
+ */
+ static
+ {
+ cache = new HashMap();
+ }
+
+ /**
+ * Default constructor for deserialization
+ */
+ private Currency ()
+ {
+ }
+
+ /**
+ * Constructor to create a <code>Currency</code> object
+ * for a particular <code>Locale</code>.
+ * All components of the given locale, other than the
+ * country code, are ignored. The results of calling this
+ * method may vary over time, as the currency associated with
+ * a particular country changes. For countries without
+ * a given currency (e.g. Antarctica), the result is null.
+ *
+ * @param loc the locale for the new currency.
+ */
+ private Currency (Locale loc)
+ {
+ this.locale = loc;
+ this.res = ResourceBundle.getBundle ("gnu.java.locale.LocaleInformation",
+ locale, ClassLoader.getSystemClassLoader());
+ /* Retrieve the ISO4217 currency code */
+ try
+ {
+ currencyCode = res.getString ("intlCurrencySymbol");
+ }
+ catch (Exception _)
+ {
+ currencyCode = null;
+ }
+ }
+
+ /**
+ * Returns the ISO4217 currency code of this currency.
+ *
+ * @return a <code>String</code> containing currency code.
+ */
+ public String getCurrencyCode ()
+ {
+ return currencyCode;
+ }
+
+ /**
+ * Returns the number of digits which occur after the decimal point
+ * for this particular currency. For example, currencies such
+ * as the U.S. dollar, the Euro and the Great British pound have two
+ * digits following the decimal point to indicate the value which exists
+ * in the associated lower-valued coinage (cents in the case of the first
+ * two, pennies in the latter). Some currencies such as the Japanese
+ * Yen have no digits after the decimal point. In the case of pseudo
+ * currencies, such as IMF Special Drawing Rights, -1 is returned.
+ *
+ * @return the number of digits after the decimal separator for this currency.
+ */
+ public int getDefaultFractionDigits ()
+ {
+ NumberFormat currency = NumberFormat.getCurrencyInstance (locale);
+
+ return currency.getMaximumFractionDigits();
+ }
+
+ /**
+ * Builds a new currency instance for this locale.
+ * All components of the given locale, other than the
+ * country code, are ignored. The results of calling this
+ * method may vary over time, as the currency associated with
+ * a particular country changes. For countries without
+ * a given currency (e.g. Antarctica), the result is null.
+ *
+ * @param locale a <code>Locale</code> instance.
+ * @return a new <code>Currency</code> instance.
+ * @throws NullPointerException if the locale or its
+ * country code is null.
+ * @throws IllegalArgumentException if the country of
+ * the given locale is not a supported ISO3166 code.
+ */
+ public static Currency getInstance (Locale locale)
+ {
+ /**
+ * The new instance must be the only available instance
+ * for the currency it supports. We ensure this happens,
+ * while maintaining a suitable performance level, by
+ * creating the appropriate object on the first call to
+ * this method, and returning the cached instance on
+ * later calls.
+ */
+ Currency newCurrency;
+
+ /* Attempt to get the currency from the cache */
+ newCurrency = (Currency) cache.get(locale);
+ if (newCurrency == null)
+ {
+ /* Create the currency for this locale */
+ newCurrency = new Currency (locale);
+ /* Cache it */
+ cache.put(locale, newCurrency);
+ }
+ /* Return the instance */
+ return newCurrency;
+ }
+
+ /**
+ * Builds the currency corresponding to the specified currency code.
+ *
+ * @param currencyCode a string representing a currency code.
+ * @return a new <code>Currency</code> instance.
+ * @throws NullPointerException if currencyCode is null.
+ * @throws IllegalArgumentException if the supplied currency code
+ * is not a supported ISO 4217 code.
+ */
+ public static Currency getInstance (String currencyCode)
+ {
+ Locale[] allLocales = Locale.getAvailableLocales ();
+
+ for (int i = 0;i < allLocales.length; i++)
+ {
+ Currency testCurrency = getInstance (allLocales[i]);
+
+ if (testCurrency.getCurrencyCode() != null &&
+ testCurrency.getCurrencyCode().equals(currencyCode))
+ return testCurrency;
+ }
+ /*
+ * If we get this far, the code is not supported by any of
+ * our locales.
+ */
+ throw new IllegalArgumentException("The currency code, " + currencyCode +
+ ", is not supported.");
+ }
+
+ /**
+ * This method returns the symbol which precedes or follows a
+ * value in this particular currency. In cases where there is no
+ * such symbol for the currency, the ISO 4217 currency
+ * code is returned.
+ *
+ * @return the currency symbol, or the ISO 4217 currency code if
+ * one doesn't exist.
+ */
+ public String getSymbol()
+ {
+ try
+ {
+ /* What does this return if there is no mapping? */
+ return res.getString ("currencySymbol");
+ }
+ catch (Exception _)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * <p>
+ * This method returns the symbol which precedes or follows a
+ * value in this particular currency. The returned value is
+ * the symbol used to denote the currency in the specified locale.
+ * </p>
+ * <p>
+ * For example, a supplied locale may specify a different symbol
+ * for the currency, due to conflicts with its own currency.
+ * This would be the case with the American currency, the dollar.
+ * Locales that also use a dollar-based currency (e.g. Canada, Australia)
+ * need to differentiate the American dollar using 'US$' rather than '$'.
+ * So, supplying one of these locales to <code>getSymbol()</code> would
+ * return this value, rather than the standard '$'.
+ * </p>
+ * <p>
+ * In cases where there is no such symbol for a particular currency,
+ * the ISO 4217 currency code is returned.
+ * </p>
+ *
+ * @param locale the locale to express the symbol in.
+ * @return the currency symbol, or the ISO 4217 currency code if
+ * one doesn't exist.
+ * @throws NullPointerException if the locale is null.
+ */
+ public String getSymbol(Locale locale)
+ {
+ // TODO. The behaviour is unclear if locale != this.locale.
+ // First we need to implement fully LocaleInformation*.java
+
+ /*
+ * FIXME: My reading of how this method works has this implementation
+ * as wrong. It should return a value relating to how the specified
+ * locale handles the symbol for this currency. This implementation
+ * seems to just do a variation of getInstance(locale).
+ */
+ try
+ {
+ ResourceBundle localeResource =
+ ResourceBundle.getBundle ("gnu.java.locale.LocaleInformation",
+ locale, Currency.class.getClassLoader());
+
+ if (localeResource.equals(res))
+ return localeResource.getString ("currencySymbol");
+ else
+ return localeResource.getString ("intlCurrencySymbol");
+ }
+ catch (Exception e1)
+ {
+ try
+ {
+ return res.getString ("intlCurrencySymbol");
+ }
+ catch (Exception e2)
+ {
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Returns the international ISO4217 currency code of this currency.
+ *
+ * @return a <code>String</code> containing the ISO4217 currency code.
+ */
+ public String toString()
+ {
+ return getCurrencyCode();
+ }
+
+ /**
+ * Resolves the deserialized object to the singleton instance for its
+ * particular currency. The currency code of the deserialized instance
+ * is used to return the correct instance.
+ *
+ * @return the singleton instance for the currency specified by the
+ * currency code of the deserialized object. This replaces
+ * the deserialized object as the returned object from
+ * deserialization.
+ * @throws ObjectStreamException if a problem occurs with deserializing
+ * the object.
+ */
+ private Object readResolve()
+ throws ObjectStreamException
+ {
+ return getInstance(currencyCode);
+ }
+
+}
diff --git a/gcc-4.2.1/libjava/java/util/GregorianCalendar.java b/gcc-4.2.1/libjava/java/util/GregorianCalendar.java
new file mode 100644
index 000000000..dc77c2f50
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/GregorianCalendar.java
@@ -0,0 +1,1358 @@
+/* java.util.GregorianCalendar
+ Copyright (C) 1998, 1999, 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;
+
+
+/**
+ * <p>
+ * This class represents the Gregorian calendar, that is used in most
+ * countries all over the world. It does also handle the Julian calendar
+ * for dates smaller than the date of the change to the Gregorian calendar.
+ * The Gregorian calendar differs from the Julian calendar by a different
+ * leap year rule (no leap year every 100 years, except if year is divisible
+ * by 400).
+ * </p>
+ * <p>
+ * This change date is different from country to country, and can be changed with
+ * <code>setGregorianChange</code>. The first countries to adopt the Gregorian
+ * calendar did so on the 15th of October, 1582. This date followed October
+ * the 4th, 1582 in the Julian calendar system. The non-existant days that were
+ * omitted when the change took place are interpreted as Gregorian dates.
+ * </p>
+ * <p>
+ * Prior to the changeover date, New Year's Day occurred on the 25th of March.
+ * However, this class always takes New Year's Day as being the 1st of January.
+ * Client code should manually adapt the year value, if required, for dates
+ * between January the 1st and March the 24th in years prior to the changeover.
+ * </p>
+ * <p>
+ * Any date infinitely forwards or backwards in time can be represented by
+ * this class. A <em>proleptic</em> calendar system is used, which allows
+ * future dates to be created via the existing rules. This allows meaningful
+ * and consistent dates to be produced for all years. However, dates are only
+ * historically accurate following March the 1st, 4AD when the Julian calendar
+ * system was adopted. Prior to this, leap year rules were applied erraticly.
+ * </p>
+ * <p>
+ * There are two eras available for the Gregorian calendar, namely BC and AD.
+ * </p>
+ * <p>
+ * Weeks are defined as a period of seven days, beginning on the first day
+ * of the week, as returned by <code>getFirstDayOfWeek()</code>, and ending
+ * on the day prior to this.
+ * </p>
+ * <p>
+ * The weeks of the year are numbered from 1 to a possible 53. The first week
+ * of the year is defined as the first week that contains at least the minimum
+ * number of days of the first week in the new year (retrieved via
+ * <code>getMinimalDaysInFirstWeek()</code>). All weeks after this are numbered
+ * from 2 onwards.
+ * </p>
+ * <p>
+ * For example, take the year 2004. It began on a Thursday. The first week
+ * of 2004 depends both on where a week begins and how long it must minimally
+ * last. Let's say that the week begins on a Monday and must have a minimum
+ * of 5 days. In this case, the first week begins on Monday, the 5th of January.
+ * The first 4 days (Thursday to Sunday) are not eligible, as they are too few
+ * to make up the minimum number of days of the first week which must be in
+ * the new year. If the minimum was lowered to 4 days, then the first week
+ * would instead begin on Monday, the 29th of December, 2003. This first week
+ * has 4 of its days in the new year, and is now eligible.
+ * </p>
+ * <p>
+ * The weeks of the month are numbered from 0 to a possible 6. The first week
+ * of the month (numbered 1) is a set of days, prior to the first day of the week,
+ * which number at least the minimum number of days in a week. Unlike the first
+ * week of the year, the first week of the month only uses days from that particular
+ * month. As a consequence, it may have a variable number of days (from the minimum
+ * number required up to a full week of 7) and it need not start on the first day of
+ * the week. It must, however, be following by the first day of the week, as this
+ * marks the beginning of week 2. Any days of the month which occur prior to the
+ * first week (because the first day of the week occurs before the minimum number
+ * of days is met) are seen as week 0.
+ * </p>
+ * <p>
+ * Again, we will take the example of the year 2004 to demonstrate this. September
+ * 2004 begins on a Wednesday. Taking our first day of the week as Monday, and the
+ * minimum length of the first week as 6, we find that week 1 runs from Monday,
+ * the 6th of September to Sunday the 12th. Prior to the 6th, there are only
+ * 5 days (Wednesday through to Sunday). This is too small a number to meet the
+ * minimum, so these are classed as being days in week 0. Week 2 begins on the
+ * 13th, and so on. This changes if we reduce the minimum to 5. In this case,
+ * week 1 is a truncated week from Wednesday the 1st to Sunday the 5th, and week
+ * 0 doesn't exist. The first seven day week is week 2, starting on the 6th.
+ * </p>
+ * <p>
+ * On using the <code>clear()</code> method, the Gregorian calendar returns
+ * to its default value of the 1st of January, 1970 AD 00:00:00 (the epoch).
+ * The day of the week is set to the correct day for that particular time.
+ * The day is also the first of the month, and the date is in week 0.
+ * </p>
+ *
+ * @see Calendar
+ * @see TimeZone
+ * @see Calendar#getFirstDayOfWeek()
+ * @see Calendar#getMinimalDaysInFirstWeek()
+ */
+public class GregorianCalendar extends Calendar
+{
+ /**
+ * Constant representing the era BC (Before Christ).
+ */
+ public static final int BC = 0;
+
+ /**
+ * Constant representing the era AD (Anno Domini).
+ */
+ public static final int AD = 1;
+
+ /**
+ * The point at which the Gregorian calendar rules were used.
+ * This is locale dependent; the default for most catholic
+ * countries is midnight (UTC) on October 5, 1582 (Julian),
+ * or October 15, 1582 (Gregorian).
+ *
+ * @serial the changeover point from the Julian calendar
+ * system to the Gregorian.
+ */
+ private long gregorianCutover;
+
+ /**
+ * For compatability with Sun's JDK.
+ */
+ static final long serialVersionUID = -8125100834729963327L;
+
+ /**
+ * The name of the resource bundle. Used only by getBundle()
+ */
+ private static final String bundleName = "gnu.java.locale.Calendar";
+
+ /**
+ * Days in the epoch. Relative Jan 1, year '0' which is not a leap year.
+ * (although there is no year zero, this does not matter.)
+ * This is consistent with the formula:
+ * = (year-1)*365L + ((year-1) >> 2)
+ *
+ * Plus the gregorian correction:
+ * Math.floor((year-1) / 400.) - Math.floor((year-1) / 100.);
+ * For a correct julian date, the correction is -2 instead.
+ *
+ * The gregorian cutover in 1582 was 10 days, so by calculating the
+ * correction from year zero, we have 15 non-leap days (even centuries)
+ * minus 3 leap days (year 400,800,1200) = 12. Subtracting two corrects
+ * this to the correct number 10.
+ */
+ private static final int EPOCH_DAYS = 719162;
+
+ /**
+ * Constructs a new GregorianCalender representing the current
+ * time, using the default time zone and the default locale.
+ */
+ public GregorianCalendar()
+ {
+ this(TimeZone.getDefault(), Locale.getDefault());
+ }
+
+ /**
+ * Constructs a new GregorianCalender representing the current
+ * time, using the specified time zone and the default locale.
+ *
+ * @param zone a time zone.
+ */
+ public GregorianCalendar(TimeZone zone)
+ {
+ this(zone, Locale.getDefault());
+ }
+
+ /**
+ * Constructs a new GregorianCalender representing the current
+ * time, using the default time zone and the specified locale.
+ *
+ * @param locale a locale.
+ */
+ public GregorianCalendar(Locale locale)
+ {
+ this(TimeZone.getDefault(), locale);
+ }
+
+ /**
+ * Constructs a new GregorianCalender representing the current
+ * time with the given time zone and the given locale.
+ *
+ * @param zone a time zone.
+ * @param locale a locale.
+ */
+ public GregorianCalendar(TimeZone zone, Locale locale)
+ {
+ this(zone, locale, false);
+ setTimeInMillis(System.currentTimeMillis());
+ complete();
+ }
+
+ /**
+ * Common constructor that all constructors should call.
+ * @param zone a time zone.
+ * @param locale a locale.
+ * @param unused unused parameter to make the signature differ from
+ * the public constructor (TimeZone, Locale).
+ */
+ private GregorianCalendar(TimeZone zone, Locale locale, boolean unused)
+ {
+ super(zone, locale);
+ ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale,
+ ClassLoader
+ .getSystemClassLoader());
+ gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime();
+ }
+
+ /**
+ * Constructs a new GregorianCalendar representing midnight on the
+ * given date with the default time zone and locale.
+ * @param year corresponds to the YEAR time field.
+ * @param month corresponds to the MONTH time field.
+ * @param day corresponds to the DAY time field.
+ */
+ public GregorianCalendar(int year, int month, int day)
+ {
+ this(TimeZone.getDefault(), Locale.getDefault(), false);
+ set(year, month, day);
+ }
+
+ /**
+ * Constructs a new GregorianCalendar representing midnight on the
+ * given date with the default time zone and locale.
+ *
+ * @param year corresponds to the YEAR time field.
+ * @param month corresponds to the MONTH time field.
+ * @param day corresponds to the DAY time field.
+ * @param hour corresponds to the HOUR_OF_DAY time field.
+ * @param minute corresponds to the MINUTE time field.
+ */
+ public GregorianCalendar(int year, int month, int day, int hour, int minute)
+ {
+ this(TimeZone.getDefault(), Locale.getDefault(), false);
+ set(year, month, day, hour, minute);
+ }
+
+ /**
+ * Constructs a new GregorianCalendar representing midnight on the
+ * given date with the default time zone and locale.
+ *
+ * @param year corresponds to the YEAR time field.
+ * @param month corresponds to the MONTH time field.
+ * @param day corresponds to the DAY time field.
+ * @param hour corresponds to the HOUR_OF_DAY time field.
+ * @param minute corresponds to the MINUTE time field.
+ * @param second corresponds to the SECOND time field.
+ */
+ public GregorianCalendar(int year, int month, int day, int hour, int minute,
+ int second)
+ {
+ this(TimeZone.getDefault(), Locale.getDefault(), false);
+ set(year, month, day, hour, minute, second);
+ }
+
+ /**
+ * Sets the date of the switch from Julian dates to Gregorian dates.
+ * You can use <code>new Date(Long.MAX_VALUE)</code> to use a pure
+ * Julian calendar, or <code>Long.MIN_VALUE</code> for a pure Gregorian
+ * calendar.
+ *
+ * @param date the date of the change.
+ */
+ public void setGregorianChange(Date date)
+ {
+ gregorianCutover = date.getTime();
+ }
+
+ /**
+ * Gets the date of the switch from Julian dates to Gregorian dates.
+ *
+ * @return the date of the change.
+ */
+ public final Date getGregorianChange()
+ {
+ return new Date(gregorianCutover);
+ }
+
+ /**
+ * <p>
+ * Determines if the given year is a leap year. The result is
+ * undefined if the Gregorian change took place in 1800, so that
+ * the end of February is skipped, and that year is specified.
+ * (well...).
+ * </p>
+ * <p>
+ * To specify a year in the BC era, use a negative value calculated
+ * as 1 - y, where y is the required year in BC. So, 1 BC is 0,
+ * 2 BC is -1, 3 BC is -2, etc.
+ * </p>
+ *
+ * @param year a year (use a negative value for BC).
+ * @return true, if the given year is a leap year, false otherwise.
+ */
+ public boolean isLeapYear(int year)
+ {
+ // Only years divisible by 4 can be leap years
+ if ((year & 3) != 0)
+ return false;
+
+ // Is the leap-day a Julian date? Then it's a leap year
+ if (! isGregorian(year, 31 + 29 - 1))
+ return true;
+
+ // Apply gregorian rules otherwise
+ return ((year % 100) != 0 || (year % 400) == 0);
+ }
+
+ /**
+ * Retrieves the day of the week corresponding to the specified
+ * day of the specified year.
+ *
+ * @param year the year in which the dayOfYear occurs.
+ * @param dayOfYear the day of the year (an integer between 0 and
+ * and 366)
+ */
+ private int getWeekDay(int year, int dayOfYear)
+ {
+ boolean greg = isGregorian(year, dayOfYear);
+ int day = (int) getLinearDay(year, dayOfYear, greg);
+
+ // The epoch was a thursday.
+ int weekday = (day + THURSDAY) % 7;
+ if (weekday <= 0)
+ weekday += 7;
+ return weekday;
+ }
+
+ /**
+ * Returns the day of the week for the first day of a given month (0..11)
+ */
+ private int getFirstDayOfMonth(int year, int month)
+ {
+ int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+
+ if (month > 11)
+ {
+ year += (month / 12);
+ month = month % 12;
+ }
+
+ if (month < 0)
+ {
+ year += (int) month / 12;
+ month = month % 12;
+ if (month < 0)
+ {
+ month += 12;
+ year--;
+ }
+ }
+
+ int dayOfYear = dayCount[month] + 1;
+ if (month > 1)
+ if (isLeapYear(year))
+ dayOfYear++;
+
+ boolean greg = isGregorian(year, dayOfYear);
+ int day = (int) getLinearDay(year, dayOfYear, greg);
+
+ // The epoch was a thursday.
+ int weekday = (day + THURSDAY) % 7;
+ if (weekday <= 0)
+ weekday += 7;
+ return weekday;
+ }
+
+ /**
+ * Takes a year, and a (zero based) day of year and determines
+ * if it is gregorian or not.
+ */
+ private boolean isGregorian(int year, int dayOfYear)
+ {
+ int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear
+ - EPOCH_DAYS; // gregorian days from 1 to epoch.
+ int gregFactor = (int) Math.floor((double) (year - 1) / 400.)
+ - (int) Math.floor((double) (year - 1) / 100.);
+
+ return ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover);
+ }
+
+ /**
+ * Check set fields for validity, without leniency.
+ *
+ * @throws IllegalArgumentException if a field is invalid
+ */
+ private void nonLeniencyCheck() throws IllegalArgumentException
+ {
+ int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ int year = fields[YEAR];
+ int month = fields[MONTH];
+ int leap = isLeapYear(year) ? 1 : 0;
+
+ if (isSet[ERA] && fields[ERA] != AD && fields[ERA] != BC)
+ throw new IllegalArgumentException("Illegal ERA.");
+ if (isSet[YEAR] && fields[YEAR] < 1)
+ throw new IllegalArgumentException("Illegal YEAR.");
+ if (isSet[MONTH] && (month < 0 || month > 11))
+ throw new IllegalArgumentException("Illegal MONTH.");
+ if (isSet[WEEK_OF_YEAR])
+ {
+ int daysInYear = 365 + leap;
+ daysInYear += (getFirstDayOfMonth(year, 0) - 1); // pad first week
+ int last = getFirstDayOfMonth(year, 11) + 4;
+ if (last > 7)
+ last -= 7;
+ daysInYear += 7 - last;
+ int weeks = daysInYear / 7;
+ if (fields[WEEK_OF_YEAR] < 1 || fields[WEEK_OF_YEAR] > weeks)
+ throw new IllegalArgumentException("Illegal WEEK_OF_YEAR.");
+ }
+
+ if (isSet[WEEK_OF_MONTH])
+ {
+ int weeks = (month == 1 && leap == 0) ? 4 : 5;
+ if (fields[WEEK_OF_MONTH] < 1 || fields[WEEK_OF_MONTH] > weeks)
+ throw new IllegalArgumentException("Illegal WEEK_OF_MONTH.");
+ }
+
+ if (isSet[DAY_OF_MONTH])
+ if (fields[DAY_OF_MONTH] < 1
+ || fields[DAY_OF_MONTH] > month_days[month]
+ + ((month == 1) ? leap : 0))
+ throw new IllegalArgumentException("Illegal DAY_OF_MONTH.");
+
+ if (isSet[DAY_OF_YEAR]
+ && (fields[DAY_OF_YEAR] < 1 || fields[DAY_OF_YEAR] > 365 + leap))
+ throw new IllegalArgumentException("Illegal DAY_OF_YEAR.");
+
+ if (isSet[DAY_OF_WEEK]
+ && (fields[DAY_OF_WEEK] < 1 || fields[DAY_OF_WEEK] > 7))
+ throw new IllegalArgumentException("Illegal DAY_OF_WEEK.");
+
+ if (isSet[DAY_OF_WEEK_IN_MONTH])
+ {
+ int weeks = (month == 1 && leap == 0) ? 4 : 5;
+ if (fields[DAY_OF_WEEK_IN_MONTH] < -weeks
+ || fields[DAY_OF_WEEK_IN_MONTH] > weeks)
+ throw new IllegalArgumentException("Illegal DAY_OF_WEEK_IN_MONTH.");
+ }
+
+ if (isSet[AM_PM] && fields[AM_PM] != AM && fields[AM_PM] != PM)
+ throw new IllegalArgumentException("Illegal AM_PM.");
+ if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 11))
+ throw new IllegalArgumentException("Illegal HOUR.");
+ if (isSet[HOUR_OF_DAY]
+ && (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23))
+ throw new IllegalArgumentException("Illegal HOUR_OF_DAY.");
+ if (isSet[MINUTE] && (fields[MINUTE] < 0 || fields[MINUTE] > 59))
+ throw new IllegalArgumentException("Illegal MINUTE.");
+ if (isSet[SECOND] && (fields[SECOND] < 0 || fields[SECOND] > 59))
+ throw new IllegalArgumentException("Illegal SECOND.");
+ if (isSet[MILLISECOND]
+ && (fields[MILLISECOND] < 0 || fields[MILLISECOND] > 999))
+ throw new IllegalArgumentException("Illegal MILLISECOND.");
+ if (isSet[ZONE_OFFSET]
+ && (fields[ZONE_OFFSET] < -12 * 60 * 60 * 1000L
+ || fields[ZONE_OFFSET] > 12 * 60 * 60 * 1000L))
+ throw new IllegalArgumentException("Illegal ZONE_OFFSET.");
+ if (isSet[DST_OFFSET]
+ && (fields[DST_OFFSET] < -12 * 60 * 60 * 1000L
+ || fields[DST_OFFSET] > 12 * 60 * 60 * 1000L))
+ throw new IllegalArgumentException("Illegal DST_OFFSET.");
+ }
+
+ /**
+ * Converts the time field values (<code>fields</code>) to
+ * milliseconds since the epoch UTC (<code>time</code>).
+ *
+ * @throws IllegalArgumentException if any calendar fields
+ * are invalid.
+ */
+ protected synchronized void computeTime()
+ {
+ int millisInDay = 0;
+ int era = fields[ERA];
+ int year = fields[YEAR];
+ int month = fields[MONTH];
+ int day = fields[DAY_OF_MONTH];
+
+ int minute = fields[MINUTE];
+ int second = fields[SECOND];
+ int millis = fields[MILLISECOND];
+ int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+ int hour = 0;
+
+ if (! isLenient())
+ nonLeniencyCheck();
+
+ if (! isSet[MONTH] && (! isSet[DAY_OF_WEEK] || isSet[WEEK_OF_YEAR]))
+ {
+ // 5: YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
+ if (isSet[WEEK_OF_YEAR])
+ {
+ int first = getFirstDayOfMonth(year, 0);
+ int offs = 1;
+ int daysInFirstWeek = getFirstDayOfWeek() - first;
+ if (daysInFirstWeek <= 0)
+ daysInFirstWeek += 7;
+
+ if (daysInFirstWeek < getMinimalDaysInFirstWeek())
+ offs += daysInFirstWeek;
+ else
+ offs -= 7 - daysInFirstWeek;
+ month = 0;
+ day = offs + 7 * (fields[WEEK_OF_YEAR] - 1);
+ offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek();
+
+ if (offs < 0)
+ offs += 7;
+ day += offs;
+ }
+ else
+ {
+ // 4: YEAR + DAY_OF_YEAR
+ month = 0;
+ day = fields[DAY_OF_YEAR];
+ }
+ }
+ else
+ {
+ if (isSet[DAY_OF_WEEK])
+ {
+ int first = getFirstDayOfMonth(year, month);
+
+ // 3: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
+ if (isSet[DAY_OF_WEEK_IN_MONTH])
+ {
+ if (fields[DAY_OF_WEEK_IN_MONTH] < 0)
+ {
+ month++;
+ first = getFirstDayOfMonth(year, month);
+ day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH]);
+ }
+ else
+ day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1);
+
+ int offs = fields[DAY_OF_WEEK] - first;
+ if (offs < 0)
+ offs += 7;
+ day += offs;
+ }
+ else
+ { // 2: YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
+ int offs = 1;
+ int daysInFirstWeek = getFirstDayOfWeek() - first;
+ if (daysInFirstWeek <= 0)
+ daysInFirstWeek += 7;
+
+ if (daysInFirstWeek < getMinimalDaysInFirstWeek())
+ offs += daysInFirstWeek;
+ else
+ offs -= 7 - daysInFirstWeek;
+
+ day = offs + 7 * (fields[WEEK_OF_MONTH] - 1);
+ offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek();
+ if (offs <= 0)
+ offs += 7;
+ day += offs;
+ }
+ }
+
+ // 1: YEAR + MONTH + DAY_OF_MONTH
+ }
+ if (era == BC && year > 0)
+ year = 1 - year;
+
+ // rest of code assumes day/month/year set
+ // should negative BC years be AD?
+ // get the hour (but no check for validity)
+ if (isSet[HOUR])
+ {
+ hour = fields[HOUR];
+ if (fields[AM_PM] == PM)
+ hour += 12;
+ }
+ else
+ hour = fields[HOUR_OF_DAY];
+
+ // Read the era,year,month,day fields and convert as appropriate.
+ // Calculate number of milliseconds into the day
+ // This takes care of both h, m, s, ms over/underflows.
+ long allMillis = (((hour * 60L) + minute) * 60L + second) * 1000L + millis;
+ day += allMillis / (24 * 60 * 60 * 1000L);
+ millisInDay = (int) (allMillis % (24 * 60 * 60 * 1000L));
+
+ if (month < 0)
+ {
+ year += (int) month / 12;
+ month = month % 12;
+ if (month < 0)
+ {
+ month += 12;
+ year--;
+ }
+ }
+ if (month > 11)
+ {
+ year += (month / 12);
+ month = month % 12;
+ }
+
+ month_days[1] = isLeapYear(year) ? 29 : 28;
+
+ while (day <= 0)
+ {
+ if (month == 0)
+ {
+ year--;
+ month_days[1] = isLeapYear(year) ? 29 : 28;
+ }
+ month = (month + 11) % 12;
+ day += month_days[month];
+ }
+ while (day > month_days[month])
+ {
+ day -= (month_days[month]);
+ month = (month + 1) % 12;
+ if (month == 0)
+ {
+ year++;
+ month_days[1] = isLeapYear(year) ? 29 : 28;
+ }
+ }
+
+ // ok, by here we have valid day,month,year,era and millisinday
+ int dayOfYear = dayCount[month] + day - 1; // (day starts on 1)
+ if (isLeapYear(year) && month > 1)
+ dayOfYear++;
+
+ int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear
+ - EPOCH_DAYS; // gregorian days from 1 to epoch.
+ int gregFactor = (int) Math.floor((double) (year - 1) / 400.)
+ - (int) Math.floor((double) (year - 1) / 100.);
+
+ if ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover)
+ relativeDay += gregFactor;
+ else
+ relativeDay -= 2;
+
+ time = relativeDay * (24 * 60 * 60 * 1000L) + millisInDay;
+
+ // the epoch was a Thursday.
+ int weekday = (int) (relativeDay + THURSDAY) % 7;
+ if (weekday <= 0)
+ weekday += 7;
+ fields[DAY_OF_WEEK] = weekday;
+
+ // Time zone corrections.
+ TimeZone zone = getTimeZone();
+ int rawOffset = isSet[ZONE_OFFSET] ? fields[ZONE_OFFSET]
+ : zone.getRawOffset();
+
+ int dstOffset = isSet[DST_OFFSET] ? fields[DST_OFFSET]
+ : (zone.getOffset((year < 0) ? BC : AD,
+ (year < 0) ? 1 - year
+ : year,
+ month, day, weekday,
+ millisInDay)
+ - zone.getRawOffset());
+
+ time -= rawOffset + dstOffset;
+
+ isTimeSet = true;
+ }
+
+ /**
+ * Get the linear day in days since the epoch, using the
+ * Julian or Gregorian calendar as specified. If you specify a
+ * nonpositive year it is interpreted as BC as following: 0 is 1
+ * BC, -1 is 2 BC and so on.
+ *
+ * @param year the year of the date.
+ * @param dayOfYear the day of year of the date; 1 based.
+ * @param gregorian <code>true</code>, if we should use the Gregorian rules.
+ * @return the days since the epoch, may be negative.
+ */
+ private long getLinearDay(int year, int dayOfYear, boolean gregorian)
+ {
+ // The 13 is the number of days, that were omitted in the Gregorian
+ // Calender until the epoch.
+ // We shift right by 2 instead of dividing by 4, to get correct
+ // results for negative years (and this is even more efficient).
+ long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1)
+ - EPOCH_DAYS; // gregorian days from 1 to epoch.
+
+ if (gregorian)
+ {
+ // subtract the days that are missing in gregorian calendar
+ // with respect to julian calendar.
+ //
+ // Okay, here we rely on the fact that the gregorian
+ // calendar was introduced in the AD era. This doesn't work
+ // with negative years.
+ //
+ // The additional leap year factor accounts for the fact that
+ // a leap day is not seen on Jan 1 of the leap year.
+ int gregOffset = (int) Math.floor((double) (year - 1) / 400.)
+ - (int) Math.floor((double) (year - 1) / 100.);
+
+ return julianDay + gregOffset;
+ }
+ else
+ julianDay -= 2;
+ return julianDay;
+ }
+
+ /**
+ * Converts the given linear day into era, year, month,
+ * day_of_year, day_of_month, day_of_week, and writes the result
+ * into the fields array.
+ *
+ * @param day the linear day.
+ * @param gregorian true, if we should use Gregorian rules.
+ */
+ private void calculateDay(int[] fields, long day, boolean gregorian)
+ {
+ // the epoch was a Thursday.
+ int weekday = (int) (day + THURSDAY) % 7;
+ if (weekday <= 0)
+ weekday += 7;
+ fields[DAY_OF_WEEK] = weekday;
+
+ // get a first approximation of the year. This may be one
+ // year too big.
+ int year = 1970
+ + (int) (gregorian
+ ? ((day - 100L) * 400L) / (365L * 400L + 100L - 4L
+ + 1L) : ((day - 100L) * 4L) / (365L * 4L + 1L));
+ if (day >= 0)
+ year++;
+
+ long firstDayOfYear = getLinearDay(year, 1, gregorian);
+
+ // Now look in which year day really lies.
+ if (day < firstDayOfYear)
+ {
+ year--;
+ firstDayOfYear = getLinearDay(year, 1, gregorian);
+ }
+
+ day -= firstDayOfYear - 1; // day of year, one based.
+
+ fields[DAY_OF_YEAR] = (int) day;
+ if (year <= 0)
+ {
+ fields[ERA] = BC;
+ fields[YEAR] = 1 - year;
+ }
+ else
+ {
+ fields[ERA] = AD;
+ fields[YEAR] = year;
+ }
+
+ int leapday = isLeapYear(year) ? 1 : 0;
+ if (day <= 31 + 28 + leapday)
+ {
+ fields[MONTH] = (int) day / 32; // 31->JANUARY, 32->FEBRUARY
+ fields[DAY_OF_MONTH] = (int) day - 31 * fields[MONTH];
+ }
+ else
+ {
+ // A few more magic formulas
+ int scaledDay = ((int) day - leapday) * 5 + 8;
+ fields[MONTH] = scaledDay / (31 + 30 + 31 + 30 + 31);
+ fields[DAY_OF_MONTH] = (scaledDay % (31 + 30 + 31 + 30 + 31)) / 5 + 1;
+ }
+ }
+
+ /**
+ * Converts the milliseconds since the epoch UTC
+ * (<code>time</code>) to time fields
+ * (<code>fields</code>).
+ */
+ protected synchronized void computeFields()
+ {
+ boolean gregorian = (time >= gregorianCutover);
+
+ TimeZone zone = getTimeZone();
+ fields[ZONE_OFFSET] = zone.getRawOffset();
+ long localTime = time + fields[ZONE_OFFSET];
+
+ long day = localTime / (24 * 60 * 60 * 1000L);
+ int millisInDay = (int) (localTime % (24 * 60 * 60 * 1000L));
+
+ if (millisInDay < 0)
+ {
+ millisInDay += (24 * 60 * 60 * 1000);
+ day--;
+ }
+
+ calculateDay(fields, day, gregorian);
+ fields[DST_OFFSET] = zone.getOffset(fields[ERA], fields[YEAR],
+ fields[MONTH], fields[DAY_OF_MONTH],
+ fields[DAY_OF_WEEK], millisInDay)
+ - fields[ZONE_OFFSET];
+
+ millisInDay += fields[DST_OFFSET];
+ if (millisInDay >= 24 * 60 * 60 * 1000)
+ {
+ millisInDay -= 24 * 60 * 60 * 1000;
+ calculateDay(fields, ++day, gregorian);
+ }
+
+ fields[DAY_OF_WEEK_IN_MONTH] = (fields[DAY_OF_MONTH] + 6) / 7;
+
+ // which day of the week are we (0..6), relative to getFirstDayOfWeek
+ int relativeWeekday = (7 + fields[DAY_OF_WEEK] - getFirstDayOfWeek()) % 7;
+
+ fields[WEEK_OF_MONTH] = (fields[DAY_OF_MONTH] - relativeWeekday + 12) / 7;
+
+ int weekOfYear = (fields[DAY_OF_YEAR] - relativeWeekday + 6) / 7;
+
+ // Do the Correction: getMinimalDaysInFirstWeek() is always in the
+ // first week.
+ int minDays = getMinimalDaysInFirstWeek();
+ int firstWeekday = (7 + getWeekDay(fields[YEAR], minDays)
+ - getFirstDayOfWeek()) % 7;
+ if (minDays - firstWeekday < 1)
+ weekOfYear++;
+ fields[WEEK_OF_YEAR] = weekOfYear;
+
+ int hourOfDay = millisInDay / (60 * 60 * 1000);
+ fields[AM_PM] = (hourOfDay < 12) ? AM : PM;
+ int hour = hourOfDay % 12;
+ fields[HOUR] = hour;
+ fields[HOUR_OF_DAY] = hourOfDay;
+ millisInDay %= (60 * 60 * 1000);
+ fields[MINUTE] = millisInDay / (60 * 1000);
+ millisInDay %= (60 * 1000);
+ fields[SECOND] = millisInDay / (1000);
+ fields[MILLISECOND] = millisInDay % 1000;
+
+ areFieldsSet = isSet[ERA] = isSet[YEAR] = isSet[MONTH] = isSet[WEEK_OF_YEAR] = isSet[WEEK_OF_MONTH] = isSet[DAY_OF_MONTH] = isSet[DAY_OF_YEAR] = isSet[DAY_OF_WEEK] = isSet[DAY_OF_WEEK_IN_MONTH] = isSet[AM_PM] = isSet[HOUR] = isSet[HOUR_OF_DAY] = isSet[MINUTE] = isSet[SECOND] = isSet[MILLISECOND] = isSet[ZONE_OFFSET] = isSet[DST_OFFSET] = true;
+ }
+
+ /**
+ * Return a hash code for this object, following the general contract
+ * specified by {@link Object#hashCode()}.
+ * @return the hash code
+ */
+ public int hashCode()
+ {
+ int val = (int) ((gregorianCutover >>> 32) ^ (gregorianCutover & 0xffffffff));
+ return super.hashCode() ^ val;
+ }
+
+ /**
+ * Compares the given calendar with this. An object, o, is
+ * equivalent to this if it is also a <code>GregorianCalendar</code>
+ * with the same time since the epoch under the same conditions
+ * (same change date and same time zone).
+ *
+ * @param o the object to that we should compare.
+ * @return true, if the given object is a calendar, that represents
+ * the same time (but doesn't necessarily have the same fields).
+ * @throws IllegalArgumentException if one of the fields
+ * <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is
+ * specified, if an unknown field is specified or if one
+ * of the calendar fields receives an illegal value when
+ * leniancy is not enabled.
+ */
+ public boolean equals(Object o)
+ {
+ if (! (o instanceof GregorianCalendar))
+ return false;
+
+ GregorianCalendar cal = (GregorianCalendar) o;
+ return (cal.gregorianCutover == gregorianCutover
+ && super.equals(o));
+ }
+
+ /**
+ * Adds the specified amount of time to the given time field. The
+ * amount may be negative to subtract the time. If the field overflows
+ * it does what you expect: Jan, 25 + 10 Days is Feb, 4.
+ * @param field one of the time field constants.
+ * @param amount the amount of time to add.
+ * @exception IllegalArgumentException if <code>field</code> is
+ * <code>ZONE_OFFSET</code>, <code>DST_OFFSET</code>, or invalid; or
+ * if <code>amount</code> contains an out-of-range value and the calendar
+ * is not in lenient mode.
+ */
+ public void add(int field, int amount)
+ {
+ switch (field)
+ {
+ case YEAR:
+ complete();
+ fields[YEAR] += amount;
+ isTimeSet = false;
+ break;
+ case MONTH:
+ complete();
+ int months = fields[MONTH] + amount;
+ fields[YEAR] += months / 12;
+ fields[MONTH] = months % 12;
+ if (fields[MONTH] < 0)
+ {
+ fields[MONTH] += 12;
+ fields[YEAR]--;
+ }
+ int maxDay = getActualMaximum(DAY_OF_MONTH);
+ if (fields[DAY_OF_MONTH] > maxDay)
+ fields[DAY_OF_MONTH] = maxDay;
+ set(YEAR, fields[YEAR]);
+ set(MONTH, fields[MONTH]);
+ break;
+ case DAY_OF_MONTH:
+ case DAY_OF_YEAR:
+ case DAY_OF_WEEK:
+ if (! isTimeSet)
+ computeTime();
+ time += amount * (24 * 60 * 60 * 1000L);
+ areFieldsSet = false;
+ break;
+ case WEEK_OF_YEAR:
+ case WEEK_OF_MONTH:
+ case DAY_OF_WEEK_IN_MONTH:
+ if (! isTimeSet)
+ computeTime();
+ time += amount * (7 * 24 * 60 * 60 * 1000L);
+ areFieldsSet = false;
+ break;
+ case AM_PM:
+ if (! isTimeSet)
+ computeTime();
+ time += amount * (12 * 60 * 60 * 1000L);
+ areFieldsSet = false;
+ break;
+ case HOUR:
+ case HOUR_OF_DAY:
+ if (! isTimeSet)
+ computeTime();
+ time += amount * (60 * 60 * 1000L);
+ areFieldsSet = false;
+ break;
+ case MINUTE:
+ if (! isTimeSet)
+ computeTime();
+ time += amount * (60 * 1000L);
+ areFieldsSet = false;
+ break;
+ case SECOND:
+ if (! isTimeSet)
+ computeTime();
+ time += amount * (1000L);
+ areFieldsSet = false;
+ break;
+ case MILLISECOND:
+ if (! isTimeSet)
+ computeTime();
+ time += amount;
+ areFieldsSet = false;
+ break;
+ case ZONE_OFFSET:
+ case DST_OFFSET:default:
+ throw new IllegalArgumentException("Invalid or unknown field");
+ }
+ }
+
+ /**
+ * Rolls the specified time field up or down. This means add one
+ * to the specified field, but don't change the other fields. If
+ * the maximum for this field is reached, start over with the
+ * minimum value.
+ *
+ * <strong>Note:</strong> There may be situation, where the other
+ * fields must be changed, e.g rolling the month on May, 31.
+ * The date June, 31 is automatically converted to July, 1.
+ * This requires lenient settings.
+ *
+ * @param field the time field. One of the time field constants.
+ * @param up the direction, true for up, false for down.
+ * @throws IllegalArgumentException if one of the fields
+ * <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is
+ * specified, if an unknown field is specified or if one
+ * of the calendar fields receives an illegal value when
+ * leniancy is not enabled.
+ */
+ public void roll(int field, boolean up)
+ {
+ roll(field, up ? 1 : -1);
+ }
+
+ /**
+ * Checks that the fields are still within their legal bounds,
+ * following use of the <code>roll()</code> method.
+ *
+ * @param field the field to check.
+ * @param delta multipler for alterations to the <code>time</code>.
+ * @see #roll(int, boolean)
+ * @see #roll(int, int)
+ */
+ private void cleanUpAfterRoll(int field, int delta)
+ {
+ switch (field)
+ {
+ case ERA:
+ case YEAR:
+ case MONTH:
+ // check that day of month is still in correct range
+ if (fields[DAY_OF_MONTH] > getActualMaximum(DAY_OF_MONTH))
+ fields[DAY_OF_MONTH] = getActualMaximum(DAY_OF_MONTH);
+ isTimeSet = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ break;
+ case DAY_OF_MONTH:
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ time += delta * (24 * 60 * 60 * 1000L);
+ break;
+ case WEEK_OF_MONTH:
+ isSet[DAY_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ time += delta * (7 * 24 * 60 * 60 * 1000L);
+ break;
+ case DAY_OF_WEEK_IN_MONTH:
+ isSet[DAY_OF_MONTH] = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ time += delta * (7 * 24 * 60 * 60 * 1000L);
+ break;
+ case DAY_OF_YEAR:
+ isSet[MONTH] = false;
+ isSet[DAY_OF_MONTH] = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[DAY_OF_WEEK] = false;
+ isSet[WEEK_OF_YEAR] = false;
+ time += delta * (24 * 60 * 60 * 1000L);
+ break;
+ case WEEK_OF_YEAR:
+ isSet[MONTH] = false;
+ isSet[DAY_OF_MONTH] = false;
+ isSet[WEEK_OF_MONTH] = false;
+ isSet[DAY_OF_WEEK_IN_MONTH] = false;
+ isSet[DAY_OF_YEAR] = false;
+ time += delta * (7 * 24 * 60 * 60 * 1000L);
+ break;
+ case AM_PM:
+ isSet[HOUR_OF_DAY] = false;
+ time += delta * (12 * 60 * 60 * 1000L);
+ break;
+ case HOUR:
+ isSet[HOUR_OF_DAY] = false;
+ time += delta * (60 * 60 * 1000L);
+ break;
+ case HOUR_OF_DAY:
+ isSet[HOUR] = false;
+ isSet[AM_PM] = false;
+ time += delta * (60 * 60 * 1000L);
+ break;
+ case MINUTE:
+ time += delta * (60 * 1000L);
+ break;
+ case SECOND:
+ time += delta * (1000L);
+ break;
+ case MILLISECOND:
+ time += delta;
+ break;
+ }
+ }
+
+ /**
+ * Rolls the specified time field by the given amount. This means
+ * add amount to the specified field, but don't change the other
+ * fields. If the maximum for this field is reached, start over
+ * with the minimum value and vice versa for negative amounts.
+ *
+ * <strong>Note:</strong> There may be situation, where the other
+ * fields must be changed, e.g rolling the month on May, 31.
+ * The date June, 31 is automatically corrected to June, 30.
+ *
+ * @param field the time field. One of the time field constants.
+ * @param amount the amount by which we should roll.
+ * @throws IllegalArgumentException if one of the fields
+ * <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is
+ * specified, if an unknown field is specified or if one
+ * of the calendar fields receives an illegal value when
+ * leniancy is not enabled.
+ */
+ public void roll(int field, int amount)
+ {
+ switch (field)
+ {
+ case DAY_OF_WEEK:
+ // day of week is special: it rolls automatically
+ add(field, amount);
+ return;
+ case ZONE_OFFSET:
+ case DST_OFFSET:
+ throw new IllegalArgumentException("Can't roll time zone");
+ }
+ complete();
+ int min = getActualMinimum(field);
+ int range = getActualMaximum(field) - min + 1;
+ int oldval = fields[field];
+ int newval = (oldval - min + range + amount) % range + min;
+ if (newval < min)
+ newval += range;
+ fields[field] = newval;
+ cleanUpAfterRoll(field, newval - oldval);
+ }
+
+ /**
+ * The minimum values for the calendar fields.
+ */
+ private static final int[] minimums =
+ {
+ BC, 1, 0, 0, 1, 1, 1, SUNDAY, 1, AM,
+ 1, 0, 0, 0, 0, -(12 * 60 * 60 * 1000),
+ 0
+ };
+
+ /**
+ * The maximum values for the calendar fields.
+ */
+ private static final int[] maximums =
+ {
+ AD, 5000000, 11, 53, 5, 31, 366,
+ SATURDAY, 5, PM, 12, 23, 59, 59, 999,
+ +(12 * 60 * 60 * 1000),
+ (12 * 60 * 60 * 1000)
+ };
+
+ /**
+ * Gets the smallest value that is allowed for the specified field.
+ *
+ * @param field one of the time field constants.
+ * @return the smallest value for the specified field.
+ */
+ public int getMinimum(int field)
+ {
+ return minimums[field];
+ }
+
+ /**
+ * Gets the biggest value that is allowed for the specified field.
+ *
+ * @param field one of the time field constants.
+ * @return the biggest value.
+ */
+ public int getMaximum(int field)
+ {
+ return maximums[field];
+ }
+
+ /**
+ * Gets the greatest minimum value that is allowed for the specified field.
+ * This is the largest value returned by the <code>getActualMinimum(int)</code>
+ * method.
+ *
+ * @param field the time field. One of the time field constants.
+ * @return the greatest minimum value.
+ * @see #getActualMinimum(int)
+ */
+ public int getGreatestMinimum(int field)
+ {
+ if (field == WEEK_OF_YEAR)
+ return 1;
+ return minimums[field];
+ }
+
+ /**
+ * Gets the smallest maximum value that is allowed for the
+ * specified field. This is the smallest value returned
+ * by the <code>getActualMaximum(int)</code>. For example,
+ * this is 28 for DAY_OF_MONTH (as all months have at least
+ * 28 days).
+ *
+ * @param field the time field. One of the time field constants.
+ * @return the least maximum value.
+ * @see #getActualMaximum(int)
+ * @since 1.2
+ */
+ public int getLeastMaximum(int field)
+ {
+ switch (field)
+ {
+ case WEEK_OF_YEAR:
+ return 52;
+ case DAY_OF_MONTH:
+ return 28;
+ case DAY_OF_YEAR:
+ return 365;
+ case DAY_OF_WEEK_IN_MONTH:
+ case WEEK_OF_MONTH:
+ return 4;
+ default:
+ return maximums[field];
+ }
+ }
+
+ /**
+ * Gets the actual minimum value that is allowed for the specified field.
+ * This value is dependent on the values of the other fields. Note that
+ * this calls <code>complete()</code> if not enough fields are set. This
+ * can have ugly side effects. The value given depends on the current
+ * time used by this instance.
+ *
+ * @param field the time field. One of the time field constants.
+ * @return the actual minimum value.
+ * @since 1.2
+ */
+ public int getActualMinimum(int field)
+ {
+ if (field == WEEK_OF_YEAR)
+ {
+ int min = getMinimalDaysInFirstWeek();
+ if (min == 0)
+ return 1;
+ if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR])
+ complete();
+
+ int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
+ int weekday = getWeekDay(year, min);
+ if ((7 + weekday - getFirstDayOfWeek()) % 7 >= min - 1)
+ return 1;
+ return 0;
+ }
+ return minimums[field];
+ }
+
+ /**
+ * Gets the actual maximum value that is allowed for the specified field.
+ * This value is dependent on the values of the other fields. Note that
+ * this calls <code>complete()</code> if not enough fields are set. This
+ * can have ugly side effects. The value given depends on the current time
+ * used by this instance; thus, leap years have a maximum day of month value of
+ * 29, rather than 28.
+ *
+ * @param field the time field. One of the time field constants.
+ * @return the actual maximum value.
+ */
+ public int getActualMaximum(int field)
+ {
+ switch (field)
+ {
+ case WEEK_OF_YEAR:
+ {
+ if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR])
+ complete();
+
+ // This is wrong for the year that contains the gregorian change.
+ // I.e it gives the weeks in the julian year or in the gregorian
+ // year in that case.
+ int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
+ int lastDay = isLeapYear(year) ? 366 : 365;
+ int weekday = getWeekDay(year, lastDay);
+ int week = (lastDay + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7;
+
+ int minimalDays = getMinimalDaysInFirstWeek();
+ int firstWeekday = getWeekDay(year, minimalDays);
+ /*
+ * Is there a set of days at the beginning of the year, before the
+ * first day of the week, equal to or greater than the minimum number
+ * of days required in the first week?
+ */
+ if (minimalDays - (7 + firstWeekday - getFirstDayOfWeek()) % 7 < 1)
+ return week + 1; /* Add week 1: firstWeekday through to firstDayOfWeek */
+ }
+ case DAY_OF_MONTH:
+ {
+ if (! areFieldsSet || ! isSet[MONTH])
+ complete();
+ int month = fields[MONTH];
+
+ // If you change this, you should also change
+ // SimpleTimeZone.getDaysInMonth();
+ if (month == FEBRUARY)
+ {
+ if (! isSet[YEAR] || ! isSet[ERA])
+ complete();
+ int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
+ return isLeapYear(year) ? 29 : 28;
+ }
+ else if (month < AUGUST)
+ return 31 - (month & 1);
+ else
+ return 30 + (month & 1);
+ }
+ case DAY_OF_YEAR:
+ {
+ if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR])
+ complete();
+ int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
+ return isLeapYear(year) ? 366 : 365;
+ }
+ case DAY_OF_WEEK_IN_MONTH:
+ {
+ // This is wrong for the month that contains the gregorian change.
+ int daysInMonth = getActualMaximum(DAY_OF_MONTH);
+
+ // That's black magic, I know
+ return (daysInMonth - (fields[DAY_OF_MONTH] - 1) % 7 + 6) / 7;
+ }
+ case WEEK_OF_MONTH:
+ {
+ int daysInMonth = getActualMaximum(DAY_OF_MONTH);
+ int weekday = (daysInMonth - fields[DAY_OF_MONTH]
+ + fields[DAY_OF_WEEK] - SUNDAY) % 7 + SUNDAY;
+ return (daysInMonth + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7;
+ }
+ default:
+ return maximums[field];
+ }
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/util/Locale.java b/gcc-4.2.1/libjava/java/util/Locale.java
new file mode 100644
index 000000000..03689aa7a
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/Locale.java
@@ -0,0 +1,864 @@
+/* Locale.java -- i18n locales
+ Copyright (C) 1998, 1999, 2001, 2002, 2005, 2006 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.SystemProperties;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * Locales represent a specific country and culture. Classes which can be
+ * passed a Locale object tailor their information for a given locale. For
+ * instance, currency number formatting is handled differently for the USA
+ * and France.
+ *
+ * <p>Locales are made up of a language code, a country code, and an optional
+ * set of variant strings. Language codes are represented by
+ * <a href="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
+ * ISO 639:1988</a> w/ additions from ISO 639/RA Newsletter No. 1/1989
+ * and a decision of the Advisory Committee of ISO/TC39 on August 8, 1997.
+ *
+ * <p>Country codes are represented by
+ * <a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">
+ * ISO 3166</a>. Variant strings are vendor and browser specific. Standard
+ * variant strings include "POSIX" for POSIX, "WIN" for MS-Windows, and
+ * "MAC" for Macintosh. When there is more than one variant string, they must
+ * be separated by an underscore (U+005F).
+ *
+ * <p>The default locale is determined by the values of the system properties
+ * user.language, user.region, and user.variant, defaulting to "en". Note that
+ * the locale does NOT contain the conversion and formatting capabilities (for
+ * that, use ResourceBundle and java.text). Rather, it is an immutable tag
+ * object for identifying a given locale, which is referenced by these other
+ * classes when they must make locale-dependent decisions.
+ *
+ * @see ResourceBundle
+ * @see java.text.Format
+ * @see java.text.NumberFormat
+ * @see java.text.Collator
+ * @author Jochen Hoenicke
+ * @author Paul Fisher
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public final class Locale implements Serializable, Cloneable
+{
+ /** Locale which represents the English language. */
+ public static final Locale ENGLISH = getLocale("en");
+
+ /** Locale which represents the French language. */
+ public static final Locale FRENCH = getLocale("fr");
+
+ /** Locale which represents the German language. */
+ public static final Locale GERMAN = getLocale("de");
+
+ /** Locale which represents the Italian language. */
+ public static final Locale ITALIAN = getLocale("it");
+
+ /** Locale which represents the Japanese language. */
+ public static final Locale JAPANESE = getLocale("ja");
+
+ /** Locale which represents the Korean language. */
+ public static final Locale KOREAN = getLocale("ko");
+
+ /** Locale which represents the Chinese language. */
+ public static final Locale CHINESE = getLocale("zh");
+
+ /** Locale which represents the Chinese language as used in China. */
+ public static final Locale SIMPLIFIED_CHINESE = getLocale("zh", "CN");
+
+ /**
+ * Locale which represents the Chinese language as used in Taiwan.
+ * Same as TAIWAN Locale.
+ */
+ public static final Locale TRADITIONAL_CHINESE = getLocale("zh", "TW");
+
+ /** Locale which represents France. */
+ public static final Locale FRANCE = getLocale("fr", "FR");
+
+ /** Locale which represents Germany. */
+ public static final Locale GERMANY = getLocale("de", "DE");
+
+ /** Locale which represents Italy. */
+ public static final Locale ITALY = getLocale("it", "IT");
+
+ /** Locale which represents Japan. */
+ public static final Locale JAPAN = getLocale("ja", "JP");
+
+ /** Locale which represents Korea. */
+ public static final Locale KOREA = getLocale("ko", "KR");
+
+ /**
+ * Locale which represents China.
+ * Same as SIMPLIFIED_CHINESE Locale.
+ */
+ public static final Locale CHINA = SIMPLIFIED_CHINESE;
+
+ /**
+ * Locale which represents the People's Republic of China.
+ * Same as CHINA Locale.
+ */
+ public static final Locale PRC = CHINA;
+
+ /**
+ * Locale which represents Taiwan.
+ * Same as TRADITIONAL_CHINESE Locale.
+ */
+ public static final Locale TAIWAN = TRADITIONAL_CHINESE;
+
+ /** Locale which represents the United Kingdom. */
+ public static final Locale UK = getLocale("en", "GB");
+
+ /** Locale which represents the United States. */
+ public static final Locale US = getLocale("en", "US");
+
+ /** Locale which represents the English speaking portion of Canada. */
+ public static final Locale CANADA = getLocale("en", "CA");
+
+ /** Locale which represents the French speaking portion of Canada. */
+ public static final Locale CANADA_FRENCH = getLocale("fr", "CA");
+
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 9149081749638150636L;
+
+ /**
+ * The language code, as returned by getLanguage().
+ *
+ * @serial the languange, possibly ""
+ */
+ private String language;
+
+ /**
+ * The country code, as returned by getCountry().
+ *
+ * @serial the country, possibly ""
+ */
+ private String country;
+
+ /**
+ * The variant code, as returned by getVariant().
+ *
+ * @serial the variant, possibly ""
+ */
+ private String variant;
+
+ /**
+ * This is the cached hashcode. When writing to stream, we write -1.
+ *
+ * @serial should be -1 in serial streams
+ */
+ private int hashcode;
+
+ /**
+ * The default locale. Except for during bootstrapping, this should never be
+ * null. Note the logic in the main constructor, to detect when
+ * bootstrapping has completed.
+ */
+ private static Locale defaultLocale =
+ getLocale(SystemProperties.getProperty("user.language", "en"),
+ SystemProperties.getProperty("user.region", ""),
+ SystemProperties.getProperty("user.variant", ""));
+
+ /**
+ * Retrieves the locale with the specified language from the cache.
+ *
+ * @param language the language of the locale to retrieve.
+ * @return the locale.
+ */
+ private static Locale getLocale(String language)
+ {
+ return getLocale(language, "", "");
+ }
+
+ /**
+ * Retrieves the locale with the specified language and region
+ * from the cache.
+ *
+ * @param language the language of the locale to retrieve.
+ * @param region the region of the locale to retrieve.
+ * @return the locale.
+ */
+ private static Locale getLocale(String language, String region)
+ {
+ return getLocale(language, region, "");
+ }
+
+ /**
+ * Retrieves the locale with the specified language, region
+ * and variant from the cache.
+ *
+ * @param language the language of the locale to retrieve.
+ * @param region the region of the locale to retrieve.
+ * @param variant the variant of the locale to retrieve.
+ * @return the locale.
+ */
+ private static Locale getLocale(String language, String region, String variant)
+ {
+ return new Locale(language, region, variant);
+ }
+
+ /**
+ * Convert new iso639 codes to the old ones.
+ *
+ * @param language the language to check
+ * @return the appropriate code
+ */
+ private String convertLanguage(String language)
+ {
+ if (language.equals(""))
+ return language;
+ language = language.toLowerCase();
+ int index = "he,id,yi".indexOf(language);
+ if (index != -1)
+ return "iw,in,ji".substring(index, index + 2);
+ return language;
+ }
+
+ /**
+ * Creates a new locale for the given language and country.
+ *
+ * @param language lowercase two-letter ISO-639 A2 language code
+ * @param country uppercase two-letter ISO-3166 A2 contry code
+ * @param variant vendor and browser specific
+ * @throws NullPointerException if any argument is null
+ */
+ public Locale(String language, String country, String variant)
+ {
+ // During bootstrap, we already know the strings being passed in are
+ // the correct capitalization, and not null. We can't call
+ // String.toUpperCase during this time, since that depends on the
+ // default locale.
+ if (defaultLocale != null)
+ {
+ language = convertLanguage(language).intern();
+ country = country.toUpperCase().intern();
+ variant = variant.intern();
+ }
+ this.language = language;
+ this.country = country;
+ this.variant = variant;
+ hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
+ }
+
+ /**
+ * Creates a new locale for the given language and country.
+ *
+ * @param language lowercase two-letter ISO-639 A2 language code
+ * @param country uppercase two-letter ISO-3166 A2 country code
+ * @throws NullPointerException if either argument is null
+ */
+ public Locale(String language, String country)
+ {
+ this(language, country, "");
+ }
+
+ /**
+ * Creates a new locale for a language.
+ *
+ * @param language lowercase two-letter ISO-639 A2 language code
+ * @throws NullPointerException if either argument is null
+ * @since 1.4
+ */
+ public Locale(String language)
+ {
+ this(language, "", "");
+ }
+
+ /**
+ * Returns the default Locale. The default locale is generally once set
+ * on start up and then never changed. Normally you should use this locale
+ * for everywhere you need a locale. The initial setting matches the
+ * default locale, the user has chosen.
+ *
+ * @return the default locale for this virtual machine
+ */
+ public static Locale getDefault()
+ {
+ return defaultLocale;
+ }
+
+ /**
+ * Changes the default locale. Normally only called on program start up.
+ * Note that this doesn't change the locale for other programs. This has
+ * a security check,
+ * <code>PropertyPermission("user.language", "write")</code>, because of
+ * its potential impact to running code.
+ *
+ * @param newLocale the new default locale
+ * @throws NullPointerException if newLocale is null
+ * @throws SecurityException if permission is denied
+ */
+ public static void setDefault(Locale newLocale)
+ {
+ if (newLocale == null)
+ throw new NullPointerException();
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new PropertyPermission("user.language", "write"));
+ defaultLocale = newLocale;
+ }
+
+ /**
+ * Returns the list of available locales.
+ *
+ * @return the installed locales
+ */
+ public static Locale[] getAvailableLocales()
+ {
+ /* I only return those for which localized language
+ * or country information exists.
+ * XXX - remove hard coded list, and implement more locales (Sun's JDK 1.4
+ * has 148 installed locales!).
+ */
+ return new Locale[]
+ {
+ ENGLISH, FRENCH, GERMAN, new Locale("ga", "")
+ };
+ }
+
+ /**
+ * Returns a list of all 2-letter uppercase country codes as defined
+ * in ISO 3166.
+ *
+ * @return a list of acceptable country codes
+ */
+ public static String[] getISOCountries()
+ {
+ return new String[]
+ {
+ "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS",
+ "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI",
+ "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA",
+ "CC", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU",
+ "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE",
+ "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX",
+ "GA", "GB", "GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ",
+ "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU",
+ "ID", "IE", "IL", "IN", "IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP",
+ "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA",
+ "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC",
+ "MD", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS",
+ "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG",
+ "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG",
+ "PH", "PK", "PL", "PM", "PN", "PR", "PT", "PW", "PY", "QA", "RE", "RO",
+ "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK",
+ "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", "TF",
+ "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW",
+ "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI",
+ "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZR", "ZW"
+ };
+ }
+
+ /**
+ * Returns a list of all 2-letter lowercase language codes as defined
+ * in ISO 639 (both old and new variant).
+ *
+ * @return a list of acceptable language codes
+ */
+ public static String[] getISOLanguages()
+ {
+ return new String[]
+ {
+ "aa", "ab", "af", "am", "ar", "as", "ay", "az", "ba", "be", "bg", "bh",
+ "bi", "bn", "bo", "br", "ca", "co", "cs", "cy", "da", "de", "dz", "el",
+ "en", "eo", "es", "et", "eu", "fa", "fi", "fj", "fo", "fr", "fy", "ga",
+ "gd", "gl", "gn", "gu", "ha", "he", "hi", "hr", "hu", "hy", "ia", "id",
+ "ie", "ik", "in", "is", "it", "iu", "iw", "ja", "ji", "jw", "ka", "kk",
+ "kl", "km", "kn", "ko", "ks", "ku", "ky", "la", "ln", "lo", "lt", "lv",
+ "mg", "mi", "mk", "ml", "mn", "mo", "mr", "ms", "mt", "my", "na", "ne",
+ "nl", "no", "oc", "om", "or", "pa", "pl", "ps", "pt", "qu", "rm", "rn",
+ "ro", "ru", "rw", "sa", "sd", "sg", "sh", "si", "sk", "sl", "sm", "sn",
+ "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta", "te", "tg", "th",
+ "ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ug", "uk", "ur",
+ "uz", "vi", "vo", "wo", "xh", "yi", "yo", "za", "zh", "zu"
+ };
+ }
+
+ /**
+ * Returns the language code of this locale. Some language codes have changed
+ * as ISO 639 has evolved; this returns the old name, even if you built
+ * the locale with the new one.
+ *
+ * @return language code portion of this locale, or an empty String
+ */
+ public String getLanguage()
+ {
+ return language;
+ }
+
+ /**
+ * Returns the country code of this locale.
+ *
+ * @return country code portion of this locale, or an empty String
+ */
+ public String getCountry()
+ {
+ return country;
+ }
+
+ /**
+ * Returns the variant code of this locale.
+ *
+ * @return the variant code portion of this locale, or an empty String
+ */
+ public String getVariant()
+ {
+ return variant;
+ }
+
+ /**
+ * Gets the string representation of the current locale. This consists of
+ * the language, the country, and the variant, separated by an underscore.
+ * The variant is listed only if there is a language or country. Examples:
+ * "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr__MAC".
+ *
+ * @return the string representation of this Locale
+ * @see #getDisplayName()
+ */
+ public String toString()
+ {
+ if (language.length() == 0 && country.length() == 0)
+ return "";
+ else if (country.length() == 0 && variant.length() == 0)
+ return language;
+ StringBuffer result = new StringBuffer(language);
+ result.append('_').append(country);
+ if (variant.length() != 0)
+ result.append('_').append(variant);
+ return result.toString();
+ }
+
+ /**
+ * Returns the three-letter ISO language abbrevation of this locale.
+ *
+ * @throws MissingResourceException if the three-letter code is not known
+ */
+ public String getISO3Language()
+ {
+ // We know all strings are interned so we can use '==' for better performance.
+ if (language == "")
+ return "";
+ int index
+ = ("aa,ab,af,am,ar,as,ay,az,ba,be,bg,bh,bi,bn,bo,br,ca,co,cs,cy,da,"
+ + "de,dz,el,en,eo,es,et,eu,fa,fi,fj,fo,fr,fy,ga,gd,gl,gn,gu,ha,iw,"
+ + "hi,hr,hu,hy,ia,in,ie,ik,in,is,it,iu,iw,ja,ji,jw,ka,kk,kl,km,kn,"
+ + "ko,ks,ku,ky,la,ln,lo,lt,lv,mg,mi,mk,ml,mn,mo,mr,ms,mt,my,na,ne,"
+ + "nl,no,oc,om,or,pa,pl,ps,pt,qu,rm,rn,ro,ru,rw,sa,sd,sg,sh,si,sk,"
+ + "sl,sm,sn,so,sq,sr,ss,st,su,sv,sw,ta,te,tg,th,ti,tk,tl,tn,to,tr,"
+ + "ts,tt,tw,ug,uk,ur,uz,vi,vo,wo,xh,ji,yo,za,zh,zu")
+ .indexOf(language);
+
+ if (index % 3 != 0 || language.length() != 2)
+ throw new MissingResourceException
+ ("Can't find ISO3 language for " + language,
+ "java.util.Locale", language);
+
+ // Don't read this aloud. These are the three letter language codes.
+ return
+ ("aarabkaframharaasmaymazebakbelbulbihbisbenbodbrecatcoscescymdandeu"
+ + "dzoellengepospaesteusfasfinfijfaofrafrygaigdhglggrngujhauhebhinhrv"
+ + "hunhyeinaindileipkindislitaikuhebjpnyidjawkatkazkalkhmkankorkaskur"
+ + "kirlatlinlaolitlavmlgmrimkdmalmonmolmarmsamltmyanaunepnldnorociorm"
+ + "oripanpolpusporquerohrunronruskinsansndsagsrpsinslkslvsmosnasomsqi"
+ + "srpsswsotsunsweswatamteltgkthatirtuktgltsntonturtsotattwiuigukrurd"
+ + "uzbvievolwolxhoyidyorzhazhozul")
+ .substring(index, index + 3);
+ }
+
+ /**
+ * Returns the three-letter ISO country abbrevation of the locale.
+ *
+ * @throws MissingResourceException if the three-letter code is not known
+ */
+ public String getISO3Country()
+ {
+ // We know all strings are interned so we can use '==' for better performance.
+ if (country == "")
+ return "";
+ int index
+ = ("AD,AE,AF,AG,AI,AL,AM,AN,AO,AQ,AR,AS,AT,AU,AW,AZ,BA,BB,BD,BE,BF,"
+ + "BG,BH,BI,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CA,CC,CF,CG,CH,CI,CK,"
+ + "CL,CM,CN,CO,CR,CU,CV,CX,CY,CZ,DE,DJ,DK,DM,DO,DZ,EC,EE,EG,EH,ER,"
+ + "ES,ET,FI,FJ,FK,FM,FO,FR,FX,GA,GB,GD,GE,GF,GH,GI,GL,GM,GN,GP,GQ,"
+ + "GR,GS,GT,GU,GW,GY,HK,HM,HN,HR,HT,HU,ID,IE,IL,IN,IO,IQ,IR,IS,IT,"
+ + "JM,JO,JP,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,"
+ + "LT,LU,LV,LY,MA,MC,MD,MG,MH,MK,ML,MM,MN,MO,MP,MQ,MR,MS,MT,MU,MV,"
+ + "MW,MX,MY,MZ,NA,NC,NE,NF,NG,NI,NL,NO,NP,NR,NU,NZ,OM,PA,PE,PF,PG,"
+ + "PH,PK,PL,PM,PN,PR,PT,PW,PY,QA,RE,RO,RU,RW,SA,SB,SC,SD,SE,SG,SH,"
+ + "SI,SJ,SK,SL,SM,SN,SO,SR,ST,SV,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TM,TN,"
+ + "TO,TP,TR,TT,TV,TW,TZ,UA,UG,UM,US,UY,UZ,VA,VC,VE,VG,VI,VN,VU,WF,"
+ + "WS,YE,YT,YU,ZA,ZM,ZR,ZW")
+ .indexOf(country);
+
+ if (index % 3 != 0 || country.length() != 2)
+ throw new MissingResourceException
+ ("Can't find ISO3 country for " + country,
+ "java.util.Locale", country);
+
+ // Don't read this aloud. These are the three letter country codes.
+ return
+ ("ANDAREAFGATGAIAALBARMANTAGOATAARGASMAUTAUSABWAZEBIHBRBBGDBELBFABGR"
+ + "BHRBDIBENBMUBRNBOLBRABHSBTNBVTBWABLRBLZCANCCKCAFCOGCHECIVCOKCHLCMR"
+ + "CHNCOLCRICUBCPVCXRCYPCZEDEUDJIDNKDMADOMDZAECUESTEGYESHERIESPETHFIN"
+ + "FJIFLKFSMFROFRAFXXGABGBRGRDGEOGUFGHAGIBGRLGMBGINGLPGNQGRCSGSGTMGUM"
+ + "GNBGUYHKGHMDHNDHRVHTIHUNIDNIRLISRINDIOTIRQIRNISLITAJAMJORJPNKENKGZ"
+ + "KHMKIRCOMKNAPRKKORKWTCYMKAZLAOLBNLCALIELKALBRLSOLTULUXLVALBYMARMCO"
+ + "MDAMDGMHLMKDMLIMMRMNGMACMNPMTQMRTMSRMLTMUSMDVMWIMEXMYSMOZNAMNCLNER"
+ + "NFKNGANICNLDNORNPLNRUNIUNZLOMNPANPERPYFPNGPHLPAKPOLSPMPCNPRIPRTPLW"
+ + "PRYQATREUROMRUSRWASAUSLBSYCSDNSWESGPSHNSVNSJMSVKSLESMRSENSOMSURSTP"
+ + "SLVSYRSWZTCATCDATFTGOTHATJKTKLTKMTUNTONTMPTURTTOTUVTWNTZAUKRUGAUMI"
+ + "USAURYUZBVATVCTVENVGBVIRVNMVUTWLFWSMYEMMYTYUGZAFZMBZARZWE")
+ .substring(index, index + 3);
+ }
+
+ /**
+ * Gets the country name suitable for display to the user, formatted
+ * for the default locale. This has the same effect as
+ * <pre>
+ * getDisplayLanguage(Locale.getDefault());
+ * </pre>
+ *
+ * @return the language name of this locale localized to the default locale,
+ * with the ISO code as backup
+ */
+ public String getDisplayLanguage()
+ {
+ return getDisplayLanguage(defaultLocale);
+ }
+
+ /**
+ * <p>
+ * Gets the name of the language specified by this locale, in a form suitable
+ * for display to the user. If possible, the display name will be localized
+ * to the specified locale. For example, if the locale instance is
+ * <code>Locale.GERMANY</code>, and the specified locale is <code>Locale.UK</code>,
+ * the result would be 'German'. Using the German locale would instead give
+ * 'Deutsch'. If the display name can not be localized to the supplied
+ * locale, it will fall back on other output in the following order:
+ * </p>
+ * <ul>
+ * <li>the display name in the default locale</li>
+ * <li>the display name in English</li>
+ * <li>the ISO code</li>
+ * </ul>
+ * <p>
+ * If the language is unspecified by this locale, then the empty string is
+ * returned.
+ * </p>
+ *
+ * @param inLocale the locale to use for formatting the display string.
+ * @return the language name of this locale localized to the given locale,
+ * with the default locale, English and the ISO code as backups.
+ * @throws NullPointerException if the supplied locale is null.
+ */
+ public String getDisplayLanguage(Locale inLocale)
+ {
+ try
+ {
+ ResourceBundle bundle
+ = ResourceBundle.getBundle("gnu.java.locale.iso639", inLocale);
+ return bundle.getString(language);
+ }
+ catch (MissingResourceException ex)
+ {
+ return language;
+ }
+ }
+
+ /**
+ * Returns the country name of this locale localized to the
+ * default locale. If the localized is not found, the ISO code
+ * is returned. This has the same effect as
+ * <pre>
+ * getDisplayCountry(Locale.getDefault());
+ * </pre>
+ *
+ * @return the country name of this locale localized to the given locale,
+ * with the ISO code as backup
+ */
+ public String getDisplayCountry()
+ {
+ return getDisplayCountry(defaultLocale);
+ }
+
+ /**
+ * <p>
+ * Gets the name of the country specified by this locale, in a form suitable
+ * for display to the user. If possible, the display name will be localized
+ * to the specified locale. For example, if the locale instance is
+ * <code>Locale.GERMANY</code>, and the specified locale is <code>Locale.UK</code>,
+ * the result would be 'Germany'. Using the German locale would instead give
+ * 'Deutschland'. If the display name can not be localized to the supplied
+ * locale, it will fall back on other output in the following order:
+ * </p>
+ * <ul>
+ * <li>the display name in the default locale</li>
+ * <li>the display name in English</li>
+ * <li>the ISO code</li>
+ * </ul>
+ * <p>
+ * If the country is unspecified by this locale, then the empty string is
+ * returned.
+ * </p>
+ *
+ * @param inLocale the locale to use for formatting the display string.
+ * @return the country name of this locale localized to the given locale,
+ * with the default locale, English and the ISO code as backups.
+ * @throws NullPointerException if the supplied locale is null.
+ */
+ public String getDisplayCountry(Locale inLocale)
+ {
+ try
+ {
+ ResourceBundle bundle =
+ ResourceBundle.getBundle("gnu.java.locale.iso3166", inLocale);
+ return bundle.getString(country);
+ }
+ catch (MissingResourceException ex)
+ {
+ return country;
+ }
+ }
+
+ /**
+ * Returns the variant name of this locale localized to the
+ * default locale. If the localized is not found, the variant code
+ * itself is returned. This has the same effect as
+ * <pre>
+ * getDisplayVariant(Locale.getDefault());
+ * </pre>
+ *
+ * @return the variant code of this locale localized to the given locale,
+ * with the ISO code as backup
+ */
+ public String getDisplayVariant()
+ {
+ return getDisplayVariant(defaultLocale);
+ }
+
+ /**
+ * <p>
+ * Gets the name of the variant specified by this locale, in a form suitable
+ * for display to the user. If possible, the display name will be localized
+ * to the specified locale. For example, if the locale instance is a revised
+ * variant, and the specified locale is <code>Locale.UK</code>, the result
+ * would be 'REVISED'. Using the German locale would instead give
+ * 'Revidiert'. If the display name can not be localized to the supplied
+ * locale, it will fall back on other output in the following order:
+ * </p>
+ * <ul>
+ * <li>the display name in the default locale</li>
+ * <li>the display name in English</li>
+ * <li>the ISO code</li>
+ * </ul>
+ * <p>
+ * If the variant is unspecified by this locale, then the empty string is
+ * returned.
+ * </p>
+ *
+ * @param inLocale the locale to use for formatting the display string.
+ * @return the variant name of this locale localized to the given locale,
+ * with the default locale, English and the ISO code as backups.
+ * @throws NullPointerException if the supplied locale is null.
+ */
+ public String getDisplayVariant(Locale inLocale)
+ {
+ // XXX - load a bundle?
+ return variant;
+ }
+
+ /**
+ * Gets all local components suitable for display to the user, formatted
+ * for the default locale. For the language component, getDisplayLanguage
+ * is called. For the country component, getDisplayCountry is called.
+ * For the variant set component, getDisplayVariant is called.
+ *
+ * <p>The returned String will be one of the following forms:<br>
+ * <pre>
+ * language (country, variant)
+ * language (country)
+ * language (variant)
+ * country (variant)
+ * language
+ * country
+ * variant
+ * </pre>
+ *
+ * @return String version of this locale, suitable for display to the user
+ */
+ public String getDisplayName()
+ {
+ return getDisplayName(defaultLocale);
+ }
+
+ /**
+ * Gets all local components suitable for display to the user, formatted
+ * for a specified locale. For the language component,
+ * getDisplayLanguage(Locale) is called. For the country component,
+ * getDisplayCountry(Locale) is called. For the variant set component,
+ * getDisplayVariant(Locale) is called.
+ *
+ * <p>The returned String will be one of the following forms:<br>
+ * <pre>
+ * language (country, variant)
+ * language (country)
+ * language (variant)
+ * country (variant)
+ * language
+ * country
+ * variant
+ * </pre>
+ *
+ * @param locale locale to use for formatting
+ * @return String version of this locale, suitable for display to the user
+ */
+ public String getDisplayName(Locale locale)
+ {
+ StringBuffer result = new StringBuffer();
+ int count = 0;
+ String[] delimiters = {"", " (", ","};
+ if (language.length() != 0)
+ {
+ result.append(delimiters[count++]);
+ result.append(getDisplayLanguage(locale));
+ }
+ if (country.length() != 0)
+ {
+ result.append(delimiters[count++]);
+ result.append(getDisplayCountry(locale));
+ }
+ if (variant.length() != 0)
+ {
+ result.append(delimiters[count++]);
+ result.append(getDisplayVariant(locale));
+ }
+ if (count > 1)
+ result.append(")");
+ return result.toString();
+ }
+
+ /**
+ * Does the same as <code>Object.clone()</code> but does not throw
+ * a <code>CloneNotSupportedException</code>. Why anyone would
+ * use this method is a secret to me, since this class is immutable.
+ *
+ * @return the clone
+ */
+ public Object clone()
+ {
+ // This class is final, so no need to use native super.clone().
+ return new Locale(language, country, variant);
+ }
+
+ /**
+ * Return the hash code for this locale. The hashcode is the logical
+ * xor of the hash codes of the language, the country and the variant.
+ * The hash code is precomputed, since <code>Locale</code>s are often
+ * used in hash tables.
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ return hashcode;
+ }
+
+ /**
+ * Compares two locales. To be equal, obj must be a Locale with the same
+ * language, country, and variant code.
+ *
+ * @param obj the other locale
+ * @return true if obj is equal to this
+ */
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (! (obj instanceof Locale))
+ return false;
+ Locale l = (Locale) obj;
+
+ return (language == l.language
+ && country == l.country
+ && variant == l.variant);
+ }
+
+ /**
+ * Write the locale to an object stream.
+ *
+ * @param output the stream to write to
+ * @throws IOException if the write fails
+ * @serialData The first three fields are Strings representing language,
+ * country, and variant. The fourth field is a placeholder for
+ * the cached hashcode, but this is always written as -1, and
+ * recomputed when reading it back.
+ */
+ private void writeObject(ObjectOutputStream s)
+ throws IOException
+ {
+ ObjectOutputStream.PutField fields = s.putFields();
+ fields.put("hashcode", -1);
+ s.defaultWriteObject();
+ }
+
+ /**
+ * Reads a locale from the input stream.
+ *
+ * @param input the stream to read from
+ * @throws IOException if reading fails
+ * @throws ClassNotFoundException if reading fails
+ * @serialData the hashCode is always invalid and must be recomputed
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ language = language.intern();
+ country = country.intern();
+ variant = variant.intern();
+ hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
+ }
+} // class Locale
diff --git a/gcc-4.2.1/libjava/java/util/ResourceBundle.java b/gcc-4.2.1/libjava/java/util/ResourceBundle.java
new file mode 100644
index 000000000..19dd3cdf1
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/ResourceBundle.java
@@ -0,0 +1,580 @@
+/* ResourceBundle -- aids in loading resource bundles
+ Copyright (C) 1998, 1999, 2001, 2002, 2003, 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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A resource bundle contains locale-specific data. If you need localized
+ * data, you can load a resource bundle that matches the locale with
+ * <code>getBundle</code>. Now you can get your object by calling
+ * <code>getObject</code> or <code>getString</code> on that bundle.
+ *
+ * <p>When a bundle is demanded for a specific locale, the ResourceBundle
+ * is searched in following order (<i>def. language</i> stands for the
+ * two letter ISO language code of the default locale (see
+ * <code>Locale.getDefault()</code>).
+ *
+<pre>baseName_<i>language code</i>_<i>country code</i>_<i>variant</i>
+baseName_<i>language code</i>_<i>country code</i>
+baseName_<i>language code</i>
+baseName_<i>def. language</i>_<i>def. country</i>_<i>def. variant</i>
+baseName_<i>def. language</i>_<i>def. country</i>
+baseName_<i>def. language</i>
+baseName</pre>
+ *
+ * <p>A bundle is backed up by less specific bundles (omitting variant, country
+ * or language). But it is not backed up by the default language locale.
+ *
+ * <p>If you provide a bundle for a given locale, say
+ * <code>Bundle_en_UK_POSIX</code>, you must also provide a bundle for
+ * all sub locales, ie. <code>Bundle_en_UK</code>, <code>Bundle_en</code>, and
+ * <code>Bundle</code>.
+ *
+ * <p>When a bundle is searched, we look first for a class with the given
+ * name, then for a file with <code>.properties</code> extension in the
+ * classpath. The name must be a fully qualified classname (with dots as
+ * path separators).
+ *
+ * <p>(Note: This implementation always backs up the class with a properties
+ * file if that is existing, but you shouldn't rely on this, if you want to
+ * be compatible to the standard JDK.)
+ *
+ * @author Jochen Hoenicke
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see Locale
+ * @see ListResourceBundle
+ * @see PropertyResourceBundle
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public abstract class ResourceBundle
+{
+ /**
+ * The parent bundle. This is consulted when you call getObject and there
+ * is no such resource in the current bundle. This field may be null.
+ */
+ protected ResourceBundle parent;
+
+ /**
+ * The locale of this resource bundle. You can read this with
+ * <code>getLocale</code> and it is automatically set in
+ * <code>getBundle</code>.
+ */
+ private Locale locale;
+
+ private static native ClassLoader getCallingClassLoader();
+
+ /**
+ * The resource bundle cache.
+ */
+ private static Map bundleCache;
+
+ /**
+ * The last default Locale we saw. If this ever changes then we have to
+ * reset our caches.
+ */
+ private static Locale lastDefaultLocale;
+
+ /**
+ * The `empty' locale is created once in order to optimize
+ * tryBundle().
+ */
+ private static final Locale emptyLocale = new Locale("");
+
+ /**
+ * The constructor. It does nothing special.
+ */
+ public ResourceBundle()
+ {
+ }
+
+ /**
+ * Get a String from this resource bundle. Since most localized Objects
+ * are Strings, this method provides a convenient way to get them without
+ * casting.
+ *
+ * @param key the name of the resource
+ * @throws MissingResourceException if the resource can't be found
+ * @throws NullPointerException if key is null
+ * @throws ClassCastException if resource is not a string
+ */
+ public final String getString(String key)
+ {
+ return (String) getObject(key);
+ }
+
+ /**
+ * Get an array of Strings from this resource bundle. This method
+ * provides a convenient way to get it without casting.
+ *
+ * @param key the name of the resource
+ * @throws MissingResourceException if the resource can't be found
+ * @throws NullPointerException if key is null
+ * @throws ClassCastException if resource is not a string
+ */
+ public final String[] getStringArray(String key)
+ {
+ return (String[]) getObject(key);
+ }
+
+ /**
+ * Get an object from this resource bundle. This will call
+ * <code>handleGetObject</code> for this resource and all of its parents,
+ * until it finds a non-null resource.
+ *
+ * @param key the name of the resource
+ * @throws MissingResourceException if the resource can't be found
+ * @throws NullPointerException if key is null
+ */
+ public final Object getObject(String key)
+ {
+ for (ResourceBundle bundle = this; bundle != null; bundle = bundle.parent)
+ {
+ Object o = bundle.handleGetObject(key);
+ if (o != null)
+ return o;
+ }
+
+ String className = getClass().getName();
+ throw new MissingResourceException("Key '" + key
+ + "'not found in Bundle: "
+ + className, className, key);
+ }
+
+ /**
+ * Return the actual locale of this bundle. You can use it after calling
+ * getBundle, to know if the bundle for the desired locale was loaded or
+ * if the fall back was used.
+ *
+ * @return the bundle's locale
+ */
+ public Locale getLocale()
+ {
+ return locale;
+ }
+
+ /**
+ * Set the parent of this bundle. The parent is consulted when you call
+ * getObject and there is no such resource in the current bundle.
+ *
+ * @param parent the parent of this bundle
+ */
+ protected void setParent(ResourceBundle parent)
+ {
+ this.parent = parent;
+ }
+
+ /**
+ * Get the appropriate ResourceBundle for the default locale. This is like
+ * calling <code>getBundle(baseName, Locale.getDefault(),
+ * getClass().getClassLoader()</code>, except that any security check of
+ * getClassLoader won't fail.
+ *
+ * @param baseName the name of the ResourceBundle
+ * @return the desired resource bundle
+ * @throws MissingResourceException if the resource bundle can't be found
+ * @throws NullPointerException if baseName is null
+ */
+ public static ResourceBundle getBundle(String baseName)
+ {
+ ClassLoader cl = getCallingClassLoader();
+ if (cl == null)
+ cl = ClassLoader.getSystemClassLoader();
+ return getBundle(baseName, Locale.getDefault(), cl);
+ }
+
+ /**
+ * Get the appropriate ResourceBundle for the given locale. This is like
+ * calling <code>getBundle(baseName, locale,
+ * getClass().getClassLoader()</code>, except that any security check of
+ * getClassLoader won't fail.
+ *
+ * @param baseName the name of the ResourceBundle
+ * @param locale A locale
+ * @return the desired resource bundle
+ * @throws MissingResourceException if the resource bundle can't be found
+ * @throws NullPointerException if baseName or locale is null
+ */
+ public static ResourceBundle getBundle(String baseName, Locale locale)
+ {
+ ClassLoader cl = getCallingClassLoader();
+ if (cl == null)
+ cl = ClassLoader.getSystemClassLoader();
+ return getBundle(baseName, locale, cl);
+ }
+
+ /** Cache key for the ResourceBundle cache. Resource bundles are keyed
+ by the combination of bundle name, locale, and class loader. */
+ private static class BundleKey
+ {
+ String baseName;
+ Locale locale;
+ ClassLoader classLoader;
+ int hashcode;
+
+ BundleKey() {}
+
+ BundleKey(String s, Locale l, ClassLoader cl)
+ {
+ set(s, l, cl);
+ }
+
+ void set(String s, Locale l, ClassLoader cl)
+ {
+ baseName = s;
+ locale = l;
+ classLoader = cl;
+ hashcode = baseName.hashCode() ^ locale.hashCode() ^
+ classLoader.hashCode();
+ }
+
+ public int hashCode()
+ {
+ return hashcode;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (! (o instanceof BundleKey))
+ return false;
+ BundleKey key = (BundleKey) o;
+ return hashcode == key.hashcode &&
+ baseName.equals(key.baseName) &&
+ locale.equals(key.locale) &&
+ classLoader.equals(key.classLoader);
+ }
+ }
+
+ /** A cache lookup key. This avoids having to a new one for every
+ * getBundle() call. */
+ private static BundleKey lookupKey = new BundleKey();
+
+ /** Singleton cache entry to represent previous failed lookups. */
+ private static Object nullEntry = new Object();
+
+ /**
+ * Get the appropriate ResourceBundle for the given locale. The following
+ * strategy is used:
+ *
+ * <p>A sequence of candidate bundle names are generated, and tested in
+ * this order, where the suffix 1 means the string from the specified
+ * locale, and the suffix 2 means the string from the default locale:</p>
+ *
+ * <ul>
+ * <li>baseName + "_" + language1 + "_" + country1 + "_" + variant1</li>
+ * <li>baseName + "_" + language1 + "_" + country1</li>
+ * <li>baseName + "_" + language1</li>
+ * <li>baseName + "_" + language2 + "_" + country2 + "_" + variant2</li>
+ * <li>baseName + "_" + language2 + "_" + country2</li>
+ * <li>baseName + "_" + language2</li>
+ * <li>baseName</li>
+ * </ul>
+ *
+ * <p>In the sequence, entries with an empty string are ignored. Next,
+ * <code>getBundle</code> tries to instantiate the resource bundle:</p>
+ *
+ * <ul>
+ * <li>First, an attempt is made to load a class in the specified classloader
+ * which is a subclass of ResourceBundle, and which has a public constructor
+ * with no arguments, via reflection.</li>
+ * <li>Next, a search is made for a property resource file, by replacing
+ * '.' with '/' and appending ".properties", and using
+ * ClassLoader.getResource(). If a file is found, then a
+ * PropertyResourceBundle is created from the file's contents.</li>
+ * </ul>
+ * If no resource bundle was found, a MissingResourceException is thrown.
+ *
+ * <p>Next, the parent chain is implemented. The remaining candidate names
+ * in the above sequence are tested in a similar manner, and if any results
+ * in a resource bundle, it is assigned as the parent of the first bundle
+ * using the <code>setParent</code> method (unless the first bundle already
+ * has a parent).</p>
+ *
+ * <p>For example, suppose the following class and property files are
+ * provided: MyResources.class, MyResources_fr_CH.properties,
+ * MyResources_fr_CH.class, MyResources_fr.properties,
+ * MyResources_en.properties, and MyResources_es_ES.class. The contents of
+ * all files are valid (that is, public non-abstract subclasses of
+ * ResourceBundle with public nullary constructors for the ".class" files,
+ * syntactically correct ".properties" files). The default locale is
+ * Locale("en", "UK").</p>
+ *
+ * <p>Calling getBundle with the shown locale argument values instantiates
+ * resource bundles from the following sources:</p>
+ *
+ * <ul>
+ * <li>Locale("fr", "CH"): result MyResources_fr_CH.class, parent
+ * MyResources_fr.properties, parent MyResources.class</li>
+ * <li>Locale("fr", "FR"): result MyResources_fr.properties, parent
+ * MyResources.class</li>
+ * <li>Locale("de", "DE"): result MyResources_en.properties, parent
+ * MyResources.class</li>
+ * <li>Locale("en", "US"): result MyResources_en.properties, parent
+ * MyResources.class</li>
+ * <li>Locale("es", "ES"): result MyResources_es_ES.class, parent
+ * MyResources.class</li>
+ * </ul>
+ *
+ * <p>The file MyResources_fr_CH.properties is never used because it is hidden
+ * by MyResources_fr_CH.class.</p>
+ *
+ * @param baseName the name of the ResourceBundle
+ * @param locale A locale
+ * @param classLoader a ClassLoader
+ * @return the desired resource bundle
+ * @throws MissingResourceException if the resource bundle can't be found
+ * @throws NullPointerException if any argument is null
+ * @since 1.2
+ */
+ // This method is synchronized so that the cache is properly
+ // handled.
+ public static synchronized ResourceBundle getBundle
+ (String baseName, Locale locale, ClassLoader classLoader)
+ {
+ // If the default locale changed since the last time we were called,
+ // all cache entries are invalidated.
+ Locale defaultLocale = Locale.getDefault();
+ if (defaultLocale != lastDefaultLocale)
+ {
+ bundleCache = new HashMap();
+ lastDefaultLocale = defaultLocale;
+ }
+
+ // This will throw NullPointerException if any arguments are null.
+ lookupKey.set(baseName, locale, classLoader);
+
+ Object obj = bundleCache.get(lookupKey);
+ ResourceBundle rb = null;
+
+ if (obj instanceof ResourceBundle)
+ {
+ return (ResourceBundle) obj;
+ }
+ else if (obj == nullEntry)
+ {
+ // Lookup has failed previously. Fall through.
+ }
+ else
+ {
+ // First, look for a bundle for the specified locale. We don't want
+ // the base bundle this time.
+ boolean wantBase = locale.equals(defaultLocale);
+ ResourceBundle bundle = tryBundle(baseName, locale, classLoader,
+ wantBase);
+
+ // Try the default locale if neccessary.
+ if (bundle == null && !locale.equals(defaultLocale))
+ bundle = tryBundle(baseName, defaultLocale, classLoader, true);
+
+ BundleKey key = new BundleKey(baseName, locale, classLoader);
+ if (bundle == null)
+ {
+ // Cache the fact that this lookup has previously failed.
+ bundleCache.put(key, nullEntry);
+ }
+ else
+ {
+ // Cache the result and return it.
+ bundleCache.put(key, bundle);
+ return bundle;
+ }
+ }
+
+ throw new MissingResourceException("Bundle " + baseName + " not found",
+ baseName, "");
+ }
+
+ /**
+ * Override this method to provide the resource for a keys. This gets
+ * called by <code>getObject</code>. If you don't have a resource
+ * for the given key, you should return null instead throwing a
+ * MissingResourceException. You don't have to ask the parent, getObject()
+ * already does this; nor should you throw a MissingResourceException.
+ *
+ * @param key the key of the resource
+ * @return the resource for the key, or null if not in bundle
+ * @throws NullPointerException if key is null
+ */
+ protected abstract Object handleGetObject(String key);
+
+ /**
+ * This method should return all keys for which a resource exists; you
+ * should include the enumeration of any parent's keys, after filtering out
+ * duplicates.
+ *
+ * @return an enumeration of the keys
+ */
+ public abstract Enumeration getKeys();
+
+ /**
+ * Tries to load a class or a property file with the specified name.
+ *
+ * @param localizedName the name
+ * @param classloader the classloader
+ * @return the resource bundle if it was loaded, otherwise the backup
+ */
+ private static ResourceBundle tryBundle(String localizedName,
+ ClassLoader classloader)
+ {
+ ResourceBundle bundle = null;
+ try
+ {
+ Class rbClass;
+ if (classloader == null)
+ rbClass = Class.forName(localizedName);
+ else
+ rbClass = classloader.loadClass(localizedName);
+ // Note that we do the check up front instead of catching
+ // ClassCastException. The reason for this is that some crazy
+ // programs (Eclipse) have classes that do not extend
+ // ResourceBundle but that have the same name as a property
+ // bundle; in fact Eclipse relies on ResourceBundle not
+ // instantiating these classes.
+ if (ResourceBundle.class.isAssignableFrom(rbClass))
+ bundle = (ResourceBundle) rbClass.newInstance();
+ }
+ catch (IllegalAccessException ex) {}
+ catch (InstantiationException ex) {}
+ catch (ClassNotFoundException ex) {}
+
+ if (bundle == null)
+ {
+ try
+ {
+ InputStream is;
+ String resourceName
+ = localizedName.replace('.', '/') + ".properties";
+ if (classloader == null)
+ is = ClassLoader.getSystemResourceAsStream(resourceName);
+ else
+ is = classloader.getResourceAsStream(resourceName);
+ if (is != null)
+ bundle = new PropertyResourceBundle(is);
+ }
+ catch (IOException ex)
+ {
+ MissingResourceException mre = new MissingResourceException
+ ("Failed to load bundle: " + localizedName, localizedName, "");
+ mre.initCause(ex);
+ throw mre;
+ }
+ }
+
+ return bundle;
+ }
+
+ /**
+ * Tries to load a the bundle for a given locale, also loads the backup
+ * locales with the same language.
+ *
+ * @param baseName the raw bundle name, without locale qualifiers
+ * @param locale the locale
+ * @param classloader the classloader
+ * @param bundle the backup (parent) bundle
+ * @param wantBase whether a resource bundle made only from the base name
+ * (with no locale information attached) should be returned.
+ * @return the resource bundle if it was loaded, otherwise the backup
+ */
+ private static ResourceBundle tryBundle(String baseName, Locale locale,
+ ClassLoader classLoader,
+ boolean wantBase)
+ {
+ String language = locale.getLanguage();
+ String country = locale.getCountry();
+ String variant = locale.getVariant();
+
+ int baseLen = baseName.length();
+
+ // Build up a StringBuffer containing the complete bundle name, fully
+ // qualified by locale.
+ StringBuffer sb = new StringBuffer(baseLen + variant.length() + 7);
+
+ sb.append(baseName);
+
+ if (language.length() > 0)
+ {
+ sb.append('_');
+ sb.append(language);
+
+ if (country.length() > 0)
+ {
+ sb.append('_');
+ sb.append(country);
+
+ if (variant.length() > 0)
+ {
+ sb.append('_');
+ sb.append(variant);
+ }
+ }
+ }
+
+ // Now try to load bundles, starting with the most specialized name.
+ // Build up the parent chain as we go.
+ String bundleName = sb.toString();
+ ResourceBundle first = null; // The most specialized bundle.
+ ResourceBundle last = null; // The least specialized bundle.
+
+ while (true)
+ {
+ ResourceBundle foundBundle = tryBundle(bundleName, classLoader);
+ if (foundBundle != null)
+ {
+ if (first == null)
+ first = foundBundle;
+ if (last != null)
+ last.parent = foundBundle;
+ foundBundle.locale = locale;
+ last = foundBundle;
+ }
+ int idx = bundleName.lastIndexOf('_');
+ // Try the non-localized base name only if we already have a
+ // localized child bundle, or wantBase is true.
+ if (idx > baseLen || (idx == baseLen && (first != null || wantBase)))
+ bundleName = bundleName.substring(0, idx);
+ else
+ break;
+ }
+
+ return first;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/util/VMTimeZone.java b/gcc-4.2.1/libjava/java/util/VMTimeZone.java
new file mode 100644
index 000000000..86b625843
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/VMTimeZone.java
@@ -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();
+}
diff --git a/gcc-4.2.1/libjava/java/util/logging/LogManager.java b/gcc-4.2.1/libjava/java/util/logging/LogManager.java
new file mode 100644
index 000000000..b8b31c43c
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/logging/LogManager.java
@@ -0,0 +1,981 @@
+/* LogManager.java -- a class for maintaining Loggers and managing
+ configuration properties
+ Copyright (C) 2002, 2005, 2006 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.logging;
+
+import gnu.classpath.SystemProperties;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+/**
+ * The <code>LogManager</code> maintains a hierarchical namespace
+ * of Logger objects and manages properties for configuring the logging
+ * framework. There exists only one single <code>LogManager</code>
+ * per virtual machine. This instance can be retrieved using the
+ * static method {@link #getLogManager()}.
+ *
+ * <p><strong>Configuration Process:</strong> The global LogManager
+ * object is created and configured when the class
+ * <code>java.util.logging.LogManager</code> is initialized.
+ * The configuration process includes the subsequent steps:
+ *
+ * <ul>
+ * <li>If the system property <code>java.util.logging.manager</code>
+ * is set to the name of a subclass of
+ * <code>java.util.logging.LogManager</code>, an instance of
+ * that subclass is created and becomes the global LogManager.
+ * Otherwise, a new instance of LogManager is created.</li>
+ * <li>The <code>LogManager</code> constructor tries to create
+ * a new instance of the class specified by the system
+ * property <code>java.util.logging.config.class</code>.
+ * Typically, the constructor of this class will call
+ * <code>LogManager.getLogManager().readConfiguration(java.io.InputStream)</code>
+ * for configuring the logging framework.
+ * The configuration process stops at this point if
+ * the system property <code>java.util.logging.config.class</code>
+ * is set (irrespective of whether the class constructor
+ * could be called or an exception was thrown).</li>
+ *
+ * <li>If the system property <code>java.util.logging.config.class</code>
+ * is <em>not</em> set, the configuration parameters are read in from
+ * a file and passed to
+ * {@link #readConfiguration(java.io.InputStream)}.
+ * The name and location of this file are specified by the system
+ * property <code>java.util.logging.config.file</code>.</li>
+ * <li>If the system property <code>java.util.logging.config.file</code>
+ * is not set, however, the contents of the URL
+ * "{gnu.classpath.home.url}/logging.properties" are passed to
+ * {@link #readConfiguration(java.io.InputStream)}.
+ * Here, "{gnu.classpath.home.url}" stands for the value of
+ * the system property <code>gnu.classpath.home.url</code>.</li>
+ * </ul>
+ *
+ * <p>The <code>LogManager</code> has a level of <code>INFO</code> by
+ * default, and this will be inherited by <code>Logger</code>s unless they
+ * override it either by properties or programmatically.
+ *
+ * @author Sascha Brawer (brawer@acm.org)
+ */
+public class LogManager
+{
+ /**
+ * The object name for the logging management bean.
+ * @since 1.5
+ */
+ public static final String LOGGING_MXBEAN_NAME
+ = "java.util.logging:type=Logging";
+
+ /**
+ * The singleton LogManager instance.
+ */
+ private static LogManager logManager;
+
+ /**
+ * The singleton logging bean.
+ */
+ private static LoggingMXBean loggingBean;
+
+ /**
+ * The registered named loggers; maps the name of a Logger to
+ * a WeakReference to it.
+ */
+ private Map loggers;
+
+ /**
+ * The properties for the logging framework which have been
+ * read in last.
+ */
+ private Properties properties;
+
+ /**
+ * A delegate object that provides support for handling
+ * PropertyChangeEvents. The API specification does not
+ * mention which bean should be the source in the distributed
+ * PropertyChangeEvents, but Mauve test code has determined that
+ * the Sun J2SE 1.4 reference implementation uses the LogManager
+ * class object. This is somewhat strange, as the class object
+ * is not the bean with which listeners have to register, but
+ * there is no reason for the GNU Classpath implementation to
+ * behave differently from the reference implementation in
+ * this case.
+ */
+ private final PropertyChangeSupport pcs = new PropertyChangeSupport( /* source bean */
+ LogManager.class);
+
+ protected LogManager()
+ {
+ loggers = new HashMap();
+ }
+
+ /**
+ * Returns the globally shared LogManager instance.
+ */
+ public static synchronized LogManager getLogManager()
+ {
+ if (logManager == null)
+ {
+ logManager = makeLogManager();
+ initLogManager();
+ }
+ return logManager;
+ }
+
+ private static final String MANAGER_PROPERTY = "java.util.logging.manager";
+
+ private static LogManager makeLogManager()
+ {
+ String managerClassName = SystemProperties.getProperty(MANAGER_PROPERTY);
+ LogManager manager = (LogManager) createInstance
+ (managerClassName, LogManager.class, MANAGER_PROPERTY);
+ if (manager == null)
+ manager = new LogManager();
+ return manager;
+ }
+
+ private static final String CONFIG_PROPERTY = "java.util.logging.config.class";
+
+ private static void initLogManager()
+ {
+ LogManager manager = getLogManager();
+ Logger.root.setLevel(Level.INFO);
+ manager.addLogger(Logger.root);
+
+ /* The Javadoc description of the class explains
+ * what is going on here.
+ */
+ Object configurator = createInstance(System.getProperty(CONFIG_PROPERTY),
+ /* must be instance of */ Object.class,
+ CONFIG_PROPERTY);
+
+ try
+ {
+ if (configurator == null)
+ manager.readConfiguration();
+ }
+ catch (IOException ex)
+ {
+ /* FIXME: Is it ok to ignore exceptions here? */
+ }
+ }
+
+ /**
+ * Registers a listener which will be notified when the
+ * logging properties are re-read.
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
+ {
+ /* do not register null. */
+ listener.getClass();
+
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Unregisters a listener.
+ *
+ * If <code>listener</code> has not been registered previously,
+ * nothing happens. Also, no exception is thrown if
+ * <code>listener</code> is <code>null</code>.
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
+ {
+ if (listener != null)
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Adds a named logger. If a logger with the same name has
+ * already been registered, the method returns <code>false</code>
+ * without adding the logger.
+ *
+ * <p>The <code>LogManager</code> only keeps weak references
+ * to registered loggers. Therefore, names can become available
+ * after automatic garbage collection.
+ *
+ * @param logger the logger to be added.
+ *
+ * @return <code>true</code>if <code>logger</code> was added,
+ * <code>false</code> otherwise.
+ *
+ * @throws NullPointerException if <code>name</code> is
+ * <code>null</code>.
+ */
+ public synchronized boolean addLogger(Logger logger)
+ {
+ /* To developers thinking about to remove the 'synchronized'
+ * declaration from this method: Please read the comment
+ * in java.util.logging.Logger.getLogger(String, String)
+ * and make sure that whatever you change wrt. synchronization
+ * does not endanger thread-safety of Logger.getLogger.
+ * The current implementation of Logger.getLogger assumes
+ * that LogManager does its synchronization on the globally
+ * shared instance of LogManager.
+ */
+ String name;
+ WeakReference ref;
+
+ /* This will throw a NullPointerException if logger is null,
+ * as required by the API specification.
+ */
+ name = logger.getName();
+
+ ref = (WeakReference) loggers.get(name);
+ if (ref != null)
+ {
+ if (ref.get() != null)
+ return false;
+
+ /* There has been a logger under this name in the past,
+ * but it has been garbage collected.
+ */
+ loggers.remove(ref);
+ }
+
+ /* Adding a named logger requires a security permission. */
+ if ((name != null) && ! name.equals(""))
+ checkAccess();
+
+ Logger parent = findAncestor(logger);
+ loggers.put(name, new WeakReference(logger));
+ if (parent != logger.getParent())
+ logger.setParent(parent);
+
+ // The level of the newly added logger must be specified.
+ // The easiest case is if there is a level for exactly this logger
+ // in the properties. If no such level exists the level needs to be
+ // searched along the hirachy. So if there is a new logger 'foo.blah.blub'
+ // and an existing parent logger 'foo' the properties 'foo.blah.blub.level'
+ // and 'foo.blah.level' need to be checked. If both do not exist in the
+ // properties the level of the new logger is set to 'null' (i.e. it uses the
+ // level of its parent 'foo').
+ Level logLevel = logger.getLevel();
+ String searchName = name;
+ String parentName = parent != null ? parent.getName() : "";
+ while (logLevel == null && ! searchName.equals(parentName))
+ {
+ logLevel = getLevelProperty(searchName + ".level", logLevel);
+ int index = searchName.lastIndexOf('.');
+ if(index > -1)
+ searchName = searchName.substring(0,index);
+ else
+ searchName = "";
+ }
+ logger.setLevel(logLevel);
+
+ /* It can happen that existing loggers should be children of
+ * the newly added logger. For example, assume that there
+ * already exist loggers under the names "", "foo", and "foo.bar.baz".
+ * When adding "foo.bar", the logger "foo.bar.baz" should change
+ * its parent to "foo.bar".
+ */
+ for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
+ {
+ Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next()))
+ .get();
+ if ((possChild == null) || (possChild == logger)
+ || (possChild.getParent() != parent))
+ continue;
+
+ if (! possChild.getName().startsWith(name))
+ continue;
+
+ if (possChild.getName().charAt(name.length()) != '.')
+ continue;
+
+ possChild.setParent(logger);
+ }
+
+ return true;
+ }
+
+ /**
+ * Finds the closest ancestor for a logger among the currently
+ * registered ones. For example, if the currently registered
+ * loggers have the names "", "foo", and "foo.bar", the result for
+ * "foo.bar.baz" will be the logger whose name is "foo.bar".
+ *
+ * @param child a logger for whose name no logger has been
+ * registered.
+ *
+ * @return the closest ancestor for <code>child</code>,
+ * or <code>null</code> if <code>child</code>
+ * is the root logger.
+ *
+ * @throws NullPointerException if <code>child</code>
+ * is <code>null</code>.
+ */
+ private synchronized Logger findAncestor(Logger child)
+ {
+ String childName = child.getName();
+ int childNameLength = childName.length();
+ Logger best = Logger.root;
+ int bestNameLength = 0;
+
+ Logger cand;
+ String candName;
+ int candNameLength;
+
+ if (child == Logger.root)
+ return null;
+
+ for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();)
+ {
+ candName = (String) iter.next();
+ candNameLength = candName.length();
+
+ if (candNameLength > bestNameLength
+ && childNameLength > candNameLength
+ && childName.startsWith(candName)
+ && childName.charAt(candNameLength) == '.')
+ {
+ cand = (Logger) ((WeakReference) loggers.get(candName)).get();
+ if ((cand == null) || (cand == child))
+ continue;
+
+ bestNameLength = candName.length();
+ best = cand;
+ }
+ }
+
+ return best;
+ }
+
+ /**
+ * Returns a Logger given its name.
+ *
+ * @param name the name of the logger.
+ *
+ * @return a named Logger, or <code>null</code> if there is no
+ * logger with that name.
+ *
+ * @throw java.lang.NullPointerException if <code>name</code>
+ * is <code>null</code>.
+ */
+ public synchronized Logger getLogger(String name)
+ {
+ WeakReference ref;
+
+ /* Throw a NullPointerException if name is null. */
+ name.getClass();
+
+ ref = (WeakReference) loggers.get(name);
+ if (ref != null)
+ return (Logger) ref.get();
+ else
+ return null;
+ }
+
+ /**
+ * Returns an Enumeration of currently registered Logger names.
+ * Since other threads can register loggers at any time, the
+ * result could be different any time this method is called.
+ *
+ * @return an Enumeration with the names of the currently
+ * registered Loggers.
+ */
+ public synchronized Enumeration getLoggerNames()
+ {
+ return Collections.enumeration(loggers.keySet());
+ }
+
+ /**
+ * Resets the logging configuration by removing all handlers for
+ * registered named loggers and setting their level to <code>null</code>.
+ * The level of the root logger will be set to <code>Level.INFO</code>.
+ *
+ * @throws SecurityException if a security manager exists and
+ * the caller is not granted the permission to control
+ * the logging infrastructure.
+ */
+ public synchronized void reset() throws SecurityException
+ {
+ /* Throw a SecurityException if the caller does not have the
+ * permission to control the logging infrastructure.
+ */
+ checkAccess();
+
+ properties = new Properties();
+
+ Iterator iter = loggers.values().iterator();
+ while (iter.hasNext())
+ {
+ WeakReference ref;
+ Logger logger;
+
+ ref = (WeakReference) iter.next();
+ if (ref != null)
+ {
+ logger = (Logger) ref.get();
+
+ if (logger == null)
+ iter.remove();
+ else if (logger != Logger.root)
+ {
+ logger.resetLogger();
+ logger.setLevel(null);
+ }
+ }
+ }
+
+ Logger.root.setLevel(Level.INFO);
+ Logger.root.resetLogger();
+ }
+
+ /**
+ * Configures the logging framework by reading a configuration file.
+ * The name and location of this file are specified by the system
+ * property <code>java.util.logging.config.file</code>. If this
+ * property is not set, the URL
+ * "{gnu.classpath.home.url}/logging.properties" is taken, where
+ * "{gnu.classpath.home.url}" stands for the value of the system
+ * property <code>gnu.classpath.home.url</code>.
+ *
+ * <p>The task of configuring the framework is then delegated to
+ * {@link #readConfiguration(java.io.InputStream)}, which will
+ * notify registered listeners after having read the properties.
+ *
+ * @throws SecurityException if a security manager exists and
+ * the caller is not granted the permission to control
+ * the logging infrastructure, or if the caller is
+ * not granted the permission to read the configuration
+ * file.
+ *
+ * @throws IOException if there is a problem reading in the
+ * configuration file.
+ */
+ public synchronized void readConfiguration()
+ throws IOException, SecurityException
+ {
+ String path;
+ InputStream inputStream;
+
+ path = System.getProperty("java.util.logging.config.file");
+ if ((path == null) || (path.length() == 0))
+ {
+ String url = (System.getProperty("gnu.classpath.home.url")
+ + "/logging.properties");
+ try
+ {
+ inputStream = new URL(url).openStream();
+ }
+ catch (Exception e)
+ {
+ inputStream=null;
+ }
+
+ // If no config file could be found use a default configuration.
+ if(inputStream == null)
+ {
+ String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n"
+ + ".level=INFO \n";
+ inputStream = new ByteArrayInputStream(defaultConfig.getBytes());
+ }
+ }
+ else
+ inputStream = new java.io.FileInputStream(path);
+
+ try
+ {
+ readConfiguration(inputStream);
+ }
+ finally
+ {
+ // Close the stream in order to save
+ // resources such as file descriptors.
+ inputStream.close();
+ }
+ }
+
+ public synchronized void readConfiguration(InputStream inputStream)
+ throws IOException, SecurityException
+ {
+ Properties newProperties;
+ Enumeration keys;
+
+ checkAccess();
+ newProperties = new Properties();
+ newProperties.load(inputStream);
+ reset();
+ this.properties = newProperties;
+ keys = newProperties.propertyNames();
+
+ while (keys.hasMoreElements())
+ {
+ String key = ((String) keys.nextElement()).trim();
+ String value = newProperties.getProperty(key);
+
+ if (value == null)
+ continue;
+
+ value = value.trim();
+
+ if ("handlers".equals(key))
+ {
+ StringTokenizer tokenizer = new StringTokenizer(value);
+ while (tokenizer.hasMoreTokens())
+ {
+ String handlerName = tokenizer.nextToken();
+ Handler handler = (Handler)
+ createInstance(handlerName, Handler.class, key);
+ Logger.root.addHandler(handler);
+ }
+ }
+
+ if (key.endsWith(".level"))
+ {
+ String loggerName = key.substring(0, key.length() - 6);
+ Logger logger = getLogger(loggerName);
+
+ if (logger == null)
+ {
+ logger = Logger.getLogger(loggerName);
+ addLogger(logger);
+ }
+ Level level = null;
+ try
+ {
+ level = Level.parse(value);
+ }
+ catch (IllegalArgumentException e)
+ {
+ warn("bad level \'" + value + "\'", e);
+ }
+ if (level != null)
+ {
+ logger.setLevel(level);
+ }
+ continue;
+ }
+ }
+
+ /* The API specification does not talk about the
+ * property name that is distributed with the
+ * PropertyChangeEvent. With test code, it could
+ * be determined that the Sun J2SE 1.4 reference
+ * implementation uses null for the property name.
+ */
+ pcs.firePropertyChange(null, null, null);
+ }
+
+ /**
+ * Returns the value of a configuration property as a String.
+ */
+ public synchronized String getProperty(String name)
+ {
+ if (properties != null)
+ return properties.getProperty(name);
+ else
+ return null;
+ }
+
+ /**
+ * Returns the value of a configuration property as an integer.
+ * This function is a helper used by the Classpath implementation
+ * of java.util.logging, it is <em>not</em> specified in the
+ * logging API.
+ *
+ * @param name the name of the configuration property.
+ *
+ * @param defaultValue the value that will be returned if the
+ * property is not defined, or if its value is not an integer
+ * number.
+ */
+ static int getIntProperty(String name, int defaultValue)
+ {
+ try
+ {
+ return Integer.parseInt(getLogManager().getProperty(name));
+ }
+ catch (Exception ex)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value of a configuration property as an integer,
+ * provided it is inside the acceptable range.
+ * This function is a helper used by the Classpath implementation
+ * of java.util.logging, it is <em>not</em> specified in the
+ * logging API.
+ *
+ * @param name the name of the configuration property.
+ *
+ * @param minValue the lowest acceptable value.
+ *
+ * @param maxValue the highest acceptable value.
+ *
+ * @param defaultValue the value that will be returned if the
+ * property is not defined, or if its value is not an integer
+ * number, or if it is less than the minimum value,
+ * or if it is greater than the maximum value.
+ */
+ static int getIntPropertyClamped(String name, int defaultValue,
+ int minValue, int maxValue)
+ {
+ int val = getIntProperty(name, defaultValue);
+ if ((val < minValue) || (val > maxValue))
+ val = defaultValue;
+ return val;
+ }
+
+ /**
+ * Returns the value of a configuration property as a boolean.
+ * This function is a helper used by the Classpath implementation
+ * of java.util.logging, it is <em>not</em> specified in the
+ * logging API.
+ *
+ * @param name the name of the configuration property.
+ *
+ * @param defaultValue the value that will be returned if the
+ * property is not defined, or if its value is neither
+ * <code>"true"</code> nor <code>"false"</code>.
+ */
+ static boolean getBooleanProperty(String name, boolean defaultValue)
+ {
+ try
+ {
+ return (Boolean.valueOf(getLogManager().getProperty(name))).booleanValue();
+ }
+ catch (Exception ex)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value of a configuration property as a Level.
+ * This function is a helper used by the Classpath implementation
+ * of java.util.logging, it is <em>not</em> specified in the
+ * logging API.
+ *
+ * @param propertyName the name of the configuration property.
+ *
+ * @param defaultValue the value that will be returned if the
+ * property is not defined, or if
+ * {@link Level#parse(java.lang.String)} does not like
+ * the property value.
+ */
+ static Level getLevelProperty(String propertyName, Level defaultValue)
+ {
+ try
+ {
+ return Level.parse(getLogManager().getProperty(propertyName));
+ }
+ catch (Exception ex)
+ {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Returns the value of a configuration property as a Class.
+ * This function is a helper used by the Classpath implementation
+ * of java.util.logging, it is <em>not</em> specified in the
+ * logging API.
+ *
+ * @param propertyName the name of the configuration property.
+ *
+ * @param defaultValue the value that will be returned if the
+ * property is not defined, or if it does not specify
+ * the name of a loadable class.
+ */
+ static final Class getClassProperty(String propertyName, Class defaultValue)
+ {
+ String propertyValue = logManager.getProperty(propertyName);
+
+ if (propertyValue != null)
+ try
+ {
+ return locateClass(propertyValue);
+ }
+ catch (ClassNotFoundException e)
+ {
+ warn(propertyName + " = " + propertyValue, e);
+ }
+
+ return defaultValue;
+ }
+
+ static final Object getInstanceProperty(String propertyName, Class ofClass,
+ Class defaultClass)
+ {
+ Class klass = getClassProperty(propertyName, defaultClass);
+ if (klass == null)
+ return null;
+
+ try
+ {
+ Object obj = klass.newInstance();
+ if (ofClass.isInstance(obj))
+ return obj;
+ }
+ catch (InstantiationException e)
+ {
+ warn(propertyName + " = " + klass.getName(), e);
+ }
+ catch (IllegalAccessException e)
+ {
+ warn(propertyName + " = " + klass.getName(), e);
+ }
+
+ if (defaultClass == null)
+ return null;
+
+ try
+ {
+ return defaultClass.newInstance();
+ }
+ catch (java.lang.InstantiationException ex)
+ {
+ throw new RuntimeException(ex.getMessage());
+ }
+ catch (java.lang.IllegalAccessException ex)
+ {
+ throw new RuntimeException(ex.getMessage());
+ }
+ }
+
+ /**
+ * An instance of <code>LoggingPermission("control")</code>
+ * that is shared between calls to <code>checkAccess()</code>.
+ */
+ private static final LoggingPermission controlPermission = new LoggingPermission("control",
+ null);
+
+ /**
+ * Checks whether the current security context allows changing
+ * the configuration of the logging framework. For the security
+ * context to be trusted, it has to be granted
+ * a LoggingPermission("control").
+ *
+ * @throws SecurityException if a security manager exists and
+ * the caller is not granted the permission to control
+ * the logging infrastructure.
+ */
+ public void checkAccess() throws SecurityException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(controlPermission);
+ }
+
+ /**
+ * Creates a new instance of a class specified by name and verifies
+ * that it is an instance (or subclass of) a given type.
+ *
+ * @param className the name of the class of which a new instance
+ * should be created.
+ *
+ * @param type the object created must be an instance of
+ * <code>type</code> or any subclass of <code>type</code>
+ *
+ * @param property the system property to reference in error
+ * messages
+ *
+ * @return the new instance, or <code>null</code> if
+ * <code>className</code> is <code>null</code>, if no class
+ * with that name could be found, if there was an error
+ * loading that class, or if the constructor of the class
+ * has thrown an exception.
+ */
+ private static final Object createInstance(String className, Class type,
+ String property)
+ {
+ Class klass = null;
+
+ if ((className == null) || (className.length() == 0))
+ return null;
+
+ try
+ {
+ klass = locateClass(className);
+ if (type.isAssignableFrom(klass))
+ return klass.newInstance();
+ warn(property, className, "not an instance of " + type.getName());
+ }
+ catch (ClassNotFoundException e)
+ {
+ warn(property, className, "class not found", e);
+ }
+ catch (IllegalAccessException e)
+ {
+ warn(property, className, "illegal access", e);
+ }
+ catch (InstantiationException e)
+ {
+ warn(property, className, e);
+ }
+ catch (java.lang.LinkageError e)
+ {
+ warn(property, className, "linkage error", e);
+ }
+
+ return null;
+ }
+
+ private static final void warn(String property, String klass, Throwable t)
+ {
+ warn(property, klass, null, t);
+ }
+
+ private static final void warn(String property, String klass, String msg)
+ {
+ warn(property, klass, msg, null);
+ }
+
+ private static final void warn(String property, String klass, String msg,
+ Throwable t)
+ {
+ warn("error instantiating '" + klass + "' referenced by " + property +
+ (msg == null ? "" : ", " + msg), t);
+ }
+
+ /**
+ * All debug warnings go through this method.
+ */
+
+ private static final void warn(String msg, Throwable t)
+ {
+ System.err.println("WARNING: " + msg);
+ if (t != null)
+ t.printStackTrace(System.err);
+ }
+
+ /**
+ * Locates a class by first checking the system class loader and
+ * then checking the context class loader.
+ *
+ * @param name the fully qualified name of the Class to locate
+ * @return Class the located Class
+ */
+
+ private static Class locateClass(String name) throws ClassNotFoundException
+ {
+ // GCJ LOCAL
+ // Unfortunately this can be called during bootstrap when
+ // Thread.currentThread() will return null.
+ // See bug #27658
+ Thread t = Thread.currentThread();
+ ClassLoader loader = (t == null) ? null : t.getContextClassLoader();
+ try
+ {
+ return Class.forName(name, true, loader);
+ }
+ catch (ClassNotFoundException e)
+ {
+ loader = ClassLoader.getSystemClassLoader();
+ return Class.forName(name, true, loader);
+ }
+ }
+
+ /**
+ * Return the logging bean. There is a single logging bean per
+ * VM instance.
+ * @since 1.5
+ */
+ public static synchronized LoggingMXBean getLoggingMXBean()
+ {
+ if (loggingBean == null)
+ {
+ loggingBean = new LoggingMXBean()
+ {
+ public String getLoggerLevel(String logger)
+ {
+ LogManager mgr = getLogManager();
+ Logger l = mgr.getLogger(logger);
+ if (l == null)
+ return null;
+ Level lev = l.getLevel();
+ if (lev == null)
+ return "";
+ return lev.getName();
+ }
+
+ public List getLoggerNames()
+ {
+ LogManager mgr = getLogManager();
+ // This is inefficient, but perhaps better for maintenance.
+ return Collections.list(mgr.getLoggerNames());
+ }
+
+ public String getParentLoggerName(String logger)
+ {
+ LogManager mgr = getLogManager();
+ Logger l = mgr.getLogger(logger);
+ if (l == null)
+ return null;
+ l = l.getParent();
+ if (l == null)
+ return "";
+ return l.getName();
+ }
+
+ public void setLoggerLevel(String logger, String level)
+ {
+ LogManager mgr = getLogManager();
+ Logger l = mgr.getLogger(logger);
+ if (l == null)
+ throw new IllegalArgumentException("no logger named " + logger);
+ Level newLevel;
+ if (level == null)
+ newLevel = null;
+ else
+ newLevel = Level.parse(level);
+ l.setLevel(newLevel);
+ }
+ };
+ }
+ return loggingBean;
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/util/logging/Logger.java b/gcc-4.2.1/libjava/java/util/logging/Logger.java
new file mode 100644
index 000000000..adb07ecf6
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/logging/Logger.java
@@ -0,0 +1,1206 @@
+/* Logger.java -- a class for logging messages
+ Copyright (C) 2002, 2004, 2006 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.logging;
+
+import java.util.List;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * A Logger is used for logging information about events. Usually, there
+ * is a seprate logger for each subsystem or component, although there
+ * is a shared instance for components that make only occasional use of
+ * the logging framework.
+ *
+ * <p>It is common to name a logger after the name of a corresponding
+ * Java package. Loggers are organized into a hierarchical namespace;
+ * for example, the logger <code>"org.gnu.foo"</code> is the
+ * <em>parent</em> of logger <code>"org.gnu.foo.bar"</code>.
+ *
+ * <p>A logger for a named subsystem can be obtained through {@link
+ * java.util.logging.Logger#getLogger(java.lang.String)}. However,
+ * only code which has been granted the permission to control the
+ * logging infrastructure will be allowed to customize that logger.
+ * Untrusted code can obtain a private, anonymous logger through
+ * {@link #getAnonymousLogger()} if it wants to perform any
+ * modifications to the logger.
+ *
+ * <p>FIXME: Write more documentation.
+ *
+ * @author Sascha Brawer (brawer@acm.org)
+ */
+public class Logger
+{
+
+ static final Logger root = new Logger("", null);
+
+ /**
+ * A logger provided to applications that make only occasional use
+ * of the logging framework, typically early prototypes. Serious
+ * products are supposed to create and use their own Loggers, so
+ * they can be controlled individually.
+ */
+ public static final Logger global;
+
+ static
+ {
+ // Our class might be initialized from an unprivileged context
+ global = (Logger) AccessController.doPrivileged
+ (new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return getLogger("global");
+ }
+ });
+ }
+
+
+ /**
+ * The name of the Logger, or <code>null</code> if the logger is
+ * anonymous.
+ *
+ * <p>A previous version of the GNU Classpath implementation granted
+ * untrusted code the permission to control any logger whose name
+ * was null. However, test code revealed that the Sun J2SE 1.4
+ * reference implementation enforces the security control for any
+ * logger that was not created through getAnonymousLogger, even if
+ * it has a null name. Therefore, a separate flag {@link
+ * Logger#anonymous} was introduced.
+ */
+ private final String name;
+
+
+ /**
+ * The name of the resource bundle used for localization.
+ *
+ * <p>This variable cannot be declared as <code>final</code>
+ * because its value can change as a result of calling
+ * getLogger(String,String).
+ */
+ private String resourceBundleName;
+
+
+ /**
+ * The resource bundle used for localization.
+ *
+ * <p>This variable cannot be declared as <code>final</code>
+ * because its value can change as a result of calling
+ * getLogger(String,String).
+ */
+ private ResourceBundle resourceBundle;
+
+ private Filter filter;
+
+ private final List handlerList = new java.util.ArrayList(4);
+ private Handler[] handlers = new Handler[0];
+
+ /**
+ * Indicates whether or not this logger is anonymous. While
+ * a LoggingPermission is required for any modifications to
+ * a normal logger, untrusted code can obtain an anonymous logger
+ * and modify it according to its needs.
+ *
+ * <p>A previous version of the GNU Classpath implementation
+ * granted access to every logger whose name was null.
+ * However, test code revealed that the Sun J2SE 1.4 reference
+ * implementation enforces the security control for any logger
+ * that was not created through getAnonymousLogger, even
+ * if it has a null name.
+ */
+ private boolean anonymous;
+
+
+ private boolean useParentHandlers;
+
+ private Level level;
+
+ private Logger parent;
+
+ /**
+ * Constructs a Logger for a subsystem. Most applications do not
+ * need to create new Loggers explicitly; instead, they should call
+ * the static factory methods
+ * {@link #getLogger(java.lang.String,java.lang.String) getLogger}
+ * (with ResourceBundle for localization) or
+ * {@link #getLogger(java.lang.String) getLogger} (without
+ * ResourceBundle), respectively.
+ *
+ * @param name the name for the logger, for example "java.awt"
+ * or "com.foo.bar". The name should be based on
+ * the name of the package issuing log records
+ * and consist of dot-separated Java identifiers.
+ *
+ * @param resourceBundleName the name of a resource bundle
+ * for localizing messages, or <code>null</code>
+ * to indicate that messages do not need to be localized.
+ *
+ * @throws java.util.MissingResourceException if
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
+ */
+ protected Logger(String name, String resourceBundleName)
+ throws MissingResourceException
+ {
+ this.name = name;
+ this.resourceBundleName = resourceBundleName;
+
+ if (resourceBundleName == null)
+ resourceBundle = null;
+ else
+ resourceBundle = ResourceBundle.getBundle(resourceBundleName);
+
+ level = null;
+
+ /* This is null when the root logger is being constructed,
+ * and the root logger afterwards.
+ */
+ parent = root;
+
+ useParentHandlers = (parent != null);
+ }
+
+
+
+ /**
+ * Finds a registered logger for a subsystem, or creates one in
+ * case no logger has been registered yet.
+ *
+ * @param name the name for the logger, for example "java.awt"
+ * or "com.foo.bar". The name should be based on
+ * the name of the package issuing log records
+ * and consist of dot-separated Java identifiers.
+ *
+ * @throws IllegalArgumentException if a logger for the subsystem
+ * identified by <code>name</code> has already been created,
+ * but uses a a resource bundle for localizing messages.
+ *
+ * @throws NullPointerException if <code>name</code> is
+ * <code>null</code>.
+ *
+ * @return a logger for the subsystem specified by <code>name</code>
+ * that does not localize messages.
+ */
+ public static Logger getLogger(String name)
+ {
+ return getLogger(name, null);
+ }
+
+
+ /**
+ * Finds a registered logger for a subsystem, or creates one in case
+ * no logger has been registered yet.
+ *
+ * <p>If a logger with the specified name has already been
+ * registered, the behavior depends on the resource bundle that is
+ * currently associated with the existing logger.
+ *
+ * <ul><li>If the existing logger uses the same resource bundle as
+ * specified by <code>resourceBundleName</code>, the existing logger
+ * is returned.</li>
+ *
+ * <li>If the existing logger currently does not localize messages,
+ * the existing logger is modified to use the bundle specified by
+ * <code>resourceBundleName</code>. The existing logger is then
+ * returned. Therefore, all subsystems currently using this logger
+ * will produce localized messages from now on.</li>
+ *
+ * <li>If the existing logger already has an associated resource
+ * bundle, but a different one than specified by
+ * <code>resourceBundleName</code>, an
+ * <code>IllegalArgumentException</code> is thrown.</li></ul>
+ *
+ * @param name the name for the logger, for example "java.awt"
+ * or "org.gnu.foo". The name should be based on
+ * the name of the package issuing log records
+ * and consist of dot-separated Java identifiers.
+ *
+ * @param resourceBundleName the name of a resource bundle
+ * for localizing messages, or <code>null</code>
+ * to indicate that messages do not need to be localized.
+ *
+ * @return a logger for the subsystem specified by <code>name</code>.
+ *
+ * @throws java.util.MissingResourceException if
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
+ *
+ * @throws IllegalArgumentException if a logger for the subsystem
+ * identified by <code>name</code> has already been created,
+ * but uses a different resource bundle for localizing
+ * messages.
+ *
+ * @throws NullPointerException if <code>name</code> is
+ * <code>null</code>.
+ */
+ public static Logger getLogger(String name, String resourceBundleName)
+ {
+ LogManager lm = LogManager.getLogManager();
+ Logger result;
+
+ /* Throw NullPointerException if name is null. */
+ name.getClass();
+
+ /* Without synchronized(lm), it could happen that another thread
+ * would create a logger between our calls to getLogger and
+ * addLogger. While addLogger would indicate this by returning
+ * false, we could not be sure that this other logger was still
+ * existing when we called getLogger a second time in order
+ * to retrieve it -- note that LogManager is only allowed to
+ * keep weak references to registered loggers, so Loggers
+ * can be garbage collected at any time in general, and between
+ * our call to addLogger and our second call go getLogger
+ * in particular.
+ *
+ * Of course, we assume here that LogManager.addLogger etc.
+ * are synchronizing on the global LogManager object. There
+ * is a comment in the implementation of LogManager.addLogger
+ * referring to this comment here, so that any change in
+ * the synchronization of LogManager will be reflected here.
+ */
+ synchronized (lm)
+ {
+ result = lm.getLogger(name);
+ if (result == null)
+ {
+ boolean couldBeAdded;
+
+ result = new Logger(name, resourceBundleName);
+ couldBeAdded = lm.addLogger(result);
+ if (!couldBeAdded)
+ throw new IllegalStateException("cannot register new logger");
+ }
+ else
+ {
+ /* The logger already exists. Make sure it uses
+ * the same resource bundle for localizing messages.
+ */
+ String existingBundleName = result.getResourceBundleName();
+
+ /* The Sun J2SE 1.4 reference implementation will return the
+ * registered logger object, even if it does not have a resource
+ * bundle associated with it. However, it seems to change the
+ * resourceBundle of the registered logger to the bundle
+ * whose name was passed to getLogger.
+ */
+ if ((existingBundleName == null) && (resourceBundleName != null))
+ {
+ /* If ResourceBundle.getBundle throws an exception, the
+ * existing logger will be unchanged. This would be
+ * different if the assignment to resourceBundleName
+ * came first.
+ */
+ result.resourceBundle = ResourceBundle.getBundle(resourceBundleName);
+ result.resourceBundleName = resourceBundleName;
+ return result;
+ }
+
+ if ((existingBundleName != resourceBundleName)
+ && ((existingBundleName == null)
+ || !existingBundleName.equals(resourceBundleName)))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ return result;
+ }
+
+
+ /**
+ * Creates a new, unnamed logger. Unnamed loggers are not
+ * registered in the namespace of the LogManager, and no special
+ * security permission is required for changing their state.
+ * Therefore, untrusted applets are able to modify their private
+ * logger instance obtained through this method.
+ *
+ * <p>The parent of the newly created logger will the the root
+ * logger, from which the level threshold and the handlers are
+ * inherited.
+ */
+ public static Logger getAnonymousLogger()
+ {
+ return getAnonymousLogger(null);
+ }
+
+
+ /**
+ * Creates a new, unnamed logger. Unnamed loggers are not
+ * registered in the namespace of the LogManager, and no special
+ * security permission is required for changing their state.
+ * Therefore, untrusted applets are able to modify their private
+ * logger instance obtained through this method.
+ *
+ * <p>The parent of the newly created logger will the the root
+ * logger, from which the level threshold and the handlers are
+ * inherited.
+ *
+ * @param resourceBundleName the name of a resource bundle
+ * for localizing messages, or <code>null</code>
+ * to indicate that messages do not need to be localized.
+ *
+ * @throws java.util.MissingResourceException if
+ * <code>resourceBundleName</code> is not <code>null</code>
+ * and no such bundle could be located.
+ */
+ public static Logger getAnonymousLogger(String resourceBundleName)
+ throws MissingResourceException
+ {
+ Logger result;
+
+ result = new Logger(null, resourceBundleName);
+ result.anonymous = true;
+ return result;
+ }
+
+
+ /**
+ * Returns the name of the resource bundle that is being used for
+ * localizing messages.
+ *
+ * @return the name of the resource bundle used for localizing messages,
+ * or <code>null</code> if the parent's resource bundle
+ * is used for this purpose.
+ */
+ public synchronized String getResourceBundleName()
+ {
+ return resourceBundleName;
+ }
+
+
+ /**
+ * Returns the resource bundle that is being used for localizing
+ * messages.
+ *
+ * @return the resource bundle used for localizing messages,
+ * or <code>null</code> if the parent's resource bundle
+ * is used for this purpose.
+ */
+ public synchronized ResourceBundle getResourceBundle()
+ {
+ return resourceBundle;
+ }
+
+
+ /**
+ * Returns the severity level threshold for this <code>Handler</code>.
+ * All log records with a lower severity level will be discarded;
+ * a log record of the same or a higher level will be published
+ * unless an installed <code>Filter</code> decides to discard it.
+ *
+ * @return the severity level below which all log messages will be
+ * discarded, or <code>null</code> if the logger inherits
+ * the threshold from its parent.
+ */
+ public synchronized Level getLevel()
+ {
+ return level;
+ }
+
+
+ /**
+ * Returns whether or not a message of the specified level
+ * would be logged by this logger.
+ *
+ * @throws NullPointerException if <code>level</code>
+ * is <code>null</code>.
+ */
+ public synchronized boolean isLoggable(Level level)
+ {
+ if (this.level != null)
+ return this.level.intValue() <= level.intValue();
+
+ if (parent != null)
+ return parent.isLoggable(level);
+ else
+ return false;
+ }
+
+
+ /**
+ * Sets the severity level threshold for this <code>Handler</code>.
+ * All log records with a lower severity level will be discarded
+ * immediately. A log record of the same or a higher level will be
+ * published unless an installed <code>Filter</code> decides to
+ * discard it.
+ *
+ * @param level the severity level below which all log messages
+ * will be discarded, or <code>null</code> to
+ * indicate that the logger should inherit the
+ * threshold from its parent.
+ *
+ * @throws SecurityException if this logger is not anonymous, a
+ * security manager exists, and the caller is not granted
+ * the permission to control the logging infrastructure by
+ * having LoggingPermission("control"). Untrusted code can
+ * obtain an anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ */
+ public synchronized void setLevel(Level level)
+ {
+ /* An application is allowed to control an anonymous logger
+ * without having the permission to control the logging
+ * infrastructure.
+ */
+ if (!anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.level = level;
+ }
+
+
+ public synchronized Filter getFilter()
+ {
+ return filter;
+ }
+
+
+ /**
+ * @throws SecurityException if this logger is not anonymous, a
+ * security manager exists, and the caller is not granted
+ * the permission to control the logging infrastructure by
+ * having LoggingPermission("control"). Untrusted code can
+ * obtain an anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ */
+ public synchronized void setFilter(Filter filter)
+ throws SecurityException
+ {
+ /* An application is allowed to control an anonymous logger
+ * without having the permission to control the logging
+ * infrastructure.
+ */
+ if (!anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.filter = filter;
+ }
+
+
+
+
+ /**
+ * Returns the name of this logger.
+ *
+ * @return the name of this logger, or <code>null</code> if
+ * the logger is anonymous.
+ */
+ public String getName()
+ {
+ /* Note that the name of a logger cannot be changed during
+ * its lifetime, so no synchronization is needed.
+ */
+ return name;
+ }
+
+
+ /**
+ * Passes a record to registered handlers, provided the record
+ * is considered as loggable both by {@link #isLoggable(Level)}
+ * and a possibly installed custom {@link #setFilter(Filter) filter}.
+ *
+ * <p>If the logger has been configured to use parent handlers,
+ * the record will be forwarded to the parent of this logger
+ * in addition to being processed by the handlers registered with
+ * this logger.
+ *
+ * <p>The other logging methods in this class are convenience methods
+ * that merely create a new LogRecord and pass it to this method.
+ * Therefore, subclasses usually just need to override this single
+ * method for customizing the logging behavior.
+ *
+ * @param record the log record to be inspected and possibly forwarded.
+ */
+ public synchronized void log(LogRecord record)
+ {
+ if (!isLoggable(record.getLevel()))
+ return;
+
+ if ((filter != null) && !filter.isLoggable(record))
+ return;
+
+ /* If no logger name has been set for the log record,
+ * use the name of this logger.
+ */
+ if (record.getLoggerName() == null)
+ record.setLoggerName(name);
+
+ /* Avoid that some other thread is changing the logger hierarchy
+ * while we are traversing it.
+ */
+ synchronized (LogManager.getLogManager())
+ {
+ Logger curLogger = this;
+
+ do
+ {
+ /* The Sun J2SE 1.4 reference implementation seems to call the
+ * filter only for the logger whose log method is called,
+ * never for any of its parents. Also, parent loggers publish
+ * log record whatever their level might be. This is pretty
+ * weird, but GNU Classpath tries to be as compatible as
+ * possible to the reference implementation.
+ */
+ for (int i = 0; i < curLogger.handlers.length; i++)
+ curLogger.handlers[i].publish(record);
+
+ if (curLogger.getUseParentHandlers() == false)
+ break;
+
+ curLogger = curLogger.getParent();
+ }
+ while (parent != null);
+ }
+ }
+
+
+ public void log(Level level, String message)
+ {
+ if (isLoggable(level))
+ log(level, message, (Object[]) null);
+ }
+
+
+ public synchronized void log(Level level,
+ String message,
+ Object param)
+ {
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level,
+ caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message,
+ param);
+ }
+ }
+
+
+ public synchronized void log(Level level,
+ String message,
+ Object[] params)
+ {
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level,
+ caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message,
+ params);
+ }
+ }
+
+
+ public synchronized void log(Level level,
+ String message,
+ Throwable thrown)
+ {
+ if (isLoggable(level))
+ {
+ StackTraceElement caller = getCallerStackFrame();
+ logp(level,
+ caller != null ? caller.getClassName() : "<unknown>",
+ caller != null ? caller.getMethodName() : "<unknown>",
+ message,
+ thrown);
+ }
+ }
+
+
+ public synchronized void logp(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String message)
+ {
+ logp(level, sourceClass, sourceMethod, message,
+ (Object[]) null);
+ }
+
+
+ public synchronized void logp(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String message,
+ Object param)
+ {
+ logp(level, sourceClass, sourceMethod, message,
+ new Object[] { param });
+ }
+
+
+ private synchronized ResourceBundle findResourceBundle()
+ {
+ if (resourceBundle != null)
+ return resourceBundle;
+
+ if (parent != null)
+ return parent.findResourceBundle();
+
+ return null;
+ }
+
+
+ private synchronized void logImpl(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String message,
+ Object[] params)
+ {
+ LogRecord rec = new LogRecord(level, message);
+
+ rec.setResourceBundle(findResourceBundle());
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setParameters(params);
+
+ log(rec);
+ }
+
+
+ public synchronized void logp(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String message,
+ Object[] params)
+ {
+ logImpl(level, sourceClass, sourceMethod, message, params);
+ }
+
+
+ public synchronized void logp(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String message,
+ Throwable thrown)
+ {
+ LogRecord rec = new LogRecord(level, message);
+
+ rec.setResourceBundle(resourceBundle);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setThrown(thrown);
+
+ log(rec);
+ }
+
+
+ public synchronized void logrb(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String bundleName,
+ String message)
+ {
+ logrb(level, sourceClass, sourceMethod, bundleName,
+ message, (Object[]) null);
+ }
+
+
+ public synchronized void logrb(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String bundleName,
+ String message,
+ Object param)
+ {
+ logrb(level, sourceClass, sourceMethod, bundleName,
+ message, new Object[] { param });
+ }
+
+
+ public synchronized void logrb(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String bundleName,
+ String message,
+ Object[] params)
+ {
+ LogRecord rec = new LogRecord(level, message);
+
+ rec.setResourceBundleName(bundleName);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setParameters(params);
+
+ log(rec);
+ }
+
+
+ public synchronized void logrb(Level level,
+ String sourceClass,
+ String sourceMethod,
+ String bundleName,
+ String message,
+ Throwable thrown)
+ {
+ LogRecord rec = new LogRecord(level, message);
+
+ rec.setResourceBundleName(bundleName);
+ rec.setSourceClassName(sourceClass);
+ rec.setSourceMethodName(sourceMethod);
+ rec.setThrown(thrown);
+
+ log(rec);
+ }
+
+
+ public synchronized void entering(String sourceClass,
+ String sourceMethod)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
+ }
+
+
+ public synchronized void entering(String sourceClass,
+ String sourceMethod,
+ Object param)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", param);
+ }
+
+
+ public synchronized void entering(String sourceClass,
+ String sourceMethod,
+ Object[] params)
+ {
+ if (isLoggable(Level.FINER))
+ {
+ StringBuffer buf = new StringBuffer(80);
+ buf.append("ENTRY");
+ for (int i = 0; i < params.length; i++)
+ {
+ buf.append(" {");
+ buf.append(i);
+ buf.append('}');
+ }
+
+ logp(Level.FINER, sourceClass, sourceMethod, buf.toString(), params);
+ }
+ }
+
+
+ public synchronized void exiting(String sourceClass,
+ String sourceMethod)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
+ }
+
+
+ public synchronized void exiting(String sourceClass,
+ String sourceMethod,
+ Object result)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
+ }
+
+
+ public synchronized void throwing(String sourceClass,
+ String sourceMethod,
+ Throwable thrown)
+ {
+ if (isLoggable(Level.FINER))
+ logp(Level.FINER, sourceClass, sourceMethod, "THROW", thrown);
+ }
+
+
+ /**
+ * Logs a message with severity level SEVERE, indicating a serious
+ * failure that prevents normal program execution. Messages at this
+ * level should be understandable to an inexperienced, non-technical
+ * end user. Ideally, they explain in simple words what actions the
+ * user can take in order to resolve the problem.
+ *
+ * @see Level#SEVERE
+ *
+ * @param message the message text, also used as look-up key if the
+ * logger is localizing messages with a resource
+ * bundle. While it is possible to pass
+ * <code>null</code>, this is not recommended, since
+ * a logging message without text is unlikely to be
+ * helpful.
+ */
+ public synchronized void severe(String message)
+ {
+ if (isLoggable(Level.SEVERE))
+ log(Level.SEVERE, message);
+ }
+
+
+ /**
+ * Logs a message with severity level WARNING, indicating a
+ * potential problem that does not prevent normal program execution.
+ * Messages at this level should be understandable to an
+ * inexperienced, non-technical end user. Ideally, they explain in
+ * simple words what actions the user can take in order to resolve
+ * the problem.
+ *
+ * @see Level#WARNING
+ *
+ * @param message the message text, also used as look-up key if the
+ * logger is localizing messages with a resource
+ * bundle. While it is possible to pass
+ * <code>null</code>, this is not recommended, since
+ * a logging message without text is unlikely to be
+ * helpful.
+ */
+ public synchronized void warning(String message)
+ {
+ if (isLoggable(Level.WARNING))
+ log(Level.WARNING, message);
+ }
+
+
+ /**
+ * Logs a message with severity level INFO. {@link Level#INFO} is
+ * intended for purely informational messages that do not indicate
+ * error or warning situations. In the default logging
+ * configuration, INFO messages will be written to the system
+ * console. For this reason, the INFO level should be used only for
+ * messages that are important to end users and system
+ * administrators. Messages at this level should be understandable
+ * to an inexperienced, non-technical user.
+ *
+ * @param message the message text, also used as look-up key if the
+ * logger is localizing messages with a resource
+ * bundle. While it is possible to pass
+ * <code>null</code>, this is not recommended, since
+ * a logging message without text is unlikely to be
+ * helpful.
+ */
+ public synchronized void info(String message)
+ {
+ if (isLoggable(Level.INFO))
+ log(Level.INFO, message);
+ }
+
+
+ /**
+ * Logs a message with severity level CONFIG. {@link Level#CONFIG} is
+ * intended for static configuration messages, for example about the
+ * windowing environment, the operating system version, etc.
+ *
+ * @param message the message text, also used as look-up key if the
+ * logger is localizing messages with a resource bundle. While
+ * it is possible to pass <code>null</code>, this is not
+ * recommended, since a logging message without text is unlikely
+ * to be helpful.
+ */
+ public synchronized void config(String message)
+ {
+ if (isLoggable(Level.CONFIG))
+ log(Level.CONFIG, message);
+ }
+
+
+ /**
+ * Logs a message with severity level FINE. {@link Level#FINE} is
+ * intended for messages that are relevant for developers using
+ * the component generating log messages. Examples include minor,
+ * recoverable failures, or possible inefficiencies.
+ *
+ * @param message the message text, also used as look-up key if the
+ * logger is localizing messages with a resource
+ * bundle. While it is possible to pass
+ * <code>null</code>, this is not recommended, since
+ * a logging message without text is unlikely to be
+ * helpful.
+ */
+ public synchronized void fine(String message)
+ {
+ if (isLoggable(Level.FINE))
+ log(Level.FINE, message);
+ }
+
+
+ /**
+ * Logs a message with severity level FINER. {@link Level#FINER} is
+ * intended for rather detailed tracing, for example entering a
+ * method, returning from a method, or throwing an exception.
+ *
+ * @param message the message text, also used as look-up key if the
+ * logger is localizing messages with a resource
+ * bundle. While it is possible to pass
+ * <code>null</code>, this is not recommended, since
+ * a logging message without text is unlikely to be
+ * helpful.
+ */
+ public synchronized void finer(String message)
+ {
+ if (isLoggable(Level.FINER))
+ log(Level.FINER, message);
+ }
+
+
+ /**
+ * Logs a message with severity level FINEST. {@link Level#FINEST}
+ * is intended for highly detailed tracing, for example reaching a
+ * certain point inside the body of a method.
+ *
+ * @param message the message text, also used as look-up key if the
+ * logger is localizing messages with a resource
+ * bundle. While it is possible to pass
+ * <code>null</code>, this is not recommended, since
+ * a logging message without text is unlikely to be
+ * helpful.
+ */
+ public synchronized void finest(String message)
+ {
+ if (isLoggable(Level.FINEST))
+ log(Level.FINEST, message);
+ }
+
+
+ /**
+ * Adds a handler to the set of handlers that get notified
+ * when a log record is to be published.
+ *
+ * @param handler the handler to be added.
+ *
+ * @throws NullPointerException if <code>handler</code>
+ * is <code>null</code>.
+ *
+ * @throws SecurityException if this logger is not anonymous, a
+ * security manager exists, and the caller is not granted
+ * the permission to control the logging infrastructure by
+ * having LoggingPermission("control"). Untrusted code can
+ * obtain an anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ */
+ public synchronized void addHandler(Handler handler)
+ throws SecurityException
+ {
+ /* Throw a new NullPointerException if handler is null. */
+ handler.getClass();
+
+ /* An application is allowed to control an anonymous logger
+ * without having the permission to control the logging
+ * infrastructure.
+ */
+ if (!anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ if (!handlerList.contains(handler))
+ {
+ handlerList.add(handler);
+ handlers = getHandlers();
+ }
+ }
+
+
+ /**
+ * Removes a handler from the set of handlers that get notified
+ * when a log record is to be published.
+ *
+ * @param handler the handler to be removed.
+ *
+ * @throws SecurityException if this logger is not anonymous, a
+ * security manager exists, and the caller is not granted the
+ * permission to control the logging infrastructure by having
+ * LoggingPermission("control"). Untrusted code can obtain an
+ * anonymous logger through the static factory method {@link
+ * #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ *
+ * @throws NullPointerException if <code>handler</code>
+ * is <code>null</code>.
+ */
+ public synchronized void removeHandler(Handler handler)
+ throws SecurityException
+ {
+ /* An application is allowed to control an anonymous logger
+ * without having the permission to control the logging
+ * infrastructure.
+ */
+ if (!anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ /* Throw a new NullPointerException if handler is null. */
+ handler.getClass();
+
+ handlerList.remove(handler);
+ handlers = getHandlers();
+ }
+
+
+ /**
+ * Returns the handlers currently registered for this Logger.
+ * When a log record has been deemed as being loggable,
+ * it will be passed to all registered handlers for
+ * publication. In addition, if the logger uses parent handlers
+ * (see {@link #getUseParentHandlers() getUseParentHandlers}
+ * and {@link #setUseParentHandlers(boolean) setUseParentHandlers},
+ * the log record will be passed to the parent's handlers.
+ */
+ public synchronized Handler[] getHandlers()
+ {
+ /* We cannot return our internal handlers array
+ * because we do not have any guarantee that the
+ * caller would not change the array entries.
+ */
+ return (Handler[]) handlerList.toArray(new Handler[handlerList.size()]);
+ }
+
+
+ /**
+ * Returns whether or not this Logger forwards log records to
+ * handlers registered for its parent loggers.
+ *
+ * @return <code>false</code> if this Logger sends log records
+ * merely to Handlers registered with itself;
+ * <code>true</code> if this Logger sends log records
+ * not only to Handlers registered with itself, but also
+ * to those Handlers registered with parent loggers.
+ */
+ public synchronized boolean getUseParentHandlers()
+ {
+ return useParentHandlers;
+ }
+
+
+ /**
+ * Sets whether or not this Logger forwards log records to
+ * handlers registered for its parent loggers.
+ *
+ * @param useParentHandlers <code>false</code> to let this
+ * Logger send log records merely to Handlers registered
+ * with itself; <code>true</code> to let this Logger
+ * send log records not only to Handlers registered
+ * with itself, but also to those Handlers registered with
+ * parent loggers.
+ *
+ * @throws SecurityException if this logger is not anonymous, a
+ * security manager exists, and the caller is not granted
+ * the permission to control the logging infrastructure by
+ * having LoggingPermission("control"). Untrusted code can
+ * obtain an anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ *
+ */
+ public synchronized void setUseParentHandlers(boolean useParentHandlers)
+ {
+ /* An application is allowed to control an anonymous logger
+ * without having the permission to control the logging
+ * infrastructure.
+ */
+ if (!anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.useParentHandlers = useParentHandlers;
+ }
+
+
+ /**
+ * Returns the parent of this logger. By default, the parent is
+ * assigned by the LogManager by inspecting the logger's name.
+ *
+ * @return the parent of this logger (as detemined by the LogManager
+ * by inspecting logger names), the root logger if no other
+ * logger has a name which is a prefix of this logger's name, or
+ * <code>null</code> for the root logger.
+ */
+ public synchronized Logger getParent()
+ {
+ return parent;
+ }
+
+
+ /**
+ * Sets the parent of this logger. Usually, applications do not
+ * call this method directly. Instead, the LogManager will ensure
+ * that the tree of loggers reflects the hierarchical logger
+ * namespace. Basically, this method should not be public at all,
+ * but the GNU implementation follows the API specification.
+ *
+ * @throws NullPointerException if <code>parent</code> is
+ * <code>null</code>.
+ *
+ * @throws SecurityException if this logger is not anonymous, a
+ * security manager exists, and the caller is not granted
+ * the permission to control the logging infrastructure by
+ * having LoggingPermission("control"). Untrusted code can
+ * obtain an anonymous logger through the static factory method
+ * {@link #getAnonymousLogger(java.lang.String) getAnonymousLogger}.
+ */
+ public synchronized void setParent(Logger parent)
+ {
+ /* Throw a new NullPointerException if parent is null. */
+ parent.getClass();
+
+ if (this == root)
+ throw new IllegalArgumentException(
+ "the root logger can only have a null parent");
+
+ /* An application is allowed to control an anonymous logger
+ * without having the permission to control the logging
+ * infrastructure.
+ */
+ if (!anonymous)
+ LogManager.getLogManager().checkAccess();
+
+ this.parent = parent;
+ }
+
+ /**
+ * Gets the StackTraceElement of the first class that is not this class.
+ * That should be the initial caller of a logging method.
+ * @return caller of the initial logging method or null if unknown.
+ */
+ private native StackTraceElement getCallerStackFrame();
+
+ /**
+ * Reset and close handlers attached to this logger. This function is package
+ * private because it must only be avaiable to the LogManager.
+ */
+ void resetLogger()
+ {
+ for (int i = 0; i < handlers.length; i++)
+ {
+ handlers[i].close();
+ handlerList.remove(handlers[i]);
+ }
+ handlers = getHandlers();
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/util/logging/natLogger.cc b/gcc-4.2.1/libjava/java/util/logging/natLogger.cc
new file mode 100644
index 000000000..5c68b1722
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/logging/natLogger.cc
@@ -0,0 +1,49 @@
+// natLogger.cc - Native part of Logger class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
+
+ This Logger is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the Logger "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <string.h>
+
+#pragma implementation "Logger.h"
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+
+#include <java/lang/Object.h>
+#include <java/lang/Class.h>
+#include <java/util/logging/Logger.h>
+#include <java/lang/StackTraceElement.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+
+using namespace java::util::logging;
+
+java::lang::StackTraceElement*
+java::util::logging::Logger::getCallerStackFrame ()
+{
+ jclass klass = NULL;
+ _Jv_Method *meth = NULL;
+ _Jv_StackTrace::GetCallerInfo (&Logger::class$, &klass, &meth);
+
+ jstring meth_name = NULL;
+ jstring klass_name = NULL;
+ if (klass != NULL)
+ klass_name = klass->getName();
+ if (meth != NULL)
+ meth_name = _Jv_NewStringUtf8Const (meth->name);
+
+ java::lang::StackTraceElement *e
+ = new java::lang::StackTraceElement
+ (JvNewStringUTF (""), 0, klass_name, meth_name, false);
+
+ return e;
+}
diff --git a/gcc-4.2.1/libjava/java/util/natResourceBundle.cc b/gcc-4.2.1/libjava/java/util/natResourceBundle.cc
new file mode 100644
index 000000000..e8d4fb4fd
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/natResourceBundle.cc
@@ -0,0 +1,29 @@
+/* Copyright (C) 2002, 2003, 2005 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@redhat.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-stack.h>
+#include <java/util/ResourceBundle.h>
+#include <java/lang/ClassLoader.h>
+#include <java/lang/Class.h>
+
+using namespace java::lang;
+
+java::lang::ClassLoader *
+java::util::ResourceBundle::getCallingClassLoader ()
+{
+ jclass caller = _Jv_StackTrace::GetCallingClass (&ResourceBundle::class$);
+ if (caller)
+ return caller->getClassLoaderInternal();
+ return NULL;
+}
diff --git a/gcc-4.2.1/libjava/java/util/natVMTimeZone.cc b/gcc-4.2.1/libjava/java/util/natVMTimeZone.cc
new file mode 100644
index 000000000..d45ebf978
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/natVMTimeZone.cc
@@ -0,0 +1,145 @@
+// natVMTimeZone.cc -- Native side of VMTimeZone class.
+
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+#include <platform.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/util/VMTimeZone.h>
+#include <java/lang/Character.h>
+#include <java/lang/Integer.h>
+
+#include <stdio.h>
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+#include <string.h>
+
+/**
+ * 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 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.
+ */
+jstring
+java::util::VMTimeZone::getSystemTimeZoneId()
+{
+ struct tm tim;
+#if !defined(HAVE_LOCALTIME_R) || !defined(_POSIX_PTHREAD_SEMANTICS)
+ struct tm *lt_tim;
+#endif
+#ifdef HAVE_TM_ZONE
+ int month;
+#endif
+ time_t current_time;
+ long tzoffset;
+ const char *tz1, *tz2;
+ char *tzid;
+
+ time(&current_time);
+#if defined(HAVE_LOCALTIME_R) && defined(_POSIX_PTHREAD_SEMANTICS)
+ localtime_r(&current_time, &tim);
+#else
+ /* Fall back on non-thread safe localtime. */
+ lt_tim = localtime(&current_time);
+ memcpy(&tim, lt_tim, sizeof (struct tm));
+#endif
+ mktime(&tim);
+
+#ifdef HAVE_TM_ZONE
+ /* We will cycle through the months to make sure we hit dst. */
+ month = tim.tm_mon;
+ tz1 = tz2 = NULL;
+ while (tz1 == NULL || tz2 == NULL)
+ {
+ if (tim.tm_isdst > 0)
+ tz2 = tim.tm_zone;
+ else if (tz1 == NULL)
+ {
+ tz1 = tim.tm_zone;
+ month = tim.tm_mon;
+ }
+
+ if (tz1 == NULL || tz2 == NULL)
+ {
+ tim.tm_mon++;
+ tim.tm_mon %= 12;
+ }
+
+ if (tim.tm_mon == month && tz2 == NULL)
+ tz2 = "";
+ else
+ mktime(&tim);
+ }
+ /* We want to make sure the tm struct we use later on is not dst. */
+ tim.tm_mon = month;
+ mktime(&tim);
+#elif defined (HAVE_TZNAME)
+ /* If dst is never used, tzname[1] is the empty string. */
+ tzset();
+ tz1 = tzname[0];
+ tz2 = tzname[1];
+#else
+ /* Some targets have no concept of timezones. Assume GMT without dst. */
+ tz1 = "GMT";
+ tz2 = "";
+#endif
+
+#ifdef STRUCT_TM_HAS_GMTOFF
+ /* tm_gmtoff is the number of seconds that you must add to GMT to get
+ local time, we need the number of seconds to add to the local time
+ to get GMT. */
+ tzoffset = -1L * tim.tm_gmtoff;
+#elif HAVE_UNDERSCORE_TIMEZONE
+ tzoffset = _timezone;
+#elif HAVE_TIMEZONE
+ /* timezone is secs WEST of UTC. */
+ tzoffset = timezone;
+#else
+ /* FIXME: there must be another global if neither tm_gmtoff nor timezone
+ is available, esp. if tzname is valid.
+ Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
+ calculate between gmtime and localtime (and accounting for possible
+ daylight savings time) as an alternative. */
+ tzoffset = 0L;
+#endif
+
+ if ((tzoffset % 3600) == 0)
+ tzoffset = tzoffset / 3600;
+
+ tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6);
+ sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2);
+ jstring retval = JvNewStringUTF (tzid);
+ _Jv_Free (tzid);
+
+ return retval;
+}
diff --git a/gcc-4.2.1/libjava/java/util/zip/Deflater.java b/gcc-4.2.1/libjava/java/util/zip/Deflater.java
new file mode 100644
index 000000000..8ac8a34a6
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/zip/Deflater.java
@@ -0,0 +1,334 @@
+/* Deflater.java - Compress a data stream
+ Copyright (C) 1999, 2000, 2001, 2004, 2006 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.zip;
+
+import gnu.gcj.RawData;
+
+/**
+ * This is the Deflater class. The deflater class compresses input
+ * with the deflate algorithm described in RFC 1951. It has several
+ * compression levels and three different strategies described below.
+ *
+ * This class is <i>not</i> thread safe. This is inherent in the API, due
+ * to the split of deflate and setInput.
+ *
+ * @author Jochen Hoenicke
+ * @author Tom Tromey
+ */
+public class Deflater
+{
+ /**
+ * The best and slowest compression level. This tries to find very
+ * long and distant string repetitions.
+ */
+ public static final int BEST_COMPRESSION = 9;
+ /**
+ * The worst but fastest compression level.
+ */
+ public static final int BEST_SPEED = 1;
+ /**
+ * The default compression level.
+ */
+ public static final int DEFAULT_COMPRESSION = -1;
+ /**
+ * This level won't compress at all but output uncompressed blocks.
+ */
+ public static final int NO_COMPRESSION = 0;
+
+ /**
+ * The default strategy.
+ */
+ public static final int DEFAULT_STRATEGY = 0;
+ /**
+ * This strategy will only allow longer string repetitions. It is
+ * useful for random data with a small character set.
+ */
+ public static final int FILTERED = 1;
+
+ /**
+ * This strategy will not look for string repetitions at all. It
+ * only encodes with Huffman trees (which means, that more common
+ * characters get a smaller encoding.
+ */
+ public static final int HUFFMAN_ONLY = 2;
+
+ /**
+ * The compression method. This is the only method supported so far.
+ * There is no need to use this constant at all.
+ */
+ public static final int DEFLATED = 8;
+
+ /** Compression level. */
+ private int level;
+
+ /** Compression strategy. */
+ private int strategy;
+
+ /** The zlib stream. */
+ private RawData zstream;
+
+ /** True if finished. */
+ private boolean is_finished;
+
+ /** `Flush' flag to pass to next call to deflate. */
+ private int flush_flag;
+
+ /**
+ * Creates a new deflater with default compression level.
+ */
+ public Deflater()
+ {
+ this(DEFAULT_COMPRESSION, false);
+ }
+
+ /**
+ * Creates a new deflater with given compression level.
+ * @param lvl the compression level, a value between NO_COMPRESSION
+ * and BEST_COMPRESSION, or DEFAULT_COMPRESSION.
+ * @exception IllegalArgumentException if lvl is out of range.
+ */
+ public Deflater(int lvl)
+ {
+ this(lvl, false);
+ }
+
+ /**
+ * Creates a new deflater with given compression level.
+ * @param lvl the compression level, a value between NO_COMPRESSION
+ * and BEST_COMPRESSION.
+ * @param nowrap true, iff we should suppress the deflate header at the
+ * beginning and the adler checksum at the end of the output. This is
+ * useful for the GZIP format.
+ * @exception IllegalArgumentException if lvl is out of range.
+ */
+ public Deflater(int lvl, boolean noHeader)
+ {
+ this.strategy = DEFAULT_STRATEGY;
+ init(lvl, noHeader);
+ setLevel(lvl);
+ }
+
+ private native void init(int level, boolean noHeader);
+
+ private native void update();
+
+ /**
+ * Resets the deflater. The deflater acts afterwards as if it was
+ * just created with the same compression level and strategy as it
+ * had before.
+ */
+ public native void reset();
+
+ /**
+ * Frees all objects allocated by the compressor. There's no
+ * reason to call this, since you can just rely on garbage
+ * collection. Exists only for compatibility against Sun's JDK,
+ * where the compressor allocates native memory.
+ * If you call any method (even reset) afterwards the behaviour is
+ * <i>undefined</i>.
+ * @deprecated Just clear all references to deflater instead.
+ */
+ public native void end();
+
+ /**
+ * Gets the current adler checksum of the data that was processed so
+ * far.
+ */
+ public native int getAdler();
+
+ /**
+ * Gets the number of input bytes processed so far.
+ */
+ public native int getTotalIn();
+
+ /**
+ * Gets the number of output bytes so far.
+ */
+ public native int getTotalOut();
+
+ /**
+ * Finalizes this object.
+ */
+ protected void finalize()
+ {
+ end();
+ }
+
+ /**
+ * Finishes the deflater with the current input block. It is an error
+ * to give more input after this method was called. This method must
+ * be called to force all bytes to be flushed.
+ */
+ public native void finish();
+
+ /**
+ * Returns true iff the stream was finished and no more output bytes
+ * are available.
+ */
+ public synchronized boolean finished()
+ {
+ return is_finished;
+ }
+
+ /**
+ * Returns true, if the input buffer is empty.
+ * You should then call setInput(). <br>
+ *
+ * <em>NOTE</em>: This method can also return true when the stream
+ * was finished.
+ */
+ public native boolean needsInput();
+
+ /**
+ * Sets the data which should be compressed next. This should be only
+ * called when needsInput indicates that more input is needed.
+ * If you call setInput when needsInput() returns false, the
+ * previous input that is still pending will be thrown away.
+ * The given byte array should not be changed, before needsInput() returns
+ * true again.
+ * This call is equivalent to <code>setInput(input, 0, input.length)</code>.
+ * @param input the buffer containing the input data.
+ * @exception IllegalStateException if the buffer was finished() or ended().
+ */
+ public void setInput(byte[] input)
+ {
+ setInput(input, 0, input.length);
+ }
+
+ /**
+ * Sets the data which should be compressed next. This should be
+ * only called when needsInput indicates that more input is needed.
+ * The given byte array should not be changed, before needsInput() returns
+ * true again.
+ * @param input the buffer containing the input data.
+ * @param off the start of the data.
+ * @param len the length of the data.
+ * @exception IllegalStateException if the buffer was finished() or ended()
+ * or if previous input is still pending.
+ */
+ public native void setInput(byte[] input, int off, int len);
+
+ /**
+ * Sets the compression level. There is no guarantee of the exact
+ * position of the change, but if you call this when needsInput is
+ * true the change of compression level will occur somewhere near
+ * before the end of the so far given input.
+ * @param lvl the new compression level.
+ */
+ public synchronized void setLevel(int lvl)
+ {
+ if (lvl != -1 && (lvl < 0 || lvl > 9))
+ throw new IllegalArgumentException();
+ level = (lvl == -1) ? 6 : lvl;
+ update();
+ }
+
+ /**
+ * Sets the compression strategy. Strategy is one of
+ * DEFAULT_STRATEGY, HUFFMAN_ONLY and FILTERED. For the exact
+ * position where the strategy is changed, the same as for
+ * setLevel() applies.
+ * @param stgy the new compression strategy.
+ */
+ public synchronized void setStrategy(int stgy)
+ {
+ if (stgy != DEFAULT_STRATEGY && stgy != FILTERED
+ && stgy != HUFFMAN_ONLY)
+ throw new IllegalArgumentException();
+ strategy = stgy;
+ update();
+ }
+
+ /**
+ * Deflates the current input block to the given array. It returns
+ * the number of bytes compressed, or 0 if either
+ * needsInput() or finished() returns true or length is zero.
+ * @param output the buffer where to write the compressed data.
+ */
+ public int deflate(byte[] output)
+ {
+ return deflate(output, 0, output.length);
+ }
+
+ /**
+ * Deflates the current input block to the given array. It returns
+ * the number of bytes compressed, or 0 if either
+ * needsInput() or finished() returns true or length is zero.
+ * @param output the buffer where to write the compressed data.
+ * @param offset the offset into the output array.
+ * @param length the maximum number of bytes that may be written.
+ * @exception IllegalStateException if end() was called.
+ * @exception IndexOutOfBoundsException if offset and/or length
+ * don't match the array length.
+ */
+ public native int deflate(byte[] output, int off, int len);
+
+ /**
+ * Sets the dictionary which should be used in the deflate process.
+ * This call is equivalent to <code>setDictionary(dict, 0,
+ * dict.length)</code>.
+ * @param dict the dictionary.
+ * @exception IllegalStateException if setInput () or deflate ()
+ * were already called or another dictionary was already set.
+ */
+ public void setDictionary(byte[] dict)
+ {
+ setDictionary(dict, 0, dict.length);
+ }
+
+ /**
+ * Sets the dictionary which should be used in the deflate process.
+ * The dictionary should be a byte array containing strings that are
+ * likely to occur in the data which should be compressed. The
+ * dictionary is not stored in the compressed output, only a
+ * checksum. To decompress the output you need to supply the same
+ * dictionary again.
+ * @param dict the dictionary.
+ * @param offset an offset into the dictionary.
+ * @param length the length of the dictionary.
+ * @exception IllegalStateException if setInput () or deflate () were
+ * already called or another dictionary was already set.
+ */
+ public native void setDictionary(byte[] buf, int off, int len);
+
+ // Classpath's compression library supports flushing, but we
+ // don't. So this is a no-op here.
+ void flush()
+ {
+ }
+}
diff --git a/gcc-4.2.1/libjava/java/util/zip/Inflater.java b/gcc-4.2.1/libjava/java/util/zip/Inflater.java
new file mode 100644
index 000000000..c51cde802
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/zip/Inflater.java
@@ -0,0 +1,269 @@
+/* Inflater.java - Decompress a data stream
+ Copyright (C) 1999, 2000, 2001, 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.util.zip;
+
+import gnu.gcj.RawData;
+
+/* Written using on-line Java Platform 1.2 API Specification
+ * and JCL book.
+ * Believed complete and correct.
+ */
+
+/**
+ * Inflater is used to decompress data that has been compressed according
+ * to the "deflate" standard described in rfc1950.
+ *
+ * The usage is as following. First you have to set some input with
+ * <code>setInput()</code>, then inflate() it. If inflate doesn't
+ * inflate any bytes there may be three reasons:
+ * <ul>
+ * <li>needsInput() returns true because the input buffer is empty.
+ * You have to provide more input with <code>setInput()</code>.
+ * NOTE: needsInput() also returns true when, the stream is finished.
+ * </li>
+ * <li>needsDictionary() returns true, you have to provide a preset
+ * dictionary with <code>setDictionary()</code>.</li>
+ * <li>finished() returns true, the inflater has finished.</li>
+ * </ul>
+ * Once the first output byte is produced, a dictionary will not be
+ * needed at a later stage.
+ *
+ * @author John Leuner, Jochen Hoenicke
+ * @author Tom Tromey
+ * @date May 17, 1999
+ * @since JDK 1.1
+ */
+public class Inflater
+{
+ // The zlib stream.
+ private RawData zstream;
+
+ // True if finished.
+ private boolean is_finished;
+
+ // True if dictionary needed.
+ private boolean dict_needed;
+
+ /**
+ * Creates a new inflater.
+ */
+ public Inflater ()
+ {
+ this (false);
+ }
+
+ /**
+ * Creates a new inflater.
+ * @param nowrap true if no header and checksum field appears in the
+ * stream. This is used for GZIPed input. For compatibility with
+ * Sun JDK you should provide one byte of input more than needed in
+ * this case.
+ */
+ public Inflater (boolean noHeader)
+ {
+ init (noHeader);
+ }
+
+ /**
+ * Finalizes this object.
+ */
+ protected void finalize ()
+ {
+ end ();
+ }
+
+ /**
+ * Frees all objects allocated by the inflater. There's no reason
+ * to call this, since you can just rely on garbage collection (even
+ * for the Sun implementation). Exists only for compatibility
+ * with Sun's JDK, where the compressor allocates native memory.
+ * If you call any method (even reset) afterwards the behaviour is
+ * <i>undefined</i>.
+ * @deprecated Just clear all references to inflater instead.
+ */
+ public native void end ();
+
+ /**
+ * Returns true, if the inflater has finished. This means, that no
+ * input is needed and no output can be produced.
+ */
+ public synchronized boolean finished ()
+ {
+ return is_finished;
+ }
+
+ /**
+ * Gets the adler checksum. This is either the checksum of all
+ * uncompressed bytes returned by inflate(), or if needsDictionary()
+ * returns true (and thus no output was yet produced) this is the
+ * adler checksum of the expected dictionary.
+ * @returns the adler checksum.
+ */
+ public native int getAdler ();
+
+ /**
+ * Gets the number of unprocessed input. Useful, if the end of the
+ * stream is reached and you want to further process the bytes after
+ * the deflate stream.
+ * @return the number of bytes of the input which were not processed.
+ */
+ public native int getRemaining ();
+
+ /**
+ * Gets the total number of processed compressed input bytes.
+ * @return the total number of bytes of processed input bytes.
+ */
+ public native int getTotalIn ();
+
+ /**
+ * Gets the total number of output bytes returned by inflate().
+ * @return the total number of output bytes.
+ */
+ public native int getTotalOut ();
+
+ /**
+ * Inflates the compressed stream to the output buffer. If this
+ * returns 0, you should check, whether needsDictionary(),
+ * needsInput() or finished() returns true, to determine why no
+ * further output is produced.
+ * @param buffer the output buffer.
+ * @return the number of bytes written to the buffer, 0 if no further
+ * output can be produced.
+ * @exception DataFormatException if deflated stream is invalid.
+ * @exception IllegalArgumentException if buf has length 0.
+ */
+ public int inflate (byte[] buf) throws DataFormatException
+ {
+ return inflate (buf, 0, buf.length);
+ }
+
+ /**
+ * Inflates the compressed stream to the output buffer. If this
+ * returns 0, you should check, whether needsDictionary(),
+ * needsInput() or finished() returns true, to determine why no
+ * further output is produced.
+ * @param buffer the output buffer.
+ * @param off the offset into buffer where the output should start.
+ * @param len the maximum length of the output.
+ * @return the number of bytes written to the buffer, 0 if no further
+ * output can be produced.
+ * @exception DataFormatException if deflated stream is invalid.
+ * @exception IndexOutOfBoundsException if the off and/or len are wrong.
+ */
+ public native int inflate (byte[] buf, int off, int len)
+ throws DataFormatException;
+
+ private native void init (boolean noHeader);
+
+ /**
+ * Returns true, if a preset dictionary is needed to inflate the input.
+ */
+ public synchronized boolean needsDictionary ()
+ {
+ return dict_needed;
+ }
+
+ /**
+ * Returns true, if the input buffer is empty.
+ * You should then call setInput(). <br>
+ *
+ * <em>NOTE</em>: This method also returns true when the stream is finished.
+ */
+ public synchronized boolean needsInput ()
+ {
+ return getRemaining () == 0;
+ }
+
+ /**
+ * Resets the inflater so that a new stream can be decompressed. All
+ * pending input and output will be discarded.
+ */
+ public native void reset ();
+
+ /**
+ * Sets the preset dictionary. This should only be called, if
+ * needsDictionary() returns true and it should set the same
+ * dictionary, that was used for deflating. The getAdler()
+ * function returns the checksum of the dictionary needed.
+ * @param buffer the dictionary.
+ * @exception IllegalStateException if no dictionary is needed.
+ * @exception IllegalArgumentException if the dictionary checksum is
+ * wrong.
+ */
+ public void setDictionary (byte[] buf)
+ {
+ setDictionary (buf, 0, buf.length);
+ }
+
+ /**
+ * Sets the preset dictionary. This should only be called, if
+ * needsDictionary() returns true and it should set the same
+ * dictionary, that was used for deflating. The getAdler()
+ * function returns the checksum of the dictionary needed.
+ * @param buffer the dictionary.
+ * @param off the offset into buffer where the dictionary starts.
+ * @param len the length of the dictionary.
+ * @exception IllegalStateException if no dictionary is needed.
+ * @exception IllegalArgumentException if the dictionary checksum is
+ * wrong.
+ * @exception IndexOutOfBoundsException if the off and/or len are wrong.
+ */
+ public native void setDictionary (byte[] buf, int off, int len);
+
+ /**
+ * Sets the input. This should only be called, if needsInput()
+ * returns true.
+ * @param buffer the input.
+ * @exception IllegalStateException if no input is needed.
+ */
+ public void setInput (byte[] buf)
+ {
+ setInput (buf, 0, buf.length);
+ }
+
+ /**
+ * Sets the input. This should only be called, if needsInput()
+ * returns true.
+ * @param buffer the input.
+ * @param off the offset into buffer where the input starts.
+ * @param len the length of the input.
+ * @exception IllegalStateException if no input is needed.
+ * @exception IndexOutOfBoundsException if the off and/or len are wrong.
+ */
+ public native void setInput (byte[] buf, int off, int len);
+}
diff --git a/gcc-4.2.1/libjava/java/util/zip/natDeflater.cc b/gcc-4.2.1/libjava/java/util/zip/natDeflater.cc
new file mode 100644
index 000000000..23e1201b5
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/zip/natDeflater.cc
@@ -0,0 +1,216 @@
+// natDeflater.cc - Implementation of Deflater native methods.
+
+/* Copyright (C) 1999, 2002 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@cygnus.com>
+
+#include <config.h>
+
+#include <zlib.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/util/zip/Deflater.h>
+#include <java/util/zip/DataFormatException.h>
+
+#include <java/lang/InternalError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+
+extern void *_Jv_ZMalloc (void *, uInt nitems, uInt size);
+extern void _Jv_ZFree (void *, void *addr);
+
+
+
+jint
+java::util::zip::Deflater::deflate (jbyteArray buf, jint off, jint len)
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+
+ if (! buf)
+ throw new java::lang::NullPointerException;
+ if (off < 0 || len < 0 || off + len > buf->length)
+ throw new java::lang::ArrayIndexOutOfBoundsException;
+
+ if (len == 0)
+ return 0;
+
+ s->next_out = (Bytef *) (elements (buf) + off);
+ s->avail_out = len;
+
+ switch (::deflate (s, flush_flag))
+ {
+ case Z_STREAM_END:
+ is_finished = true;
+ if (s->avail_out == (unsigned int) len)
+ return -1;
+ break;
+
+ case Z_STREAM_ERROR:
+ case Z_BUF_ERROR:
+ // FIXME?
+ throw new java::lang::InternalError;
+ break;
+
+ case Z_OK:
+ break;
+ }
+
+ return len - s->avail_out;
+}
+
+void
+java::util::zip::Deflater::end ()
+{
+ JvSynchronize sync (this);
+ // Just ignore errors.
+ deflateEnd ((z_streamp) zstream);
+ _Jv_Free (zstream);
+ zstream = NULL;
+}
+
+void
+java::util::zip::Deflater::finish ()
+{
+ JvSynchronize sync (this);
+ flush_flag = Z_FINISH;
+}
+
+jint
+java::util::zip::Deflater::getAdler ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->adler;
+}
+
+jint
+java::util::zip::Deflater::getTotalIn ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->total_in;
+}
+
+jint
+java::util::zip::Deflater::getTotalOut ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->total_out;
+}
+
+jboolean
+java::util::zip::Deflater::needsInput ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->avail_in == 0;
+}
+
+void
+java::util::zip::Deflater::reset ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ // Just ignore errors.
+ deflateReset (s);
+ s->avail_in = 0;
+ flush_flag = 0;
+ is_finished = false;
+}
+
+void
+java::util::zip::Deflater::setDictionary (jbyteArray buf, jint off, jint len)
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+
+ if (! buf)
+ throw new java::lang::NullPointerException;
+ if (off < 0 || len < 0 || off + len > buf->length)
+ throw new java::lang::ArrayIndexOutOfBoundsException;
+
+ // Ignore errors.
+ deflateSetDictionary (s, (Bytef *) (elements (buf) + off), len);
+}
+
+void
+java::util::zip::Deflater::setInput (jbyteArray buf, jint off, jint len)
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+
+ if (! buf)
+ throw new java::lang::NullPointerException;
+ if (off < 0 || len < 0 || off + len > buf->length)
+ throw new java::lang::ArrayIndexOutOfBoundsException;
+
+ s->next_in = (Bytef *) (elements (buf) + off);
+ s->avail_in = len;
+}
+
+void
+java::util::zip::Deflater::update ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+
+ int strat = Z_DEFAULT_STRATEGY;
+ switch (strategy)
+ {
+ case DEFAULT_STRATEGY:
+ strat = Z_DEFAULT_STRATEGY;
+ break;
+ case FILTERED:
+ strat = Z_FILTERED;
+ break;
+ case HUFFMAN_ONLY:
+ strat = Z_HUFFMAN_ONLY;
+ break;
+ default:
+ JvFail ("unexpected strategy");
+ }
+
+ // Ignore errors.
+ deflateParams (s, level, strat);
+}
+
+void
+java::util::zip::Deflater::init (jint level, jboolean no_header)
+{
+ z_stream_s *stream = (z_stream_s *) _Jv_Malloc (sizeof (z_stream_s));
+ stream->next_in = Z_NULL;
+ stream->avail_in = 0;
+ stream->zalloc = _Jv_ZMalloc;
+ stream->zfree = _Jv_ZFree;
+ stream->opaque = NULL;
+
+ // Handle NO_HEADER using undocumented zlib feature.
+ int wbits = MAX_WBITS;
+ if (no_header)
+ wbits = - wbits;
+
+#define DEFAULT_MEM_LEVEL 8
+ if (deflateInit2 (stream, level, Z_DEFLATED, wbits,
+ DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ jstring msg = NULL;
+ if (stream->msg != NULL)
+ msg = JvNewStringLatin1 (stream->msg);
+ throw new java::lang::InternalError (msg);
+ }
+
+ zstream = reinterpret_cast<gnu::gcj::RawData *> (stream);
+ is_finished = false;
+ flush_flag = 0;
+}
diff --git a/gcc-4.2.1/libjava/java/util/zip/natInflater.cc b/gcc-4.2.1/libjava/java/util/zip/natInflater.cc
new file mode 100644
index 000000000..69de6c335
--- /dev/null
+++ b/gcc-4.2.1/libjava/java/util/zip/natInflater.cc
@@ -0,0 +1,214 @@
+// natInflater.cc - Implementation of Inflater native methods.
+
+/* Copyright (C) 1999, 2002 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+// Written by Tom Tromey <tromey@cygnus.com>
+
+#include <config.h>
+
+#include <zlib.h>
+#include <stdlib.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+
+#include <java/util/zip/Inflater.h>
+#include <java/util/zip/DataFormatException.h>
+
+#include <java/lang/InternalError.h>
+#include <java/lang/NullPointerException.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/OutOfMemoryError.h>
+
+
+
+// A couple of helper functions used to interface with zlib's
+// allocation.
+
+void *
+_Jv_ZMalloc (void *, uInt nitems, uInt size)
+{
+ return _Jv_Malloc (nitems * size);
+}
+
+void
+_Jv_ZFree (void *, void *addr)
+{
+ _Jv_Free (addr);
+}
+
+
+
+void
+java::util::zip::Inflater::end ()
+{
+ JvSynchronize sync (this);
+ // Just ignore errors.
+ inflateEnd ((z_streamp) zstream);
+ _Jv_Free (zstream);
+ zstream = NULL;
+}
+
+jint
+java::util::zip::Inflater::getAdler ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->adler;
+}
+
+jint
+java::util::zip::Inflater::getRemaining ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->avail_in;
+}
+
+jint
+java::util::zip::Inflater::getTotalIn ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->total_in;
+}
+
+jint
+java::util::zip::Inflater::getTotalOut ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ return s->total_out;
+}
+
+jint
+java::util::zip::Inflater::inflate (jbyteArray buf, jint off, jint len)
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+
+ if (! buf)
+ throw new java::lang::NullPointerException;
+ if (off < 0 || len < 0 || off + len > buf->length)
+ throw new java::lang::ArrayIndexOutOfBoundsException;
+
+ if (len == 0)
+ return 0;
+
+ s->next_out = (Bytef *) (elements (buf) + off);
+ s->avail_out = len;
+
+ switch (::inflate (s, Z_SYNC_FLUSH))
+ {
+ case Z_BUF_ERROR:
+ /* Using the no_header option, zlib requires an extra padding byte at the
+ end of the stream in order to successfully complete decompression (see
+ zlib/contrib/minizip/unzip.c). We don't do this, so can end up with a
+ Z_BUF_ERROR at the end of a stream when zlib has completed inflation
+ and there's no more input. Thats not a problem. */
+ if (s->avail_in != 0)
+ throw new java::lang::InternalError;
+ // Fall through.
+
+ case Z_STREAM_END:
+ is_finished = true;
+ if (s->avail_out == (unsigned int) len)
+ return -1;
+ break;
+
+ case Z_NEED_DICT:
+ dict_needed = true;
+ break;
+
+ case Z_DATA_ERROR:
+ throw new java::util::zip::DataFormatException
+ (s->msg == NULL ? NULL : JvNewStringLatin1 (s->msg));
+ break;
+
+ case Z_MEM_ERROR:
+ throw new java::lang::OutOfMemoryError;
+ break;
+
+ case Z_OK:
+ break;
+ }
+
+ return len - s->avail_out;
+}
+
+void
+java::util::zip::Inflater::reset ()
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+ // Just ignore errors.
+ inflateReset (s);
+ s->avail_in = 0;
+ is_finished = false;
+ dict_needed = false;
+}
+
+void
+java::util::zip::Inflater::setDictionary (jbyteArray buf, jint off, jint len)
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+
+ if (! buf)
+ throw new java::lang::NullPointerException;
+ if (off < 0 || len < 0 || off + len > buf->length)
+ throw new java::lang::ArrayIndexOutOfBoundsException;
+
+ // Ignore errors.
+ inflateSetDictionary (s, (Bytef *) (elements (buf) + off), len);
+ dict_needed = false;
+}
+
+void
+java::util::zip::Inflater::setInput (jbyteArray buf, jint off, jint len)
+{
+ JvSynchronize sync (this);
+ z_streamp s = (z_streamp) zstream;
+
+ if (! buf)
+ throw new java::lang::NullPointerException;
+ if (off < 0 || len < 0 || off + len > buf->length)
+ throw new java::lang::ArrayIndexOutOfBoundsException;
+
+ s->next_in = (Bytef *) (elements (buf) + off);
+ s->avail_in = len;
+}
+
+void
+java::util::zip::Inflater::init (jboolean no_header)
+{
+ z_stream_s *stream = (z_stream_s *) _Jv_Malloc (sizeof (z_stream_s));
+ stream->next_in = Z_NULL;
+ stream->avail_in = 0;
+ stream->zalloc = _Jv_ZMalloc;
+ stream->zfree = _Jv_ZFree;
+ stream->opaque = NULL;
+
+ // Handle NO_HEADER using undocumented zlib feature.
+ int wbits = MAX_WBITS;
+ if (no_header)
+ wbits = - wbits;
+
+ if (inflateInit2 (stream, wbits) != Z_OK)
+ {
+ jstring msg = NULL;
+ if (stream->msg != NULL)
+ msg = JvNewStringLatin1 (stream->msg);
+ throw new java::lang::InternalError (msg);
+ }
+
+ zstream = reinterpret_cast<gnu::gcj::RawData *> (stream);
+ is_finished = false;
+ dict_needed = false;
+}