1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/compact/src/main/java/java/io/BufferedWriter.java Sat Sep 07 13:51:24 2013 +0200
1.3 @@ -0,0 +1,272 @@
1.4 +/*
1.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.io;
1.30 +
1.31 +
1.32 +/**
1.33 + * Writes text to a character-output stream, buffering characters so as to
1.34 + * provide for the efficient writing of single characters, arrays, and strings.
1.35 + *
1.36 + * <p> The buffer size may be specified, or the default size may be accepted.
1.37 + * The default is large enough for most purposes.
1.38 + *
1.39 + * <p> A newLine() method is provided, which uses the platform's own notion of
1.40 + * line separator as defined by the system property <tt>line.separator</tt>.
1.41 + * Not all platforms use the newline character ('\n') to terminate lines.
1.42 + * Calling this method to terminate each output line is therefore preferred to
1.43 + * writing a newline character directly.
1.44 + *
1.45 + * <p> In general, a Writer sends its output immediately to the underlying
1.46 + * character or byte stream. Unless prompt output is required, it is advisable
1.47 + * to wrap a BufferedWriter around any Writer whose write() operations may be
1.48 + * costly, such as FileWriters and OutputStreamWriters. For example,
1.49 + *
1.50 + * <pre>
1.51 + * PrintWriter out
1.52 + * = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
1.53 + * </pre>
1.54 + *
1.55 + * will buffer the PrintWriter's output to the file. Without buffering, each
1.56 + * invocation of a print() method would cause characters to be converted into
1.57 + * bytes that would then be written immediately to the file, which can be very
1.58 + * inefficient.
1.59 + *
1.60 + * @see PrintWriter
1.61 + * @see FileWriter
1.62 + * @see OutputStreamWriter
1.63 + * @see java.nio.file.Files#newBufferedWriter
1.64 + *
1.65 + * @author Mark Reinhold
1.66 + * @since JDK1.1
1.67 + */
1.68 +
1.69 +public class BufferedWriter extends Writer {
1.70 +
1.71 + private Writer out;
1.72 +
1.73 + private char cb[];
1.74 + private int nChars, nextChar;
1.75 +
1.76 + private static int defaultCharBufferSize = 8192;
1.77 +
1.78 + /**
1.79 + * Line separator string. This is the value of the line.separator
1.80 + * property at the moment that the stream was created.
1.81 + */
1.82 + private String lineSeparator;
1.83 +
1.84 + /**
1.85 + * Creates a buffered character-output stream that uses a default-sized
1.86 + * output buffer.
1.87 + *
1.88 + * @param out A Writer
1.89 + */
1.90 + public BufferedWriter(Writer out) {
1.91 + this(out, defaultCharBufferSize);
1.92 + }
1.93 +
1.94 + /**
1.95 + * Creates a new buffered character-output stream that uses an output
1.96 + * buffer of the given size.
1.97 + *
1.98 + * @param out A Writer
1.99 + * @param sz Output-buffer size, a positive integer
1.100 + *
1.101 + * @exception IllegalArgumentException If sz is <= 0
1.102 + */
1.103 + public BufferedWriter(Writer out, int sz) {
1.104 + super(out);
1.105 + if (sz <= 0)
1.106 + throw new IllegalArgumentException("Buffer size <= 0");
1.107 + this.out = out;
1.108 + cb = new char[sz];
1.109 + nChars = sz;
1.110 + nextChar = 0;
1.111 +
1.112 + lineSeparator = java.security.AccessController.doPrivileged(
1.113 + new sun.security.action.GetPropertyAction("line.separator"));
1.114 + }
1.115 +
1.116 + /** Checks to make sure that the stream has not been closed */
1.117 + private void ensureOpen() throws IOException {
1.118 + if (out == null)
1.119 + throw new IOException("Stream closed");
1.120 + }
1.121 +
1.122 + /**
1.123 + * Flushes the output buffer to the underlying character stream, without
1.124 + * flushing the stream itself. This method is non-private only so that it
1.125 + * may be invoked by PrintStream.
1.126 + */
1.127 + void flushBuffer() throws IOException {
1.128 + synchronized (lock) {
1.129 + ensureOpen();
1.130 + if (nextChar == 0)
1.131 + return;
1.132 + out.write(cb, 0, nextChar);
1.133 + nextChar = 0;
1.134 + }
1.135 + }
1.136 +
1.137 + /**
1.138 + * Writes a single character.
1.139 + *
1.140 + * @exception IOException If an I/O error occurs
1.141 + */
1.142 + public void write(int c) throws IOException {
1.143 + synchronized (lock) {
1.144 + ensureOpen();
1.145 + if (nextChar >= nChars)
1.146 + flushBuffer();
1.147 + cb[nextChar++] = (char) c;
1.148 + }
1.149 + }
1.150 +
1.151 + /**
1.152 + * Our own little min method, to avoid loading java.lang.Math if we've run
1.153 + * out of file descriptors and we're trying to print a stack trace.
1.154 + */
1.155 + private int min(int a, int b) {
1.156 + if (a < b) return a;
1.157 + return b;
1.158 + }
1.159 +
1.160 + /**
1.161 + * Writes a portion of an array of characters.
1.162 + *
1.163 + * <p> Ordinarily this method stores characters from the given array into
1.164 + * this stream's buffer, flushing the buffer to the underlying stream as
1.165 + * needed. If the requested length is at least as large as the buffer,
1.166 + * however, then this method will flush the buffer and write the characters
1.167 + * directly to the underlying stream. Thus redundant
1.168 + * <code>BufferedWriter</code>s will not copy data unnecessarily.
1.169 + *
1.170 + * @param cbuf A character array
1.171 + * @param off Offset from which to start reading characters
1.172 + * @param len Number of characters to write
1.173 + *
1.174 + * @exception IOException If an I/O error occurs
1.175 + */
1.176 + public void write(char cbuf[], int off, int len) throws IOException {
1.177 + synchronized (lock) {
1.178 + ensureOpen();
1.179 + if ((off < 0) || (off > cbuf.length) || (len < 0) ||
1.180 + ((off + len) > cbuf.length) || ((off + len) < 0)) {
1.181 + throw new IndexOutOfBoundsException();
1.182 + } else if (len == 0) {
1.183 + return;
1.184 + }
1.185 +
1.186 + if (len >= nChars) {
1.187 + /* If the request length exceeds the size of the output buffer,
1.188 + flush the buffer and then write the data directly. In this
1.189 + way buffered streams will cascade harmlessly. */
1.190 + flushBuffer();
1.191 + out.write(cbuf, off, len);
1.192 + return;
1.193 + }
1.194 +
1.195 + int b = off, t = off + len;
1.196 + while (b < t) {
1.197 + int d = min(nChars - nextChar, t - b);
1.198 + System.arraycopy(cbuf, b, cb, nextChar, d);
1.199 + b += d;
1.200 + nextChar += d;
1.201 + if (nextChar >= nChars)
1.202 + flushBuffer();
1.203 + }
1.204 + }
1.205 + }
1.206 +
1.207 + /**
1.208 + * Writes a portion of a String.
1.209 + *
1.210 + * <p> If the value of the <tt>len</tt> parameter is negative then no
1.211 + * characters are written. This is contrary to the specification of this
1.212 + * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int)
1.213 + * superclass}, which requires that an {@link IndexOutOfBoundsException} be
1.214 + * thrown.
1.215 + *
1.216 + * @param s String to be written
1.217 + * @param off Offset from which to start reading characters
1.218 + * @param len Number of characters to be written
1.219 + *
1.220 + * @exception IOException If an I/O error occurs
1.221 + */
1.222 + public void write(String s, int off, int len) throws IOException {
1.223 + synchronized (lock) {
1.224 + ensureOpen();
1.225 +
1.226 + int b = off, t = off + len;
1.227 + while (b < t) {
1.228 + int d = min(nChars - nextChar, t - b);
1.229 + s.getChars(b, b + d, cb, nextChar);
1.230 + b += d;
1.231 + nextChar += d;
1.232 + if (nextChar >= nChars)
1.233 + flushBuffer();
1.234 + }
1.235 + }
1.236 + }
1.237 +
1.238 + /**
1.239 + * Writes a line separator. The line separator string is defined by the
1.240 + * system property <tt>line.separator</tt>, and is not necessarily a single
1.241 + * newline ('\n') character.
1.242 + *
1.243 + * @exception IOException If an I/O error occurs
1.244 + */
1.245 + public void newLine() throws IOException {
1.246 + write(lineSeparator);
1.247 + }
1.248 +
1.249 + /**
1.250 + * Flushes the stream.
1.251 + *
1.252 + * @exception IOException If an I/O error occurs
1.253 + */
1.254 + public void flush() throws IOException {
1.255 + synchronized (lock) {
1.256 + flushBuffer();
1.257 + out.flush();
1.258 + }
1.259 + }
1.260 +
1.261 + public void close() throws IOException {
1.262 + synchronized (lock) {
1.263 + if (out == null) {
1.264 + return;
1.265 + }
1.266 + try {
1.267 + flushBuffer();
1.268 + } finally {
1.269 + out.close();
1.270 + out = null;
1.271 + cb = null;
1.272 + }
1.273 + }
1.274 + }
1.275 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/emul/compact/src/main/java/java/io/File.java Sat Sep 07 13:51:24 2013 +0200
2.3 @@ -0,0 +1,2076 @@
2.4 +/*
2.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2.7 + *
2.8 + * This code is free software; you can redistribute it and/or modify it
2.9 + * under the terms of the GNU General Public License version 2 only, as
2.10 + * published by the Free Software Foundation. Oracle designates this
2.11 + * particular file as subject to the "Classpath" exception as provided
2.12 + * by Oracle in the LICENSE file that accompanied this code.
2.13 + *
2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2.17 + * version 2 for more details (a copy is included in the LICENSE file that
2.18 + * accompanied this code).
2.19 + *
2.20 + * You should have received a copy of the GNU General Public License version
2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2.23 + *
2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2.25 + * or visit www.oracle.com if you need additional information or have any
2.26 + * questions.
2.27 + */
2.28 +
2.29 +package java.io;
2.30 +
2.31 +import java.net.URI;
2.32 +import java.net.URL;
2.33 +import java.net.MalformedURLException;
2.34 +import java.net.URISyntaxException;
2.35 +import java.util.List;
2.36 +import java.util.ArrayList;
2.37 +import java.security.AccessController;
2.38 +import java.security.SecureRandom;
2.39 +import java.nio.file.Path;
2.40 +import java.nio.file.FileSystems;
2.41 +import sun.security.action.GetPropertyAction;
2.42 +
2.43 +/**
2.44 + * An abstract representation of file and directory pathnames.
2.45 + *
2.46 + * <p> User interfaces and operating systems use system-dependent <em>pathname
2.47 + * strings</em> to name files and directories. This class presents an
2.48 + * abstract, system-independent view of hierarchical pathnames. An
2.49 + * <em>abstract pathname</em> has two components:
2.50 + *
2.51 + * <ol>
2.52 + * <li> An optional system-dependent <em>prefix</em> string,
2.53 + * such as a disk-drive specifier, <code>"/"</code> for the UNIX root
2.54 + * directory, or <code>"\\\\"</code> for a Microsoft Windows UNC pathname, and
2.55 + * <li> A sequence of zero or more string <em>names</em>.
2.56 + * </ol>
2.57 + *
2.58 + * The first name in an abstract pathname may be a directory name or, in the
2.59 + * case of Microsoft Windows UNC pathnames, a hostname. Each subsequent name
2.60 + * in an abstract pathname denotes a directory; the last name may denote
2.61 + * either a directory or a file. The <em>empty</em> abstract pathname has no
2.62 + * prefix and an empty name sequence.
2.63 + *
2.64 + * <p> The conversion of a pathname string to or from an abstract pathname is
2.65 + * inherently system-dependent. When an abstract pathname is converted into a
2.66 + * pathname string, each name is separated from the next by a single copy of
2.67 + * the default <em>separator character</em>. The default name-separator
2.68 + * character is defined by the system property <code>file.separator</code>, and
2.69 + * is made available in the public static fields <code>{@link
2.70 + * #separator}</code> and <code>{@link #separatorChar}</code> of this class.
2.71 + * When a pathname string is converted into an abstract pathname, the names
2.72 + * within it may be separated by the default name-separator character or by any
2.73 + * other name-separator character that is supported by the underlying system.
2.74 + *
2.75 + * <p> A pathname, whether abstract or in string form, may be either
2.76 + * <em>absolute</em> or <em>relative</em>. An absolute pathname is complete in
2.77 + * that no other information is required in order to locate the file that it
2.78 + * denotes. A relative pathname, in contrast, must be interpreted in terms of
2.79 + * information taken from some other pathname. By default the classes in the
2.80 + * <code>java.io</code> package always resolve relative pathnames against the
2.81 + * current user directory. This directory is named by the system property
2.82 + * <code>user.dir</code>, and is typically the directory in which the Java
2.83 + * virtual machine was invoked.
2.84 + *
2.85 + * <p> The <em>parent</em> of an abstract pathname may be obtained by invoking
2.86 + * the {@link #getParent} method of this class and consists of the pathname's
2.87 + * prefix and each name in the pathname's name sequence except for the last.
2.88 + * Each directory's absolute pathname is an ancestor of any <tt>File</tt>
2.89 + * object with an absolute abstract pathname which begins with the directory's
2.90 + * absolute pathname. For example, the directory denoted by the abstract
2.91 + * pathname <tt>"/usr"</tt> is an ancestor of the directory denoted by the
2.92 + * pathname <tt>"/usr/local/bin"</tt>.
2.93 + *
2.94 + * <p> The prefix concept is used to handle root directories on UNIX platforms,
2.95 + * and drive specifiers, root directories and UNC pathnames on Microsoft Windows platforms,
2.96 + * as follows:
2.97 + *
2.98 + * <ul>
2.99 + *
2.100 + * <li> For UNIX platforms, the prefix of an absolute pathname is always
2.101 + * <code>"/"</code>. Relative pathnames have no prefix. The abstract pathname
2.102 + * denoting the root directory has the prefix <code>"/"</code> and an empty
2.103 + * name sequence.
2.104 + *
2.105 + * <li> For Microsoft Windows platforms, the prefix of a pathname that contains a drive
2.106 + * specifier consists of the drive letter followed by <code>":"</code> and
2.107 + * possibly followed by <code>"\\"</code> if the pathname is absolute. The
2.108 + * prefix of a UNC pathname is <code>"\\\\"</code>; the hostname and the share
2.109 + * name are the first two names in the name sequence. A relative pathname that
2.110 + * does not specify a drive has no prefix.
2.111 + *
2.112 + * </ul>
2.113 + *
2.114 + * <p> Instances of this class may or may not denote an actual file-system
2.115 + * object such as a file or a directory. If it does denote such an object
2.116 + * then that object resides in a <i>partition</i>. A partition is an
2.117 + * operating system-specific portion of storage for a file system. A single
2.118 + * storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may
2.119 + * contain multiple partitions. The object, if any, will reside on the
2.120 + * partition <a name="partName">named</a> by some ancestor of the absolute
2.121 + * form of this pathname.
2.122 + *
2.123 + * <p> A file system may implement restrictions to certain operations on the
2.124 + * actual file-system object, such as reading, writing, and executing. These
2.125 + * restrictions are collectively known as <i>access permissions</i>. The file
2.126 + * system may have multiple sets of access permissions on a single object.
2.127 + * For example, one set may apply to the object's <i>owner</i>, and another
2.128 + * may apply to all other users. The access permissions on an object may
2.129 + * cause some methods in this class to fail.
2.130 + *
2.131 + * <p> Instances of the <code>File</code> class are immutable; that is, once
2.132 + * created, the abstract pathname represented by a <code>File</code> object
2.133 + * will never change.
2.134 + *
2.135 + * <h4>Interoperability with {@code java.nio.file} package</h4>
2.136 + *
2.137 + * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a>
2.138 + * package defines interfaces and classes for the Java virtual machine to access
2.139 + * files, file attributes, and file systems. This API may be used to overcome
2.140 + * many of the limitations of the {@code java.io.File} class.
2.141 + * The {@link #toPath toPath} method may be used to obtain a {@link
2.142 + * Path} that uses the abstract path represented by a {@code File} object to
2.143 + * locate a file. The resulting {@code Path} may be used with the {@link
2.144 + * java.nio.file.Files} class to provide more efficient and extensive access to
2.145 + * additional file operations, file attributes, and I/O exceptions to help
2.146 + * diagnose errors when an operation on a file fails.
2.147 + *
2.148 + * @author unascribed
2.149 + * @since JDK1.0
2.150 + */
2.151 +
2.152 +public class File
2.153 + implements Serializable, Comparable<File>
2.154 +{
2.155 +
2.156 + /**
2.157 + * The FileSystem object representing the platform's local file system.
2.158 + */
2.159 + static private FileSystem fs = FileSystem.getFileSystem();
2.160 +
2.161 + /**
2.162 + * This abstract pathname's normalized pathname string. A normalized
2.163 + * pathname string uses the default name-separator character and does not
2.164 + * contain any duplicate or redundant separators.
2.165 + *
2.166 + * @serial
2.167 + */
2.168 + private String path;
2.169 +
2.170 + /**
2.171 + * The length of this abstract pathname's prefix, or zero if it has no
2.172 + * prefix.
2.173 + */
2.174 + private transient int prefixLength;
2.175 +
2.176 + /**
2.177 + * Returns the length of this abstract pathname's prefix.
2.178 + * For use by FileSystem classes.
2.179 + */
2.180 + int getPrefixLength() {
2.181 + return prefixLength;
2.182 + }
2.183 +
2.184 + /**
2.185 + * The system-dependent default name-separator character. This field is
2.186 + * initialized to contain the first character of the value of the system
2.187 + * property <code>file.separator</code>. On UNIX systems the value of this
2.188 + * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>.
2.189 + *
2.190 + * @see java.lang.System#getProperty(java.lang.String)
2.191 + */
2.192 + public static final char separatorChar = fs.getSeparator();
2.193 +
2.194 + /**
2.195 + * The system-dependent default name-separator character, represented as a
2.196 + * string for convenience. This string contains a single character, namely
2.197 + * <code>{@link #separatorChar}</code>.
2.198 + */
2.199 + public static final String separator = "" + separatorChar;
2.200 +
2.201 + /**
2.202 + * The system-dependent path-separator character. This field is
2.203 + * initialized to contain the first character of the value of the system
2.204 + * property <code>path.separator</code>. This character is used to
2.205 + * separate filenames in a sequence of files given as a <em>path list</em>.
2.206 + * On UNIX systems, this character is <code>':'</code>; on Microsoft Windows systems it
2.207 + * is <code>';'</code>.
2.208 + *
2.209 + * @see java.lang.System#getProperty(java.lang.String)
2.210 + */
2.211 + public static final char pathSeparatorChar = fs.getPathSeparator();
2.212 +
2.213 + /**
2.214 + * The system-dependent path-separator character, represented as a string
2.215 + * for convenience. This string contains a single character, namely
2.216 + * <code>{@link #pathSeparatorChar}</code>.
2.217 + */
2.218 + public static final String pathSeparator = "" + pathSeparatorChar;
2.219 +
2.220 +
2.221 + /* -- Constructors -- */
2.222 +
2.223 + /**
2.224 + * Internal constructor for already-normalized pathname strings.
2.225 + */
2.226 + private File(String pathname, int prefixLength) {
2.227 + this.path = pathname;
2.228 + this.prefixLength = prefixLength;
2.229 + }
2.230 +
2.231 + /**
2.232 + * Internal constructor for already-normalized pathname strings.
2.233 + * The parameter order is used to disambiguate this method from the
2.234 + * public(File, String) constructor.
2.235 + */
2.236 + private File(String child, File parent) {
2.237 + assert parent.path != null;
2.238 + assert (!parent.path.equals(""));
2.239 + this.path = fs.resolve(parent.path, child);
2.240 + this.prefixLength = parent.prefixLength;
2.241 + }
2.242 +
2.243 + /**
2.244 + * Creates a new <code>File</code> instance by converting the given
2.245 + * pathname string into an abstract pathname. If the given string is
2.246 + * the empty string, then the result is the empty abstract pathname.
2.247 + *
2.248 + * @param pathname A pathname string
2.249 + * @throws NullPointerException
2.250 + * If the <code>pathname</code> argument is <code>null</code>
2.251 + */
2.252 + public File(String pathname) {
2.253 + if (pathname == null) {
2.254 + throw new NullPointerException();
2.255 + }
2.256 + this.path = fs.normalize(pathname);
2.257 + this.prefixLength = fs.prefixLength(this.path);
2.258 + }
2.259 +
2.260 + /* Note: The two-argument File constructors do not interpret an empty
2.261 + parent abstract pathname as the current user directory. An empty parent
2.262 + instead causes the child to be resolved against the system-dependent
2.263 + directory defined by the FileSystem.getDefaultParent method. On Unix
2.264 + this default is "/", while on Microsoft Windows it is "\\". This is required for
2.265 + compatibility with the original behavior of this class. */
2.266 +
2.267 + /**
2.268 + * Creates a new <code>File</code> instance from a parent pathname string
2.269 + * and a child pathname string.
2.270 + *
2.271 + * <p> If <code>parent</code> is <code>null</code> then the new
2.272 + * <code>File</code> instance is created as if by invoking the
2.273 + * single-argument <code>File</code> constructor on the given
2.274 + * <code>child</code> pathname string.
2.275 + *
2.276 + * <p> Otherwise the <code>parent</code> pathname string is taken to denote
2.277 + * a directory, and the <code>child</code> pathname string is taken to
2.278 + * denote either a directory or a file. If the <code>child</code> pathname
2.279 + * string is absolute then it is converted into a relative pathname in a
2.280 + * system-dependent way. If <code>parent</code> is the empty string then
2.281 + * the new <code>File</code> instance is created by converting
2.282 + * <code>child</code> into an abstract pathname and resolving the result
2.283 + * against a system-dependent default directory. Otherwise each pathname
2.284 + * string is converted into an abstract pathname and the child abstract
2.285 + * pathname is resolved against the parent.
2.286 + *
2.287 + * @param parent The parent pathname string
2.288 + * @param child The child pathname string
2.289 + * @throws NullPointerException
2.290 + * If <code>child</code> is <code>null</code>
2.291 + */
2.292 + public File(String parent, String child) {
2.293 + if (child == null) {
2.294 + throw new NullPointerException();
2.295 + }
2.296 + if (parent != null) {
2.297 + if (parent.equals("")) {
2.298 + this.path = fs.resolve(fs.getDefaultParent(),
2.299 + fs.normalize(child));
2.300 + } else {
2.301 + this.path = fs.resolve(fs.normalize(parent),
2.302 + fs.normalize(child));
2.303 + }
2.304 + } else {
2.305 + this.path = fs.normalize(child);
2.306 + }
2.307 + this.prefixLength = fs.prefixLength(this.path);
2.308 + }
2.309 +
2.310 + /**
2.311 + * Creates a new <code>File</code> instance from a parent abstract
2.312 + * pathname and a child pathname string.
2.313 + *
2.314 + * <p> If <code>parent</code> is <code>null</code> then the new
2.315 + * <code>File</code> instance is created as if by invoking the
2.316 + * single-argument <code>File</code> constructor on the given
2.317 + * <code>child</code> pathname string.
2.318 + *
2.319 + * <p> Otherwise the <code>parent</code> abstract pathname is taken to
2.320 + * denote a directory, and the <code>child</code> pathname string is taken
2.321 + * to denote either a directory or a file. If the <code>child</code>
2.322 + * pathname string is absolute then it is converted into a relative
2.323 + * pathname in a system-dependent way. If <code>parent</code> is the empty
2.324 + * abstract pathname then the new <code>File</code> instance is created by
2.325 + * converting <code>child</code> into an abstract pathname and resolving
2.326 + * the result against a system-dependent default directory. Otherwise each
2.327 + * pathname string is converted into an abstract pathname and the child
2.328 + * abstract pathname is resolved against the parent.
2.329 + *
2.330 + * @param parent The parent abstract pathname
2.331 + * @param child The child pathname string
2.332 + * @throws NullPointerException
2.333 + * If <code>child</code> is <code>null</code>
2.334 + */
2.335 + public File(File parent, String child) {
2.336 + if (child == null) {
2.337 + throw new NullPointerException();
2.338 + }
2.339 + if (parent != null) {
2.340 + if (parent.path.equals("")) {
2.341 + this.path = fs.resolve(fs.getDefaultParent(),
2.342 + fs.normalize(child));
2.343 + } else {
2.344 + this.path = fs.resolve(parent.path,
2.345 + fs.normalize(child));
2.346 + }
2.347 + } else {
2.348 + this.path = fs.normalize(child);
2.349 + }
2.350 + this.prefixLength = fs.prefixLength(this.path);
2.351 + }
2.352 +
2.353 + /**
2.354 + * Creates a new <tt>File</tt> instance by converting the given
2.355 + * <tt>file:</tt> URI into an abstract pathname.
2.356 + *
2.357 + * <p> The exact form of a <tt>file:</tt> URI is system-dependent, hence
2.358 + * the transformation performed by this constructor is also
2.359 + * system-dependent.
2.360 + *
2.361 + * <p> For a given abstract pathname <i>f</i> it is guaranteed that
2.362 + *
2.363 + * <blockquote><tt>
2.364 + * new File(</tt><i> f</i><tt>.{@link #toURI() toURI}()).equals(</tt><i> f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
2.365 + * </tt></blockquote>
2.366 + *
2.367 + * so long as the original abstract pathname, the URI, and the new abstract
2.368 + * pathname are all created in (possibly different invocations of) the same
2.369 + * Java virtual machine. This relationship typically does not hold,
2.370 + * however, when a <tt>file:</tt> URI that is created in a virtual machine
2.371 + * on one operating system is converted into an abstract pathname in a
2.372 + * virtual machine on a different operating system.
2.373 + *
2.374 + * @param uri
2.375 + * An absolute, hierarchical URI with a scheme equal to
2.376 + * <tt>"file"</tt>, a non-empty path component, and undefined
2.377 + * authority, query, and fragment components
2.378 + *
2.379 + * @throws NullPointerException
2.380 + * If <tt>uri</tt> is <tt>null</tt>
2.381 + *
2.382 + * @throws IllegalArgumentException
2.383 + * If the preconditions on the parameter do not hold
2.384 + *
2.385 + * @see #toURI()
2.386 + * @see java.net.URI
2.387 + * @since 1.4
2.388 + */
2.389 + public File(URI uri) {
2.390 +
2.391 + // Check our many preconditions
2.392 + if (!uri.isAbsolute())
2.393 + throw new IllegalArgumentException("URI is not absolute");
2.394 + if (uri.isOpaque())
2.395 + throw new IllegalArgumentException("URI is not hierarchical");
2.396 + String scheme = uri.getScheme();
2.397 + if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
2.398 + throw new IllegalArgumentException("URI scheme is not \"file\"");
2.399 + if (uri.getAuthority() != null)
2.400 + throw new IllegalArgumentException("URI has an authority component");
2.401 + if (uri.getFragment() != null)
2.402 + throw new IllegalArgumentException("URI has a fragment component");
2.403 + if (uri.getQuery() != null)
2.404 + throw new IllegalArgumentException("URI has a query component");
2.405 + String p = uri.getPath();
2.406 + if (p.equals(""))
2.407 + throw new IllegalArgumentException("URI path component is empty");
2.408 +
2.409 + // Okay, now initialize
2.410 + p = fs.fromURIPath(p);
2.411 + if (File.separatorChar != '/')
2.412 + p = p.replace('/', File.separatorChar);
2.413 + this.path = fs.normalize(p);
2.414 + this.prefixLength = fs.prefixLength(this.path);
2.415 + }
2.416 +
2.417 +
2.418 + /* -- Path-component accessors -- */
2.419 +
2.420 + /**
2.421 + * Returns the name of the file or directory denoted by this abstract
2.422 + * pathname. This is just the last name in the pathname's name
2.423 + * sequence. If the pathname's name sequence is empty, then the empty
2.424 + * string is returned.
2.425 + *
2.426 + * @return The name of the file or directory denoted by this abstract
2.427 + * pathname, or the empty string if this pathname's name sequence
2.428 + * is empty
2.429 + */
2.430 + public String getName() {
2.431 + int index = path.lastIndexOf(separatorChar);
2.432 + if (index < prefixLength) return path.substring(prefixLength);
2.433 + return path.substring(index + 1);
2.434 + }
2.435 +
2.436 + /**
2.437 + * Returns the pathname string of this abstract pathname's parent, or
2.438 + * <code>null</code> if this pathname does not name a parent directory.
2.439 + *
2.440 + * <p> The <em>parent</em> of an abstract pathname consists of the
2.441 + * pathname's prefix, if any, and each name in the pathname's name
2.442 + * sequence except for the last. If the name sequence is empty then
2.443 + * the pathname does not name a parent directory.
2.444 + *
2.445 + * @return The pathname string of the parent directory named by this
2.446 + * abstract pathname, or <code>null</code> if this pathname
2.447 + * does not name a parent
2.448 + */
2.449 + public String getParent() {
2.450 + int index = path.lastIndexOf(separatorChar);
2.451 + if (index < prefixLength) {
2.452 + if ((prefixLength > 0) && (path.length() > prefixLength))
2.453 + return path.substring(0, prefixLength);
2.454 + return null;
2.455 + }
2.456 + return path.substring(0, index);
2.457 + }
2.458 +
2.459 + /**
2.460 + * Returns the abstract pathname of this abstract pathname's parent,
2.461 + * or <code>null</code> if this pathname does not name a parent
2.462 + * directory.
2.463 + *
2.464 + * <p> The <em>parent</em> of an abstract pathname consists of the
2.465 + * pathname's prefix, if any, and each name in the pathname's name
2.466 + * sequence except for the last. If the name sequence is empty then
2.467 + * the pathname does not name a parent directory.
2.468 + *
2.469 + * @return The abstract pathname of the parent directory named by this
2.470 + * abstract pathname, or <code>null</code> if this pathname
2.471 + * does not name a parent
2.472 + *
2.473 + * @since 1.2
2.474 + */
2.475 + public File getParentFile() {
2.476 + String p = this.getParent();
2.477 + if (p == null) return null;
2.478 + return new File(p, this.prefixLength);
2.479 + }
2.480 +
2.481 + /**
2.482 + * Converts this abstract pathname into a pathname string. The resulting
2.483 + * string uses the {@link #separator default name-separator character} to
2.484 + * separate the names in the name sequence.
2.485 + *
2.486 + * @return The string form of this abstract pathname
2.487 + */
2.488 + public String getPath() {
2.489 + return path;
2.490 + }
2.491 +
2.492 +
2.493 + /* -- Path operations -- */
2.494 +
2.495 + /**
2.496 + * Tests whether this abstract pathname is absolute. The definition of
2.497 + * absolute pathname is system dependent. On UNIX systems, a pathname is
2.498 + * absolute if its prefix is <code>"/"</code>. On Microsoft Windows systems, a
2.499 + * pathname is absolute if its prefix is a drive specifier followed by
2.500 + * <code>"\\"</code>, or if its prefix is <code>"\\\\"</code>.
2.501 + *
2.502 + * @return <code>true</code> if this abstract pathname is absolute,
2.503 + * <code>false</code> otherwise
2.504 + */
2.505 + public boolean isAbsolute() {
2.506 + return fs.isAbsolute(this);
2.507 + }
2.508 +
2.509 + /**
2.510 + * Returns the absolute pathname string of this abstract pathname.
2.511 + *
2.512 + * <p> If this abstract pathname is already absolute, then the pathname
2.513 + * string is simply returned as if by the <code>{@link #getPath}</code>
2.514 + * method. If this abstract pathname is the empty abstract pathname then
2.515 + * the pathname string of the current user directory, which is named by the
2.516 + * system property <code>user.dir</code>, is returned. Otherwise this
2.517 + * pathname is resolved in a system-dependent way. On UNIX systems, a
2.518 + * relative pathname is made absolute by resolving it against the current
2.519 + * user directory. On Microsoft Windows systems, a relative pathname is made absolute
2.520 + * by resolving it against the current directory of the drive named by the
2.521 + * pathname, if any; if not, it is resolved against the current user
2.522 + * directory.
2.523 + *
2.524 + * @return The absolute pathname string denoting the same file or
2.525 + * directory as this abstract pathname
2.526 + *
2.527 + * @throws SecurityException
2.528 + * If a required system property value cannot be accessed.
2.529 + *
2.530 + * @see java.io.File#isAbsolute()
2.531 + */
2.532 + public String getAbsolutePath() {
2.533 + return fs.resolve(this);
2.534 + }
2.535 +
2.536 + /**
2.537 + * Returns the absolute form of this abstract pathname. Equivalent to
2.538 + * <code>new File(this.{@link #getAbsolutePath})</code>.
2.539 + *
2.540 + * @return The absolute abstract pathname denoting the same file or
2.541 + * directory as this abstract pathname
2.542 + *
2.543 + * @throws SecurityException
2.544 + * If a required system property value cannot be accessed.
2.545 + *
2.546 + * @since 1.2
2.547 + */
2.548 + public File getAbsoluteFile() {
2.549 + String absPath = getAbsolutePath();
2.550 + return new File(absPath, fs.prefixLength(absPath));
2.551 + }
2.552 +
2.553 + /**
2.554 + * Returns the canonical pathname string of this abstract pathname.
2.555 + *
2.556 + * <p> A canonical pathname is both absolute and unique. The precise
2.557 + * definition of canonical form is system-dependent. This method first
2.558 + * converts this pathname to absolute form if necessary, as if by invoking the
2.559 + * {@link #getAbsolutePath} method, and then maps it to its unique form in a
2.560 + * system-dependent way. This typically involves removing redundant names
2.561 + * such as <tt>"."</tt> and <tt>".."</tt> from the pathname, resolving
2.562 + * symbolic links (on UNIX platforms), and converting drive letters to a
2.563 + * standard case (on Microsoft Windows platforms).
2.564 + *
2.565 + * <p> Every pathname that denotes an existing file or directory has a
2.566 + * unique canonical form. Every pathname that denotes a nonexistent file
2.567 + * or directory also has a unique canonical form. The canonical form of
2.568 + * the pathname of a nonexistent file or directory may be different from
2.569 + * the canonical form of the same pathname after the file or directory is
2.570 + * created. Similarly, the canonical form of the pathname of an existing
2.571 + * file or directory may be different from the canonical form of the same
2.572 + * pathname after the file or directory is deleted.
2.573 + *
2.574 + * @return The canonical pathname string denoting the same file or
2.575 + * directory as this abstract pathname
2.576 + *
2.577 + * @throws IOException
2.578 + * If an I/O error occurs, which is possible because the
2.579 + * construction of the canonical pathname may require
2.580 + * filesystem queries
2.581 + *
2.582 + * @throws SecurityException
2.583 + * If a required system property value cannot be accessed, or
2.584 + * if a security manager exists and its <code>{@link
2.585 + * java.lang.SecurityManager#checkRead}</code> method denies
2.586 + * read access to the file
2.587 + *
2.588 + * @since JDK1.1
2.589 + * @see Path#toRealPath
2.590 + */
2.591 + public String getCanonicalPath() throws IOException {
2.592 + return fs.canonicalize(fs.resolve(this));
2.593 + }
2.594 +
2.595 + /**
2.596 + * Returns the canonical form of this abstract pathname. Equivalent to
2.597 + * <code>new File(this.{@link #getCanonicalPath})</code>.
2.598 + *
2.599 + * @return The canonical pathname string denoting the same file or
2.600 + * directory as this abstract pathname
2.601 + *
2.602 + * @throws IOException
2.603 + * If an I/O error occurs, which is possible because the
2.604 + * construction of the canonical pathname may require
2.605 + * filesystem queries
2.606 + *
2.607 + * @throws SecurityException
2.608 + * If a required system property value cannot be accessed, or
2.609 + * if a security manager exists and its <code>{@link
2.610 + * java.lang.SecurityManager#checkRead}</code> method denies
2.611 + * read access to the file
2.612 + *
2.613 + * @since 1.2
2.614 + * @see Path#toRealPath
2.615 + */
2.616 + public File getCanonicalFile() throws IOException {
2.617 + String canonPath = getCanonicalPath();
2.618 + return new File(canonPath, fs.prefixLength(canonPath));
2.619 + }
2.620 +
2.621 + private static String slashify(String path, boolean isDirectory) {
2.622 + String p = path;
2.623 + if (File.separatorChar != '/')
2.624 + p = p.replace(File.separatorChar, '/');
2.625 + if (!p.startsWith("/"))
2.626 + p = "/" + p;
2.627 + if (!p.endsWith("/") && isDirectory)
2.628 + p = p + "/";
2.629 + return p;
2.630 + }
2.631 +
2.632 + /**
2.633 + * Converts this abstract pathname into a <code>file:</code> URL. The
2.634 + * exact form of the URL is system-dependent. If it can be determined that
2.635 + * the file denoted by this abstract pathname is a directory, then the
2.636 + * resulting URL will end with a slash.
2.637 + *
2.638 + * @return A URL object representing the equivalent file URL
2.639 + *
2.640 + * @throws MalformedURLException
2.641 + * If the path cannot be parsed as a URL
2.642 + *
2.643 + * @see #toURI()
2.644 + * @see java.net.URI
2.645 + * @see java.net.URI#toURL()
2.646 + * @see java.net.URL
2.647 + * @since 1.2
2.648 + *
2.649 + * @deprecated This method does not automatically escape characters that
2.650 + * are illegal in URLs. It is recommended that new code convert an
2.651 + * abstract pathname into a URL by first converting it into a URI, via the
2.652 + * {@link #toURI() toURI} method, and then converting the URI into a URL
2.653 + * via the {@link java.net.URI#toURL() URI.toURL} method.
2.654 + */
2.655 + @Deprecated
2.656 + public URL toURL() throws MalformedURLException {
2.657 + return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
2.658 + }
2.659 +
2.660 + /**
2.661 + * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
2.662 + *
2.663 + * <p> The exact form of the URI is system-dependent. If it can be
2.664 + * determined that the file denoted by this abstract pathname is a
2.665 + * directory, then the resulting URI will end with a slash.
2.666 + *
2.667 + * <p> For a given abstract pathname <i>f</i>, it is guaranteed that
2.668 + *
2.669 + * <blockquote><tt>
2.670 + * new {@link #File(java.net.URI) File}(</tt><i> f</i><tt>.toURI()).equals(</tt><i> f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
2.671 + * </tt></blockquote>
2.672 + *
2.673 + * so long as the original abstract pathname, the URI, and the new abstract
2.674 + * pathname are all created in (possibly different invocations of) the same
2.675 + * Java virtual machine. Due to the system-dependent nature of abstract
2.676 + * pathnames, however, this relationship typically does not hold when a
2.677 + * <tt>file:</tt> URI that is created in a virtual machine on one operating
2.678 + * system is converted into an abstract pathname in a virtual machine on a
2.679 + * different operating system.
2.680 + *
2.681 + * <p> Note that when this abstract pathname represents a UNC pathname then
2.682 + * all components of the UNC (including the server name component) are encoded
2.683 + * in the {@code URI} path. The authority component is undefined, meaning
2.684 + * that it is represented as {@code null}. The {@link Path} class defines the
2.685 + * {@link Path#toUri toUri} method to encode the server name in the authority
2.686 + * component of the resulting {@code URI}. The {@link #toPath toPath} method
2.687 + * may be used to obtain a {@code Path} representing this abstract pathname.
2.688 + *
2.689 + * @return An absolute, hierarchical URI with a scheme equal to
2.690 + * <tt>"file"</tt>, a path representing this abstract pathname,
2.691 + * and undefined authority, query, and fragment components
2.692 + * @throws SecurityException If a required system property value cannot
2.693 + * be accessed.
2.694 + *
2.695 + * @see #File(java.net.URI)
2.696 + * @see java.net.URI
2.697 + * @see java.net.URI#toURL()
2.698 + * @since 1.4
2.699 + */
2.700 + public URI toURI() {
2.701 + try {
2.702 + File f = getAbsoluteFile();
2.703 + String sp = slashify(f.getPath(), f.isDirectory());
2.704 + if (sp.startsWith("//"))
2.705 + sp = "//" + sp;
2.706 + return new URI("file", null, sp, null);
2.707 + } catch (URISyntaxException x) {
2.708 + throw new Error(x); // Can't happen
2.709 + }
2.710 + }
2.711 +
2.712 +
2.713 + /* -- Attribute accessors -- */
2.714 +
2.715 + /**
2.716 + * Tests whether the application can read the file denoted by this
2.717 + * abstract pathname.
2.718 + *
2.719 + * @return <code>true</code> if and only if the file specified by this
2.720 + * abstract pathname exists <em>and</em> can be read by the
2.721 + * application; <code>false</code> otherwise
2.722 + *
2.723 + * @throws SecurityException
2.724 + * If a security manager exists and its <code>{@link
2.725 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.726 + * method denies read access to the file
2.727 + */
2.728 + public boolean canRead() {
2.729 + SecurityManager security = System.getSecurityManager();
2.730 + if (security != null) {
2.731 + security.checkRead(path);
2.732 + }
2.733 + return fs.checkAccess(this, FileSystem.ACCESS_READ);
2.734 + }
2.735 +
2.736 + /**
2.737 + * Tests whether the application can modify the file denoted by this
2.738 + * abstract pathname.
2.739 + *
2.740 + * @return <code>true</code> if and only if the file system actually
2.741 + * contains a file denoted by this abstract pathname <em>and</em>
2.742 + * the application is allowed to write to the file;
2.743 + * <code>false</code> otherwise.
2.744 + *
2.745 + * @throws SecurityException
2.746 + * If a security manager exists and its <code>{@link
2.747 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.748 + * method denies write access to the file
2.749 + */
2.750 + public boolean canWrite() {
2.751 + SecurityManager security = System.getSecurityManager();
2.752 + if (security != null) {
2.753 + security.checkWrite(path);
2.754 + }
2.755 + return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
2.756 + }
2.757 +
2.758 + /**
2.759 + * Tests whether the file or directory denoted by this abstract pathname
2.760 + * exists.
2.761 + *
2.762 + * @return <code>true</code> if and only if the file or directory denoted
2.763 + * by this abstract pathname exists; <code>false</code> otherwise
2.764 + *
2.765 + * @throws SecurityException
2.766 + * If a security manager exists and its <code>{@link
2.767 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.768 + * method denies read access to the file or directory
2.769 + */
2.770 + public boolean exists() {
2.771 + SecurityManager security = System.getSecurityManager();
2.772 + if (security != null) {
2.773 + security.checkRead(path);
2.774 + }
2.775 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
2.776 + }
2.777 +
2.778 + /**
2.779 + * Tests whether the file denoted by this abstract pathname is a
2.780 + * directory.
2.781 + *
2.782 + * <p> Where it is required to distinguish an I/O exception from the case
2.783 + * that the file is not a directory, or where several attributes of the
2.784 + * same file are required at the same time, then the {@link
2.785 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
2.786 + * Files.readAttributes} method may be used.
2.787 + *
2.788 + * @return <code>true</code> if and only if the file denoted by this
2.789 + * abstract pathname exists <em>and</em> is a directory;
2.790 + * <code>false</code> otherwise
2.791 + *
2.792 + * @throws SecurityException
2.793 + * If a security manager exists and its <code>{@link
2.794 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.795 + * method denies read access to the file
2.796 + */
2.797 + public boolean isDirectory() {
2.798 + SecurityManager security = System.getSecurityManager();
2.799 + if (security != null) {
2.800 + security.checkRead(path);
2.801 + }
2.802 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
2.803 + != 0);
2.804 + }
2.805 +
2.806 + /**
2.807 + * Tests whether the file denoted by this abstract pathname is a normal
2.808 + * file. A file is <em>normal</em> if it is not a directory and, in
2.809 + * addition, satisfies other system-dependent criteria. Any non-directory
2.810 + * file created by a Java application is guaranteed to be a normal file.
2.811 + *
2.812 + * <p> Where it is required to distinguish an I/O exception from the case
2.813 + * that the file is not a normal file, or where several attributes of the
2.814 + * same file are required at the same time, then the {@link
2.815 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
2.816 + * Files.readAttributes} method may be used.
2.817 + *
2.818 + * @return <code>true</code> if and only if the file denoted by this
2.819 + * abstract pathname exists <em>and</em> is a normal file;
2.820 + * <code>false</code> otherwise
2.821 + *
2.822 + * @throws SecurityException
2.823 + * If a security manager exists and its <code>{@link
2.824 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.825 + * method denies read access to the file
2.826 + */
2.827 + public boolean isFile() {
2.828 + SecurityManager security = System.getSecurityManager();
2.829 + if (security != null) {
2.830 + security.checkRead(path);
2.831 + }
2.832 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
2.833 + }
2.834 +
2.835 + /**
2.836 + * Tests whether the file named by this abstract pathname is a hidden
2.837 + * file. The exact definition of <em>hidden</em> is system-dependent. On
2.838 + * UNIX systems, a file is considered to be hidden if its name begins with
2.839 + * a period character (<code>'.'</code>). On Microsoft Windows systems, a file is
2.840 + * considered to be hidden if it has been marked as such in the filesystem.
2.841 + *
2.842 + * @return <code>true</code> if and only if the file denoted by this
2.843 + * abstract pathname is hidden according to the conventions of the
2.844 + * underlying platform
2.845 + *
2.846 + * @throws SecurityException
2.847 + * If a security manager exists and its <code>{@link
2.848 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.849 + * method denies read access to the file
2.850 + *
2.851 + * @since 1.2
2.852 + */
2.853 + public boolean isHidden() {
2.854 + SecurityManager security = System.getSecurityManager();
2.855 + if (security != null) {
2.856 + security.checkRead(path);
2.857 + }
2.858 + return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
2.859 + }
2.860 +
2.861 + /**
2.862 + * Returns the time that the file denoted by this abstract pathname was
2.863 + * last modified.
2.864 + *
2.865 + * <p> Where it is required to distinguish an I/O exception from the case
2.866 + * where {@code 0L} is returned, or where several attributes of the
2.867 + * same file are required at the same time, or where the time of last
2.868 + * access or the creation time are required, then the {@link
2.869 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
2.870 + * Files.readAttributes} method may be used.
2.871 + *
2.872 + * @return A <code>long</code> value representing the time the file was
2.873 + * last modified, measured in milliseconds since the epoch
2.874 + * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
2.875 + * file does not exist or if an I/O error occurs
2.876 + *
2.877 + * @throws SecurityException
2.878 + * If a security manager exists and its <code>{@link
2.879 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.880 + * method denies read access to the file
2.881 + */
2.882 + public long lastModified() {
2.883 + SecurityManager security = System.getSecurityManager();
2.884 + if (security != null) {
2.885 + security.checkRead(path);
2.886 + }
2.887 + return fs.getLastModifiedTime(this);
2.888 + }
2.889 +
2.890 + /**
2.891 + * Returns the length of the file denoted by this abstract pathname.
2.892 + * The return value is unspecified if this pathname denotes a directory.
2.893 + *
2.894 + * <p> Where it is required to distinguish an I/O exception from the case
2.895 + * that {@code 0L} is returned, or where several attributes of the same file
2.896 + * are required at the same time, then the {@link
2.897 + * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
2.898 + * Files.readAttributes} method may be used.
2.899 + *
2.900 + * @return The length, in bytes, of the file denoted by this abstract
2.901 + * pathname, or <code>0L</code> if the file does not exist. Some
2.902 + * operating systems may return <code>0L</code> for pathnames
2.903 + * denoting system-dependent entities such as devices or pipes.
2.904 + *
2.905 + * @throws SecurityException
2.906 + * If a security manager exists and its <code>{@link
2.907 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.908 + * method denies read access to the file
2.909 + */
2.910 + public long length() {
2.911 + SecurityManager security = System.getSecurityManager();
2.912 + if (security != null) {
2.913 + security.checkRead(path);
2.914 + }
2.915 + return fs.getLength(this);
2.916 + }
2.917 +
2.918 +
2.919 + /* -- File operations -- */
2.920 +
2.921 + /**
2.922 + * Atomically creates a new, empty file named by this abstract pathname if
2.923 + * and only if a file with this name does not yet exist. The check for the
2.924 + * existence of the file and the creation of the file if it does not exist
2.925 + * are a single operation that is atomic with respect to all other
2.926 + * filesystem activities that might affect the file.
2.927 + * <P>
2.928 + * Note: this method should <i>not</i> be used for file-locking, as
2.929 + * the resulting protocol cannot be made to work reliably. The
2.930 + * {@link java.nio.channels.FileLock FileLock}
2.931 + * facility should be used instead.
2.932 + *
2.933 + * @return <code>true</code> if the named file does not exist and was
2.934 + * successfully created; <code>false</code> if the named file
2.935 + * already exists
2.936 + *
2.937 + * @throws IOException
2.938 + * If an I/O error occurred
2.939 + *
2.940 + * @throws SecurityException
2.941 + * If a security manager exists and its <code>{@link
2.942 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.943 + * method denies write access to the file
2.944 + *
2.945 + * @since 1.2
2.946 + */
2.947 + public boolean createNewFile() throws IOException {
2.948 + SecurityManager security = System.getSecurityManager();
2.949 + if (security != null) security.checkWrite(path);
2.950 + return fs.createFileExclusively(path);
2.951 + }
2.952 +
2.953 + /**
2.954 + * Deletes the file or directory denoted by this abstract pathname. If
2.955 + * this pathname denotes a directory, then the directory must be empty in
2.956 + * order to be deleted.
2.957 + *
2.958 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
2.959 + * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
2.960 + * when a file cannot be deleted. This is useful for error reporting and to
2.961 + * diagnose why a file cannot be deleted.
2.962 + *
2.963 + * @return <code>true</code> if and only if the file or directory is
2.964 + * successfully deleted; <code>false</code> otherwise
2.965 + *
2.966 + * @throws SecurityException
2.967 + * If a security manager exists and its <code>{@link
2.968 + * java.lang.SecurityManager#checkDelete}</code> method denies
2.969 + * delete access to the file
2.970 + */
2.971 + public boolean delete() {
2.972 + SecurityManager security = System.getSecurityManager();
2.973 + if (security != null) {
2.974 + security.checkDelete(path);
2.975 + }
2.976 + return fs.delete(this);
2.977 + }
2.978 +
2.979 + /**
2.980 + * Requests that the file or directory denoted by this abstract
2.981 + * pathname be deleted when the virtual machine terminates.
2.982 + * Files (or directories) are deleted in the reverse order that
2.983 + * they are registered. Invoking this method to delete a file or
2.984 + * directory that is already registered for deletion has no effect.
2.985 + * Deletion will be attempted only for normal termination of the
2.986 + * virtual machine, as defined by the Java Language Specification.
2.987 + *
2.988 + * <p> Once deletion has been requested, it is not possible to cancel the
2.989 + * request. This method should therefore be used with care.
2.990 + *
2.991 + * <P>
2.992 + * Note: this method should <i>not</i> be used for file-locking, as
2.993 + * the resulting protocol cannot be made to work reliably. The
2.994 + * {@link java.nio.channels.FileLock FileLock}
2.995 + * facility should be used instead.
2.996 + *
2.997 + * @throws SecurityException
2.998 + * If a security manager exists and its <code>{@link
2.999 + * java.lang.SecurityManager#checkDelete}</code> method denies
2.1000 + * delete access to the file
2.1001 + *
2.1002 + * @see #delete
2.1003 + *
2.1004 + * @since 1.2
2.1005 + */
2.1006 + public void deleteOnExit() {
2.1007 + SecurityManager security = System.getSecurityManager();
2.1008 + if (security != null) {
2.1009 + security.checkDelete(path);
2.1010 + }
2.1011 + DeleteOnExitHook.add(path);
2.1012 + }
2.1013 +
2.1014 + /**
2.1015 + * Returns an array of strings naming the files and directories in the
2.1016 + * directory denoted by this abstract pathname.
2.1017 + *
2.1018 + * <p> If this abstract pathname does not denote a directory, then this
2.1019 + * method returns {@code null}. Otherwise an array of strings is
2.1020 + * returned, one for each file or directory in the directory. Names
2.1021 + * denoting the directory itself and the directory's parent directory are
2.1022 + * not included in the result. Each string is a file name rather than a
2.1023 + * complete path.
2.1024 + *
2.1025 + * <p> There is no guarantee that the name strings in the resulting array
2.1026 + * will appear in any specific order; they are not, in particular,
2.1027 + * guaranteed to appear in alphabetical order.
2.1028 + *
2.1029 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
2.1030 + * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to
2.1031 + * open a directory and iterate over the names of the files in the directory.
2.1032 + * This may use less resources when working with very large directories, and
2.1033 + * may be more responsive when working with remote directories.
2.1034 + *
2.1035 + * @return An array of strings naming the files and directories in the
2.1036 + * directory denoted by this abstract pathname. The array will be
2.1037 + * empty if the directory is empty. Returns {@code null} if
2.1038 + * this abstract pathname does not denote a directory, or if an
2.1039 + * I/O error occurs.
2.1040 + *
2.1041 + * @throws SecurityException
2.1042 + * If a security manager exists and its {@link
2.1043 + * SecurityManager#checkRead(String)} method denies read access to
2.1044 + * the directory
2.1045 + */
2.1046 + public String[] list() {
2.1047 + SecurityManager security = System.getSecurityManager();
2.1048 + if (security != null) {
2.1049 + security.checkRead(path);
2.1050 + }
2.1051 + return fs.list(this);
2.1052 + }
2.1053 +
2.1054 + /**
2.1055 + * Returns an array of strings naming the files and directories in the
2.1056 + * directory denoted by this abstract pathname that satisfy the specified
2.1057 + * filter. The behavior of this method is the same as that of the
2.1058 + * {@link #list()} method, except that the strings in the returned array
2.1059 + * must satisfy the filter. If the given {@code filter} is {@code null}
2.1060 + * then all names are accepted. Otherwise, a name satisfies the filter if
2.1061 + * and only if the value {@code true} results when the {@link
2.1062 + * FilenameFilter#accept FilenameFilter.accept(File, String)} method
2.1063 + * of the filter is invoked on this abstract pathname and the name of a
2.1064 + * file or directory in the directory that it denotes.
2.1065 + *
2.1066 + * @param filter
2.1067 + * A filename filter
2.1068 + *
2.1069 + * @return An array of strings naming the files and directories in the
2.1070 + * directory denoted by this abstract pathname that were accepted
2.1071 + * by the given {@code filter}. The array will be empty if the
2.1072 + * directory is empty or if no names were accepted by the filter.
2.1073 + * Returns {@code null} if this abstract pathname does not denote
2.1074 + * a directory, or if an I/O error occurs.
2.1075 + *
2.1076 + * @throws SecurityException
2.1077 + * If a security manager exists and its {@link
2.1078 + * SecurityManager#checkRead(String)} method denies read access to
2.1079 + * the directory
2.1080 + *
2.1081 + * @see java.nio.file.Files#newDirectoryStream(Path,String)
2.1082 + */
2.1083 + public String[] list(FilenameFilter filter) {
2.1084 + String names[] = list();
2.1085 + if ((names == null) || (filter == null)) {
2.1086 + return names;
2.1087 + }
2.1088 + List<String> v = new ArrayList<>();
2.1089 + for (int i = 0 ; i < names.length ; i++) {
2.1090 + if (filter.accept(this, names[i])) {
2.1091 + v.add(names[i]);
2.1092 + }
2.1093 + }
2.1094 + return v.toArray(new String[v.size()]);
2.1095 + }
2.1096 +
2.1097 + /**
2.1098 + * Returns an array of abstract pathnames denoting the files in the
2.1099 + * directory denoted by this abstract pathname.
2.1100 + *
2.1101 + * <p> If this abstract pathname does not denote a directory, then this
2.1102 + * method returns {@code null}. Otherwise an array of {@code File} objects
2.1103 + * is returned, one for each file or directory in the directory. Pathnames
2.1104 + * denoting the directory itself and the directory's parent directory are
2.1105 + * not included in the result. Each resulting abstract pathname is
2.1106 + * constructed from this abstract pathname using the {@link #File(File,
2.1107 + * String) File(File, String)} constructor. Therefore if this
2.1108 + * pathname is absolute then each resulting pathname is absolute; if this
2.1109 + * pathname is relative then each resulting pathname will be relative to
2.1110 + * the same directory.
2.1111 + *
2.1112 + * <p> There is no guarantee that the name strings in the resulting array
2.1113 + * will appear in any specific order; they are not, in particular,
2.1114 + * guaranteed to appear in alphabetical order.
2.1115 + *
2.1116 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
2.1117 + * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
2.1118 + * to open a directory and iterate over the names of the files in the
2.1119 + * directory. This may use less resources when working with very large
2.1120 + * directories.
2.1121 + *
2.1122 + * @return An array of abstract pathnames denoting the files and
2.1123 + * directories in the directory denoted by this abstract pathname.
2.1124 + * The array will be empty if the directory is empty. Returns
2.1125 + * {@code null} if this abstract pathname does not denote a
2.1126 + * directory, or if an I/O error occurs.
2.1127 + *
2.1128 + * @throws SecurityException
2.1129 + * If a security manager exists and its {@link
2.1130 + * SecurityManager#checkRead(String)} method denies read access to
2.1131 + * the directory
2.1132 + *
2.1133 + * @since 1.2
2.1134 + */
2.1135 + public File[] listFiles() {
2.1136 + String[] ss = list();
2.1137 + if (ss == null) return null;
2.1138 + int n = ss.length;
2.1139 + File[] fs = new File[n];
2.1140 + for (int i = 0; i < n; i++) {
2.1141 + fs[i] = new File(ss[i], this);
2.1142 + }
2.1143 + return fs;
2.1144 + }
2.1145 +
2.1146 + /**
2.1147 + * Returns an array of abstract pathnames denoting the files and
2.1148 + * directories in the directory denoted by this abstract pathname that
2.1149 + * satisfy the specified filter. The behavior of this method is the same
2.1150 + * as that of the {@link #listFiles()} method, except that the pathnames in
2.1151 + * the returned array must satisfy the filter. If the given {@code filter}
2.1152 + * is {@code null} then all pathnames are accepted. Otherwise, a pathname
2.1153 + * satisfies the filter if and only if the value {@code true} results when
2.1154 + * the {@link FilenameFilter#accept
2.1155 + * FilenameFilter.accept(File, String)} method of the filter is
2.1156 + * invoked on this abstract pathname and the name of a file or directory in
2.1157 + * the directory that it denotes.
2.1158 + *
2.1159 + * @param filter
2.1160 + * A filename filter
2.1161 + *
2.1162 + * @return An array of abstract pathnames denoting the files and
2.1163 + * directories in the directory denoted by this abstract pathname.
2.1164 + * The array will be empty if the directory is empty. Returns
2.1165 + * {@code null} if this abstract pathname does not denote a
2.1166 + * directory, or if an I/O error occurs.
2.1167 + *
2.1168 + * @throws SecurityException
2.1169 + * If a security manager exists and its {@link
2.1170 + * SecurityManager#checkRead(String)} method denies read access to
2.1171 + * the directory
2.1172 + *
2.1173 + * @since 1.2
2.1174 + * @see java.nio.file.Files#newDirectoryStream(Path,String)
2.1175 + */
2.1176 + public File[] listFiles(FilenameFilter filter) {
2.1177 + String ss[] = list();
2.1178 + if (ss == null) return null;
2.1179 + ArrayList<File> files = new ArrayList<>();
2.1180 + for (String s : ss)
2.1181 + if ((filter == null) || filter.accept(this, s))
2.1182 + files.add(new File(s, this));
2.1183 + return files.toArray(new File[files.size()]);
2.1184 + }
2.1185 +
2.1186 + /**
2.1187 + * Returns an array of abstract pathnames denoting the files and
2.1188 + * directories in the directory denoted by this abstract pathname that
2.1189 + * satisfy the specified filter. The behavior of this method is the same
2.1190 + * as that of the {@link #listFiles()} method, except that the pathnames in
2.1191 + * the returned array must satisfy the filter. If the given {@code filter}
2.1192 + * is {@code null} then all pathnames are accepted. Otherwise, a pathname
2.1193 + * satisfies the filter if and only if the value {@code true} results when
2.1194 + * the {@link FileFilter#accept FileFilter.accept(File)} method of the
2.1195 + * filter is invoked on the pathname.
2.1196 + *
2.1197 + * @param filter
2.1198 + * A file filter
2.1199 + *
2.1200 + * @return An array of abstract pathnames denoting the files and
2.1201 + * directories in the directory denoted by this abstract pathname.
2.1202 + * The array will be empty if the directory is empty. Returns
2.1203 + * {@code null} if this abstract pathname does not denote a
2.1204 + * directory, or if an I/O error occurs.
2.1205 + *
2.1206 + * @throws SecurityException
2.1207 + * If a security manager exists and its {@link
2.1208 + * SecurityManager#checkRead(String)} method denies read access to
2.1209 + * the directory
2.1210 + *
2.1211 + * @since 1.2
2.1212 + * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter)
2.1213 + */
2.1214 + public File[] listFiles(FileFilter filter) {
2.1215 + String ss[] = list();
2.1216 + if (ss == null) return null;
2.1217 + ArrayList<File> files = new ArrayList<>();
2.1218 + for (String s : ss) {
2.1219 + File f = new File(s, this);
2.1220 + if ((filter == null) || filter.accept(f))
2.1221 + files.add(f);
2.1222 + }
2.1223 + return files.toArray(new File[files.size()]);
2.1224 + }
2.1225 +
2.1226 + /**
2.1227 + * Creates the directory named by this abstract pathname.
2.1228 + *
2.1229 + * @return <code>true</code> if and only if the directory was
2.1230 + * created; <code>false</code> otherwise
2.1231 + *
2.1232 + * @throws SecurityException
2.1233 + * If a security manager exists and its <code>{@link
2.1234 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1235 + * method does not permit the named directory to be created
2.1236 + */
2.1237 + public boolean mkdir() {
2.1238 + SecurityManager security = System.getSecurityManager();
2.1239 + if (security != null) {
2.1240 + security.checkWrite(path);
2.1241 + }
2.1242 + return fs.createDirectory(this);
2.1243 + }
2.1244 +
2.1245 + /**
2.1246 + * Creates the directory named by this abstract pathname, including any
2.1247 + * necessary but nonexistent parent directories. Note that if this
2.1248 + * operation fails it may have succeeded in creating some of the necessary
2.1249 + * parent directories.
2.1250 + *
2.1251 + * @return <code>true</code> if and only if the directory was created,
2.1252 + * along with all necessary parent directories; <code>false</code>
2.1253 + * otherwise
2.1254 + *
2.1255 + * @throws SecurityException
2.1256 + * If a security manager exists and its <code>{@link
2.1257 + * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
2.1258 + * method does not permit verification of the existence of the
2.1259 + * named directory and all necessary parent directories; or if
2.1260 + * the <code>{@link
2.1261 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1262 + * method does not permit the named directory and all necessary
2.1263 + * parent directories to be created
2.1264 + */
2.1265 + public boolean mkdirs() {
2.1266 + if (exists()) {
2.1267 + return false;
2.1268 + }
2.1269 + if (mkdir()) {
2.1270 + return true;
2.1271 + }
2.1272 + File canonFile = null;
2.1273 + try {
2.1274 + canonFile = getCanonicalFile();
2.1275 + } catch (IOException e) {
2.1276 + return false;
2.1277 + }
2.1278 +
2.1279 + File parent = canonFile.getParentFile();
2.1280 + return (parent != null && (parent.mkdirs() || parent.exists()) &&
2.1281 + canonFile.mkdir());
2.1282 + }
2.1283 +
2.1284 + /**
2.1285 + * Renames the file denoted by this abstract pathname.
2.1286 + *
2.1287 + * <p> Many aspects of the behavior of this method are inherently
2.1288 + * platform-dependent: The rename operation might not be able to move a
2.1289 + * file from one filesystem to another, it might not be atomic, and it
2.1290 + * might not succeed if a file with the destination abstract pathname
2.1291 + * already exists. The return value should always be checked to make sure
2.1292 + * that the rename operation was successful.
2.1293 + *
2.1294 + * <p> Note that the {@link java.nio.file.Files} class defines the {@link
2.1295 + * java.nio.file.Files#move move} method to move or rename a file in a
2.1296 + * platform independent manner.
2.1297 + *
2.1298 + * @param dest The new abstract pathname for the named file
2.1299 + *
2.1300 + * @return <code>true</code> if and only if the renaming succeeded;
2.1301 + * <code>false</code> otherwise
2.1302 + *
2.1303 + * @throws SecurityException
2.1304 + * If a security manager exists and its <code>{@link
2.1305 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1306 + * method denies write access to either the old or new pathnames
2.1307 + *
2.1308 + * @throws NullPointerException
2.1309 + * If parameter <code>dest</code> is <code>null</code>
2.1310 + */
2.1311 + public boolean renameTo(File dest) {
2.1312 + SecurityManager security = System.getSecurityManager();
2.1313 + if (security != null) {
2.1314 + security.checkWrite(path);
2.1315 + security.checkWrite(dest.path);
2.1316 + }
2.1317 + return fs.rename(this, dest);
2.1318 + }
2.1319 +
2.1320 + /**
2.1321 + * Sets the last-modified time of the file or directory named by this
2.1322 + * abstract pathname.
2.1323 + *
2.1324 + * <p> All platforms support file-modification times to the nearest second,
2.1325 + * but some provide more precision. The argument will be truncated to fit
2.1326 + * the supported precision. If the operation succeeds and no intervening
2.1327 + * operations on the file take place, then the next invocation of the
2.1328 + * <code>{@link #lastModified}</code> method will return the (possibly
2.1329 + * truncated) <code>time</code> argument that was passed to this method.
2.1330 + *
2.1331 + * @param time The new last-modified time, measured in milliseconds since
2.1332 + * the epoch (00:00:00 GMT, January 1, 1970)
2.1333 + *
2.1334 + * @return <code>true</code> if and only if the operation succeeded;
2.1335 + * <code>false</code> otherwise
2.1336 + *
2.1337 + * @throws IllegalArgumentException If the argument is negative
2.1338 + *
2.1339 + * @throws SecurityException
2.1340 + * If a security manager exists and its <code>{@link
2.1341 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1342 + * method denies write access to the named file
2.1343 + *
2.1344 + * @since 1.2
2.1345 + */
2.1346 + public boolean setLastModified(long time) {
2.1347 + if (time < 0) throw new IllegalArgumentException("Negative time");
2.1348 + SecurityManager security = System.getSecurityManager();
2.1349 + if (security != null) {
2.1350 + security.checkWrite(path);
2.1351 + }
2.1352 + return fs.setLastModifiedTime(this, time);
2.1353 + }
2.1354 +
2.1355 + /**
2.1356 + * Marks the file or directory named by this abstract pathname so that
2.1357 + * only read operations are allowed. After invoking this method the file
2.1358 + * or directory is guaranteed not to change until it is either deleted or
2.1359 + * marked to allow write access. Whether or not a read-only file or
2.1360 + * directory may be deleted depends upon the underlying system.
2.1361 + *
2.1362 + * @return <code>true</code> if and only if the operation succeeded;
2.1363 + * <code>false</code> otherwise
2.1364 + *
2.1365 + * @throws SecurityException
2.1366 + * If a security manager exists and its <code>{@link
2.1367 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1368 + * method denies write access to the named file
2.1369 + *
2.1370 + * @since 1.2
2.1371 + */
2.1372 + public boolean setReadOnly() {
2.1373 + SecurityManager security = System.getSecurityManager();
2.1374 + if (security != null) {
2.1375 + security.checkWrite(path);
2.1376 + }
2.1377 + return fs.setReadOnly(this);
2.1378 + }
2.1379 +
2.1380 + /**
2.1381 + * Sets the owner's or everybody's write permission for this abstract
2.1382 + * pathname.
2.1383 + *
2.1384 + * <p> The {@link java.nio.file.Files} class defines methods that operate on
2.1385 + * file attributes including file permissions. This may be used when finer
2.1386 + * manipulation of file permissions is required.
2.1387 + *
2.1388 + * @param writable
2.1389 + * If <code>true</code>, sets the access permission to allow write
2.1390 + * operations; if <code>false</code> to disallow write operations
2.1391 + *
2.1392 + * @param ownerOnly
2.1393 + * If <code>true</code>, the write permission applies only to the
2.1394 + * owner's write permission; otherwise, it applies to everybody. If
2.1395 + * the underlying file system can not distinguish the owner's write
2.1396 + * permission from that of others, then the permission will apply to
2.1397 + * everybody, regardless of this value.
2.1398 + *
2.1399 + * @return <code>true</code> if and only if the operation succeeded. The
2.1400 + * operation will fail if the user does not have permission to change
2.1401 + * the access permissions of this abstract pathname.
2.1402 + *
2.1403 + * @throws SecurityException
2.1404 + * If a security manager exists and its <code>{@link
2.1405 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1406 + * method denies write access to the named file
2.1407 + *
2.1408 + * @since 1.6
2.1409 + */
2.1410 + public boolean setWritable(boolean writable, boolean ownerOnly) {
2.1411 + SecurityManager security = System.getSecurityManager();
2.1412 + if (security != null) {
2.1413 + security.checkWrite(path);
2.1414 + }
2.1415 + return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
2.1416 + }
2.1417 +
2.1418 + /**
2.1419 + * A convenience method to set the owner's write permission for this abstract
2.1420 + * pathname.
2.1421 + *
2.1422 + * <p> An invocation of this method of the form <tt>file.setWritable(arg)</tt>
2.1423 + * behaves in exactly the same way as the invocation
2.1424 + *
2.1425 + * <pre>
2.1426 + * file.setWritable(arg, true) </pre>
2.1427 + *
2.1428 + * @param writable
2.1429 + * If <code>true</code>, sets the access permission to allow write
2.1430 + * operations; if <code>false</code> to disallow write operations
2.1431 + *
2.1432 + * @return <code>true</code> if and only if the operation succeeded. The
2.1433 + * operation will fail if the user does not have permission to
2.1434 + * change the access permissions of this abstract pathname.
2.1435 + *
2.1436 + * @throws SecurityException
2.1437 + * If a security manager exists and its <code>{@link
2.1438 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1439 + * method denies write access to the file
2.1440 + *
2.1441 + * @since 1.6
2.1442 + */
2.1443 + public boolean setWritable(boolean writable) {
2.1444 + return setWritable(writable, true);
2.1445 + }
2.1446 +
2.1447 + /**
2.1448 + * Sets the owner's or everybody's read permission for this abstract
2.1449 + * pathname.
2.1450 + *
2.1451 + * <p> The {@link java.nio.file.Files} class defines methods that operate on
2.1452 + * file attributes including file permissions. This may be used when finer
2.1453 + * manipulation of file permissions is required.
2.1454 + *
2.1455 + * @param readable
2.1456 + * If <code>true</code>, sets the access permission to allow read
2.1457 + * operations; if <code>false</code> to disallow read operations
2.1458 + *
2.1459 + * @param ownerOnly
2.1460 + * If <code>true</code>, the read permission applies only to the
2.1461 + * owner's read permission; otherwise, it applies to everybody. If
2.1462 + * the underlying file system can not distinguish the owner's read
2.1463 + * permission from that of others, then the permission will apply to
2.1464 + * everybody, regardless of this value.
2.1465 + *
2.1466 + * @return <code>true</code> if and only if the operation succeeded. The
2.1467 + * operation will fail if the user does not have permission to
2.1468 + * change the access permissions of this abstract pathname. If
2.1469 + * <code>readable</code> is <code>false</code> and the underlying
2.1470 + * file system does not implement a read permission, then the
2.1471 + * operation will fail.
2.1472 + *
2.1473 + * @throws SecurityException
2.1474 + * If a security manager exists and its <code>{@link
2.1475 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1476 + * method denies write access to the file
2.1477 + *
2.1478 + * @since 1.6
2.1479 + */
2.1480 + public boolean setReadable(boolean readable, boolean ownerOnly) {
2.1481 + SecurityManager security = System.getSecurityManager();
2.1482 + if (security != null) {
2.1483 + security.checkWrite(path);
2.1484 + }
2.1485 + return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
2.1486 + }
2.1487 +
2.1488 + /**
2.1489 + * A convenience method to set the owner's read permission for this abstract
2.1490 + * pathname.
2.1491 + *
2.1492 + * <p>An invocation of this method of the form <tt>file.setReadable(arg)</tt>
2.1493 + * behaves in exactly the same way as the invocation
2.1494 + *
2.1495 + * <pre>
2.1496 + * file.setReadable(arg, true) </pre>
2.1497 + *
2.1498 + * @param readable
2.1499 + * If <code>true</code>, sets the access permission to allow read
2.1500 + * operations; if <code>false</code> to disallow read operations
2.1501 + *
2.1502 + * @return <code>true</code> if and only if the operation succeeded. The
2.1503 + * operation will fail if the user does not have permission to
2.1504 + * change the access permissions of this abstract pathname. If
2.1505 + * <code>readable</code> is <code>false</code> and the underlying
2.1506 + * file system does not implement a read permission, then the
2.1507 + * operation will fail.
2.1508 + *
2.1509 + * @throws SecurityException
2.1510 + * If a security manager exists and its <code>{@link
2.1511 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1512 + * method denies write access to the file
2.1513 + *
2.1514 + * @since 1.6
2.1515 + */
2.1516 + public boolean setReadable(boolean readable) {
2.1517 + return setReadable(readable, true);
2.1518 + }
2.1519 +
2.1520 + /**
2.1521 + * Sets the owner's or everybody's execute permission for this abstract
2.1522 + * pathname.
2.1523 + *
2.1524 + * <p> The {@link java.nio.file.Files} class defines methods that operate on
2.1525 + * file attributes including file permissions. This may be used when finer
2.1526 + * manipulation of file permissions is required.
2.1527 + *
2.1528 + * @param executable
2.1529 + * If <code>true</code>, sets the access permission to allow execute
2.1530 + * operations; if <code>false</code> to disallow execute operations
2.1531 + *
2.1532 + * @param ownerOnly
2.1533 + * If <code>true</code>, the execute permission applies only to the
2.1534 + * owner's execute permission; otherwise, it applies to everybody.
2.1535 + * If the underlying file system can not distinguish the owner's
2.1536 + * execute permission from that of others, then the permission will
2.1537 + * apply to everybody, regardless of this value.
2.1538 + *
2.1539 + * @return <code>true</code> if and only if the operation succeeded. The
2.1540 + * operation will fail if the user does not have permission to
2.1541 + * change the access permissions of this abstract pathname. If
2.1542 + * <code>executable</code> is <code>false</code> and the underlying
2.1543 + * file system does not implement an execute permission, then the
2.1544 + * operation will fail.
2.1545 + *
2.1546 + * @throws SecurityException
2.1547 + * If a security manager exists and its <code>{@link
2.1548 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1549 + * method denies write access to the file
2.1550 + *
2.1551 + * @since 1.6
2.1552 + */
2.1553 + public boolean setExecutable(boolean executable, boolean ownerOnly) {
2.1554 + SecurityManager security = System.getSecurityManager();
2.1555 + if (security != null) {
2.1556 + security.checkWrite(path);
2.1557 + }
2.1558 + return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
2.1559 + }
2.1560 +
2.1561 + /**
2.1562 + * A convenience method to set the owner's execute permission for this abstract
2.1563 + * pathname.
2.1564 + *
2.1565 + * <p>An invocation of this method of the form <tt>file.setExcutable(arg)</tt>
2.1566 + * behaves in exactly the same way as the invocation
2.1567 + *
2.1568 + * <pre>
2.1569 + * file.setExecutable(arg, true) </pre>
2.1570 + *
2.1571 + * @param executable
2.1572 + * If <code>true</code>, sets the access permission to allow execute
2.1573 + * operations; if <code>false</code> to disallow execute operations
2.1574 + *
2.1575 + * @return <code>true</code> if and only if the operation succeeded. The
2.1576 + * operation will fail if the user does not have permission to
2.1577 + * change the access permissions of this abstract pathname. If
2.1578 + * <code>executable</code> is <code>false</code> and the underlying
2.1579 + * file system does not implement an excute permission, then the
2.1580 + * operation will fail.
2.1581 + *
2.1582 + * @throws SecurityException
2.1583 + * If a security manager exists and its <code>{@link
2.1584 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1585 + * method denies write access to the file
2.1586 + *
2.1587 + * @since 1.6
2.1588 + */
2.1589 + public boolean setExecutable(boolean executable) {
2.1590 + return setExecutable(executable, true);
2.1591 + }
2.1592 +
2.1593 + /**
2.1594 + * Tests whether the application can execute the file denoted by this
2.1595 + * abstract pathname.
2.1596 + *
2.1597 + * @return <code>true</code> if and only if the abstract pathname exists
2.1598 + * <em>and</em> the application is allowed to execute the file
2.1599 + *
2.1600 + * @throws SecurityException
2.1601 + * If a security manager exists and its <code>{@link
2.1602 + * java.lang.SecurityManager#checkExec(java.lang.String)}</code>
2.1603 + * method denies execute access to the file
2.1604 + *
2.1605 + * @since 1.6
2.1606 + */
2.1607 + public boolean canExecute() {
2.1608 + SecurityManager security = System.getSecurityManager();
2.1609 + if (security != null) {
2.1610 + security.checkExec(path);
2.1611 + }
2.1612 + return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
2.1613 + }
2.1614 +
2.1615 +
2.1616 + /* -- Filesystem interface -- */
2.1617 +
2.1618 + /**
2.1619 + * List the available filesystem roots.
2.1620 + *
2.1621 + * <p> A particular Java platform may support zero or more
2.1622 + * hierarchically-organized file systems. Each file system has a
2.1623 + * {@code root} directory from which all other files in that file system
2.1624 + * can be reached. Windows platforms, for example, have a root directory
2.1625 + * for each active drive; UNIX platforms have a single root directory,
2.1626 + * namely {@code "/"}. The set of available filesystem roots is affected
2.1627 + * by various system-level operations such as the insertion or ejection of
2.1628 + * removable media and the disconnecting or unmounting of physical or
2.1629 + * virtual disk drives.
2.1630 + *
2.1631 + * <p> This method returns an array of {@code File} objects that denote the
2.1632 + * root directories of the available filesystem roots. It is guaranteed
2.1633 + * that the canonical pathname of any file physically present on the local
2.1634 + * machine will begin with one of the roots returned by this method.
2.1635 + *
2.1636 + * <p> The canonical pathname of a file that resides on some other machine
2.1637 + * and is accessed via a remote-filesystem protocol such as SMB or NFS may
2.1638 + * or may not begin with one of the roots returned by this method. If the
2.1639 + * pathname of a remote file is syntactically indistinguishable from the
2.1640 + * pathname of a local file then it will begin with one of the roots
2.1641 + * returned by this method. Thus, for example, {@code File} objects
2.1642 + * denoting the root directories of the mapped network drives of a Windows
2.1643 + * platform will be returned by this method, while {@code File} objects
2.1644 + * containing UNC pathnames will not be returned by this method.
2.1645 + *
2.1646 + * <p> Unlike most methods in this class, this method does not throw
2.1647 + * security exceptions. If a security manager exists and its {@link
2.1648 + * SecurityManager#checkRead(String)} method denies read access to a
2.1649 + * particular root directory, then that directory will not appear in the
2.1650 + * result.
2.1651 + *
2.1652 + * @return An array of {@code File} objects denoting the available
2.1653 + * filesystem roots, or {@code null} if the set of roots could not
2.1654 + * be determined. The array will be empty if there are no
2.1655 + * filesystem roots.
2.1656 + *
2.1657 + * @since 1.2
2.1658 + * @see java.nio.file.FileStore
2.1659 + */
2.1660 + public static File[] listRoots() {
2.1661 + return fs.listRoots();
2.1662 + }
2.1663 +
2.1664 +
2.1665 + /* -- Disk usage -- */
2.1666 +
2.1667 + /**
2.1668 + * Returns the size of the partition <a href="#partName">named</a> by this
2.1669 + * abstract pathname.
2.1670 + *
2.1671 + * @return The size, in bytes, of the partition or <tt>0L</tt> if this
2.1672 + * abstract pathname does not name a partition
2.1673 + *
2.1674 + * @throws SecurityException
2.1675 + * If a security manager has been installed and it denies
2.1676 + * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
2.1677 + * or its {@link SecurityManager#checkRead(String)} method denies
2.1678 + * read access to the file named by this abstract pathname
2.1679 + *
2.1680 + * @since 1.6
2.1681 + */
2.1682 + public long getTotalSpace() {
2.1683 + SecurityManager sm = System.getSecurityManager();
2.1684 + if (sm != null) {
2.1685 + sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
2.1686 + sm.checkRead(path);
2.1687 + }
2.1688 + return fs.getSpace(this, FileSystem.SPACE_TOTAL);
2.1689 + }
2.1690 +
2.1691 + /**
2.1692 + * Returns the number of unallocated bytes in the partition <a
2.1693 + * href="#partName">named</a> by this abstract path name.
2.1694 + *
2.1695 + * <p> The returned number of unallocated bytes is a hint, but not
2.1696 + * a guarantee, that it is possible to use most or any of these
2.1697 + * bytes. The number of unallocated bytes is most likely to be
2.1698 + * accurate immediately after this call. It is likely to be made
2.1699 + * inaccurate by any external I/O operations including those made
2.1700 + * on the system outside of this virtual machine. This method
2.1701 + * makes no guarantee that write operations to this file system
2.1702 + * will succeed.
2.1703 + *
2.1704 + * @return The number of unallocated bytes on the partition <tt>0L</tt>
2.1705 + * if the abstract pathname does not name a partition. This
2.1706 + * value will be less than or equal to the total file system size
2.1707 + * returned by {@link #getTotalSpace}.
2.1708 + *
2.1709 + * @throws SecurityException
2.1710 + * If a security manager has been installed and it denies
2.1711 + * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
2.1712 + * or its {@link SecurityManager#checkRead(String)} method denies
2.1713 + * read access to the file named by this abstract pathname
2.1714 + *
2.1715 + * @since 1.6
2.1716 + */
2.1717 + public long getFreeSpace() {
2.1718 + SecurityManager sm = System.getSecurityManager();
2.1719 + if (sm != null) {
2.1720 + sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
2.1721 + sm.checkRead(path);
2.1722 + }
2.1723 + return fs.getSpace(this, FileSystem.SPACE_FREE);
2.1724 + }
2.1725 +
2.1726 + /**
2.1727 + * Returns the number of bytes available to this virtual machine on the
2.1728 + * partition <a href="#partName">named</a> by this abstract pathname. When
2.1729 + * possible, this method checks for write permissions and other operating
2.1730 + * system restrictions and will therefore usually provide a more accurate
2.1731 + * estimate of how much new data can actually be written than {@link
2.1732 + * #getFreeSpace}.
2.1733 + *
2.1734 + * <p> The returned number of available bytes is a hint, but not a
2.1735 + * guarantee, that it is possible to use most or any of these bytes. The
2.1736 + * number of unallocated bytes is most likely to be accurate immediately
2.1737 + * after this call. It is likely to be made inaccurate by any external
2.1738 + * I/O operations including those made on the system outside of this
2.1739 + * virtual machine. This method makes no guarantee that write operations
2.1740 + * to this file system will succeed.
2.1741 + *
2.1742 + * @return The number of available bytes on the partition or <tt>0L</tt>
2.1743 + * if the abstract pathname does not name a partition. On
2.1744 + * systems where this information is not available, this method
2.1745 + * will be equivalent to a call to {@link #getFreeSpace}.
2.1746 + *
2.1747 + * @throws SecurityException
2.1748 + * If a security manager has been installed and it denies
2.1749 + * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
2.1750 + * or its {@link SecurityManager#checkRead(String)} method denies
2.1751 + * read access to the file named by this abstract pathname
2.1752 + *
2.1753 + * @since 1.6
2.1754 + */
2.1755 + public long getUsableSpace() {
2.1756 + SecurityManager sm = System.getSecurityManager();
2.1757 + if (sm != null) {
2.1758 + sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
2.1759 + sm.checkRead(path);
2.1760 + }
2.1761 + return fs.getSpace(this, FileSystem.SPACE_USABLE);
2.1762 + }
2.1763 +
2.1764 + /* -- Temporary files -- */
2.1765 +
2.1766 + private static class TempDirectory {
2.1767 + private TempDirectory() { }
2.1768 +
2.1769 + // temporary directory location
2.1770 + private static final File tmpdir = new File(fs.normalize(AccessController
2.1771 + .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
2.1772 + static File location() {
2.1773 + return tmpdir;
2.1774 + }
2.1775 +
2.1776 + // file name generation
2.1777 + private static final SecureRandom random = new SecureRandom();
2.1778 + static File generateFile(String prefix, String suffix, File dir) {
2.1779 + long n = random.nextLong();
2.1780 + if (n == Long.MIN_VALUE) {
2.1781 + n = 0; // corner case
2.1782 + } else {
2.1783 + n = Math.abs(n);
2.1784 + }
2.1785 + return new File(dir, prefix + Long.toString(n) + suffix);
2.1786 + }
2.1787 + }
2.1788 +
2.1789 + /**
2.1790 + * <p> Creates a new empty file in the specified directory, using the
2.1791 + * given prefix and suffix strings to generate its name. If this method
2.1792 + * returns successfully then it is guaranteed that:
2.1793 + *
2.1794 + * <ol>
2.1795 + * <li> The file denoted by the returned abstract pathname did not exist
2.1796 + * before this method was invoked, and
2.1797 + * <li> Neither this method nor any of its variants will return the same
2.1798 + * abstract pathname again in the current invocation of the virtual
2.1799 + * machine.
2.1800 + * </ol>
2.1801 + *
2.1802 + * This method provides only part of a temporary-file facility. To arrange
2.1803 + * for a file created by this method to be deleted automatically, use the
2.1804 + * <code>{@link #deleteOnExit}</code> method.
2.1805 + *
2.1806 + * <p> The <code>prefix</code> argument must be at least three characters
2.1807 + * long. It is recommended that the prefix be a short, meaningful string
2.1808 + * such as <code>"hjb"</code> or <code>"mail"</code>. The
2.1809 + * <code>suffix</code> argument may be <code>null</code>, in which case the
2.1810 + * suffix <code>".tmp"</code> will be used.
2.1811 + *
2.1812 + * <p> To create the new file, the prefix and the suffix may first be
2.1813 + * adjusted to fit the limitations of the underlying platform. If the
2.1814 + * prefix is too long then it will be truncated, but its first three
2.1815 + * characters will always be preserved. If the suffix is too long then it
2.1816 + * too will be truncated, but if it begins with a period character
2.1817 + * (<code>'.'</code>) then the period and the first three characters
2.1818 + * following it will always be preserved. Once these adjustments have been
2.1819 + * made the name of the new file will be generated by concatenating the
2.1820 + * prefix, five or more internally-generated characters, and the suffix.
2.1821 + *
2.1822 + * <p> If the <code>directory</code> argument is <code>null</code> then the
2.1823 + * system-dependent default temporary-file directory will be used. The
2.1824 + * default temporary-file directory is specified by the system property
2.1825 + * <code>java.io.tmpdir</code>. On UNIX systems the default value of this
2.1826 + * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on
2.1827 + * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>. A different
2.1828 + * value may be given to this system property when the Java virtual machine
2.1829 + * is invoked, but programmatic changes to this property are not guaranteed
2.1830 + * to have any effect upon the temporary directory used by this method.
2.1831 + *
2.1832 + * @param prefix The prefix string to be used in generating the file's
2.1833 + * name; must be at least three characters long
2.1834 + *
2.1835 + * @param suffix The suffix string to be used in generating the file's
2.1836 + * name; may be <code>null</code>, in which case the
2.1837 + * suffix <code>".tmp"</code> will be used
2.1838 + *
2.1839 + * @param directory The directory in which the file is to be created, or
2.1840 + * <code>null</code> if the default temporary-file
2.1841 + * directory is to be used
2.1842 + *
2.1843 + * @return An abstract pathname denoting a newly-created empty file
2.1844 + *
2.1845 + * @throws IllegalArgumentException
2.1846 + * If the <code>prefix</code> argument contains fewer than three
2.1847 + * characters
2.1848 + *
2.1849 + * @throws IOException If a file could not be created
2.1850 + *
2.1851 + * @throws SecurityException
2.1852 + * If a security manager exists and its <code>{@link
2.1853 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1854 + * method does not allow a file to be created
2.1855 + *
2.1856 + * @since 1.2
2.1857 + */
2.1858 + public static File createTempFile(String prefix, String suffix,
2.1859 + File directory)
2.1860 + throws IOException
2.1861 + {
2.1862 + if (prefix.length() < 3)
2.1863 + throw new IllegalArgumentException("Prefix string too short");
2.1864 + if (suffix == null)
2.1865 + suffix = ".tmp";
2.1866 +
2.1867 + File tmpdir = (directory != null) ? directory : TempDirectory.location();
2.1868 + SecurityManager sm = System.getSecurityManager();
2.1869 + File f;
2.1870 + do {
2.1871 + f = TempDirectory.generateFile(prefix, suffix, tmpdir);
2.1872 + if (sm != null) {
2.1873 + try {
2.1874 + sm.checkWrite(f.getPath());
2.1875 + } catch (SecurityException se) {
2.1876 + // don't reveal temporary directory location
2.1877 + if (directory == null)
2.1878 + throw new SecurityException("Unable to create temporary file");
2.1879 + throw se;
2.1880 + }
2.1881 + }
2.1882 + } while (!fs.createFileExclusively(f.getPath()));
2.1883 + return f;
2.1884 + }
2.1885 +
2.1886 + /**
2.1887 + * Creates an empty file in the default temporary-file directory, using
2.1888 + * the given prefix and suffix to generate its name. Invoking this method
2.1889 + * is equivalent to invoking <code>{@link #createTempFile(java.lang.String,
2.1890 + * java.lang.String, java.io.File)
2.1891 + * createTempFile(prefix, suffix, null)}</code>.
2.1892 + *
2.1893 + * <p> The {@link
2.1894 + * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[])
2.1895 + * Files.createTempFile} method provides an alternative method to create an
2.1896 + * empty file in the temporary-file directory. Files created by that method
2.1897 + * may have more restrictive access permissions to files created by this
2.1898 + * method and so may be more suited to security-sensitive applications.
2.1899 + *
2.1900 + * @param prefix The prefix string to be used in generating the file's
2.1901 + * name; must be at least three characters long
2.1902 + *
2.1903 + * @param suffix The suffix string to be used in generating the file's
2.1904 + * name; may be <code>null</code>, in which case the
2.1905 + * suffix <code>".tmp"</code> will be used
2.1906 + *
2.1907 + * @return An abstract pathname denoting a newly-created empty file
2.1908 + *
2.1909 + * @throws IllegalArgumentException
2.1910 + * If the <code>prefix</code> argument contains fewer than three
2.1911 + * characters
2.1912 + *
2.1913 + * @throws IOException If a file could not be created
2.1914 + *
2.1915 + * @throws SecurityException
2.1916 + * If a security manager exists and its <code>{@link
2.1917 + * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
2.1918 + * method does not allow a file to be created
2.1919 + *
2.1920 + * @since 1.2
2.1921 + * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[])
2.1922 + */
2.1923 + public static File createTempFile(String prefix, String suffix)
2.1924 + throws IOException
2.1925 + {
2.1926 + return createTempFile(prefix, suffix, null);
2.1927 + }
2.1928 +
2.1929 + /* -- Basic infrastructure -- */
2.1930 +
2.1931 + /**
2.1932 + * Compares two abstract pathnames lexicographically. The ordering
2.1933 + * defined by this method depends upon the underlying system. On UNIX
2.1934 + * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
2.1935 + * systems it is not.
2.1936 + *
2.1937 + * @param pathname The abstract pathname to be compared to this abstract
2.1938 + * pathname
2.1939 + *
2.1940 + * @return Zero if the argument is equal to this abstract pathname, a
2.1941 + * value less than zero if this abstract pathname is
2.1942 + * lexicographically less than the argument, or a value greater
2.1943 + * than zero if this abstract pathname is lexicographically
2.1944 + * greater than the argument
2.1945 + *
2.1946 + * @since 1.2
2.1947 + */
2.1948 + public int compareTo(File pathname) {
2.1949 + return fs.compare(this, pathname);
2.1950 + }
2.1951 +
2.1952 + /**
2.1953 + * Tests this abstract pathname for equality with the given object.
2.1954 + * Returns <code>true</code> if and only if the argument is not
2.1955 + * <code>null</code> and is an abstract pathname that denotes the same file
2.1956 + * or directory as this abstract pathname. Whether or not two abstract
2.1957 + * pathnames are equal depends upon the underlying system. On UNIX
2.1958 + * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
2.1959 + * systems it is not.
2.1960 + *
2.1961 + * @param obj The object to be compared with this abstract pathname
2.1962 + *
2.1963 + * @return <code>true</code> if and only if the objects are the same;
2.1964 + * <code>false</code> otherwise
2.1965 + */
2.1966 + public boolean equals(Object obj) {
2.1967 + if ((obj != null) && (obj instanceof File)) {
2.1968 + return compareTo((File)obj) == 0;
2.1969 + }
2.1970 + return false;
2.1971 + }
2.1972 +
2.1973 + /**
2.1974 + * Computes a hash code for this abstract pathname. Because equality of
2.1975 + * abstract pathnames is inherently system-dependent, so is the computation
2.1976 + * of their hash codes. On UNIX systems, the hash code of an abstract
2.1977 + * pathname is equal to the exclusive <em>or</em> of the hash code
2.1978 + * of its pathname string and the decimal value
2.1979 + * <code>1234321</code>. On Microsoft Windows systems, the hash
2.1980 + * code is equal to the exclusive <em>or</em> of the hash code of
2.1981 + * its pathname string converted to lower case and the decimal
2.1982 + * value <code>1234321</code>. Locale is not taken into account on
2.1983 + * lowercasing the pathname string.
2.1984 + *
2.1985 + * @return A hash code for this abstract pathname
2.1986 + */
2.1987 + public int hashCode() {
2.1988 + return fs.hashCode(this);
2.1989 + }
2.1990 +
2.1991 + /**
2.1992 + * Returns the pathname string of this abstract pathname. This is just the
2.1993 + * string returned by the <code>{@link #getPath}</code> method.
2.1994 + *
2.1995 + * @return The string form of this abstract pathname
2.1996 + */
2.1997 + public String toString() {
2.1998 + return getPath();
2.1999 + }
2.2000 +
2.2001 + /**
2.2002 + * WriteObject is called to save this filename.
2.2003 + * The separator character is saved also so it can be replaced
2.2004 + * in case the path is reconstituted on a different host type.
2.2005 + * <p>
2.2006 + * @serialData Default fields followed by separator character.
2.2007 + */
2.2008 + private synchronized void writeObject(java.io.ObjectOutputStream s)
2.2009 + throws IOException
2.2010 + {
2.2011 + s.defaultWriteObject();
2.2012 + s.writeChar(this.separatorChar); // Add the separator character
2.2013 + }
2.2014 +
2.2015 + /**
2.2016 + * readObject is called to restore this filename.
2.2017 + * The original separator character is read. If it is different
2.2018 + * than the separator character on this system, then the old separator
2.2019 + * is replaced by the local separator.
2.2020 + */
2.2021 + private synchronized void readObject(java.io.ObjectInputStream s)
2.2022 + throws IOException, ClassNotFoundException
2.2023 + {
2.2024 + ObjectInputStream.GetField fields = s.readFields();
2.2025 + String pathField = (String)fields.get("path", null);
2.2026 + char sep = s.readChar(); // read the previous separator char
2.2027 + if (sep != separatorChar)
2.2028 + pathField = pathField.replace(sep, separatorChar);
2.2029 + this.path = fs.normalize(pathField);
2.2030 + this.prefixLength = fs.prefixLength(this.path);
2.2031 + }
2.2032 +
2.2033 + /** use serialVersionUID from JDK 1.0.2 for interoperability */
2.2034 + private static final long serialVersionUID = 301077366599181567L;
2.2035 +
2.2036 + // -- Integration with java.nio.file --
2.2037 +
2.2038 + private volatile transient Path filePath;
2.2039 +
2.2040 + /**
2.2041 + * Returns a {@link Path java.nio.file.Path} object constructed from the
2.2042 + * this abstract path. The resulting {@code Path} is associated with the
2.2043 + * {@link java.nio.file.FileSystems#getDefault default-filesystem}.
2.2044 + *
2.2045 + * <p> The first invocation of this method works as if invoking it were
2.2046 + * equivalent to evaluating the expression:
2.2047 + * <blockquote><pre>
2.2048 + * {@link java.nio.file.FileSystems#getDefault FileSystems.getDefault}().{@link
2.2049 + * java.nio.file.FileSystem#getPath getPath}(this.{@link #getPath getPath}());
2.2050 + * </pre></blockquote>
2.2051 + * Subsequent invocations of this method return the same {@code Path}.
2.2052 + *
2.2053 + * <p> If this abstract pathname is the empty abstract pathname then this
2.2054 + * method returns a {@code Path} that may be used to access the current
2.2055 + * user directory.
2.2056 + *
2.2057 + * @return a {@code Path} constructed from this abstract path
2.2058 + *
2.2059 + * @throws java.nio.file.InvalidPathException
2.2060 + * if a {@code Path} object cannot be constructed from the abstract
2.2061 + * path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
2.2062 + *
2.2063 + * @since 1.7
2.2064 + * @see Path#toFile
2.2065 + */
2.2066 + public Path toPath() {
2.2067 + Path result = filePath;
2.2068 + if (result == null) {
2.2069 + synchronized (this) {
2.2070 + result = filePath;
2.2071 + if (result == null) {
2.2072 + result = FileSystems.getDefault().getPath(path);
2.2073 + filePath = result;
2.2074 + }
2.2075 + }
2.2076 + }
2.2077 + return result;
2.2078 + }
2.2079 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/emul/compact/src/main/java/java/io/FileFilter.java Sat Sep 07 13:51:24 2013 +0200
3.3 @@ -0,0 +1,50 @@
3.4 +/*
3.5 + * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3.7 + *
3.8 + * This code is free software; you can redistribute it and/or modify it
3.9 + * under the terms of the GNU General Public License version 2 only, as
3.10 + * published by the Free Software Foundation. Oracle designates this
3.11 + * particular file as subject to the "Classpath" exception as provided
3.12 + * by Oracle in the LICENSE file that accompanied this code.
3.13 + *
3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3.17 + * version 2 for more details (a copy is included in the LICENSE file that
3.18 + * accompanied this code).
3.19 + *
3.20 + * You should have received a copy of the GNU General Public License version
3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3.23 + *
3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3.25 + * or visit www.oracle.com if you need additional information or have any
3.26 + * questions.
3.27 + */
3.28 +
3.29 +package java.io;
3.30 +
3.31 +
3.32 +/**
3.33 + * A filter for abstract pathnames.
3.34 + *
3.35 + * <p> Instances of this interface may be passed to the <code>{@link
3.36 + * File#listFiles(java.io.FileFilter) listFiles(FileFilter)}</code> method
3.37 + * of the <code>{@link java.io.File}</code> class.
3.38 + *
3.39 + * @since 1.2
3.40 + */
3.41 +public interface FileFilter {
3.42 +
3.43 + /**
3.44 + * Tests whether or not the specified abstract pathname should be
3.45 + * included in a pathname list.
3.46 + *
3.47 + * @param pathname The abstract pathname to be tested
3.48 + * @return <code>true</code> if and only if <code>pathname</code>
3.49 + * should be included
3.50 + */
3.51 + boolean accept(File pathname);
3.52 +
3.53 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/emul/compact/src/main/java/java/io/FileNotFoundException.java Sat Sep 07 13:51:24 2013 +0200
4.3 @@ -0,0 +1,82 @@
4.4 +/*
4.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4.7 + *
4.8 + * This code is free software; you can redistribute it and/or modify it
4.9 + * under the terms of the GNU General Public License version 2 only, as
4.10 + * published by the Free Software Foundation. Oracle designates this
4.11 + * particular file as subject to the "Classpath" exception as provided
4.12 + * by Oracle in the LICENSE file that accompanied this code.
4.13 + *
4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4.17 + * version 2 for more details (a copy is included in the LICENSE file that
4.18 + * accompanied this code).
4.19 + *
4.20 + * You should have received a copy of the GNU General Public License version
4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4.23 + *
4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4.25 + * or visit www.oracle.com if you need additional information or have any
4.26 + * questions.
4.27 + */
4.28 +
4.29 +package java.io;
4.30 +
4.31 +
4.32 +/**
4.33 + * Signals that an attempt to open the file denoted by a specified pathname
4.34 + * has failed.
4.35 + *
4.36 + * <p> This exception will be thrown by the {@link FileInputStream}, {@link
4.37 + * FileOutputStream}, and {@link RandomAccessFile} constructors when a file
4.38 + * with the specified pathname does not exist. It will also be thrown by these
4.39 + * constructors if the file does exist but for some reason is inaccessible, for
4.40 + * example when an attempt is made to open a read-only file for writing.
4.41 + *
4.42 + * @author unascribed
4.43 + * @since JDK1.0
4.44 + */
4.45 +
4.46 +public class FileNotFoundException extends IOException {
4.47 + private static final long serialVersionUID = -897856973823710492L;
4.48 +
4.49 + /**
4.50 + * Constructs a <code>FileNotFoundException</code> with
4.51 + * <code>null</code> as its error detail message.
4.52 + */
4.53 + public FileNotFoundException() {
4.54 + super();
4.55 + }
4.56 +
4.57 + /**
4.58 + * Constructs a <code>FileNotFoundException</code> with the
4.59 + * specified detail message. The string <code>s</code> can be
4.60 + * retrieved later by the
4.61 + * <code>{@link java.lang.Throwable#getMessage}</code>
4.62 + * method of class <code>java.lang.Throwable</code>.
4.63 + *
4.64 + * @param s the detail message.
4.65 + */
4.66 + public FileNotFoundException(String s) {
4.67 + super(s);
4.68 + }
4.69 +
4.70 + /**
4.71 + * Constructs a <code>FileNotFoundException</code> with a detail message
4.72 + * consisting of the given pathname string followed by the given reason
4.73 + * string. If the <code>reason</code> argument is <code>null</code> then
4.74 + * it will be omitted. This private constructor is invoked only by native
4.75 + * I/O methods.
4.76 + *
4.77 + * @since 1.2
4.78 + */
4.79 + private FileNotFoundException(String path, String reason) {
4.80 + super(path + ((reason == null)
4.81 + ? ""
4.82 + : " (" + reason + ")"));
4.83 + }
4.84 +
4.85 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/emul/compact/src/main/java/java/io/FilenameFilter.java Sat Sep 07 13:51:24 2013 +0200
5.3 @@ -0,0 +1,53 @@
5.4 +/*
5.5 + * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.7 + *
5.8 + * This code is free software; you can redistribute it and/or modify it
5.9 + * under the terms of the GNU General Public License version 2 only, as
5.10 + * published by the Free Software Foundation. Oracle designates this
5.11 + * particular file as subject to the "Classpath" exception as provided
5.12 + * by Oracle in the LICENSE file that accompanied this code.
5.13 + *
5.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
5.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5.17 + * version 2 for more details (a copy is included in the LICENSE file that
5.18 + * accompanied this code).
5.19 + *
5.20 + * You should have received a copy of the GNU General Public License version
5.21 + * 2 along with this work; if not, write to the Free Software Foundation,
5.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5.23 + *
5.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5.25 + * or visit www.oracle.com if you need additional information or have any
5.26 + * questions.
5.27 + */
5.28 +
5.29 +package java.io;
5.30 +
5.31 +/**
5.32 + * Instances of classes that implement this interface are used to
5.33 + * filter filenames. These instances are used to filter directory
5.34 + * listings in the <code>list</code> method of class
5.35 + * <code>File</code>, and by the Abstract Window Toolkit's file
5.36 + * dialog component.
5.37 + *
5.38 + * @author Arthur van Hoff
5.39 + * @author Jonathan Payne
5.40 + * @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
5.41 + * @see java.io.File
5.42 + * @see java.io.File#list(java.io.FilenameFilter)
5.43 + * @since JDK1.0
5.44 + */
5.45 +public
5.46 +interface FilenameFilter {
5.47 + /**
5.48 + * Tests if a specified file should be included in a file list.
5.49 + *
5.50 + * @param dir the directory in which the file was found.
5.51 + * @param name the name of the file.
5.52 + * @return <code>true</code> if and only if the name should be
5.53 + * included in the file list; <code>false</code> otherwise.
5.54 + */
5.55 + boolean accept(File dir, String name);
5.56 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/emul/compact/src/main/java/java/io/InterruptedIOException.java Sat Sep 07 13:51:24 2013 +0200
6.3 @@ -0,0 +1,74 @@
6.4 +/*
6.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.7 + *
6.8 + * This code is free software; you can redistribute it and/or modify it
6.9 + * under the terms of the GNU General Public License version 2 only, as
6.10 + * published by the Free Software Foundation. Oracle designates this
6.11 + * particular file as subject to the "Classpath" exception as provided
6.12 + * by Oracle in the LICENSE file that accompanied this code.
6.13 + *
6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6.17 + * version 2 for more details (a copy is included in the LICENSE file that
6.18 + * accompanied this code).
6.19 + *
6.20 + * You should have received a copy of the GNU General Public License version
6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6.23 + *
6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6.25 + * or visit www.oracle.com if you need additional information or have any
6.26 + * questions.
6.27 + */
6.28 +
6.29 +package java.io;
6.30 +
6.31 +/**
6.32 + * Signals that an I/O operation has been interrupted. An
6.33 + * <code>InterruptedIOException</code> is thrown to indicate that an
6.34 + * input or output transfer has been terminated because the thread
6.35 + * performing it was interrupted. The field {@link #bytesTransferred}
6.36 + * indicates how many bytes were successfully transferred before
6.37 + * the interruption occurred.
6.38 + *
6.39 + * @author unascribed
6.40 + * @see java.io.InputStream
6.41 + * @see java.io.OutputStream
6.42 + * @see java.lang.Thread#interrupt()
6.43 + * @since JDK1.0
6.44 + */
6.45 +public
6.46 +class InterruptedIOException extends IOException {
6.47 + private static final long serialVersionUID = 4020568460727500567L;
6.48 +
6.49 + /**
6.50 + * Constructs an <code>InterruptedIOException</code> with
6.51 + * <code>null</code> as its error detail message.
6.52 + */
6.53 + public InterruptedIOException() {
6.54 + super();
6.55 + }
6.56 +
6.57 + /**
6.58 + * Constructs an <code>InterruptedIOException</code> with the
6.59 + * specified detail message. The string <code>s</code> can be
6.60 + * retrieved later by the
6.61 + * <code>{@link java.lang.Throwable#getMessage}</code>
6.62 + * method of class <code>java.lang.Throwable</code>.
6.63 + *
6.64 + * @param s the detail message.
6.65 + */
6.66 + public InterruptedIOException(String s) {
6.67 + super(s);
6.68 + }
6.69 +
6.70 + /**
6.71 + * Reports how many bytes had been transferred as part of the I/O
6.72 + * operation before it was interrupted.
6.73 + *
6.74 + * @serial
6.75 + */
6.76 + public int bytesTransferred = 0;
6.77 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/emul/compact/src/main/java/java/io/OutputStreamWriter.java Sat Sep 07 13:51:24 2013 +0200
7.3 @@ -0,0 +1,235 @@
7.4 +/*
7.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7.7 + *
7.8 + * This code is free software; you can redistribute it and/or modify it
7.9 + * under the terms of the GNU General Public License version 2 only, as
7.10 + * published by the Free Software Foundation. Oracle designates this
7.11 + * particular file as subject to the "Classpath" exception as provided
7.12 + * by Oracle in the LICENSE file that accompanied this code.
7.13 + *
7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7.17 + * version 2 for more details (a copy is included in the LICENSE file that
7.18 + * accompanied this code).
7.19 + *
7.20 + * You should have received a copy of the GNU General Public License version
7.21 + * 2 along with this work; if not, write to the Free Software Foundation,
7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7.23 + *
7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7.25 + * or visit www.oracle.com if you need additional information or have any
7.26 + * questions.
7.27 + */
7.28 +
7.29 +package java.io;
7.30 +
7.31 +import java.nio.charset.Charset;
7.32 +import java.nio.charset.CharsetEncoder;
7.33 +import sun.nio.cs.StreamEncoder;
7.34 +
7.35 +
7.36 +/**
7.37 + * An OutputStreamWriter is a bridge from character streams to byte streams:
7.38 + * Characters written to it are encoded into bytes using a specified {@link
7.39 + * java.nio.charset.Charset <code>charset</code>}. The charset that it uses
7.40 + * may be specified by name or may be given explicitly, or the platform's
7.41 + * default charset may be accepted.
7.42 + *
7.43 + * <p> Each invocation of a write() method causes the encoding converter to be
7.44 + * invoked on the given character(s). The resulting bytes are accumulated in a
7.45 + * buffer before being written to the underlying output stream. The size of
7.46 + * this buffer may be specified, but by default it is large enough for most
7.47 + * purposes. Note that the characters passed to the write() methods are not
7.48 + * buffered.
7.49 + *
7.50 + * <p> For top efficiency, consider wrapping an OutputStreamWriter within a
7.51 + * BufferedWriter so as to avoid frequent converter invocations. For example:
7.52 + *
7.53 + * <pre>
7.54 + * Writer out
7.55 + * = new BufferedWriter(new OutputStreamWriter(System.out));
7.56 + * </pre>
7.57 + *
7.58 + * <p> A <i>surrogate pair</i> is a character represented by a sequence of two
7.59 + * <tt>char</tt> values: A <i>high</i> surrogate in the range '\uD800' to
7.60 + * '\uDBFF' followed by a <i>low</i> surrogate in the range '\uDC00' to
7.61 + * '\uDFFF'.
7.62 + *
7.63 + * <p> A <i>malformed surrogate element</i> is a high surrogate that is not
7.64 + * followed by a low surrogate or a low surrogate that is not preceded by a
7.65 + * high surrogate.
7.66 + *
7.67 + * <p> This class always replaces malformed surrogate elements and unmappable
7.68 + * character sequences with the charset's default <i>substitution sequence</i>.
7.69 + * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more
7.70 + * control over the encoding process is required.
7.71 + *
7.72 + * @see BufferedWriter
7.73 + * @see OutputStream
7.74 + * @see java.nio.charset.Charset
7.75 + *
7.76 + * @author Mark Reinhold
7.77 + * @since JDK1.1
7.78 + */
7.79 +
7.80 +public class OutputStreamWriter extends Writer {
7.81 +
7.82 + private final StreamEncoder se;
7.83 +
7.84 + /**
7.85 + * Creates an OutputStreamWriter that uses the named charset.
7.86 + *
7.87 + * @param out
7.88 + * An OutputStream
7.89 + *
7.90 + * @param charsetName
7.91 + * The name of a supported
7.92 + * {@link java.nio.charset.Charset </code>charset<code>}
7.93 + *
7.94 + * @exception UnsupportedEncodingException
7.95 + * If the named encoding is not supported
7.96 + */
7.97 + public OutputStreamWriter(OutputStream out, String charsetName)
7.98 + throws UnsupportedEncodingException
7.99 + {
7.100 + super(out);
7.101 + if (charsetName == null)
7.102 + throw new NullPointerException("charsetName");
7.103 + se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
7.104 + }
7.105 +
7.106 + /**
7.107 + * Creates an OutputStreamWriter that uses the default character encoding.
7.108 + *
7.109 + * @param out An OutputStream
7.110 + */
7.111 + public OutputStreamWriter(OutputStream out) {
7.112 + super(out);
7.113 + try {
7.114 + se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
7.115 + } catch (UnsupportedEncodingException e) {
7.116 + throw new Error(e);
7.117 + }
7.118 + }
7.119 +
7.120 + /**
7.121 + * Creates an OutputStreamWriter that uses the given charset. </p>
7.122 + *
7.123 + * @param out
7.124 + * An OutputStream
7.125 + *
7.126 + * @param cs
7.127 + * A charset
7.128 + *
7.129 + * @since 1.4
7.130 + * @spec JSR-51
7.131 + */
7.132 + public OutputStreamWriter(OutputStream out, Charset cs) {
7.133 + super(out);
7.134 + if (cs == null)
7.135 + throw new NullPointerException("charset");
7.136 + se = StreamEncoder.forOutputStreamWriter(out, this, cs);
7.137 + }
7.138 +
7.139 + /**
7.140 + * Creates an OutputStreamWriter that uses the given charset encoder. </p>
7.141 + *
7.142 + * @param out
7.143 + * An OutputStream
7.144 + *
7.145 + * @param enc
7.146 + * A charset encoder
7.147 + *
7.148 + * @since 1.4
7.149 + * @spec JSR-51
7.150 + */
7.151 + public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
7.152 + super(out);
7.153 + if (enc == null)
7.154 + throw new NullPointerException("charset encoder");
7.155 + se = StreamEncoder.forOutputStreamWriter(out, this, enc);
7.156 + }
7.157 +
7.158 + /**
7.159 + * Returns the name of the character encoding being used by this stream.
7.160 + *
7.161 + * <p> If the encoding has an historical name then that name is returned;
7.162 + * otherwise the encoding's canonical name is returned.
7.163 + *
7.164 + * <p> If this instance was created with the {@link
7.165 + * #OutputStreamWriter(OutputStream, String)} constructor then the returned
7.166 + * name, being unique for the encoding, may differ from the name passed to
7.167 + * the constructor. This method may return <tt>null</tt> if the stream has
7.168 + * been closed. </p>
7.169 + *
7.170 + * @return The historical name of this encoding, or possibly
7.171 + * <code>null</code> if the stream has been closed
7.172 + *
7.173 + * @see java.nio.charset.Charset
7.174 + *
7.175 + * @revised 1.4
7.176 + * @spec JSR-51
7.177 + */
7.178 + public String getEncoding() {
7.179 + return se.getEncoding();
7.180 + }
7.181 +
7.182 + /**
7.183 + * Flushes the output buffer to the underlying byte stream, without flushing
7.184 + * the byte stream itself. This method is non-private only so that it may
7.185 + * be invoked by PrintStream.
7.186 + */
7.187 + void flushBuffer() throws IOException {
7.188 + se.flushBuffer();
7.189 + }
7.190 +
7.191 + /**
7.192 + * Writes a single character.
7.193 + *
7.194 + * @exception IOException If an I/O error occurs
7.195 + */
7.196 + public void write(int c) throws IOException {
7.197 + se.write(c);
7.198 + }
7.199 +
7.200 + /**
7.201 + * Writes a portion of an array of characters.
7.202 + *
7.203 + * @param cbuf Buffer of characters
7.204 + * @param off Offset from which to start writing characters
7.205 + * @param len Number of characters to write
7.206 + *
7.207 + * @exception IOException If an I/O error occurs
7.208 + */
7.209 + public void write(char cbuf[], int off, int len) throws IOException {
7.210 + se.write(cbuf, off, len);
7.211 + }
7.212 +
7.213 + /**
7.214 + * Writes a portion of a string.
7.215 + *
7.216 + * @param str A String
7.217 + * @param off Offset from which to start writing characters
7.218 + * @param len Number of characters to write
7.219 + *
7.220 + * @exception IOException If an I/O error occurs
7.221 + */
7.222 + public void write(String str, int off, int len) throws IOException {
7.223 + se.write(str, off, len);
7.224 + }
7.225 +
7.226 + /**
7.227 + * Flushes the stream.
7.228 + *
7.229 + * @exception IOException If an I/O error occurs
7.230 + */
7.231 + public void flush() throws IOException {
7.232 + se.flush();
7.233 + }
7.234 +
7.235 + public void close() throws IOException {
7.236 + se.close();
7.237 + }
7.238 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/emul/compact/src/main/java/java/io/PrintStream.java Sat Sep 07 13:51:24 2013 +0200
8.3 @@ -0,0 +1,1129 @@
8.4 +/*
8.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8.7 + *
8.8 + * This code is free software; you can redistribute it and/or modify it
8.9 + * under the terms of the GNU General Public License version 2 only, as
8.10 + * published by the Free Software Foundation. Oracle designates this
8.11 + * particular file as subject to the "Classpath" exception as provided
8.12 + * by Oracle in the LICENSE file that accompanied this code.
8.13 + *
8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
8.17 + * version 2 for more details (a copy is included in the LICENSE file that
8.18 + * accompanied this code).
8.19 + *
8.20 + * You should have received a copy of the GNU General Public License version
8.21 + * 2 along with this work; if not, write to the Free Software Foundation,
8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8.23 + *
8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8.25 + * or visit www.oracle.com if you need additional information or have any
8.26 + * questions.
8.27 + */
8.28 +
8.29 +package java.io;
8.30 +
8.31 +import java.util.Formatter;
8.32 +import java.util.Locale;
8.33 +import java.nio.charset.Charset;
8.34 +import java.nio.charset.IllegalCharsetNameException;
8.35 +import java.nio.charset.UnsupportedCharsetException;
8.36 +
8.37 +/**
8.38 + * A <code>PrintStream</code> adds functionality to another output stream,
8.39 + * namely the ability to print representations of various data values
8.40 + * conveniently. Two other features are provided as well. Unlike other output
8.41 + * streams, a <code>PrintStream</code> never throws an
8.42 + * <code>IOException</code>; instead, exceptional situations merely set an
8.43 + * internal flag that can be tested via the <code>checkError</code> method.
8.44 + * Optionally, a <code>PrintStream</code> can be created so as to flush
8.45 + * automatically; this means that the <code>flush</code> method is
8.46 + * automatically invoked after a byte array is written, one of the
8.47 + * <code>println</code> methods is invoked, or a newline character or byte
8.48 + * (<code>'\n'</code>) is written.
8.49 + *
8.50 + * <p> All characters printed by a <code>PrintStream</code> are converted into
8.51 + * bytes using the platform's default character encoding. The <code>{@link
8.52 + * PrintWriter}</code> class should be used in situations that require writing
8.53 + * characters rather than bytes.
8.54 + *
8.55 + * @author Frank Yellin
8.56 + * @author Mark Reinhold
8.57 + * @since JDK1.0
8.58 + */
8.59 +
8.60 +public class PrintStream extends FilterOutputStream
8.61 + implements Appendable, Closeable
8.62 +{
8.63 +
8.64 + private final boolean autoFlush;
8.65 + private boolean trouble = false;
8.66 + private Formatter formatter;
8.67 +
8.68 + /**
8.69 + * Track both the text- and character-output streams, so that their buffers
8.70 + * can be flushed without flushing the entire stream.
8.71 + */
8.72 + private BufferedWriter textOut;
8.73 + private OutputStreamWriter charOut;
8.74 +
8.75 + /**
8.76 + * requireNonNull is explicitly declared here so as not to create an extra
8.77 + * dependency on java.util.Objects.requireNonNull. PrintStream is loaded
8.78 + * early during system initialization.
8.79 + */
8.80 + private static <T> T requireNonNull(T obj, String message) {
8.81 + if (obj == null)
8.82 + throw new NullPointerException(message);
8.83 + return obj;
8.84 + }
8.85 +
8.86 + /**
8.87 + * Returns a charset object for the given charset name.
8.88 + * @throws NullPointerException is csn is null
8.89 + * @throws UnsupportedEncodingException if the charset is not supported
8.90 + */
8.91 + private static Charset toCharset(String csn)
8.92 + throws UnsupportedEncodingException
8.93 + {
8.94 + requireNonNull(csn, "charsetName");
8.95 + try {
8.96 + return Charset.forName(csn);
8.97 + } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
8.98 + // UnsupportedEncodingException should be thrown
8.99 + throw new UnsupportedEncodingException(csn);
8.100 + }
8.101 + }
8.102 +
8.103 + /* Private constructors */
8.104 + private PrintStream(boolean autoFlush, OutputStream out) {
8.105 + super(out);
8.106 + this.autoFlush = autoFlush;
8.107 + this.charOut = new OutputStreamWriter(this);
8.108 + this.textOut = new BufferedWriter(charOut);
8.109 + }
8.110 +
8.111 + private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
8.112 + super(out);
8.113 + this.autoFlush = autoFlush;
8.114 + this.charOut = new OutputStreamWriter(this, charset);
8.115 + this.textOut = new BufferedWriter(charOut);
8.116 + }
8.117 +
8.118 + /* Variant of the private constructor so that the given charset name
8.119 + * can be verified before evaluating the OutputStream argument. Used
8.120 + * by constructors creating a FileOutputStream that also take a
8.121 + * charset name.
8.122 + */
8.123 + private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
8.124 + throws UnsupportedEncodingException
8.125 + {
8.126 + this(autoFlush, out, charset);
8.127 + }
8.128 +
8.129 + /**
8.130 + * Creates a new print stream. This stream will not flush automatically.
8.131 + *
8.132 + * @param out The output stream to which values and objects will be
8.133 + * printed
8.134 + *
8.135 + * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
8.136 + */
8.137 + public PrintStream(OutputStream out) {
8.138 + this(out, false);
8.139 + }
8.140 +
8.141 + /**
8.142 + * Creates a new print stream.
8.143 + *
8.144 + * @param out The output stream to which values and objects will be
8.145 + * printed
8.146 + * @param autoFlush A boolean; if true, the output buffer will be flushed
8.147 + * whenever a byte array is written, one of the
8.148 + * <code>println</code> methods is invoked, or a newline
8.149 + * character or byte (<code>'\n'</code>) is written
8.150 + *
8.151 + * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
8.152 + */
8.153 + public PrintStream(OutputStream out, boolean autoFlush) {
8.154 + this(autoFlush, requireNonNull(out, "Null output stream"));
8.155 + }
8.156 +
8.157 + /**
8.158 + * Creates a new print stream.
8.159 + *
8.160 + * @param out The output stream to which values and objects will be
8.161 + * printed
8.162 + * @param autoFlush A boolean; if true, the output buffer will be flushed
8.163 + * whenever a byte array is written, one of the
8.164 + * <code>println</code> methods is invoked, or a newline
8.165 + * character or byte (<code>'\n'</code>) is written
8.166 + * @param encoding The name of a supported
8.167 + * <a href="../lang/package-summary.html#charenc">
8.168 + * character encoding</a>
8.169 + *
8.170 + * @throws UnsupportedEncodingException
8.171 + * If the named encoding is not supported
8.172 + *
8.173 + * @since 1.4
8.174 + */
8.175 + public PrintStream(OutputStream out, boolean autoFlush, String encoding)
8.176 + throws UnsupportedEncodingException
8.177 + {
8.178 + this(autoFlush,
8.179 + requireNonNull(out, "Null output stream"),
8.180 + toCharset(encoding));
8.181 + }
8.182 +
8.183 + /**
8.184 + * Creates a new print stream, without automatic line flushing, with the
8.185 + * specified file name. This convenience constructor creates
8.186 + * the necessary intermediate {@link java.io.OutputStreamWriter
8.187 + * OutputStreamWriter}, which will encode characters using the
8.188 + * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
8.189 + * for this instance of the Java virtual machine.
8.190 + *
8.191 + * @param fileName
8.192 + * The name of the file to use as the destination of this print
8.193 + * stream. If the file exists, then it will be truncated to
8.194 + * zero size; otherwise, a new file will be created. The output
8.195 + * will be written to the file and is buffered.
8.196 + *
8.197 + * @throws FileNotFoundException
8.198 + * If the given file object does not denote an existing, writable
8.199 + * regular file and a new regular file of that name cannot be
8.200 + * created, or if some other error occurs while opening or
8.201 + * creating the file
8.202 + *
8.203 + * @throws SecurityException
8.204 + * If a security manager is present and {@link
8.205 + * SecurityManager#checkWrite checkWrite(fileName)} denies write
8.206 + * access to the file
8.207 + *
8.208 + * @since 1.5
8.209 + */
8.210 + public PrintStream(String fileName) throws FileNotFoundException {
8.211 + this(false, new FileOutputStream(fileName));
8.212 + }
8.213 +
8.214 + /**
8.215 + * Creates a new print stream, without automatic line flushing, with the
8.216 + * specified file name and charset. This convenience constructor creates
8.217 + * the necessary intermediate {@link java.io.OutputStreamWriter
8.218 + * OutputStreamWriter}, which will encode characters using the provided
8.219 + * charset.
8.220 + *
8.221 + * @param fileName
8.222 + * The name of the file to use as the destination of this print
8.223 + * stream. If the file exists, then it will be truncated to
8.224 + * zero size; otherwise, a new file will be created. The output
8.225 + * will be written to the file and is buffered.
8.226 + *
8.227 + * @param csn
8.228 + * The name of a supported {@linkplain java.nio.charset.Charset
8.229 + * charset}
8.230 + *
8.231 + * @throws FileNotFoundException
8.232 + * If the given file object does not denote an existing, writable
8.233 + * regular file and a new regular file of that name cannot be
8.234 + * created, or if some other error occurs while opening or
8.235 + * creating the file
8.236 + *
8.237 + * @throws SecurityException
8.238 + * If a security manager is present and {@link
8.239 + * SecurityManager#checkWrite checkWrite(fileName)} denies write
8.240 + * access to the file
8.241 + *
8.242 + * @throws UnsupportedEncodingException
8.243 + * If the named charset is not supported
8.244 + *
8.245 + * @since 1.5
8.246 + */
8.247 + public PrintStream(String fileName, String csn)
8.248 + throws FileNotFoundException, UnsupportedEncodingException
8.249 + {
8.250 + // ensure charset is checked before the file is opened
8.251 + this(false, toCharset(csn), new FileOutputStream(fileName));
8.252 + }
8.253 +
8.254 + /**
8.255 + * Creates a new print stream, without automatic line flushing, with the
8.256 + * specified file. This convenience constructor creates the necessary
8.257 + * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
8.258 + * which will encode characters using the {@linkplain
8.259 + * java.nio.charset.Charset#defaultCharset() default charset} for this
8.260 + * instance of the Java virtual machine.
8.261 + *
8.262 + * @param file
8.263 + * The file to use as the destination of this print stream. If the
8.264 + * file exists, then it will be truncated to zero size; otherwise,
8.265 + * a new file will be created. The output will be written to the
8.266 + * file and is buffered.
8.267 + *
8.268 + * @throws FileNotFoundException
8.269 + * If the given file object does not denote an existing, writable
8.270 + * regular file and a new regular file of that name cannot be
8.271 + * created, or if some other error occurs while opening or
8.272 + * creating the file
8.273 + *
8.274 + * @throws SecurityException
8.275 + * If a security manager is present and {@link
8.276 + * SecurityManager#checkWrite checkWrite(file.getPath())}
8.277 + * denies write access to the file
8.278 + *
8.279 + * @since 1.5
8.280 + */
8.281 + public PrintStream(File file) throws FileNotFoundException {
8.282 + this(false, new FileOutputStream(file));
8.283 + }
8.284 +
8.285 + /**
8.286 + * Creates a new print stream, without automatic line flushing, with the
8.287 + * specified file and charset. This convenience constructor creates
8.288 + * the necessary intermediate {@link java.io.OutputStreamWriter
8.289 + * OutputStreamWriter}, which will encode characters using the provided
8.290 + * charset.
8.291 + *
8.292 + * @param file
8.293 + * The file to use as the destination of this print stream. If the
8.294 + * file exists, then it will be truncated to zero size; otherwise,
8.295 + * a new file will be created. The output will be written to the
8.296 + * file and is buffered.
8.297 + *
8.298 + * @param csn
8.299 + * The name of a supported {@linkplain java.nio.charset.Charset
8.300 + * charset}
8.301 + *
8.302 + * @throws FileNotFoundException
8.303 + * If the given file object does not denote an existing, writable
8.304 + * regular file and a new regular file of that name cannot be
8.305 + * created, or if some other error occurs while opening or
8.306 + * creating the file
8.307 + *
8.308 + * @throws SecurityException
8.309 + * If a security manager is presentand {@link
8.310 + * SecurityManager#checkWrite checkWrite(file.getPath())}
8.311 + * denies write access to the file
8.312 + *
8.313 + * @throws UnsupportedEncodingException
8.314 + * If the named charset is not supported
8.315 + *
8.316 + * @since 1.5
8.317 + */
8.318 + public PrintStream(File file, String csn)
8.319 + throws FileNotFoundException, UnsupportedEncodingException
8.320 + {
8.321 + // ensure charset is checked before the file is opened
8.322 + this(false, toCharset(csn), new FileOutputStream(file));
8.323 + }
8.324 +
8.325 + /** Check to make sure that the stream has not been closed */
8.326 + private void ensureOpen() throws IOException {
8.327 + if (out == null)
8.328 + throw new IOException("Stream closed");
8.329 + }
8.330 +
8.331 + /**
8.332 + * Flushes the stream. This is done by writing any buffered output bytes to
8.333 + * the underlying output stream and then flushing that stream.
8.334 + *
8.335 + * @see java.io.OutputStream#flush()
8.336 + */
8.337 + public void flush() {
8.338 + synchronized (this) {
8.339 + try {
8.340 + ensureOpen();
8.341 + out.flush();
8.342 + }
8.343 + catch (IOException x) {
8.344 + trouble = true;
8.345 + }
8.346 + }
8.347 + }
8.348 +
8.349 + private boolean closing = false; /* To avoid recursive closing */
8.350 +
8.351 + /**
8.352 + * Closes the stream. This is done by flushing the stream and then closing
8.353 + * the underlying output stream.
8.354 + *
8.355 + * @see java.io.OutputStream#close()
8.356 + */
8.357 + public void close() {
8.358 + synchronized (this) {
8.359 + if (! closing) {
8.360 + closing = true;
8.361 + try {
8.362 + textOut.close();
8.363 + out.close();
8.364 + }
8.365 + catch (IOException x) {
8.366 + trouble = true;
8.367 + }
8.368 + textOut = null;
8.369 + charOut = null;
8.370 + out = null;
8.371 + }
8.372 + }
8.373 + }
8.374 +
8.375 + /**
8.376 + * Flushes the stream and checks its error state. The internal error state
8.377 + * is set to <code>true</code> when the underlying output stream throws an
8.378 + * <code>IOException</code> other than <code>InterruptedIOException</code>,
8.379 + * and when the <code>setError</code> method is invoked. If an operation
8.380 + * on the underlying output stream throws an
8.381 + * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
8.382 + * converts the exception back into an interrupt by doing:
8.383 + * <pre>
8.384 + * Thread.currentThread().interrupt();
8.385 + * </pre>
8.386 + * or the equivalent.
8.387 + *
8.388 + * @return <code>true</code> if and only if this stream has encountered an
8.389 + * <code>IOException</code> other than
8.390 + * <code>InterruptedIOException</code>, or the
8.391 + * <code>setError</code> method has been invoked
8.392 + */
8.393 + public boolean checkError() {
8.394 + if (out != null)
8.395 + flush();
8.396 + if (out instanceof java.io.PrintStream) {
8.397 + PrintStream ps = (PrintStream) out;
8.398 + return ps.checkError();
8.399 + }
8.400 + return trouble;
8.401 + }
8.402 +
8.403 + /**
8.404 + * Sets the error state of the stream to <code>true</code>.
8.405 + *
8.406 + * <p> This method will cause subsequent invocations of {@link
8.407 + * #checkError()} to return <tt>true</tt> until {@link
8.408 + * #clearError()} is invoked.
8.409 + *
8.410 + * @since JDK1.1
8.411 + */
8.412 + protected void setError() {
8.413 + trouble = true;
8.414 + }
8.415 +
8.416 + /**
8.417 + * Clears the internal error state of this stream.
8.418 + *
8.419 + * <p> This method will cause subsequent invocations of {@link
8.420 + * #checkError()} to return <tt>false</tt> until another write
8.421 + * operation fails and invokes {@link #setError()}.
8.422 + *
8.423 + * @since 1.6
8.424 + */
8.425 + protected void clearError() {
8.426 + trouble = false;
8.427 + }
8.428 +
8.429 + /*
8.430 + * Exception-catching, synchronized output operations,
8.431 + * which also implement the write() methods of OutputStream
8.432 + */
8.433 +
8.434 + /**
8.435 + * Writes the specified byte to this stream. If the byte is a newline and
8.436 + * automatic flushing is enabled then the <code>flush</code> method will be
8.437 + * invoked.
8.438 + *
8.439 + * <p> Note that the byte is written as given; to write a character that
8.440 + * will be translated according to the platform's default character
8.441 + * encoding, use the <code>print(char)</code> or <code>println(char)</code>
8.442 + * methods.
8.443 + *
8.444 + * @param b The byte to be written
8.445 + * @see #print(char)
8.446 + * @see #println(char)
8.447 + */
8.448 + public void write(int b) {
8.449 + try {
8.450 + synchronized (this) {
8.451 + ensureOpen();
8.452 + out.write(b);
8.453 + if ((b == '\n') && autoFlush)
8.454 + out.flush();
8.455 + }
8.456 + }
8.457 + catch (InterruptedIOException x) {
8.458 + Thread.currentThread().interrupt();
8.459 + }
8.460 + catch (IOException x) {
8.461 + trouble = true;
8.462 + }
8.463 + }
8.464 +
8.465 + /**
8.466 + * Writes <code>len</code> bytes from the specified byte array starting at
8.467 + * offset <code>off</code> to this stream. If automatic flushing is
8.468 + * enabled then the <code>flush</code> method will be invoked.
8.469 + *
8.470 + * <p> Note that the bytes will be written as given; to write characters
8.471 + * that will be translated according to the platform's default character
8.472 + * encoding, use the <code>print(char)</code> or <code>println(char)</code>
8.473 + * methods.
8.474 + *
8.475 + * @param buf A byte array
8.476 + * @param off Offset from which to start taking bytes
8.477 + * @param len Number of bytes to write
8.478 + */
8.479 + public void write(byte buf[], int off, int len) {
8.480 + try {
8.481 + synchronized (this) {
8.482 + ensureOpen();
8.483 + out.write(buf, off, len);
8.484 + if (autoFlush)
8.485 + out.flush();
8.486 + }
8.487 + }
8.488 + catch (InterruptedIOException x) {
8.489 + Thread.currentThread().interrupt();
8.490 + }
8.491 + catch (IOException x) {
8.492 + trouble = true;
8.493 + }
8.494 + }
8.495 +
8.496 + /*
8.497 + * The following private methods on the text- and character-output streams
8.498 + * always flush the stream buffers, so that writes to the underlying byte
8.499 + * stream occur as promptly as with the original PrintStream.
8.500 + */
8.501 +
8.502 + private void write(char buf[]) {
8.503 + try {
8.504 + synchronized (this) {
8.505 + ensureOpen();
8.506 + textOut.write(buf);
8.507 + textOut.flushBuffer();
8.508 + charOut.flushBuffer();
8.509 + if (autoFlush) {
8.510 + for (int i = 0; i < buf.length; i++)
8.511 + if (buf[i] == '\n')
8.512 + out.flush();
8.513 + }
8.514 + }
8.515 + }
8.516 + catch (InterruptedIOException x) {
8.517 + Thread.currentThread().interrupt();
8.518 + }
8.519 + catch (IOException x) {
8.520 + trouble = true;
8.521 + }
8.522 + }
8.523 +
8.524 + private void write(String s) {
8.525 + try {
8.526 + synchronized (this) {
8.527 + ensureOpen();
8.528 + textOut.write(s);
8.529 + textOut.flushBuffer();
8.530 + charOut.flushBuffer();
8.531 + if (autoFlush && (s.indexOf('\n') >= 0))
8.532 + out.flush();
8.533 + }
8.534 + }
8.535 + catch (InterruptedIOException x) {
8.536 + Thread.currentThread().interrupt();
8.537 + }
8.538 + catch (IOException x) {
8.539 + trouble = true;
8.540 + }
8.541 + }
8.542 +
8.543 + private void newLine() {
8.544 + try {
8.545 + synchronized (this) {
8.546 + ensureOpen();
8.547 + textOut.newLine();
8.548 + textOut.flushBuffer();
8.549 + charOut.flushBuffer();
8.550 + if (autoFlush)
8.551 + out.flush();
8.552 + }
8.553 + }
8.554 + catch (InterruptedIOException x) {
8.555 + Thread.currentThread().interrupt();
8.556 + }
8.557 + catch (IOException x) {
8.558 + trouble = true;
8.559 + }
8.560 + }
8.561 +
8.562 + /* Methods that do not terminate lines */
8.563 +
8.564 + /**
8.565 + * Prints a boolean value. The string produced by <code>{@link
8.566 + * java.lang.String#valueOf(boolean)}</code> is translated into bytes
8.567 + * according to the platform's default character encoding, and these bytes
8.568 + * are written in exactly the manner of the
8.569 + * <code>{@link #write(int)}</code> method.
8.570 + *
8.571 + * @param b The <code>boolean</code> to be printed
8.572 + */
8.573 + public void print(boolean b) {
8.574 + write(b ? "true" : "false");
8.575 + }
8.576 +
8.577 + /**
8.578 + * Prints a character. The character is translated into one or more bytes
8.579 + * according to the platform's default character encoding, and these bytes
8.580 + * are written in exactly the manner of the
8.581 + * <code>{@link #write(int)}</code> method.
8.582 + *
8.583 + * @param c The <code>char</code> to be printed
8.584 + */
8.585 + public void print(char c) {
8.586 + write(String.valueOf(c));
8.587 + }
8.588 +
8.589 + /**
8.590 + * Prints an integer. The string produced by <code>{@link
8.591 + * java.lang.String#valueOf(int)}</code> is translated into bytes
8.592 + * according to the platform's default character encoding, and these bytes
8.593 + * are written in exactly the manner of the
8.594 + * <code>{@link #write(int)}</code> method.
8.595 + *
8.596 + * @param i The <code>int</code> to be printed
8.597 + * @see java.lang.Integer#toString(int)
8.598 + */
8.599 + public void print(int i) {
8.600 + write(String.valueOf(i));
8.601 + }
8.602 +
8.603 + /**
8.604 + * Prints a long integer. The string produced by <code>{@link
8.605 + * java.lang.String#valueOf(long)}</code> is translated into bytes
8.606 + * according to the platform's default character encoding, and these bytes
8.607 + * are written in exactly the manner of the
8.608 + * <code>{@link #write(int)}</code> method.
8.609 + *
8.610 + * @param l The <code>long</code> to be printed
8.611 + * @see java.lang.Long#toString(long)
8.612 + */
8.613 + public void print(long l) {
8.614 + write(String.valueOf(l));
8.615 + }
8.616 +
8.617 + /**
8.618 + * Prints a floating-point number. The string produced by <code>{@link
8.619 + * java.lang.String#valueOf(float)}</code> is translated into bytes
8.620 + * according to the platform's default character encoding, and these bytes
8.621 + * are written in exactly the manner of the
8.622 + * <code>{@link #write(int)}</code> method.
8.623 + *
8.624 + * @param f The <code>float</code> to be printed
8.625 + * @see java.lang.Float#toString(float)
8.626 + */
8.627 + public void print(float f) {
8.628 + write(String.valueOf(f));
8.629 + }
8.630 +
8.631 + /**
8.632 + * Prints a double-precision floating-point number. The string produced by
8.633 + * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
8.634 + * bytes according to the platform's default character encoding, and these
8.635 + * bytes are written in exactly the manner of the <code>{@link
8.636 + * #write(int)}</code> method.
8.637 + *
8.638 + * @param d The <code>double</code> to be printed
8.639 + * @see java.lang.Double#toString(double)
8.640 + */
8.641 + public void print(double d) {
8.642 + write(String.valueOf(d));
8.643 + }
8.644 +
8.645 + /**
8.646 + * Prints an array of characters. The characters are converted into bytes
8.647 + * according to the platform's default character encoding, and these bytes
8.648 + * are written in exactly the manner of the
8.649 + * <code>{@link #write(int)}</code> method.
8.650 + *
8.651 + * @param s The array of chars to be printed
8.652 + *
8.653 + * @throws NullPointerException If <code>s</code> is <code>null</code>
8.654 + */
8.655 + public void print(char s[]) {
8.656 + write(s);
8.657 + }
8.658 +
8.659 + /**
8.660 + * Prints a string. If the argument is <code>null</code> then the string
8.661 + * <code>"null"</code> is printed. Otherwise, the string's characters are
8.662 + * converted into bytes according to the platform's default character
8.663 + * encoding, and these bytes are written in exactly the manner of the
8.664 + * <code>{@link #write(int)}</code> method.
8.665 + *
8.666 + * @param s The <code>String</code> to be printed
8.667 + */
8.668 + public void print(String s) {
8.669 + if (s == null) {
8.670 + s = "null";
8.671 + }
8.672 + write(s);
8.673 + }
8.674 +
8.675 + /**
8.676 + * Prints an object. The string produced by the <code>{@link
8.677 + * java.lang.String#valueOf(Object)}</code> method is translated into bytes
8.678 + * according to the platform's default character encoding, and these bytes
8.679 + * are written in exactly the manner of the
8.680 + * <code>{@link #write(int)}</code> method.
8.681 + *
8.682 + * @param obj The <code>Object</code> to be printed
8.683 + * @see java.lang.Object#toString()
8.684 + */
8.685 + public void print(Object obj) {
8.686 + write(String.valueOf(obj));
8.687 + }
8.688 +
8.689 +
8.690 + /* Methods that do terminate lines */
8.691 +
8.692 + /**
8.693 + * Terminates the current line by writing the line separator string. The
8.694 + * line separator string is defined by the system property
8.695 + * <code>line.separator</code>, and is not necessarily a single newline
8.696 + * character (<code>'\n'</code>).
8.697 + */
8.698 + public void println() {
8.699 + newLine();
8.700 + }
8.701 +
8.702 + /**
8.703 + * Prints a boolean and then terminate the line. This method behaves as
8.704 + * though it invokes <code>{@link #print(boolean)}</code> and then
8.705 + * <code>{@link #println()}</code>.
8.706 + *
8.707 + * @param x The <code>boolean</code> to be printed
8.708 + */
8.709 + public void println(boolean x) {
8.710 + synchronized (this) {
8.711 + print(x);
8.712 + newLine();
8.713 + }
8.714 + }
8.715 +
8.716 + /**
8.717 + * Prints a character and then terminate the line. This method behaves as
8.718 + * though it invokes <code>{@link #print(char)}</code> and then
8.719 + * <code>{@link #println()}</code>.
8.720 + *
8.721 + * @param x The <code>char</code> to be printed.
8.722 + */
8.723 + public void println(char x) {
8.724 + synchronized (this) {
8.725 + print(x);
8.726 + newLine();
8.727 + }
8.728 + }
8.729 +
8.730 + /**
8.731 + * Prints an integer and then terminate the line. This method behaves as
8.732 + * though it invokes <code>{@link #print(int)}</code> and then
8.733 + * <code>{@link #println()}</code>.
8.734 + *
8.735 + * @param x The <code>int</code> to be printed.
8.736 + */
8.737 + public void println(int x) {
8.738 + synchronized (this) {
8.739 + print(x);
8.740 + newLine();
8.741 + }
8.742 + }
8.743 +
8.744 + /**
8.745 + * Prints a long and then terminate the line. This method behaves as
8.746 + * though it invokes <code>{@link #print(long)}</code> and then
8.747 + * <code>{@link #println()}</code>.
8.748 + *
8.749 + * @param x a The <code>long</code> to be printed.
8.750 + */
8.751 + public void println(long x) {
8.752 + synchronized (this) {
8.753 + print(x);
8.754 + newLine();
8.755 + }
8.756 + }
8.757 +
8.758 + /**
8.759 + * Prints a float and then terminate the line. This method behaves as
8.760 + * though it invokes <code>{@link #print(float)}</code> and then
8.761 + * <code>{@link #println()}</code>.
8.762 + *
8.763 + * @param x The <code>float</code> to be printed.
8.764 + */
8.765 + public void println(float x) {
8.766 + synchronized (this) {
8.767 + print(x);
8.768 + newLine();
8.769 + }
8.770 + }
8.771 +
8.772 + /**
8.773 + * Prints a double and then terminate the line. This method behaves as
8.774 + * though it invokes <code>{@link #print(double)}</code> and then
8.775 + * <code>{@link #println()}</code>.
8.776 + *
8.777 + * @param x The <code>double</code> to be printed.
8.778 + */
8.779 + public void println(double x) {
8.780 + synchronized (this) {
8.781 + print(x);
8.782 + newLine();
8.783 + }
8.784 + }
8.785 +
8.786 + /**
8.787 + * Prints an array of characters and then terminate the line. This method
8.788 + * behaves as though it invokes <code>{@link #print(char[])}</code> and
8.789 + * then <code>{@link #println()}</code>.
8.790 + *
8.791 + * @param x an array of chars to print.
8.792 + */
8.793 + public void println(char x[]) {
8.794 + synchronized (this) {
8.795 + print(x);
8.796 + newLine();
8.797 + }
8.798 + }
8.799 +
8.800 + /**
8.801 + * Prints a String and then terminate the line. This method behaves as
8.802 + * though it invokes <code>{@link #print(String)}</code> and then
8.803 + * <code>{@link #println()}</code>.
8.804 + *
8.805 + * @param x The <code>String</code> to be printed.
8.806 + */
8.807 + public void println(String x) {
8.808 + synchronized (this) {
8.809 + print(x);
8.810 + newLine();
8.811 + }
8.812 + }
8.813 +
8.814 + /**
8.815 + * Prints an Object and then terminate the line. This method calls
8.816 + * at first String.valueOf(x) to get the printed object's string value,
8.817 + * then behaves as
8.818 + * though it invokes <code>{@link #print(String)}</code> and then
8.819 + * <code>{@link #println()}</code>.
8.820 + *
8.821 + * @param x The <code>Object</code> to be printed.
8.822 + */
8.823 + public void println(Object x) {
8.824 + String s = String.valueOf(x);
8.825 + synchronized (this) {
8.826 + print(s);
8.827 + newLine();
8.828 + }
8.829 + }
8.830 +
8.831 +
8.832 + /**
8.833 + * A convenience method to write a formatted string to this output stream
8.834 + * using the specified format string and arguments.
8.835 + *
8.836 + * <p> An invocation of this method of the form <tt>out.printf(format,
8.837 + * args)</tt> behaves in exactly the same way as the invocation
8.838 + *
8.839 + * <pre>
8.840 + * out.format(format, args) </pre>
8.841 + *
8.842 + * @param format
8.843 + * A format string as described in <a
8.844 + * href="../util/Formatter.html#syntax">Format string syntax</a>
8.845 + *
8.846 + * @param args
8.847 + * Arguments referenced by the format specifiers in the format
8.848 + * string. If there are more arguments than format specifiers, the
8.849 + * extra arguments are ignored. The number of arguments is
8.850 + * variable and may be zero. The maximum number of arguments is
8.851 + * limited by the maximum dimension of a Java array as defined by
8.852 + * <cite>The Java™ Virtual Machine Specification</cite>.
8.853 + * The behaviour on a
8.854 + * <tt>null</tt> argument depends on the <a
8.855 + * href="../util/Formatter.html#syntax">conversion</a>.
8.856 + *
8.857 + * @throws IllegalFormatException
8.858 + * If a format string contains an illegal syntax, a format
8.859 + * specifier that is incompatible with the given arguments,
8.860 + * insufficient arguments given the format string, or other
8.861 + * illegal conditions. For specification of all possible
8.862 + * formatting errors, see the <a
8.863 + * href="../util/Formatter.html#detail">Details</a> section of the
8.864 + * formatter class specification.
8.865 + *
8.866 + * @throws NullPointerException
8.867 + * If the <tt>format</tt> is <tt>null</tt>
8.868 + *
8.869 + * @return This output stream
8.870 + *
8.871 + * @since 1.5
8.872 + */
8.873 + public PrintStream printf(String format, Object ... args) {
8.874 + return format(format, args);
8.875 + }
8.876 +
8.877 + /**
8.878 + * A convenience method to write a formatted string to this output stream
8.879 + * using the specified format string and arguments.
8.880 + *
8.881 + * <p> An invocation of this method of the form <tt>out.printf(l, format,
8.882 + * args)</tt> behaves in exactly the same way as the invocation
8.883 + *
8.884 + * <pre>
8.885 + * out.format(l, format, args) </pre>
8.886 + *
8.887 + * @param l
8.888 + * The {@linkplain java.util.Locale locale} to apply during
8.889 + * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
8.890 + * is applied.
8.891 + *
8.892 + * @param format
8.893 + * A format string as described in <a
8.894 + * href="../util/Formatter.html#syntax">Format string syntax</a>
8.895 + *
8.896 + * @param args
8.897 + * Arguments referenced by the format specifiers in the format
8.898 + * string. If there are more arguments than format specifiers, the
8.899 + * extra arguments are ignored. The number of arguments is
8.900 + * variable and may be zero. The maximum number of arguments is
8.901 + * limited by the maximum dimension of a Java array as defined by
8.902 + * <cite>The Java™ Virtual Machine Specification</cite>.
8.903 + * The behaviour on a
8.904 + * <tt>null</tt> argument depends on the <a
8.905 + * href="../util/Formatter.html#syntax">conversion</a>.
8.906 + *
8.907 + * @throws IllegalFormatException
8.908 + * If a format string contains an illegal syntax, a format
8.909 + * specifier that is incompatible with the given arguments,
8.910 + * insufficient arguments given the format string, or other
8.911 + * illegal conditions. For specification of all possible
8.912 + * formatting errors, see the <a
8.913 + * href="../util/Formatter.html#detail">Details</a> section of the
8.914 + * formatter class specification.
8.915 + *
8.916 + * @throws NullPointerException
8.917 + * If the <tt>format</tt> is <tt>null</tt>
8.918 + *
8.919 + * @return This output stream
8.920 + *
8.921 + * @since 1.5
8.922 + */
8.923 + public PrintStream printf(Locale l, String format, Object ... args) {
8.924 + return format(l, format, args);
8.925 + }
8.926 +
8.927 + /**
8.928 + * Writes a formatted string to this output stream using the specified
8.929 + * format string and arguments.
8.930 + *
8.931 + * <p> The locale always used is the one returned by {@link
8.932 + * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
8.933 + * previous invocations of other formatting methods on this object.
8.934 + *
8.935 + * @param format
8.936 + * A format string as described in <a
8.937 + * href="../util/Formatter.html#syntax">Format string syntax</a>
8.938 + *
8.939 + * @param args
8.940 + * Arguments referenced by the format specifiers in the format
8.941 + * string. If there are more arguments than format specifiers, the
8.942 + * extra arguments are ignored. The number of arguments is
8.943 + * variable and may be zero. The maximum number of arguments is
8.944 + * limited by the maximum dimension of a Java array as defined by
8.945 + * <cite>The Java™ Virtual Machine Specification</cite>.
8.946 + * The behaviour on a
8.947 + * <tt>null</tt> argument depends on the <a
8.948 + * href="../util/Formatter.html#syntax">conversion</a>.
8.949 + *
8.950 + * @throws IllegalFormatException
8.951 + * If a format string contains an illegal syntax, a format
8.952 + * specifier that is incompatible with the given arguments,
8.953 + * insufficient arguments given the format string, or other
8.954 + * illegal conditions. For specification of all possible
8.955 + * formatting errors, see the <a
8.956 + * href="../util/Formatter.html#detail">Details</a> section of the
8.957 + * formatter class specification.
8.958 + *
8.959 + * @throws NullPointerException
8.960 + * If the <tt>format</tt> is <tt>null</tt>
8.961 + *
8.962 + * @return This output stream
8.963 + *
8.964 + * @since 1.5
8.965 + */
8.966 + public PrintStream format(String format, Object ... args) {
8.967 + try {
8.968 + synchronized (this) {
8.969 + ensureOpen();
8.970 + if ((formatter == null)
8.971 + || (formatter.locale() != Locale.getDefault()))
8.972 + formatter = new Formatter((Appendable) this);
8.973 + formatter.format(Locale.getDefault(), format, args);
8.974 + }
8.975 + } catch (InterruptedIOException x) {
8.976 + Thread.currentThread().interrupt();
8.977 + } catch (IOException x) {
8.978 + trouble = true;
8.979 + }
8.980 + return this;
8.981 + }
8.982 +
8.983 + /**
8.984 + * Writes a formatted string to this output stream using the specified
8.985 + * format string and arguments.
8.986 + *
8.987 + * @param l
8.988 + * The {@linkplain java.util.Locale locale} to apply during
8.989 + * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
8.990 + * is applied.
8.991 + *
8.992 + * @param format
8.993 + * A format string as described in <a
8.994 + * href="../util/Formatter.html#syntax">Format string syntax</a>
8.995 + *
8.996 + * @param args
8.997 + * Arguments referenced by the format specifiers in the format
8.998 + * string. If there are more arguments than format specifiers, the
8.999 + * extra arguments are ignored. The number of arguments is
8.1000 + * variable and may be zero. The maximum number of arguments is
8.1001 + * limited by the maximum dimension of a Java array as defined by
8.1002 + * <cite>The Java™ Virtual Machine Specification</cite>.
8.1003 + * The behaviour on a
8.1004 + * <tt>null</tt> argument depends on the <a
8.1005 + * href="../util/Formatter.html#syntax">conversion</a>.
8.1006 + *
8.1007 + * @throws IllegalFormatException
8.1008 + * If a format string contains an illegal syntax, a format
8.1009 + * specifier that is incompatible with the given arguments,
8.1010 + * insufficient arguments given the format string, or other
8.1011 + * illegal conditions. For specification of all possible
8.1012 + * formatting errors, see the <a
8.1013 + * href="../util/Formatter.html#detail">Details</a> section of the
8.1014 + * formatter class specification.
8.1015 + *
8.1016 + * @throws NullPointerException
8.1017 + * If the <tt>format</tt> is <tt>null</tt>
8.1018 + *
8.1019 + * @return This output stream
8.1020 + *
8.1021 + * @since 1.5
8.1022 + */
8.1023 + public PrintStream format(Locale l, String format, Object ... args) {
8.1024 + try {
8.1025 + synchronized (this) {
8.1026 + ensureOpen();
8.1027 + if ((formatter == null)
8.1028 + || (formatter.locale() != l))
8.1029 + formatter = new Formatter(this, l);
8.1030 + formatter.format(l, format, args);
8.1031 + }
8.1032 + } catch (InterruptedIOException x) {
8.1033 + Thread.currentThread().interrupt();
8.1034 + } catch (IOException x) {
8.1035 + trouble = true;
8.1036 + }
8.1037 + return this;
8.1038 + }
8.1039 +
8.1040 + /**
8.1041 + * Appends the specified character sequence to this output stream.
8.1042 + *
8.1043 + * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
8.1044 + * behaves in exactly the same way as the invocation
8.1045 + *
8.1046 + * <pre>
8.1047 + * out.print(csq.toString()) </pre>
8.1048 + *
8.1049 + * <p> Depending on the specification of <tt>toString</tt> for the
8.1050 + * character sequence <tt>csq</tt>, the entire sequence may not be
8.1051 + * appended. For instance, invoking then <tt>toString</tt> method of a
8.1052 + * character buffer will return a subsequence whose content depends upon
8.1053 + * the buffer's position and limit.
8.1054 + *
8.1055 + * @param csq
8.1056 + * The character sequence to append. If <tt>csq</tt> is
8.1057 + * <tt>null</tt>, then the four characters <tt>"null"</tt> are
8.1058 + * appended to this output stream.
8.1059 + *
8.1060 + * @return This output stream
8.1061 + *
8.1062 + * @since 1.5
8.1063 + */
8.1064 + public PrintStream append(CharSequence csq) {
8.1065 + if (csq == null)
8.1066 + print("null");
8.1067 + else
8.1068 + print(csq.toString());
8.1069 + return this;
8.1070 + }
8.1071 +
8.1072 + /**
8.1073 + * Appends a subsequence of the specified character sequence to this output
8.1074 + * stream.
8.1075 + *
8.1076 + * <p> An invocation of this method of the form <tt>out.append(csq, start,
8.1077 + * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
8.1078 + * exactly the same way as the invocation
8.1079 + *
8.1080 + * <pre>
8.1081 + * out.print(csq.subSequence(start, end).toString()) </pre>
8.1082 + *
8.1083 + * @param csq
8.1084 + * The character sequence from which a subsequence will be
8.1085 + * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
8.1086 + * will be appended as if <tt>csq</tt> contained the four
8.1087 + * characters <tt>"null"</tt>.
8.1088 + *
8.1089 + * @param start
8.1090 + * The index of the first character in the subsequence
8.1091 + *
8.1092 + * @param end
8.1093 + * The index of the character following the last character in the
8.1094 + * subsequence
8.1095 + *
8.1096 + * @return This output stream
8.1097 + *
8.1098 + * @throws IndexOutOfBoundsException
8.1099 + * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
8.1100 + * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
8.1101 + * <tt>csq.length()</tt>
8.1102 + *
8.1103 + * @since 1.5
8.1104 + */
8.1105 + public PrintStream append(CharSequence csq, int start, int end) {
8.1106 + CharSequence cs = (csq == null ? "null" : csq);
8.1107 + write(cs.subSequence(start, end).toString());
8.1108 + return this;
8.1109 + }
8.1110 +
8.1111 + /**
8.1112 + * Appends the specified character to this output stream.
8.1113 + *
8.1114 + * <p> An invocation of this method of the form <tt>out.append(c)</tt>
8.1115 + * behaves in exactly the same way as the invocation
8.1116 + *
8.1117 + * <pre>
8.1118 + * out.print(c) </pre>
8.1119 + *
8.1120 + * @param c
8.1121 + * The 16-bit character to append
8.1122 + *
8.1123 + * @return This output stream
8.1124 + *
8.1125 + * @since 1.5
8.1126 + */
8.1127 + public PrintStream append(char c) {
8.1128 + print(c);
8.1129 + return this;
8.1130 + }
8.1131 +
8.1132 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/emul/compact/src/main/java/java/io/PrintWriter.java Sat Sep 07 13:51:24 2013 +0200
9.3 @@ -0,0 +1,1066 @@
9.4 +/*
9.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9.7 + *
9.8 + * This code is free software; you can redistribute it and/or modify it
9.9 + * under the terms of the GNU General Public License version 2 only, as
9.10 + * published by the Free Software Foundation. Oracle designates this
9.11 + * particular file as subject to the "Classpath" exception as provided
9.12 + * by Oracle in the LICENSE file that accompanied this code.
9.13 + *
9.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
9.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9.17 + * version 2 for more details (a copy is included in the LICENSE file that
9.18 + * accompanied this code).
9.19 + *
9.20 + * You should have received a copy of the GNU General Public License version
9.21 + * 2 along with this work; if not, write to the Free Software Foundation,
9.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9.23 + *
9.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
9.25 + * or visit www.oracle.com if you need additional information or have any
9.26 + * questions.
9.27 + */
9.28 +
9.29 +package java.io;
9.30 +
9.31 +import java.util.Objects;
9.32 +import java.util.Formatter;
9.33 +import java.util.Locale;
9.34 +import java.nio.charset.Charset;
9.35 +import java.nio.charset.IllegalCharsetNameException;
9.36 +import java.nio.charset.UnsupportedCharsetException;
9.37 +
9.38 +/**
9.39 + * Prints formatted representations of objects to a text-output stream. This
9.40 + * class implements all of the <tt>print</tt> methods found in {@link
9.41 + * PrintStream}. It does not contain methods for writing raw bytes, for which
9.42 + * a program should use unencoded byte streams.
9.43 + *
9.44 + * <p> Unlike the {@link PrintStream} class, if automatic flushing is enabled
9.45 + * it will be done only when one of the <tt>println</tt>, <tt>printf</tt>, or
9.46 + * <tt>format</tt> methods is invoked, rather than whenever a newline character
9.47 + * happens to be output. These methods use the platform's own notion of line
9.48 + * separator rather than the newline character.
9.49 + *
9.50 + * <p> Methods in this class never throw I/O exceptions, although some of its
9.51 + * constructors may. The client may inquire as to whether any errors have
9.52 + * occurred by invoking {@link #checkError checkError()}.
9.53 + *
9.54 + * @author Frank Yellin
9.55 + * @author Mark Reinhold
9.56 + * @since JDK1.1
9.57 + */
9.58 +
9.59 +public class PrintWriter extends Writer {
9.60 +
9.61 + /**
9.62 + * The underlying character-output stream of this
9.63 + * <code>PrintWriter</code>.
9.64 + *
9.65 + * @since 1.2
9.66 + */
9.67 + protected Writer out;
9.68 +
9.69 + private final boolean autoFlush;
9.70 + private boolean trouble = false;
9.71 + private Formatter formatter;
9.72 + private PrintStream psOut = null;
9.73 +
9.74 + /**
9.75 + * Line separator string. This is the value of the line.separator
9.76 + * property at the moment that the stream was created.
9.77 + */
9.78 + private final String lineSeparator;
9.79 +
9.80 + /**
9.81 + * Returns a charset object for the given charset name.
9.82 + * @throws NullPointerException is csn is null
9.83 + * @throws UnsupportedEncodingException if the charset is not supported
9.84 + */
9.85 + private static Charset toCharset(String csn)
9.86 + throws UnsupportedEncodingException
9.87 + {
9.88 + Objects.requireNonNull(csn, "charsetName");
9.89 + try {
9.90 + return Charset.forName(csn);
9.91 + } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
9.92 + // UnsupportedEncodingException should be thrown
9.93 + throw new UnsupportedEncodingException(csn);
9.94 + }
9.95 + }
9.96 +
9.97 + /**
9.98 + * Creates a new PrintWriter, without automatic line flushing.
9.99 + *
9.100 + * @param out A character-output stream
9.101 + */
9.102 + public PrintWriter (Writer out) {
9.103 + this(out, false);
9.104 + }
9.105 +
9.106 + /**
9.107 + * Creates a new PrintWriter.
9.108 + *
9.109 + * @param out A character-output stream
9.110 + * @param autoFlush A boolean; if true, the <tt>println</tt>,
9.111 + * <tt>printf</tt>, or <tt>format</tt> methods will
9.112 + * flush the output buffer
9.113 + */
9.114 + public PrintWriter(Writer out,
9.115 + boolean autoFlush) {
9.116 + super(out);
9.117 + this.out = out;
9.118 + this.autoFlush = autoFlush;
9.119 + lineSeparator = java.security.AccessController.doPrivileged(
9.120 + new sun.security.action.GetPropertyAction("line.separator"));
9.121 + }
9.122 +
9.123 + /**
9.124 + * Creates a new PrintWriter, without automatic line flushing, from an
9.125 + * existing OutputStream. This convenience constructor creates the
9.126 + * necessary intermediate OutputStreamWriter, which will convert characters
9.127 + * into bytes using the default character encoding.
9.128 + *
9.129 + * @param out An output stream
9.130 + *
9.131 + * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
9.132 + */
9.133 + public PrintWriter(OutputStream out) {
9.134 + this(out, false);
9.135 + }
9.136 +
9.137 + /**
9.138 + * Creates a new PrintWriter from an existing OutputStream. This
9.139 + * convenience constructor creates the necessary intermediate
9.140 + * OutputStreamWriter, which will convert characters into bytes using the
9.141 + * default character encoding.
9.142 + *
9.143 + * @param out An output stream
9.144 + * @param autoFlush A boolean; if true, the <tt>println</tt>,
9.145 + * <tt>printf</tt>, or <tt>format</tt> methods will
9.146 + * flush the output buffer
9.147 + *
9.148 + * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
9.149 + */
9.150 + public PrintWriter(OutputStream out, boolean autoFlush) {
9.151 + this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);
9.152 +
9.153 + // save print stream for error propagation
9.154 + if (out instanceof java.io.PrintStream) {
9.155 + psOut = (PrintStream) out;
9.156 + }
9.157 + }
9.158 +
9.159 + /**
9.160 + * Creates a new PrintWriter, without automatic line flushing, with the
9.161 + * specified file name. This convenience constructor creates the necessary
9.162 + * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
9.163 + * which will encode characters using the {@linkplain
9.164 + * java.nio.charset.Charset#defaultCharset() default charset} for this
9.165 + * instance of the Java virtual machine.
9.166 + *
9.167 + * @param fileName
9.168 + * The name of the file to use as the destination of this writer.
9.169 + * If the file exists then it will be truncated to zero size;
9.170 + * otherwise, a new file will be created. The output will be
9.171 + * written to the file and is buffered.
9.172 + *
9.173 + * @throws FileNotFoundException
9.174 + * If the given string does not denote an existing, writable
9.175 + * regular file and a new regular file of that name cannot be
9.176 + * created, or if some other error occurs while opening or
9.177 + * creating the file
9.178 + *
9.179 + * @throws SecurityException
9.180 + * If a security manager is present and {@link
9.181 + * SecurityManager#checkWrite checkWrite(fileName)} denies write
9.182 + * access to the file
9.183 + *
9.184 + * @since 1.5
9.185 + */
9.186 + public PrintWriter(String fileName) throws FileNotFoundException {
9.187 + this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
9.188 + false);
9.189 + }
9.190 +
9.191 + /* Private constructor */
9.192 + private PrintWriter(Charset charset, File file)
9.193 + throws FileNotFoundException
9.194 + {
9.195 + this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)),
9.196 + false);
9.197 + }
9.198 +
9.199 + /**
9.200 + * Creates a new PrintWriter, without automatic line flushing, with the
9.201 + * specified file name and charset. This convenience constructor creates
9.202 + * the necessary intermediate {@link java.io.OutputStreamWriter
9.203 + * OutputStreamWriter}, which will encode characters using the provided
9.204 + * charset.
9.205 + *
9.206 + * @param fileName
9.207 + * The name of the file to use as the destination of this writer.
9.208 + * If the file exists then it will be truncated to zero size;
9.209 + * otherwise, a new file will be created. The output will be
9.210 + * written to the file and is buffered.
9.211 + *
9.212 + * @param csn
9.213 + * The name of a supported {@linkplain java.nio.charset.Charset
9.214 + * charset}
9.215 + *
9.216 + * @throws FileNotFoundException
9.217 + * If the given string does not denote an existing, writable
9.218 + * regular file and a new regular file of that name cannot be
9.219 + * created, or if some other error occurs while opening or
9.220 + * creating the file
9.221 + *
9.222 + * @throws SecurityException
9.223 + * If a security manager is present and {@link
9.224 + * SecurityManager#checkWrite checkWrite(fileName)} denies write
9.225 + * access to the file
9.226 + *
9.227 + * @throws UnsupportedEncodingException
9.228 + * If the named charset is not supported
9.229 + *
9.230 + * @since 1.5
9.231 + */
9.232 + public PrintWriter(String fileName, String csn)
9.233 + throws FileNotFoundException, UnsupportedEncodingException
9.234 + {
9.235 + this(toCharset(csn), new File(fileName));
9.236 + }
9.237 +
9.238 + /**
9.239 + * Creates a new PrintWriter, without automatic line flushing, with the
9.240 + * specified file. This convenience constructor creates the necessary
9.241 + * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
9.242 + * which will encode characters using the {@linkplain
9.243 + * java.nio.charset.Charset#defaultCharset() default charset} for this
9.244 + * instance of the Java virtual machine.
9.245 + *
9.246 + * @param file
9.247 + * The file to use as the destination of this writer. If the file
9.248 + * exists then it will be truncated to zero size; otherwise, a new
9.249 + * file will be created. The output will be written to the file
9.250 + * and is buffered.
9.251 + *
9.252 + * @throws FileNotFoundException
9.253 + * If the given file object does not denote an existing, writable
9.254 + * regular file and a new regular file of that name cannot be
9.255 + * created, or if some other error occurs while opening or
9.256 + * creating the file
9.257 + *
9.258 + * @throws SecurityException
9.259 + * If a security manager is present and {@link
9.260 + * SecurityManager#checkWrite checkWrite(file.getPath())}
9.261 + * denies write access to the file
9.262 + *
9.263 + * @since 1.5
9.264 + */
9.265 + public PrintWriter(File file) throws FileNotFoundException {
9.266 + this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
9.267 + false);
9.268 + }
9.269 +
9.270 + /**
9.271 + * Creates a new PrintWriter, without automatic line flushing, with the
9.272 + * specified file and charset. This convenience constructor creates the
9.273 + * necessary intermediate {@link java.io.OutputStreamWriter
9.274 + * OutputStreamWriter}, which will encode characters using the provided
9.275 + * charset.
9.276 + *
9.277 + * @param file
9.278 + * The file to use as the destination of this writer. If the file
9.279 + * exists then it will be truncated to zero size; otherwise, a new
9.280 + * file will be created. The output will be written to the file
9.281 + * and is buffered.
9.282 + *
9.283 + * @param csn
9.284 + * The name of a supported {@linkplain java.nio.charset.Charset
9.285 + * charset}
9.286 + *
9.287 + * @throws FileNotFoundException
9.288 + * If the given file object does not denote an existing, writable
9.289 + * regular file and a new regular file of that name cannot be
9.290 + * created, or if some other error occurs while opening or
9.291 + * creating the file
9.292 + *
9.293 + * @throws SecurityException
9.294 + * If a security manager is present and {@link
9.295 + * SecurityManager#checkWrite checkWrite(file.getPath())}
9.296 + * denies write access to the file
9.297 + *
9.298 + * @throws UnsupportedEncodingException
9.299 + * If the named charset is not supported
9.300 + *
9.301 + * @since 1.5
9.302 + */
9.303 + public PrintWriter(File file, String csn)
9.304 + throws FileNotFoundException, UnsupportedEncodingException
9.305 + {
9.306 + this(toCharset(csn), file);
9.307 + }
9.308 +
9.309 + /** Checks to make sure that the stream has not been closed */
9.310 + private void ensureOpen() throws IOException {
9.311 + if (out == null)
9.312 + throw new IOException("Stream closed");
9.313 + }
9.314 +
9.315 + /**
9.316 + * Flushes the stream.
9.317 + * @see #checkError()
9.318 + */
9.319 + public void flush() {
9.320 + try {
9.321 + synchronized (lock) {
9.322 + ensureOpen();
9.323 + out.flush();
9.324 + }
9.325 + }
9.326 + catch (IOException x) {
9.327 + trouble = true;
9.328 + }
9.329 + }
9.330 +
9.331 + /**
9.332 + * Closes the stream and releases any system resources associated
9.333 + * with it. Closing a previously closed stream has no effect.
9.334 + *
9.335 + * @see #checkError()
9.336 + */
9.337 + public void close() {
9.338 + try {
9.339 + synchronized (lock) {
9.340 + if (out == null)
9.341 + return;
9.342 + out.close();
9.343 + out = null;
9.344 + }
9.345 + }
9.346 + catch (IOException x) {
9.347 + trouble = true;
9.348 + }
9.349 + }
9.350 +
9.351 + /**
9.352 + * Flushes the stream if it's not closed and checks its error state.
9.353 + *
9.354 + * @return <code>true</code> if the print stream has encountered an error,
9.355 + * either on the underlying output stream or during a format
9.356 + * conversion.
9.357 + */
9.358 + public boolean checkError() {
9.359 + if (out != null) {
9.360 + flush();
9.361 + }
9.362 + if (out instanceof java.io.PrintWriter) {
9.363 + PrintWriter pw = (PrintWriter) out;
9.364 + return pw.checkError();
9.365 + } else if (psOut != null) {
9.366 + return psOut.checkError();
9.367 + }
9.368 + return trouble;
9.369 + }
9.370 +
9.371 + /**
9.372 + * Indicates that an error has occurred.
9.373 + *
9.374 + * <p> This method will cause subsequent invocations of {@link
9.375 + * #checkError()} to return <tt>true</tt> until {@link
9.376 + * #clearError()} is invoked.
9.377 + */
9.378 + protected void setError() {
9.379 + trouble = true;
9.380 + }
9.381 +
9.382 + /**
9.383 + * Clears the error state of this stream.
9.384 + *
9.385 + * <p> This method will cause subsequent invocations of {@link
9.386 + * #checkError()} to return <tt>false</tt> until another write
9.387 + * operation fails and invokes {@link #setError()}.
9.388 + *
9.389 + * @since 1.6
9.390 + */
9.391 + protected void clearError() {
9.392 + trouble = false;
9.393 + }
9.394 +
9.395 + /*
9.396 + * Exception-catching, synchronized output operations,
9.397 + * which also implement the write() methods of Writer
9.398 + */
9.399 +
9.400 + /**
9.401 + * Writes a single character.
9.402 + * @param c int specifying a character to be written.
9.403 + */
9.404 + public void write(int c) {
9.405 + try {
9.406 + synchronized (lock) {
9.407 + ensureOpen();
9.408 + out.write(c);
9.409 + }
9.410 + }
9.411 + catch (InterruptedIOException x) {
9.412 + Thread.currentThread().interrupt();
9.413 + }
9.414 + catch (IOException x) {
9.415 + trouble = true;
9.416 + }
9.417 + }
9.418 +
9.419 + /**
9.420 + * Writes A Portion of an array of characters.
9.421 + * @param buf Array of characters
9.422 + * @param off Offset from which to start writing characters
9.423 + * @param len Number of characters to write
9.424 + */
9.425 + public void write(char buf[], int off, int len) {
9.426 + try {
9.427 + synchronized (lock) {
9.428 + ensureOpen();
9.429 + out.write(buf, off, len);
9.430 + }
9.431 + }
9.432 + catch (InterruptedIOException x) {
9.433 + Thread.currentThread().interrupt();
9.434 + }
9.435 + catch (IOException x) {
9.436 + trouble = true;
9.437 + }
9.438 + }
9.439 +
9.440 + /**
9.441 + * Writes an array of characters. This method cannot be inherited from the
9.442 + * Writer class because it must suppress I/O exceptions.
9.443 + * @param buf Array of characters to be written
9.444 + */
9.445 + public void write(char buf[]) {
9.446 + write(buf, 0, buf.length);
9.447 + }
9.448 +
9.449 + /**
9.450 + * Writes a portion of a string.
9.451 + * @param s A String
9.452 + * @param off Offset from which to start writing characters
9.453 + * @param len Number of characters to write
9.454 + */
9.455 + public void write(String s, int off, int len) {
9.456 + try {
9.457 + synchronized (lock) {
9.458 + ensureOpen();
9.459 + out.write(s, off, len);
9.460 + }
9.461 + }
9.462 + catch (InterruptedIOException x) {
9.463 + Thread.currentThread().interrupt();
9.464 + }
9.465 + catch (IOException x) {
9.466 + trouble = true;
9.467 + }
9.468 + }
9.469 +
9.470 + /**
9.471 + * Writes a string. This method cannot be inherited from the Writer class
9.472 + * because it must suppress I/O exceptions.
9.473 + * @param s String to be written
9.474 + */
9.475 + public void write(String s) {
9.476 + write(s, 0, s.length());
9.477 + }
9.478 +
9.479 + private void newLine() {
9.480 + try {
9.481 + synchronized (lock) {
9.482 + ensureOpen();
9.483 + out.write(lineSeparator);
9.484 + if (autoFlush)
9.485 + out.flush();
9.486 + }
9.487 + }
9.488 + catch (InterruptedIOException x) {
9.489 + Thread.currentThread().interrupt();
9.490 + }
9.491 + catch (IOException x) {
9.492 + trouble = true;
9.493 + }
9.494 + }
9.495 +
9.496 + /* Methods that do not terminate lines */
9.497 +
9.498 + /**
9.499 + * Prints a boolean value. The string produced by <code>{@link
9.500 + * java.lang.String#valueOf(boolean)}</code> is translated into bytes
9.501 + * according to the platform's default character encoding, and these bytes
9.502 + * are written in exactly the manner of the <code>{@link
9.503 + * #write(int)}</code> method.
9.504 + *
9.505 + * @param b The <code>boolean</code> to be printed
9.506 + */
9.507 + public void print(boolean b) {
9.508 + write(b ? "true" : "false");
9.509 + }
9.510 +
9.511 + /**
9.512 + * Prints a character. The character is translated into one or more bytes
9.513 + * according to the platform's default character encoding, and these bytes
9.514 + * are written in exactly the manner of the <code>{@link
9.515 + * #write(int)}</code> method.
9.516 + *
9.517 + * @param c The <code>char</code> to be printed
9.518 + */
9.519 + public void print(char c) {
9.520 + write(c);
9.521 + }
9.522 +
9.523 + /**
9.524 + * Prints an integer. The string produced by <code>{@link
9.525 + * java.lang.String#valueOf(int)}</code> is translated into bytes according
9.526 + * to the platform's default character encoding, and these bytes are
9.527 + * written in exactly the manner of the <code>{@link #write(int)}</code>
9.528 + * method.
9.529 + *
9.530 + * @param i The <code>int</code> to be printed
9.531 + * @see java.lang.Integer#toString(int)
9.532 + */
9.533 + public void print(int i) {
9.534 + write(String.valueOf(i));
9.535 + }
9.536 +
9.537 + /**
9.538 + * Prints a long integer. The string produced by <code>{@link
9.539 + * java.lang.String#valueOf(long)}</code> is translated into bytes
9.540 + * according to the platform's default character encoding, and these bytes
9.541 + * are written in exactly the manner of the <code>{@link #write(int)}</code>
9.542 + * method.
9.543 + *
9.544 + * @param l The <code>long</code> to be printed
9.545 + * @see java.lang.Long#toString(long)
9.546 + */
9.547 + public void print(long l) {
9.548 + write(String.valueOf(l));
9.549 + }
9.550 +
9.551 + /**
9.552 + * Prints a floating-point number. The string produced by <code>{@link
9.553 + * java.lang.String#valueOf(float)}</code> is translated into bytes
9.554 + * according to the platform's default character encoding, and these bytes
9.555 + * are written in exactly the manner of the <code>{@link #write(int)}</code>
9.556 + * method.
9.557 + *
9.558 + * @param f The <code>float</code> to be printed
9.559 + * @see java.lang.Float#toString(float)
9.560 + */
9.561 + public void print(float f) {
9.562 + write(String.valueOf(f));
9.563 + }
9.564 +
9.565 + /**
9.566 + * Prints a double-precision floating-point number. The string produced by
9.567 + * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
9.568 + * bytes according to the platform's default character encoding, and these
9.569 + * bytes are written in exactly the manner of the <code>{@link
9.570 + * #write(int)}</code> method.
9.571 + *
9.572 + * @param d The <code>double</code> to be printed
9.573 + * @see java.lang.Double#toString(double)
9.574 + */
9.575 + public void print(double d) {
9.576 + write(String.valueOf(d));
9.577 + }
9.578 +
9.579 + /**
9.580 + * Prints an array of characters. The characters are converted into bytes
9.581 + * according to the platform's default character encoding, and these bytes
9.582 + * are written in exactly the manner of the <code>{@link #write(int)}</code>
9.583 + * method.
9.584 + *
9.585 + * @param s The array of chars to be printed
9.586 + *
9.587 + * @throws NullPointerException If <code>s</code> is <code>null</code>
9.588 + */
9.589 + public void print(char s[]) {
9.590 + write(s);
9.591 + }
9.592 +
9.593 + /**
9.594 + * Prints a string. If the argument is <code>null</code> then the string
9.595 + * <code>"null"</code> is printed. Otherwise, the string's characters are
9.596 + * converted into bytes according to the platform's default character
9.597 + * encoding, and these bytes are written in exactly the manner of the
9.598 + * <code>{@link #write(int)}</code> method.
9.599 + *
9.600 + * @param s The <code>String</code> to be printed
9.601 + */
9.602 + public void print(String s) {
9.603 + if (s == null) {
9.604 + s = "null";
9.605 + }
9.606 + write(s);
9.607 + }
9.608 +
9.609 + /**
9.610 + * Prints an object. The string produced by the <code>{@link
9.611 + * java.lang.String#valueOf(Object)}</code> method is translated into bytes
9.612 + * according to the platform's default character encoding, and these bytes
9.613 + * are written in exactly the manner of the <code>{@link #write(int)}</code>
9.614 + * method.
9.615 + *
9.616 + * @param obj The <code>Object</code> to be printed
9.617 + * @see java.lang.Object#toString()
9.618 + */
9.619 + public void print(Object obj) {
9.620 + write(String.valueOf(obj));
9.621 + }
9.622 +
9.623 + /* Methods that do terminate lines */
9.624 +
9.625 + /**
9.626 + * Terminates the current line by writing the line separator string. The
9.627 + * line separator string is defined by the system property
9.628 + * <code>line.separator</code>, and is not necessarily a single newline
9.629 + * character (<code>'\n'</code>).
9.630 + */
9.631 + public void println() {
9.632 + newLine();
9.633 + }
9.634 +
9.635 + /**
9.636 + * Prints a boolean value and then terminates the line. This method behaves
9.637 + * as though it invokes <code>{@link #print(boolean)}</code> and then
9.638 + * <code>{@link #println()}</code>.
9.639 + *
9.640 + * @param x the <code>boolean</code> value to be printed
9.641 + */
9.642 + public void println(boolean x) {
9.643 + synchronized (lock) {
9.644 + print(x);
9.645 + println();
9.646 + }
9.647 + }
9.648 +
9.649 + /**
9.650 + * Prints a character and then terminates the line. This method behaves as
9.651 + * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
9.652 + * #println()}</code>.
9.653 + *
9.654 + * @param x the <code>char</code> value to be printed
9.655 + */
9.656 + public void println(char x) {
9.657 + synchronized (lock) {
9.658 + print(x);
9.659 + println();
9.660 + }
9.661 + }
9.662 +
9.663 + /**
9.664 + * Prints an integer and then terminates the line. This method behaves as
9.665 + * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
9.666 + * #println()}</code>.
9.667 + *
9.668 + * @param x the <code>int</code> value to be printed
9.669 + */
9.670 + public void println(int x) {
9.671 + synchronized (lock) {
9.672 + print(x);
9.673 + println();
9.674 + }
9.675 + }
9.676 +
9.677 + /**
9.678 + * Prints a long integer and then terminates the line. This method behaves
9.679 + * as though it invokes <code>{@link #print(long)}</code> and then
9.680 + * <code>{@link #println()}</code>.
9.681 + *
9.682 + * @param x the <code>long</code> value to be printed
9.683 + */
9.684 + public void println(long x) {
9.685 + synchronized (lock) {
9.686 + print(x);
9.687 + println();
9.688 + }
9.689 + }
9.690 +
9.691 + /**
9.692 + * Prints a floating-point number and then terminates the line. This method
9.693 + * behaves as though it invokes <code>{@link #print(float)}</code> and then
9.694 + * <code>{@link #println()}</code>.
9.695 + *
9.696 + * @param x the <code>float</code> value to be printed
9.697 + */
9.698 + public void println(float x) {
9.699 + synchronized (lock) {
9.700 + print(x);
9.701 + println();
9.702 + }
9.703 + }
9.704 +
9.705 + /**
9.706 + * Prints a double-precision floating-point number and then terminates the
9.707 + * line. This method behaves as though it invokes <code>{@link
9.708 + * #print(double)}</code> and then <code>{@link #println()}</code>.
9.709 + *
9.710 + * @param x the <code>double</code> value to be printed
9.711 + */
9.712 + public void println(double x) {
9.713 + synchronized (lock) {
9.714 + print(x);
9.715 + println();
9.716 + }
9.717 + }
9.718 +
9.719 + /**
9.720 + * Prints an array of characters and then terminates the line. This method
9.721 + * behaves as though it invokes <code>{@link #print(char[])}</code> and then
9.722 + * <code>{@link #println()}</code>.
9.723 + *
9.724 + * @param x the array of <code>char</code> values to be printed
9.725 + */
9.726 + public void println(char x[]) {
9.727 + synchronized (lock) {
9.728 + print(x);
9.729 + println();
9.730 + }
9.731 + }
9.732 +
9.733 + /**
9.734 + * Prints a String and then terminates the line. This method behaves as
9.735 + * though it invokes <code>{@link #print(String)}</code> and then
9.736 + * <code>{@link #println()}</code>.
9.737 + *
9.738 + * @param x the <code>String</code> value to be printed
9.739 + */
9.740 + public void println(String x) {
9.741 + synchronized (lock) {
9.742 + print(x);
9.743 + println();
9.744 + }
9.745 + }
9.746 +
9.747 + /**
9.748 + * Prints an Object and then terminates the line. This method calls
9.749 + * at first String.valueOf(x) to get the printed object's string value,
9.750 + * then behaves as
9.751 + * though it invokes <code>{@link #print(String)}</code> and then
9.752 + * <code>{@link #println()}</code>.
9.753 + *
9.754 + * @param x The <code>Object</code> to be printed.
9.755 + */
9.756 + public void println(Object x) {
9.757 + String s = String.valueOf(x);
9.758 + synchronized (lock) {
9.759 + print(s);
9.760 + println();
9.761 + }
9.762 + }
9.763 +
9.764 + /**
9.765 + * A convenience method to write a formatted string to this writer using
9.766 + * the specified format string and arguments. If automatic flushing is
9.767 + * enabled, calls to this method will flush the output buffer.
9.768 + *
9.769 + * <p> An invocation of this method of the form <tt>out.printf(format,
9.770 + * args)</tt> behaves in exactly the same way as the invocation
9.771 + *
9.772 + * <pre>
9.773 + * out.format(format, args) </pre>
9.774 + *
9.775 + * @param format
9.776 + * A format string as described in <a
9.777 + * href="../util/Formatter.html#syntax">Format string syntax</a>.
9.778 + *
9.779 + * @param args
9.780 + * Arguments referenced by the format specifiers in the format
9.781 + * string. If there are more arguments than format specifiers, the
9.782 + * extra arguments are ignored. The number of arguments is
9.783 + * variable and may be zero. The maximum number of arguments is
9.784 + * limited by the maximum dimension of a Java array as defined by
9.785 + * <cite>The Java™ Virtual Machine Specification</cite>.
9.786 + * The behaviour on a
9.787 + * <tt>null</tt> argument depends on the <a
9.788 + * href="../util/Formatter.html#syntax">conversion</a>.
9.789 + *
9.790 + * @throws IllegalFormatException
9.791 + * If a format string contains an illegal syntax, a format
9.792 + * specifier that is incompatible with the given arguments,
9.793 + * insufficient arguments given the format string, or other
9.794 + * illegal conditions. For specification of all possible
9.795 + * formatting errors, see the <a
9.796 + * href="../util/Formatter.html#detail">Details</a> section of the
9.797 + * formatter class specification.
9.798 + *
9.799 + * @throws NullPointerException
9.800 + * If the <tt>format</tt> is <tt>null</tt>
9.801 + *
9.802 + * @return This writer
9.803 + *
9.804 + * @since 1.5
9.805 + */
9.806 + public PrintWriter printf(String format, Object ... args) {
9.807 + return format(format, args);
9.808 + }
9.809 +
9.810 + /**
9.811 + * A convenience method to write a formatted string to this writer using
9.812 + * the specified format string and arguments. If automatic flushing is
9.813 + * enabled, calls to this method will flush the output buffer.
9.814 + *
9.815 + * <p> An invocation of this method of the form <tt>out.printf(l, format,
9.816 + * args)</tt> behaves in exactly the same way as the invocation
9.817 + *
9.818 + * <pre>
9.819 + * out.format(l, format, args) </pre>
9.820 + *
9.821 + * @param l
9.822 + * The {@linkplain java.util.Locale locale} to apply during
9.823 + * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
9.824 + * is applied.
9.825 + *
9.826 + * @param format
9.827 + * A format string as described in <a
9.828 + * href="../util/Formatter.html#syntax">Format string syntax</a>.
9.829 + *
9.830 + * @param args
9.831 + * Arguments referenced by the format specifiers in the format
9.832 + * string. If there are more arguments than format specifiers, the
9.833 + * extra arguments are ignored. The number of arguments is
9.834 + * variable and may be zero. The maximum number of arguments is
9.835 + * limited by the maximum dimension of a Java array as defined by
9.836 + * <cite>The Java™ Virtual Machine Specification</cite>.
9.837 + * The behaviour on a
9.838 + * <tt>null</tt> argument depends on the <a
9.839 + * href="../util/Formatter.html#syntax">conversion</a>.
9.840 + *
9.841 + * @throws IllegalFormatException
9.842 + * If a format string contains an illegal syntax, a format
9.843 + * specifier that is incompatible with the given arguments,
9.844 + * insufficient arguments given the format string, or other
9.845 + * illegal conditions. For specification of all possible
9.846 + * formatting errors, see the <a
9.847 + * href="../util/Formatter.html#detail">Details</a> section of the
9.848 + * formatter class specification.
9.849 + *
9.850 + * @throws NullPointerException
9.851 + * If the <tt>format</tt> is <tt>null</tt>
9.852 + *
9.853 + * @return This writer
9.854 + *
9.855 + * @since 1.5
9.856 + */
9.857 + public PrintWriter printf(Locale l, String format, Object ... args) {
9.858 + return format(l, format, args);
9.859 + }
9.860 +
9.861 + /**
9.862 + * Writes a formatted string to this writer using the specified format
9.863 + * string and arguments. If automatic flushing is enabled, calls to this
9.864 + * method will flush the output buffer.
9.865 + *
9.866 + * <p> The locale always used is the one returned by {@link
9.867 + * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
9.868 + * previous invocations of other formatting methods on this object.
9.869 + *
9.870 + * @param format
9.871 + * A format string as described in <a
9.872 + * href="../util/Formatter.html#syntax">Format string syntax</a>.
9.873 + *
9.874 + * @param args
9.875 + * Arguments referenced by the format specifiers in the format
9.876 + * string. If there are more arguments than format specifiers, the
9.877 + * extra arguments are ignored. The number of arguments is
9.878 + * variable and may be zero. The maximum number of arguments is
9.879 + * limited by the maximum dimension of a Java array as defined by
9.880 + * <cite>The Java™ Virtual Machine Specification</cite>.
9.881 + * The behaviour on a
9.882 + * <tt>null</tt> argument depends on the <a
9.883 + * href="../util/Formatter.html#syntax">conversion</a>.
9.884 + *
9.885 + * @throws IllegalFormatException
9.886 + * If a format string contains an illegal syntax, a format
9.887 + * specifier that is incompatible with the given arguments,
9.888 + * insufficient arguments given the format string, or other
9.889 + * illegal conditions. For specification of all possible
9.890 + * formatting errors, see the <a
9.891 + * href="../util/Formatter.html#detail">Details</a> section of the
9.892 + * Formatter class specification.
9.893 + *
9.894 + * @throws NullPointerException
9.895 + * If the <tt>format</tt> is <tt>null</tt>
9.896 + *
9.897 + * @return This writer
9.898 + *
9.899 + * @since 1.5
9.900 + */
9.901 + public PrintWriter format(String format, Object ... args) {
9.902 + try {
9.903 + synchronized (lock) {
9.904 + ensureOpen();
9.905 + if ((formatter == null)
9.906 + || (formatter.locale() != Locale.getDefault()))
9.907 + formatter = new Formatter(this);
9.908 + formatter.format(Locale.getDefault(), format, args);
9.909 + if (autoFlush)
9.910 + out.flush();
9.911 + }
9.912 + } catch (InterruptedIOException x) {
9.913 + Thread.currentThread().interrupt();
9.914 + } catch (IOException x) {
9.915 + trouble = true;
9.916 + }
9.917 + return this;
9.918 + }
9.919 +
9.920 + /**
9.921 + * Writes a formatted string to this writer using the specified format
9.922 + * string and arguments. If automatic flushing is enabled, calls to this
9.923 + * method will flush the output buffer.
9.924 + *
9.925 + * @param l
9.926 + * The {@linkplain java.util.Locale locale} to apply during
9.927 + * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
9.928 + * is applied.
9.929 + *
9.930 + * @param format
9.931 + * A format string as described in <a
9.932 + * href="../util/Formatter.html#syntax">Format string syntax</a>.
9.933 + *
9.934 + * @param args
9.935 + * Arguments referenced by the format specifiers in the format
9.936 + * string. If there are more arguments than format specifiers, the
9.937 + * extra arguments are ignored. The number of arguments is
9.938 + * variable and may be zero. The maximum number of arguments is
9.939 + * limited by the maximum dimension of a Java array as defined by
9.940 + * <cite>The Java™ Virtual Machine Specification</cite>.
9.941 + * The behaviour on a
9.942 + * <tt>null</tt> argument depends on the <a
9.943 + * href="../util/Formatter.html#syntax">conversion</a>.
9.944 + *
9.945 + * @throws IllegalFormatException
9.946 + * If a format string contains an illegal syntax, a format
9.947 + * specifier that is incompatible with the given arguments,
9.948 + * insufficient arguments given the format string, or other
9.949 + * illegal conditions. For specification of all possible
9.950 + * formatting errors, see the <a
9.951 + * href="../util/Formatter.html#detail">Details</a> section of the
9.952 + * formatter class specification.
9.953 + *
9.954 + * @throws NullPointerException
9.955 + * If the <tt>format</tt> is <tt>null</tt>
9.956 + *
9.957 + * @return This writer
9.958 + *
9.959 + * @since 1.5
9.960 + */
9.961 + public PrintWriter format(Locale l, String format, Object ... args) {
9.962 + try {
9.963 + synchronized (lock) {
9.964 + ensureOpen();
9.965 + if ((formatter == null) || (formatter.locale() != l))
9.966 + formatter = new Formatter(this, l);
9.967 + formatter.format(l, format, args);
9.968 + if (autoFlush)
9.969 + out.flush();
9.970 + }
9.971 + } catch (InterruptedIOException x) {
9.972 + Thread.currentThread().interrupt();
9.973 + } catch (IOException x) {
9.974 + trouble = true;
9.975 + }
9.976 + return this;
9.977 + }
9.978 +
9.979 + /**
9.980 + * Appends the specified character sequence to this writer.
9.981 + *
9.982 + * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
9.983 + * behaves in exactly the same way as the invocation
9.984 + *
9.985 + * <pre>
9.986 + * out.write(csq.toString()) </pre>
9.987 + *
9.988 + * <p> Depending on the specification of <tt>toString</tt> for the
9.989 + * character sequence <tt>csq</tt>, the entire sequence may not be
9.990 + * appended. For instance, invoking the <tt>toString</tt> method of a
9.991 + * character buffer will return a subsequence whose content depends upon
9.992 + * the buffer's position and limit.
9.993 + *
9.994 + * @param csq
9.995 + * The character sequence to append. If <tt>csq</tt> is
9.996 + * <tt>null</tt>, then the four characters <tt>"null"</tt> are
9.997 + * appended to this writer.
9.998 + *
9.999 + * @return This writer
9.1000 + *
9.1001 + * @since 1.5
9.1002 + */
9.1003 + public PrintWriter append(CharSequence csq) {
9.1004 + if (csq == null)
9.1005 + write("null");
9.1006 + else
9.1007 + write(csq.toString());
9.1008 + return this;
9.1009 + }
9.1010 +
9.1011 + /**
9.1012 + * Appends a subsequence of the specified character sequence to this writer.
9.1013 + *
9.1014 + * <p> An invocation of this method of the form <tt>out.append(csq, start,
9.1015 + * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
9.1016 + * exactly the same way as the invocation
9.1017 + *
9.1018 + * <pre>
9.1019 + * out.write(csq.subSequence(start, end).toString()) </pre>
9.1020 + *
9.1021 + * @param csq
9.1022 + * The character sequence from which a subsequence will be
9.1023 + * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
9.1024 + * will be appended as if <tt>csq</tt> contained the four
9.1025 + * characters <tt>"null"</tt>.
9.1026 + *
9.1027 + * @param start
9.1028 + * The index of the first character in the subsequence
9.1029 + *
9.1030 + * @param end
9.1031 + * The index of the character following the last character in the
9.1032 + * subsequence
9.1033 + *
9.1034 + * @return This writer
9.1035 + *
9.1036 + * @throws IndexOutOfBoundsException
9.1037 + * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
9.1038 + * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
9.1039 + * <tt>csq.length()</tt>
9.1040 + *
9.1041 + * @since 1.5
9.1042 + */
9.1043 + public PrintWriter append(CharSequence csq, int start, int end) {
9.1044 + CharSequence cs = (csq == null ? "null" : csq);
9.1045 + write(cs.subSequence(start, end).toString());
9.1046 + return this;
9.1047 + }
9.1048 +
9.1049 + /**
9.1050 + * Appends the specified character to this writer.
9.1051 + *
9.1052 + * <p> An invocation of this method of the form <tt>out.append(c)</tt>
9.1053 + * behaves in exactly the same way as the invocation
9.1054 + *
9.1055 + * <pre>
9.1056 + * out.write(c) </pre>
9.1057 + *
9.1058 + * @param c
9.1059 + * The 16-bit character to append
9.1060 + *
9.1061 + * @return This writer
9.1062 + *
9.1063 + * @since 1.5
9.1064 + */
9.1065 + public PrintWriter append(char c) {
9.1066 + write(c);
9.1067 + return this;
9.1068 + }
9.1069 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/emul/compact/src/main/java/java/io/Writer.java Sat Sep 07 13:51:24 2013 +0200
10.3 @@ -0,0 +1,325 @@
10.4 +/*
10.5 + * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.7 + *
10.8 + * This code is free software; you can redistribute it and/or modify it
10.9 + * under the terms of the GNU General Public License version 2 only, as
10.10 + * published by the Free Software Foundation. Oracle designates this
10.11 + * particular file as subject to the "Classpath" exception as provided
10.12 + * by Oracle in the LICENSE file that accompanied this code.
10.13 + *
10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10.17 + * version 2 for more details (a copy is included in the LICENSE file that
10.18 + * accompanied this code).
10.19 + *
10.20 + * You should have received a copy of the GNU General Public License version
10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10.23 + *
10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
10.25 + * or visit www.oracle.com if you need additional information or have any
10.26 + * questions.
10.27 + */
10.28 +
10.29 +package java.io;
10.30 +
10.31 +
10.32 +/**
10.33 + * Abstract class for writing to character streams. The only methods that a
10.34 + * subclass must implement are write(char[], int, int), flush(), and close().
10.35 + * Most subclasses, however, will override some of the methods defined here in
10.36 + * order to provide higher efficiency, additional functionality, or both.
10.37 + *
10.38 + * @see Writer
10.39 + * @see BufferedWriter
10.40 + * @see CharArrayWriter
10.41 + * @see FilterWriter
10.42 + * @see OutputStreamWriter
10.43 + * @see FileWriter
10.44 + * @see PipedWriter
10.45 + * @see PrintWriter
10.46 + * @see StringWriter
10.47 + * @see Reader
10.48 + *
10.49 + * @author Mark Reinhold
10.50 + * @since JDK1.1
10.51 + */
10.52 +
10.53 +public abstract class Writer implements Appendable, Closeable, Flushable {
10.54 +
10.55 + /**
10.56 + * Temporary buffer used to hold writes of strings and single characters
10.57 + */
10.58 + private char[] writeBuffer;
10.59 +
10.60 + /**
10.61 + * Size of writeBuffer, must be >= 1
10.62 + */
10.63 + private final int writeBufferSize = 1024;
10.64 +
10.65 + /**
10.66 + * The object used to synchronize operations on this stream. For
10.67 + * efficiency, a character-stream object may use an object other than
10.68 + * itself to protect critical sections. A subclass should therefore use
10.69 + * the object in this field rather than <tt>this</tt> or a synchronized
10.70 + * method.
10.71 + */
10.72 + protected Object lock;
10.73 +
10.74 + /**
10.75 + * Creates a new character-stream writer whose critical sections will
10.76 + * synchronize on the writer itself.
10.77 + */
10.78 + protected Writer() {
10.79 + this.lock = this;
10.80 + }
10.81 +
10.82 + /**
10.83 + * Creates a new character-stream writer whose critical sections will
10.84 + * synchronize on the given object.
10.85 + *
10.86 + * @param lock
10.87 + * Object to synchronize on
10.88 + */
10.89 + protected Writer(Object lock) {
10.90 + if (lock == null) {
10.91 + throw new NullPointerException();
10.92 + }
10.93 + this.lock = lock;
10.94 + }
10.95 +
10.96 + /**
10.97 + * Writes a single character. The character to be written is contained in
10.98 + * the 16 low-order bits of the given integer value; the 16 high-order bits
10.99 + * are ignored.
10.100 + *
10.101 + * <p> Subclasses that intend to support efficient single-character output
10.102 + * should override this method.
10.103 + *
10.104 + * @param c
10.105 + * int specifying a character to be written
10.106 + *
10.107 + * @throws IOException
10.108 + * If an I/O error occurs
10.109 + */
10.110 + public void write(int c) throws IOException {
10.111 + synchronized (lock) {
10.112 + if (writeBuffer == null){
10.113 + writeBuffer = new char[writeBufferSize];
10.114 + }
10.115 + writeBuffer[0] = (char) c;
10.116 + write(writeBuffer, 0, 1);
10.117 + }
10.118 + }
10.119 +
10.120 + /**
10.121 + * Writes an array of characters.
10.122 + *
10.123 + * @param cbuf
10.124 + * Array of characters to be written
10.125 + *
10.126 + * @throws IOException
10.127 + * If an I/O error occurs
10.128 + */
10.129 + public void write(char cbuf[]) throws IOException {
10.130 + write(cbuf, 0, cbuf.length);
10.131 + }
10.132 +
10.133 + /**
10.134 + * Writes a portion of an array of characters.
10.135 + *
10.136 + * @param cbuf
10.137 + * Array of characters
10.138 + *
10.139 + * @param off
10.140 + * Offset from which to start writing characters
10.141 + *
10.142 + * @param len
10.143 + * Number of characters to write
10.144 + *
10.145 + * @throws IOException
10.146 + * If an I/O error occurs
10.147 + */
10.148 + abstract public void write(char cbuf[], int off, int len) throws IOException;
10.149 +
10.150 + /**
10.151 + * Writes a string.
10.152 + *
10.153 + * @param str
10.154 + * String to be written
10.155 + *
10.156 + * @throws IOException
10.157 + * If an I/O error occurs
10.158 + */
10.159 + public void write(String str) throws IOException {
10.160 + write(str, 0, str.length());
10.161 + }
10.162 +
10.163 + /**
10.164 + * Writes a portion of a string.
10.165 + *
10.166 + * @param str
10.167 + * A String
10.168 + *
10.169 + * @param off
10.170 + * Offset from which to start writing characters
10.171 + *
10.172 + * @param len
10.173 + * Number of characters to write
10.174 + *
10.175 + * @throws IndexOutOfBoundsException
10.176 + * If <tt>off</tt> is negative, or <tt>len</tt> is negative,
10.177 + * or <tt>off+len</tt> is negative or greater than the length
10.178 + * of the given string
10.179 + *
10.180 + * @throws IOException
10.181 + * If an I/O error occurs
10.182 + */
10.183 + public void write(String str, int off, int len) throws IOException {
10.184 + synchronized (lock) {
10.185 + char cbuf[];
10.186 + if (len <= writeBufferSize) {
10.187 + if (writeBuffer == null) {
10.188 + writeBuffer = new char[writeBufferSize];
10.189 + }
10.190 + cbuf = writeBuffer;
10.191 + } else { // Don't permanently allocate very large buffers.
10.192 + cbuf = new char[len];
10.193 + }
10.194 + str.getChars(off, (off + len), cbuf, 0);
10.195 + write(cbuf, 0, len);
10.196 + }
10.197 + }
10.198 +
10.199 + /**
10.200 + * Appends the specified character sequence to this writer.
10.201 + *
10.202 + * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
10.203 + * behaves in exactly the same way as the invocation
10.204 + *
10.205 + * <pre>
10.206 + * out.write(csq.toString()) </pre>
10.207 + *
10.208 + * <p> Depending on the specification of <tt>toString</tt> for the
10.209 + * character sequence <tt>csq</tt>, the entire sequence may not be
10.210 + * appended. For instance, invoking the <tt>toString</tt> method of a
10.211 + * character buffer will return a subsequence whose content depends upon
10.212 + * the buffer's position and limit.
10.213 + *
10.214 + * @param csq
10.215 + * The character sequence to append. If <tt>csq</tt> is
10.216 + * <tt>null</tt>, then the four characters <tt>"null"</tt> are
10.217 + * appended to this writer.
10.218 + *
10.219 + * @return This writer
10.220 + *
10.221 + * @throws IOException
10.222 + * If an I/O error occurs
10.223 + *
10.224 + * @since 1.5
10.225 + */
10.226 + public Writer append(CharSequence csq) throws IOException {
10.227 + if (csq == null)
10.228 + write("null");
10.229 + else
10.230 + write(csq.toString());
10.231 + return this;
10.232 + }
10.233 +
10.234 + /**
10.235 + * Appends a subsequence of the specified character sequence to this writer.
10.236 + * <tt>Appendable</tt>.
10.237 + *
10.238 + * <p> An invocation of this method of the form <tt>out.append(csq, start,
10.239 + * end)</tt> when <tt>csq</tt> is not <tt>null</tt> behaves in exactly the
10.240 + * same way as the invocation
10.241 + *
10.242 + * <pre>
10.243 + * out.write(csq.subSequence(start, end).toString()) </pre>
10.244 + *
10.245 + * @param csq
10.246 + * The character sequence from which a subsequence will be
10.247 + * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
10.248 + * will be appended as if <tt>csq</tt> contained the four
10.249 + * characters <tt>"null"</tt>.
10.250 + *
10.251 + * @param start
10.252 + * The index of the first character in the subsequence
10.253 + *
10.254 + * @param end
10.255 + * The index of the character following the last character in the
10.256 + * subsequence
10.257 + *
10.258 + * @return This writer
10.259 + *
10.260 + * @throws IndexOutOfBoundsException
10.261 + * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
10.262 + * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
10.263 + * <tt>csq.length()</tt>
10.264 + *
10.265 + * @throws IOException
10.266 + * If an I/O error occurs
10.267 + *
10.268 + * @since 1.5
10.269 + */
10.270 + public Writer append(CharSequence csq, int start, int end) throws IOException {
10.271 + CharSequence cs = (csq == null ? "null" : csq);
10.272 + write(cs.subSequence(start, end).toString());
10.273 + return this;
10.274 + }
10.275 +
10.276 + /**
10.277 + * Appends the specified character to this writer.
10.278 + *
10.279 + * <p> An invocation of this method of the form <tt>out.append(c)</tt>
10.280 + * behaves in exactly the same way as the invocation
10.281 + *
10.282 + * <pre>
10.283 + * out.write(c) </pre>
10.284 + *
10.285 + * @param c
10.286 + * The 16-bit character to append
10.287 + *
10.288 + * @return This writer
10.289 + *
10.290 + * @throws IOException
10.291 + * If an I/O error occurs
10.292 + *
10.293 + * @since 1.5
10.294 + */
10.295 + public Writer append(char c) throws IOException {
10.296 + write(c);
10.297 + return this;
10.298 + }
10.299 +
10.300 + /**
10.301 + * Flushes the stream. If the stream has saved any characters from the
10.302 + * various write() methods in a buffer, write them immediately to their
10.303 + * intended destination. Then, if that destination is another character or
10.304 + * byte stream, flush it. Thus one flush() invocation will flush all the
10.305 + * buffers in a chain of Writers and OutputStreams.
10.306 + *
10.307 + * <p> If the intended destination of this stream is an abstraction provided
10.308 + * by the underlying operating system, for example a file, then flushing the
10.309 + * stream guarantees only that bytes previously written to the stream are
10.310 + * passed to the operating system for writing; it does not guarantee that
10.311 + * they are actually written to a physical device such as a disk drive.
10.312 + *
10.313 + * @throws IOException
10.314 + * If an I/O error occurs
10.315 + */
10.316 + abstract public void flush() throws IOException;
10.317 +
10.318 + /**
10.319 + * Closes the stream, flushing it first. Once the stream has been closed,
10.320 + * further write() or flush() invocations will cause an IOException to be
10.321 + * thrown. Closing a previously closed stream has no effect.
10.322 + *
10.323 + * @throws IOException
10.324 + * If an I/O error occurs
10.325 + */
10.326 + abstract public void close() throws IOException;
10.327 +
10.328 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/emul/compact/src/main/java/java/lang/StackOverflowError.java Sat Sep 07 13:51:24 2013 +0200
11.3 @@ -0,0 +1,55 @@
11.4 +/*
11.5 + * Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.7 + *
11.8 + * This code is free software; you can redistribute it and/or modify it
11.9 + * under the terms of the GNU General Public License version 2 only, as
11.10 + * published by the Free Software Foundation. Oracle designates this
11.11 + * particular file as subject to the "Classpath" exception as provided
11.12 + * by Oracle in the LICENSE file that accompanied this code.
11.13 + *
11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.17 + * version 2 for more details (a copy is included in the LICENSE file that
11.18 + * accompanied this code).
11.19 + *
11.20 + * You should have received a copy of the GNU General Public License version
11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.23 + *
11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
11.25 + * or visit www.oracle.com if you need additional information or have any
11.26 + * questions.
11.27 + */
11.28 +
11.29 +package java.lang;
11.30 +
11.31 +/**
11.32 + * Thrown when a stack overflow occurs because an application
11.33 + * recurses too deeply.
11.34 + *
11.35 + * @author unascribed
11.36 + * @since JDK1.0
11.37 + */
11.38 +public
11.39 +class StackOverflowError extends VirtualMachineError {
11.40 + private static final long serialVersionUID = 8609175038441759607L;
11.41 +
11.42 + /**
11.43 + * Constructs a <code>StackOverflowError</code> with no detail message.
11.44 + */
11.45 + public StackOverflowError() {
11.46 + super();
11.47 + }
11.48 +
11.49 + /**
11.50 + * Constructs a <code>StackOverflowError</code> with the specified
11.51 + * detail message.
11.52 + *
11.53 + * @param s the detail message.
11.54 + */
11.55 + public StackOverflowError(String s) {
11.56 + super(s);
11.57 + }
11.58 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/emul/compact/src/main/java/java/lang/System.java Sat Sep 07 13:51:24 2013 +0200
12.3 @@ -0,0 +1,1206 @@
12.4 +/*
12.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.7 + *
12.8 + * This code is free software; you can redistribute it and/or modify it
12.9 + * under the terms of the GNU General Public License version 2 only, as
12.10 + * published by the Free Software Foundation. Oracle designates this
12.11 + * particular file as subject to the "Classpath" exception as provided
12.12 + * by Oracle in the LICENSE file that accompanied this code.
12.13 + *
12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.17 + * version 2 for more details (a copy is included in the LICENSE file that
12.18 + * accompanied this code).
12.19 + *
12.20 + * You should have received a copy of the GNU General Public License version
12.21 + * 2 along with this work; if not, write to the Free Software Foundation,
12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.23 + *
12.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
12.25 + * or visit www.oracle.com if you need additional information or have any
12.26 + * questions.
12.27 + */
12.28 +package java.lang;
12.29 +
12.30 +import java.io.*;
12.31 +import java.util.Properties;
12.32 +import java.util.PropertyPermission;
12.33 +import java.util.StringTokenizer;
12.34 +import java.security.AccessController;
12.35 +import java.security.PrivilegedAction;
12.36 +import java.security.AllPermission;
12.37 +import java.nio.channels.Channel;
12.38 +import java.nio.channels.spi.SelectorProvider;
12.39 +import sun.nio.ch.Interruptible;
12.40 +import sun.reflect.Reflection;
12.41 +import sun.security.util.SecurityConstants;
12.42 +import sun.reflect.annotation.AnnotationType;
12.43 +
12.44 +/**
12.45 + * The <code>System</code> class contains several useful class fields
12.46 + * and methods. It cannot be instantiated.
12.47 + *
12.48 + * <p>Among the facilities provided by the <code>System</code> class
12.49 + * are standard input, standard output, and error output streams;
12.50 + * access to externally defined properties and environment
12.51 + * variables; a means of loading files and libraries; and a utility
12.52 + * method for quickly copying a portion of an array.
12.53 + *
12.54 + * @author unascribed
12.55 + * @since JDK1.0
12.56 + */
12.57 +public final class System {
12.58 +
12.59 + /* register the natives via the static initializer.
12.60 + *
12.61 + * VM will invoke the initializeSystemClass method to complete
12.62 + * the initialization for this class separated from clinit.
12.63 + * Note that to use properties set by the VM, see the constraints
12.64 + * described in the initializeSystemClass method.
12.65 + */
12.66 + private static native void registerNatives();
12.67 + static {
12.68 + registerNatives();
12.69 + }
12.70 +
12.71 + /** Don't let anyone instantiate this class */
12.72 + private System() {
12.73 + }
12.74 +
12.75 + /**
12.76 + * The "standard" input stream. This stream is already
12.77 + * open and ready to supply input data. Typically this stream
12.78 + * corresponds to keyboard input or another input source specified by
12.79 + * the host environment or user.
12.80 + */
12.81 + public final static InputStream in = null;
12.82 +
12.83 + /**
12.84 + * The "standard" output stream. This stream is already
12.85 + * open and ready to accept output data. Typically this stream
12.86 + * corresponds to display output or another output destination
12.87 + * specified by the host environment or user.
12.88 + * <p>
12.89 + * For simple stand-alone Java applications, a typical way to write
12.90 + * a line of output data is:
12.91 + * <blockquote><pre>
12.92 + * System.out.println(data)
12.93 + * </pre></blockquote>
12.94 + * <p>
12.95 + * See the <code>println</code> methods in class <code>PrintStream</code>.
12.96 + *
12.97 + * @see java.io.PrintStream#println()
12.98 + * @see java.io.PrintStream#println(boolean)
12.99 + * @see java.io.PrintStream#println(char)
12.100 + * @see java.io.PrintStream#println(char[])
12.101 + * @see java.io.PrintStream#println(double)
12.102 + * @see java.io.PrintStream#println(float)
12.103 + * @see java.io.PrintStream#println(int)
12.104 + * @see java.io.PrintStream#println(long)
12.105 + * @see java.io.PrintStream#println(java.lang.Object)
12.106 + * @see java.io.PrintStream#println(java.lang.String)
12.107 + */
12.108 + public final static PrintStream out = null;
12.109 +
12.110 + /**
12.111 + * The "standard" error output stream. This stream is already
12.112 + * open and ready to accept output data.
12.113 + * <p>
12.114 + * Typically this stream corresponds to display output or another
12.115 + * output destination specified by the host environment or user. By
12.116 + * convention, this output stream is used to display error messages
12.117 + * or other information that should come to the immediate attention
12.118 + * of a user even if the principal output stream, the value of the
12.119 + * variable <code>out</code>, has been redirected to a file or other
12.120 + * destination that is typically not continuously monitored.
12.121 + */
12.122 + public final static PrintStream err = null;
12.123 +
12.124 + /* The security manager for the system.
12.125 + */
12.126 + private static volatile SecurityManager security = null;
12.127 +
12.128 + /**
12.129 + * Reassigns the "standard" input stream.
12.130 + *
12.131 + * <p>First, if there is a security manager, its <code>checkPermission</code>
12.132 + * method is called with a <code>RuntimePermission("setIO")</code> permission
12.133 + * to see if it's ok to reassign the "standard" input stream.
12.134 + * <p>
12.135 + *
12.136 + * @param in the new standard input stream.
12.137 + *
12.138 + * @throws SecurityException
12.139 + * if a security manager exists and its
12.140 + * <code>checkPermission</code> method doesn't allow
12.141 + * reassigning of the standard input stream.
12.142 + *
12.143 + * @see SecurityManager#checkPermission
12.144 + * @see java.lang.RuntimePermission
12.145 + *
12.146 + * @since JDK1.1
12.147 + */
12.148 + public static void setIn(InputStream in) {
12.149 + checkIO();
12.150 + setIn0(in);
12.151 + }
12.152 +
12.153 + /**
12.154 + * Reassigns the "standard" output stream.
12.155 + *
12.156 + * <p>First, if there is a security manager, its <code>checkPermission</code>
12.157 + * method is called with a <code>RuntimePermission("setIO")</code> permission
12.158 + * to see if it's ok to reassign the "standard" output stream.
12.159 + *
12.160 + * @param out the new standard output stream
12.161 + *
12.162 + * @throws SecurityException
12.163 + * if a security manager exists and its
12.164 + * <code>checkPermission</code> method doesn't allow
12.165 + * reassigning of the standard output stream.
12.166 + *
12.167 + * @see SecurityManager#checkPermission
12.168 + * @see java.lang.RuntimePermission
12.169 + *
12.170 + * @since JDK1.1
12.171 + */
12.172 + public static void setOut(PrintStream out) {
12.173 + checkIO();
12.174 + setOut0(out);
12.175 + }
12.176 +
12.177 + /**
12.178 + * Reassigns the "standard" error output stream.
12.179 + *
12.180 + * <p>First, if there is a security manager, its <code>checkPermission</code>
12.181 + * method is called with a <code>RuntimePermission("setIO")</code> permission
12.182 + * to see if it's ok to reassign the "standard" error output stream.
12.183 + *
12.184 + * @param err the new standard error output stream.
12.185 + *
12.186 + * @throws SecurityException
12.187 + * if a security manager exists and its
12.188 + * <code>checkPermission</code> method doesn't allow
12.189 + * reassigning of the standard error output stream.
12.190 + *
12.191 + * @see SecurityManager#checkPermission
12.192 + * @see java.lang.RuntimePermission
12.193 + *
12.194 + * @since JDK1.1
12.195 + */
12.196 + public static void setErr(PrintStream err) {
12.197 + checkIO();
12.198 + setErr0(err);
12.199 + }
12.200 +
12.201 + private static volatile Console cons = null;
12.202 + /**
12.203 + * Returns the unique {@link java.io.Console Console} object associated
12.204 + * with the current Java virtual machine, if any.
12.205 + *
12.206 + * @return The system console, if any, otherwise <tt>null</tt>.
12.207 + *
12.208 + * @since 1.6
12.209 + */
12.210 + public static Console console() {
12.211 + if (cons == null) {
12.212 + synchronized (System.class) {
12.213 + cons = sun.misc.SharedSecrets.getJavaIOAccess().console();
12.214 + }
12.215 + }
12.216 + return cons;
12.217 + }
12.218 +
12.219 + /**
12.220 + * Returns the channel inherited from the entity that created this
12.221 + * Java virtual machine.
12.222 + *
12.223 + * <p> This method returns the channel obtained by invoking the
12.224 + * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
12.225 + * inheritedChannel} method of the system-wide default
12.226 + * {@link java.nio.channels.spi.SelectorProvider} object. </p>
12.227 + *
12.228 + * <p> In addition to the network-oriented channels described in
12.229 + * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel
12.230 + * inheritedChannel}, this method may return other kinds of
12.231 + * channels in the future.
12.232 + *
12.233 + * @return The inherited channel, if any, otherwise <tt>null</tt>.
12.234 + *
12.235 + * @throws IOException
12.236 + * If an I/O error occurs
12.237 + *
12.238 + * @throws SecurityException
12.239 + * If a security manager is present and it does not
12.240 + * permit access to the channel.
12.241 + *
12.242 + * @since 1.5
12.243 + */
12.244 + public static Channel inheritedChannel() throws IOException {
12.245 + return SelectorProvider.provider().inheritedChannel();
12.246 + }
12.247 +
12.248 + private static void checkIO() {
12.249 + SecurityManager sm = getSecurityManager();
12.250 + if (sm != null) {
12.251 + sm.checkPermission(new RuntimePermission("setIO"));
12.252 + }
12.253 + }
12.254 +
12.255 + private static native void setIn0(InputStream in);
12.256 + private static native void setOut0(PrintStream out);
12.257 + private static native void setErr0(PrintStream err);
12.258 +
12.259 + /**
12.260 + * Sets the System security.
12.261 + *
12.262 + * <p> If there is a security manager already installed, this method first
12.263 + * calls the security manager's <code>checkPermission</code> method
12.264 + * with a <code>RuntimePermission("setSecurityManager")</code>
12.265 + * permission to ensure it's ok to replace the existing
12.266 + * security manager.
12.267 + * This may result in throwing a <code>SecurityException</code>.
12.268 + *
12.269 + * <p> Otherwise, the argument is established as the current
12.270 + * security manager. If the argument is <code>null</code> and no
12.271 + * security manager has been established, then no action is taken and
12.272 + * the method simply returns.
12.273 + *
12.274 + * @param s the security manager.
12.275 + * @exception SecurityException if the security manager has already
12.276 + * been set and its <code>checkPermission</code> method
12.277 + * doesn't allow it to be replaced.
12.278 + * @see #getSecurityManager
12.279 + * @see SecurityManager#checkPermission
12.280 + * @see java.lang.RuntimePermission
12.281 + */
12.282 + public static
12.283 + void setSecurityManager(final SecurityManager s) {
12.284 + try {
12.285 + s.checkPackageAccess("java.lang");
12.286 + } catch (Exception e) {
12.287 + // no-op
12.288 + }
12.289 + setSecurityManager0(s);
12.290 + }
12.291 +
12.292 + private static synchronized
12.293 + void setSecurityManager0(final SecurityManager s) {
12.294 + SecurityManager sm = getSecurityManager();
12.295 + if (sm != null) {
12.296 + // ask the currently installed security manager if we
12.297 + // can replace it.
12.298 + sm.checkPermission(new RuntimePermission
12.299 + ("setSecurityManager"));
12.300 + }
12.301 +
12.302 + if ((s != null) && (s.getClass().getClassLoader() != null)) {
12.303 + // New security manager class is not on bootstrap classpath.
12.304 + // Cause policy to get initialized before we install the new
12.305 + // security manager, in order to prevent infinite loops when
12.306 + // trying to initialize the policy (which usually involves
12.307 + // accessing some security and/or system properties, which in turn
12.308 + // calls the installed security manager's checkPermission method
12.309 + // which will loop infinitely if there is a non-system class
12.310 + // (in this case: the new security manager class) on the stack).
12.311 + AccessController.doPrivileged(new PrivilegedAction<Object>() {
12.312 + public Object run() {
12.313 + s.getClass().getProtectionDomain().implies
12.314 + (SecurityConstants.ALL_PERMISSION);
12.315 + return null;
12.316 + }
12.317 + });
12.318 + }
12.319 +
12.320 + security = s;
12.321 + }
12.322 +
12.323 + /**
12.324 + * Gets the system security interface.
12.325 + *
12.326 + * @return if a security manager has already been established for the
12.327 + * current application, then that security manager is returned;
12.328 + * otherwise, <code>null</code> is returned.
12.329 + * @see #setSecurityManager
12.330 + */
12.331 + public static SecurityManager getSecurityManager() {
12.332 + return security;
12.333 + }
12.334 +
12.335 + /**
12.336 + * Returns the current time in milliseconds. Note that
12.337 + * while the unit of time of the return value is a millisecond,
12.338 + * the granularity of the value depends on the underlying
12.339 + * operating system and may be larger. For example, many
12.340 + * operating systems measure time in units of tens of
12.341 + * milliseconds.
12.342 + *
12.343 + * <p> See the description of the class <code>Date</code> for
12.344 + * a discussion of slight discrepancies that may arise between
12.345 + * "computer time" and coordinated universal time (UTC).
12.346 + *
12.347 + * @return the difference, measured in milliseconds, between
12.348 + * the current time and midnight, January 1, 1970 UTC.
12.349 + * @see java.util.Date
12.350 + */
12.351 + public static native long currentTimeMillis();
12.352 +
12.353 + /**
12.354 + * Returns the current value of the running Java Virtual Machine's
12.355 + * high-resolution time source, in nanoseconds.
12.356 + *
12.357 + * <p>This method can only be used to measure elapsed time and is
12.358 + * not related to any other notion of system or wall-clock time.
12.359 + * The value returned represents nanoseconds since some fixed but
12.360 + * arbitrary <i>origin</i> time (perhaps in the future, so values
12.361 + * may be negative). The same origin is used by all invocations of
12.362 + * this method in an instance of a Java virtual machine; other
12.363 + * virtual machine instances are likely to use a different origin.
12.364 + *
12.365 + * <p>This method provides nanosecond precision, but not necessarily
12.366 + * nanosecond resolution (that is, how frequently the value changes)
12.367 + * - no guarantees are made except that the resolution is at least as
12.368 + * good as that of {@link #currentTimeMillis()}.
12.369 + *
12.370 + * <p>Differences in successive calls that span greater than
12.371 + * approximately 292 years (2<sup>63</sup> nanoseconds) will not
12.372 + * correctly compute elapsed time due to numerical overflow.
12.373 + *
12.374 + * <p>The values returned by this method become meaningful only when
12.375 + * the difference between two such values, obtained within the same
12.376 + * instance of a Java virtual machine, is computed.
12.377 + *
12.378 + * <p> For example, to measure how long some code takes to execute:
12.379 + * <pre> {@code
12.380 + * long startTime = System.nanoTime();
12.381 + * // ... the code being measured ...
12.382 + * long estimatedTime = System.nanoTime() - startTime;}</pre>
12.383 + *
12.384 + * <p>To compare two nanoTime values
12.385 + * <pre> {@code
12.386 + * long t0 = System.nanoTime();
12.387 + * ...
12.388 + * long t1 = System.nanoTime();}</pre>
12.389 + *
12.390 + * one should use {@code t1 - t0 < 0}, not {@code t1 < t0},
12.391 + * because of the possibility of numerical overflow.
12.392 + *
12.393 + * @return the current value of the running Java Virtual Machine's
12.394 + * high-resolution time source, in nanoseconds
12.395 + * @since 1.5
12.396 + */
12.397 + public static native long nanoTime();
12.398 +
12.399 + /**
12.400 + * Copies an array from the specified source array, beginning at the
12.401 + * specified position, to the specified position of the destination array.
12.402 + * A subsequence of array components are copied from the source
12.403 + * array referenced by <code>src</code> to the destination array
12.404 + * referenced by <code>dest</code>. The number of components copied is
12.405 + * equal to the <code>length</code> argument. The components at
12.406 + * positions <code>srcPos</code> through
12.407 + * <code>srcPos+length-1</code> in the source array are copied into
12.408 + * positions <code>destPos</code> through
12.409 + * <code>destPos+length-1</code>, respectively, of the destination
12.410 + * array.
12.411 + * <p>
12.412 + * If the <code>src</code> and <code>dest</code> arguments refer to the
12.413 + * same array object, then the copying is performed as if the
12.414 + * components at positions <code>srcPos</code> through
12.415 + * <code>srcPos+length-1</code> were first copied to a temporary
12.416 + * array with <code>length</code> components and then the contents of
12.417 + * the temporary array were copied into positions
12.418 + * <code>destPos</code> through <code>destPos+length-1</code> of the
12.419 + * destination array.
12.420 + * <p>
12.421 + * If <code>dest</code> is <code>null</code>, then a
12.422 + * <code>NullPointerException</code> is thrown.
12.423 + * <p>
12.424 + * If <code>src</code> is <code>null</code>, then a
12.425 + * <code>NullPointerException</code> is thrown and the destination
12.426 + * array is not modified.
12.427 + * <p>
12.428 + * Otherwise, if any of the following is true, an
12.429 + * <code>ArrayStoreException</code> is thrown and the destination is
12.430 + * not modified:
12.431 + * <ul>
12.432 + * <li>The <code>src</code> argument refers to an object that is not an
12.433 + * array.
12.434 + * <li>The <code>dest</code> argument refers to an object that is not an
12.435 + * array.
12.436 + * <li>The <code>src</code> argument and <code>dest</code> argument refer
12.437 + * to arrays whose component types are different primitive types.
12.438 + * <li>The <code>src</code> argument refers to an array with a primitive
12.439 + * component type and the <code>dest</code> argument refers to an array
12.440 + * with a reference component type.
12.441 + * <li>The <code>src</code> argument refers to an array with a reference
12.442 + * component type and the <code>dest</code> argument refers to an array
12.443 + * with a primitive component type.
12.444 + * </ul>
12.445 + * <p>
12.446 + * Otherwise, if any of the following is true, an
12.447 + * <code>IndexOutOfBoundsException</code> is
12.448 + * thrown and the destination is not modified:
12.449 + * <ul>
12.450 + * <li>The <code>srcPos</code> argument is negative.
12.451 + * <li>The <code>destPos</code> argument is negative.
12.452 + * <li>The <code>length</code> argument is negative.
12.453 + * <li><code>srcPos+length</code> is greater than
12.454 + * <code>src.length</code>, the length of the source array.
12.455 + * <li><code>destPos+length</code> is greater than
12.456 + * <code>dest.length</code>, the length of the destination array.
12.457 + * </ul>
12.458 + * <p>
12.459 + * Otherwise, if any actual component of the source array from
12.460 + * position <code>srcPos</code> through
12.461 + * <code>srcPos+length-1</code> cannot be converted to the component
12.462 + * type of the destination array by assignment conversion, an
12.463 + * <code>ArrayStoreException</code> is thrown. In this case, let
12.464 + * <b><i>k</i></b> be the smallest nonnegative integer less than
12.465 + * length such that <code>src[srcPos+</code><i>k</i><code>]</code>
12.466 + * cannot be converted to the component type of the destination
12.467 + * array; when the exception is thrown, source array components from
12.468 + * positions <code>srcPos</code> through
12.469 + * <code>srcPos+</code><i>k</i><code>-1</code>
12.470 + * will already have been copied to destination array positions
12.471 + * <code>destPos</code> through
12.472 + * <code>destPos+</code><i>k</I><code>-1</code> and no other
12.473 + * positions of the destination array will have been modified.
12.474 + * (Because of the restrictions already itemized, this
12.475 + * paragraph effectively applies only to the situation where both
12.476 + * arrays have component types that are reference types.)
12.477 + *
12.478 + * @param src the source array.
12.479 + * @param srcPos starting position in the source array.
12.480 + * @param dest the destination array.
12.481 + * @param destPos starting position in the destination data.
12.482 + * @param length the number of array elements to be copied.
12.483 + * @exception IndexOutOfBoundsException if copying would cause
12.484 + * access of data outside array bounds.
12.485 + * @exception ArrayStoreException if an element in the <code>src</code>
12.486 + * array could not be stored into the <code>dest</code> array
12.487 + * because of a type mismatch.
12.488 + * @exception NullPointerException if either <code>src</code> or
12.489 + * <code>dest</code> is <code>null</code>.
12.490 + */
12.491 + public static native void arraycopy(Object src, int srcPos,
12.492 + Object dest, int destPos,
12.493 + int length);
12.494 +
12.495 + /**
12.496 + * Returns the same hash code for the given object as
12.497 + * would be returned by the default method hashCode(),
12.498 + * whether or not the given object's class overrides
12.499 + * hashCode().
12.500 + * The hash code for the null reference is zero.
12.501 + *
12.502 + * @param x object for which the hashCode is to be calculated
12.503 + * @return the hashCode
12.504 + * @since JDK1.1
12.505 + */
12.506 + public static native int identityHashCode(Object x);
12.507 +
12.508 + /**
12.509 + * System properties. The following properties are guaranteed to be defined:
12.510 + * <dl>
12.511 + * <dt>java.version <dd>Java version number
12.512 + * <dt>java.vendor <dd>Java vendor specific string
12.513 + * <dt>java.vendor.url <dd>Java vendor URL
12.514 + * <dt>java.home <dd>Java installation directory
12.515 + * <dt>java.class.version <dd>Java class version number
12.516 + * <dt>java.class.path <dd>Java classpath
12.517 + * <dt>os.name <dd>Operating System Name
12.518 + * <dt>os.arch <dd>Operating System Architecture
12.519 + * <dt>os.version <dd>Operating System Version
12.520 + * <dt>file.separator <dd>File separator ("/" on Unix)
12.521 + * <dt>path.separator <dd>Path separator (":" on Unix)
12.522 + * <dt>line.separator <dd>Line separator ("\n" on Unix)
12.523 + * <dt>user.name <dd>User account name
12.524 + * <dt>user.home <dd>User home directory
12.525 + * <dt>user.dir <dd>User's current working directory
12.526 + * </dl>
12.527 + */
12.528 +
12.529 + private static Properties props;
12.530 + private static native Properties initProperties(Properties props);
12.531 +
12.532 + /**
12.533 + * Determines the current system properties.
12.534 + * <p>
12.535 + * First, if there is a security manager, its
12.536 + * <code>checkPropertiesAccess</code> method is called with no
12.537 + * arguments. This may result in a security exception.
12.538 + * <p>
12.539 + * The current set of system properties for use by the
12.540 + * {@link #getProperty(String)} method is returned as a
12.541 + * <code>Properties</code> object. If there is no current set of
12.542 + * system properties, a set of system properties is first created and
12.543 + * initialized. This set of system properties always includes values
12.544 + * for the following keys:
12.545 + * <table summary="Shows property keys and associated values">
12.546 + * <tr><th>Key</th>
12.547 + * <th>Description of Associated Value</th></tr>
12.548 + * <tr><td><code>java.version</code></td>
12.549 + * <td>Java Runtime Environment version</td></tr>
12.550 + * <tr><td><code>java.vendor</code></td>
12.551 + * <td>Java Runtime Environment vendor</td></tr
12.552 + * <tr><td><code>java.vendor.url</code></td>
12.553 + * <td>Java vendor URL</td></tr>
12.554 + * <tr><td><code>java.home</code></td>
12.555 + * <td>Java installation directory</td></tr>
12.556 + * <tr><td><code>java.vm.specification.version</code></td>
12.557 + * <td>Java Virtual Machine specification version</td></tr>
12.558 + * <tr><td><code>java.vm.specification.vendor</code></td>
12.559 + * <td>Java Virtual Machine specification vendor</td></tr>
12.560 + * <tr><td><code>java.vm.specification.name</code></td>
12.561 + * <td>Java Virtual Machine specification name</td></tr>
12.562 + * <tr><td><code>java.vm.version</code></td>
12.563 + * <td>Java Virtual Machine implementation version</td></tr>
12.564 + * <tr><td><code>java.vm.vendor</code></td>
12.565 + * <td>Java Virtual Machine implementation vendor</td></tr>
12.566 + * <tr><td><code>java.vm.name</code></td>
12.567 + * <td>Java Virtual Machine implementation name</td></tr>
12.568 + * <tr><td><code>java.specification.version</code></td>
12.569 + * <td>Java Runtime Environment specification version</td></tr>
12.570 + * <tr><td><code>java.specification.vendor</code></td>
12.571 + * <td>Java Runtime Environment specification vendor</td></tr>
12.572 + * <tr><td><code>java.specification.name</code></td>
12.573 + * <td>Java Runtime Environment specification name</td></tr>
12.574 + * <tr><td><code>java.class.version</code></td>
12.575 + * <td>Java class format version number</td></tr>
12.576 + * <tr><td><code>java.class.path</code></td>
12.577 + * <td>Java class path</td></tr>
12.578 + * <tr><td><code>java.library.path</code></td>
12.579 + * <td>List of paths to search when loading libraries</td></tr>
12.580 + * <tr><td><code>java.io.tmpdir</code></td>
12.581 + * <td>Default temp file path</td></tr>
12.582 + * <tr><td><code>java.compiler</code></td>
12.583 + * <td>Name of JIT compiler to use</td></tr>
12.584 + * <tr><td><code>java.ext.dirs</code></td>
12.585 + * <td>Path of extension directory or directories</td></tr>
12.586 + * <tr><td><code>os.name</code></td>
12.587 + * <td>Operating system name</td></tr>
12.588 + * <tr><td><code>os.arch</code></td>
12.589 + * <td>Operating system architecture</td></tr>
12.590 + * <tr><td><code>os.version</code></td>
12.591 + * <td>Operating system version</td></tr>
12.592 + * <tr><td><code>file.separator</code></td>
12.593 + * <td>File separator ("/" on UNIX)</td></tr>
12.594 + * <tr><td><code>path.separator</code></td>
12.595 + * <td>Path separator (":" on UNIX)</td></tr>
12.596 + * <tr><td><code>line.separator</code></td>
12.597 + * <td>Line separator ("\n" on UNIX)</td></tr>
12.598 + * <tr><td><code>user.name</code></td>
12.599 + * <td>User's account name</td></tr>
12.600 + * <tr><td><code>user.home</code></td>
12.601 + * <td>User's home directory</td></tr>
12.602 + * <tr><td><code>user.dir</code></td>
12.603 + * <td>User's current working directory</td></tr>
12.604 + * </table>
12.605 + * <p>
12.606 + * Multiple paths in a system property value are separated by the path
12.607 + * separator character of the platform.
12.608 + * <p>
12.609 + * Note that even if the security manager does not permit the
12.610 + * <code>getProperties</code> operation, it may choose to permit the
12.611 + * {@link #getProperty(String)} operation.
12.612 + *
12.613 + * @return the system properties
12.614 + * @exception SecurityException if a security manager exists and its
12.615 + * <code>checkPropertiesAccess</code> method doesn't allow access
12.616 + * to the system properties.
12.617 + * @see #setProperties
12.618 + * @see java.lang.SecurityException
12.619 + * @see java.lang.SecurityManager#checkPropertiesAccess()
12.620 + * @see java.util.Properties
12.621 + */
12.622 + public static Properties getProperties() {
12.623 + SecurityManager sm = getSecurityManager();
12.624 + if (sm != null) {
12.625 + sm.checkPropertiesAccess();
12.626 + }
12.627 +
12.628 + return props;
12.629 + }
12.630 +
12.631 + /**
12.632 + * Returns the system-dependent line separator string. It always
12.633 + * returns the same value - the initial value of the {@linkplain
12.634 + * #getProperty(String) system property} {@code line.separator}.
12.635 + *
12.636 + * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
12.637 + * Windows systems it returns {@code "\r\n"}.
12.638 + */
12.639 + public static String lineSeparator() {
12.640 + return lineSeparator;
12.641 + }
12.642 +
12.643 + private static String lineSeparator;
12.644 +
12.645 + /**
12.646 + * Sets the system properties to the <code>Properties</code>
12.647 + * argument.
12.648 + * <p>
12.649 + * First, if there is a security manager, its
12.650 + * <code>checkPropertiesAccess</code> method is called with no
12.651 + * arguments. This may result in a security exception.
12.652 + * <p>
12.653 + * The argument becomes the current set of system properties for use
12.654 + * by the {@link #getProperty(String)} method. If the argument is
12.655 + * <code>null</code>, then the current set of system properties is
12.656 + * forgotten.
12.657 + *
12.658 + * @param props the new system properties.
12.659 + * @exception SecurityException if a security manager exists and its
12.660 + * <code>checkPropertiesAccess</code> method doesn't allow access
12.661 + * to the system properties.
12.662 + * @see #getProperties
12.663 + * @see java.util.Properties
12.664 + * @see java.lang.SecurityException
12.665 + * @see java.lang.SecurityManager#checkPropertiesAccess()
12.666 + */
12.667 + public static void setProperties(Properties props) {
12.668 + SecurityManager sm = getSecurityManager();
12.669 + if (sm != null) {
12.670 + sm.checkPropertiesAccess();
12.671 + }
12.672 + if (props == null) {
12.673 + props = new Properties();
12.674 + initProperties(props);
12.675 + }
12.676 + System.props = props;
12.677 + }
12.678 +
12.679 + /**
12.680 + * Gets the system property indicated by the specified key.
12.681 + * <p>
12.682 + * First, if there is a security manager, its
12.683 + * <code>checkPropertyAccess</code> method is called with the key as
12.684 + * its argument. This may result in a SecurityException.
12.685 + * <p>
12.686 + * If there is no current set of system properties, a set of system
12.687 + * properties is first created and initialized in the same manner as
12.688 + * for the <code>getProperties</code> method.
12.689 + *
12.690 + * @param key the name of the system property.
12.691 + * @return the string value of the system property,
12.692 + * or <code>null</code> if there is no property with that key.
12.693 + *
12.694 + * @exception SecurityException if a security manager exists and its
12.695 + * <code>checkPropertyAccess</code> method doesn't allow
12.696 + * access to the specified system property.
12.697 + * @exception NullPointerException if <code>key</code> is
12.698 + * <code>null</code>.
12.699 + * @exception IllegalArgumentException if <code>key</code> is empty.
12.700 + * @see #setProperty
12.701 + * @see java.lang.SecurityException
12.702 + * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
12.703 + * @see java.lang.System#getProperties()
12.704 + */
12.705 + public static String getProperty(String key) {
12.706 + checkKey(key);
12.707 + SecurityManager sm = getSecurityManager();
12.708 + if (sm != null) {
12.709 + sm.checkPropertyAccess(key);
12.710 + }
12.711 +
12.712 + return props.getProperty(key);
12.713 + }
12.714 +
12.715 + /**
12.716 + * Gets the system property indicated by the specified key.
12.717 + * <p>
12.718 + * First, if there is a security manager, its
12.719 + * <code>checkPropertyAccess</code> method is called with the
12.720 + * <code>key</code> as its argument.
12.721 + * <p>
12.722 + * If there is no current set of system properties, a set of system
12.723 + * properties is first created and initialized in the same manner as
12.724 + * for the <code>getProperties</code> method.
12.725 + *
12.726 + * @param key the name of the system property.
12.727 + * @param def a default value.
12.728 + * @return the string value of the system property,
12.729 + * or the default value if there is no property with that key.
12.730 + *
12.731 + * @exception SecurityException if a security manager exists and its
12.732 + * <code>checkPropertyAccess</code> method doesn't allow
12.733 + * access to the specified system property.
12.734 + * @exception NullPointerException if <code>key</code> is
12.735 + * <code>null</code>.
12.736 + * @exception IllegalArgumentException if <code>key</code> is empty.
12.737 + * @see #setProperty
12.738 + * @see java.lang.SecurityManager#checkPropertyAccess(java.lang.String)
12.739 + * @see java.lang.System#getProperties()
12.740 + */
12.741 + public static String getProperty(String key, String def) {
12.742 + checkKey(key);
12.743 + SecurityManager sm = getSecurityManager();
12.744 + if (sm != null) {
12.745 + sm.checkPropertyAccess(key);
12.746 + }
12.747 +
12.748 + return props.getProperty(key, def);
12.749 + }
12.750 +
12.751 + /**
12.752 + * Sets the system property indicated by the specified key.
12.753 + * <p>
12.754 + * First, if a security manager exists, its
12.755 + * <code>SecurityManager.checkPermission</code> method
12.756 + * is called with a <code>PropertyPermission(key, "write")</code>
12.757 + * permission. This may result in a SecurityException being thrown.
12.758 + * If no exception is thrown, the specified property is set to the given
12.759 + * value.
12.760 + * <p>
12.761 + *
12.762 + * @param key the name of the system property.
12.763 + * @param value the value of the system property.
12.764 + * @return the previous value of the system property,
12.765 + * or <code>null</code> if it did not have one.
12.766 + *
12.767 + * @exception SecurityException if a security manager exists and its
12.768 + * <code>checkPermission</code> method doesn't allow
12.769 + * setting of the specified property.
12.770 + * @exception NullPointerException if <code>key</code> or
12.771 + * <code>value</code> is <code>null</code>.
12.772 + * @exception IllegalArgumentException if <code>key</code> is empty.
12.773 + * @see #getProperty
12.774 + * @see java.lang.System#getProperty(java.lang.String)
12.775 + * @see java.lang.System#getProperty(java.lang.String, java.lang.String)
12.776 + * @see java.util.PropertyPermission
12.777 + * @see SecurityManager#checkPermission
12.778 + * @since 1.2
12.779 + */
12.780 + public static String setProperty(String key, String value) {
12.781 + checkKey(key);
12.782 + SecurityManager sm = getSecurityManager();
12.783 + if (sm != null) {
12.784 + sm.checkPermission(new PropertyPermission(key,
12.785 + SecurityConstants.PROPERTY_WRITE_ACTION));
12.786 + }
12.787 +
12.788 + return (String) props.setProperty(key, value);
12.789 + }
12.790 +
12.791 + /**
12.792 + * Removes the system property indicated by the specified key.
12.793 + * <p>
12.794 + * First, if a security manager exists, its
12.795 + * <code>SecurityManager.checkPermission</code> method
12.796 + * is called with a <code>PropertyPermission(key, "write")</code>
12.797 + * permission. This may result in a SecurityException being thrown.
12.798 + * If no exception is thrown, the specified property is removed.
12.799 + * <p>
12.800 + *
12.801 + * @param key the name of the system property to be removed.
12.802 + * @return the previous string value of the system property,
12.803 + * or <code>null</code> if there was no property with that key.
12.804 + *
12.805 + * @exception SecurityException if a security manager exists and its
12.806 + * <code>checkPropertyAccess</code> method doesn't allow
12.807 + * access to the specified system property.
12.808 + * @exception NullPointerException if <code>key</code> is
12.809 + * <code>null</code>.
12.810 + * @exception IllegalArgumentException if <code>key</code> is empty.
12.811 + * @see #getProperty
12.812 + * @see #setProperty
12.813 + * @see java.util.Properties
12.814 + * @see java.lang.SecurityException
12.815 + * @see java.lang.SecurityManager#checkPropertiesAccess()
12.816 + * @since 1.5
12.817 + */
12.818 + public static String clearProperty(String key) {
12.819 + checkKey(key);
12.820 + SecurityManager sm = getSecurityManager();
12.821 + if (sm != null) {
12.822 + sm.checkPermission(new PropertyPermission(key, "write"));
12.823 + }
12.824 +
12.825 + return (String) props.remove(key);
12.826 + }
12.827 +
12.828 + private static void checkKey(String key) {
12.829 + if (key == null) {
12.830 + throw new NullPointerException("key can't be null");
12.831 + }
12.832 + if (key.equals("")) {
12.833 + throw new IllegalArgumentException("key can't be empty");
12.834 + }
12.835 + }
12.836 +
12.837 + /**
12.838 + * Gets the value of the specified environment variable. An
12.839 + * environment variable is a system-dependent external named
12.840 + * value.
12.841 + *
12.842 + * <p>If a security manager exists, its
12.843 + * {@link SecurityManager#checkPermission checkPermission}
12.844 + * method is called with a
12.845 + * <code>{@link RuntimePermission}("getenv."+name)</code>
12.846 + * permission. This may result in a {@link SecurityException}
12.847 + * being thrown. If no exception is thrown the value of the
12.848 + * variable <code>name</code> is returned.
12.849 + *
12.850 + * <p><a name="EnvironmentVSSystemProperties"><i>System
12.851 + * properties</i> and <i>environment variables</i></a> are both
12.852 + * conceptually mappings between names and values. Both
12.853 + * mechanisms can be used to pass user-defined information to a
12.854 + * Java process. Environment variables have a more global effect,
12.855 + * because they are visible to all descendants of the process
12.856 + * which defines them, not just the immediate Java subprocess.
12.857 + * They can have subtly different semantics, such as case
12.858 + * insensitivity, on different operating systems. For these
12.859 + * reasons, environment variables are more likely to have
12.860 + * unintended side effects. It is best to use system properties
12.861 + * where possible. Environment variables should be used when a
12.862 + * global effect is desired, or when an external system interface
12.863 + * requires an environment variable (such as <code>PATH</code>).
12.864 + *
12.865 + * <p>On UNIX systems the alphabetic case of <code>name</code> is
12.866 + * typically significant, while on Microsoft Windows systems it is
12.867 + * typically not. For example, the expression
12.868 + * <code>System.getenv("FOO").equals(System.getenv("foo"))</code>
12.869 + * is likely to be true on Microsoft Windows.
12.870 + *
12.871 + * @param name the name of the environment variable
12.872 + * @return the string value of the variable, or <code>null</code>
12.873 + * if the variable is not defined in the system environment
12.874 + * @throws NullPointerException if <code>name</code> is <code>null</code>
12.875 + * @throws SecurityException
12.876 + * if a security manager exists and its
12.877 + * {@link SecurityManager#checkPermission checkPermission}
12.878 + * method doesn't allow access to the environment variable
12.879 + * <code>name</code>
12.880 + * @see #getenv()
12.881 + * @see ProcessBuilder#environment()
12.882 + */
12.883 + public static String getenv(String name) {
12.884 + SecurityManager sm = getSecurityManager();
12.885 + if (sm != null) {
12.886 + sm.checkPermission(new RuntimePermission("getenv."+name));
12.887 + }
12.888 +
12.889 + return ProcessEnvironment.getenv(name);
12.890 + }
12.891 +
12.892 +
12.893 + /**
12.894 + * Returns an unmodifiable string map view of the current system environment.
12.895 + * The environment is a system-dependent mapping from names to
12.896 + * values which is passed from parent to child processes.
12.897 + *
12.898 + * <p>If the system does not support environment variables, an
12.899 + * empty map is returned.
12.900 + *
12.901 + * <p>The returned map will never contain null keys or values.
12.902 + * Attempting to query the presence of a null key or value will
12.903 + * throw a {@link NullPointerException}. Attempting to query
12.904 + * the presence of a key or value which is not of type
12.905 + * {@link String} will throw a {@link ClassCastException}.
12.906 + *
12.907 + * <p>The returned map and its collection views may not obey the
12.908 + * general contract of the {@link Object#equals} and
12.909 + * {@link Object#hashCode} methods.
12.910 + *
12.911 + * <p>The returned map is typically case-sensitive on all platforms.
12.912 + *
12.913 + * <p>If a security manager exists, its
12.914 + * {@link SecurityManager#checkPermission checkPermission}
12.915 + * method is called with a
12.916 + * <code>{@link RuntimePermission}("getenv.*")</code>
12.917 + * permission. This may result in a {@link SecurityException} being
12.918 + * thrown.
12.919 + *
12.920 + * <p>When passing information to a Java subprocess,
12.921 + * <a href=#EnvironmentVSSystemProperties>system properties</a>
12.922 + * are generally preferred over environment variables.
12.923 + *
12.924 + * @return the environment as a map of variable names to values
12.925 + * @throws SecurityException
12.926 + * if a security manager exists and its
12.927 + * {@link SecurityManager#checkPermission checkPermission}
12.928 + * method doesn't allow access to the process environment
12.929 + * @see #getenv(String)
12.930 + * @see ProcessBuilder#environment()
12.931 + * @since 1.5
12.932 + */
12.933 + public static java.util.Map<String,String> getenv() {
12.934 + SecurityManager sm = getSecurityManager();
12.935 + if (sm != null) {
12.936 + sm.checkPermission(new RuntimePermission("getenv.*"));
12.937 + }
12.938 +
12.939 + return ProcessEnvironment.getenv();
12.940 + }
12.941 +
12.942 + /**
12.943 + * Terminates the currently running Java Virtual Machine. The
12.944 + * argument serves as a status code; by convention, a nonzero status
12.945 + * code indicates abnormal termination.
12.946 + * <p>
12.947 + * This method calls the <code>exit</code> method in class
12.948 + * <code>Runtime</code>. This method never returns normally.
12.949 + * <p>
12.950 + * The call <code>System.exit(n)</code> is effectively equivalent to
12.951 + * the call:
12.952 + * <blockquote><pre>
12.953 + * Runtime.getRuntime().exit(n)
12.954 + * </pre></blockquote>
12.955 + *
12.956 + * @param status exit status.
12.957 + * @throws SecurityException
12.958 + * if a security manager exists and its <code>checkExit</code>
12.959 + * method doesn't allow exit with the specified status.
12.960 + * @see java.lang.Runtime#exit(int)
12.961 + */
12.962 + public static void exit(int status) {
12.963 + Runtime.getRuntime().exit(status);
12.964 + }
12.965 +
12.966 + /**
12.967 + * Runs the garbage collector.
12.968 + * <p>
12.969 + * Calling the <code>gc</code> method suggests that the Java Virtual
12.970 + * Machine expend effort toward recycling unused objects in order to
12.971 + * make the memory they currently occupy available for quick reuse.
12.972 + * When control returns from the method call, the Java Virtual
12.973 + * Machine has made a best effort to reclaim space from all discarded
12.974 + * objects.
12.975 + * <p>
12.976 + * The call <code>System.gc()</code> is effectively equivalent to the
12.977 + * call:
12.978 + * <blockquote><pre>
12.979 + * Runtime.getRuntime().gc()
12.980 + * </pre></blockquote>
12.981 + *
12.982 + * @see java.lang.Runtime#gc()
12.983 + */
12.984 + public static void gc() {
12.985 + Runtime.getRuntime().gc();
12.986 + }
12.987 +
12.988 + /**
12.989 + * Runs the finalization methods of any objects pending finalization.
12.990 + * <p>
12.991 + * Calling this method suggests that the Java Virtual Machine expend
12.992 + * effort toward running the <code>finalize</code> methods of objects
12.993 + * that have been found to be discarded but whose <code>finalize</code>
12.994 + * methods have not yet been run. When control returns from the
12.995 + * method call, the Java Virtual Machine has made a best effort to
12.996 + * complete all outstanding finalizations.
12.997 + * <p>
12.998 + * The call <code>System.runFinalization()</code> is effectively
12.999 + * equivalent to the call:
12.1000 + * <blockquote><pre>
12.1001 + * Runtime.getRuntime().runFinalization()
12.1002 + * </pre></blockquote>
12.1003 + *
12.1004 + * @see java.lang.Runtime#runFinalization()
12.1005 + */
12.1006 + public static void runFinalization() {
12.1007 + Runtime.getRuntime().runFinalization();
12.1008 + }
12.1009 +
12.1010 + /**
12.1011 + * Enable or disable finalization on exit; doing so specifies that the
12.1012 + * finalizers of all objects that have finalizers that have not yet been
12.1013 + * automatically invoked are to be run before the Java runtime exits.
12.1014 + * By default, finalization on exit is disabled.
12.1015 + *
12.1016 + * <p>If there is a security manager,
12.1017 + * its <code>checkExit</code> method is first called
12.1018 + * with 0 as its argument to ensure the exit is allowed.
12.1019 + * This could result in a SecurityException.
12.1020 + *
12.1021 + * @deprecated This method is inherently unsafe. It may result in
12.1022 + * finalizers being called on live objects while other threads are
12.1023 + * concurrently manipulating those objects, resulting in erratic
12.1024 + * behavior or deadlock.
12.1025 + * @param value indicating enabling or disabling of finalization
12.1026 + * @throws SecurityException
12.1027 + * if a security manager exists and its <code>checkExit</code>
12.1028 + * method doesn't allow the exit.
12.1029 + *
12.1030 + * @see java.lang.Runtime#exit(int)
12.1031 + * @see java.lang.Runtime#gc()
12.1032 + * @see java.lang.SecurityManager#checkExit(int)
12.1033 + * @since JDK1.1
12.1034 + */
12.1035 + @Deprecated
12.1036 + public static void runFinalizersOnExit(boolean value) {
12.1037 + Runtime.getRuntime().runFinalizersOnExit(value);
12.1038 + }
12.1039 +
12.1040 + /**
12.1041 + * Loads a code file with the specified filename from the local file
12.1042 + * system as a dynamic library. The filename
12.1043 + * argument must be a complete path name.
12.1044 + * <p>
12.1045 + * The call <code>System.load(name)</code> is effectively equivalent
12.1046 + * to the call:
12.1047 + * <blockquote><pre>
12.1048 + * Runtime.getRuntime().load(name)
12.1049 + * </pre></blockquote>
12.1050 + *
12.1051 + * @param filename the file to load.
12.1052 + * @exception SecurityException if a security manager exists and its
12.1053 + * <code>checkLink</code> method doesn't allow
12.1054 + * loading of the specified dynamic library
12.1055 + * @exception UnsatisfiedLinkError if the file does not exist.
12.1056 + * @exception NullPointerException if <code>filename</code> is
12.1057 + * <code>null</code>
12.1058 + * @see java.lang.Runtime#load(java.lang.String)
12.1059 + * @see java.lang.SecurityManager#checkLink(java.lang.String)
12.1060 + */
12.1061 + public static void load(String filename) {
12.1062 + Runtime.getRuntime().load0(getCallerClass(), filename);
12.1063 + }
12.1064 +
12.1065 + /**
12.1066 + * Loads the system library specified by the <code>libname</code>
12.1067 + * argument. The manner in which a library name is mapped to the
12.1068 + * actual system library is system dependent.
12.1069 + * <p>
12.1070 + * The call <code>System.loadLibrary(name)</code> is effectively
12.1071 + * equivalent to the call
12.1072 + * <blockquote><pre>
12.1073 + * Runtime.getRuntime().loadLibrary(name)
12.1074 + * </pre></blockquote>
12.1075 + *
12.1076 + * @param libname the name of the library.
12.1077 + * @exception SecurityException if a security manager exists and its
12.1078 + * <code>checkLink</code> method doesn't allow
12.1079 + * loading of the specified dynamic library
12.1080 + * @exception UnsatisfiedLinkError if the library does not exist.
12.1081 + * @exception NullPointerException if <code>libname</code> is
12.1082 + * <code>null</code>
12.1083 + * @see java.lang.Runtime#loadLibrary(java.lang.String)
12.1084 + * @see java.lang.SecurityManager#checkLink(java.lang.String)
12.1085 + */
12.1086 + public static void loadLibrary(String libname) {
12.1087 + Runtime.getRuntime().loadLibrary0(getCallerClass(), libname);
12.1088 + }
12.1089 +
12.1090 + /**
12.1091 + * Maps a library name into a platform-specific string representing
12.1092 + * a native library.
12.1093 + *
12.1094 + * @param libname the name of the library.
12.1095 + * @return a platform-dependent native library name.
12.1096 + * @exception NullPointerException if <code>libname</code> is
12.1097 + * <code>null</code>
12.1098 + * @see java.lang.System#loadLibrary(java.lang.String)
12.1099 + * @see java.lang.ClassLoader#findLibrary(java.lang.String)
12.1100 + * @since 1.2
12.1101 + */
12.1102 + public static native String mapLibraryName(String libname);
12.1103 +
12.1104 + /**
12.1105 + * Initialize the system class. Called after thread initialization.
12.1106 + */
12.1107 + private static void initializeSystemClass() {
12.1108 +
12.1109 + // VM might invoke JNU_NewStringPlatform() to set those encoding
12.1110 + // sensitive properties (user.home, user.name, boot.class.path, etc.)
12.1111 + // during "props" initialization, in which it may need access, via
12.1112 + // System.getProperty(), to the related system encoding property that
12.1113 + // have been initialized (put into "props") at early stage of the
12.1114 + // initialization. So make sure the "props" is available at the
12.1115 + // very beginning of the initialization and all system properties to
12.1116 + // be put into it directly.
12.1117 + props = new Properties();
12.1118 + initProperties(props); // initialized by the VM
12.1119 +
12.1120 + // There are certain system configurations that may be controlled by
12.1121 + // VM options such as the maximum amount of direct memory and
12.1122 + // Integer cache size used to support the object identity semantics
12.1123 + // of autoboxing. Typically, the library will obtain these values
12.1124 + // from the properties set by the VM. If the properties are for
12.1125 + // internal implementation use only, these properties should be
12.1126 + // removed from the system properties.
12.1127 + //
12.1128 + // See java.lang.Integer.IntegerCache and the
12.1129 + // sun.misc.VM.saveAndRemoveProperties method for example.
12.1130 + //
12.1131 + // Save a private copy of the system properties object that
12.1132 + // can only be accessed by the internal implementation. Remove
12.1133 + // certain system properties that are not intended for public access.
12.1134 + sun.misc.VM.saveAndRemoveProperties(props);
12.1135 +
12.1136 +
12.1137 + lineSeparator = props.getProperty("line.separator");
12.1138 + sun.misc.Version.init();
12.1139 +
12.1140 + FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
12.1141 + FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
12.1142 + FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
12.1143 + setIn0(new BufferedInputStream(fdIn));
12.1144 + setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
12.1145 + setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));
12.1146 + // Load the zip library now in order to keep java.util.zip.ZipFile
12.1147 + // from trying to use itself to load this library later.
12.1148 + loadLibrary("zip");
12.1149 +
12.1150 + // Setup Java signal handlers for HUP, TERM, and INT (where available).
12.1151 + Terminator.setup();
12.1152 +
12.1153 + // Initialize any miscellenous operating system settings that need to be
12.1154 + // set for the class libraries. Currently this is no-op everywhere except
12.1155 + // for Windows where the process-wide error mode is set before the java.io
12.1156 + // classes are used.
12.1157 + sun.misc.VM.initializeOSEnvironment();
12.1158 +
12.1159 + // Subsystems that are invoked during initialization can invoke
12.1160 + // sun.misc.VM.isBooted() in order to avoid doing things that should
12.1161 + // wait until the application class loader has been set up.
12.1162 + sun.misc.VM.booted();
12.1163 +
12.1164 + // The main thread is not added to its thread group in the same
12.1165 + // way as other threads; we must do it ourselves here.
12.1166 + Thread current = Thread.currentThread();
12.1167 + current.getThreadGroup().add(current);
12.1168 +
12.1169 + // register shared secrets
12.1170 + setJavaLangAccess();
12.1171 + }
12.1172 +
12.1173 + private static void setJavaLangAccess() {
12.1174 + // Allow privileged classes outside of java.lang
12.1175 + sun.misc.SharedSecrets.setJavaLangAccess(new sun.misc.JavaLangAccess(){
12.1176 + public sun.reflect.ConstantPool getConstantPool(Class klass) {
12.1177 + return klass.getConstantPool();
12.1178 + }
12.1179 + public void setAnnotationType(Class klass, AnnotationType type) {
12.1180 + klass.setAnnotationType(type);
12.1181 + }
12.1182 + public AnnotationType getAnnotationType(Class klass) {
12.1183 + return klass.getAnnotationType();
12.1184 + }
12.1185 + public <E extends Enum<E>>
12.1186 + E[] getEnumConstantsShared(Class<E> klass) {
12.1187 + return klass.getEnumConstantsShared();
12.1188 + }
12.1189 + public void blockedOn(Thread t, Interruptible b) {
12.1190 + t.blockedOn(b);
12.1191 + }
12.1192 + public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
12.1193 + Shutdown.add(slot, registerShutdownInProgress, hook);
12.1194 + }
12.1195 + public int getStackTraceDepth(Throwable t) {
12.1196 + return t.getStackTraceDepth();
12.1197 + }
12.1198 + public StackTraceElement getStackTraceElement(Throwable t, int i) {
12.1199 + return t.getStackTraceElement(i);
12.1200 + }
12.1201 + });
12.1202 + }
12.1203 +
12.1204 + /* returns the class of the caller. */
12.1205 + static Class<?> getCallerClass() {
12.1206 + // NOTE use of more generic Reflection.getCallerClass()
12.1207 + return Reflection.getCallerClass(3);
12.1208 + }
12.1209 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/emul/compact/src/main/java/java/lang/Thread.java Sat Sep 07 13:51:24 2013 +0200
13.3 @@ -0,0 +1,2035 @@
13.4 +/*
13.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.7 + *
13.8 + * This code is free software; you can redistribute it and/or modify it
13.9 + * under the terms of the GNU General Public License version 2 only, as
13.10 + * published by the Free Software Foundation. Oracle designates this
13.11 + * particular file as subject to the "Classpath" exception as provided
13.12 + * by Oracle in the LICENSE file that accompanied this code.
13.13 + *
13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.17 + * version 2 for more details (a copy is included in the LICENSE file that
13.18 + * accompanied this code).
13.19 + *
13.20 + * You should have received a copy of the GNU General Public License version
13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.23 + *
13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
13.25 + * or visit www.oracle.com if you need additional information or have any
13.26 + * questions.
13.27 + */
13.28 +
13.29 +package java.lang;
13.30 +
13.31 +import java.lang.ref.Reference;
13.32 +import java.lang.ref.ReferenceQueue;
13.33 +import java.lang.ref.WeakReference;
13.34 +import java.security.AccessController;
13.35 +import java.security.AccessControlContext;
13.36 +import java.security.PrivilegedAction;
13.37 +import java.util.Map;
13.38 +import java.util.HashMap;
13.39 +import java.util.concurrent.ConcurrentHashMap;
13.40 +import java.util.concurrent.ConcurrentMap;
13.41 +import java.util.concurrent.locks.LockSupport;
13.42 +import sun.nio.ch.Interruptible;
13.43 +import sun.security.util.SecurityConstants;
13.44 +
13.45 +
13.46 +/**
13.47 + * A <i>thread</i> is a thread of execution in a program. The Java
13.48 + * Virtual Machine allows an application to have multiple threads of
13.49 + * execution running concurrently.
13.50 + * <p>
13.51 + * Every thread has a priority. Threads with higher priority are
13.52 + * executed in preference to threads with lower priority. Each thread
13.53 + * may or may not also be marked as a daemon. When code running in
13.54 + * some thread creates a new <code>Thread</code> object, the new
13.55 + * thread has its priority initially set equal to the priority of the
13.56 + * creating thread, and is a daemon thread if and only if the
13.57 + * creating thread is a daemon.
13.58 + * <p>
13.59 + * When a Java Virtual Machine starts up, there is usually a single
13.60 + * non-daemon thread (which typically calls the method named
13.61 + * <code>main</code> of some designated class). The Java Virtual
13.62 + * Machine continues to execute threads until either of the following
13.63 + * occurs:
13.64 + * <ul>
13.65 + * <li>The <code>exit</code> method of class <code>Runtime</code> has been
13.66 + * called and the security manager has permitted the exit operation
13.67 + * to take place.
13.68 + * <li>All threads that are not daemon threads have died, either by
13.69 + * returning from the call to the <code>run</code> method or by
13.70 + * throwing an exception that propagates beyond the <code>run</code>
13.71 + * method.
13.72 + * </ul>
13.73 + * <p>
13.74 + * There are two ways to create a new thread of execution. One is to
13.75 + * declare a class to be a subclass of <code>Thread</code>. This
13.76 + * subclass should override the <code>run</code> method of class
13.77 + * <code>Thread</code>. An instance of the subclass can then be
13.78 + * allocated and started. For example, a thread that computes primes
13.79 + * larger than a stated value could be written as follows:
13.80 + * <p><hr><blockquote><pre>
13.81 + * class PrimeThread extends Thread {
13.82 + * long minPrime;
13.83 + * PrimeThread(long minPrime) {
13.84 + * this.minPrime = minPrime;
13.85 + * }
13.86 + *
13.87 + * public void run() {
13.88 + * // compute primes larger than minPrime
13.89 + * . . .
13.90 + * }
13.91 + * }
13.92 + * </pre></blockquote><hr>
13.93 + * <p>
13.94 + * The following code would then create a thread and start it running:
13.95 + * <p><blockquote><pre>
13.96 + * PrimeThread p = new PrimeThread(143);
13.97 + * p.start();
13.98 + * </pre></blockquote>
13.99 + * <p>
13.100 + * The other way to create a thread is to declare a class that
13.101 + * implements the <code>Runnable</code> interface. That class then
13.102 + * implements the <code>run</code> method. An instance of the class can
13.103 + * then be allocated, passed as an argument when creating
13.104 + * <code>Thread</code>, and started. The same example in this other
13.105 + * style looks like the following:
13.106 + * <p><hr><blockquote><pre>
13.107 + * class PrimeRun implements Runnable {
13.108 + * long minPrime;
13.109 + * PrimeRun(long minPrime) {
13.110 + * this.minPrime = minPrime;
13.111 + * }
13.112 + *
13.113 + * public void run() {
13.114 + * // compute primes larger than minPrime
13.115 + * . . .
13.116 + * }
13.117 + * }
13.118 + * </pre></blockquote><hr>
13.119 + * <p>
13.120 + * The following code would then create a thread and start it running:
13.121 + * <p><blockquote><pre>
13.122 + * PrimeRun p = new PrimeRun(143);
13.123 + * new Thread(p).start();
13.124 + * </pre></blockquote>
13.125 + * <p>
13.126 + * Every thread has a name for identification purposes. More than
13.127 + * one thread may have the same name. If a name is not specified when
13.128 + * a thread is created, a new name is generated for it.
13.129 + * <p>
13.130 + * Unless otherwise noted, passing a {@code null} argument to a constructor
13.131 + * or method in this class will cause a {@link NullPointerException} to be
13.132 + * thrown.
13.133 + *
13.134 + * @author unascribed
13.135 + * @see Runnable
13.136 + * @see Runtime#exit(int)
13.137 + * @see #run()
13.138 + * @see #stop()
13.139 + * @since JDK1.0
13.140 + */
13.141 +public
13.142 +class Thread implements Runnable {
13.143 + /* Make sure registerNatives is the first thing <clinit> does. */
13.144 + private static native void registerNatives();
13.145 + static {
13.146 + registerNatives();
13.147 + }
13.148 +
13.149 + private char name[];
13.150 + private int priority;
13.151 + private Thread threadQ;
13.152 + private long eetop;
13.153 +
13.154 + /* Whether or not to single_step this thread. */
13.155 + private boolean single_step;
13.156 +
13.157 + /* Whether or not the thread is a daemon thread. */
13.158 + private boolean daemon = false;
13.159 +
13.160 + /* JVM state */
13.161 + private boolean stillborn = false;
13.162 +
13.163 + /* What will be run. */
13.164 + private Runnable target;
13.165 +
13.166 + /* The group of this thread */
13.167 + private ThreadGroup group;
13.168 +
13.169 + /* The context ClassLoader for this thread */
13.170 + private ClassLoader contextClassLoader;
13.171 +
13.172 + /* The inherited AccessControlContext of this thread */
13.173 + private AccessControlContext inheritedAccessControlContext;
13.174 +
13.175 + /* For autonumbering anonymous threads. */
13.176 + private static int threadInitNumber;
13.177 + private static synchronized int nextThreadNum() {
13.178 + return threadInitNumber++;
13.179 + }
13.180 +
13.181 + /* ThreadLocal values pertaining to this thread. This map is maintained
13.182 + * by the ThreadLocal class. */
13.183 + ThreadLocal.ThreadLocalMap threadLocals = null;
13.184 +
13.185 + /*
13.186 + * InheritableThreadLocal values pertaining to this thread. This map is
13.187 + * maintained by the InheritableThreadLocal class.
13.188 + */
13.189 + ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
13.190 +
13.191 + /*
13.192 + * The requested stack size for this thread, or 0 if the creator did
13.193 + * not specify a stack size. It is up to the VM to do whatever it
13.194 + * likes with this number; some VMs will ignore it.
13.195 + */
13.196 + private long stackSize;
13.197 +
13.198 + /*
13.199 + * JVM-private state that persists after native thread termination.
13.200 + */
13.201 + private long nativeParkEventPointer;
13.202 +
13.203 + /*
13.204 + * Thread ID
13.205 + */
13.206 + private long tid;
13.207 +
13.208 + /* For generating thread ID */
13.209 + private static long threadSeqNumber;
13.210 +
13.211 + /* Java thread status for tools,
13.212 + * initialized to indicate thread 'not yet started'
13.213 + */
13.214 +
13.215 + private volatile int threadStatus = 0;
13.216 +
13.217 +
13.218 + private static synchronized long nextThreadID() {
13.219 + return ++threadSeqNumber;
13.220 + }
13.221 +
13.222 + /**
13.223 + * The argument supplied to the current call to
13.224 + * java.util.concurrent.locks.LockSupport.park.
13.225 + * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
13.226 + * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
13.227 + */
13.228 + volatile Object parkBlocker;
13.229 +
13.230 + /* The object in which this thread is blocked in an interruptible I/O
13.231 + * operation, if any. The blocker's interrupt method should be invoked
13.232 + * after setting this thread's interrupt status.
13.233 + */
13.234 + private volatile Interruptible blocker;
13.235 + private final Object blockerLock = new Object();
13.236 +
13.237 + /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
13.238 + */
13.239 + void blockedOn(Interruptible b) {
13.240 + synchronized (blockerLock) {
13.241 + blocker = b;
13.242 + }
13.243 + }
13.244 +
13.245 + /**
13.246 + * The minimum priority that a thread can have.
13.247 + */
13.248 + public final static int MIN_PRIORITY = 1;
13.249 +
13.250 + /**
13.251 + * The default priority that is assigned to a thread.
13.252 + */
13.253 + public final static int NORM_PRIORITY = 5;
13.254 +
13.255 + /**
13.256 + * The maximum priority that a thread can have.
13.257 + */
13.258 + public final static int MAX_PRIORITY = 10;
13.259 +
13.260 + /**
13.261 + * Returns a reference to the currently executing thread object.
13.262 + *
13.263 + * @return the currently executing thread.
13.264 + */
13.265 + public static native Thread currentThread();
13.266 +
13.267 + /**
13.268 + * A hint to the scheduler that the current thread is willing to yield
13.269 + * its current use of a processor. The scheduler is free to ignore this
13.270 + * hint.
13.271 + *
13.272 + * <p> Yield is a heuristic attempt to improve relative progression
13.273 + * between threads that would otherwise over-utilise a CPU. Its use
13.274 + * should be combined with detailed profiling and benchmarking to
13.275 + * ensure that it actually has the desired effect.
13.276 + *
13.277 + * <p> It is rarely appropriate to use this method. It may be useful
13.278 + * for debugging or testing purposes, where it may help to reproduce
13.279 + * bugs due to race conditions. It may also be useful when designing
13.280 + * concurrency control constructs such as the ones in the
13.281 + * {@link java.util.concurrent.locks} package.
13.282 + */
13.283 + public static native void yield();
13.284 +
13.285 + /**
13.286 + * Causes the currently executing thread to sleep (temporarily cease
13.287 + * execution) for the specified number of milliseconds, subject to
13.288 + * the precision and accuracy of system timers and schedulers. The thread
13.289 + * does not lose ownership of any monitors.
13.290 + *
13.291 + * @param millis
13.292 + * the length of time to sleep in milliseconds
13.293 + *
13.294 + * @throws IllegalArgumentException
13.295 + * if the value of {@code millis} is negative
13.296 + *
13.297 + * @throws InterruptedException
13.298 + * if any thread has interrupted the current thread. The
13.299 + * <i>interrupted status</i> of the current thread is
13.300 + * cleared when this exception is thrown.
13.301 + */
13.302 + public static native void sleep(long millis) throws InterruptedException;
13.303 +
13.304 + /**
13.305 + * Causes the currently executing thread to sleep (temporarily cease
13.306 + * execution) for the specified number of milliseconds plus the specified
13.307 + * number of nanoseconds, subject to the precision and accuracy of system
13.308 + * timers and schedulers. The thread does not lose ownership of any
13.309 + * monitors.
13.310 + *
13.311 + * @param millis
13.312 + * the length of time to sleep in milliseconds
13.313 + *
13.314 + * @param nanos
13.315 + * {@code 0-999999} additional nanoseconds to sleep
13.316 + *
13.317 + * @throws IllegalArgumentException
13.318 + * if the value of {@code millis} is negative, or the value of
13.319 + * {@code nanos} is not in the range {@code 0-999999}
13.320 + *
13.321 + * @throws InterruptedException
13.322 + * if any thread has interrupted the current thread. The
13.323 + * <i>interrupted status</i> of the current thread is
13.324 + * cleared when this exception is thrown.
13.325 + */
13.326 + public static void sleep(long millis, int nanos)
13.327 + throws InterruptedException {
13.328 + if (millis < 0) {
13.329 + throw new IllegalArgumentException("timeout value is negative");
13.330 + }
13.331 +
13.332 + if (nanos < 0 || nanos > 999999) {
13.333 + throw new IllegalArgumentException(
13.334 + "nanosecond timeout value out of range");
13.335 + }
13.336 +
13.337 + if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
13.338 + millis++;
13.339 + }
13.340 +
13.341 + sleep(millis);
13.342 + }
13.343 +
13.344 + /**
13.345 + * Initializes a Thread.
13.346 + *
13.347 + * @param g the Thread group
13.348 + * @param target the object whose run() method gets called
13.349 + * @param name the name of the new Thread
13.350 + * @param stackSize the desired stack size for the new thread, or
13.351 + * zero to indicate that this parameter is to be ignored.
13.352 + */
13.353 + private void init(ThreadGroup g, Runnable target, String name,
13.354 + long stackSize) {
13.355 + if (name == null) {
13.356 + throw new NullPointerException("name cannot be null");
13.357 + }
13.358 +
13.359 + Thread parent = currentThread();
13.360 + SecurityManager security = System.getSecurityManager();
13.361 + if (g == null) {
13.362 + /* Determine if it's an applet or not */
13.363 +
13.364 + /* If there is a security manager, ask the security manager
13.365 + what to do. */
13.366 + if (security != null) {
13.367 + g = security.getThreadGroup();
13.368 + }
13.369 +
13.370 + /* If the security doesn't have a strong opinion of the matter
13.371 + use the parent thread group. */
13.372 + if (g == null) {
13.373 + g = parent.getThreadGroup();
13.374 + }
13.375 + }
13.376 +
13.377 + /* checkAccess regardless of whether or not threadgroup is
13.378 + explicitly passed in. */
13.379 + g.checkAccess();
13.380 +
13.381 + /*
13.382 + * Do we have the required permissions?
13.383 + */
13.384 + if (security != null) {
13.385 + if (isCCLOverridden(getClass())) {
13.386 + security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
13.387 + }
13.388 + }
13.389 +
13.390 + g.addUnstarted();
13.391 +
13.392 + this.group = g;
13.393 + this.daemon = parent.isDaemon();
13.394 + this.priority = parent.getPriority();
13.395 + this.name = name.toCharArray();
13.396 + if (security == null || isCCLOverridden(parent.getClass()))
13.397 + this.contextClassLoader = parent.getContextClassLoader();
13.398 + else
13.399 + this.contextClassLoader = parent.contextClassLoader;
13.400 + this.inheritedAccessControlContext = AccessController.getContext();
13.401 + this.target = target;
13.402 + setPriority(priority);
13.403 + if (parent.inheritableThreadLocals != null)
13.404 + this.inheritableThreadLocals =
13.405 + ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
13.406 + /* Stash the specified stack size in case the VM cares */
13.407 + this.stackSize = stackSize;
13.408 +
13.409 + /* Set thread ID */
13.410 + tid = nextThreadID();
13.411 + }
13.412 +
13.413 + /**
13.414 + * Throws CloneNotSupportedException as a Thread can not be meaningfully
13.415 + * cloned. Construct a new Thread instead.
13.416 + *
13.417 + * @throws CloneNotSupportedException
13.418 + * always
13.419 + */
13.420 + @Override
13.421 + protected Object clone() throws CloneNotSupportedException {
13.422 + throw new CloneNotSupportedException();
13.423 + }
13.424 +
13.425 + /**
13.426 + * Allocates a new {@code Thread} object. This constructor has the same
13.427 + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
13.428 + * {@code (null, null, gname)}, where {@code gname} is a newly generated
13.429 + * name. Automatically generated names are of the form
13.430 + * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
13.431 + */
13.432 + public Thread() {
13.433 + init(null, null, "Thread-" + nextThreadNum(), 0);
13.434 + }
13.435 +
13.436 + /**
13.437 + * Allocates a new {@code Thread} object. This constructor has the same
13.438 + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
13.439 + * {@code (null, target, gname)}, where {@code gname} is a newly generated
13.440 + * name. Automatically generated names are of the form
13.441 + * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
13.442 + *
13.443 + * @param target
13.444 + * the object whose {@code run} method is invoked when this thread
13.445 + * is started. If {@code null}, this classes {@code run} method does
13.446 + * nothing.
13.447 + */
13.448 + public Thread(Runnable target) {
13.449 + init(null, target, "Thread-" + nextThreadNum(), 0);
13.450 + }
13.451 +
13.452 + /**
13.453 + * Allocates a new {@code Thread} object. This constructor has the same
13.454 + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
13.455 + * {@code (group, target, gname)} ,where {@code gname} is a newly generated
13.456 + * name. Automatically generated names are of the form
13.457 + * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
13.458 + *
13.459 + * @param group
13.460 + * the thread group. If {@code null} and there is a security
13.461 + * manager, the group is determined by {@linkplain
13.462 + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
13.463 + * If there is not a security manager or {@code
13.464 + * SecurityManager.getThreadGroup()} returns {@code null}, the group
13.465 + * is set to the current thread's thread group.
13.466 + *
13.467 + * @param target
13.468 + * the object whose {@code run} method is invoked when this thread
13.469 + * is started. If {@code null}, this thread's run method is invoked.
13.470 + *
13.471 + * @throws SecurityException
13.472 + * if the current thread cannot create a thread in the specified
13.473 + * thread group
13.474 + */
13.475 + public Thread(ThreadGroup group, Runnable target) {
13.476 + init(group, target, "Thread-" + nextThreadNum(), 0);
13.477 + }
13.478 +
13.479 + /**
13.480 + * Allocates a new {@code Thread} object. This constructor has the same
13.481 + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
13.482 + * {@code (null, null, name)}.
13.483 + *
13.484 + * @param name
13.485 + * the name of the new thread
13.486 + */
13.487 + public Thread(String name) {
13.488 + init(null, null, name, 0);
13.489 + }
13.490 +
13.491 + /**
13.492 + * Allocates a new {@code Thread} object. This constructor has the same
13.493 + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
13.494 + * {@code (group, null, name)}.
13.495 + *
13.496 + * @param group
13.497 + * the thread group. If {@code null} and there is a security
13.498 + * manager, the group is determined by {@linkplain
13.499 + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
13.500 + * If there is not a security manager or {@code
13.501 + * SecurityManager.getThreadGroup()} returns {@code null}, the group
13.502 + * is set to the current thread's thread group.
13.503 + *
13.504 + * @param name
13.505 + * the name of the new thread
13.506 + *
13.507 + * @throws SecurityException
13.508 + * if the current thread cannot create a thread in the specified
13.509 + * thread group
13.510 + */
13.511 + public Thread(ThreadGroup group, String name) {
13.512 + init(group, null, name, 0);
13.513 + }
13.514 +
13.515 + /**
13.516 + * Allocates a new {@code Thread} object. This constructor has the same
13.517 + * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
13.518 + * {@code (null, target, name)}.
13.519 + *
13.520 + * @param target
13.521 + * the object whose {@code run} method is invoked when this thread
13.522 + * is started. If {@code null}, this thread's run method is invoked.
13.523 + *
13.524 + * @param name
13.525 + * the name of the new thread
13.526 + */
13.527 + public Thread(Runnable target, String name) {
13.528 + init(null, target, name, 0);
13.529 + }
13.530 +
13.531 + /**
13.532 + * Allocates a new {@code Thread} object so that it has {@code target}
13.533 + * as its run object, has the specified {@code name} as its name,
13.534 + * and belongs to the thread group referred to by {@code group}.
13.535 + *
13.536 + * <p>If there is a security manager, its
13.537 + * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}
13.538 + * method is invoked with the ThreadGroup as its argument.
13.539 + *
13.540 + * <p>In addition, its {@code checkPermission} method is invoked with
13.541 + * the {@code RuntimePermission("enableContextClassLoaderOverride")}
13.542 + * permission when invoked directly or indirectly by the constructor
13.543 + * of a subclass which overrides the {@code getContextClassLoader}
13.544 + * or {@code setContextClassLoader} methods.
13.545 + *
13.546 + * <p>The priority of the newly created thread is set equal to the
13.547 + * priority of the thread creating it, that is, the currently running
13.548 + * thread. The method {@linkplain #setPriority setPriority} may be
13.549 + * used to change the priority to a new value.
13.550 + *
13.551 + * <p>The newly created thread is initially marked as being a daemon
13.552 + * thread if and only if the thread creating it is currently marked
13.553 + * as a daemon thread. The method {@linkplain #setDaemon setDaemon}
13.554 + * may be used to change whether or not a thread is a daemon.
13.555 + *
13.556 + * @param group
13.557 + * the thread group. If {@code null} and there is a security
13.558 + * manager, the group is determined by {@linkplain
13.559 + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
13.560 + * If there is not a security manager or {@code
13.561 + * SecurityManager.getThreadGroup()} returns {@code null}, the group
13.562 + * is set to the current thread's thread group.
13.563 + *
13.564 + * @param target
13.565 + * the object whose {@code run} method is invoked when this thread
13.566 + * is started. If {@code null}, this thread's run method is invoked.
13.567 + *
13.568 + * @param name
13.569 + * the name of the new thread
13.570 + *
13.571 + * @throws SecurityException
13.572 + * if the current thread cannot create a thread in the specified
13.573 + * thread group or cannot override the context class loader methods.
13.574 + */
13.575 + public Thread(ThreadGroup group, Runnable target, String name) {
13.576 + init(group, target, name, 0);
13.577 + }
13.578 +
13.579 + /**
13.580 + * Allocates a new {@code Thread} object so that it has {@code target}
13.581 + * as its run object, has the specified {@code name} as its name,
13.582 + * and belongs to the thread group referred to by {@code group}, and has
13.583 + * the specified <i>stack size</i>.
13.584 + *
13.585 + * <p>This constructor is identical to {@link
13.586 + * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
13.587 + * that it allows the thread stack size to be specified. The stack size
13.588 + * is the approximate number of bytes of address space that the virtual
13.589 + * machine is to allocate for this thread's stack. <b>The effect of the
13.590 + * {@code stackSize} parameter, if any, is highly platform dependent.</b>
13.591 + *
13.592 + * <p>On some platforms, specifying a higher value for the
13.593 + * {@code stackSize} parameter may allow a thread to achieve greater
13.594 + * recursion depth before throwing a {@link StackOverflowError}.
13.595 + * Similarly, specifying a lower value may allow a greater number of
13.596 + * threads to exist concurrently without throwing an {@link
13.597 + * OutOfMemoryError} (or other internal error). The details of
13.598 + * the relationship between the value of the <tt>stackSize</tt> parameter
13.599 + * and the maximum recursion depth and concurrency level are
13.600 + * platform-dependent. <b>On some platforms, the value of the
13.601 + * {@code stackSize} parameter may have no effect whatsoever.</b>
13.602 + *
13.603 + * <p>The virtual machine is free to treat the {@code stackSize}
13.604 + * parameter as a suggestion. If the specified value is unreasonably low
13.605 + * for the platform, the virtual machine may instead use some
13.606 + * platform-specific minimum value; if the specified value is unreasonably
13.607 + * high, the virtual machine may instead use some platform-specific
13.608 + * maximum. Likewise, the virtual machine is free to round the specified
13.609 + * value up or down as it sees fit (or to ignore it completely).
13.610 + *
13.611 + * <p>Specifying a value of zero for the {@code stackSize} parameter will
13.612 + * cause this constructor to behave exactly like the
13.613 + * {@code Thread(ThreadGroup, Runnable, String)} constructor.
13.614 + *
13.615 + * <p><i>Due to the platform-dependent nature of the behavior of this
13.616 + * constructor, extreme care should be exercised in its use.
13.617 + * The thread stack size necessary to perform a given computation will
13.618 + * likely vary from one JRE implementation to another. In light of this
13.619 + * variation, careful tuning of the stack size parameter may be required,
13.620 + * and the tuning may need to be repeated for each JRE implementation on
13.621 + * which an application is to run.</i>
13.622 + *
13.623 + * <p>Implementation note: Java platform implementers are encouraged to
13.624 + * document their implementation's behavior with respect to the
13.625 + * {@code stackSize} parameter.
13.626 + *
13.627 + *
13.628 + * @param group
13.629 + * the thread group. If {@code null} and there is a security
13.630 + * manager, the group is determined by {@linkplain
13.631 + * SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
13.632 + * If there is not a security manager or {@code
13.633 + * SecurityManager.getThreadGroup()} returns {@code null}, the group
13.634 + * is set to the current thread's thread group.
13.635 + *
13.636 + * @param target
13.637 + * the object whose {@code run} method is invoked when this thread
13.638 + * is started. If {@code null}, this thread's run method is invoked.
13.639 + *
13.640 + * @param name
13.641 + * the name of the new thread
13.642 + *
13.643 + * @param stackSize
13.644 + * the desired stack size for the new thread, or zero to indicate
13.645 + * that this parameter is to be ignored.
13.646 + *
13.647 + * @throws SecurityException
13.648 + * if the current thread cannot create a thread in the specified
13.649 + * thread group
13.650 + *
13.651 + * @since 1.4
13.652 + */
13.653 + public Thread(ThreadGroup group, Runnable target, String name,
13.654 + long stackSize) {
13.655 + init(group, target, name, stackSize);
13.656 + }
13.657 +
13.658 + /**
13.659 + * Causes this thread to begin execution; the Java Virtual Machine
13.660 + * calls the <code>run</code> method of this thread.
13.661 + * <p>
13.662 + * The result is that two threads are running concurrently: the
13.663 + * current thread (which returns from the call to the
13.664 + * <code>start</code> method) and the other thread (which executes its
13.665 + * <code>run</code> method).
13.666 + * <p>
13.667 + * It is never legal to start a thread more than once.
13.668 + * In particular, a thread may not be restarted once it has completed
13.669 + * execution.
13.670 + *
13.671 + * @exception IllegalThreadStateException if the thread was already
13.672 + * started.
13.673 + * @see #run()
13.674 + * @see #stop()
13.675 + */
13.676 + public synchronized void start() {
13.677 + /**
13.678 + * This method is not invoked for the main method thread or "system"
13.679 + * group threads created/set up by the VM. Any new functionality added
13.680 + * to this method in the future may have to also be added to the VM.
13.681 + *
13.682 + * A zero status value corresponds to state "NEW".
13.683 + */
13.684 + if (threadStatus != 0)
13.685 + throw new IllegalThreadStateException();
13.686 +
13.687 + /* Notify the group that this thread is about to be started
13.688 + * so that it can be added to the group's list of threads
13.689 + * and the group's unstarted count can be decremented. */
13.690 + group.add(this);
13.691 +
13.692 + boolean started = false;
13.693 + try {
13.694 + start0();
13.695 + started = true;
13.696 + } finally {
13.697 + try {
13.698 + if (!started) {
13.699 + group.threadStartFailed(this);
13.700 + }
13.701 + } catch (Throwable ignore) {
13.702 + /* do nothing. If start0 threw a Throwable then
13.703 + it will be passed up the call stack */
13.704 + }
13.705 + }
13.706 + }
13.707 +
13.708 + private native void start0();
13.709 +
13.710 + /**
13.711 + * If this thread was constructed using a separate
13.712 + * <code>Runnable</code> run object, then that
13.713 + * <code>Runnable</code> object's <code>run</code> method is called;
13.714 + * otherwise, this method does nothing and returns.
13.715 + * <p>
13.716 + * Subclasses of <code>Thread</code> should override this method.
13.717 + *
13.718 + * @see #start()
13.719 + * @see #stop()
13.720 + * @see #Thread(ThreadGroup, Runnable, String)
13.721 + */
13.722 + @Override
13.723 + public void run() {
13.724 + if (target != null) {
13.725 + target.run();
13.726 + }
13.727 + }
13.728 +
13.729 + /**
13.730 + * This method is called by the system to give a Thread
13.731 + * a chance to clean up before it actually exits.
13.732 + */
13.733 + private void exit() {
13.734 + if (group != null) {
13.735 + group.threadTerminated(this);
13.736 + group = null;
13.737 + }
13.738 + /* Aggressively null out all reference fields: see bug 4006245 */
13.739 + target = null;
13.740 + /* Speed the release of some of these resources */
13.741 + threadLocals = null;
13.742 + inheritableThreadLocals = null;
13.743 + inheritedAccessControlContext = null;
13.744 + blocker = null;
13.745 + uncaughtExceptionHandler = null;
13.746 + }
13.747 +
13.748 + /**
13.749 + * Forces the thread to stop executing.
13.750 + * <p>
13.751 + * If there is a security manager installed, its <code>checkAccess</code>
13.752 + * method is called with <code>this</code>
13.753 + * as its argument. This may result in a
13.754 + * <code>SecurityException</code> being raised (in the current thread).
13.755 + * <p>
13.756 + * If this thread is different from the current thread (that is, the current
13.757 + * thread is trying to stop a thread other than itself), the
13.758 + * security manager's <code>checkPermission</code> method (with a
13.759 + * <code>RuntimePermission("stopThread")</code> argument) is called in
13.760 + * addition.
13.761 + * Again, this may result in throwing a
13.762 + * <code>SecurityException</code> (in the current thread).
13.763 + * <p>
13.764 + * The thread represented by this thread is forced to stop whatever
13.765 + * it is doing abnormally and to throw a newly created
13.766 + * <code>ThreadDeath</code> object as an exception.
13.767 + * <p>
13.768 + * It is permitted to stop a thread that has not yet been started.
13.769 + * If the thread is eventually started, it immediately terminates.
13.770 + * <p>
13.771 + * An application should not normally try to catch
13.772 + * <code>ThreadDeath</code> unless it must do some extraordinary
13.773 + * cleanup operation (note that the throwing of
13.774 + * <code>ThreadDeath</code> causes <code>finally</code> clauses of
13.775 + * <code>try</code> statements to be executed before the thread
13.776 + * officially dies). If a <code>catch</code> clause catches a
13.777 + * <code>ThreadDeath</code> object, it is important to rethrow the
13.778 + * object so that the thread actually dies.
13.779 + * <p>
13.780 + * The top-level error handler that reacts to otherwise uncaught
13.781 + * exceptions does not print out a message or otherwise notify the
13.782 + * application if the uncaught exception is an instance of
13.783 + * <code>ThreadDeath</code>.
13.784 + *
13.785 + * @exception SecurityException if the current thread cannot
13.786 + * modify this thread.
13.787 + * @see #interrupt()
13.788 + * @see #checkAccess()
13.789 + * @see #run()
13.790 + * @see #start()
13.791 + * @see ThreadDeath
13.792 + * @see ThreadGroup#uncaughtException(Thread,Throwable)
13.793 + * @see SecurityManager#checkAccess(Thread)
13.794 + * @see SecurityManager#checkPermission
13.795 + * @deprecated This method is inherently unsafe. Stopping a thread with
13.796 + * Thread.stop causes it to unlock all of the monitors that it
13.797 + * has locked (as a natural consequence of the unchecked
13.798 + * <code>ThreadDeath</code> exception propagating up the stack). If
13.799 + * any of the objects previously protected by these monitors were in
13.800 + * an inconsistent state, the damaged objects become visible to
13.801 + * other threads, potentially resulting in arbitrary behavior. Many
13.802 + * uses of <code>stop</code> should be replaced by code that simply
13.803 + * modifies some variable to indicate that the target thread should
13.804 + * stop running. The target thread should check this variable
13.805 + * regularly, and return from its run method in an orderly fashion
13.806 + * if the variable indicates that it is to stop running. If the
13.807 + * target thread waits for long periods (on a condition variable,
13.808 + * for example), the <code>interrupt</code> method should be used to
13.809 + * interrupt the wait.
13.810 + * For more information, see
13.811 + * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
13.812 + * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
13.813 + */
13.814 + @Deprecated
13.815 + public final void stop() {
13.816 + stop(new ThreadDeath());
13.817 + }
13.818 +
13.819 + /**
13.820 + * Forces the thread to stop executing.
13.821 + * <p>
13.822 + * If there is a security manager installed, the <code>checkAccess</code>
13.823 + * method of this thread is called, which may result in a
13.824 + * <code>SecurityException</code> being raised (in the current thread).
13.825 + * <p>
13.826 + * If this thread is different from the current thread (that is, the current
13.827 + * thread is trying to stop a thread other than itself) or
13.828 + * <code>obj</code> is not an instance of <code>ThreadDeath</code>, the
13.829 + * security manager's <code>checkPermission</code> method (with the
13.830 + * <code>RuntimePermission("stopThread")</code> argument) is called in
13.831 + * addition.
13.832 + * Again, this may result in throwing a
13.833 + * <code>SecurityException</code> (in the current thread).
13.834 + * <p>
13.835 + * If the argument <code>obj</code> is null, a
13.836 + * <code>NullPointerException</code> is thrown (in the current thread).
13.837 + * <p>
13.838 + * The thread represented by this thread is forced to stop
13.839 + * whatever it is doing abnormally and to throw the
13.840 + * <code>Throwable</code> object <code>obj</code> as an exception. This
13.841 + * is an unusual action to take; normally, the <code>stop</code> method
13.842 + * that takes no arguments should be used.
13.843 + * <p>
13.844 + * It is permitted to stop a thread that has not yet been started.
13.845 + * If the thread is eventually started, it immediately terminates.
13.846 + *
13.847 + * @param obj the Throwable object to be thrown.
13.848 + * @exception SecurityException if the current thread cannot modify
13.849 + * this thread.
13.850 + * @throws NullPointerException if obj is <tt>null</tt>.
13.851 + * @see #interrupt()
13.852 + * @see #checkAccess()
13.853 + * @see #run()
13.854 + * @see #start()
13.855 + * @see #stop()
13.856 + * @see SecurityManager#checkAccess(Thread)
13.857 + * @see SecurityManager#checkPermission
13.858 + * @deprecated This method is inherently unsafe. See {@link #stop()}
13.859 + * for details. An additional danger of this
13.860 + * method is that it may be used to generate exceptions that the
13.861 + * target thread is unprepared to handle (including checked
13.862 + * exceptions that the thread could not possibly throw, were it
13.863 + * not for this method).
13.864 + * For more information, see
13.865 + * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
13.866 + * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
13.867 + */
13.868 + @Deprecated
13.869 + public final synchronized void stop(Throwable obj) {
13.870 + if (obj == null)
13.871 + throw new NullPointerException();
13.872 +
13.873 + SecurityManager security = System.getSecurityManager();
13.874 + if (security != null) {
13.875 + checkAccess();
13.876 + if ((this != Thread.currentThread()) ||
13.877 + (!(obj instanceof ThreadDeath))) {
13.878 + security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
13.879 + }
13.880 + }
13.881 + // A zero status value corresponds to "NEW", it can't change to
13.882 + // not-NEW because we hold the lock.
13.883 + if (threadStatus != 0) {
13.884 + resume(); // Wake up thread if it was suspended; no-op otherwise
13.885 + }
13.886 +
13.887 + // The VM can handle all thread states
13.888 + stop0(obj);
13.889 + }
13.890 +
13.891 + /**
13.892 + * Interrupts this thread.
13.893 + *
13.894 + * <p> Unless the current thread is interrupting itself, which is
13.895 + * always permitted, the {@link #checkAccess() checkAccess} method
13.896 + * of this thread is invoked, which may cause a {@link
13.897 + * SecurityException} to be thrown.
13.898 + *
13.899 + * <p> If this thread is blocked in an invocation of the {@link
13.900 + * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
13.901 + * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
13.902 + * class, or of the {@link #join()}, {@link #join(long)}, {@link
13.903 + * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
13.904 + * methods of this class, then its interrupt status will be cleared and it
13.905 + * will receive an {@link InterruptedException}.
13.906 + *
13.907 + * <p> If this thread is blocked in an I/O operation upon an {@link
13.908 + * java.nio.channels.InterruptibleChannel </code>interruptible
13.909 + * channel<code>} then the channel will be closed, the thread's interrupt
13.910 + * status will be set, and the thread will receive a {@link
13.911 + * java.nio.channels.ClosedByInterruptException}.
13.912 + *
13.913 + * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
13.914 + * then the thread's interrupt status will be set and it will return
13.915 + * immediately from the selection operation, possibly with a non-zero
13.916 + * value, just as if the selector's {@link
13.917 + * java.nio.channels.Selector#wakeup wakeup} method were invoked.
13.918 + *
13.919 + * <p> If none of the previous conditions hold then this thread's interrupt
13.920 + * status will be set. </p>
13.921 + *
13.922 + * <p> Interrupting a thread that is not alive need not have any effect.
13.923 + *
13.924 + * @throws SecurityException
13.925 + * if the current thread cannot modify this thread
13.926 + *
13.927 + * @revised 6.0
13.928 + * @spec JSR-51
13.929 + */
13.930 + public void interrupt() {
13.931 + if (this != Thread.currentThread())
13.932 + checkAccess();
13.933 +
13.934 + synchronized (blockerLock) {
13.935 + Interruptible b = blocker;
13.936 + if (b != null) {
13.937 + interrupt0(); // Just to set the interrupt flag
13.938 + b.interrupt(this);
13.939 + return;
13.940 + }
13.941 + }
13.942 + interrupt0();
13.943 + }
13.944 +
13.945 + /**
13.946 + * Tests whether the current thread has been interrupted. The
13.947 + * <i>interrupted status</i> of the thread is cleared by this method. In
13.948 + * other words, if this method were to be called twice in succession, the
13.949 + * second call would return false (unless the current thread were
13.950 + * interrupted again, after the first call had cleared its interrupted
13.951 + * status and before the second call had examined it).
13.952 + *
13.953 + * <p>A thread interruption ignored because a thread was not alive
13.954 + * at the time of the interrupt will be reflected by this method
13.955 + * returning false.
13.956 + *
13.957 + * @return <code>true</code> if the current thread has been interrupted;
13.958 + * <code>false</code> otherwise.
13.959 + * @see #isInterrupted()
13.960 + * @revised 6.0
13.961 + */
13.962 + public static boolean interrupted() {
13.963 + return currentThread().isInterrupted(true);
13.964 + }
13.965 +
13.966 + /**
13.967 + * Tests whether this thread has been interrupted. The <i>interrupted
13.968 + * status</i> of the thread is unaffected by this method.
13.969 + *
13.970 + * <p>A thread interruption ignored because a thread was not alive
13.971 + * at the time of the interrupt will be reflected by this method
13.972 + * returning false.
13.973 + *
13.974 + * @return <code>true</code> if this thread has been interrupted;
13.975 + * <code>false</code> otherwise.
13.976 + * @see #interrupted()
13.977 + * @revised 6.0
13.978 + */
13.979 + public boolean isInterrupted() {
13.980 + return isInterrupted(false);
13.981 + }
13.982 +
13.983 + /**
13.984 + * Tests if some Thread has been interrupted. The interrupted state
13.985 + * is reset or not based on the value of ClearInterrupted that is
13.986 + * passed.
13.987 + */
13.988 + private native boolean isInterrupted(boolean ClearInterrupted);
13.989 +
13.990 + /**
13.991 + * Throws {@link NoSuchMethodError}.
13.992 + *
13.993 + * @deprecated This method was originally designed to destroy this
13.994 + * thread without any cleanup. Any monitors it held would have
13.995 + * remained locked. However, the method was never implemented.
13.996 + * If if were to be implemented, it would be deadlock-prone in
13.997 + * much the manner of {@link #suspend}. If the target thread held
13.998 + * a lock protecting a critical system resource when it was
13.999 + * destroyed, no thread could ever access this resource again.
13.1000 + * If another thread ever attempted to lock this resource, deadlock
13.1001 + * would result. Such deadlocks typically manifest themselves as
13.1002 + * "frozen" processes. For more information, see
13.1003 + * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
13.1004 + * Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
13.1005 + * @throws NoSuchMethodError always
13.1006 + */
13.1007 + @Deprecated
13.1008 + public void destroy() {
13.1009 + throw new NoSuchMethodError();
13.1010 + }
13.1011 +
13.1012 + /**
13.1013 + * Tests if this thread is alive. A thread is alive if it has
13.1014 + * been started and has not yet died.
13.1015 + *
13.1016 + * @return <code>true</code> if this thread is alive;
13.1017 + * <code>false</code> otherwise.
13.1018 + */
13.1019 + public final native boolean isAlive();
13.1020 +
13.1021 + /**
13.1022 + * Suspends this thread.
13.1023 + * <p>
13.1024 + * First, the <code>checkAccess</code> method of this thread is called
13.1025 + * with no arguments. This may result in throwing a
13.1026 + * <code>SecurityException </code>(in the current thread).
13.1027 + * <p>
13.1028 + * If the thread is alive, it is suspended and makes no further
13.1029 + * progress unless and until it is resumed.
13.1030 + *
13.1031 + * @exception SecurityException if the current thread cannot modify
13.1032 + * this thread.
13.1033 + * @see #checkAccess
13.1034 + * @deprecated This method has been deprecated, as it is
13.1035 + * inherently deadlock-prone. If the target thread holds a lock on the
13.1036 + * monitor protecting a critical system resource when it is suspended, no
13.1037 + * thread can access this resource until the target thread is resumed. If
13.1038 + * the thread that would resume the target thread attempts to lock this
13.1039 + * monitor prior to calling <code>resume</code>, deadlock results. Such
13.1040 + * deadlocks typically manifest themselves as "frozen" processes.
13.1041 + * For more information, see
13.1042 + * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
13.1043 + * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
13.1044 + */
13.1045 + @Deprecated
13.1046 + public final void suspend() {
13.1047 + checkAccess();
13.1048 + suspend0();
13.1049 + }
13.1050 +
13.1051 + /**
13.1052 + * Resumes a suspended thread.
13.1053 + * <p>
13.1054 + * First, the <code>checkAccess</code> method of this thread is called
13.1055 + * with no arguments. This may result in throwing a
13.1056 + * <code>SecurityException</code> (in the current thread).
13.1057 + * <p>
13.1058 + * If the thread is alive but suspended, it is resumed and is
13.1059 + * permitted to make progress in its execution.
13.1060 + *
13.1061 + * @exception SecurityException if the current thread cannot modify this
13.1062 + * thread.
13.1063 + * @see #checkAccess
13.1064 + * @see #suspend()
13.1065 + * @deprecated This method exists solely for use with {@link #suspend},
13.1066 + * which has been deprecated because it is deadlock-prone.
13.1067 + * For more information, see
13.1068 + * <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
13.1069 + * are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
13.1070 + */
13.1071 + @Deprecated
13.1072 + public final void resume() {
13.1073 + checkAccess();
13.1074 + resume0();
13.1075 + }
13.1076 +
13.1077 + /**
13.1078 + * Changes the priority of this thread.
13.1079 + * <p>
13.1080 + * First the <code>checkAccess</code> method of this thread is called
13.1081 + * with no arguments. This may result in throwing a
13.1082 + * <code>SecurityException</code>.
13.1083 + * <p>
13.1084 + * Otherwise, the priority of this thread is set to the smaller of
13.1085 + * the specified <code>newPriority</code> and the maximum permitted
13.1086 + * priority of the thread's thread group.
13.1087 + *
13.1088 + * @param newPriority priority to set this thread to
13.1089 + * @exception IllegalArgumentException If the priority is not in the
13.1090 + * range <code>MIN_PRIORITY</code> to
13.1091 + * <code>MAX_PRIORITY</code>.
13.1092 + * @exception SecurityException if the current thread cannot modify
13.1093 + * this thread.
13.1094 + * @see #getPriority
13.1095 + * @see #checkAccess()
13.1096 + * @see #getThreadGroup()
13.1097 + * @see #MAX_PRIORITY
13.1098 + * @see #MIN_PRIORITY
13.1099 + * @see ThreadGroup#getMaxPriority()
13.1100 + */
13.1101 + public final void setPriority(int newPriority) {
13.1102 + ThreadGroup g;
13.1103 + checkAccess();
13.1104 + if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
13.1105 + throw new IllegalArgumentException();
13.1106 + }
13.1107 + if((g = getThreadGroup()) != null) {
13.1108 + if (newPriority > g.getMaxPriority()) {
13.1109 + newPriority = g.getMaxPriority();
13.1110 + }
13.1111 + setPriority0(priority = newPriority);
13.1112 + }
13.1113 + }
13.1114 +
13.1115 + /**
13.1116 + * Returns this thread's priority.
13.1117 + *
13.1118 + * @return this thread's priority.
13.1119 + * @see #setPriority
13.1120 + */
13.1121 + public final int getPriority() {
13.1122 + return priority;
13.1123 + }
13.1124 +
13.1125 + /**
13.1126 + * Changes the name of this thread to be equal to the argument
13.1127 + * <code>name</code>.
13.1128 + * <p>
13.1129 + * First the <code>checkAccess</code> method of this thread is called
13.1130 + * with no arguments. This may result in throwing a
13.1131 + * <code>SecurityException</code>.
13.1132 + *
13.1133 + * @param name the new name for this thread.
13.1134 + * @exception SecurityException if the current thread cannot modify this
13.1135 + * thread.
13.1136 + * @see #getName
13.1137 + * @see #checkAccess()
13.1138 + */
13.1139 + public final void setName(String name) {
13.1140 + checkAccess();
13.1141 + this.name = name.toCharArray();
13.1142 + }
13.1143 +
13.1144 + /**
13.1145 + * Returns this thread's name.
13.1146 + *
13.1147 + * @return this thread's name.
13.1148 + * @see #setName(String)
13.1149 + */
13.1150 + public final String getName() {
13.1151 + return String.valueOf(name);
13.1152 + }
13.1153 +
13.1154 + /**
13.1155 + * Returns the thread group to which this thread belongs.
13.1156 + * This method returns null if this thread has died
13.1157 + * (been stopped).
13.1158 + *
13.1159 + * @return this thread's thread group.
13.1160 + */
13.1161 + public final ThreadGroup getThreadGroup() {
13.1162 + return group;
13.1163 + }
13.1164 +
13.1165 + /**
13.1166 + * Returns an estimate of the number of active threads in the current
13.1167 + * thread's {@linkplain java.lang.ThreadGroup thread group} and its
13.1168 + * subgroups. Recursively iterates over all subgroups in the current
13.1169 + * thread's thread group.
13.1170 + *
13.1171 + * <p> The value returned is only an estimate because the number of
13.1172 + * threads may change dynamically while this method traverses internal
13.1173 + * data structures, and might be affected by the presence of certain
13.1174 + * system threads. This method is intended primarily for debugging
13.1175 + * and monitoring purposes.
13.1176 + *
13.1177 + * @return an estimate of the number of active threads in the current
13.1178 + * thread's thread group and in any other thread group that
13.1179 + * has the current thread's thread group as an ancestor
13.1180 + */
13.1181 + public static int activeCount() {
13.1182 + return currentThread().getThreadGroup().activeCount();
13.1183 + }
13.1184 +
13.1185 + /**
13.1186 + * Copies into the specified array every active thread in the current
13.1187 + * thread's thread group and its subgroups. This method simply
13.1188 + * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}
13.1189 + * method of the current thread's thread group.
13.1190 + *
13.1191 + * <p> An application might use the {@linkplain #activeCount activeCount}
13.1192 + * method to get an estimate of how big the array should be, however
13.1193 + * <i>if the array is too short to hold all the threads, the extra threads
13.1194 + * are silently ignored.</i> If it is critical to obtain every active
13.1195 + * thread in the current thread's thread group and its subgroups, the
13.1196 + * invoker should verify that the returned int value is strictly less
13.1197 + * than the length of {@code tarray}.
13.1198 + *
13.1199 + * <p> Due to the inherent race condition in this method, it is recommended
13.1200 + * that the method only be used for debugging and monitoring purposes.
13.1201 + *
13.1202 + * @param tarray
13.1203 + * an array into which to put the list of threads
13.1204 + *
13.1205 + * @return the number of threads put into the array
13.1206 + *
13.1207 + * @throws SecurityException
13.1208 + * if {@link java.lang.ThreadGroup#checkAccess} determines that
13.1209 + * the current thread cannot access its thread group
13.1210 + */
13.1211 + public static int enumerate(Thread tarray[]) {
13.1212 + return currentThread().getThreadGroup().enumerate(tarray);
13.1213 + }
13.1214 +
13.1215 + /**
13.1216 + * Counts the number of stack frames in this thread. The thread must
13.1217 + * be suspended.
13.1218 + *
13.1219 + * @return the number of stack frames in this thread.
13.1220 + * @exception IllegalThreadStateException if this thread is not
13.1221 + * suspended.
13.1222 + * @deprecated The definition of this call depends on {@link #suspend},
13.1223 + * which is deprecated. Further, the results of this call
13.1224 + * were never well-defined.
13.1225 + */
13.1226 + @Deprecated
13.1227 + public native int countStackFrames();
13.1228 +
13.1229 + /**
13.1230 + * Waits at most {@code millis} milliseconds for this thread to
13.1231 + * die. A timeout of {@code 0} means to wait forever.
13.1232 + *
13.1233 + * <p> This implementation uses a loop of {@code this.wait} calls
13.1234 + * conditioned on {@code this.isAlive}. As a thread terminates the
13.1235 + * {@code this.notifyAll} method is invoked. It is recommended that
13.1236 + * applications not use {@code wait}, {@code notify}, or
13.1237 + * {@code notifyAll} on {@code Thread} instances.
13.1238 + *
13.1239 + * @param millis
13.1240 + * the time to wait in milliseconds
13.1241 + *
13.1242 + * @throws IllegalArgumentException
13.1243 + * if the value of {@code millis} is negative
13.1244 + *
13.1245 + * @throws InterruptedException
13.1246 + * if any thread has interrupted the current thread. The
13.1247 + * <i>interrupted status</i> of the current thread is
13.1248 + * cleared when this exception is thrown.
13.1249 + */
13.1250 + public final synchronized void join(long millis)
13.1251 + throws InterruptedException {
13.1252 + long base = System.currentTimeMillis();
13.1253 + long now = 0;
13.1254 +
13.1255 + if (millis < 0) {
13.1256 + throw new IllegalArgumentException("timeout value is negative");
13.1257 + }
13.1258 +
13.1259 + if (millis == 0) {
13.1260 + while (isAlive()) {
13.1261 + wait(0);
13.1262 + }
13.1263 + } else {
13.1264 + while (isAlive()) {
13.1265 + long delay = millis - now;
13.1266 + if (delay <= 0) {
13.1267 + break;
13.1268 + }
13.1269 + wait(delay);
13.1270 + now = System.currentTimeMillis() - base;
13.1271 + }
13.1272 + }
13.1273 + }
13.1274 +
13.1275 + /**
13.1276 + * Waits at most {@code millis} milliseconds plus
13.1277 + * {@code nanos} nanoseconds for this thread to die.
13.1278 + *
13.1279 + * <p> This implementation uses a loop of {@code this.wait} calls
13.1280 + * conditioned on {@code this.isAlive}. As a thread terminates the
13.1281 + * {@code this.notifyAll} method is invoked. It is recommended that
13.1282 + * applications not use {@code wait}, {@code notify}, or
13.1283 + * {@code notifyAll} on {@code Thread} instances.
13.1284 + *
13.1285 + * @param millis
13.1286 + * the time to wait in milliseconds
13.1287 + *
13.1288 + * @param nanos
13.1289 + * {@code 0-999999} additional nanoseconds to wait
13.1290 + *
13.1291 + * @throws IllegalArgumentException
13.1292 + * if the value of {@code millis} is negative, or the value
13.1293 + * of {@code nanos} is not in the range {@code 0-999999}
13.1294 + *
13.1295 + * @throws InterruptedException
13.1296 + * if any thread has interrupted the current thread. The
13.1297 + * <i>interrupted status</i> of the current thread is
13.1298 + * cleared when this exception is thrown.
13.1299 + */
13.1300 + public final synchronized void join(long millis, int nanos)
13.1301 + throws InterruptedException {
13.1302 +
13.1303 + if (millis < 0) {
13.1304 + throw new IllegalArgumentException("timeout value is negative");
13.1305 + }
13.1306 +
13.1307 + if (nanos < 0 || nanos > 999999) {
13.1308 + throw new IllegalArgumentException(
13.1309 + "nanosecond timeout value out of range");
13.1310 + }
13.1311 +
13.1312 + if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
13.1313 + millis++;
13.1314 + }
13.1315 +
13.1316 + join(millis);
13.1317 + }
13.1318 +
13.1319 + /**
13.1320 + * Waits for this thread to die.
13.1321 + *
13.1322 + * <p> An invocation of this method behaves in exactly the same
13.1323 + * way as the invocation
13.1324 + *
13.1325 + * <blockquote>
13.1326 + * {@linkplain #join(long) join}{@code (0)}
13.1327 + * </blockquote>
13.1328 + *
13.1329 + * @throws InterruptedException
13.1330 + * if any thread has interrupted the current thread. The
13.1331 + * <i>interrupted status</i> of the current thread is
13.1332 + * cleared when this exception is thrown.
13.1333 + */
13.1334 + public final void join() throws InterruptedException {
13.1335 + join(0);
13.1336 + }
13.1337 +
13.1338 + /**
13.1339 + * Prints a stack trace of the current thread to the standard error stream.
13.1340 + * This method is used only for debugging.
13.1341 + *
13.1342 + * @see Throwable#printStackTrace()
13.1343 + */
13.1344 + public static void dumpStack() {
13.1345 + new Exception("Stack trace").printStackTrace();
13.1346 + }
13.1347 +
13.1348 + /**
13.1349 + * Marks this thread as either a {@linkplain #isDaemon daemon} thread
13.1350 + * or a user thread. The Java Virtual Machine exits when the only
13.1351 + * threads running are all daemon threads.
13.1352 + *
13.1353 + * <p> This method must be invoked before the thread is started.
13.1354 + *
13.1355 + * @param on
13.1356 + * if {@code true}, marks this thread as a daemon thread
13.1357 + *
13.1358 + * @throws IllegalThreadStateException
13.1359 + * if this thread is {@linkplain #isAlive alive}
13.1360 + *
13.1361 + * @throws SecurityException
13.1362 + * if {@link #checkAccess} determines that the current
13.1363 + * thread cannot modify this thread
13.1364 + */
13.1365 + public final void setDaemon(boolean on) {
13.1366 + checkAccess();
13.1367 + if (isAlive()) {
13.1368 + throw new IllegalThreadStateException();
13.1369 + }
13.1370 + daemon = on;
13.1371 + }
13.1372 +
13.1373 + /**
13.1374 + * Tests if this thread is a daemon thread.
13.1375 + *
13.1376 + * @return <code>true</code> if this thread is a daemon thread;
13.1377 + * <code>false</code> otherwise.
13.1378 + * @see #setDaemon(boolean)
13.1379 + */
13.1380 + public final boolean isDaemon() {
13.1381 + return daemon;
13.1382 + }
13.1383 +
13.1384 + /**
13.1385 + * Determines if the currently running thread has permission to
13.1386 + * modify this thread.
13.1387 + * <p>
13.1388 + * If there is a security manager, its <code>checkAccess</code> method
13.1389 + * is called with this thread as its argument. This may result in
13.1390 + * throwing a <code>SecurityException</code>.
13.1391 + *
13.1392 + * @exception SecurityException if the current thread is not allowed to
13.1393 + * access this thread.
13.1394 + * @see SecurityManager#checkAccess(Thread)
13.1395 + */
13.1396 + public final void checkAccess() {
13.1397 + SecurityManager security = System.getSecurityManager();
13.1398 + if (security != null) {
13.1399 + security.checkAccess(this);
13.1400 + }
13.1401 + }
13.1402 +
13.1403 + /**
13.1404 + * Returns a string representation of this thread, including the
13.1405 + * thread's name, priority, and thread group.
13.1406 + *
13.1407 + * @return a string representation of this thread.
13.1408 + */
13.1409 + public String toString() {
13.1410 + ThreadGroup group = getThreadGroup();
13.1411 + if (group != null) {
13.1412 + return "Thread[" + getName() + "," + getPriority() + "," +
13.1413 + group.getName() + "]";
13.1414 + } else {
13.1415 + return "Thread[" + getName() + "," + getPriority() + "," +
13.1416 + "" + "]";
13.1417 + }
13.1418 + }
13.1419 +
13.1420 + /**
13.1421 + * Returns the context ClassLoader for this Thread. The context
13.1422 + * ClassLoader is provided by the creator of the thread for use
13.1423 + * by code running in this thread when loading classes and resources.
13.1424 + * If not {@linkplain #setContextClassLoader set}, the default is the
13.1425 + * ClassLoader context of the parent Thread. The context ClassLoader of the
13.1426 + * primordial thread is typically set to the class loader used to load the
13.1427 + * application.
13.1428 + *
13.1429 + * <p>If a security manager is present, and the invoker's class loader is not
13.1430 + * {@code null} and is not the same as or an ancestor of the context class
13.1431 + * loader, then this method invokes the security manager's {@link
13.1432 + * SecurityManager#checkPermission(java.security.Permission) checkPermission}
13.1433 + * method with a {@link RuntimePermission RuntimePermission}{@code
13.1434 + * ("getClassLoader")} permission to verify that retrieval of the context
13.1435 + * class loader is permitted.
13.1436 + *
13.1437 + * @return the context ClassLoader for this Thread, or {@code null}
13.1438 + * indicating the system class loader (or, failing that, the
13.1439 + * bootstrap class loader)
13.1440 + *
13.1441 + * @throws SecurityException
13.1442 + * if the current thread cannot get the context ClassLoader
13.1443 + *
13.1444 + * @since 1.2
13.1445 + */
13.1446 + public ClassLoader getContextClassLoader() {
13.1447 + if (contextClassLoader == null)
13.1448 + return null;
13.1449 + SecurityManager sm = System.getSecurityManager();
13.1450 + if (sm != null) {
13.1451 + ClassLoader ccl = ClassLoader.getCallerClassLoader();
13.1452 + if (ccl != null && ccl != contextClassLoader &&
13.1453 + !contextClassLoader.isAncestor(ccl)) {
13.1454 + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
13.1455 + }
13.1456 + }
13.1457 + return contextClassLoader;
13.1458 + }
13.1459 +
13.1460 + /**
13.1461 + * Sets the context ClassLoader for this Thread. The context
13.1462 + * ClassLoader can be set when a thread is created, and allows
13.1463 + * the creator of the thread to provide the appropriate class loader,
13.1464 + * through {@code getContextClassLoader}, to code running in the thread
13.1465 + * when loading classes and resources.
13.1466 + *
13.1467 + * <p>If a security manager is present, its {@link
13.1468 + * SecurityManager#checkPermission(java.security.Permission) checkPermission}
13.1469 + * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
13.1470 + * ("setContextClassLoader")} permission to see if setting the context
13.1471 + * ClassLoader is permitted.
13.1472 + *
13.1473 + * @param cl
13.1474 + * the context ClassLoader for this Thread, or null indicating the
13.1475 + * system class loader (or, failing that, the bootstrap class loader)
13.1476 + *
13.1477 + * @throws SecurityException
13.1478 + * if the current thread cannot set the context ClassLoader
13.1479 + *
13.1480 + * @since 1.2
13.1481 + */
13.1482 + public void setContextClassLoader(ClassLoader cl) {
13.1483 + SecurityManager sm = System.getSecurityManager();
13.1484 + if (sm != null) {
13.1485 + sm.checkPermission(new RuntimePermission("setContextClassLoader"));
13.1486 + }
13.1487 + contextClassLoader = cl;
13.1488 + }
13.1489 +
13.1490 + /**
13.1491 + * Returns <tt>true</tt> if and only if the current thread holds the
13.1492 + * monitor lock on the specified object.
13.1493 + *
13.1494 + * <p>This method is designed to allow a program to assert that
13.1495 + * the current thread already holds a specified lock:
13.1496 + * <pre>
13.1497 + * assert Thread.holdsLock(obj);
13.1498 + * </pre>
13.1499 + *
13.1500 + * @param obj the object on which to test lock ownership
13.1501 + * @throws NullPointerException if obj is <tt>null</tt>
13.1502 + * @return <tt>true</tt> if the current thread holds the monitor lock on
13.1503 + * the specified object.
13.1504 + * @since 1.4
13.1505 + */
13.1506 + public static native boolean holdsLock(Object obj);
13.1507 +
13.1508 + private static final StackTraceElement[] EMPTY_STACK_TRACE
13.1509 + = new StackTraceElement[0];
13.1510 +
13.1511 + /**
13.1512 + * Returns an array of stack trace elements representing the stack dump
13.1513 + * of this thread. This method will return a zero-length array if
13.1514 + * this thread has not started, has started but has not yet been
13.1515 + * scheduled to run by the system, or has terminated.
13.1516 + * If the returned array is of non-zero length then the first element of
13.1517 + * the array represents the top of the stack, which is the most recent
13.1518 + * method invocation in the sequence. The last element of the array
13.1519 + * represents the bottom of the stack, which is the least recent method
13.1520 + * invocation in the sequence.
13.1521 + *
13.1522 + * <p>If there is a security manager, and this thread is not
13.1523 + * the current thread, then the security manager's
13.1524 + * <tt>checkPermission</tt> method is called with a
13.1525 + * <tt>RuntimePermission("getStackTrace")</tt> permission
13.1526 + * to see if it's ok to get the stack trace.
13.1527 + *
13.1528 + * <p>Some virtual machines may, under some circumstances, omit one
13.1529 + * or more stack frames from the stack trace. In the extreme case,
13.1530 + * a virtual machine that has no stack trace information concerning
13.1531 + * this thread is permitted to return a zero-length array from this
13.1532 + * method.
13.1533 + *
13.1534 + * @return an array of <tt>StackTraceElement</tt>,
13.1535 + * each represents one stack frame.
13.1536 + *
13.1537 + * @throws SecurityException
13.1538 + * if a security manager exists and its
13.1539 + * <tt>checkPermission</tt> method doesn't allow
13.1540 + * getting the stack trace of thread.
13.1541 + * @see SecurityManager#checkPermission
13.1542 + * @see RuntimePermission
13.1543 + * @see Throwable#getStackTrace
13.1544 + *
13.1545 + * @since 1.5
13.1546 + */
13.1547 + public StackTraceElement[] getStackTrace() {
13.1548 + if (this != Thread.currentThread()) {
13.1549 + // check for getStackTrace permission
13.1550 + SecurityManager security = System.getSecurityManager();
13.1551 + if (security != null) {
13.1552 + security.checkPermission(
13.1553 + SecurityConstants.GET_STACK_TRACE_PERMISSION);
13.1554 + }
13.1555 + // optimization so we do not call into the vm for threads that
13.1556 + // have not yet started or have terminated
13.1557 + if (!isAlive()) {
13.1558 + return EMPTY_STACK_TRACE;
13.1559 + }
13.1560 + StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
13.1561 + StackTraceElement[] stackTrace = stackTraceArray[0];
13.1562 + // a thread that was alive during the previous isAlive call may have
13.1563 + // since terminated, therefore not having a stacktrace.
13.1564 + if (stackTrace == null) {
13.1565 + stackTrace = EMPTY_STACK_TRACE;
13.1566 + }
13.1567 + return stackTrace;
13.1568 + } else {
13.1569 + // Don't need JVM help for current thread
13.1570 + return (new Exception()).getStackTrace();
13.1571 + }
13.1572 + }
13.1573 +
13.1574 + /**
13.1575 + * Returns a map of stack traces for all live threads.
13.1576 + * The map keys are threads and each map value is an array of
13.1577 + * <tt>StackTraceElement</tt> that represents the stack dump
13.1578 + * of the corresponding <tt>Thread</tt>.
13.1579 + * The returned stack traces are in the format specified for
13.1580 + * the {@link #getStackTrace getStackTrace} method.
13.1581 + *
13.1582 + * <p>The threads may be executing while this method is called.
13.1583 + * The stack trace of each thread only represents a snapshot and
13.1584 + * each stack trace may be obtained at different time. A zero-length
13.1585 + * array will be returned in the map value if the virtual machine has
13.1586 + * no stack trace information about a thread.
13.1587 + *
13.1588 + * <p>If there is a security manager, then the security manager's
13.1589 + * <tt>checkPermission</tt> method is called with a
13.1590 + * <tt>RuntimePermission("getStackTrace")</tt> permission as well as
13.1591 + * <tt>RuntimePermission("modifyThreadGroup")</tt> permission
13.1592 + * to see if it is ok to get the stack trace of all threads.
13.1593 + *
13.1594 + * @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
13.1595 + * <tt>StackTraceElement</tt> that represents the stack trace of
13.1596 + * the corresponding thread.
13.1597 + *
13.1598 + * @throws SecurityException
13.1599 + * if a security manager exists and its
13.1600 + * <tt>checkPermission</tt> method doesn't allow
13.1601 + * getting the stack trace of thread.
13.1602 + * @see #getStackTrace
13.1603 + * @see SecurityManager#checkPermission
13.1604 + * @see RuntimePermission
13.1605 + * @see Throwable#getStackTrace
13.1606 + *
13.1607 + * @since 1.5
13.1608 + */
13.1609 + public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
13.1610 + // check for getStackTrace permission
13.1611 + SecurityManager security = System.getSecurityManager();
13.1612 + if (security != null) {
13.1613 + security.checkPermission(
13.1614 + SecurityConstants.GET_STACK_TRACE_PERMISSION);
13.1615 + security.checkPermission(
13.1616 + SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
13.1617 + }
13.1618 +
13.1619 + // Get a snapshot of the list of all threads
13.1620 + Thread[] threads = getThreads();
13.1621 + StackTraceElement[][] traces = dumpThreads(threads);
13.1622 + Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
13.1623 + for (int i = 0; i < threads.length; i++) {
13.1624 + StackTraceElement[] stackTrace = traces[i];
13.1625 + if (stackTrace != null) {
13.1626 + m.put(threads[i], stackTrace);
13.1627 + }
13.1628 + // else terminated so we don't put it in the map
13.1629 + }
13.1630 + return m;
13.1631 + }
13.1632 +
13.1633 +
13.1634 + private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
13.1635 + new RuntimePermission("enableContextClassLoaderOverride");
13.1636 +
13.1637 + /** cache of subclass security audit results */
13.1638 + /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
13.1639 + * release */
13.1640 + private static class Caches {
13.1641 + /** cache of subclass security audit results */
13.1642 + static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
13.1643 + new ConcurrentHashMap<>();
13.1644 +
13.1645 + /** queue for WeakReferences to audited subclasses */
13.1646 + static final ReferenceQueue<Class<?>> subclassAuditsQueue =
13.1647 + new ReferenceQueue<>();
13.1648 + }
13.1649 +
13.1650 + /**
13.1651 + * Verifies that this (possibly subclass) instance can be constructed
13.1652 + * without violating security constraints: the subclass must not override
13.1653 + * security-sensitive non-final methods, or else the
13.1654 + * "enableContextClassLoaderOverride" RuntimePermission is checked.
13.1655 + */
13.1656 + private static boolean isCCLOverridden(Class cl) {
13.1657 + if (cl == Thread.class)
13.1658 + return false;
13.1659 +
13.1660 + processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
13.1661 + WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
13.1662 + Boolean result = Caches.subclassAudits.get(key);
13.1663 + if (result == null) {
13.1664 + result = Boolean.valueOf(auditSubclass(cl));
13.1665 + Caches.subclassAudits.putIfAbsent(key, result);
13.1666 + }
13.1667 +
13.1668 + return result.booleanValue();
13.1669 + }
13.1670 +
13.1671 + /**
13.1672 + * Performs reflective checks on given subclass to verify that it doesn't
13.1673 + * override security-sensitive non-final methods. Returns true if the
13.1674 + * subclass overrides any of the methods, false otherwise.
13.1675 + */
13.1676 + private static boolean auditSubclass(final Class subcl) {
13.1677 + Boolean result = AccessController.doPrivileged(
13.1678 + new PrivilegedAction<Boolean>() {
13.1679 + public Boolean run() {
13.1680 + for (Class cl = subcl;
13.1681 + cl != Thread.class;
13.1682 + cl = cl.getSuperclass())
13.1683 + {
13.1684 + try {
13.1685 + cl.getDeclaredMethod("getContextClassLoader", new Class[0]);
13.1686 + return Boolean.TRUE;
13.1687 + } catch (NoSuchMethodException ex) {
13.1688 + }
13.1689 + try {
13.1690 + Class[] params = {ClassLoader.class};
13.1691 + cl.getDeclaredMethod("setContextClassLoader", params);
13.1692 + return Boolean.TRUE;
13.1693 + } catch (NoSuchMethodException ex) {
13.1694 + }
13.1695 + }
13.1696 + return Boolean.FALSE;
13.1697 + }
13.1698 + }
13.1699 + );
13.1700 + return result.booleanValue();
13.1701 + }
13.1702 +
13.1703 + private native static StackTraceElement[][] dumpThreads(Thread[] threads);
13.1704 + private native static Thread[] getThreads();
13.1705 +
13.1706 + /**
13.1707 + * Returns the identifier of this Thread. The thread ID is a positive
13.1708 + * <tt>long</tt> number generated when this thread was created.
13.1709 + * The thread ID is unique and remains unchanged during its lifetime.
13.1710 + * When a thread is terminated, this thread ID may be reused.
13.1711 + *
13.1712 + * @return this thread's ID.
13.1713 + * @since 1.5
13.1714 + */
13.1715 + public long getId() {
13.1716 + return tid;
13.1717 + }
13.1718 +
13.1719 + /**
13.1720 + * A thread state. A thread can be in one of the following states:
13.1721 + * <ul>
13.1722 + * <li>{@link #NEW}<br>
13.1723 + * A thread that has not yet started is in this state.
13.1724 + * </li>
13.1725 + * <li>{@link #RUNNABLE}<br>
13.1726 + * A thread executing in the Java virtual machine is in this state.
13.1727 + * </li>
13.1728 + * <li>{@link #BLOCKED}<br>
13.1729 + * A thread that is blocked waiting for a monitor lock
13.1730 + * is in this state.
13.1731 + * </li>
13.1732 + * <li>{@link #WAITING}<br>
13.1733 + * A thread that is waiting indefinitely for another thread to
13.1734 + * perform a particular action is in this state.
13.1735 + * </li>
13.1736 + * <li>{@link #TIMED_WAITING}<br>
13.1737 + * A thread that is waiting for another thread to perform an action
13.1738 + * for up to a specified waiting time is in this state.
13.1739 + * </li>
13.1740 + * <li>{@link #TERMINATED}<br>
13.1741 + * A thread that has exited is in this state.
13.1742 + * </li>
13.1743 + * </ul>
13.1744 + *
13.1745 + * <p>
13.1746 + * A thread can be in only one state at a given point in time.
13.1747 + * These states are virtual machine states which do not reflect
13.1748 + * any operating system thread states.
13.1749 + *
13.1750 + * @since 1.5
13.1751 + * @see #getState
13.1752 + */
13.1753 + public enum State {
13.1754 + /**
13.1755 + * Thread state for a thread which has not yet started.
13.1756 + */
13.1757 + NEW,
13.1758 +
13.1759 + /**
13.1760 + * Thread state for a runnable thread. A thread in the runnable
13.1761 + * state is executing in the Java virtual machine but it may
13.1762 + * be waiting for other resources from the operating system
13.1763 + * such as processor.
13.1764 + */
13.1765 + RUNNABLE,
13.1766 +
13.1767 + /**
13.1768 + * Thread state for a thread blocked waiting for a monitor lock.
13.1769 + * A thread in the blocked state is waiting for a monitor lock
13.1770 + * to enter a synchronized block/method or
13.1771 + * reenter a synchronized block/method after calling
13.1772 + * {@link Object#wait() Object.wait}.
13.1773 + */
13.1774 + BLOCKED,
13.1775 +
13.1776 + /**
13.1777 + * Thread state for a waiting thread.
13.1778 + * A thread is in the waiting state due to calling one of the
13.1779 + * following methods:
13.1780 + * <ul>
13.1781 + * <li>{@link Object#wait() Object.wait} with no timeout</li>
13.1782 + * <li>{@link #join() Thread.join} with no timeout</li>
13.1783 + * <li>{@link LockSupport#park() LockSupport.park}</li>
13.1784 + * </ul>
13.1785 + *
13.1786 + * <p>A thread in the waiting state is waiting for another thread to
13.1787 + * perform a particular action.
13.1788 + *
13.1789 + * For example, a thread that has called <tt>Object.wait()</tt>
13.1790 + * on an object is waiting for another thread to call
13.1791 + * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
13.1792 + * that object. A thread that has called <tt>Thread.join()</tt>
13.1793 + * is waiting for a specified thread to terminate.
13.1794 + */
13.1795 + WAITING,
13.1796 +
13.1797 + /**
13.1798 + * Thread state for a waiting thread with a specified waiting time.
13.1799 + * A thread is in the timed waiting state due to calling one of
13.1800 + * the following methods with a specified positive waiting time:
13.1801 + * <ul>
13.1802 + * <li>{@link #sleep Thread.sleep}</li>
13.1803 + * <li>{@link Object#wait(long) Object.wait} with timeout</li>
13.1804 + * <li>{@link #join(long) Thread.join} with timeout</li>
13.1805 + * <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
13.1806 + * <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
13.1807 + * </ul>
13.1808 + */
13.1809 + TIMED_WAITING,
13.1810 +
13.1811 + /**
13.1812 + * Thread state for a terminated thread.
13.1813 + * The thread has completed execution.
13.1814 + */
13.1815 + TERMINATED;
13.1816 + }
13.1817 +
13.1818 + /**
13.1819 + * Returns the state of this thread.
13.1820 + * This method is designed for use in monitoring of the system state,
13.1821 + * not for synchronization control.
13.1822 + *
13.1823 + * @return this thread's state.
13.1824 + * @since 1.5
13.1825 + */
13.1826 + public State getState() {
13.1827 + // get current thread state
13.1828 + return sun.misc.VM.toThreadState(threadStatus);
13.1829 + }
13.1830 +
13.1831 + // Added in JSR-166
13.1832 +
13.1833 + /**
13.1834 + * Interface for handlers invoked when a <tt>Thread</tt> abruptly
13.1835 + * terminates due to an uncaught exception.
13.1836 + * <p>When a thread is about to terminate due to an uncaught exception
13.1837 + * the Java Virtual Machine will query the thread for its
13.1838 + * <tt>UncaughtExceptionHandler</tt> using
13.1839 + * {@link #getUncaughtExceptionHandler} and will invoke the handler's
13.1840 + * <tt>uncaughtException</tt> method, passing the thread and the
13.1841 + * exception as arguments.
13.1842 + * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
13.1843 + * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
13.1844 + * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
13.1845 + * has no
13.1846 + * special requirements for dealing with the exception, it can forward
13.1847 + * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
13.1848 + * default uncaught exception handler}.
13.1849 + *
13.1850 + * @see #setDefaultUncaughtExceptionHandler
13.1851 + * @see #setUncaughtExceptionHandler
13.1852 + * @see ThreadGroup#uncaughtException
13.1853 + * @since 1.5
13.1854 + */
13.1855 + public interface UncaughtExceptionHandler {
13.1856 + /**
13.1857 + * Method invoked when the given thread terminates due to the
13.1858 + * given uncaught exception.
13.1859 + * <p>Any exception thrown by this method will be ignored by the
13.1860 + * Java Virtual Machine.
13.1861 + * @param t the thread
13.1862 + * @param e the exception
13.1863 + */
13.1864 + void uncaughtException(Thread t, Throwable e);
13.1865 + }
13.1866 +
13.1867 + // null unless explicitly set
13.1868 + private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
13.1869 +
13.1870 + // null unless explicitly set
13.1871 + private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
13.1872 +
13.1873 + /**
13.1874 + * Set the default handler invoked when a thread abruptly terminates
13.1875 + * due to an uncaught exception, and no other handler has been defined
13.1876 + * for that thread.
13.1877 + *
13.1878 + * <p>Uncaught exception handling is controlled first by the thread, then
13.1879 + * by the thread's {@link ThreadGroup} object and finally by the default
13.1880 + * uncaught exception handler. If the thread does not have an explicit
13.1881 + * uncaught exception handler set, and the thread's thread group
13.1882 + * (including parent thread groups) does not specialize its
13.1883 + * <tt>uncaughtException</tt> method, then the default handler's
13.1884 + * <tt>uncaughtException</tt> method will be invoked.
13.1885 + * <p>By setting the default uncaught exception handler, an application
13.1886 + * can change the way in which uncaught exceptions are handled (such as
13.1887 + * logging to a specific device, or file) for those threads that would
13.1888 + * already accept whatever "default" behavior the system
13.1889 + * provided.
13.1890 + *
13.1891 + * <p>Note that the default uncaught exception handler should not usually
13.1892 + * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
13.1893 + * infinite recursion.
13.1894 + *
13.1895 + * @param eh the object to use as the default uncaught exception handler.
13.1896 + * If <tt>null</tt> then there is no default handler.
13.1897 + *
13.1898 + * @throws SecurityException if a security manager is present and it
13.1899 + * denies <tt>{@link RuntimePermission}
13.1900 + * ("setDefaultUncaughtExceptionHandler")</tt>
13.1901 + *
13.1902 + * @see #setUncaughtExceptionHandler
13.1903 + * @see #getUncaughtExceptionHandler
13.1904 + * @see ThreadGroup#uncaughtException
13.1905 + * @since 1.5
13.1906 + */
13.1907 + public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
13.1908 + SecurityManager sm = System.getSecurityManager();
13.1909 + if (sm != null) {
13.1910 + sm.checkPermission(
13.1911 + new RuntimePermission("setDefaultUncaughtExceptionHandler")
13.1912 + );
13.1913 + }
13.1914 +
13.1915 + defaultUncaughtExceptionHandler = eh;
13.1916 + }
13.1917 +
13.1918 + /**
13.1919 + * Returns the default handler invoked when a thread abruptly terminates
13.1920 + * due to an uncaught exception. If the returned value is <tt>null</tt>,
13.1921 + * there is no default.
13.1922 + * @since 1.5
13.1923 + * @see #setDefaultUncaughtExceptionHandler
13.1924 + */
13.1925 + public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
13.1926 + return defaultUncaughtExceptionHandler;
13.1927 + }
13.1928 +
13.1929 + /**
13.1930 + * Returns the handler invoked when this thread abruptly terminates
13.1931 + * due to an uncaught exception. If this thread has not had an
13.1932 + * uncaught exception handler explicitly set then this thread's
13.1933 + * <tt>ThreadGroup</tt> object is returned, unless this thread
13.1934 + * has terminated, in which case <tt>null</tt> is returned.
13.1935 + * @since 1.5
13.1936 + */
13.1937 + public UncaughtExceptionHandler getUncaughtExceptionHandler() {
13.1938 + return uncaughtExceptionHandler != null ?
13.1939 + uncaughtExceptionHandler : group;
13.1940 + }
13.1941 +
13.1942 + /**
13.1943 + * Set the handler invoked when this thread abruptly terminates
13.1944 + * due to an uncaught exception.
13.1945 + * <p>A thread can take full control of how it responds to uncaught
13.1946 + * exceptions by having its uncaught exception handler explicitly set.
13.1947 + * If no such handler is set then the thread's <tt>ThreadGroup</tt>
13.1948 + * object acts as its handler.
13.1949 + * @param eh the object to use as this thread's uncaught exception
13.1950 + * handler. If <tt>null</tt> then this thread has no explicit handler.
13.1951 + * @throws SecurityException if the current thread is not allowed to
13.1952 + * modify this thread.
13.1953 + * @see #setDefaultUncaughtExceptionHandler
13.1954 + * @see ThreadGroup#uncaughtException
13.1955 + * @since 1.5
13.1956 + */
13.1957 + public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
13.1958 + checkAccess();
13.1959 + uncaughtExceptionHandler = eh;
13.1960 + }
13.1961 +
13.1962 + /**
13.1963 + * Dispatch an uncaught exception to the handler. This method is
13.1964 + * intended to be called only by the JVM.
13.1965 + */
13.1966 + private void dispatchUncaughtException(Throwable e) {
13.1967 + getUncaughtExceptionHandler().uncaughtException(this, e);
13.1968 + }
13.1969 +
13.1970 + /**
13.1971 + * Removes from the specified map any keys that have been enqueued
13.1972 + * on the specified reference queue.
13.1973 + */
13.1974 + static void processQueue(ReferenceQueue<Class<?>> queue,
13.1975 + ConcurrentMap<? extends
13.1976 + WeakReference<Class<?>>, ?> map)
13.1977 + {
13.1978 + Reference<? extends Class<?>> ref;
13.1979 + while((ref = queue.poll()) != null) {
13.1980 + map.remove(ref);
13.1981 + }
13.1982 + }
13.1983 +
13.1984 + /**
13.1985 + * Weak key for Class objects.
13.1986 + **/
13.1987 + static class WeakClassKey extends WeakReference<Class<?>> {
13.1988 + /**
13.1989 + * saved value of the referent's identity hash code, to maintain
13.1990 + * a consistent hash code after the referent has been cleared
13.1991 + */
13.1992 + private final int hash;
13.1993 +
13.1994 + /**
13.1995 + * Create a new WeakClassKey to the given object, registered
13.1996 + * with a queue.
13.1997 + */
13.1998 + WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
13.1999 + super(cl, refQueue);
13.2000 + hash = System.identityHashCode(cl);
13.2001 + }
13.2002 +
13.2003 + /**
13.2004 + * Returns the identity hash code of the original referent.
13.2005 + */
13.2006 + @Override
13.2007 + public int hashCode() {
13.2008 + return hash;
13.2009 + }
13.2010 +
13.2011 + /**
13.2012 + * Returns true if the given object is this identical
13.2013 + * WeakClassKey instance, or, if this object's referent has not
13.2014 + * been cleared, if the given object is another WeakClassKey
13.2015 + * instance with the identical non-null referent as this one.
13.2016 + */
13.2017 + @Override
13.2018 + public boolean equals(Object obj) {
13.2019 + if (obj == this)
13.2020 + return true;
13.2021 +
13.2022 + if (obj instanceof WeakClassKey) {
13.2023 + Object referent = get();
13.2024 + return (referent != null) &&
13.2025 + (referent == ((WeakClassKey) obj).get());
13.2026 + } else {
13.2027 + return false;
13.2028 + }
13.2029 + }
13.2030 + }
13.2031 +
13.2032 + /* Some private helper methods */
13.2033 + private native void setPriority0(int newPriority);
13.2034 + private native void stop0(Object o);
13.2035 + private native void suspend0();
13.2036 + private native void resume0();
13.2037 + private native void interrupt0();
13.2038 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/emul/compact/src/main/java/java/math/BigDecimal.java Sat Sep 07 13:51:24 2013 +0200
14.3 @@ -0,0 +1,3855 @@
14.4 +/*
14.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.7 + *
14.8 + * This code is free software; you can redistribute it and/or modify it
14.9 + * under the terms of the GNU General Public License version 2 only, as
14.10 + * published by the Free Software Foundation. Oracle designates this
14.11 + * particular file as subject to the "Classpath" exception as provided
14.12 + * by Oracle in the LICENSE file that accompanied this code.
14.13 + *
14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.17 + * version 2 for more details (a copy is included in the LICENSE file that
14.18 + * accompanied this code).
14.19 + *
14.20 + * You should have received a copy of the GNU General Public License version
14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.23 + *
14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
14.25 + * or visit www.oracle.com if you need additional information or have any
14.26 + * questions.
14.27 + */
14.28 +
14.29 +/*
14.30 + * Portions Copyright IBM Corporation, 2001. All Rights Reserved.
14.31 + */
14.32 +
14.33 +package java.math;
14.34 +
14.35 +import java.util.Arrays;
14.36 +import static java.math.BigInteger.LONG_MASK;
14.37 +
14.38 +/**
14.39 + * Immutable, arbitrary-precision signed decimal numbers. A
14.40 + * {@code BigDecimal} consists of an arbitrary precision integer
14.41 + * <i>unscaled value</i> and a 32-bit integer <i>scale</i>. If zero
14.42 + * or positive, the scale is the number of digits to the right of the
14.43 + * decimal point. If negative, the unscaled value of the number is
14.44 + * multiplied by ten to the power of the negation of the scale. The
14.45 + * value of the number represented by the {@code BigDecimal} is
14.46 + * therefore <tt>(unscaledValue × 10<sup>-scale</sup>)</tt>.
14.47 + *
14.48 + * <p>The {@code BigDecimal} class provides operations for
14.49 + * arithmetic, scale manipulation, rounding, comparison, hashing, and
14.50 + * format conversion. The {@link #toString} method provides a
14.51 + * canonical representation of a {@code BigDecimal}.
14.52 + *
14.53 + * <p>The {@code BigDecimal} class gives its user complete control
14.54 + * over rounding behavior. If no rounding mode is specified and the
14.55 + * exact result cannot be represented, an exception is thrown;
14.56 + * otherwise, calculations can be carried out to a chosen precision
14.57 + * and rounding mode by supplying an appropriate {@link MathContext}
14.58 + * object to the operation. In either case, eight <em>rounding
14.59 + * modes</em> are provided for the control of rounding. Using the
14.60 + * integer fields in this class (such as {@link #ROUND_HALF_UP}) to
14.61 + * represent rounding mode is largely obsolete; the enumeration values
14.62 + * of the {@code RoundingMode} {@code enum}, (such as {@link
14.63 + * RoundingMode#HALF_UP}) should be used instead.
14.64 + *
14.65 + * <p>When a {@code MathContext} object is supplied with a precision
14.66 + * setting of 0 (for example, {@link MathContext#UNLIMITED}),
14.67 + * arithmetic operations are exact, as are the arithmetic methods
14.68 + * which take no {@code MathContext} object. (This is the only
14.69 + * behavior that was supported in releases prior to 5.) As a
14.70 + * corollary of computing the exact result, the rounding mode setting
14.71 + * of a {@code MathContext} object with a precision setting of 0 is
14.72 + * not used and thus irrelevant. In the case of divide, the exact
14.73 + * quotient could have an infinitely long decimal expansion; for
14.74 + * example, 1 divided by 3. If the quotient has a nonterminating
14.75 + * decimal expansion and the operation is specified to return an exact
14.76 + * result, an {@code ArithmeticException} is thrown. Otherwise, the
14.77 + * exact result of the division is returned, as done for other
14.78 + * operations.
14.79 + *
14.80 + * <p>When the precision setting is not 0, the rules of
14.81 + * {@code BigDecimal} arithmetic are broadly compatible with selected
14.82 + * modes of operation of the arithmetic defined in ANSI X3.274-1996
14.83 + * and ANSI X3.274-1996/AM 1-2000 (section 7.4). Unlike those
14.84 + * standards, {@code BigDecimal} includes many rounding modes, which
14.85 + * were mandatory for division in {@code BigDecimal} releases prior
14.86 + * to 5. Any conflicts between these ANSI standards and the
14.87 + * {@code BigDecimal} specification are resolved in favor of
14.88 + * {@code BigDecimal}.
14.89 + *
14.90 + * <p>Since the same numerical value can have different
14.91 + * representations (with different scales), the rules of arithmetic
14.92 + * and rounding must specify both the numerical result and the scale
14.93 + * used in the result's representation.
14.94 + *
14.95 + *
14.96 + * <p>In general the rounding modes and precision setting determine
14.97 + * how operations return results with a limited number of digits when
14.98 + * the exact result has more digits (perhaps infinitely many in the
14.99 + * case of division) than the number of digits returned.
14.100 + *
14.101 + * First, the
14.102 + * total number of digits to return is specified by the
14.103 + * {@code MathContext}'s {@code precision} setting; this determines
14.104 + * the result's <i>precision</i>. The digit count starts from the
14.105 + * leftmost nonzero digit of the exact result. The rounding mode
14.106 + * determines how any discarded trailing digits affect the returned
14.107 + * result.
14.108 + *
14.109 + * <p>For all arithmetic operators , the operation is carried out as
14.110 + * though an exact intermediate result were first calculated and then
14.111 + * rounded to the number of digits specified by the precision setting
14.112 + * (if necessary), using the selected rounding mode. If the exact
14.113 + * result is not returned, some digit positions of the exact result
14.114 + * are discarded. When rounding increases the magnitude of the
14.115 + * returned result, it is possible for a new digit position to be
14.116 + * created by a carry propagating to a leading {@literal "9"} digit.
14.117 + * For example, rounding the value 999.9 to three digits rounding up
14.118 + * would be numerically equal to one thousand, represented as
14.119 + * 100×10<sup>1</sup>. In such cases, the new {@literal "1"} is
14.120 + * the leading digit position of the returned result.
14.121 + *
14.122 + * <p>Besides a logical exact result, each arithmetic operation has a
14.123 + * preferred scale for representing a result. The preferred
14.124 + * scale for each operation is listed in the table below.
14.125 + *
14.126 + * <table border>
14.127 + * <caption><b>Preferred Scales for Results of Arithmetic Operations
14.128 + * </b></caption>
14.129 + * <tr><th>Operation</th><th>Preferred Scale of Result</th></tr>
14.130 + * <tr><td>Add</td><td>max(addend.scale(), augend.scale())</td>
14.131 + * <tr><td>Subtract</td><td>max(minuend.scale(), subtrahend.scale())</td>
14.132 + * <tr><td>Multiply</td><td>multiplier.scale() + multiplicand.scale()</td>
14.133 + * <tr><td>Divide</td><td>dividend.scale() - divisor.scale()</td>
14.134 + * </table>
14.135 + *
14.136 + * These scales are the ones used by the methods which return exact
14.137 + * arithmetic results; except that an exact divide may have to use a
14.138 + * larger scale since the exact result may have more digits. For
14.139 + * example, {@code 1/32} is {@code 0.03125}.
14.140 + *
14.141 + * <p>Before rounding, the scale of the logical exact intermediate
14.142 + * result is the preferred scale for that operation. If the exact
14.143 + * numerical result cannot be represented in {@code precision}
14.144 + * digits, rounding selects the set of digits to return and the scale
14.145 + * of the result is reduced from the scale of the intermediate result
14.146 + * to the least scale which can represent the {@code precision}
14.147 + * digits actually returned. If the exact result can be represented
14.148 + * with at most {@code precision} digits, the representation
14.149 + * of the result with the scale closest to the preferred scale is
14.150 + * returned. In particular, an exactly representable quotient may be
14.151 + * represented in fewer than {@code precision} digits by removing
14.152 + * trailing zeros and decreasing the scale. For example, rounding to
14.153 + * three digits using the {@linkplain RoundingMode#FLOOR floor}
14.154 + * rounding mode, <br>
14.155 + *
14.156 + * {@code 19/100 = 0.19 // integer=19, scale=2} <br>
14.157 + *
14.158 + * but<br>
14.159 + *
14.160 + * {@code 21/110 = 0.190 // integer=190, scale=3} <br>
14.161 + *
14.162 + * <p>Note that for add, subtract, and multiply, the reduction in
14.163 + * scale will equal the number of digit positions of the exact result
14.164 + * which are discarded. If the rounding causes a carry propagation to
14.165 + * create a new high-order digit position, an additional digit of the
14.166 + * result is discarded than when no new digit position is created.
14.167 + *
14.168 + * <p>Other methods may have slightly different rounding semantics.
14.169 + * For example, the result of the {@code pow} method using the
14.170 + * {@linkplain #pow(int, MathContext) specified algorithm} can
14.171 + * occasionally differ from the rounded mathematical result by more
14.172 + * than one unit in the last place, one <i>{@linkplain #ulp() ulp}</i>.
14.173 + *
14.174 + * <p>Two types of operations are provided for manipulating the scale
14.175 + * of a {@code BigDecimal}: scaling/rounding operations and decimal
14.176 + * point motion operations. Scaling/rounding operations ({@link
14.177 + * #setScale setScale} and {@link #round round}) return a
14.178 + * {@code BigDecimal} whose value is approximately (or exactly) equal
14.179 + * to that of the operand, but whose scale or precision is the
14.180 + * specified value; that is, they increase or decrease the precision
14.181 + * of the stored number with minimal effect on its value. Decimal
14.182 + * point motion operations ({@link #movePointLeft movePointLeft} and
14.183 + * {@link #movePointRight movePointRight}) return a
14.184 + * {@code BigDecimal} created from the operand by moving the decimal
14.185 + * point a specified distance in the specified direction.
14.186 + *
14.187 + * <p>For the sake of brevity and clarity, pseudo-code is used
14.188 + * throughout the descriptions of {@code BigDecimal} methods. The
14.189 + * pseudo-code expression {@code (i + j)} is shorthand for "a
14.190 + * {@code BigDecimal} whose value is that of the {@code BigDecimal}
14.191 + * {@code i} added to that of the {@code BigDecimal}
14.192 + * {@code j}." The pseudo-code expression {@code (i == j)} is
14.193 + * shorthand for "{@code true} if and only if the
14.194 + * {@code BigDecimal} {@code i} represents the same value as the
14.195 + * {@code BigDecimal} {@code j}." Other pseudo-code expressions
14.196 + * are interpreted similarly. Square brackets are used to represent
14.197 + * the particular {@code BigInteger} and scale pair defining a
14.198 + * {@code BigDecimal} value; for example [19, 2] is the
14.199 + * {@code BigDecimal} numerically equal to 0.19 having a scale of 2.
14.200 + *
14.201 + * <p>Note: care should be exercised if {@code BigDecimal} objects
14.202 + * are used as keys in a {@link java.util.SortedMap SortedMap} or
14.203 + * elements in a {@link java.util.SortedSet SortedSet} since
14.204 + * {@code BigDecimal}'s <i>natural ordering</i> is <i>inconsistent
14.205 + * with equals</i>. See {@link Comparable}, {@link
14.206 + * java.util.SortedMap} or {@link java.util.SortedSet} for more
14.207 + * information.
14.208 + *
14.209 + * <p>All methods and constructors for this class throw
14.210 + * {@code NullPointerException} when passed a {@code null} object
14.211 + * reference for any input parameter.
14.212 + *
14.213 + * @see BigInteger
14.214 + * @see MathContext
14.215 + * @see RoundingMode
14.216 + * @see java.util.SortedMap
14.217 + * @see java.util.SortedSet
14.218 + * @author Josh Bloch
14.219 + * @author Mike Cowlishaw
14.220 + * @author Joseph D. Darcy
14.221 + */
14.222 +public class BigDecimal extends Number implements Comparable<BigDecimal> {
14.223 + /**
14.224 + * The unscaled value of this BigDecimal, as returned by {@link
14.225 + * #unscaledValue}.
14.226 + *
14.227 + * @serial
14.228 + * @see #unscaledValue
14.229 + */
14.230 + private volatile BigInteger intVal;
14.231 +
14.232 + /**
14.233 + * The scale of this BigDecimal, as returned by {@link #scale}.
14.234 + *
14.235 + * @serial
14.236 + * @see #scale
14.237 + */
14.238 + private int scale; // Note: this may have any value, so
14.239 + // calculations must be done in longs
14.240 + /**
14.241 + * The number of decimal digits in this BigDecimal, or 0 if the
14.242 + * number of digits are not known (lookaside information). If
14.243 + * nonzero, the value is guaranteed correct. Use the precision()
14.244 + * method to obtain and set the value if it might be 0. This
14.245 + * field is mutable until set nonzero.
14.246 + *
14.247 + * @since 1.5
14.248 + */
14.249 + private transient int precision;
14.250 +
14.251 + /**
14.252 + * Used to store the canonical string representation, if computed.
14.253 + */
14.254 + private transient String stringCache;
14.255 +
14.256 + /**
14.257 + * Sentinel value for {@link #intCompact} indicating the
14.258 + * significand information is only available from {@code intVal}.
14.259 + */
14.260 + static final long INFLATED = Long.MIN_VALUE;
14.261 +
14.262 + /**
14.263 + * If the absolute value of the significand of this BigDecimal is
14.264 + * less than or equal to {@code Long.MAX_VALUE}, the value can be
14.265 + * compactly stored in this field and used in computations.
14.266 + */
14.267 + private transient long intCompact;
14.268 +
14.269 + // All 18-digit base ten strings fit into a long; not all 19-digit
14.270 + // strings will
14.271 + private static final int MAX_COMPACT_DIGITS = 18;
14.272 +
14.273 + private static final int MAX_BIGINT_BITS = 62;
14.274 +
14.275 + /* Appease the serialization gods */
14.276 + private static final long serialVersionUID = 6108874887143696463L;
14.277 +
14.278 + private static final ThreadLocal<StringBuilderHelper>
14.279 + threadLocalStringBuilderHelper = new ThreadLocal<StringBuilderHelper>() {
14.280 + @Override
14.281 + protected StringBuilderHelper initialValue() {
14.282 + return new StringBuilderHelper();
14.283 + }
14.284 + };
14.285 +
14.286 + // Cache of common small BigDecimal values.
14.287 + private static final BigDecimal zeroThroughTen[] = {
14.288 + new BigDecimal(BigInteger.ZERO, 0, 0, 1),
14.289 + new BigDecimal(BigInteger.ONE, 1, 0, 1),
14.290 + new BigDecimal(BigInteger.valueOf(2), 2, 0, 1),
14.291 + new BigDecimal(BigInteger.valueOf(3), 3, 0, 1),
14.292 + new BigDecimal(BigInteger.valueOf(4), 4, 0, 1),
14.293 + new BigDecimal(BigInteger.valueOf(5), 5, 0, 1),
14.294 + new BigDecimal(BigInteger.valueOf(6), 6, 0, 1),
14.295 + new BigDecimal(BigInteger.valueOf(7), 7, 0, 1),
14.296 + new BigDecimal(BigInteger.valueOf(8), 8, 0, 1),
14.297 + new BigDecimal(BigInteger.valueOf(9), 9, 0, 1),
14.298 + new BigDecimal(BigInteger.TEN, 10, 0, 2),
14.299 + };
14.300 +
14.301 + // Cache of zero scaled by 0 - 15
14.302 + private static final BigDecimal[] ZERO_SCALED_BY = {
14.303 + zeroThroughTen[0],
14.304 + new BigDecimal(BigInteger.ZERO, 0, 1, 1),
14.305 + new BigDecimal(BigInteger.ZERO, 0, 2, 1),
14.306 + new BigDecimal(BigInteger.ZERO, 0, 3, 1),
14.307 + new BigDecimal(BigInteger.ZERO, 0, 4, 1),
14.308 + new BigDecimal(BigInteger.ZERO, 0, 5, 1),
14.309 + new BigDecimal(BigInteger.ZERO, 0, 6, 1),
14.310 + new BigDecimal(BigInteger.ZERO, 0, 7, 1),
14.311 + new BigDecimal(BigInteger.ZERO, 0, 8, 1),
14.312 + new BigDecimal(BigInteger.ZERO, 0, 9, 1),
14.313 + new BigDecimal(BigInteger.ZERO, 0, 10, 1),
14.314 + new BigDecimal(BigInteger.ZERO, 0, 11, 1),
14.315 + new BigDecimal(BigInteger.ZERO, 0, 12, 1),
14.316 + new BigDecimal(BigInteger.ZERO, 0, 13, 1),
14.317 + new BigDecimal(BigInteger.ZERO, 0, 14, 1),
14.318 + new BigDecimal(BigInteger.ZERO, 0, 15, 1),
14.319 + };
14.320 +
14.321 + // Half of Long.MIN_VALUE & Long.MAX_VALUE.
14.322 + private static final long HALF_LONG_MAX_VALUE = Long.MAX_VALUE / 2;
14.323 + private static final long HALF_LONG_MIN_VALUE = Long.MIN_VALUE / 2;
14.324 +
14.325 + // Constants
14.326 + /**
14.327 + * The value 0, with a scale of 0.
14.328 + *
14.329 + * @since 1.5
14.330 + */
14.331 + public static final BigDecimal ZERO =
14.332 + zeroThroughTen[0];
14.333 +
14.334 + /**
14.335 + * The value 1, with a scale of 0.
14.336 + *
14.337 + * @since 1.5
14.338 + */
14.339 + public static final BigDecimal ONE =
14.340 + zeroThroughTen[1];
14.341 +
14.342 + /**
14.343 + * The value 10, with a scale of 0.
14.344 + *
14.345 + * @since 1.5
14.346 + */
14.347 + public static final BigDecimal TEN =
14.348 + zeroThroughTen[10];
14.349 +
14.350 + // Constructors
14.351 +
14.352 + /**
14.353 + * Trusted package private constructor.
14.354 + * Trusted simply means if val is INFLATED, intVal could not be null and
14.355 + * if intVal is null, val could not be INFLATED.
14.356 + */
14.357 + BigDecimal(BigInteger intVal, long val, int scale, int prec) {
14.358 + this.scale = scale;
14.359 + this.precision = prec;
14.360 + this.intCompact = val;
14.361 + this.intVal = intVal;
14.362 + }
14.363 +
14.364 + /**
14.365 + * Translates a character array representation of a
14.366 + * {@code BigDecimal} into a {@code BigDecimal}, accepting the
14.367 + * same sequence of characters as the {@link #BigDecimal(String)}
14.368 + * constructor, while allowing a sub-array to be specified.
14.369 + *
14.370 + * <p>Note that if the sequence of characters is already available
14.371 + * within a character array, using this constructor is faster than
14.372 + * converting the {@code char} array to string and using the
14.373 + * {@code BigDecimal(String)} constructor .
14.374 + *
14.375 + * @param in {@code char} array that is the source of characters.
14.376 + * @param offset first character in the array to inspect.
14.377 + * @param len number of characters to consider.
14.378 + * @throws NumberFormatException if {@code in} is not a valid
14.379 + * representation of a {@code BigDecimal} or the defined subarray
14.380 + * is not wholly within {@code in}.
14.381 + * @since 1.5
14.382 + */
14.383 + public BigDecimal(char[] in, int offset, int len) {
14.384 + // protect against huge length.
14.385 + if (offset+len > in.length || offset < 0)
14.386 + throw new NumberFormatException();
14.387 + // This is the primary string to BigDecimal constructor; all
14.388 + // incoming strings end up here; it uses explicit (inline)
14.389 + // parsing for speed and generates at most one intermediate
14.390 + // (temporary) object (a char[] array) for non-compact case.
14.391 +
14.392 + // Use locals for all fields values until completion
14.393 + int prec = 0; // record precision value
14.394 + int scl = 0; // record scale value
14.395 + long rs = 0; // the compact value in long
14.396 + BigInteger rb = null; // the inflated value in BigInteger
14.397 +
14.398 + // use array bounds checking to handle too-long, len == 0,
14.399 + // bad offset, etc.
14.400 + try {
14.401 + // handle the sign
14.402 + boolean isneg = false; // assume positive
14.403 + if (in[offset] == '-') {
14.404 + isneg = true; // leading minus means negative
14.405 + offset++;
14.406 + len--;
14.407 + } else if (in[offset] == '+') { // leading + allowed
14.408 + offset++;
14.409 + len--;
14.410 + }
14.411 +
14.412 + // should now be at numeric part of the significand
14.413 + boolean dot = false; // true when there is a '.'
14.414 + int cfirst = offset; // record start of integer
14.415 + long exp = 0; // exponent
14.416 + char c; // current character
14.417 +
14.418 + boolean isCompact = (len <= MAX_COMPACT_DIGITS);
14.419 + // integer significand array & idx is the index to it. The array
14.420 + // is ONLY used when we can't use a compact representation.
14.421 + char coeff[] = isCompact ? null : new char[len];
14.422 + int idx = 0;
14.423 +
14.424 + for (; len > 0; offset++, len--) {
14.425 + c = in[offset];
14.426 + // have digit
14.427 + if ((c >= '0' && c <= '9') || Character.isDigit(c)) {
14.428 + // First compact case, we need not to preserve the character
14.429 + // and we can just compute the value in place.
14.430 + if (isCompact) {
14.431 + int digit = Character.digit(c, 10);
14.432 + if (digit == 0) {
14.433 + if (prec == 0)
14.434 + prec = 1;
14.435 + else if (rs != 0) {
14.436 + rs *= 10;
14.437 + ++prec;
14.438 + } // else digit is a redundant leading zero
14.439 + } else {
14.440 + if (prec != 1 || rs != 0)
14.441 + ++prec; // prec unchanged if preceded by 0s
14.442 + rs = rs * 10 + digit;
14.443 + }
14.444 + } else { // the unscaled value is likely a BigInteger object.
14.445 + if (c == '0' || Character.digit(c, 10) == 0) {
14.446 + if (prec == 0) {
14.447 + coeff[idx] = c;
14.448 + prec = 1;
14.449 + } else if (idx != 0) {
14.450 + coeff[idx++] = c;
14.451 + ++prec;
14.452 + } // else c must be a redundant leading zero
14.453 + } else {
14.454 + if (prec != 1 || idx != 0)
14.455 + ++prec; // prec unchanged if preceded by 0s
14.456 + coeff[idx++] = c;
14.457 + }
14.458 + }
14.459 + if (dot)
14.460 + ++scl;
14.461 + continue;
14.462 + }
14.463 + // have dot
14.464 + if (c == '.') {
14.465 + // have dot
14.466 + if (dot) // two dots
14.467 + throw new NumberFormatException();
14.468 + dot = true;
14.469 + continue;
14.470 + }
14.471 + // exponent expected
14.472 + if ((c != 'e') && (c != 'E'))
14.473 + throw new NumberFormatException();
14.474 + offset++;
14.475 + c = in[offset];
14.476 + len--;
14.477 + boolean negexp = (c == '-');
14.478 + // optional sign
14.479 + if (negexp || c == '+') {
14.480 + offset++;
14.481 + c = in[offset];
14.482 + len--;
14.483 + }
14.484 + if (len <= 0) // no exponent digits
14.485 + throw new NumberFormatException();
14.486 + // skip leading zeros in the exponent
14.487 + while (len > 10 && Character.digit(c, 10) == 0) {
14.488 + offset++;
14.489 + c = in[offset];
14.490 + len--;
14.491 + }
14.492 + if (len > 10) // too many nonzero exponent digits
14.493 + throw new NumberFormatException();
14.494 + // c now holds first digit of exponent
14.495 + for (;; len--) {
14.496 + int v;
14.497 + if (c >= '0' && c <= '9') {
14.498 + v = c - '0';
14.499 + } else {
14.500 + v = Character.digit(c, 10);
14.501 + if (v < 0) // not a digit
14.502 + throw new NumberFormatException();
14.503 + }
14.504 + exp = exp * 10 + v;
14.505 + if (len == 1)
14.506 + break; // that was final character
14.507 + offset++;
14.508 + c = in[offset];
14.509 + }
14.510 + if (negexp) // apply sign
14.511 + exp = -exp;
14.512 + // Next test is required for backwards compatibility
14.513 + if ((int)exp != exp) // overflow
14.514 + throw new NumberFormatException();
14.515 + break; // [saves a test]
14.516 + }
14.517 + // here when no characters left
14.518 + if (prec == 0) // no digits found
14.519 + throw new NumberFormatException();
14.520 +
14.521 + // Adjust scale if exp is not zero.
14.522 + if (exp != 0) { // had significant exponent
14.523 + // Can't call checkScale which relies on proper fields value
14.524 + long adjustedScale = scl - exp;
14.525 + if (adjustedScale > Integer.MAX_VALUE ||
14.526 + adjustedScale < Integer.MIN_VALUE)
14.527 + throw new NumberFormatException("Scale out of range.");
14.528 + scl = (int)adjustedScale;
14.529 + }
14.530 +
14.531 + // Remove leading zeros from precision (digits count)
14.532 + if (isCompact) {
14.533 + rs = isneg ? -rs : rs;
14.534 + } else {
14.535 + char quick[];
14.536 + if (!isneg) {
14.537 + quick = (coeff.length != prec) ?
14.538 + Arrays.copyOf(coeff, prec) : coeff;
14.539 + } else {
14.540 + quick = new char[prec + 1];
14.541 + quick[0] = '-';
14.542 + System.arraycopy(coeff, 0, quick, 1, prec);
14.543 + }
14.544 + rb = new BigInteger(quick);
14.545 + rs = compactValFor(rb);
14.546 + }
14.547 + } catch (ArrayIndexOutOfBoundsException e) {
14.548 + throw new NumberFormatException();
14.549 + } catch (NegativeArraySizeException e) {
14.550 + throw new NumberFormatException();
14.551 + }
14.552 + this.scale = scl;
14.553 + this.precision = prec;
14.554 + this.intCompact = rs;
14.555 + this.intVal = (rs != INFLATED) ? null : rb;
14.556 + }
14.557 +
14.558 + /**
14.559 + * Translates a character array representation of a
14.560 + * {@code BigDecimal} into a {@code BigDecimal}, accepting the
14.561 + * same sequence of characters as the {@link #BigDecimal(String)}
14.562 + * constructor, while allowing a sub-array to be specified and
14.563 + * with rounding according to the context settings.
14.564 + *
14.565 + * <p>Note that if the sequence of characters is already available
14.566 + * within a character array, using this constructor is faster than
14.567 + * converting the {@code char} array to string and using the
14.568 + * {@code BigDecimal(String)} constructor .
14.569 + *
14.570 + * @param in {@code char} array that is the source of characters.
14.571 + * @param offset first character in the array to inspect.
14.572 + * @param len number of characters to consider..
14.573 + * @param mc the context to use.
14.574 + * @throws ArithmeticException if the result is inexact but the
14.575 + * rounding mode is {@code UNNECESSARY}.
14.576 + * @throws NumberFormatException if {@code in} is not a valid
14.577 + * representation of a {@code BigDecimal} or the defined subarray
14.578 + * is not wholly within {@code in}.
14.579 + * @since 1.5
14.580 + */
14.581 + public BigDecimal(char[] in, int offset, int len, MathContext mc) {
14.582 + this(in, offset, len);
14.583 + if (mc.precision > 0)
14.584 + roundThis(mc);
14.585 + }
14.586 +
14.587 + /**
14.588 + * Translates a character array representation of a
14.589 + * {@code BigDecimal} into a {@code BigDecimal}, accepting the
14.590 + * same sequence of characters as the {@link #BigDecimal(String)}
14.591 + * constructor.
14.592 + *
14.593 + * <p>Note that if the sequence of characters is already available
14.594 + * as a character array, using this constructor is faster than
14.595 + * converting the {@code char} array to string and using the
14.596 + * {@code BigDecimal(String)} constructor .
14.597 + *
14.598 + * @param in {@code char} array that is the source of characters.
14.599 + * @throws NumberFormatException if {@code in} is not a valid
14.600 + * representation of a {@code BigDecimal}.
14.601 + * @since 1.5
14.602 + */
14.603 + public BigDecimal(char[] in) {
14.604 + this(in, 0, in.length);
14.605 + }
14.606 +
14.607 + /**
14.608 + * Translates a character array representation of a
14.609 + * {@code BigDecimal} into a {@code BigDecimal}, accepting the
14.610 + * same sequence of characters as the {@link #BigDecimal(String)}
14.611 + * constructor and with rounding according to the context
14.612 + * settings.
14.613 + *
14.614 + * <p>Note that if the sequence of characters is already available
14.615 + * as a character array, using this constructor is faster than
14.616 + * converting the {@code char} array to string and using the
14.617 + * {@code BigDecimal(String)} constructor .
14.618 + *
14.619 + * @param in {@code char} array that is the source of characters.
14.620 + * @param mc the context to use.
14.621 + * @throws ArithmeticException if the result is inexact but the
14.622 + * rounding mode is {@code UNNECESSARY}.
14.623 + * @throws NumberFormatException if {@code in} is not a valid
14.624 + * representation of a {@code BigDecimal}.
14.625 + * @since 1.5
14.626 + */
14.627 + public BigDecimal(char[] in, MathContext mc) {
14.628 + this(in, 0, in.length, mc);
14.629 + }
14.630 +
14.631 + /**
14.632 + * Translates the string representation of a {@code BigDecimal}
14.633 + * into a {@code BigDecimal}. The string representation consists
14.634 + * of an optional sign, {@code '+'} (<tt> '\u002B'</tt>) or
14.635 + * {@code '-'} (<tt>'\u002D'</tt>), followed by a sequence of
14.636 + * zero or more decimal digits ("the integer"), optionally
14.637 + * followed by a fraction, optionally followed by an exponent.
14.638 + *
14.639 + * <p>The fraction consists of a decimal point followed by zero
14.640 + * or more decimal digits. The string must contain at least one
14.641 + * digit in either the integer or the fraction. The number formed
14.642 + * by the sign, the integer and the fraction is referred to as the
14.643 + * <i>significand</i>.
14.644 + *
14.645 + * <p>The exponent consists of the character {@code 'e'}
14.646 + * (<tt>'\u0065'</tt>) or {@code 'E'} (<tt>'\u0045'</tt>)
14.647 + * followed by one or more decimal digits. The value of the
14.648 + * exponent must lie between -{@link Integer#MAX_VALUE} ({@link
14.649 + * Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive.
14.650 + *
14.651 + * <p>More formally, the strings this constructor accepts are
14.652 + * described by the following grammar:
14.653 + * <blockquote>
14.654 + * <dl>
14.655 + * <dt><i>BigDecimalString:</i>
14.656 + * <dd><i>Sign<sub>opt</sub> Significand Exponent<sub>opt</sub></i>
14.657 + * <p>
14.658 + * <dt><i>Sign:</i>
14.659 + * <dd>{@code +}
14.660 + * <dd>{@code -}
14.661 + * <p>
14.662 + * <dt><i>Significand:</i>
14.663 + * <dd><i>IntegerPart</i> {@code .} <i>FractionPart<sub>opt</sub></i>
14.664 + * <dd>{@code .} <i>FractionPart</i>
14.665 + * <dd><i>IntegerPart</i>
14.666 + * <p>
14.667 + * <dt><i>IntegerPart:</i>
14.668 + * <dd><i>Digits</i>
14.669 + * <p>
14.670 + * <dt><i>FractionPart:</i>
14.671 + * <dd><i>Digits</i>
14.672 + * <p>
14.673 + * <dt><i>Exponent:</i>
14.674 + * <dd><i>ExponentIndicator SignedInteger</i>
14.675 + * <p>
14.676 + * <dt><i>ExponentIndicator:</i>
14.677 + * <dd>{@code e}
14.678 + * <dd>{@code E}
14.679 + * <p>
14.680 + * <dt><i>SignedInteger:</i>
14.681 + * <dd><i>Sign<sub>opt</sub> Digits</i>
14.682 + * <p>
14.683 + * <dt><i>Digits:</i>
14.684 + * <dd><i>Digit</i>
14.685 + * <dd><i>Digits Digit</i>
14.686 + * <p>
14.687 + * <dt><i>Digit:</i>
14.688 + * <dd>any character for which {@link Character#isDigit}
14.689 + * returns {@code true}, including 0, 1, 2 ...
14.690 + * </dl>
14.691 + * </blockquote>
14.692 + *
14.693 + * <p>The scale of the returned {@code BigDecimal} will be the
14.694 + * number of digits in the fraction, or zero if the string
14.695 + * contains no decimal point, subject to adjustment for any
14.696 + * exponent; if the string contains an exponent, the exponent is
14.697 + * subtracted from the scale. The value of the resulting scale
14.698 + * must lie between {@code Integer.MIN_VALUE} and
14.699 + * {@code Integer.MAX_VALUE}, inclusive.
14.700 + *
14.701 + * <p>The character-to-digit mapping is provided by {@link
14.702 + * java.lang.Character#digit} set to convert to radix 10. The
14.703 + * String may not contain any extraneous characters (whitespace,
14.704 + * for example).
14.705 + *
14.706 + * <p><b>Examples:</b><br>
14.707 + * The value of the returned {@code BigDecimal} is equal to
14.708 + * <i>significand</i> × 10<sup> <i>exponent</i></sup>.
14.709 + * For each string on the left, the resulting representation
14.710 + * [{@code BigInteger}, {@code scale}] is shown on the right.
14.711 + * <pre>
14.712 + * "0" [0,0]
14.713 + * "0.00" [0,2]
14.714 + * "123" [123,0]
14.715 + * "-123" [-123,0]
14.716 + * "1.23E3" [123,-1]
14.717 + * "1.23E+3" [123,-1]
14.718 + * "12.3E+7" [123,-6]
14.719 + * "12.0" [120,1]
14.720 + * "12.3" [123,1]
14.721 + * "0.00123" [123,5]
14.722 + * "-1.23E-12" [-123,14]
14.723 + * "1234.5E-4" [12345,5]
14.724 + * "0E+7" [0,-7]
14.725 + * "-0" [0,0]
14.726 + * </pre>
14.727 + *
14.728 + * <p>Note: For values other than {@code float} and
14.729 + * {@code double} NaN and ±Infinity, this constructor is
14.730 + * compatible with the values returned by {@link Float#toString}
14.731 + * and {@link Double#toString}. This is generally the preferred
14.732 + * way to convert a {@code float} or {@code double} into a
14.733 + * BigDecimal, as it doesn't suffer from the unpredictability of
14.734 + * the {@link #BigDecimal(double)} constructor.
14.735 + *
14.736 + * @param val String representation of {@code BigDecimal}.
14.737 + *
14.738 + * @throws NumberFormatException if {@code val} is not a valid
14.739 + * representation of a {@code BigDecimal}.
14.740 + */
14.741 + public BigDecimal(String val) {
14.742 + this(val.toCharArray(), 0, val.length());
14.743 + }
14.744 +
14.745 + /**
14.746 + * Translates the string representation of a {@code BigDecimal}
14.747 + * into a {@code BigDecimal}, accepting the same strings as the
14.748 + * {@link #BigDecimal(String)} constructor, with rounding
14.749 + * according to the context settings.
14.750 + *
14.751 + * @param val string representation of a {@code BigDecimal}.
14.752 + * @param mc the context to use.
14.753 + * @throws ArithmeticException if the result is inexact but the
14.754 + * rounding mode is {@code UNNECESSARY}.
14.755 + * @throws NumberFormatException if {@code val} is not a valid
14.756 + * representation of a BigDecimal.
14.757 + * @since 1.5
14.758 + */
14.759 + public BigDecimal(String val, MathContext mc) {
14.760 + this(val.toCharArray(), 0, val.length());
14.761 + if (mc.precision > 0)
14.762 + roundThis(mc);
14.763 + }
14.764 +
14.765 + /**
14.766 + * Translates a {@code double} into a {@code BigDecimal} which
14.767 + * is the exact decimal representation of the {@code double}'s
14.768 + * binary floating-point value. The scale of the returned
14.769 + * {@code BigDecimal} is the smallest value such that
14.770 + * <tt>(10<sup>scale</sup> × val)</tt> is an integer.
14.771 + * <p>
14.772 + * <b>Notes:</b>
14.773 + * <ol>
14.774 + * <li>
14.775 + * The results of this constructor can be somewhat unpredictable.
14.776 + * One might assume that writing {@code new BigDecimal(0.1)} in
14.777 + * Java creates a {@code BigDecimal} which is exactly equal to
14.778 + * 0.1 (an unscaled value of 1, with a scale of 1), but it is
14.779 + * actually equal to
14.780 + * 0.1000000000000000055511151231257827021181583404541015625.
14.781 + * This is because 0.1 cannot be represented exactly as a
14.782 + * {@code double} (or, for that matter, as a binary fraction of
14.783 + * any finite length). Thus, the value that is being passed
14.784 + * <i>in</i> to the constructor is not exactly equal to 0.1,
14.785 + * appearances notwithstanding.
14.786 + *
14.787 + * <li>
14.788 + * The {@code String} constructor, on the other hand, is
14.789 + * perfectly predictable: writing {@code new BigDecimal("0.1")}
14.790 + * creates a {@code BigDecimal} which is <i>exactly</i> equal to
14.791 + * 0.1, as one would expect. Therefore, it is generally
14.792 + * recommended that the {@linkplain #BigDecimal(String)
14.793 + * <tt>String</tt> constructor} be used in preference to this one.
14.794 + *
14.795 + * <li>
14.796 + * When a {@code double} must be used as a source for a
14.797 + * {@code BigDecimal}, note that this constructor provides an
14.798 + * exact conversion; it does not give the same result as
14.799 + * converting the {@code double} to a {@code String} using the
14.800 + * {@link Double#toString(double)} method and then using the
14.801 + * {@link #BigDecimal(String)} constructor. To get that result,
14.802 + * use the {@code static} {@link #valueOf(double)} method.
14.803 + * </ol>
14.804 + *
14.805 + * @param val {@code double} value to be converted to
14.806 + * {@code BigDecimal}.
14.807 + * @throws NumberFormatException if {@code val} is infinite or NaN.
14.808 + */
14.809 + public BigDecimal(double val) {
14.810 + if (Double.isInfinite(val) || Double.isNaN(val))
14.811 + throw new NumberFormatException("Infinite or NaN");
14.812 +
14.813 + // Translate the double into sign, exponent and significand, according
14.814 + // to the formulae in JLS, Section 20.10.22.
14.815 + long valBits = Double.doubleToLongBits(val);
14.816 + int sign = ((valBits >> 63)==0 ? 1 : -1);
14.817 + int exponent = (int) ((valBits >> 52) & 0x7ffL);
14.818 + long significand = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1
14.819 + : (valBits & ((1L<<52) - 1)) | (1L<<52));
14.820 + exponent -= 1075;
14.821 + // At this point, val == sign * significand * 2**exponent.
14.822 +
14.823 + /*
14.824 + * Special case zero to supress nonterminating normalization
14.825 + * and bogus scale calculation.
14.826 + */
14.827 + if (significand == 0) {
14.828 + intVal = BigInteger.ZERO;
14.829 + intCompact = 0;
14.830 + precision = 1;
14.831 + return;
14.832 + }
14.833 +
14.834 + // Normalize
14.835 + while((significand & 1) == 0) { // i.e., significand is even
14.836 + significand >>= 1;
14.837 + exponent++;
14.838 + }
14.839 +
14.840 + // Calculate intVal and scale
14.841 + long s = sign * significand;
14.842 + BigInteger b;
14.843 + if (exponent < 0) {
14.844 + b = BigInteger.valueOf(5).pow(-exponent).multiply(s);
14.845 + scale = -exponent;
14.846 + } else if (exponent > 0) {
14.847 + b = BigInteger.valueOf(2).pow(exponent).multiply(s);
14.848 + } else {
14.849 + b = BigInteger.valueOf(s);
14.850 + }
14.851 + intCompact = compactValFor(b);
14.852 + intVal = (intCompact != INFLATED) ? null : b;
14.853 + }
14.854 +
14.855 + /**
14.856 + * Translates a {@code double} into a {@code BigDecimal}, with
14.857 + * rounding according to the context settings. The scale of the
14.858 + * {@code BigDecimal} is the smallest value such that
14.859 + * <tt>(10<sup>scale</sup> × val)</tt> is an integer.
14.860 + *
14.861 + * <p>The results of this constructor can be somewhat unpredictable
14.862 + * and its use is generally not recommended; see the notes under
14.863 + * the {@link #BigDecimal(double)} constructor.
14.864 + *
14.865 + * @param val {@code double} value to be converted to
14.866 + * {@code BigDecimal}.
14.867 + * @param mc the context to use.
14.868 + * @throws ArithmeticException if the result is inexact but the
14.869 + * RoundingMode is UNNECESSARY.
14.870 + * @throws NumberFormatException if {@code val} is infinite or NaN.
14.871 + * @since 1.5
14.872 + */
14.873 + public BigDecimal(double val, MathContext mc) {
14.874 + this(val);
14.875 + if (mc.precision > 0)
14.876 + roundThis(mc);
14.877 + }
14.878 +
14.879 + /**
14.880 + * Translates a {@code BigInteger} into a {@code BigDecimal}.
14.881 + * The scale of the {@code BigDecimal} is zero.
14.882 + *
14.883 + * @param val {@code BigInteger} value to be converted to
14.884 + * {@code BigDecimal}.
14.885 + */
14.886 + public BigDecimal(BigInteger val) {
14.887 + intCompact = compactValFor(val);
14.888 + intVal = (intCompact != INFLATED) ? null : val;
14.889 + }
14.890 +
14.891 + /**
14.892 + * Translates a {@code BigInteger} into a {@code BigDecimal}
14.893 + * rounding according to the context settings. The scale of the
14.894 + * {@code BigDecimal} is zero.
14.895 + *
14.896 + * @param val {@code BigInteger} value to be converted to
14.897 + * {@code BigDecimal}.
14.898 + * @param mc the context to use.
14.899 + * @throws ArithmeticException if the result is inexact but the
14.900 + * rounding mode is {@code UNNECESSARY}.
14.901 + * @since 1.5
14.902 + */
14.903 + public BigDecimal(BigInteger val, MathContext mc) {
14.904 + this(val);
14.905 + if (mc.precision > 0)
14.906 + roundThis(mc);
14.907 + }
14.908 +
14.909 + /**
14.910 + * Translates a {@code BigInteger} unscaled value and an
14.911 + * {@code int} scale into a {@code BigDecimal}. The value of
14.912 + * the {@code BigDecimal} is
14.913 + * <tt>(unscaledVal × 10<sup>-scale</sup>)</tt>.
14.914 + *
14.915 + * @param unscaledVal unscaled value of the {@code BigDecimal}.
14.916 + * @param scale scale of the {@code BigDecimal}.
14.917 + */
14.918 + public BigDecimal(BigInteger unscaledVal, int scale) {
14.919 + // Negative scales are now allowed
14.920 + this(unscaledVal);
14.921 + this.scale = scale;
14.922 + }
14.923 +
14.924 + /**
14.925 + * Translates a {@code BigInteger} unscaled value and an
14.926 + * {@code int} scale into a {@code BigDecimal}, with rounding
14.927 + * according to the context settings. The value of the
14.928 + * {@code BigDecimal} is <tt>(unscaledVal ×
14.929 + * 10<sup>-scale</sup>)</tt>, rounded according to the
14.930 + * {@code precision} and rounding mode settings.
14.931 + *
14.932 + * @param unscaledVal unscaled value of the {@code BigDecimal}.
14.933 + * @param scale scale of the {@code BigDecimal}.
14.934 + * @param mc the context to use.
14.935 + * @throws ArithmeticException if the result is inexact but the
14.936 + * rounding mode is {@code UNNECESSARY}.
14.937 + * @since 1.5
14.938 + */
14.939 + public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
14.940 + this(unscaledVal);
14.941 + this.scale = scale;
14.942 + if (mc.precision > 0)
14.943 + roundThis(mc);
14.944 + }
14.945 +
14.946 + /**
14.947 + * Translates an {@code int} into a {@code BigDecimal}. The
14.948 + * scale of the {@code BigDecimal} is zero.
14.949 + *
14.950 + * @param val {@code int} value to be converted to
14.951 + * {@code BigDecimal}.
14.952 + * @since 1.5
14.953 + */
14.954 + public BigDecimal(int val) {
14.955 + intCompact = val;
14.956 + }
14.957 +
14.958 + /**
14.959 + * Translates an {@code int} into a {@code BigDecimal}, with
14.960 + * rounding according to the context settings. The scale of the
14.961 + * {@code BigDecimal}, before any rounding, is zero.
14.962 + *
14.963 + * @param val {@code int} value to be converted to {@code BigDecimal}.
14.964 + * @param mc the context to use.
14.965 + * @throws ArithmeticException if the result is inexact but the
14.966 + * rounding mode is {@code UNNECESSARY}.
14.967 + * @since 1.5
14.968 + */
14.969 + public BigDecimal(int val, MathContext mc) {
14.970 + intCompact = val;
14.971 + if (mc.precision > 0)
14.972 + roundThis(mc);
14.973 + }
14.974 +
14.975 + /**
14.976 + * Translates a {@code long} into a {@code BigDecimal}. The
14.977 + * scale of the {@code BigDecimal} is zero.
14.978 + *
14.979 + * @param val {@code long} value to be converted to {@code BigDecimal}.
14.980 + * @since 1.5
14.981 + */
14.982 + public BigDecimal(long val) {
14.983 + this.intCompact = val;
14.984 + this.intVal = (val == INFLATED) ? BigInteger.valueOf(val) : null;
14.985 + }
14.986 +
14.987 + /**
14.988 + * Translates a {@code long} into a {@code BigDecimal}, with
14.989 + * rounding according to the context settings. The scale of the
14.990 + * {@code BigDecimal}, before any rounding, is zero.
14.991 + *
14.992 + * @param val {@code long} value to be converted to {@code BigDecimal}.
14.993 + * @param mc the context to use.
14.994 + * @throws ArithmeticException if the result is inexact but the
14.995 + * rounding mode is {@code UNNECESSARY}.
14.996 + * @since 1.5
14.997 + */
14.998 + public BigDecimal(long val, MathContext mc) {
14.999 + this(val);
14.1000 + if (mc.precision > 0)
14.1001 + roundThis(mc);
14.1002 + }
14.1003 +
14.1004 + // Static Factory Methods
14.1005 +
14.1006 + /**
14.1007 + * Translates a {@code long} unscaled value and an
14.1008 + * {@code int} scale into a {@code BigDecimal}. This
14.1009 + * {@literal "static factory method"} is provided in preference to
14.1010 + * a ({@code long}, {@code int}) constructor because it
14.1011 + * allows for reuse of frequently used {@code BigDecimal} values..
14.1012 + *
14.1013 + * @param unscaledVal unscaled value of the {@code BigDecimal}.
14.1014 + * @param scale scale of the {@code BigDecimal}.
14.1015 + * @return a {@code BigDecimal} whose value is
14.1016 + * <tt>(unscaledVal × 10<sup>-scale</sup>)</tt>.
14.1017 + */
14.1018 + public static BigDecimal valueOf(long unscaledVal, int scale) {
14.1019 + if (scale == 0)
14.1020 + return valueOf(unscaledVal);
14.1021 + else if (unscaledVal == 0) {
14.1022 + if (scale > 0 && scale < ZERO_SCALED_BY.length)
14.1023 + return ZERO_SCALED_BY[scale];
14.1024 + else
14.1025 + return new BigDecimal(BigInteger.ZERO, 0, scale, 1);
14.1026 + }
14.1027 + return new BigDecimal(unscaledVal == INFLATED ?
14.1028 + BigInteger.valueOf(unscaledVal) : null,
14.1029 + unscaledVal, scale, 0);
14.1030 + }
14.1031 +
14.1032 + /**
14.1033 + * Translates a {@code long} value into a {@code BigDecimal}
14.1034 + * with a scale of zero. This {@literal "static factory method"}
14.1035 + * is provided in preference to a ({@code long}) constructor
14.1036 + * because it allows for reuse of frequently used
14.1037 + * {@code BigDecimal} values.
14.1038 + *
14.1039 + * @param val value of the {@code BigDecimal}.
14.1040 + * @return a {@code BigDecimal} whose value is {@code val}.
14.1041 + */
14.1042 + public static BigDecimal valueOf(long val) {
14.1043 + if (val >= 0 && val < zeroThroughTen.length)
14.1044 + return zeroThroughTen[(int)val];
14.1045 + else if (val != INFLATED)
14.1046 + return new BigDecimal(null, val, 0, 0);
14.1047 + return new BigDecimal(BigInteger.valueOf(val), val, 0, 0);
14.1048 + }
14.1049 +
14.1050 + /**
14.1051 + * Translates a {@code double} into a {@code BigDecimal}, using
14.1052 + * the {@code double}'s canonical string representation provided
14.1053 + * by the {@link Double#toString(double)} method.
14.1054 + *
14.1055 + * <p><b>Note:</b> This is generally the preferred way to convert
14.1056 + * a {@code double} (or {@code float}) into a
14.1057 + * {@code BigDecimal}, as the value returned is equal to that
14.1058 + * resulting from constructing a {@code BigDecimal} from the
14.1059 + * result of using {@link Double#toString(double)}.
14.1060 + *
14.1061 + * @param val {@code double} to convert to a {@code BigDecimal}.
14.1062 + * @return a {@code BigDecimal} whose value is equal to or approximately
14.1063 + * equal to the value of {@code val}.
14.1064 + * @throws NumberFormatException if {@code val} is infinite or NaN.
14.1065 + * @since 1.5
14.1066 + */
14.1067 + public static BigDecimal valueOf(double val) {
14.1068 + // Reminder: a zero double returns '0.0', so we cannot fastpath
14.1069 + // to use the constant ZERO. This might be important enough to
14.1070 + // justify a factory approach, a cache, or a few private
14.1071 + // constants, later.
14.1072 + return new BigDecimal(Double.toString(val));
14.1073 + }
14.1074 +
14.1075 + // Arithmetic Operations
14.1076 + /**
14.1077 + * Returns a {@code BigDecimal} whose value is {@code (this +
14.1078 + * augend)}, and whose scale is {@code max(this.scale(),
14.1079 + * augend.scale())}.
14.1080 + *
14.1081 + * @param augend value to be added to this {@code BigDecimal}.
14.1082 + * @return {@code this + augend}
14.1083 + */
14.1084 + public BigDecimal add(BigDecimal augend) {
14.1085 + long xs = this.intCompact;
14.1086 + long ys = augend.intCompact;
14.1087 + BigInteger fst = (xs != INFLATED) ? null : this.intVal;
14.1088 + BigInteger snd = (ys != INFLATED) ? null : augend.intVal;
14.1089 + int rscale = this.scale;
14.1090 +
14.1091 + long sdiff = (long)rscale - augend.scale;
14.1092 + if (sdiff != 0) {
14.1093 + if (sdiff < 0) {
14.1094 + int raise = checkScale(-sdiff);
14.1095 + rscale = augend.scale;
14.1096 + if (xs == INFLATED ||
14.1097 + (xs = longMultiplyPowerTen(xs, raise)) == INFLATED)
14.1098 + fst = bigMultiplyPowerTen(raise);
14.1099 + } else {
14.1100 + int raise = augend.checkScale(sdiff);
14.1101 + if (ys == INFLATED ||
14.1102 + (ys = longMultiplyPowerTen(ys, raise)) == INFLATED)
14.1103 + snd = augend.bigMultiplyPowerTen(raise);
14.1104 + }
14.1105 + }
14.1106 + if (xs != INFLATED && ys != INFLATED) {
14.1107 + long sum = xs + ys;
14.1108 + // See "Hacker's Delight" section 2-12 for explanation of
14.1109 + // the overflow test.
14.1110 + if ( (((sum ^ xs) & (sum ^ ys))) >= 0L) // not overflowed
14.1111 + return BigDecimal.valueOf(sum, rscale);
14.1112 + }
14.1113 + if (fst == null)
14.1114 + fst = BigInteger.valueOf(xs);
14.1115 + if (snd == null)
14.1116 + snd = BigInteger.valueOf(ys);
14.1117 + BigInteger sum = fst.add(snd);
14.1118 + return (fst.signum == snd.signum) ?
14.1119 + new BigDecimal(sum, INFLATED, rscale, 0) :
14.1120 + new BigDecimal(sum, rscale);
14.1121 + }
14.1122 +
14.1123 + /**
14.1124 + * Returns a {@code BigDecimal} whose value is {@code (this + augend)},
14.1125 + * with rounding according to the context settings.
14.1126 + *
14.1127 + * If either number is zero and the precision setting is nonzero then
14.1128 + * the other number, rounded if necessary, is used as the result.
14.1129 + *
14.1130 + * @param augend value to be added to this {@code BigDecimal}.
14.1131 + * @param mc the context to use.
14.1132 + * @return {@code this + augend}, rounded as necessary.
14.1133 + * @throws ArithmeticException if the result is inexact but the
14.1134 + * rounding mode is {@code UNNECESSARY}.
14.1135 + * @since 1.5
14.1136 + */
14.1137 + public BigDecimal add(BigDecimal augend, MathContext mc) {
14.1138 + if (mc.precision == 0)
14.1139 + return add(augend);
14.1140 + BigDecimal lhs = this;
14.1141 +
14.1142 + // Could optimize if values are compact
14.1143 + this.inflate();
14.1144 + augend.inflate();
14.1145 +
14.1146 + // If either number is zero then the other number, rounded and
14.1147 + // scaled if necessary, is used as the result.
14.1148 + {
14.1149 + boolean lhsIsZero = lhs.signum() == 0;
14.1150 + boolean augendIsZero = augend.signum() == 0;
14.1151 +
14.1152 + if (lhsIsZero || augendIsZero) {
14.1153 + int preferredScale = Math.max(lhs.scale(), augend.scale());
14.1154 + BigDecimal result;
14.1155 +
14.1156 + // Could use a factory for zero instead of a new object
14.1157 + if (lhsIsZero && augendIsZero)
14.1158 + return new BigDecimal(BigInteger.ZERO, 0, preferredScale, 0);
14.1159 +
14.1160 + result = lhsIsZero ? doRound(augend, mc) : doRound(lhs, mc);
14.1161 +
14.1162 + if (result.scale() == preferredScale)
14.1163 + return result;
14.1164 + else if (result.scale() > preferredScale) {
14.1165 + BigDecimal scaledResult =
14.1166 + new BigDecimal(result.intVal, result.intCompact,
14.1167 + result.scale, 0);
14.1168 + scaledResult.stripZerosToMatchScale(preferredScale);
14.1169 + return scaledResult;
14.1170 + } else { // result.scale < preferredScale
14.1171 + int precisionDiff = mc.precision - result.precision();
14.1172 + int scaleDiff = preferredScale - result.scale();
14.1173 +
14.1174 + if (precisionDiff >= scaleDiff)
14.1175 + return result.setScale(preferredScale); // can achieve target scale
14.1176 + else
14.1177 + return result.setScale(result.scale() + precisionDiff);
14.1178 + }
14.1179 + }
14.1180 + }
14.1181 +
14.1182 + long padding = (long)lhs.scale - augend.scale;
14.1183 + if (padding != 0) { // scales differ; alignment needed
14.1184 + BigDecimal arg[] = preAlign(lhs, augend, padding, mc);
14.1185 + matchScale(arg);
14.1186 + lhs = arg[0];
14.1187 + augend = arg[1];
14.1188 + }
14.1189 +
14.1190 + BigDecimal d = new BigDecimal(lhs.inflate().add(augend.inflate()),
14.1191 + lhs.scale);
14.1192 + return doRound(d, mc);
14.1193 + }
14.1194 +
14.1195 + /**
14.1196 + * Returns an array of length two, the sum of whose entries is
14.1197 + * equal to the rounded sum of the {@code BigDecimal} arguments.
14.1198 + *
14.1199 + * <p>If the digit positions of the arguments have a sufficient
14.1200 + * gap between them, the value smaller in magnitude can be
14.1201 + * condensed into a {@literal "sticky bit"} and the end result will
14.1202 + * round the same way <em>if</em> the precision of the final
14.1203 + * result does not include the high order digit of the small
14.1204 + * magnitude operand.
14.1205 + *
14.1206 + * <p>Note that while strictly speaking this is an optimization,
14.1207 + * it makes a much wider range of additions practical.
14.1208 + *
14.1209 + * <p>This corresponds to a pre-shift operation in a fixed
14.1210 + * precision floating-point adder; this method is complicated by
14.1211 + * variable precision of the result as determined by the
14.1212 + * MathContext. A more nuanced operation could implement a
14.1213 + * {@literal "right shift"} on the smaller magnitude operand so
14.1214 + * that the number of digits of the smaller operand could be
14.1215 + * reduced even though the significands partially overlapped.
14.1216 + */
14.1217 + private BigDecimal[] preAlign(BigDecimal lhs, BigDecimal augend,
14.1218 + long padding, MathContext mc) {
14.1219 + assert padding != 0;
14.1220 + BigDecimal big;
14.1221 + BigDecimal small;
14.1222 +
14.1223 + if (padding < 0) { // lhs is big; augend is small
14.1224 + big = lhs;
14.1225 + small = augend;
14.1226 + } else { // lhs is small; augend is big
14.1227 + big = augend;
14.1228 + small = lhs;
14.1229 + }
14.1230 +
14.1231 + /*
14.1232 + * This is the estimated scale of an ulp of the result; it
14.1233 + * assumes that the result doesn't have a carry-out on a true
14.1234 + * add (e.g. 999 + 1 => 1000) or any subtractive cancellation
14.1235 + * on borrowing (e.g. 100 - 1.2 => 98.8)
14.1236 + */
14.1237 + long estResultUlpScale = (long)big.scale - big.precision() + mc.precision;
14.1238 +
14.1239 + /*
14.1240 + * The low-order digit position of big is big.scale(). This
14.1241 + * is true regardless of whether big has a positive or
14.1242 + * negative scale. The high-order digit position of small is
14.1243 + * small.scale - (small.precision() - 1). To do the full
14.1244 + * condensation, the digit positions of big and small must be
14.1245 + * disjoint *and* the digit positions of small should not be
14.1246 + * directly visible in the result.
14.1247 + */
14.1248 + long smallHighDigitPos = (long)small.scale - small.precision() + 1;
14.1249 + if (smallHighDigitPos > big.scale + 2 && // big and small disjoint
14.1250 + smallHighDigitPos > estResultUlpScale + 2) { // small digits not visible
14.1251 + small = BigDecimal.valueOf(small.signum(),
14.1252 + this.checkScale(Math.max(big.scale, estResultUlpScale) + 3));
14.1253 + }
14.1254 +
14.1255 + // Since addition is symmetric, preserving input order in
14.1256 + // returned operands doesn't matter
14.1257 + BigDecimal[] result = {big, small};
14.1258 + return result;
14.1259 + }
14.1260 +
14.1261 + /**
14.1262 + * Returns a {@code BigDecimal} whose value is {@code (this -
14.1263 + * subtrahend)}, and whose scale is {@code max(this.scale(),
14.1264 + * subtrahend.scale())}.
14.1265 + *
14.1266 + * @param subtrahend value to be subtracted from this {@code BigDecimal}.
14.1267 + * @return {@code this - subtrahend}
14.1268 + */
14.1269 + public BigDecimal subtract(BigDecimal subtrahend) {
14.1270 + return add(subtrahend.negate());
14.1271 + }
14.1272 +
14.1273 + /**
14.1274 + * Returns a {@code BigDecimal} whose value is {@code (this - subtrahend)},
14.1275 + * with rounding according to the context settings.
14.1276 + *
14.1277 + * If {@code subtrahend} is zero then this, rounded if necessary, is used as the
14.1278 + * result. If this is zero then the result is {@code subtrahend.negate(mc)}.
14.1279 + *
14.1280 + * @param subtrahend value to be subtracted from this {@code BigDecimal}.
14.1281 + * @param mc the context to use.
14.1282 + * @return {@code this - subtrahend}, rounded as necessary.
14.1283 + * @throws ArithmeticException if the result is inexact but the
14.1284 + * rounding mode is {@code UNNECESSARY}.
14.1285 + * @since 1.5
14.1286 + */
14.1287 + public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
14.1288 + BigDecimal nsubtrahend = subtrahend.negate();
14.1289 + if (mc.precision == 0)
14.1290 + return add(nsubtrahend);
14.1291 + // share the special rounding code in add()
14.1292 + return add(nsubtrahend, mc);
14.1293 + }
14.1294 +
14.1295 + /**
14.1296 + * Returns a {@code BigDecimal} whose value is <tt>(this ×
14.1297 + * multiplicand)</tt>, and whose scale is {@code (this.scale() +
14.1298 + * multiplicand.scale())}.
14.1299 + *
14.1300 + * @param multiplicand value to be multiplied by this {@code BigDecimal}.
14.1301 + * @return {@code this * multiplicand}
14.1302 + */
14.1303 + public BigDecimal multiply(BigDecimal multiplicand) {
14.1304 + long x = this.intCompact;
14.1305 + long y = multiplicand.intCompact;
14.1306 + int productScale = checkScale((long)scale + multiplicand.scale);
14.1307 +
14.1308 + // Might be able to do a more clever check incorporating the
14.1309 + // inflated check into the overflow computation.
14.1310 + if (x != INFLATED && y != INFLATED) {
14.1311 + /*
14.1312 + * If the product is not an overflowed value, continue
14.1313 + * to use the compact representation. if either of x or y
14.1314 + * is INFLATED, the product should also be regarded as
14.1315 + * an overflow. Before using the overflow test suggested in
14.1316 + * "Hacker's Delight" section 2-12, we perform quick checks
14.1317 + * using the precision information to see whether the overflow
14.1318 + * would occur since division is expensive on most CPUs.
14.1319 + */
14.1320 + long product = x * y;
14.1321 + long prec = this.precision() + multiplicand.precision();
14.1322 + if (prec < 19 || (prec < 21 && (y == 0 || product / y == x)))
14.1323 + return BigDecimal.valueOf(product, productScale);
14.1324 + return new BigDecimal(BigInteger.valueOf(x).multiply(y), INFLATED,
14.1325 + productScale, 0);
14.1326 + }
14.1327 + BigInteger rb;
14.1328 + if (x == INFLATED && y == INFLATED)
14.1329 + rb = this.intVal.multiply(multiplicand.intVal);
14.1330 + else if (x != INFLATED)
14.1331 + rb = multiplicand.intVal.multiply(x);
14.1332 + else
14.1333 + rb = this.intVal.multiply(y);
14.1334 + return new BigDecimal(rb, INFLATED, productScale, 0);
14.1335 + }
14.1336 +
14.1337 + /**
14.1338 + * Returns a {@code BigDecimal} whose value is <tt>(this ×
14.1339 + * multiplicand)</tt>, with rounding according to the context settings.
14.1340 + *
14.1341 + * @param multiplicand value to be multiplied by this {@code BigDecimal}.
14.1342 + * @param mc the context to use.
14.1343 + * @return {@code this * multiplicand}, rounded as necessary.
14.1344 + * @throws ArithmeticException if the result is inexact but the
14.1345 + * rounding mode is {@code UNNECESSARY}.
14.1346 + * @since 1.5
14.1347 + */
14.1348 + public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
14.1349 + if (mc.precision == 0)
14.1350 + return multiply(multiplicand);
14.1351 + return doRound(this.multiply(multiplicand), mc);
14.1352 + }
14.1353 +
14.1354 + /**
14.1355 + * Returns a {@code BigDecimal} whose value is {@code (this /
14.1356 + * divisor)}, and whose scale is as specified. If rounding must
14.1357 + * be performed to generate a result with the specified scale, the
14.1358 + * specified rounding mode is applied.
14.1359 + *
14.1360 + * <p>The new {@link #divide(BigDecimal, int, RoundingMode)} method
14.1361 + * should be used in preference to this legacy method.
14.1362 + *
14.1363 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1364 + * @param scale scale of the {@code BigDecimal} quotient to be returned.
14.1365 + * @param roundingMode rounding mode to apply.
14.1366 + * @return {@code this / divisor}
14.1367 + * @throws ArithmeticException if {@code divisor} is zero,
14.1368 + * {@code roundingMode==ROUND_UNNECESSARY} and
14.1369 + * the specified scale is insufficient to represent the result
14.1370 + * of the division exactly.
14.1371 + * @throws IllegalArgumentException if {@code roundingMode} does not
14.1372 + * represent a valid rounding mode.
14.1373 + * @see #ROUND_UP
14.1374 + * @see #ROUND_DOWN
14.1375 + * @see #ROUND_CEILING
14.1376 + * @see #ROUND_FLOOR
14.1377 + * @see #ROUND_HALF_UP
14.1378 + * @see #ROUND_HALF_DOWN
14.1379 + * @see #ROUND_HALF_EVEN
14.1380 + * @see #ROUND_UNNECESSARY
14.1381 + */
14.1382 + public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
14.1383 + /*
14.1384 + * IMPLEMENTATION NOTE: This method *must* return a new object
14.1385 + * since divideAndRound uses divide to generate a value whose
14.1386 + * scale is then modified.
14.1387 + */
14.1388 + if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
14.1389 + throw new IllegalArgumentException("Invalid rounding mode");
14.1390 + /*
14.1391 + * Rescale dividend or divisor (whichever can be "upscaled" to
14.1392 + * produce correctly scaled quotient).
14.1393 + * Take care to detect out-of-range scales
14.1394 + */
14.1395 + BigDecimal dividend = this;
14.1396 + if (checkScale((long)scale + divisor.scale) > this.scale)
14.1397 + dividend = this.setScale(scale + divisor.scale, ROUND_UNNECESSARY);
14.1398 + else
14.1399 + divisor = divisor.setScale(checkScale((long)this.scale - scale),
14.1400 + ROUND_UNNECESSARY);
14.1401 + return divideAndRound(dividend.intCompact, dividend.intVal,
14.1402 + divisor.intCompact, divisor.intVal,
14.1403 + scale, roundingMode, scale);
14.1404 + }
14.1405 +
14.1406 + /**
14.1407 + * Internally used for division operation. The dividend and divisor are
14.1408 + * passed both in {@code long} format and {@code BigInteger} format. The
14.1409 + * returned {@code BigDecimal} object is the quotient whose scale is set to
14.1410 + * the passed in scale. If the remainder is not zero, it will be rounded
14.1411 + * based on the passed in roundingMode. Also, if the remainder is zero and
14.1412 + * the last parameter, i.e. preferredScale is NOT equal to scale, the
14.1413 + * trailing zeros of the result is stripped to match the preferredScale.
14.1414 + */
14.1415 + private static BigDecimal divideAndRound(long ldividend, BigInteger bdividend,
14.1416 + long ldivisor, BigInteger bdivisor,
14.1417 + int scale, int roundingMode,
14.1418 + int preferredScale) {
14.1419 + boolean isRemainderZero; // record remainder is zero or not
14.1420 + int qsign; // quotient sign
14.1421 + long q = 0, r = 0; // store quotient & remainder in long
14.1422 + MutableBigInteger mq = null; // store quotient
14.1423 + MutableBigInteger mr = null; // store remainder
14.1424 + MutableBigInteger mdivisor = null;
14.1425 + boolean isLongDivision = (ldividend != INFLATED && ldivisor != INFLATED);
14.1426 + if (isLongDivision) {
14.1427 + q = ldividend / ldivisor;
14.1428 + if (roundingMode == ROUND_DOWN && scale == preferredScale)
14.1429 + return new BigDecimal(null, q, scale, 0);
14.1430 + r = ldividend % ldivisor;
14.1431 + isRemainderZero = (r == 0);
14.1432 + qsign = ((ldividend < 0) == (ldivisor < 0)) ? 1 : -1;
14.1433 + } else {
14.1434 + if (bdividend == null)
14.1435 + bdividend = BigInteger.valueOf(ldividend);
14.1436 + // Descend into mutables for faster remainder checks
14.1437 + MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
14.1438 + mq = new MutableBigInteger();
14.1439 + if (ldivisor != INFLATED) {
14.1440 + r = mdividend.divide(ldivisor, mq);
14.1441 + isRemainderZero = (r == 0);
14.1442 + qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum;
14.1443 + } else {
14.1444 + mdivisor = new MutableBigInteger(bdivisor.mag);
14.1445 + mr = mdividend.divide(mdivisor, mq);
14.1446 + isRemainderZero = mr.isZero();
14.1447 + qsign = (bdividend.signum != bdivisor.signum) ? -1 : 1;
14.1448 + }
14.1449 + }
14.1450 + boolean increment = false;
14.1451 + if (!isRemainderZero) {
14.1452 + int cmpFracHalf;
14.1453 + /* Round as appropriate */
14.1454 + if (roundingMode == ROUND_UNNECESSARY) { // Rounding prohibited
14.1455 + throw new ArithmeticException("Rounding necessary");
14.1456 + } else if (roundingMode == ROUND_UP) { // Away from zero
14.1457 + increment = true;
14.1458 + } else if (roundingMode == ROUND_DOWN) { // Towards zero
14.1459 + increment = false;
14.1460 + } else if (roundingMode == ROUND_CEILING) { // Towards +infinity
14.1461 + increment = (qsign > 0);
14.1462 + } else if (roundingMode == ROUND_FLOOR) { // Towards -infinity
14.1463 + increment = (qsign < 0);
14.1464 + } else {
14.1465 + if (isLongDivision || ldivisor != INFLATED) {
14.1466 + if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
14.1467 + cmpFracHalf = 1; // 2 * r can't fit into long
14.1468 + } else {
14.1469 + cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
14.1470 + }
14.1471 + } else {
14.1472 + cmpFracHalf = mr.compareHalf(mdivisor);
14.1473 + }
14.1474 + if (cmpFracHalf < 0)
14.1475 + increment = false; // We're closer to higher digit
14.1476 + else if (cmpFracHalf > 0) // We're closer to lower digit
14.1477 + increment = true;
14.1478 + else if (roundingMode == ROUND_HALF_UP)
14.1479 + increment = true;
14.1480 + else if (roundingMode == ROUND_HALF_DOWN)
14.1481 + increment = false;
14.1482 + else // roundingMode == ROUND_HALF_EVEN, true iff quotient is odd
14.1483 + increment = isLongDivision ? (q & 1L) != 0L : mq.isOdd();
14.1484 + }
14.1485 + }
14.1486 + BigDecimal res;
14.1487 + if (isLongDivision)
14.1488 + res = new BigDecimal(null, (increment ? q + qsign : q), scale, 0);
14.1489 + else {
14.1490 + if (increment)
14.1491 + mq.add(MutableBigInteger.ONE);
14.1492 + res = mq.toBigDecimal(qsign, scale);
14.1493 + }
14.1494 + if (isRemainderZero && preferredScale != scale)
14.1495 + res.stripZerosToMatchScale(preferredScale);
14.1496 + return res;
14.1497 + }
14.1498 +
14.1499 + /**
14.1500 + * Returns a {@code BigDecimal} whose value is {@code (this /
14.1501 + * divisor)}, and whose scale is as specified. If rounding must
14.1502 + * be performed to generate a result with the specified scale, the
14.1503 + * specified rounding mode is applied.
14.1504 + *
14.1505 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1506 + * @param scale scale of the {@code BigDecimal} quotient to be returned.
14.1507 + * @param roundingMode rounding mode to apply.
14.1508 + * @return {@code this / divisor}
14.1509 + * @throws ArithmeticException if {@code divisor} is zero,
14.1510 + * {@code roundingMode==RoundingMode.UNNECESSARY} and
14.1511 + * the specified scale is insufficient to represent the result
14.1512 + * of the division exactly.
14.1513 + * @since 1.5
14.1514 + */
14.1515 + public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
14.1516 + return divide(divisor, scale, roundingMode.oldMode);
14.1517 + }
14.1518 +
14.1519 + /**
14.1520 + * Returns a {@code BigDecimal} whose value is {@code (this /
14.1521 + * divisor)}, and whose scale is {@code this.scale()}. If
14.1522 + * rounding must be performed to generate a result with the given
14.1523 + * scale, the specified rounding mode is applied.
14.1524 + *
14.1525 + * <p>The new {@link #divide(BigDecimal, RoundingMode)} method
14.1526 + * should be used in preference to this legacy method.
14.1527 + *
14.1528 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1529 + * @param roundingMode rounding mode to apply.
14.1530 + * @return {@code this / divisor}
14.1531 + * @throws ArithmeticException if {@code divisor==0}, or
14.1532 + * {@code roundingMode==ROUND_UNNECESSARY} and
14.1533 + * {@code this.scale()} is insufficient to represent the result
14.1534 + * of the division exactly.
14.1535 + * @throws IllegalArgumentException if {@code roundingMode} does not
14.1536 + * represent a valid rounding mode.
14.1537 + * @see #ROUND_UP
14.1538 + * @see #ROUND_DOWN
14.1539 + * @see #ROUND_CEILING
14.1540 + * @see #ROUND_FLOOR
14.1541 + * @see #ROUND_HALF_UP
14.1542 + * @see #ROUND_HALF_DOWN
14.1543 + * @see #ROUND_HALF_EVEN
14.1544 + * @see #ROUND_UNNECESSARY
14.1545 + */
14.1546 + public BigDecimal divide(BigDecimal divisor, int roundingMode) {
14.1547 + return this.divide(divisor, scale, roundingMode);
14.1548 + }
14.1549 +
14.1550 + /**
14.1551 + * Returns a {@code BigDecimal} whose value is {@code (this /
14.1552 + * divisor)}, and whose scale is {@code this.scale()}. If
14.1553 + * rounding must be performed to generate a result with the given
14.1554 + * scale, the specified rounding mode is applied.
14.1555 + *
14.1556 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1557 + * @param roundingMode rounding mode to apply.
14.1558 + * @return {@code this / divisor}
14.1559 + * @throws ArithmeticException if {@code divisor==0}, or
14.1560 + * {@code roundingMode==RoundingMode.UNNECESSARY} and
14.1561 + * {@code this.scale()} is insufficient to represent the result
14.1562 + * of the division exactly.
14.1563 + * @since 1.5
14.1564 + */
14.1565 + public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {
14.1566 + return this.divide(divisor, scale, roundingMode.oldMode);
14.1567 + }
14.1568 +
14.1569 + /**
14.1570 + * Returns a {@code BigDecimal} whose value is {@code (this /
14.1571 + * divisor)}, and whose preferred scale is {@code (this.scale() -
14.1572 + * divisor.scale())}; if the exact quotient cannot be
14.1573 + * represented (because it has a non-terminating decimal
14.1574 + * expansion) an {@code ArithmeticException} is thrown.
14.1575 + *
14.1576 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1577 + * @throws ArithmeticException if the exact quotient does not have a
14.1578 + * terminating decimal expansion
14.1579 + * @return {@code this / divisor}
14.1580 + * @since 1.5
14.1581 + * @author Joseph D. Darcy
14.1582 + */
14.1583 + public BigDecimal divide(BigDecimal divisor) {
14.1584 + /*
14.1585 + * Handle zero cases first.
14.1586 + */
14.1587 + if (divisor.signum() == 0) { // x/0
14.1588 + if (this.signum() == 0) // 0/0
14.1589 + throw new ArithmeticException("Division undefined"); // NaN
14.1590 + throw new ArithmeticException("Division by zero");
14.1591 + }
14.1592 +
14.1593 + // Calculate preferred scale
14.1594 + int preferredScale = saturateLong((long)this.scale - divisor.scale);
14.1595 + if (this.signum() == 0) // 0/y
14.1596 + return (preferredScale >= 0 &&
14.1597 + preferredScale < ZERO_SCALED_BY.length) ?
14.1598 + ZERO_SCALED_BY[preferredScale] :
14.1599 + BigDecimal.valueOf(0, preferredScale);
14.1600 + else {
14.1601 + this.inflate();
14.1602 + divisor.inflate();
14.1603 + /*
14.1604 + * If the quotient this/divisor has a terminating decimal
14.1605 + * expansion, the expansion can have no more than
14.1606 + * (a.precision() + ceil(10*b.precision)/3) digits.
14.1607 + * Therefore, create a MathContext object with this
14.1608 + * precision and do a divide with the UNNECESSARY rounding
14.1609 + * mode.
14.1610 + */
14.1611 + MathContext mc = new MathContext( (int)Math.min(this.precision() +
14.1612 + (long)Math.ceil(10.0*divisor.precision()/3.0),
14.1613 + Integer.MAX_VALUE),
14.1614 + RoundingMode.UNNECESSARY);
14.1615 + BigDecimal quotient;
14.1616 + try {
14.1617 + quotient = this.divide(divisor, mc);
14.1618 + } catch (ArithmeticException e) {
14.1619 + throw new ArithmeticException("Non-terminating decimal expansion; " +
14.1620 + "no exact representable decimal result.");
14.1621 + }
14.1622 +
14.1623 + int quotientScale = quotient.scale();
14.1624 +
14.1625 + // divide(BigDecimal, mc) tries to adjust the quotient to
14.1626 + // the desired one by removing trailing zeros; since the
14.1627 + // exact divide method does not have an explicit digit
14.1628 + // limit, we can add zeros too.
14.1629 +
14.1630 + if (preferredScale > quotientScale)
14.1631 + return quotient.setScale(preferredScale, ROUND_UNNECESSARY);
14.1632 +
14.1633 + return quotient;
14.1634 + }
14.1635 + }
14.1636 +
14.1637 + /**
14.1638 + * Returns a {@code BigDecimal} whose value is {@code (this /
14.1639 + * divisor)}, with rounding according to the context settings.
14.1640 + *
14.1641 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1642 + * @param mc the context to use.
14.1643 + * @return {@code this / divisor}, rounded as necessary.
14.1644 + * @throws ArithmeticException if the result is inexact but the
14.1645 + * rounding mode is {@code UNNECESSARY} or
14.1646 + * {@code mc.precision == 0} and the quotient has a
14.1647 + * non-terminating decimal expansion.
14.1648 + * @since 1.5
14.1649 + */
14.1650 + public BigDecimal divide(BigDecimal divisor, MathContext mc) {
14.1651 + int mcp = mc.precision;
14.1652 + if (mcp == 0)
14.1653 + return divide(divisor);
14.1654 +
14.1655 + BigDecimal dividend = this;
14.1656 + long preferredScale = (long)dividend.scale - divisor.scale;
14.1657 + // Now calculate the answer. We use the existing
14.1658 + // divide-and-round method, but as this rounds to scale we have
14.1659 + // to normalize the values here to achieve the desired result.
14.1660 + // For x/y we first handle y=0 and x=0, and then normalize x and
14.1661 + // y to give x' and y' with the following constraints:
14.1662 + // (a) 0.1 <= x' < 1
14.1663 + // (b) x' <= y' < 10*x'
14.1664 + // Dividing x'/y' with the required scale set to mc.precision then
14.1665 + // will give a result in the range 0.1 to 1 rounded to exactly
14.1666 + // the right number of digits (except in the case of a result of
14.1667 + // 1.000... which can arise when x=y, or when rounding overflows
14.1668 + // The 1.000... case will reduce properly to 1.
14.1669 + if (divisor.signum() == 0) { // x/0
14.1670 + if (dividend.signum() == 0) // 0/0
14.1671 + throw new ArithmeticException("Division undefined"); // NaN
14.1672 + throw new ArithmeticException("Division by zero");
14.1673 + }
14.1674 + if (dividend.signum() == 0) // 0/y
14.1675 + return new BigDecimal(BigInteger.ZERO, 0,
14.1676 + saturateLong(preferredScale), 1);
14.1677 +
14.1678 + // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
14.1679 + int xscale = dividend.precision();
14.1680 + int yscale = divisor.precision();
14.1681 + dividend = new BigDecimal(dividend.intVal, dividend.intCompact,
14.1682 + xscale, xscale);
14.1683 + divisor = new BigDecimal(divisor.intVal, divisor.intCompact,
14.1684 + yscale, yscale);
14.1685 + if (dividend.compareMagnitude(divisor) > 0) // satisfy constraint (b)
14.1686 + yscale = divisor.scale -= 1; // [that is, divisor *= 10]
14.1687 +
14.1688 + // In order to find out whether the divide generates the exact result,
14.1689 + // we avoid calling the above divide method. 'quotient' holds the
14.1690 + // return BigDecimal object whose scale will be set to 'scl'.
14.1691 + BigDecimal quotient;
14.1692 + int scl = checkScale(preferredScale + yscale - xscale + mcp);
14.1693 + if (checkScale((long)mcp + yscale) > xscale)
14.1694 + dividend = dividend.setScale(mcp + yscale, ROUND_UNNECESSARY);
14.1695 + else
14.1696 + divisor = divisor.setScale(checkScale((long)xscale - mcp),
14.1697 + ROUND_UNNECESSARY);
14.1698 + quotient = divideAndRound(dividend.intCompact, dividend.intVal,
14.1699 + divisor.intCompact, divisor.intVal,
14.1700 + scl, mc.roundingMode.oldMode,
14.1701 + checkScale(preferredScale));
14.1702 + // doRound, here, only affects 1000000000 case.
14.1703 + quotient = doRound(quotient, mc);
14.1704 +
14.1705 + return quotient;
14.1706 + }
14.1707 +
14.1708 + /**
14.1709 + * Returns a {@code BigDecimal} whose value is the integer part
14.1710 + * of the quotient {@code (this / divisor)} rounded down. The
14.1711 + * preferred scale of the result is {@code (this.scale() -
14.1712 + * divisor.scale())}.
14.1713 + *
14.1714 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1715 + * @return The integer part of {@code this / divisor}.
14.1716 + * @throws ArithmeticException if {@code divisor==0}
14.1717 + * @since 1.5
14.1718 + */
14.1719 + public BigDecimal divideToIntegralValue(BigDecimal divisor) {
14.1720 + // Calculate preferred scale
14.1721 + int preferredScale = saturateLong((long)this.scale - divisor.scale);
14.1722 + if (this.compareMagnitude(divisor) < 0) {
14.1723 + // much faster when this << divisor
14.1724 + return BigDecimal.valueOf(0, preferredScale);
14.1725 + }
14.1726 +
14.1727 + if(this.signum() == 0 && divisor.signum() != 0)
14.1728 + return this.setScale(preferredScale, ROUND_UNNECESSARY);
14.1729 +
14.1730 + // Perform a divide with enough digits to round to a correct
14.1731 + // integer value; then remove any fractional digits
14.1732 +
14.1733 + int maxDigits = (int)Math.min(this.precision() +
14.1734 + (long)Math.ceil(10.0*divisor.precision()/3.0) +
14.1735 + Math.abs((long)this.scale() - divisor.scale()) + 2,
14.1736 + Integer.MAX_VALUE);
14.1737 + BigDecimal quotient = this.divide(divisor, new MathContext(maxDigits,
14.1738 + RoundingMode.DOWN));
14.1739 + if (quotient.scale > 0) {
14.1740 + quotient = quotient.setScale(0, RoundingMode.DOWN);
14.1741 + quotient.stripZerosToMatchScale(preferredScale);
14.1742 + }
14.1743 +
14.1744 + if (quotient.scale < preferredScale) {
14.1745 + // pad with zeros if necessary
14.1746 + quotient = quotient.setScale(preferredScale, ROUND_UNNECESSARY);
14.1747 + }
14.1748 + return quotient;
14.1749 + }
14.1750 +
14.1751 + /**
14.1752 + * Returns a {@code BigDecimal} whose value is the integer part
14.1753 + * of {@code (this / divisor)}. Since the integer part of the
14.1754 + * exact quotient does not depend on the rounding mode, the
14.1755 + * rounding mode does not affect the values returned by this
14.1756 + * method. The preferred scale of the result is
14.1757 + * {@code (this.scale() - divisor.scale())}. An
14.1758 + * {@code ArithmeticException} is thrown if the integer part of
14.1759 + * the exact quotient needs more than {@code mc.precision}
14.1760 + * digits.
14.1761 + *
14.1762 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1763 + * @param mc the context to use.
14.1764 + * @return The integer part of {@code this / divisor}.
14.1765 + * @throws ArithmeticException if {@code divisor==0}
14.1766 + * @throws ArithmeticException if {@code mc.precision} {@literal >} 0 and the result
14.1767 + * requires a precision of more than {@code mc.precision} digits.
14.1768 + * @since 1.5
14.1769 + * @author Joseph D. Darcy
14.1770 + */
14.1771 + public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {
14.1772 + if (mc.precision == 0 || // exact result
14.1773 + (this.compareMagnitude(divisor) < 0) ) // zero result
14.1774 + return divideToIntegralValue(divisor);
14.1775 +
14.1776 + // Calculate preferred scale
14.1777 + int preferredScale = saturateLong((long)this.scale - divisor.scale);
14.1778 +
14.1779 + /*
14.1780 + * Perform a normal divide to mc.precision digits. If the
14.1781 + * remainder has absolute value less than the divisor, the
14.1782 + * integer portion of the quotient fits into mc.precision
14.1783 + * digits. Next, remove any fractional digits from the
14.1784 + * quotient and adjust the scale to the preferred value.
14.1785 + */
14.1786 + BigDecimal result = this.
14.1787 + divide(divisor, new MathContext(mc.precision, RoundingMode.DOWN));
14.1788 +
14.1789 + if (result.scale() < 0) {
14.1790 + /*
14.1791 + * Result is an integer. See if quotient represents the
14.1792 + * full integer portion of the exact quotient; if it does,
14.1793 + * the computed remainder will be less than the divisor.
14.1794 + */
14.1795 + BigDecimal product = result.multiply(divisor);
14.1796 + // If the quotient is the full integer value,
14.1797 + // |dividend-product| < |divisor|.
14.1798 + if (this.subtract(product).compareMagnitude(divisor) >= 0) {
14.1799 + throw new ArithmeticException("Division impossible");
14.1800 + }
14.1801 + } else if (result.scale() > 0) {
14.1802 + /*
14.1803 + * Integer portion of quotient will fit into precision
14.1804 + * digits; recompute quotient to scale 0 to avoid double
14.1805 + * rounding and then try to adjust, if necessary.
14.1806 + */
14.1807 + result = result.setScale(0, RoundingMode.DOWN);
14.1808 + }
14.1809 + // else result.scale() == 0;
14.1810 +
14.1811 + int precisionDiff;
14.1812 + if ((preferredScale > result.scale()) &&
14.1813 + (precisionDiff = mc.precision - result.precision()) > 0) {
14.1814 + return result.setScale(result.scale() +
14.1815 + Math.min(precisionDiff, preferredScale - result.scale) );
14.1816 + } else {
14.1817 + result.stripZerosToMatchScale(preferredScale);
14.1818 + return result;
14.1819 + }
14.1820 + }
14.1821 +
14.1822 + /**
14.1823 + * Returns a {@code BigDecimal} whose value is {@code (this % divisor)}.
14.1824 + *
14.1825 + * <p>The remainder is given by
14.1826 + * {@code this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))}.
14.1827 + * Note that this is not the modulo operation (the result can be
14.1828 + * negative).
14.1829 + *
14.1830 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1831 + * @return {@code this % divisor}.
14.1832 + * @throws ArithmeticException if {@code divisor==0}
14.1833 + * @since 1.5
14.1834 + */
14.1835 + public BigDecimal remainder(BigDecimal divisor) {
14.1836 + BigDecimal divrem[] = this.divideAndRemainder(divisor);
14.1837 + return divrem[1];
14.1838 + }
14.1839 +
14.1840 +
14.1841 + /**
14.1842 + * Returns a {@code BigDecimal} whose value is {@code (this %
14.1843 + * divisor)}, with rounding according to the context settings.
14.1844 + * The {@code MathContext} settings affect the implicit divide
14.1845 + * used to compute the remainder. The remainder computation
14.1846 + * itself is by definition exact. Therefore, the remainder may
14.1847 + * contain more than {@code mc.getPrecision()} digits.
14.1848 + *
14.1849 + * <p>The remainder is given by
14.1850 + * {@code this.subtract(this.divideToIntegralValue(divisor,
14.1851 + * mc).multiply(divisor))}. Note that this is not the modulo
14.1852 + * operation (the result can be negative).
14.1853 + *
14.1854 + * @param divisor value by which this {@code BigDecimal} is to be divided.
14.1855 + * @param mc the context to use.
14.1856 + * @return {@code this % divisor}, rounded as necessary.
14.1857 + * @throws ArithmeticException if {@code divisor==0}
14.1858 + * @throws ArithmeticException if the result is inexact but the
14.1859 + * rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
14.1860 + * {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
14.1861 + * require a precision of more than {@code mc.precision} digits.
14.1862 + * @see #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
14.1863 + * @since 1.5
14.1864 + */
14.1865 + public BigDecimal remainder(BigDecimal divisor, MathContext mc) {
14.1866 + BigDecimal divrem[] = this.divideAndRemainder(divisor, mc);
14.1867 + return divrem[1];
14.1868 + }
14.1869 +
14.1870 + /**
14.1871 + * Returns a two-element {@code BigDecimal} array containing the
14.1872 + * result of {@code divideToIntegralValue} followed by the result of
14.1873 + * {@code remainder} on the two operands.
14.1874 + *
14.1875 + * <p>Note that if both the integer quotient and remainder are
14.1876 + * needed, this method is faster than using the
14.1877 + * {@code divideToIntegralValue} and {@code remainder} methods
14.1878 + * separately because the division need only be carried out once.
14.1879 + *
14.1880 + * @param divisor value by which this {@code BigDecimal} is to be divided,
14.1881 + * and the remainder computed.
14.1882 + * @return a two element {@code BigDecimal} array: the quotient
14.1883 + * (the result of {@code divideToIntegralValue}) is the initial element
14.1884 + * and the remainder is the final element.
14.1885 + * @throws ArithmeticException if {@code divisor==0}
14.1886 + * @see #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
14.1887 + * @see #remainder(java.math.BigDecimal, java.math.MathContext)
14.1888 + * @since 1.5
14.1889 + */
14.1890 + public BigDecimal[] divideAndRemainder(BigDecimal divisor) {
14.1891 + // we use the identity x = i * y + r to determine r
14.1892 + BigDecimal[] result = new BigDecimal[2];
14.1893 +
14.1894 + result[0] = this.divideToIntegralValue(divisor);
14.1895 + result[1] = this.subtract(result[0].multiply(divisor));
14.1896 + return result;
14.1897 + }
14.1898 +
14.1899 + /**
14.1900 + * Returns a two-element {@code BigDecimal} array containing the
14.1901 + * result of {@code divideToIntegralValue} followed by the result of
14.1902 + * {@code remainder} on the two operands calculated with rounding
14.1903 + * according to the context settings.
14.1904 + *
14.1905 + * <p>Note that if both the integer quotient and remainder are
14.1906 + * needed, this method is faster than using the
14.1907 + * {@code divideToIntegralValue} and {@code remainder} methods
14.1908 + * separately because the division need only be carried out once.
14.1909 + *
14.1910 + * @param divisor value by which this {@code BigDecimal} is to be divided,
14.1911 + * and the remainder computed.
14.1912 + * @param mc the context to use.
14.1913 + * @return a two element {@code BigDecimal} array: the quotient
14.1914 + * (the result of {@code divideToIntegralValue}) is the
14.1915 + * initial element and the remainder is the final element.
14.1916 + * @throws ArithmeticException if {@code divisor==0}
14.1917 + * @throws ArithmeticException if the result is inexact but the
14.1918 + * rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
14.1919 + * {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
14.1920 + * require a precision of more than {@code mc.precision} digits.
14.1921 + * @see #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
14.1922 + * @see #remainder(java.math.BigDecimal, java.math.MathContext)
14.1923 + * @since 1.5
14.1924 + */
14.1925 + public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
14.1926 + if (mc.precision == 0)
14.1927 + return divideAndRemainder(divisor);
14.1928 +
14.1929 + BigDecimal[] result = new BigDecimal[2];
14.1930 + BigDecimal lhs = this;
14.1931 +
14.1932 + result[0] = lhs.divideToIntegralValue(divisor, mc);
14.1933 + result[1] = lhs.subtract(result[0].multiply(divisor));
14.1934 + return result;
14.1935 + }
14.1936 +
14.1937 + /**
14.1938 + * Returns a {@code BigDecimal} whose value is
14.1939 + * <tt>(this<sup>n</sup>)</tt>, The power is computed exactly, to
14.1940 + * unlimited precision.
14.1941 + *
14.1942 + * <p>The parameter {@code n} must be in the range 0 through
14.1943 + * 999999999, inclusive. {@code ZERO.pow(0)} returns {@link
14.1944 + * #ONE}.
14.1945 + *
14.1946 + * Note that future releases may expand the allowable exponent
14.1947 + * range of this method.
14.1948 + *
14.1949 + * @param n power to raise this {@code BigDecimal} to.
14.1950 + * @return <tt>this<sup>n</sup></tt>
14.1951 + * @throws ArithmeticException if {@code n} is out of range.
14.1952 + * @since 1.5
14.1953 + */
14.1954 + public BigDecimal pow(int n) {
14.1955 + if (n < 0 || n > 999999999)
14.1956 + throw new ArithmeticException("Invalid operation");
14.1957 + // No need to calculate pow(n) if result will over/underflow.
14.1958 + // Don't attempt to support "supernormal" numbers.
14.1959 + int newScale = checkScale((long)scale * n);
14.1960 + this.inflate();
14.1961 + return new BigDecimal(intVal.pow(n), newScale);
14.1962 + }
14.1963 +
14.1964 +
14.1965 + /**
14.1966 + * Returns a {@code BigDecimal} whose value is
14.1967 + * <tt>(this<sup>n</sup>)</tt>. The current implementation uses
14.1968 + * the core algorithm defined in ANSI standard X3.274-1996 with
14.1969 + * rounding according to the context settings. In general, the
14.1970 + * returned numerical value is within two ulps of the exact
14.1971 + * numerical value for the chosen precision. Note that future
14.1972 + * releases may use a different algorithm with a decreased
14.1973 + * allowable error bound and increased allowable exponent range.
14.1974 + *
14.1975 + * <p>The X3.274-1996 algorithm is:
14.1976 + *
14.1977 + * <ul>
14.1978 + * <li> An {@code ArithmeticException} exception is thrown if
14.1979 + * <ul>
14.1980 + * <li>{@code abs(n) > 999999999}
14.1981 + * <li>{@code mc.precision == 0} and {@code n < 0}
14.1982 + * <li>{@code mc.precision > 0} and {@code n} has more than
14.1983 + * {@code mc.precision} decimal digits
14.1984 + * </ul>
14.1985 + *
14.1986 + * <li> if {@code n} is zero, {@link #ONE} is returned even if
14.1987 + * {@code this} is zero, otherwise
14.1988 + * <ul>
14.1989 + * <li> if {@code n} is positive, the result is calculated via
14.1990 + * the repeated squaring technique into a single accumulator.
14.1991 + * The individual multiplications with the accumulator use the
14.1992 + * same math context settings as in {@code mc} except for a
14.1993 + * precision increased to {@code mc.precision + elength + 1}
14.1994 + * where {@code elength} is the number of decimal digits in
14.1995 + * {@code n}.
14.1996 + *
14.1997 + * <li> if {@code n} is negative, the result is calculated as if
14.1998 + * {@code n} were positive; this value is then divided into one
14.1999 + * using the working precision specified above.
14.2000 + *
14.2001 + * <li> The final value from either the positive or negative case
14.2002 + * is then rounded to the destination precision.
14.2003 + * </ul>
14.2004 + * </ul>
14.2005 + *
14.2006 + * @param n power to raise this {@code BigDecimal} to.
14.2007 + * @param mc the context to use.
14.2008 + * @return <tt>this<sup>n</sup></tt> using the ANSI standard X3.274-1996
14.2009 + * algorithm
14.2010 + * @throws ArithmeticException if the result is inexact but the
14.2011 + * rounding mode is {@code UNNECESSARY}, or {@code n} is out
14.2012 + * of range.
14.2013 + * @since 1.5
14.2014 + */
14.2015 + public BigDecimal pow(int n, MathContext mc) {
14.2016 + if (mc.precision == 0)
14.2017 + return pow(n);
14.2018 + if (n < -999999999 || n > 999999999)
14.2019 + throw new ArithmeticException("Invalid operation");
14.2020 + if (n == 0)
14.2021 + return ONE; // x**0 == 1 in X3.274
14.2022 + this.inflate();
14.2023 + BigDecimal lhs = this;
14.2024 + MathContext workmc = mc; // working settings
14.2025 + int mag = Math.abs(n); // magnitude of n
14.2026 + if (mc.precision > 0) {
14.2027 +
14.2028 + int elength = longDigitLength(mag); // length of n in digits
14.2029 + if (elength > mc.precision) // X3.274 rule
14.2030 + throw new ArithmeticException("Invalid operation");
14.2031 + workmc = new MathContext(mc.precision + elength + 1,
14.2032 + mc.roundingMode);
14.2033 + }
14.2034 + // ready to carry out power calculation...
14.2035 + BigDecimal acc = ONE; // accumulator
14.2036 + boolean seenbit = false; // set once we've seen a 1-bit
14.2037 + for (int i=1;;i++) { // for each bit [top bit ignored]
14.2038 + mag += mag; // shift left 1 bit
14.2039 + if (mag < 0) { // top bit is set
14.2040 + seenbit = true; // OK, we're off
14.2041 + acc = acc.multiply(lhs, workmc); // acc=acc*x
14.2042 + }
14.2043 + if (i == 31)
14.2044 + break; // that was the last bit
14.2045 + if (seenbit)
14.2046 + acc=acc.multiply(acc, workmc); // acc=acc*acc [square]
14.2047 + // else (!seenbit) no point in squaring ONE
14.2048 + }
14.2049 + // if negative n, calculate the reciprocal using working precision
14.2050 + if (n<0) // [hence mc.precision>0]
14.2051 + acc=ONE.divide(acc, workmc);
14.2052 + // round to final precision and strip zeros
14.2053 + return doRound(acc, mc);
14.2054 + }
14.2055 +
14.2056 + /**
14.2057 + * Returns a {@code BigDecimal} whose value is the absolute value
14.2058 + * of this {@code BigDecimal}, and whose scale is
14.2059 + * {@code this.scale()}.
14.2060 + *
14.2061 + * @return {@code abs(this)}
14.2062 + */
14.2063 + public BigDecimal abs() {
14.2064 + return (signum() < 0 ? negate() : this);
14.2065 + }
14.2066 +
14.2067 + /**
14.2068 + * Returns a {@code BigDecimal} whose value is the absolute value
14.2069 + * of this {@code BigDecimal}, with rounding according to the
14.2070 + * context settings.
14.2071 + *
14.2072 + * @param mc the context to use.
14.2073 + * @return {@code abs(this)}, rounded as necessary.
14.2074 + * @throws ArithmeticException if the result is inexact but the
14.2075 + * rounding mode is {@code UNNECESSARY}.
14.2076 + * @since 1.5
14.2077 + */
14.2078 + public BigDecimal abs(MathContext mc) {
14.2079 + return (signum() < 0 ? negate(mc) : plus(mc));
14.2080 + }
14.2081 +
14.2082 + /**
14.2083 + * Returns a {@code BigDecimal} whose value is {@code (-this)},
14.2084 + * and whose scale is {@code this.scale()}.
14.2085 + *
14.2086 + * @return {@code -this}.
14.2087 + */
14.2088 + public BigDecimal negate() {
14.2089 + BigDecimal result;
14.2090 + if (intCompact != INFLATED)
14.2091 + result = BigDecimal.valueOf(-intCompact, scale);
14.2092 + else {
14.2093 + result = new BigDecimal(intVal.negate(), scale);
14.2094 + result.precision = precision;
14.2095 + }
14.2096 + return result;
14.2097 + }
14.2098 +
14.2099 + /**
14.2100 + * Returns a {@code BigDecimal} whose value is {@code (-this)},
14.2101 + * with rounding according to the context settings.
14.2102 + *
14.2103 + * @param mc the context to use.
14.2104 + * @return {@code -this}, rounded as necessary.
14.2105 + * @throws ArithmeticException if the result is inexact but the
14.2106 + * rounding mode is {@code UNNECESSARY}.
14.2107 + * @since 1.5
14.2108 + */
14.2109 + public BigDecimal negate(MathContext mc) {
14.2110 + return negate().plus(mc);
14.2111 + }
14.2112 +
14.2113 + /**
14.2114 + * Returns a {@code BigDecimal} whose value is {@code (+this)}, and whose
14.2115 + * scale is {@code this.scale()}.
14.2116 + *
14.2117 + * <p>This method, which simply returns this {@code BigDecimal}
14.2118 + * is included for symmetry with the unary minus method {@link
14.2119 + * #negate()}.
14.2120 + *
14.2121 + * @return {@code this}.
14.2122 + * @see #negate()
14.2123 + * @since 1.5
14.2124 + */
14.2125 + public BigDecimal plus() {
14.2126 + return this;
14.2127 + }
14.2128 +
14.2129 + /**
14.2130 + * Returns a {@code BigDecimal} whose value is {@code (+this)},
14.2131 + * with rounding according to the context settings.
14.2132 + *
14.2133 + * <p>The effect of this method is identical to that of the {@link
14.2134 + * #round(MathContext)} method.
14.2135 + *
14.2136 + * @param mc the context to use.
14.2137 + * @return {@code this}, rounded as necessary. A zero result will
14.2138 + * have a scale of 0.
14.2139 + * @throws ArithmeticException if the result is inexact but the
14.2140 + * rounding mode is {@code UNNECESSARY}.
14.2141 + * @see #round(MathContext)
14.2142 + * @since 1.5
14.2143 + */
14.2144 + public BigDecimal plus(MathContext mc) {
14.2145 + if (mc.precision == 0) // no rounding please
14.2146 + return this;
14.2147 + return doRound(this, mc);
14.2148 + }
14.2149 +
14.2150 + /**
14.2151 + * Returns the signum function of this {@code BigDecimal}.
14.2152 + *
14.2153 + * @return -1, 0, or 1 as the value of this {@code BigDecimal}
14.2154 + * is negative, zero, or positive.
14.2155 + */
14.2156 + public int signum() {
14.2157 + return (intCompact != INFLATED)?
14.2158 + Long.signum(intCompact):
14.2159 + intVal.signum();
14.2160 + }
14.2161 +
14.2162 + /**
14.2163 + * Returns the <i>scale</i> of this {@code BigDecimal}. If zero
14.2164 + * or positive, the scale is the number of digits to the right of
14.2165 + * the decimal point. If negative, the unscaled value of the
14.2166 + * number is multiplied by ten to the power of the negation of the
14.2167 + * scale. For example, a scale of {@code -3} means the unscaled
14.2168 + * value is multiplied by 1000.
14.2169 + *
14.2170 + * @return the scale of this {@code BigDecimal}.
14.2171 + */
14.2172 + public int scale() {
14.2173 + return scale;
14.2174 + }
14.2175 +
14.2176 + /**
14.2177 + * Returns the <i>precision</i> of this {@code BigDecimal}. (The
14.2178 + * precision is the number of digits in the unscaled value.)
14.2179 + *
14.2180 + * <p>The precision of a zero value is 1.
14.2181 + *
14.2182 + * @return the precision of this {@code BigDecimal}.
14.2183 + * @since 1.5
14.2184 + */
14.2185 + public int precision() {
14.2186 + int result = precision;
14.2187 + if (result == 0) {
14.2188 + long s = intCompact;
14.2189 + if (s != INFLATED)
14.2190 + result = longDigitLength(s);
14.2191 + else
14.2192 + result = bigDigitLength(inflate());
14.2193 + precision = result;
14.2194 + }
14.2195 + return result;
14.2196 + }
14.2197 +
14.2198 +
14.2199 + /**
14.2200 + * Returns a {@code BigInteger} whose value is the <i>unscaled
14.2201 + * value</i> of this {@code BigDecimal}. (Computes <tt>(this *
14.2202 + * 10<sup>this.scale()</sup>)</tt>.)
14.2203 + *
14.2204 + * @return the unscaled value of this {@code BigDecimal}.
14.2205 + * @since 1.2
14.2206 + */
14.2207 + public BigInteger unscaledValue() {
14.2208 + return this.inflate();
14.2209 + }
14.2210 +
14.2211 + // Rounding Modes
14.2212 +
14.2213 + /**
14.2214 + * Rounding mode to round away from zero. Always increments the
14.2215 + * digit prior to a nonzero discarded fraction. Note that this rounding
14.2216 + * mode never decreases the magnitude of the calculated value.
14.2217 + */
14.2218 + public final static int ROUND_UP = 0;
14.2219 +
14.2220 + /**
14.2221 + * Rounding mode to round towards zero. Never increments the digit
14.2222 + * prior to a discarded fraction (i.e., truncates). Note that this
14.2223 + * rounding mode never increases the magnitude of the calculated value.
14.2224 + */
14.2225 + public final static int ROUND_DOWN = 1;
14.2226 +
14.2227 + /**
14.2228 + * Rounding mode to round towards positive infinity. If the
14.2229 + * {@code BigDecimal} is positive, behaves as for
14.2230 + * {@code ROUND_UP}; if negative, behaves as for
14.2231 + * {@code ROUND_DOWN}. Note that this rounding mode never
14.2232 + * decreases the calculated value.
14.2233 + */
14.2234 + public final static int ROUND_CEILING = 2;
14.2235 +
14.2236 + /**
14.2237 + * Rounding mode to round towards negative infinity. If the
14.2238 + * {@code BigDecimal} is positive, behave as for
14.2239 + * {@code ROUND_DOWN}; if negative, behave as for
14.2240 + * {@code ROUND_UP}. Note that this rounding mode never
14.2241 + * increases the calculated value.
14.2242 + */
14.2243 + public final static int ROUND_FLOOR = 3;
14.2244 +
14.2245 + /**
14.2246 + * Rounding mode to round towards {@literal "nearest neighbor"}
14.2247 + * unless both neighbors are equidistant, in which case round up.
14.2248 + * Behaves as for {@code ROUND_UP} if the discarded fraction is
14.2249 + * ≥ 0.5; otherwise, behaves as for {@code ROUND_DOWN}. Note
14.2250 + * that this is the rounding mode that most of us were taught in
14.2251 + * grade school.
14.2252 + */
14.2253 + public final static int ROUND_HALF_UP = 4;
14.2254 +
14.2255 + /**
14.2256 + * Rounding mode to round towards {@literal "nearest neighbor"}
14.2257 + * unless both neighbors are equidistant, in which case round
14.2258 + * down. Behaves as for {@code ROUND_UP} if the discarded
14.2259 + * fraction is {@literal >} 0.5; otherwise, behaves as for
14.2260 + * {@code ROUND_DOWN}.
14.2261 + */
14.2262 + public final static int ROUND_HALF_DOWN = 5;
14.2263 +
14.2264 + /**
14.2265 + * Rounding mode to round towards the {@literal "nearest neighbor"}
14.2266 + * unless both neighbors are equidistant, in which case, round
14.2267 + * towards the even neighbor. Behaves as for
14.2268 + * {@code ROUND_HALF_UP} if the digit to the left of the
14.2269 + * discarded fraction is odd; behaves as for
14.2270 + * {@code ROUND_HALF_DOWN} if it's even. Note that this is the
14.2271 + * rounding mode that minimizes cumulative error when applied
14.2272 + * repeatedly over a sequence of calculations.
14.2273 + */
14.2274 + public final static int ROUND_HALF_EVEN = 6;
14.2275 +
14.2276 + /**
14.2277 + * Rounding mode to assert that the requested operation has an exact
14.2278 + * result, hence no rounding is necessary. If this rounding mode is
14.2279 + * specified on an operation that yields an inexact result, an
14.2280 + * {@code ArithmeticException} is thrown.
14.2281 + */
14.2282 + public final static int ROUND_UNNECESSARY = 7;
14.2283 +
14.2284 +
14.2285 + // Scaling/Rounding Operations
14.2286 +
14.2287 + /**
14.2288 + * Returns a {@code BigDecimal} rounded according to the
14.2289 + * {@code MathContext} settings. If the precision setting is 0 then
14.2290 + * no rounding takes place.
14.2291 + *
14.2292 + * <p>The effect of this method is identical to that of the
14.2293 + * {@link #plus(MathContext)} method.
14.2294 + *
14.2295 + * @param mc the context to use.
14.2296 + * @return a {@code BigDecimal} rounded according to the
14.2297 + * {@code MathContext} settings.
14.2298 + * @throws ArithmeticException if the rounding mode is
14.2299 + * {@code UNNECESSARY} and the
14.2300 + * {@code BigDecimal} operation would require rounding.
14.2301 + * @see #plus(MathContext)
14.2302 + * @since 1.5
14.2303 + */
14.2304 + public BigDecimal round(MathContext mc) {
14.2305 + return plus(mc);
14.2306 + }
14.2307 +
14.2308 + /**
14.2309 + * Returns a {@code BigDecimal} whose scale is the specified
14.2310 + * value, and whose unscaled value is determined by multiplying or
14.2311 + * dividing this {@code BigDecimal}'s unscaled value by the
14.2312 + * appropriate power of ten to maintain its overall value. If the
14.2313 + * scale is reduced by the operation, the unscaled value must be
14.2314 + * divided (rather than multiplied), and the value may be changed;
14.2315 + * in this case, the specified rounding mode is applied to the
14.2316 + * division.
14.2317 + *
14.2318 + * <p>Note that since BigDecimal objects are immutable, calls of
14.2319 + * this method do <i>not</i> result in the original object being
14.2320 + * modified, contrary to the usual convention of having methods
14.2321 + * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
14.2322 + * Instead, {@code setScale} returns an object with the proper
14.2323 + * scale; the returned object may or may not be newly allocated.
14.2324 + *
14.2325 + * @param newScale scale of the {@code BigDecimal} value to be returned.
14.2326 + * @param roundingMode The rounding mode to apply.
14.2327 + * @return a {@code BigDecimal} whose scale is the specified value,
14.2328 + * and whose unscaled value is determined by multiplying or
14.2329 + * dividing this {@code BigDecimal}'s unscaled value by the
14.2330 + * appropriate power of ten to maintain its overall value.
14.2331 + * @throws ArithmeticException if {@code roundingMode==UNNECESSARY}
14.2332 + * and the specified scaling operation would require
14.2333 + * rounding.
14.2334 + * @see RoundingMode
14.2335 + * @since 1.5
14.2336 + */
14.2337 + public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
14.2338 + return setScale(newScale, roundingMode.oldMode);
14.2339 + }
14.2340 +
14.2341 + /**
14.2342 + * Returns a {@code BigDecimal} whose scale is the specified
14.2343 + * value, and whose unscaled value is determined by multiplying or
14.2344 + * dividing this {@code BigDecimal}'s unscaled value by the
14.2345 + * appropriate power of ten to maintain its overall value. If the
14.2346 + * scale is reduced by the operation, the unscaled value must be
14.2347 + * divided (rather than multiplied), and the value may be changed;
14.2348 + * in this case, the specified rounding mode is applied to the
14.2349 + * division.
14.2350 + *
14.2351 + * <p>Note that since BigDecimal objects are immutable, calls of
14.2352 + * this method do <i>not</i> result in the original object being
14.2353 + * modified, contrary to the usual convention of having methods
14.2354 + * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
14.2355 + * Instead, {@code setScale} returns an object with the proper
14.2356 + * scale; the returned object may or may not be newly allocated.
14.2357 + *
14.2358 + * <p>The new {@link #setScale(int, RoundingMode)} method should
14.2359 + * be used in preference to this legacy method.
14.2360 + *
14.2361 + * @param newScale scale of the {@code BigDecimal} value to be returned.
14.2362 + * @param roundingMode The rounding mode to apply.
14.2363 + * @return a {@code BigDecimal} whose scale is the specified value,
14.2364 + * and whose unscaled value is determined by multiplying or
14.2365 + * dividing this {@code BigDecimal}'s unscaled value by the
14.2366 + * appropriate power of ten to maintain its overall value.
14.2367 + * @throws ArithmeticException if {@code roundingMode==ROUND_UNNECESSARY}
14.2368 + * and the specified scaling operation would require
14.2369 + * rounding.
14.2370 + * @throws IllegalArgumentException if {@code roundingMode} does not
14.2371 + * represent a valid rounding mode.
14.2372 + * @see #ROUND_UP
14.2373 + * @see #ROUND_DOWN
14.2374 + * @see #ROUND_CEILING
14.2375 + * @see #ROUND_FLOOR
14.2376 + * @see #ROUND_HALF_UP
14.2377 + * @see #ROUND_HALF_DOWN
14.2378 + * @see #ROUND_HALF_EVEN
14.2379 + * @see #ROUND_UNNECESSARY
14.2380 + */
14.2381 + public BigDecimal setScale(int newScale, int roundingMode) {
14.2382 + if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
14.2383 + throw new IllegalArgumentException("Invalid rounding mode");
14.2384 +
14.2385 + int oldScale = this.scale;
14.2386 + if (newScale == oldScale) // easy case
14.2387 + return this;
14.2388 + if (this.signum() == 0) // zero can have any scale
14.2389 + return BigDecimal.valueOf(0, newScale);
14.2390 +
14.2391 + long rs = this.intCompact;
14.2392 + if (newScale > oldScale) {
14.2393 + int raise = checkScale((long)newScale - oldScale);
14.2394 + BigInteger rb = null;
14.2395 + if (rs == INFLATED ||
14.2396 + (rs = longMultiplyPowerTen(rs, raise)) == INFLATED)
14.2397 + rb = bigMultiplyPowerTen(raise);
14.2398 + return new BigDecimal(rb, rs, newScale,
14.2399 + (precision > 0) ? precision + raise : 0);
14.2400 + } else {
14.2401 + // newScale < oldScale -- drop some digits
14.2402 + // Can't predict the precision due to the effect of rounding.
14.2403 + int drop = checkScale((long)oldScale - newScale);
14.2404 + if (drop < LONG_TEN_POWERS_TABLE.length)
14.2405 + return divideAndRound(rs, this.intVal,
14.2406 + LONG_TEN_POWERS_TABLE[drop], null,
14.2407 + newScale, roundingMode, newScale);
14.2408 + else
14.2409 + return divideAndRound(rs, this.intVal,
14.2410 + INFLATED, bigTenToThe(drop),
14.2411 + newScale, roundingMode, newScale);
14.2412 + }
14.2413 + }
14.2414 +
14.2415 + /**
14.2416 + * Returns a {@code BigDecimal} whose scale is the specified
14.2417 + * value, and whose value is numerically equal to this
14.2418 + * {@code BigDecimal}'s. Throws an {@code ArithmeticException}
14.2419 + * if this is not possible.
14.2420 + *
14.2421 + * <p>This call is typically used to increase the scale, in which
14.2422 + * case it is guaranteed that there exists a {@code BigDecimal}
14.2423 + * of the specified scale and the correct value. The call can
14.2424 + * also be used to reduce the scale if the caller knows that the
14.2425 + * {@code BigDecimal} has sufficiently many zeros at the end of
14.2426 + * its fractional part (i.e., factors of ten in its integer value)
14.2427 + * to allow for the rescaling without changing its value.
14.2428 + *
14.2429 + * <p>This method returns the same result as the two-argument
14.2430 + * versions of {@code setScale}, but saves the caller the trouble
14.2431 + * of specifying a rounding mode in cases where it is irrelevant.
14.2432 + *
14.2433 + * <p>Note that since {@code BigDecimal} objects are immutable,
14.2434 + * calls of this method do <i>not</i> result in the original
14.2435 + * object being modified, contrary to the usual convention of
14.2436 + * having methods named <tt>set<i>X</i></tt> mutate field
14.2437 + * <i>{@code X}</i>. Instead, {@code setScale} returns an
14.2438 + * object with the proper scale; the returned object may or may
14.2439 + * not be newly allocated.
14.2440 + *
14.2441 + * @param newScale scale of the {@code BigDecimal} value to be returned.
14.2442 + * @return a {@code BigDecimal} whose scale is the specified value, and
14.2443 + * whose unscaled value is determined by multiplying or dividing
14.2444 + * this {@code BigDecimal}'s unscaled value by the appropriate
14.2445 + * power of ten to maintain its overall value.
14.2446 + * @throws ArithmeticException if the specified scaling operation would
14.2447 + * require rounding.
14.2448 + * @see #setScale(int, int)
14.2449 + * @see #setScale(int, RoundingMode)
14.2450 + */
14.2451 + public BigDecimal setScale(int newScale) {
14.2452 + return setScale(newScale, ROUND_UNNECESSARY);
14.2453 + }
14.2454 +
14.2455 + // Decimal Point Motion Operations
14.2456 +
14.2457 + /**
14.2458 + * Returns a {@code BigDecimal} which is equivalent to this one
14.2459 + * with the decimal point moved {@code n} places to the left. If
14.2460 + * {@code n} is non-negative, the call merely adds {@code n} to
14.2461 + * the scale. If {@code n} is negative, the call is equivalent
14.2462 + * to {@code movePointRight(-n)}. The {@code BigDecimal}
14.2463 + * returned by this call has value <tt>(this ×
14.2464 + * 10<sup>-n</sup>)</tt> and scale {@code max(this.scale()+n,
14.2465 + * 0)}.
14.2466 + *
14.2467 + * @param n number of places to move the decimal point to the left.
14.2468 + * @return a {@code BigDecimal} which is equivalent to this one with the
14.2469 + * decimal point moved {@code n} places to the left.
14.2470 + * @throws ArithmeticException if scale overflows.
14.2471 + */
14.2472 + public BigDecimal movePointLeft(int n) {
14.2473 + // Cannot use movePointRight(-n) in case of n==Integer.MIN_VALUE
14.2474 + int newScale = checkScale((long)scale + n);
14.2475 + BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
14.2476 + return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
14.2477 + }
14.2478 +
14.2479 + /**
14.2480 + * Returns a {@code BigDecimal} which is equivalent to this one
14.2481 + * with the decimal point moved {@code n} places to the right.
14.2482 + * If {@code n} is non-negative, the call merely subtracts
14.2483 + * {@code n} from the scale. If {@code n} is negative, the call
14.2484 + * is equivalent to {@code movePointLeft(-n)}. The
14.2485 + * {@code BigDecimal} returned by this call has value <tt>(this
14.2486 + * × 10<sup>n</sup>)</tt> and scale {@code max(this.scale()-n,
14.2487 + * 0)}.
14.2488 + *
14.2489 + * @param n number of places to move the decimal point to the right.
14.2490 + * @return a {@code BigDecimal} which is equivalent to this one
14.2491 + * with the decimal point moved {@code n} places to the right.
14.2492 + * @throws ArithmeticException if scale overflows.
14.2493 + */
14.2494 + public BigDecimal movePointRight(int n) {
14.2495 + // Cannot use movePointLeft(-n) in case of n==Integer.MIN_VALUE
14.2496 + int newScale = checkScale((long)scale - n);
14.2497 + BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
14.2498 + return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
14.2499 + }
14.2500 +
14.2501 + /**
14.2502 + * Returns a BigDecimal whose numerical value is equal to
14.2503 + * ({@code this} * 10<sup>n</sup>). The scale of
14.2504 + * the result is {@code (this.scale() - n)}.
14.2505 + *
14.2506 + * @throws ArithmeticException if the scale would be
14.2507 + * outside the range of a 32-bit integer.
14.2508 + *
14.2509 + * @since 1.5
14.2510 + */
14.2511 + public BigDecimal scaleByPowerOfTen(int n) {
14.2512 + return new BigDecimal(intVal, intCompact,
14.2513 + checkScale((long)scale - n), precision);
14.2514 + }
14.2515 +
14.2516 + /**
14.2517 + * Returns a {@code BigDecimal} which is numerically equal to
14.2518 + * this one but with any trailing zeros removed from the
14.2519 + * representation. For example, stripping the trailing zeros from
14.2520 + * the {@code BigDecimal} value {@code 600.0}, which has
14.2521 + * [{@code BigInteger}, {@code scale}] components equals to
14.2522 + * [6000, 1], yields {@code 6E2} with [{@code BigInteger},
14.2523 + * {@code scale}] components equals to [6, -2]
14.2524 + *
14.2525 + * @return a numerically equal {@code BigDecimal} with any
14.2526 + * trailing zeros removed.
14.2527 + * @since 1.5
14.2528 + */
14.2529 + public BigDecimal stripTrailingZeros() {
14.2530 + this.inflate();
14.2531 + BigDecimal result = new BigDecimal(intVal, scale);
14.2532 + result.stripZerosToMatchScale(Long.MIN_VALUE);
14.2533 + return result;
14.2534 + }
14.2535 +
14.2536 + // Comparison Operations
14.2537 +
14.2538 + /**
14.2539 + * Compares this {@code BigDecimal} with the specified
14.2540 + * {@code BigDecimal}. Two {@code BigDecimal} objects that are
14.2541 + * equal in value but have a different scale (like 2.0 and 2.00)
14.2542 + * are considered equal by this method. This method is provided
14.2543 + * in preference to individual methods for each of the six boolean
14.2544 + * comparison operators ({@literal <}, ==,
14.2545 + * {@literal >}, {@literal >=}, !=, {@literal <=}). The
14.2546 + * suggested idiom for performing these comparisons is:
14.2547 + * {@code (x.compareTo(y)} <<i>op</i>> {@code 0)}, where
14.2548 + * <<i>op</i>> is one of the six comparison operators.
14.2549 + *
14.2550 + * @param val {@code BigDecimal} to which this {@code BigDecimal} is
14.2551 + * to be compared.
14.2552 + * @return -1, 0, or 1 as this {@code BigDecimal} is numerically
14.2553 + * less than, equal to, or greater than {@code val}.
14.2554 + */
14.2555 + public int compareTo(BigDecimal val) {
14.2556 + // Quick path for equal scale and non-inflated case.
14.2557 + if (scale == val.scale) {
14.2558 + long xs = intCompact;
14.2559 + long ys = val.intCompact;
14.2560 + if (xs != INFLATED && ys != INFLATED)
14.2561 + return xs != ys ? ((xs > ys) ? 1 : -1) : 0;
14.2562 + }
14.2563 + int xsign = this.signum();
14.2564 + int ysign = val.signum();
14.2565 + if (xsign != ysign)
14.2566 + return (xsign > ysign) ? 1 : -1;
14.2567 + if (xsign == 0)
14.2568 + return 0;
14.2569 + int cmp = compareMagnitude(val);
14.2570 + return (xsign > 0) ? cmp : -cmp;
14.2571 + }
14.2572 +
14.2573 + /**
14.2574 + * Version of compareTo that ignores sign.
14.2575 + */
14.2576 + private int compareMagnitude(BigDecimal val) {
14.2577 + // Match scales, avoid unnecessary inflation
14.2578 + long ys = val.intCompact;
14.2579 + long xs = this.intCompact;
14.2580 + if (xs == 0)
14.2581 + return (ys == 0) ? 0 : -1;
14.2582 + if (ys == 0)
14.2583 + return 1;
14.2584 +
14.2585 + int sdiff = this.scale - val.scale;
14.2586 + if (sdiff != 0) {
14.2587 + // Avoid matching scales if the (adjusted) exponents differ
14.2588 + int xae = this.precision() - this.scale; // [-1]
14.2589 + int yae = val.precision() - val.scale; // [-1]
14.2590 + if (xae < yae)
14.2591 + return -1;
14.2592 + if (xae > yae)
14.2593 + return 1;
14.2594 + BigInteger rb = null;
14.2595 + if (sdiff < 0) {
14.2596 + if ( (xs == INFLATED ||
14.2597 + (xs = longMultiplyPowerTen(xs, -sdiff)) == INFLATED) &&
14.2598 + ys == INFLATED) {
14.2599 + rb = bigMultiplyPowerTen(-sdiff);
14.2600 + return rb.compareMagnitude(val.intVal);
14.2601 + }
14.2602 + } else { // sdiff > 0
14.2603 + if ( (ys == INFLATED ||
14.2604 + (ys = longMultiplyPowerTen(ys, sdiff)) == INFLATED) &&
14.2605 + xs == INFLATED) {
14.2606 + rb = val.bigMultiplyPowerTen(sdiff);
14.2607 + return this.intVal.compareMagnitude(rb);
14.2608 + }
14.2609 + }
14.2610 + }
14.2611 + if (xs != INFLATED)
14.2612 + return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
14.2613 + else if (ys != INFLATED)
14.2614 + return 1;
14.2615 + else
14.2616 + return this.intVal.compareMagnitude(val.intVal);
14.2617 + }
14.2618 +
14.2619 + /**
14.2620 + * Compares this {@code BigDecimal} with the specified
14.2621 + * {@code Object} for equality. Unlike {@link
14.2622 + * #compareTo(BigDecimal) compareTo}, this method considers two
14.2623 + * {@code BigDecimal} objects equal only if they are equal in
14.2624 + * value and scale (thus 2.0 is not equal to 2.00 when compared by
14.2625 + * this method).
14.2626 + *
14.2627 + * @param x {@code Object} to which this {@code BigDecimal} is
14.2628 + * to be compared.
14.2629 + * @return {@code true} if and only if the specified {@code Object} is a
14.2630 + * {@code BigDecimal} whose value and scale are equal to this
14.2631 + * {@code BigDecimal}'s.
14.2632 + * @see #compareTo(java.math.BigDecimal)
14.2633 + * @see #hashCode
14.2634 + */
14.2635 + @Override
14.2636 + public boolean equals(Object x) {
14.2637 + if (!(x instanceof BigDecimal))
14.2638 + return false;
14.2639 + BigDecimal xDec = (BigDecimal) x;
14.2640 + if (x == this)
14.2641 + return true;
14.2642 + if (scale != xDec.scale)
14.2643 + return false;
14.2644 + long s = this.intCompact;
14.2645 + long xs = xDec.intCompact;
14.2646 + if (s != INFLATED) {
14.2647 + if (xs == INFLATED)
14.2648 + xs = compactValFor(xDec.intVal);
14.2649 + return xs == s;
14.2650 + } else if (xs != INFLATED)
14.2651 + return xs == compactValFor(this.intVal);
14.2652 +
14.2653 + return this.inflate().equals(xDec.inflate());
14.2654 + }
14.2655 +
14.2656 + /**
14.2657 + * Returns the minimum of this {@code BigDecimal} and
14.2658 + * {@code val}.
14.2659 + *
14.2660 + * @param val value with which the minimum is to be computed.
14.2661 + * @return the {@code BigDecimal} whose value is the lesser of this
14.2662 + * {@code BigDecimal} and {@code val}. If they are equal,
14.2663 + * as defined by the {@link #compareTo(BigDecimal) compareTo}
14.2664 + * method, {@code this} is returned.
14.2665 + * @see #compareTo(java.math.BigDecimal)
14.2666 + */
14.2667 + public BigDecimal min(BigDecimal val) {
14.2668 + return (compareTo(val) <= 0 ? this : val);
14.2669 + }
14.2670 +
14.2671 + /**
14.2672 + * Returns the maximum of this {@code BigDecimal} and {@code val}.
14.2673 + *
14.2674 + * @param val value with which the maximum is to be computed.
14.2675 + * @return the {@code BigDecimal} whose value is the greater of this
14.2676 + * {@code BigDecimal} and {@code val}. If they are equal,
14.2677 + * as defined by the {@link #compareTo(BigDecimal) compareTo}
14.2678 + * method, {@code this} is returned.
14.2679 + * @see #compareTo(java.math.BigDecimal)
14.2680 + */
14.2681 + public BigDecimal max(BigDecimal val) {
14.2682 + return (compareTo(val) >= 0 ? this : val);
14.2683 + }
14.2684 +
14.2685 + // Hash Function
14.2686 +
14.2687 + /**
14.2688 + * Returns the hash code for this {@code BigDecimal}. Note that
14.2689 + * two {@code BigDecimal} objects that are numerically equal but
14.2690 + * differ in scale (like 2.0 and 2.00) will generally <i>not</i>
14.2691 + * have the same hash code.
14.2692 + *
14.2693 + * @return hash code for this {@code BigDecimal}.
14.2694 + * @see #equals(Object)
14.2695 + */
14.2696 + @Override
14.2697 + public int hashCode() {
14.2698 + if (intCompact != INFLATED) {
14.2699 + long val2 = (intCompact < 0)? -intCompact : intCompact;
14.2700 + int temp = (int)( ((int)(val2 >>> 32)) * 31 +
14.2701 + (val2 & LONG_MASK));
14.2702 + return 31*((intCompact < 0) ?-temp:temp) + scale;
14.2703 + } else
14.2704 + return 31*intVal.hashCode() + scale;
14.2705 + }
14.2706 +
14.2707 + // Format Converters
14.2708 +
14.2709 + /**
14.2710 + * Returns the string representation of this {@code BigDecimal},
14.2711 + * using scientific notation if an exponent is needed.
14.2712 + *
14.2713 + * <p>A standard canonical string form of the {@code BigDecimal}
14.2714 + * is created as though by the following steps: first, the
14.2715 + * absolute value of the unscaled value of the {@code BigDecimal}
14.2716 + * is converted to a string in base ten using the characters
14.2717 + * {@code '0'} through {@code '9'} with no leading zeros (except
14.2718 + * if its value is zero, in which case a single {@code '0'}
14.2719 + * character is used).
14.2720 + *
14.2721 + * <p>Next, an <i>adjusted exponent</i> is calculated; this is the
14.2722 + * negated scale, plus the number of characters in the converted
14.2723 + * unscaled value, less one. That is,
14.2724 + * {@code -scale+(ulength-1)}, where {@code ulength} is the
14.2725 + * length of the absolute value of the unscaled value in decimal
14.2726 + * digits (its <i>precision</i>).
14.2727 + *
14.2728 + * <p>If the scale is greater than or equal to zero and the
14.2729 + * adjusted exponent is greater than or equal to {@code -6}, the
14.2730 + * number will be converted to a character form without using
14.2731 + * exponential notation. In this case, if the scale is zero then
14.2732 + * no decimal point is added and if the scale is positive a
14.2733 + * decimal point will be inserted with the scale specifying the
14.2734 + * number of characters to the right of the decimal point.
14.2735 + * {@code '0'} characters are added to the left of the converted
14.2736 + * unscaled value as necessary. If no character precedes the
14.2737 + * decimal point after this insertion then a conventional
14.2738 + * {@code '0'} character is prefixed.
14.2739 + *
14.2740 + * <p>Otherwise (that is, if the scale is negative, or the
14.2741 + * adjusted exponent is less than {@code -6}), the number will be
14.2742 + * converted to a character form using exponential notation. In
14.2743 + * this case, if the converted {@code BigInteger} has more than
14.2744 + * one digit a decimal point is inserted after the first digit.
14.2745 + * An exponent in character form is then suffixed to the converted
14.2746 + * unscaled value (perhaps with inserted decimal point); this
14.2747 + * comprises the letter {@code 'E'} followed immediately by the
14.2748 + * adjusted exponent converted to a character form. The latter is
14.2749 + * in base ten, using the characters {@code '0'} through
14.2750 + * {@code '9'} with no leading zeros, and is always prefixed by a
14.2751 + * sign character {@code '-'} (<tt>'\u002D'</tt>) if the
14.2752 + * adjusted exponent is negative, {@code '+'}
14.2753 + * (<tt>'\u002B'</tt>) otherwise).
14.2754 + *
14.2755 + * <p>Finally, the entire string is prefixed by a minus sign
14.2756 + * character {@code '-'} (<tt>'\u002D'</tt>) if the unscaled
14.2757 + * value is less than zero. No sign character is prefixed if the
14.2758 + * unscaled value is zero or positive.
14.2759 + *
14.2760 + * <p><b>Examples:</b>
14.2761 + * <p>For each representation [<i>unscaled value</i>, <i>scale</i>]
14.2762 + * on the left, the resulting string is shown on the right.
14.2763 + * <pre>
14.2764 + * [123,0] "123"
14.2765 + * [-123,0] "-123"
14.2766 + * [123,-1] "1.23E+3"
14.2767 + * [123,-3] "1.23E+5"
14.2768 + * [123,1] "12.3"
14.2769 + * [123,5] "0.00123"
14.2770 + * [123,10] "1.23E-8"
14.2771 + * [-123,12] "-1.23E-10"
14.2772 + * </pre>
14.2773 + *
14.2774 + * <b>Notes:</b>
14.2775 + * <ol>
14.2776 + *
14.2777 + * <li>There is a one-to-one mapping between the distinguishable
14.2778 + * {@code BigDecimal} values and the result of this conversion.
14.2779 + * That is, every distinguishable {@code BigDecimal} value
14.2780 + * (unscaled value and scale) has a unique string representation
14.2781 + * as a result of using {@code toString}. If that string
14.2782 + * representation is converted back to a {@code BigDecimal} using
14.2783 + * the {@link #BigDecimal(String)} constructor, then the original
14.2784 + * value will be recovered.
14.2785 + *
14.2786 + * <li>The string produced for a given number is always the same;
14.2787 + * it is not affected by locale. This means that it can be used
14.2788 + * as a canonical string representation for exchanging decimal
14.2789 + * data, or as a key for a Hashtable, etc. Locale-sensitive
14.2790 + * number formatting and parsing is handled by the {@link
14.2791 + * java.text.NumberFormat} class and its subclasses.
14.2792 + *
14.2793 + * <li>The {@link #toEngineeringString} method may be used for
14.2794 + * presenting numbers with exponents in engineering notation, and the
14.2795 + * {@link #setScale(int,RoundingMode) setScale} method may be used for
14.2796 + * rounding a {@code BigDecimal} so it has a known number of digits after
14.2797 + * the decimal point.
14.2798 + *
14.2799 + * <li>The digit-to-character mapping provided by
14.2800 + * {@code Character.forDigit} is used.
14.2801 + *
14.2802 + * </ol>
14.2803 + *
14.2804 + * @return string representation of this {@code BigDecimal}.
14.2805 + * @see Character#forDigit
14.2806 + * @see #BigDecimal(java.lang.String)
14.2807 + */
14.2808 + @Override
14.2809 + public String toString() {
14.2810 + String sc = stringCache;
14.2811 + if (sc == null)
14.2812 + stringCache = sc = layoutChars(true);
14.2813 + return sc;
14.2814 + }
14.2815 +
14.2816 + /**
14.2817 + * Returns a string representation of this {@code BigDecimal},
14.2818 + * using engineering notation if an exponent is needed.
14.2819 + *
14.2820 + * <p>Returns a string that represents the {@code BigDecimal} as
14.2821 + * described in the {@link #toString()} method, except that if
14.2822 + * exponential notation is used, the power of ten is adjusted to
14.2823 + * be a multiple of three (engineering notation) such that the
14.2824 + * integer part of nonzero values will be in the range 1 through
14.2825 + * 999. If exponential notation is used for zero values, a
14.2826 + * decimal point and one or two fractional zero digits are used so
14.2827 + * that the scale of the zero value is preserved. Note that
14.2828 + * unlike the output of {@link #toString()}, the output of this
14.2829 + * method is <em>not</em> guaranteed to recover the same [integer,
14.2830 + * scale] pair of this {@code BigDecimal} if the output string is
14.2831 + * converting back to a {@code BigDecimal} using the {@linkplain
14.2832 + * #BigDecimal(String) string constructor}. The result of this method meets
14.2833 + * the weaker constraint of always producing a numerically equal
14.2834 + * result from applying the string constructor to the method's output.
14.2835 + *
14.2836 + * @return string representation of this {@code BigDecimal}, using
14.2837 + * engineering notation if an exponent is needed.
14.2838 + * @since 1.5
14.2839 + */
14.2840 + public String toEngineeringString() {
14.2841 + return layoutChars(false);
14.2842 + }
14.2843 +
14.2844 + /**
14.2845 + * Returns a string representation of this {@code BigDecimal}
14.2846 + * without an exponent field. For values with a positive scale,
14.2847 + * the number of digits to the right of the decimal point is used
14.2848 + * to indicate scale. For values with a zero or negative scale,
14.2849 + * the resulting string is generated as if the value were
14.2850 + * converted to a numerically equal value with zero scale and as
14.2851 + * if all the trailing zeros of the zero scale value were present
14.2852 + * in the result.
14.2853 + *
14.2854 + * The entire string is prefixed by a minus sign character '-'
14.2855 + * (<tt>'\u002D'</tt>) if the unscaled value is less than
14.2856 + * zero. No sign character is prefixed if the unscaled value is
14.2857 + * zero or positive.
14.2858 + *
14.2859 + * Note that if the result of this method is passed to the
14.2860 + * {@linkplain #BigDecimal(String) string constructor}, only the
14.2861 + * numerical value of this {@code BigDecimal} will necessarily be
14.2862 + * recovered; the representation of the new {@code BigDecimal}
14.2863 + * may have a different scale. In particular, if this
14.2864 + * {@code BigDecimal} has a negative scale, the string resulting
14.2865 + * from this method will have a scale of zero when processed by
14.2866 + * the string constructor.
14.2867 + *
14.2868 + * (This method behaves analogously to the {@code toString}
14.2869 + * method in 1.4 and earlier releases.)
14.2870 + *
14.2871 + * @return a string representation of this {@code BigDecimal}
14.2872 + * without an exponent field.
14.2873 + * @since 1.5
14.2874 + * @see #toString()
14.2875 + * @see #toEngineeringString()
14.2876 + */
14.2877 + public String toPlainString() {
14.2878 + BigDecimal bd = this;
14.2879 + if (bd.scale < 0)
14.2880 + bd = bd.setScale(0);
14.2881 + bd.inflate();
14.2882 + if (bd.scale == 0) // No decimal point
14.2883 + return bd.intVal.toString();
14.2884 + return bd.getValueString(bd.signum(), bd.intVal.abs().toString(), bd.scale);
14.2885 + }
14.2886 +
14.2887 + /* Returns a digit.digit string */
14.2888 + private String getValueString(int signum, String intString, int scale) {
14.2889 + /* Insert decimal point */
14.2890 + StringBuilder buf;
14.2891 + int insertionPoint = intString.length() - scale;
14.2892 + if (insertionPoint == 0) { /* Point goes right before intVal */
14.2893 + return (signum<0 ? "-0." : "0.") + intString;
14.2894 + } else if (insertionPoint > 0) { /* Point goes inside intVal */
14.2895 + buf = new StringBuilder(intString);
14.2896 + buf.insert(insertionPoint, '.');
14.2897 + if (signum < 0)
14.2898 + buf.insert(0, '-');
14.2899 + } else { /* We must insert zeros between point and intVal */
14.2900 + buf = new StringBuilder(3-insertionPoint + intString.length());
14.2901 + buf.append(signum<0 ? "-0." : "0.");
14.2902 + for (int i=0; i<-insertionPoint; i++)
14.2903 + buf.append('0');
14.2904 + buf.append(intString);
14.2905 + }
14.2906 + return buf.toString();
14.2907 + }
14.2908 +
14.2909 + /**
14.2910 + * Converts this {@code BigDecimal} to a {@code BigInteger}.
14.2911 + * This conversion is analogous to the
14.2912 + * <i>narrowing primitive conversion</i> from {@code double} to
14.2913 + * {@code long} as defined in section 5.1.3 of
14.2914 + * <cite>The Java™ Language Specification</cite>:
14.2915 + * any fractional part of this
14.2916 + * {@code BigDecimal} will be discarded. Note that this
14.2917 + * conversion can lose information about the precision of the
14.2918 + * {@code BigDecimal} value.
14.2919 + * <p>
14.2920 + * To have an exception thrown if the conversion is inexact (in
14.2921 + * other words if a nonzero fractional part is discarded), use the
14.2922 + * {@link #toBigIntegerExact()} method.
14.2923 + *
14.2924 + * @return this {@code BigDecimal} converted to a {@code BigInteger}.
14.2925 + */
14.2926 + public BigInteger toBigInteger() {
14.2927 + // force to an integer, quietly
14.2928 + return this.setScale(0, ROUND_DOWN).inflate();
14.2929 + }
14.2930 +
14.2931 + /**
14.2932 + * Converts this {@code BigDecimal} to a {@code BigInteger},
14.2933 + * checking for lost information. An exception is thrown if this
14.2934 + * {@code BigDecimal} has a nonzero fractional part.
14.2935 + *
14.2936 + * @return this {@code BigDecimal} converted to a {@code BigInteger}.
14.2937 + * @throws ArithmeticException if {@code this} has a nonzero
14.2938 + * fractional part.
14.2939 + * @since 1.5
14.2940 + */
14.2941 + public BigInteger toBigIntegerExact() {
14.2942 + // round to an integer, with Exception if decimal part non-0
14.2943 + return this.setScale(0, ROUND_UNNECESSARY).inflate();
14.2944 + }
14.2945 +
14.2946 + /**
14.2947 + * Converts this {@code BigDecimal} to a {@code long}.
14.2948 + * This conversion is analogous to the
14.2949 + * <i>narrowing primitive conversion</i> from {@code double} to
14.2950 + * {@code short} as defined in section 5.1.3 of
14.2951 + * <cite>The Java™ Language Specification</cite>:
14.2952 + * any fractional part of this
14.2953 + * {@code BigDecimal} will be discarded, and if the resulting
14.2954 + * "{@code BigInteger}" is too big to fit in a
14.2955 + * {@code long}, only the low-order 64 bits are returned.
14.2956 + * Note that this conversion can lose information about the
14.2957 + * overall magnitude and precision of this {@code BigDecimal} value as well
14.2958 + * as return a result with the opposite sign.
14.2959 + *
14.2960 + * @return this {@code BigDecimal} converted to a {@code long}.
14.2961 + */
14.2962 + public long longValue(){
14.2963 + return (intCompact != INFLATED && scale == 0) ?
14.2964 + intCompact:
14.2965 + toBigInteger().longValue();
14.2966 + }
14.2967 +
14.2968 + /**
14.2969 + * Converts this {@code BigDecimal} to a {@code long}, checking
14.2970 + * for lost information. If this {@code BigDecimal} has a
14.2971 + * nonzero fractional part or is out of the possible range for a
14.2972 + * {@code long} result then an {@code ArithmeticException} is
14.2973 + * thrown.
14.2974 + *
14.2975 + * @return this {@code BigDecimal} converted to a {@code long}.
14.2976 + * @throws ArithmeticException if {@code this} has a nonzero
14.2977 + * fractional part, or will not fit in a {@code long}.
14.2978 + * @since 1.5
14.2979 + */
14.2980 + public long longValueExact() {
14.2981 + if (intCompact != INFLATED && scale == 0)
14.2982 + return intCompact;
14.2983 + // If more than 19 digits in integer part it cannot possibly fit
14.2984 + if ((precision() - scale) > 19) // [OK for negative scale too]
14.2985 + throw new java.lang.ArithmeticException("Overflow");
14.2986 + // Fastpath zero and < 1.0 numbers (the latter can be very slow
14.2987 + // to round if very small)
14.2988 + if (this.signum() == 0)
14.2989 + return 0;
14.2990 + if ((this.precision() - this.scale) <= 0)
14.2991 + throw new ArithmeticException("Rounding necessary");
14.2992 + // round to an integer, with Exception if decimal part non-0
14.2993 + BigDecimal num = this.setScale(0, ROUND_UNNECESSARY);
14.2994 + if (num.precision() >= 19) // need to check carefully
14.2995 + LongOverflow.check(num);
14.2996 + return num.inflate().longValue();
14.2997 + }
14.2998 +
14.2999 + private static class LongOverflow {
14.3000 + /** BigInteger equal to Long.MIN_VALUE. */
14.3001 + private static final BigInteger LONGMIN = BigInteger.valueOf(Long.MIN_VALUE);
14.3002 +
14.3003 + /** BigInteger equal to Long.MAX_VALUE. */
14.3004 + private static final BigInteger LONGMAX = BigInteger.valueOf(Long.MAX_VALUE);
14.3005 +
14.3006 + public static void check(BigDecimal num) {
14.3007 + num.inflate();
14.3008 + if ((num.intVal.compareTo(LONGMIN) < 0) ||
14.3009 + (num.intVal.compareTo(LONGMAX) > 0))
14.3010 + throw new java.lang.ArithmeticException("Overflow");
14.3011 + }
14.3012 + }
14.3013 +
14.3014 + /**
14.3015 + * Converts this {@code BigDecimal} to an {@code int}.
14.3016 + * This conversion is analogous to the
14.3017 + * <i>narrowing primitive conversion</i> from {@code double} to
14.3018 + * {@code short} as defined in section 5.1.3 of
14.3019 + * <cite>The Java™ Language Specification</cite>:
14.3020 + * any fractional part of this
14.3021 + * {@code BigDecimal} will be discarded, and if the resulting
14.3022 + * "{@code BigInteger}" is too big to fit in an
14.3023 + * {@code int}, only the low-order 32 bits are returned.
14.3024 + * Note that this conversion can lose information about the
14.3025 + * overall magnitude and precision of this {@code BigDecimal}
14.3026 + * value as well as return a result with the opposite sign.
14.3027 + *
14.3028 + * @return this {@code BigDecimal} converted to an {@code int}.
14.3029 + */
14.3030 + public int intValue() {
14.3031 + return (intCompact != INFLATED && scale == 0) ?
14.3032 + (int)intCompact :
14.3033 + toBigInteger().intValue();
14.3034 + }
14.3035 +
14.3036 + /**
14.3037 + * Converts this {@code BigDecimal} to an {@code int}, checking
14.3038 + * for lost information. If this {@code BigDecimal} has a
14.3039 + * nonzero fractional part or is out of the possible range for an
14.3040 + * {@code int} result then an {@code ArithmeticException} is
14.3041 + * thrown.
14.3042 + *
14.3043 + * @return this {@code BigDecimal} converted to an {@code int}.
14.3044 + * @throws ArithmeticException if {@code this} has a nonzero
14.3045 + * fractional part, or will not fit in an {@code int}.
14.3046 + * @since 1.5
14.3047 + */
14.3048 + public int intValueExact() {
14.3049 + long num;
14.3050 + num = this.longValueExact(); // will check decimal part
14.3051 + if ((int)num != num)
14.3052 + throw new java.lang.ArithmeticException("Overflow");
14.3053 + return (int)num;
14.3054 + }
14.3055 +
14.3056 + /**
14.3057 + * Converts this {@code BigDecimal} to a {@code short}, checking
14.3058 + * for lost information. If this {@code BigDecimal} has a
14.3059 + * nonzero fractional part or is out of the possible range for a
14.3060 + * {@code short} result then an {@code ArithmeticException} is
14.3061 + * thrown.
14.3062 + *
14.3063 + * @return this {@code BigDecimal} converted to a {@code short}.
14.3064 + * @throws ArithmeticException if {@code this} has a nonzero
14.3065 + * fractional part, or will not fit in a {@code short}.
14.3066 + * @since 1.5
14.3067 + */
14.3068 + public short shortValueExact() {
14.3069 + long num;
14.3070 + num = this.longValueExact(); // will check decimal part
14.3071 + if ((short)num != num)
14.3072 + throw new java.lang.ArithmeticException("Overflow");
14.3073 + return (short)num;
14.3074 + }
14.3075 +
14.3076 + /**
14.3077 + * Converts this {@code BigDecimal} to a {@code byte}, checking
14.3078 + * for lost information. If this {@code BigDecimal} has a
14.3079 + * nonzero fractional part or is out of the possible range for a
14.3080 + * {@code byte} result then an {@code ArithmeticException} is
14.3081 + * thrown.
14.3082 + *
14.3083 + * @return this {@code BigDecimal} converted to a {@code byte}.
14.3084 + * @throws ArithmeticException if {@code this} has a nonzero
14.3085 + * fractional part, or will not fit in a {@code byte}.
14.3086 + * @since 1.5
14.3087 + */
14.3088 + public byte byteValueExact() {
14.3089 + long num;
14.3090 + num = this.longValueExact(); // will check decimal part
14.3091 + if ((byte)num != num)
14.3092 + throw new java.lang.ArithmeticException("Overflow");
14.3093 + return (byte)num;
14.3094 + }
14.3095 +
14.3096 + /**
14.3097 + * Converts this {@code BigDecimal} to a {@code float}.
14.3098 + * This conversion is similar to the
14.3099 + * <i>narrowing primitive conversion</i> from {@code double} to
14.3100 + * {@code float} as defined in section 5.1.3 of
14.3101 + * <cite>The Java™ Language Specification</cite>:
14.3102 + * if this {@code BigDecimal} has too great a
14.3103 + * magnitude to represent as a {@code float}, it will be
14.3104 + * converted to {@link Float#NEGATIVE_INFINITY} or {@link
14.3105 + * Float#POSITIVE_INFINITY} as appropriate. Note that even when
14.3106 + * the return value is finite, this conversion can lose
14.3107 + * information about the precision of the {@code BigDecimal}
14.3108 + * value.
14.3109 + *
14.3110 + * @return this {@code BigDecimal} converted to a {@code float}.
14.3111 + */
14.3112 + public float floatValue(){
14.3113 + if (scale == 0 && intCompact != INFLATED)
14.3114 + return (float)intCompact;
14.3115 + // Somewhat inefficient, but guaranteed to work.
14.3116 + return Float.parseFloat(this.toString());
14.3117 + }
14.3118 +
14.3119 + /**
14.3120 + * Converts this {@code BigDecimal} to a {@code double}.
14.3121 + * This conversion is similar to the
14.3122 + * <i>narrowing primitive conversion</i> from {@code double} to
14.3123 + * {@code float} as defined in section 5.1.3 of
14.3124 + * <cite>The Java™ Language Specification</cite>:
14.3125 + * if this {@code BigDecimal} has too great a
14.3126 + * magnitude represent as a {@code double}, it will be
14.3127 + * converted to {@link Double#NEGATIVE_INFINITY} or {@link
14.3128 + * Double#POSITIVE_INFINITY} as appropriate. Note that even when
14.3129 + * the return value is finite, this conversion can lose
14.3130 + * information about the precision of the {@code BigDecimal}
14.3131 + * value.
14.3132 + *
14.3133 + * @return this {@code BigDecimal} converted to a {@code double}.
14.3134 + */
14.3135 + public double doubleValue(){
14.3136 + if (scale == 0 && intCompact != INFLATED)
14.3137 + return (double)intCompact;
14.3138 + // Somewhat inefficient, but guaranteed to work.
14.3139 + return Double.parseDouble(this.toString());
14.3140 + }
14.3141 +
14.3142 + /**
14.3143 + * Returns the size of an ulp, a unit in the last place, of this
14.3144 + * {@code BigDecimal}. An ulp of a nonzero {@code BigDecimal}
14.3145 + * value is the positive distance between this value and the
14.3146 + * {@code BigDecimal} value next larger in magnitude with the
14.3147 + * same number of digits. An ulp of a zero value is numerically
14.3148 + * equal to 1 with the scale of {@code this}. The result is
14.3149 + * stored with the same scale as {@code this} so the result
14.3150 + * for zero and nonzero values is equal to {@code [1,
14.3151 + * this.scale()]}.
14.3152 + *
14.3153 + * @return the size of an ulp of {@code this}
14.3154 + * @since 1.5
14.3155 + */
14.3156 + public BigDecimal ulp() {
14.3157 + return BigDecimal.valueOf(1, this.scale());
14.3158 + }
14.3159 +
14.3160 +
14.3161 + // Private class to build a string representation for BigDecimal object.
14.3162 + // "StringBuilderHelper" is constructed as a thread local variable so it is
14.3163 + // thread safe. The StringBuilder field acts as a buffer to hold the temporary
14.3164 + // representation of BigDecimal. The cmpCharArray holds all the characters for
14.3165 + // the compact representation of BigDecimal (except for '-' sign' if it is
14.3166 + // negative) if its intCompact field is not INFLATED. It is shared by all
14.3167 + // calls to toString() and its variants in that particular thread.
14.3168 + static class StringBuilderHelper {
14.3169 + final StringBuilder sb; // Placeholder for BigDecimal string
14.3170 + final char[] cmpCharArray; // character array to place the intCompact
14.3171 +
14.3172 + StringBuilderHelper() {
14.3173 + sb = new StringBuilder();
14.3174 + // All non negative longs can be made to fit into 19 character array.
14.3175 + cmpCharArray = new char[19];
14.3176 + }
14.3177 +
14.3178 + // Accessors.
14.3179 + StringBuilder getStringBuilder() {
14.3180 + sb.setLength(0);
14.3181 + return sb;
14.3182 + }
14.3183 +
14.3184 + char[] getCompactCharArray() {
14.3185 + return cmpCharArray;
14.3186 + }
14.3187 +
14.3188 + /**
14.3189 + * Places characters representing the intCompact in {@code long} into
14.3190 + * cmpCharArray and returns the offset to the array where the
14.3191 + * representation starts.
14.3192 + *
14.3193 + * @param intCompact the number to put into the cmpCharArray.
14.3194 + * @return offset to the array where the representation starts.
14.3195 + * Note: intCompact must be greater or equal to zero.
14.3196 + */
14.3197 + int putIntCompact(long intCompact) {
14.3198 + assert intCompact >= 0;
14.3199 +
14.3200 + long q;
14.3201 + int r;
14.3202 + // since we start from the least significant digit, charPos points to
14.3203 + // the last character in cmpCharArray.
14.3204 + int charPos = cmpCharArray.length;
14.3205 +
14.3206 + // Get 2 digits/iteration using longs until quotient fits into an int
14.3207 + while (intCompact > Integer.MAX_VALUE) {
14.3208 + q = intCompact / 100;
14.3209 + r = (int)(intCompact - q * 100);
14.3210 + intCompact = q;
14.3211 + cmpCharArray[--charPos] = DIGIT_ONES[r];
14.3212 + cmpCharArray[--charPos] = DIGIT_TENS[r];
14.3213 + }
14.3214 +
14.3215 + // Get 2 digits/iteration using ints when i2 >= 100
14.3216 + int q2;
14.3217 + int i2 = (int)intCompact;
14.3218 + while (i2 >= 100) {
14.3219 + q2 = i2 / 100;
14.3220 + r = i2 - q2 * 100;
14.3221 + i2 = q2;
14.3222 + cmpCharArray[--charPos] = DIGIT_ONES[r];
14.3223 + cmpCharArray[--charPos] = DIGIT_TENS[r];
14.3224 + }
14.3225 +
14.3226 + cmpCharArray[--charPos] = DIGIT_ONES[i2];
14.3227 + if (i2 >= 10)
14.3228 + cmpCharArray[--charPos] = DIGIT_TENS[i2];
14.3229 +
14.3230 + return charPos;
14.3231 + }
14.3232 +
14.3233 + final static char[] DIGIT_TENS = {
14.3234 + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
14.3235 + '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
14.3236 + '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
14.3237 + '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
14.3238 + '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
14.3239 + '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
14.3240 + '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
14.3241 + '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
14.3242 + '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
14.3243 + '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
14.3244 + };
14.3245 +
14.3246 + final static char[] DIGIT_ONES = {
14.3247 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3248 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3249 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3250 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3251 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3252 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3253 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3254 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3255 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3256 + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
14.3257 + };
14.3258 + }
14.3259 +
14.3260 + /**
14.3261 + * Lay out this {@code BigDecimal} into a {@code char[]} array.
14.3262 + * The Java 1.2 equivalent to this was called {@code getValueString}.
14.3263 + *
14.3264 + * @param sci {@code true} for Scientific exponential notation;
14.3265 + * {@code false} for Engineering
14.3266 + * @return string with canonical string representation of this
14.3267 + * {@code BigDecimal}
14.3268 + */
14.3269 + private String layoutChars(boolean sci) {
14.3270 + if (scale == 0) // zero scale is trivial
14.3271 + return (intCompact != INFLATED) ?
14.3272 + Long.toString(intCompact):
14.3273 + intVal.toString();
14.3274 +
14.3275 + StringBuilderHelper sbHelper = threadLocalStringBuilderHelper.get();
14.3276 + char[] coeff;
14.3277 + int offset; // offset is the starting index for coeff array
14.3278 + // Get the significand as an absolute value
14.3279 + if (intCompact != INFLATED) {
14.3280 + offset = sbHelper.putIntCompact(Math.abs(intCompact));
14.3281 + coeff = sbHelper.getCompactCharArray();
14.3282 + } else {
14.3283 + offset = 0;
14.3284 + coeff = intVal.abs().toString().toCharArray();
14.3285 + }
14.3286 +
14.3287 + // Construct a buffer, with sufficient capacity for all cases.
14.3288 + // If E-notation is needed, length will be: +1 if negative, +1
14.3289 + // if '.' needed, +2 for "E+", + up to 10 for adjusted exponent.
14.3290 + // Otherwise it could have +1 if negative, plus leading "0.00000"
14.3291 + StringBuilder buf = sbHelper.getStringBuilder();
14.3292 + if (signum() < 0) // prefix '-' if negative
14.3293 + buf.append('-');
14.3294 + int coeffLen = coeff.length - offset;
14.3295 + long adjusted = -(long)scale + (coeffLen -1);
14.3296 + if ((scale >= 0) && (adjusted >= -6)) { // plain number
14.3297 + int pad = scale - coeffLen; // count of padding zeros
14.3298 + if (pad >= 0) { // 0.xxx form
14.3299 + buf.append('0');
14.3300 + buf.append('.');
14.3301 + for (; pad>0; pad--) {
14.3302 + buf.append('0');
14.3303 + }
14.3304 + buf.append(coeff, offset, coeffLen);
14.3305 + } else { // xx.xx form
14.3306 + buf.append(coeff, offset, -pad);
14.3307 + buf.append('.');
14.3308 + buf.append(coeff, -pad + offset, scale);
14.3309 + }
14.3310 + } else { // E-notation is needed
14.3311 + if (sci) { // Scientific notation
14.3312 + buf.append(coeff[offset]); // first character
14.3313 + if (coeffLen > 1) { // more to come
14.3314 + buf.append('.');
14.3315 + buf.append(coeff, offset + 1, coeffLen - 1);
14.3316 + }
14.3317 + } else { // Engineering notation
14.3318 + int sig = (int)(adjusted % 3);
14.3319 + if (sig < 0)
14.3320 + sig += 3; // [adjusted was negative]
14.3321 + adjusted -= sig; // now a multiple of 3
14.3322 + sig++;
14.3323 + if (signum() == 0) {
14.3324 + switch (sig) {
14.3325 + case 1:
14.3326 + buf.append('0'); // exponent is a multiple of three
14.3327 + break;
14.3328 + case 2:
14.3329 + buf.append("0.00");
14.3330 + adjusted += 3;
14.3331 + break;
14.3332 + case 3:
14.3333 + buf.append("0.0");
14.3334 + adjusted += 3;
14.3335 + break;
14.3336 + default:
14.3337 + throw new AssertionError("Unexpected sig value " + sig);
14.3338 + }
14.3339 + } else if (sig >= coeffLen) { // significand all in integer
14.3340 + buf.append(coeff, offset, coeffLen);
14.3341 + // may need some zeros, too
14.3342 + for (int i = sig - coeffLen; i > 0; i--)
14.3343 + buf.append('0');
14.3344 + } else { // xx.xxE form
14.3345 + buf.append(coeff, offset, sig);
14.3346 + buf.append('.');
14.3347 + buf.append(coeff, offset + sig, coeffLen - sig);
14.3348 + }
14.3349 + }
14.3350 + if (adjusted != 0) { // [!sci could have made 0]
14.3351 + buf.append('E');
14.3352 + if (adjusted > 0) // force sign for positive
14.3353 + buf.append('+');
14.3354 + buf.append(adjusted);
14.3355 + }
14.3356 + }
14.3357 + return buf.toString();
14.3358 + }
14.3359 +
14.3360 + /**
14.3361 + * Return 10 to the power n, as a {@code BigInteger}.
14.3362 + *
14.3363 + * @param n the power of ten to be returned (>=0)
14.3364 + * @return a {@code BigInteger} with the value (10<sup>n</sup>)
14.3365 + */
14.3366 + private static BigInteger bigTenToThe(int n) {
14.3367 + if (n < 0)
14.3368 + return BigInteger.ZERO;
14.3369 +
14.3370 + if (n < BIG_TEN_POWERS_TABLE_MAX) {
14.3371 + BigInteger[] pows = BIG_TEN_POWERS_TABLE;
14.3372 + if (n < pows.length)
14.3373 + return pows[n];
14.3374 + else
14.3375 + return expandBigIntegerTenPowers(n);
14.3376 + }
14.3377 + // BigInteger.pow is slow, so make 10**n by constructing a
14.3378 + // BigInteger from a character string (still not very fast)
14.3379 + char tenpow[] = new char[n + 1];
14.3380 + tenpow[0] = '1';
14.3381 + for (int i = 1; i <= n; i++)
14.3382 + tenpow[i] = '0';
14.3383 + return new BigInteger(tenpow);
14.3384 + }
14.3385 +
14.3386 + /**
14.3387 + * Expand the BIG_TEN_POWERS_TABLE array to contain at least 10**n.
14.3388 + *
14.3389 + * @param n the power of ten to be returned (>=0)
14.3390 + * @return a {@code BigDecimal} with the value (10<sup>n</sup>) and
14.3391 + * in the meantime, the BIG_TEN_POWERS_TABLE array gets
14.3392 + * expanded to the size greater than n.
14.3393 + */
14.3394 + private static BigInteger expandBigIntegerTenPowers(int n) {
14.3395 + synchronized(BigDecimal.class) {
14.3396 + BigInteger[] pows = BIG_TEN_POWERS_TABLE;
14.3397 + int curLen = pows.length;
14.3398 + // The following comparison and the above synchronized statement is
14.3399 + // to prevent multiple threads from expanding the same array.
14.3400 + if (curLen <= n) {
14.3401 + int newLen = curLen << 1;
14.3402 + while (newLen <= n)
14.3403 + newLen <<= 1;
14.3404 + pows = Arrays.copyOf(pows, newLen);
14.3405 + for (int i = curLen; i < newLen; i++)
14.3406 + pows[i] = pows[i - 1].multiply(BigInteger.TEN);
14.3407 + // Based on the following facts:
14.3408 + // 1. pows is a private local varible;
14.3409 + // 2. the following store is a volatile store.
14.3410 + // the newly created array elements can be safely published.
14.3411 + BIG_TEN_POWERS_TABLE = pows;
14.3412 + }
14.3413 + return pows[n];
14.3414 + }
14.3415 + }
14.3416 +
14.3417 + private static final long[] LONG_TEN_POWERS_TABLE = {
14.3418 + 1, // 0 / 10^0
14.3419 + 10, // 1 / 10^1
14.3420 + 100, // 2 / 10^2
14.3421 + 1000, // 3 / 10^3
14.3422 + 10000, // 4 / 10^4
14.3423 + 100000, // 5 / 10^5
14.3424 + 1000000, // 6 / 10^6
14.3425 + 10000000, // 7 / 10^7
14.3426 + 100000000, // 8 / 10^8
14.3427 + 1000000000, // 9 / 10^9
14.3428 + 10000000000L, // 10 / 10^10
14.3429 + 100000000000L, // 11 / 10^11
14.3430 + 1000000000000L, // 12 / 10^12
14.3431 + 10000000000000L, // 13 / 10^13
14.3432 + 100000000000000L, // 14 / 10^14
14.3433 + 1000000000000000L, // 15 / 10^15
14.3434 + 10000000000000000L, // 16 / 10^16
14.3435 + 100000000000000000L, // 17 / 10^17
14.3436 + 1000000000000000000L // 18 / 10^18
14.3437 + };
14.3438 +
14.3439 + private static volatile BigInteger BIG_TEN_POWERS_TABLE[] = {BigInteger.ONE,
14.3440 + BigInteger.valueOf(10), BigInteger.valueOf(100),
14.3441 + BigInteger.valueOf(1000), BigInteger.valueOf(10000),
14.3442 + BigInteger.valueOf(100000), BigInteger.valueOf(1000000),
14.3443 + BigInteger.valueOf(10000000), BigInteger.valueOf(100000000),
14.3444 + BigInteger.valueOf(1000000000),
14.3445 + BigInteger.valueOf(10000000000L),
14.3446 + BigInteger.valueOf(100000000000L),
14.3447 + BigInteger.valueOf(1000000000000L),
14.3448 + BigInteger.valueOf(10000000000000L),
14.3449 + BigInteger.valueOf(100000000000000L),
14.3450 + BigInteger.valueOf(1000000000000000L),
14.3451 + BigInteger.valueOf(10000000000000000L),
14.3452 + BigInteger.valueOf(100000000000000000L),
14.3453 + BigInteger.valueOf(1000000000000000000L)
14.3454 + };
14.3455 +
14.3456 + private static final int BIG_TEN_POWERS_TABLE_INITLEN =
14.3457 + BIG_TEN_POWERS_TABLE.length;
14.3458 + private static final int BIG_TEN_POWERS_TABLE_MAX =
14.3459 + 16 * BIG_TEN_POWERS_TABLE_INITLEN;
14.3460 +
14.3461 + private static final long THRESHOLDS_TABLE[] = {
14.3462 + Long.MAX_VALUE, // 0
14.3463 + Long.MAX_VALUE/10L, // 1
14.3464 + Long.MAX_VALUE/100L, // 2
14.3465 + Long.MAX_VALUE/1000L, // 3
14.3466 + Long.MAX_VALUE/10000L, // 4
14.3467 + Long.MAX_VALUE/100000L, // 5
14.3468 + Long.MAX_VALUE/1000000L, // 6
14.3469 + Long.MAX_VALUE/10000000L, // 7
14.3470 + Long.MAX_VALUE/100000000L, // 8
14.3471 + Long.MAX_VALUE/1000000000L, // 9
14.3472 + Long.MAX_VALUE/10000000000L, // 10
14.3473 + Long.MAX_VALUE/100000000000L, // 11
14.3474 + Long.MAX_VALUE/1000000000000L, // 12
14.3475 + Long.MAX_VALUE/10000000000000L, // 13
14.3476 + Long.MAX_VALUE/100000000000000L, // 14
14.3477 + Long.MAX_VALUE/1000000000000000L, // 15
14.3478 + Long.MAX_VALUE/10000000000000000L, // 16
14.3479 + Long.MAX_VALUE/100000000000000000L, // 17
14.3480 + Long.MAX_VALUE/1000000000000000000L // 18
14.3481 + };
14.3482 +
14.3483 + /**
14.3484 + * Compute val * 10 ^ n; return this product if it is
14.3485 + * representable as a long, INFLATED otherwise.
14.3486 + */
14.3487 + private static long longMultiplyPowerTen(long val, int n) {
14.3488 + if (val == 0 || n <= 0)
14.3489 + return val;
14.3490 + long[] tab = LONG_TEN_POWERS_TABLE;
14.3491 + long[] bounds = THRESHOLDS_TABLE;
14.3492 + if (n < tab.length && n < bounds.length) {
14.3493 + long tenpower = tab[n];
14.3494 + if (val == 1)
14.3495 + return tenpower;
14.3496 + if (Math.abs(val) <= bounds[n])
14.3497 + return val * tenpower;
14.3498 + }
14.3499 + return INFLATED;
14.3500 + }
14.3501 +
14.3502 + /**
14.3503 + * Compute this * 10 ^ n.
14.3504 + * Needed mainly to allow special casing to trap zero value
14.3505 + */
14.3506 + private BigInteger bigMultiplyPowerTen(int n) {
14.3507 + if (n <= 0)
14.3508 + return this.inflate();
14.3509 +
14.3510 + if (intCompact != INFLATED)
14.3511 + return bigTenToThe(n).multiply(intCompact);
14.3512 + else
14.3513 + return intVal.multiply(bigTenToThe(n));
14.3514 + }
14.3515 +
14.3516 + /**
14.3517 + * Assign appropriate BigInteger to intVal field if intVal is
14.3518 + * null, i.e. the compact representation is in use.
14.3519 + */
14.3520 + private BigInteger inflate() {
14.3521 + if (intVal == null)
14.3522 + intVal = BigInteger.valueOf(intCompact);
14.3523 + return intVal;
14.3524 + }
14.3525 +
14.3526 + /**
14.3527 + * Match the scales of two {@code BigDecimal}s to align their
14.3528 + * least significant digits.
14.3529 + *
14.3530 + * <p>If the scales of val[0] and val[1] differ, rescale
14.3531 + * (non-destructively) the lower-scaled {@code BigDecimal} so
14.3532 + * they match. That is, the lower-scaled reference will be
14.3533 + * replaced by a reference to a new object with the same scale as
14.3534 + * the other {@code BigDecimal}.
14.3535 + *
14.3536 + * @param val array of two elements referring to the two
14.3537 + * {@code BigDecimal}s to be aligned.
14.3538 + */
14.3539 + private static void matchScale(BigDecimal[] val) {
14.3540 + if (val[0].scale == val[1].scale) {
14.3541 + return;
14.3542 + } else if (val[0].scale < val[1].scale) {
14.3543 + val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY);
14.3544 + } else if (val[1].scale < val[0].scale) {
14.3545 + val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY);
14.3546 + }
14.3547 + }
14.3548 +
14.3549 + /**
14.3550 + * Reconstitute the {@code BigDecimal} instance from a stream (that is,
14.3551 + * deserialize it).
14.3552 + *
14.3553 + * @param s the stream being read.
14.3554 + */
14.3555 + private void readObject(java.io.ObjectInputStream s)
14.3556 + throws java.io.IOException, ClassNotFoundException {
14.3557 + // Read in all fields
14.3558 + s.defaultReadObject();
14.3559 + // validate possibly bad fields
14.3560 + if (intVal == null) {
14.3561 + String message = "BigDecimal: null intVal in stream";
14.3562 + throw new java.io.StreamCorruptedException(message);
14.3563 + // [all values of scale are now allowed]
14.3564 + }
14.3565 + intCompact = compactValFor(intVal);
14.3566 + }
14.3567 +
14.3568 + /**
14.3569 + * Serialize this {@code BigDecimal} to the stream in question
14.3570 + *
14.3571 + * @param s the stream to serialize to.
14.3572 + */
14.3573 + private void writeObject(java.io.ObjectOutputStream s)
14.3574 + throws java.io.IOException {
14.3575 + // Must inflate to maintain compatible serial form.
14.3576 + this.inflate();
14.3577 +
14.3578 + // Write proper fields
14.3579 + s.defaultWriteObject();
14.3580 + }
14.3581 +
14.3582 +
14.3583 + /**
14.3584 + * Returns the length of the absolute value of a {@code long}, in decimal
14.3585 + * digits.
14.3586 + *
14.3587 + * @param x the {@code long}
14.3588 + * @return the length of the unscaled value, in deciaml digits.
14.3589 + */
14.3590 + private static int longDigitLength(long x) {
14.3591 + /*
14.3592 + * As described in "Bit Twiddling Hacks" by Sean Anderson,
14.3593 + * (http://graphics.stanford.edu/~seander/bithacks.html)
14.3594 + * integer log 10 of x is within 1 of
14.3595 + * (1233/4096)* (1 + integer log 2 of x).
14.3596 + * The fraction 1233/4096 approximates log10(2). So we first
14.3597 + * do a version of log2 (a variant of Long class with
14.3598 + * pre-checks and opposite directionality) and then scale and
14.3599 + * check against powers table. This is a little simpler in
14.3600 + * present context than the version in Hacker's Delight sec
14.3601 + * 11-4. Adding one to bit length allows comparing downward
14.3602 + * from the LONG_TEN_POWERS_TABLE that we need anyway.
14.3603 + */
14.3604 + assert x != INFLATED;
14.3605 + if (x < 0)
14.3606 + x = -x;
14.3607 + if (x < 10) // must screen for 0, might as well 10
14.3608 + return 1;
14.3609 + int n = 64; // not 63, to avoid needing to add 1 later
14.3610 + int y = (int)(x >>> 32);
14.3611 + if (y == 0) { n -= 32; y = (int)x; }
14.3612 + if (y >>> 16 == 0) { n -= 16; y <<= 16; }
14.3613 + if (y >>> 24 == 0) { n -= 8; y <<= 8; }
14.3614 + if (y >>> 28 == 0) { n -= 4; y <<= 4; }
14.3615 + if (y >>> 30 == 0) { n -= 2; y <<= 2; }
14.3616 + int r = (((y >>> 31) + n) * 1233) >>> 12;
14.3617 + long[] tab = LONG_TEN_POWERS_TABLE;
14.3618 + // if r >= length, must have max possible digits for long
14.3619 + return (r >= tab.length || x < tab[r])? r : r+1;
14.3620 + }
14.3621 +
14.3622 + /**
14.3623 + * Returns the length of the absolute value of a BigInteger, in
14.3624 + * decimal digits.
14.3625 + *
14.3626 + * @param b the BigInteger
14.3627 + * @return the length of the unscaled value, in decimal digits
14.3628 + */
14.3629 + private static int bigDigitLength(BigInteger b) {
14.3630 + /*
14.3631 + * Same idea as the long version, but we need a better
14.3632 + * approximation of log10(2). Using 646456993/2^31
14.3633 + * is accurate up to max possible reported bitLength.
14.3634 + */
14.3635 + if (b.signum == 0)
14.3636 + return 1;
14.3637 + int r = (int)((((long)b.bitLength() + 1) * 646456993) >>> 31);
14.3638 + return b.compareMagnitude(bigTenToThe(r)) < 0? r : r+1;
14.3639 + }
14.3640 +
14.3641 +
14.3642 + /**
14.3643 + * Remove insignificant trailing zeros from this
14.3644 + * {@code BigDecimal} until the preferred scale is reached or no
14.3645 + * more zeros can be removed. If the preferred scale is less than
14.3646 + * Integer.MIN_VALUE, all the trailing zeros will be removed.
14.3647 + *
14.3648 + * {@code BigInteger} assistance could help, here?
14.3649 + *
14.3650 + * <p>WARNING: This method should only be called on new objects as
14.3651 + * it mutates the value fields.
14.3652 + *
14.3653 + * @return this {@code BigDecimal} with a scale possibly reduced
14.3654 + * to be closed to the preferred scale.
14.3655 + */
14.3656 + private BigDecimal stripZerosToMatchScale(long preferredScale) {
14.3657 + this.inflate();
14.3658 + BigInteger qr[]; // quotient-remainder pair
14.3659 + while ( intVal.compareMagnitude(BigInteger.TEN) >= 0 &&
14.3660 + scale > preferredScale) {
14.3661 + if (intVal.testBit(0))
14.3662 + break; // odd number cannot end in 0
14.3663 + qr = intVal.divideAndRemainder(BigInteger.TEN);
14.3664 + if (qr[1].signum() != 0)
14.3665 + break; // non-0 remainder
14.3666 + intVal=qr[0];
14.3667 + scale = checkScale((long)scale-1); // could Overflow
14.3668 + if (precision > 0) // adjust precision if known
14.3669 + precision--;
14.3670 + }
14.3671 + if (intVal != null)
14.3672 + intCompact = compactValFor(intVal);
14.3673 + return this;
14.3674 + }
14.3675 +
14.3676 + /**
14.3677 + * Check a scale for Underflow or Overflow. If this BigDecimal is
14.3678 + * nonzero, throw an exception if the scale is outof range. If this
14.3679 + * is zero, saturate the scale to the extreme value of the right
14.3680 + * sign if the scale is out of range.
14.3681 + *
14.3682 + * @param val The new scale.
14.3683 + * @throws ArithmeticException (overflow or underflow) if the new
14.3684 + * scale is out of range.
14.3685 + * @return validated scale as an int.
14.3686 + */
14.3687 + private int checkScale(long val) {
14.3688 + int asInt = (int)val;
14.3689 + if (asInt != val) {
14.3690 + asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
14.3691 + BigInteger b;
14.3692 + if (intCompact != 0 &&
14.3693 + ((b = intVal) == null || b.signum() != 0))
14.3694 + throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
14.3695 + }
14.3696 + return asInt;
14.3697 + }
14.3698 +
14.3699 + /**
14.3700 + * Round an operand; used only if digits > 0. Does not change
14.3701 + * {@code this}; if rounding is needed a new {@code BigDecimal}
14.3702 + * is created and returned.
14.3703 + *
14.3704 + * @param mc the context to use.
14.3705 + * @throws ArithmeticException if the result is inexact but the
14.3706 + * rounding mode is {@code UNNECESSARY}.
14.3707 + */
14.3708 + private BigDecimal roundOp(MathContext mc) {
14.3709 + BigDecimal rounded = doRound(this, mc);
14.3710 + return rounded;
14.3711 + }
14.3712 +
14.3713 + /** Round this BigDecimal according to the MathContext settings;
14.3714 + * used only if precision {@literal >} 0.
14.3715 + *
14.3716 + * <p>WARNING: This method should only be called on new objects as
14.3717 + * it mutates the value fields.
14.3718 + *
14.3719 + * @param mc the context to use.
14.3720 + * @throws ArithmeticException if the rounding mode is
14.3721 + * {@code RoundingMode.UNNECESSARY} and the
14.3722 + * {@code BigDecimal} operation would require rounding.
14.3723 + */
14.3724 + private void roundThis(MathContext mc) {
14.3725 + BigDecimal rounded = doRound(this, mc);
14.3726 + if (rounded == this) // wasn't rounded
14.3727 + return;
14.3728 + this.intVal = rounded.intVal;
14.3729 + this.intCompact = rounded.intCompact;
14.3730 + this.scale = rounded.scale;
14.3731 + this.precision = rounded.precision;
14.3732 + }
14.3733 +
14.3734 + /**
14.3735 + * Returns a {@code BigDecimal} rounded according to the
14.3736 + * MathContext settings; used only if {@code mc.precision > 0}.
14.3737 + * Does not change {@code this}; if rounding is needed a new
14.3738 + * {@code BigDecimal} is created and returned.
14.3739 + *
14.3740 + * @param mc the context to use.
14.3741 + * @return a {@code BigDecimal} rounded according to the MathContext
14.3742 + * settings. May return this, if no rounding needed.
14.3743 + * @throws ArithmeticException if the rounding mode is
14.3744 + * {@code RoundingMode.UNNECESSARY} and the
14.3745 + * result is inexact.
14.3746 + */
14.3747 + private static BigDecimal doRound(BigDecimal d, MathContext mc) {
14.3748 + int mcp = mc.precision;
14.3749 + int drop;
14.3750 + // This might (rarely) iterate to cover the 999=>1000 case
14.3751 + while ((drop = d.precision() - mcp) > 0) {
14.3752 + int newScale = d.checkScale((long)d.scale - drop);
14.3753 + int mode = mc.roundingMode.oldMode;
14.3754 + if (drop < LONG_TEN_POWERS_TABLE.length)
14.3755 + d = divideAndRound(d.intCompact, d.intVal,
14.3756 + LONG_TEN_POWERS_TABLE[drop], null,
14.3757 + newScale, mode, newScale);
14.3758 + else
14.3759 + d = divideAndRound(d.intCompact, d.intVal,
14.3760 + INFLATED, bigTenToThe(drop),
14.3761 + newScale, mode, newScale);
14.3762 + }
14.3763 + return d;
14.3764 + }
14.3765 +
14.3766 + /**
14.3767 + * Returns the compact value for given {@code BigInteger}, or
14.3768 + * INFLATED if too big. Relies on internal representation of
14.3769 + * {@code BigInteger}.
14.3770 + */
14.3771 + private static long compactValFor(BigInteger b) {
14.3772 + int[] m = b.mag;
14.3773 + int len = m.length;
14.3774 + if (len == 0)
14.3775 + return 0;
14.3776 + int d = m[0];
14.3777 + if (len > 2 || (len == 2 && d < 0))
14.3778 + return INFLATED;
14.3779 +
14.3780 + long u = (len == 2)?
14.3781 + (((long) m[1] & LONG_MASK) + (((long)d) << 32)) :
14.3782 + (((long)d) & LONG_MASK);
14.3783 + return (b.signum < 0)? -u : u;
14.3784 + }
14.3785 +
14.3786 + private static int longCompareMagnitude(long x, long y) {
14.3787 + if (x < 0)
14.3788 + x = -x;
14.3789 + if (y < 0)
14.3790 + y = -y;
14.3791 + return (x < y) ? -1 : ((x == y) ? 0 : 1);
14.3792 + }
14.3793 +
14.3794 + private static int saturateLong(long s) {
14.3795 + int i = (int)s;
14.3796 + return (s == i) ? i : (s < 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE);
14.3797 + }
14.3798 +
14.3799 + /*
14.3800 + * Internal printing routine
14.3801 + */
14.3802 + private static void print(String name, BigDecimal bd) {
14.3803 + System.err.format("%s:\tintCompact %d\tintVal %d\tscale %d\tprecision %d%n",
14.3804 + name,
14.3805 + bd.intCompact,
14.3806 + bd.intVal,
14.3807 + bd.scale,
14.3808 + bd.precision);
14.3809 + }
14.3810 +
14.3811 + /**
14.3812 + * Check internal invariants of this BigDecimal. These invariants
14.3813 + * include:
14.3814 + *
14.3815 + * <ul>
14.3816 + *
14.3817 + * <li>The object must be initialized; either intCompact must not be
14.3818 + * INFLATED or intVal is non-null. Both of these conditions may
14.3819 + * be true.
14.3820 + *
14.3821 + * <li>If both intCompact and intVal and set, their values must be
14.3822 + * consistent.
14.3823 + *
14.3824 + * <li>If precision is nonzero, it must have the right value.
14.3825 + * </ul>
14.3826 + *
14.3827 + * Note: Since this is an audit method, we are not supposed to change the
14.3828 + * state of this BigDecimal object.
14.3829 + */
14.3830 + private BigDecimal audit() {
14.3831 + if (intCompact == INFLATED) {
14.3832 + if (intVal == null) {
14.3833 + print("audit", this);
14.3834 + throw new AssertionError("null intVal");
14.3835 + }
14.3836 + // Check precision
14.3837 + if (precision > 0 && precision != bigDigitLength(intVal)) {
14.3838 + print("audit", this);
14.3839 + throw new AssertionError("precision mismatch");
14.3840 + }
14.3841 + } else {
14.3842 + if (intVal != null) {
14.3843 + long val = intVal.longValue();
14.3844 + if (val != intCompact) {
14.3845 + print("audit", this);
14.3846 + throw new AssertionError("Inconsistent state, intCompact=" +
14.3847 + intCompact + "\t intVal=" + val);
14.3848 + }
14.3849 + }
14.3850 + // Check precision
14.3851 + if (precision > 0 && precision != longDigitLength(intCompact)) {
14.3852 + print("audit", this);
14.3853 + throw new AssertionError("precision mismatch");
14.3854 + }
14.3855 + }
14.3856 + return this;
14.3857 + }
14.3858 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/emul/compact/src/main/java/java/math/BigInteger.java Sat Sep 07 13:51:24 2013 +0200
15.3 @@ -0,0 +1,3186 @@
15.4 +/*
15.5 + * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.7 + *
15.8 + * This code is free software; you can redistribute it and/or modify it
15.9 + * under the terms of the GNU General Public License version 2 only, as
15.10 + * published by the Free Software Foundation. Oracle designates this
15.11 + * particular file as subject to the "Classpath" exception as provided
15.12 + * by Oracle in the LICENSE file that accompanied this code.
15.13 + *
15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15.17 + * version 2 for more details (a copy is included in the LICENSE file that
15.18 + * accompanied this code).
15.19 + *
15.20 + * You should have received a copy of the GNU General Public License version
15.21 + * 2 along with this work; if not, write to the Free Software Foundation,
15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
15.23 + *
15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
15.25 + * or visit www.oracle.com if you need additional information or have any
15.26 + * questions.
15.27 + */
15.28 +
15.29 +/*
15.30 + * Portions Copyright (c) 1995 Colin Plumb. All rights reserved.
15.31 + */
15.32 +
15.33 +package java.math;
15.34 +
15.35 +import java.util.Random;
15.36 +import java.io.*;
15.37 +
15.38 +/**
15.39 + * Immutable arbitrary-precision integers. All operations behave as if
15.40 + * BigIntegers were represented in two's-complement notation (like Java's
15.41 + * primitive integer types). BigInteger provides analogues to all of Java's
15.42 + * primitive integer operators, and all relevant methods from java.lang.Math.
15.43 + * Additionally, BigInteger provides operations for modular arithmetic, GCD
15.44 + * calculation, primality testing, prime generation, bit manipulation,
15.45 + * and a few other miscellaneous operations.
15.46 + *
15.47 + * <p>Semantics of arithmetic operations exactly mimic those of Java's integer
15.48 + * arithmetic operators, as defined in <i>The Java Language Specification</i>.
15.49 + * For example, division by zero throws an {@code ArithmeticException}, and
15.50 + * division of a negative by a positive yields a negative (or zero) remainder.
15.51 + * All of the details in the Spec concerning overflow are ignored, as
15.52 + * BigIntegers are made as large as necessary to accommodate the results of an
15.53 + * operation.
15.54 + *
15.55 + * <p>Semantics of shift operations extend those of Java's shift operators
15.56 + * to allow for negative shift distances. A right-shift with a negative
15.57 + * shift distance results in a left shift, and vice-versa. The unsigned
15.58 + * right shift operator ({@code >>>}) is omitted, as this operation makes
15.59 + * little sense in combination with the "infinite word size" abstraction
15.60 + * provided by this class.
15.61 + *
15.62 + * <p>Semantics of bitwise logical operations exactly mimic those of Java's
15.63 + * bitwise integer operators. The binary operators ({@code and},
15.64 + * {@code or}, {@code xor}) implicitly perform sign extension on the shorter
15.65 + * of the two operands prior to performing the operation.
15.66 + *
15.67 + * <p>Comparison operations perform signed integer comparisons, analogous to
15.68 + * those performed by Java's relational and equality operators.
15.69 + *
15.70 + * <p>Modular arithmetic operations are provided to compute residues, perform
15.71 + * exponentiation, and compute multiplicative inverses. These methods always
15.72 + * return a non-negative result, between {@code 0} and {@code (modulus - 1)},
15.73 + * inclusive.
15.74 + *
15.75 + * <p>Bit operations operate on a single bit of the two's-complement
15.76 + * representation of their operand. If necessary, the operand is sign-
15.77 + * extended so that it contains the designated bit. None of the single-bit
15.78 + * operations can produce a BigInteger with a different sign from the
15.79 + * BigInteger being operated on, as they affect only a single bit, and the
15.80 + * "infinite word size" abstraction provided by this class ensures that there
15.81 + * are infinitely many "virtual sign bits" preceding each BigInteger.
15.82 + *
15.83 + * <p>For the sake of brevity and clarity, pseudo-code is used throughout the
15.84 + * descriptions of BigInteger methods. The pseudo-code expression
15.85 + * {@code (i + j)} is shorthand for "a BigInteger whose value is
15.86 + * that of the BigInteger {@code i} plus that of the BigInteger {@code j}."
15.87 + * The pseudo-code expression {@code (i == j)} is shorthand for
15.88 + * "{@code true} if and only if the BigInteger {@code i} represents the same
15.89 + * value as the BigInteger {@code j}." Other pseudo-code expressions are
15.90 + * interpreted similarly.
15.91 + *
15.92 + * <p>All methods and constructors in this class throw
15.93 + * {@code NullPointerException} when passed
15.94 + * a null object reference for any input parameter.
15.95 + *
15.96 + * @see BigDecimal
15.97 + * @author Josh Bloch
15.98 + * @author Michael McCloskey
15.99 + * @since JDK1.1
15.100 + */
15.101 +
15.102 +public class BigInteger extends Number implements Comparable<BigInteger> {
15.103 + /**
15.104 + * The signum of this BigInteger: -1 for negative, 0 for zero, or
15.105 + * 1 for positive. Note that the BigInteger zero <i>must</i> have
15.106 + * a signum of 0. This is necessary to ensures that there is exactly one
15.107 + * representation for each BigInteger value.
15.108 + *
15.109 + * @serial
15.110 + */
15.111 + final int signum;
15.112 +
15.113 + /**
15.114 + * The magnitude of this BigInteger, in <i>big-endian</i> order: the
15.115 + * zeroth element of this array is the most-significant int of the
15.116 + * magnitude. The magnitude must be "minimal" in that the most-significant
15.117 + * int ({@code mag[0]}) must be non-zero. This is necessary to
15.118 + * ensure that there is exactly one representation for each BigInteger
15.119 + * value. Note that this implies that the BigInteger zero has a
15.120 + * zero-length mag array.
15.121 + */
15.122 + final int[] mag;
15.123 +
15.124 + // These "redundant fields" are initialized with recognizable nonsense
15.125 + // values, and cached the first time they are needed (or never, if they
15.126 + // aren't needed).
15.127 +
15.128 + /**
15.129 + * One plus the bitCount of this BigInteger. Zeros means unitialized.
15.130 + *
15.131 + * @serial
15.132 + * @see #bitCount
15.133 + * @deprecated Deprecated since logical value is offset from stored
15.134 + * value and correction factor is applied in accessor method.
15.135 + */
15.136 + @Deprecated
15.137 + private int bitCount;
15.138 +
15.139 + /**
15.140 + * One plus the bitLength of this BigInteger. Zeros means unitialized.
15.141 + * (either value is acceptable).
15.142 + *
15.143 + * @serial
15.144 + * @see #bitLength()
15.145 + * @deprecated Deprecated since logical value is offset from stored
15.146 + * value and correction factor is applied in accessor method.
15.147 + */
15.148 + @Deprecated
15.149 + private int bitLength;
15.150 +
15.151 + /**
15.152 + * Two plus the lowest set bit of this BigInteger, as returned by
15.153 + * getLowestSetBit().
15.154 + *
15.155 + * @serial
15.156 + * @see #getLowestSetBit
15.157 + * @deprecated Deprecated since logical value is offset from stored
15.158 + * value and correction factor is applied in accessor method.
15.159 + */
15.160 + @Deprecated
15.161 + private int lowestSetBit;
15.162 +
15.163 + /**
15.164 + * Two plus the index of the lowest-order int in the magnitude of this
15.165 + * BigInteger that contains a nonzero int, or -2 (either value is acceptable).
15.166 + * The least significant int has int-number 0, the next int in order of
15.167 + * increasing significance has int-number 1, and so forth.
15.168 + * @deprecated Deprecated since logical value is offset from stored
15.169 + * value and correction factor is applied in accessor method.
15.170 + */
15.171 + @Deprecated
15.172 + private int firstNonzeroIntNum;
15.173 +
15.174 + /**
15.175 + * This mask is used to obtain the value of an int as if it were unsigned.
15.176 + */
15.177 + final static long LONG_MASK = 0xffffffffL;
15.178 +
15.179 + //Constructors
15.180 +
15.181 + /**
15.182 + * Translates a byte array containing the two's-complement binary
15.183 + * representation of a BigInteger into a BigInteger. The input array is
15.184 + * assumed to be in <i>big-endian</i> byte-order: the most significant
15.185 + * byte is in the zeroth element.
15.186 + *
15.187 + * @param val big-endian two's-complement binary representation of
15.188 + * BigInteger.
15.189 + * @throws NumberFormatException {@code val} is zero bytes long.
15.190 + */
15.191 + public BigInteger(byte[] val) {
15.192 + if (val.length == 0)
15.193 + throw new NumberFormatException("Zero length BigInteger");
15.194 +
15.195 + if (val[0] < 0) {
15.196 + mag = makePositive(val);
15.197 + signum = -1;
15.198 + } else {
15.199 + mag = stripLeadingZeroBytes(val);
15.200 + signum = (mag.length == 0 ? 0 : 1);
15.201 + }
15.202 + }
15.203 +
15.204 + /**
15.205 + * This private constructor translates an int array containing the
15.206 + * two's-complement binary representation of a BigInteger into a
15.207 + * BigInteger. The input array is assumed to be in <i>big-endian</i>
15.208 + * int-order: the most significant int is in the zeroth element.
15.209 + */
15.210 + private BigInteger(int[] val) {
15.211 + if (val.length == 0)
15.212 + throw new NumberFormatException("Zero length BigInteger");
15.213 +
15.214 + if (val[0] < 0) {
15.215 + mag = makePositive(val);
15.216 + signum = -1;
15.217 + } else {
15.218 + mag = trustedStripLeadingZeroInts(val);
15.219 + signum = (mag.length == 0 ? 0 : 1);
15.220 + }
15.221 + }
15.222 +
15.223 + /**
15.224 + * Translates the sign-magnitude representation of a BigInteger into a
15.225 + * BigInteger. The sign is represented as an integer signum value: -1 for
15.226 + * negative, 0 for zero, or 1 for positive. The magnitude is a byte array
15.227 + * in <i>big-endian</i> byte-order: the most significant byte is in the
15.228 + * zeroth element. A zero-length magnitude array is permissible, and will
15.229 + * result in a BigInteger value of 0, whether signum is -1, 0 or 1.
15.230 + *
15.231 + * @param signum signum of the number (-1 for negative, 0 for zero, 1
15.232 + * for positive).
15.233 + * @param magnitude big-endian binary representation of the magnitude of
15.234 + * the number.
15.235 + * @throws NumberFormatException {@code signum} is not one of the three
15.236 + * legal values (-1, 0, and 1), or {@code signum} is 0 and
15.237 + * {@code magnitude} contains one or more non-zero bytes.
15.238 + */
15.239 + public BigInteger(int signum, byte[] magnitude) {
15.240 + this.mag = stripLeadingZeroBytes(magnitude);
15.241 +
15.242 + if (signum < -1 || signum > 1)
15.243 + throw(new NumberFormatException("Invalid signum value"));
15.244 +
15.245 + if (this.mag.length==0) {
15.246 + this.signum = 0;
15.247 + } else {
15.248 + if (signum == 0)
15.249 + throw(new NumberFormatException("signum-magnitude mismatch"));
15.250 + this.signum = signum;
15.251 + }
15.252 + }
15.253 +
15.254 + /**
15.255 + * A constructor for internal use that translates the sign-magnitude
15.256 + * representation of a BigInteger into a BigInteger. It checks the
15.257 + * arguments and copies the magnitude so this constructor would be
15.258 + * safe for external use.
15.259 + */
15.260 + private BigInteger(int signum, int[] magnitude) {
15.261 + this.mag = stripLeadingZeroInts(magnitude);
15.262 +
15.263 + if (signum < -1 || signum > 1)
15.264 + throw(new NumberFormatException("Invalid signum value"));
15.265 +
15.266 + if (this.mag.length==0) {
15.267 + this.signum = 0;
15.268 + } else {
15.269 + if (signum == 0)
15.270 + throw(new NumberFormatException("signum-magnitude mismatch"));
15.271 + this.signum = signum;
15.272 + }
15.273 + }
15.274 +
15.275 + /**
15.276 + * Translates the String representation of a BigInteger in the
15.277 + * specified radix into a BigInteger. The String representation
15.278 + * consists of an optional minus or plus sign followed by a
15.279 + * sequence of one or more digits in the specified radix. The
15.280 + * character-to-digit mapping is provided by {@code
15.281 + * Character.digit}. The String may not contain any extraneous
15.282 + * characters (whitespace, for example).
15.283 + *
15.284 + * @param val String representation of BigInteger.
15.285 + * @param radix radix to be used in interpreting {@code val}.
15.286 + * @throws NumberFormatException {@code val} is not a valid representation
15.287 + * of a BigInteger in the specified radix, or {@code radix} is
15.288 + * outside the range from {@link Character#MIN_RADIX} to
15.289 + * {@link Character#MAX_RADIX}, inclusive.
15.290 + * @see Character#digit
15.291 + */
15.292 + public BigInteger(String val, int radix) {
15.293 + int cursor = 0, numDigits;
15.294 + final int len = val.length();
15.295 +
15.296 + if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
15.297 + throw new NumberFormatException("Radix out of range");
15.298 + if (len == 0)
15.299 + throw new NumberFormatException("Zero length BigInteger");
15.300 +
15.301 + // Check for at most one leading sign
15.302 + int sign = 1;
15.303 + int index1 = val.lastIndexOf('-');
15.304 + int index2 = val.lastIndexOf('+');
15.305 + if ((index1 + index2) <= -1) {
15.306 + // No leading sign character or at most one leading sign character
15.307 + if (index1 == 0 || index2 == 0) {
15.308 + cursor = 1;
15.309 + if (len == 1)
15.310 + throw new NumberFormatException("Zero length BigInteger");
15.311 + }
15.312 + if (index1 == 0)
15.313 + sign = -1;
15.314 + } else
15.315 + throw new NumberFormatException("Illegal embedded sign character");
15.316 +
15.317 + // Skip leading zeros and compute number of digits in magnitude
15.318 + while (cursor < len &&
15.319 + Character.digit(val.charAt(cursor), radix) == 0)
15.320 + cursor++;
15.321 + if (cursor == len) {
15.322 + signum = 0;
15.323 + mag = ZERO.mag;
15.324 + return;
15.325 + }
15.326 +
15.327 + numDigits = len - cursor;
15.328 + signum = sign;
15.329 +
15.330 + // Pre-allocate array of expected size. May be too large but can
15.331 + // never be too small. Typically exact.
15.332 + int numBits = (int)(((numDigits * bitsPerDigit[radix]) >>> 10) + 1);
15.333 + int numWords = (numBits + 31) >>> 5;
15.334 + int[] magnitude = new int[numWords];
15.335 +
15.336 + // Process first (potentially short) digit group
15.337 + int firstGroupLen = numDigits % digitsPerInt[radix];
15.338 + if (firstGroupLen == 0)
15.339 + firstGroupLen = digitsPerInt[radix];
15.340 + String group = val.substring(cursor, cursor += firstGroupLen);
15.341 + magnitude[numWords - 1] = Integer.parseInt(group, radix);
15.342 + if (magnitude[numWords - 1] < 0)
15.343 + throw new NumberFormatException("Illegal digit");
15.344 +
15.345 + // Process remaining digit groups
15.346 + int superRadix = intRadix[radix];
15.347 + int groupVal = 0;
15.348 + while (cursor < len) {
15.349 + group = val.substring(cursor, cursor += digitsPerInt[radix]);
15.350 + groupVal = Integer.parseInt(group, radix);
15.351 + if (groupVal < 0)
15.352 + throw new NumberFormatException("Illegal digit");
15.353 + destructiveMulAdd(magnitude, superRadix, groupVal);
15.354 + }
15.355 + // Required for cases where the array was overallocated.
15.356 + mag = trustedStripLeadingZeroInts(magnitude);
15.357 + }
15.358 +
15.359 + // Constructs a new BigInteger using a char array with radix=10
15.360 + BigInteger(char[] val) {
15.361 + int cursor = 0, numDigits;
15.362 + int len = val.length;
15.363 +
15.364 + // Check for leading minus sign
15.365 + int sign = 1;
15.366 + if (val[0] == '-') {
15.367 + if (len == 1)
15.368 + throw new NumberFormatException("Zero length BigInteger");
15.369 + sign = -1;
15.370 + cursor = 1;
15.371 + } else if (val[0] == '+') {
15.372 + if (len == 1)
15.373 + throw new NumberFormatException("Zero length BigInteger");
15.374 + cursor = 1;
15.375 + }
15.376 +
15.377 + // Skip leading zeros and compute number of digits in magnitude
15.378 + while (cursor < len && Character.digit(val[cursor], 10) == 0)
15.379 + cursor++;
15.380 + if (cursor == len) {
15.381 + signum = 0;
15.382 + mag = ZERO.mag;
15.383 + return;
15.384 + }
15.385 +
15.386 + numDigits = len - cursor;
15.387 + signum = sign;
15.388 +
15.389 + // Pre-allocate array of expected size
15.390 + int numWords;
15.391 + if (len < 10) {
15.392 + numWords = 1;
15.393 + } else {
15.394 + int numBits = (int)(((numDigits * bitsPerDigit[10]) >>> 10) + 1);
15.395 + numWords = (numBits + 31) >>> 5;
15.396 + }
15.397 + int[] magnitude = new int[numWords];
15.398 +
15.399 + // Process first (potentially short) digit group
15.400 + int firstGroupLen = numDigits % digitsPerInt[10];
15.401 + if (firstGroupLen == 0)
15.402 + firstGroupLen = digitsPerInt[10];
15.403 + magnitude[numWords - 1] = parseInt(val, cursor, cursor += firstGroupLen);
15.404 +
15.405 + // Process remaining digit groups
15.406 + while (cursor < len) {
15.407 + int groupVal = parseInt(val, cursor, cursor += digitsPerInt[10]);
15.408 + destructiveMulAdd(magnitude, intRadix[10], groupVal);
15.409 + }
15.410 + mag = trustedStripLeadingZeroInts(magnitude);
15.411 + }
15.412 +
15.413 + // Create an integer with the digits between the two indexes
15.414 + // Assumes start < end. The result may be negative, but it
15.415 + // is to be treated as an unsigned value.
15.416 + private int parseInt(char[] source, int start, int end) {
15.417 + int result = Character.digit(source[start++], 10);
15.418 + if (result == -1)
15.419 + throw new NumberFormatException(new String(source));
15.420 +
15.421 + for (int index = start; index<end; index++) {
15.422 + int nextVal = Character.digit(source[index], 10);
15.423 + if (nextVal == -1)
15.424 + throw new NumberFormatException(new String(source));
15.425 + result = 10*result + nextVal;
15.426 + }
15.427 +
15.428 + return result;
15.429 + }
15.430 +
15.431 + // bitsPerDigit in the given radix times 1024
15.432 + // Rounded up to avoid underallocation.
15.433 + private static long bitsPerDigit[] = { 0, 0,
15.434 + 1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,
15.435 + 3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,
15.436 + 4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,
15.437 + 5253, 5295};
15.438 +
15.439 + // Multiply x array times word y in place, and add word z
15.440 + private static void destructiveMulAdd(int[] x, int y, int z) {
15.441 + // Perform the multiplication word by word
15.442 + long ylong = y & LONG_MASK;
15.443 + long zlong = z & LONG_MASK;
15.444 + int len = x.length;
15.445 +
15.446 + long product = 0;
15.447 + long carry = 0;
15.448 + for (int i = len-1; i >= 0; i--) {
15.449 + product = ylong * (x[i] & LONG_MASK) + carry;
15.450 + x[i] = (int)product;
15.451 + carry = product >>> 32;
15.452 + }
15.453 +
15.454 + // Perform the addition
15.455 + long sum = (x[len-1] & LONG_MASK) + zlong;
15.456 + x[len-1] = (int)sum;
15.457 + carry = sum >>> 32;
15.458 + for (int i = len-2; i >= 0; i--) {
15.459 + sum = (x[i] & LONG_MASK) + carry;
15.460 + x[i] = (int)sum;
15.461 + carry = sum >>> 32;
15.462 + }
15.463 + }
15.464 +
15.465 + /**
15.466 + * Translates the decimal String representation of a BigInteger into a
15.467 + * BigInteger. The String representation consists of an optional minus
15.468 + * sign followed by a sequence of one or more decimal digits. The
15.469 + * character-to-digit mapping is provided by {@code Character.digit}.
15.470 + * The String may not contain any extraneous characters (whitespace, for
15.471 + * example).
15.472 + *
15.473 + * @param val decimal String representation of BigInteger.
15.474 + * @throws NumberFormatException {@code val} is not a valid representation
15.475 + * of a BigInteger.
15.476 + * @see Character#digit
15.477 + */
15.478 + public BigInteger(String val) {
15.479 + this(val, 10);
15.480 + }
15.481 +
15.482 + /**
15.483 + * Constructs a randomly generated BigInteger, uniformly distributed over
15.484 + * the range 0 to (2<sup>{@code numBits}</sup> - 1), inclusive.
15.485 + * The uniformity of the distribution assumes that a fair source of random
15.486 + * bits is provided in {@code rnd}. Note that this constructor always
15.487 + * constructs a non-negative BigInteger.
15.488 + *
15.489 + * @param numBits maximum bitLength of the new BigInteger.
15.490 + * @param rnd source of randomness to be used in computing the new
15.491 + * BigInteger.
15.492 + * @throws IllegalArgumentException {@code numBits} is negative.
15.493 + * @see #bitLength()
15.494 + */
15.495 + public BigInteger(int numBits, Random rnd) {
15.496 + this(1, randomBits(numBits, rnd));
15.497 + }
15.498 +
15.499 + private static byte[] randomBits(int numBits, Random rnd) {
15.500 + if (numBits < 0)
15.501 + throw new IllegalArgumentException("numBits must be non-negative");
15.502 + int numBytes = (int)(((long)numBits+7)/8); // avoid overflow
15.503 + byte[] randomBits = new byte[numBytes];
15.504 +
15.505 + // Generate random bytes and mask out any excess bits
15.506 + if (numBytes > 0) {
15.507 + rnd.nextBytes(randomBits);
15.508 + int excessBits = 8*numBytes - numBits;
15.509 + randomBits[0] &= (1 << (8-excessBits)) - 1;
15.510 + }
15.511 + return randomBits;
15.512 + }
15.513 +
15.514 + /**
15.515 + * Constructs a randomly generated positive BigInteger that is probably
15.516 + * prime, with the specified bitLength.
15.517 + *
15.518 + * <p>It is recommended that the {@link #probablePrime probablePrime}
15.519 + * method be used in preference to this constructor unless there
15.520 + * is a compelling need to specify a certainty.
15.521 + *
15.522 + * @param bitLength bitLength of the returned BigInteger.
15.523 + * @param certainty a measure of the uncertainty that the caller is
15.524 + * willing to tolerate. The probability that the new BigInteger
15.525 + * represents a prime number will exceed
15.526 + * (1 - 1/2<sup>{@code certainty}</sup>). The execution time of
15.527 + * this constructor is proportional to the value of this parameter.
15.528 + * @param rnd source of random bits used to select candidates to be
15.529 + * tested for primality.
15.530 + * @throws ArithmeticException {@code bitLength < 2}.
15.531 + * @see #bitLength()
15.532 + */
15.533 + public BigInteger(int bitLength, int certainty, Random rnd) {
15.534 + BigInteger prime;
15.535 +
15.536 + if (bitLength < 2)
15.537 + throw new ArithmeticException("bitLength < 2");
15.538 + // The cutoff of 95 was chosen empirically for best performance
15.539 + prime = (bitLength < 95 ? smallPrime(bitLength, certainty, rnd)
15.540 + : largePrime(bitLength, certainty, rnd));
15.541 + signum = 1;
15.542 + mag = prime.mag;
15.543 + }
15.544 +
15.545 + // Minimum size in bits that the requested prime number has
15.546 + // before we use the large prime number generating algorithms
15.547 + private static final int SMALL_PRIME_THRESHOLD = 95;
15.548 +
15.549 + // Certainty required to meet the spec of probablePrime
15.550 + private static final int DEFAULT_PRIME_CERTAINTY = 100;
15.551 +
15.552 + /**
15.553 + * Returns a positive BigInteger that is probably prime, with the
15.554 + * specified bitLength. The probability that a BigInteger returned
15.555 + * by this method is composite does not exceed 2<sup>-100</sup>.
15.556 + *
15.557 + * @param bitLength bitLength of the returned BigInteger.
15.558 + * @param rnd source of random bits used to select candidates to be
15.559 + * tested for primality.
15.560 + * @return a BigInteger of {@code bitLength} bits that is probably prime
15.561 + * @throws ArithmeticException {@code bitLength < 2}.
15.562 + * @see #bitLength()
15.563 + * @since 1.4
15.564 + */
15.565 + public static BigInteger probablePrime(int bitLength, Random rnd) {
15.566 + if (bitLength < 2)
15.567 + throw new ArithmeticException("bitLength < 2");
15.568 +
15.569 + // The cutoff of 95 was chosen empirically for best performance
15.570 + return (bitLength < SMALL_PRIME_THRESHOLD ?
15.571 + smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
15.572 + largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
15.573 + }
15.574 +
15.575 + /**
15.576 + * Find a random number of the specified bitLength that is probably prime.
15.577 + * This method is used for smaller primes, its performance degrades on
15.578 + * larger bitlengths.
15.579 + *
15.580 + * This method assumes bitLength > 1.
15.581 + */
15.582 + private static BigInteger smallPrime(int bitLength, int certainty, Random rnd) {
15.583 + int magLen = (bitLength + 31) >>> 5;
15.584 + int temp[] = new int[magLen];
15.585 + int highBit = 1 << ((bitLength+31) & 0x1f); // High bit of high int
15.586 + int highMask = (highBit << 1) - 1; // Bits to keep in high int
15.587 +
15.588 + while(true) {
15.589 + // Construct a candidate
15.590 + for (int i=0; i<magLen; i++)
15.591 + temp[i] = rnd.nextInt();
15.592 + temp[0] = (temp[0] & highMask) | highBit; // Ensure exact length
15.593 + if (bitLength > 2)
15.594 + temp[magLen-1] |= 1; // Make odd if bitlen > 2
15.595 +
15.596 + BigInteger p = new BigInteger(temp, 1);
15.597 +
15.598 + // Do cheap "pre-test" if applicable
15.599 + if (bitLength > 6) {
15.600 + long r = p.remainder(SMALL_PRIME_PRODUCT).longValue();
15.601 + if ((r%3==0) || (r%5==0) || (r%7==0) || (r%11==0) ||
15.602 + (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||
15.603 + (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0))
15.604 + continue; // Candidate is composite; try another
15.605 + }
15.606 +
15.607 + // All candidates of bitLength 2 and 3 are prime by this point
15.608 + if (bitLength < 4)
15.609 + return p;
15.610 +
15.611 + // Do expensive test if we survive pre-test (or it's inapplicable)
15.612 + if (p.primeToCertainty(certainty, rnd))
15.613 + return p;
15.614 + }
15.615 + }
15.616 +
15.617 + private static final BigInteger SMALL_PRIME_PRODUCT
15.618 + = valueOf(3L*5*7*11*13*17*19*23*29*31*37*41);
15.619 +
15.620 + /**
15.621 + * Find a random number of the specified bitLength that is probably prime.
15.622 + * This method is more appropriate for larger bitlengths since it uses
15.623 + * a sieve to eliminate most composites before using a more expensive
15.624 + * test.
15.625 + */
15.626 + private static BigInteger largePrime(int bitLength, int certainty, Random rnd) {
15.627 + BigInteger p;
15.628 + p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
15.629 + p.mag[p.mag.length-1] &= 0xfffffffe;
15.630 +
15.631 + // Use a sieve length likely to contain the next prime number
15.632 + int searchLen = (bitLength / 20) * 64;
15.633 + BitSieve searchSieve = new BitSieve(p, searchLen);
15.634 + BigInteger candidate = searchSieve.retrieve(p, certainty, rnd);
15.635 +
15.636 + while ((candidate == null) || (candidate.bitLength() != bitLength)) {
15.637 + p = p.add(BigInteger.valueOf(2*searchLen));
15.638 + if (p.bitLength() != bitLength)
15.639 + p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
15.640 + p.mag[p.mag.length-1] &= 0xfffffffe;
15.641 + searchSieve = new BitSieve(p, searchLen);
15.642 + candidate = searchSieve.retrieve(p, certainty, rnd);
15.643 + }
15.644 + return candidate;
15.645 + }
15.646 +
15.647 + /**
15.648 + * Returns the first integer greater than this {@code BigInteger} that
15.649 + * is probably prime. The probability that the number returned by this
15.650 + * method is composite does not exceed 2<sup>-100</sup>. This method will
15.651 + * never skip over a prime when searching: if it returns {@code p}, there
15.652 + * is no prime {@code q} such that {@code this < q < p}.
15.653 + *
15.654 + * @return the first integer greater than this {@code BigInteger} that
15.655 + * is probably prime.
15.656 + * @throws ArithmeticException {@code this < 0}.
15.657 + * @since 1.5
15.658 + */
15.659 + public BigInteger nextProbablePrime() {
15.660 + if (this.signum < 0)
15.661 + throw new ArithmeticException("start < 0: " + this);
15.662 +
15.663 + // Handle trivial cases
15.664 + if ((this.signum == 0) || this.equals(ONE))
15.665 + return TWO;
15.666 +
15.667 + BigInteger result = this.add(ONE);
15.668 +
15.669 + // Fastpath for small numbers
15.670 + if (result.bitLength() < SMALL_PRIME_THRESHOLD) {
15.671 +
15.672 + // Ensure an odd number
15.673 + if (!result.testBit(0))
15.674 + result = result.add(ONE);
15.675 +
15.676 + while(true) {
15.677 + // Do cheap "pre-test" if applicable
15.678 + if (result.bitLength() > 6) {
15.679 + long r = result.remainder(SMALL_PRIME_PRODUCT).longValue();
15.680 + if ((r%3==0) || (r%5==0) || (r%7==0) || (r%11==0) ||
15.681 + (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||
15.682 + (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0)) {
15.683 + result = result.add(TWO);
15.684 + continue; // Candidate is composite; try another
15.685 + }
15.686 + }
15.687 +
15.688 + // All candidates of bitLength 2 and 3 are prime by this point
15.689 + if (result.bitLength() < 4)
15.690 + return result;
15.691 +
15.692 + // The expensive test
15.693 + if (result.primeToCertainty(DEFAULT_PRIME_CERTAINTY, null))
15.694 + return result;
15.695 +
15.696 + result = result.add(TWO);
15.697 + }
15.698 + }
15.699 +
15.700 + // Start at previous even number
15.701 + if (result.testBit(0))
15.702 + result = result.subtract(ONE);
15.703 +
15.704 + // Looking for the next large prime
15.705 + int searchLen = (result.bitLength() / 20) * 64;
15.706 +
15.707 + while(true) {
15.708 + BitSieve searchSieve = new BitSieve(result, searchLen);
15.709 + BigInteger candidate = searchSieve.retrieve(result,
15.710 + DEFAULT_PRIME_CERTAINTY, null);
15.711 + if (candidate != null)
15.712 + return candidate;
15.713 + result = result.add(BigInteger.valueOf(2 * searchLen));
15.714 + }
15.715 + }
15.716 +
15.717 + /**
15.718 + * Returns {@code true} if this BigInteger is probably prime,
15.719 + * {@code false} if it's definitely composite.
15.720 + *
15.721 + * This method assumes bitLength > 2.
15.722 + *
15.723 + * @param certainty a measure of the uncertainty that the caller is
15.724 + * willing to tolerate: if the call returns {@code true}
15.725 + * the probability that this BigInteger is prime exceeds
15.726 + * {@code (1 - 1/2<sup>certainty</sup>)}. The execution time of
15.727 + * this method is proportional to the value of this parameter.
15.728 + * @return {@code true} if this BigInteger is probably prime,
15.729 + * {@code false} if it's definitely composite.
15.730 + */
15.731 + boolean primeToCertainty(int certainty, Random random) {
15.732 + int rounds = 0;
15.733 + int n = (Math.min(certainty, Integer.MAX_VALUE-1)+1)/2;
15.734 +
15.735 + // The relationship between the certainty and the number of rounds
15.736 + // we perform is given in the draft standard ANSI X9.80, "PRIME
15.737 + // NUMBER GENERATION, PRIMALITY TESTING, AND PRIMALITY CERTIFICATES".
15.738 + int sizeInBits = this.bitLength();
15.739 + if (sizeInBits < 100) {
15.740 + rounds = 50;
15.741 + rounds = n < rounds ? n : rounds;
15.742 + return passesMillerRabin(rounds, random);
15.743 + }
15.744 +
15.745 + if (sizeInBits < 256) {
15.746 + rounds = 27;
15.747 + } else if (sizeInBits < 512) {
15.748 + rounds = 15;
15.749 + } else if (sizeInBits < 768) {
15.750 + rounds = 8;
15.751 + } else if (sizeInBits < 1024) {
15.752 + rounds = 4;
15.753 + } else {
15.754 + rounds = 2;
15.755 + }
15.756 + rounds = n < rounds ? n : rounds;
15.757 +
15.758 + return passesMillerRabin(rounds, random) && passesLucasLehmer();
15.759 + }
15.760 +
15.761 + /**
15.762 + * Returns true iff this BigInteger is a Lucas-Lehmer probable prime.
15.763 + *
15.764 + * The following assumptions are made:
15.765 + * This BigInteger is a positive, odd number.
15.766 + */
15.767 + private boolean passesLucasLehmer() {
15.768 + BigInteger thisPlusOne = this.add(ONE);
15.769 +
15.770 + // Step 1
15.771 + int d = 5;
15.772 + while (jacobiSymbol(d, this) != -1) {
15.773 + // 5, -7, 9, -11, ...
15.774 + d = (d<0) ? Math.abs(d)+2 : -(d+2);
15.775 + }
15.776 +
15.777 + // Step 2
15.778 + BigInteger u = lucasLehmerSequence(d, thisPlusOne, this);
15.779 +
15.780 + // Step 3
15.781 + return u.mod(this).equals(ZERO);
15.782 + }
15.783 +
15.784 + /**
15.785 + * Computes Jacobi(p,n).
15.786 + * Assumes n positive, odd, n>=3.
15.787 + */
15.788 + private static int jacobiSymbol(int p, BigInteger n) {
15.789 + if (p == 0)
15.790 + return 0;
15.791 +
15.792 + // Algorithm and comments adapted from Colin Plumb's C library.
15.793 + int j = 1;
15.794 + int u = n.mag[n.mag.length-1];
15.795 +
15.796 + // Make p positive
15.797 + if (p < 0) {
15.798 + p = -p;
15.799 + int n8 = u & 7;
15.800 + if ((n8 == 3) || (n8 == 7))
15.801 + j = -j; // 3 (011) or 7 (111) mod 8
15.802 + }
15.803 +
15.804 + // Get rid of factors of 2 in p
15.805 + while ((p & 3) == 0)
15.806 + p >>= 2;
15.807 + if ((p & 1) == 0) {
15.808 + p >>= 1;
15.809 + if (((u ^ (u>>1)) & 2) != 0)
15.810 + j = -j; // 3 (011) or 5 (101) mod 8
15.811 + }
15.812 + if (p == 1)
15.813 + return j;
15.814 + // Then, apply quadratic reciprocity
15.815 + if ((p & u & 2) != 0) // p = u = 3 (mod 4)?
15.816 + j = -j;
15.817 + // And reduce u mod p
15.818 + u = n.mod(BigInteger.valueOf(p)).intValue();
15.819 +
15.820 + // Now compute Jacobi(u,p), u < p
15.821 + while (u != 0) {
15.822 + while ((u & 3) == 0)
15.823 + u >>= 2;
15.824 + if ((u & 1) == 0) {
15.825 + u >>= 1;
15.826 + if (((p ^ (p>>1)) & 2) != 0)
15.827 + j = -j; // 3 (011) or 5 (101) mod 8
15.828 + }
15.829 + if (u == 1)
15.830 + return j;
15.831 + // Now both u and p are odd, so use quadratic reciprocity
15.832 + assert (u < p);
15.833 + int t = u; u = p; p = t;
15.834 + if ((u & p & 2) != 0) // u = p = 3 (mod 4)?
15.835 + j = -j;
15.836 + // Now u >= p, so it can be reduced
15.837 + u %= p;
15.838 + }
15.839 + return 0;
15.840 + }
15.841 +
15.842 + private static BigInteger lucasLehmerSequence(int z, BigInteger k, BigInteger n) {
15.843 + BigInteger d = BigInteger.valueOf(z);
15.844 + BigInteger u = ONE; BigInteger u2;
15.845 + BigInteger v = ONE; BigInteger v2;
15.846 +
15.847 + for (int i=k.bitLength()-2; i>=0; i--) {
15.848 + u2 = u.multiply(v).mod(n);
15.849 +
15.850 + v2 = v.square().add(d.multiply(u.square())).mod(n);
15.851 + if (v2.testBit(0))
15.852 + v2 = v2.subtract(n);
15.853 +
15.854 + v2 = v2.shiftRight(1);
15.855 +
15.856 + u = u2; v = v2;
15.857 + if (k.testBit(i)) {
15.858 + u2 = u.add(v).mod(n);
15.859 + if (u2.testBit(0))
15.860 + u2 = u2.subtract(n);
15.861 +
15.862 + u2 = u2.shiftRight(1);
15.863 + v2 = v.add(d.multiply(u)).mod(n);
15.864 + if (v2.testBit(0))
15.865 + v2 = v2.subtract(n);
15.866 + v2 = v2.shiftRight(1);
15.867 +
15.868 + u = u2; v = v2;
15.869 + }
15.870 + }
15.871 + return u;
15.872 + }
15.873 +
15.874 + private static volatile Random staticRandom;
15.875 +
15.876 + private static Random getSecureRandom() {
15.877 + if (staticRandom == null) {
15.878 + staticRandom = new java.security.SecureRandom();
15.879 + }
15.880 + return staticRandom;
15.881 + }
15.882 +
15.883 + /**
15.884 + * Returns true iff this BigInteger passes the specified number of
15.885 + * Miller-Rabin tests. This test is taken from the DSA spec (NIST FIPS
15.886 + * 186-2).
15.887 + *
15.888 + * The following assumptions are made:
15.889 + * This BigInteger is a positive, odd number greater than 2.
15.890 + * iterations<=50.
15.891 + */
15.892 + private boolean passesMillerRabin(int iterations, Random rnd) {
15.893 + // Find a and m such that m is odd and this == 1 + 2**a * m
15.894 + BigInteger thisMinusOne = this.subtract(ONE);
15.895 + BigInteger m = thisMinusOne;
15.896 + int a = m.getLowestSetBit();
15.897 + m = m.shiftRight(a);
15.898 +
15.899 + // Do the tests
15.900 + if (rnd == null) {
15.901 + rnd = getSecureRandom();
15.902 + }
15.903 + for (int i=0; i<iterations; i++) {
15.904 + // Generate a uniform random on (1, this)
15.905 + BigInteger b;
15.906 + do {
15.907 + b = new BigInteger(this.bitLength(), rnd);
15.908 + } while (b.compareTo(ONE) <= 0 || b.compareTo(this) >= 0);
15.909 +
15.910 + int j = 0;
15.911 + BigInteger z = b.modPow(m, this);
15.912 + while(!((j==0 && z.equals(ONE)) || z.equals(thisMinusOne))) {
15.913 + if (j>0 && z.equals(ONE) || ++j==a)
15.914 + return false;
15.915 + z = z.modPow(TWO, this);
15.916 + }
15.917 + }
15.918 + return true;
15.919 + }
15.920 +
15.921 + /**
15.922 + * This internal constructor differs from its public cousin
15.923 + * with the arguments reversed in two ways: it assumes that its
15.924 + * arguments are correct, and it doesn't copy the magnitude array.
15.925 + */
15.926 + BigInteger(int[] magnitude, int signum) {
15.927 + this.signum = (magnitude.length==0 ? 0 : signum);
15.928 + this.mag = magnitude;
15.929 + }
15.930 +
15.931 + /**
15.932 + * This private constructor is for internal use and assumes that its
15.933 + * arguments are correct.
15.934 + */
15.935 + private BigInteger(byte[] magnitude, int signum) {
15.936 + this.signum = (magnitude.length==0 ? 0 : signum);
15.937 + this.mag = stripLeadingZeroBytes(magnitude);
15.938 + }
15.939 +
15.940 + //Static Factory Methods
15.941 +
15.942 + /**
15.943 + * Returns a BigInteger whose value is equal to that of the
15.944 + * specified {@code long}. This "static factory method" is
15.945 + * provided in preference to a ({@code long}) constructor
15.946 + * because it allows for reuse of frequently used BigIntegers.
15.947 + *
15.948 + * @param val value of the BigInteger to return.
15.949 + * @return a BigInteger with the specified value.
15.950 + */
15.951 + public static BigInteger valueOf(long val) {
15.952 + // If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant
15.953 + if (val == 0)
15.954 + return ZERO;
15.955 + if (val > 0 && val <= MAX_CONSTANT)
15.956 + return posConst[(int) val];
15.957 + else if (val < 0 && val >= -MAX_CONSTANT)
15.958 + return negConst[(int) -val];
15.959 +
15.960 + return new BigInteger(val);
15.961 + }
15.962 +
15.963 + /**
15.964 + * Constructs a BigInteger with the specified value, which may not be zero.
15.965 + */
15.966 + private BigInteger(long val) {
15.967 + if (val < 0) {
15.968 + val = -val;
15.969 + signum = -1;
15.970 + } else {
15.971 + signum = 1;
15.972 + }
15.973 +
15.974 + int highWord = (int)(val >>> 32);
15.975 + if (highWord==0) {
15.976 + mag = new int[1];
15.977 + mag[0] = (int)val;
15.978 + } else {
15.979 + mag = new int[2];
15.980 + mag[0] = highWord;
15.981 + mag[1] = (int)val;
15.982 + }
15.983 + }
15.984 +
15.985 + /**
15.986 + * Returns a BigInteger with the given two's complement representation.
15.987 + * Assumes that the input array will not be modified (the returned
15.988 + * BigInteger will reference the input array if feasible).
15.989 + */
15.990 + private static BigInteger valueOf(int val[]) {
15.991 + return (val[0]>0 ? new BigInteger(val, 1) : new BigInteger(val));
15.992 + }
15.993 +
15.994 + // Constants
15.995 +
15.996 + /**
15.997 + * Initialize static constant array when class is loaded.
15.998 + */
15.999 + private final static int MAX_CONSTANT = 16;
15.1000 + private static BigInteger posConst[] = new BigInteger[MAX_CONSTANT+1];
15.1001 + private static BigInteger negConst[] = new BigInteger[MAX_CONSTANT+1];
15.1002 + static {
15.1003 + for (int i = 1; i <= MAX_CONSTANT; i++) {
15.1004 + int[] magnitude = new int[1];
15.1005 + magnitude[0] = i;
15.1006 + posConst[i] = new BigInteger(magnitude, 1);
15.1007 + negConst[i] = new BigInteger(magnitude, -1);
15.1008 + }
15.1009 + }
15.1010 +
15.1011 + /**
15.1012 + * The BigInteger constant zero.
15.1013 + *
15.1014 + * @since 1.2
15.1015 + */
15.1016 + public static final BigInteger ZERO = new BigInteger(new int[0], 0);
15.1017 +
15.1018 + /**
15.1019 + * The BigInteger constant one.
15.1020 + *
15.1021 + * @since 1.2
15.1022 + */
15.1023 + public static final BigInteger ONE = valueOf(1);
15.1024 +
15.1025 + /**
15.1026 + * The BigInteger constant two. (Not exported.)
15.1027 + */
15.1028 + private static final BigInteger TWO = valueOf(2);
15.1029 +
15.1030 + /**
15.1031 + * The BigInteger constant ten.
15.1032 + *
15.1033 + * @since 1.5
15.1034 + */
15.1035 + public static final BigInteger TEN = valueOf(10);
15.1036 +
15.1037 + // Arithmetic Operations
15.1038 +
15.1039 + /**
15.1040 + * Returns a BigInteger whose value is {@code (this + val)}.
15.1041 + *
15.1042 + * @param val value to be added to this BigInteger.
15.1043 + * @return {@code this + val}
15.1044 + */
15.1045 + public BigInteger add(BigInteger val) {
15.1046 + if (val.signum == 0)
15.1047 + return this;
15.1048 + if (signum == 0)
15.1049 + return val;
15.1050 + if (val.signum == signum)
15.1051 + return new BigInteger(add(mag, val.mag), signum);
15.1052 +
15.1053 + int cmp = compareMagnitude(val);
15.1054 + if (cmp == 0)
15.1055 + return ZERO;
15.1056 + int[] resultMag = (cmp > 0 ? subtract(mag, val.mag)
15.1057 + : subtract(val.mag, mag));
15.1058 + resultMag = trustedStripLeadingZeroInts(resultMag);
15.1059 +
15.1060 + return new BigInteger(resultMag, cmp == signum ? 1 : -1);
15.1061 + }
15.1062 +
15.1063 + /**
15.1064 + * Adds the contents of the int arrays x and y. This method allocates
15.1065 + * a new int array to hold the answer and returns a reference to that
15.1066 + * array.
15.1067 + */
15.1068 + private static int[] add(int[] x, int[] y) {
15.1069 + // If x is shorter, swap the two arrays
15.1070 + if (x.length < y.length) {
15.1071 + int[] tmp = x;
15.1072 + x = y;
15.1073 + y = tmp;
15.1074 + }
15.1075 +
15.1076 + int xIndex = x.length;
15.1077 + int yIndex = y.length;
15.1078 + int result[] = new int[xIndex];
15.1079 + long sum = 0;
15.1080 +
15.1081 + // Add common parts of both numbers
15.1082 + while(yIndex > 0) {
15.1083 + sum = (x[--xIndex] & LONG_MASK) +
15.1084 + (y[--yIndex] & LONG_MASK) + (sum >>> 32);
15.1085 + result[xIndex] = (int)sum;
15.1086 + }
15.1087 +
15.1088 + // Copy remainder of longer number while carry propagation is required
15.1089 + boolean carry = (sum >>> 32 != 0);
15.1090 + while (xIndex > 0 && carry)
15.1091 + carry = ((result[--xIndex] = x[xIndex] + 1) == 0);
15.1092 +
15.1093 + // Copy remainder of longer number
15.1094 + while (xIndex > 0)
15.1095 + result[--xIndex] = x[xIndex];
15.1096 +
15.1097 + // Grow result if necessary
15.1098 + if (carry) {
15.1099 + int bigger[] = new int[result.length + 1];
15.1100 + System.arraycopy(result, 0, bigger, 1, result.length);
15.1101 + bigger[0] = 0x01;
15.1102 + return bigger;
15.1103 + }
15.1104 + return result;
15.1105 + }
15.1106 +
15.1107 + /**
15.1108 + * Returns a BigInteger whose value is {@code (this - val)}.
15.1109 + *
15.1110 + * @param val value to be subtracted from this BigInteger.
15.1111 + * @return {@code this - val}
15.1112 + */
15.1113 + public BigInteger subtract(BigInteger val) {
15.1114 + if (val.signum == 0)
15.1115 + return this;
15.1116 + if (signum == 0)
15.1117 + return val.negate();
15.1118 + if (val.signum != signum)
15.1119 + return new BigInteger(add(mag, val.mag), signum);
15.1120 +
15.1121 + int cmp = compareMagnitude(val);
15.1122 + if (cmp == 0)
15.1123 + return ZERO;
15.1124 + int[] resultMag = (cmp > 0 ? subtract(mag, val.mag)
15.1125 + : subtract(val.mag, mag));
15.1126 + resultMag = trustedStripLeadingZeroInts(resultMag);
15.1127 + return new BigInteger(resultMag, cmp == signum ? 1 : -1);
15.1128 + }
15.1129 +
15.1130 + /**
15.1131 + * Subtracts the contents of the second int arrays (little) from the
15.1132 + * first (big). The first int array (big) must represent a larger number
15.1133 + * than the second. This method allocates the space necessary to hold the
15.1134 + * answer.
15.1135 + */
15.1136 + private static int[] subtract(int[] big, int[] little) {
15.1137 + int bigIndex = big.length;
15.1138 + int result[] = new int[bigIndex];
15.1139 + int littleIndex = little.length;
15.1140 + long difference = 0;
15.1141 +
15.1142 + // Subtract common parts of both numbers
15.1143 + while(littleIndex > 0) {
15.1144 + difference = (big[--bigIndex] & LONG_MASK) -
15.1145 + (little[--littleIndex] & LONG_MASK) +
15.1146 + (difference >> 32);
15.1147 + result[bigIndex] = (int)difference;
15.1148 + }
15.1149 +
15.1150 + // Subtract remainder of longer number while borrow propagates
15.1151 + boolean borrow = (difference >> 32 != 0);
15.1152 + while (bigIndex > 0 && borrow)
15.1153 + borrow = ((result[--bigIndex] = big[bigIndex] - 1) == -1);
15.1154 +
15.1155 + // Copy remainder of longer number
15.1156 + while (bigIndex > 0)
15.1157 + result[--bigIndex] = big[bigIndex];
15.1158 +
15.1159 + return result;
15.1160 + }
15.1161 +
15.1162 + /**
15.1163 + * Returns a BigInteger whose value is {@code (this * val)}.
15.1164 + *
15.1165 + * @param val value to be multiplied by this BigInteger.
15.1166 + * @return {@code this * val}
15.1167 + */
15.1168 + public BigInteger multiply(BigInteger val) {
15.1169 + if (val.signum == 0 || signum == 0)
15.1170 + return ZERO;
15.1171 +
15.1172 + int[] result = multiplyToLen(mag, mag.length,
15.1173 + val.mag, val.mag.length, null);
15.1174 + result = trustedStripLeadingZeroInts(result);
15.1175 + return new BigInteger(result, signum == val.signum ? 1 : -1);
15.1176 + }
15.1177 +
15.1178 + /**
15.1179 + * Package private methods used by BigDecimal code to multiply a BigInteger
15.1180 + * with a long. Assumes v is not equal to INFLATED.
15.1181 + */
15.1182 + BigInteger multiply(long v) {
15.1183 + if (v == 0 || signum == 0)
15.1184 + return ZERO;
15.1185 + if (v == BigDecimal.INFLATED)
15.1186 + return multiply(BigInteger.valueOf(v));
15.1187 + int rsign = (v > 0 ? signum : -signum);
15.1188 + if (v < 0)
15.1189 + v = -v;
15.1190 + long dh = v >>> 32; // higher order bits
15.1191 + long dl = v & LONG_MASK; // lower order bits
15.1192 +
15.1193 + int xlen = mag.length;
15.1194 + int[] value = mag;
15.1195 + int[] rmag = (dh == 0L) ? (new int[xlen + 1]) : (new int[xlen + 2]);
15.1196 + long carry = 0;
15.1197 + int rstart = rmag.length - 1;
15.1198 + for (int i = xlen - 1; i >= 0; i--) {
15.1199 + long product = (value[i] & LONG_MASK) * dl + carry;
15.1200 + rmag[rstart--] = (int)product;
15.1201 + carry = product >>> 32;
15.1202 + }
15.1203 + rmag[rstart] = (int)carry;
15.1204 + if (dh != 0L) {
15.1205 + carry = 0;
15.1206 + rstart = rmag.length - 2;
15.1207 + for (int i = xlen - 1; i >= 0; i--) {
15.1208 + long product = (value[i] & LONG_MASK) * dh +
15.1209 + (rmag[rstart] & LONG_MASK) + carry;
15.1210 + rmag[rstart--] = (int)product;
15.1211 + carry = product >>> 32;
15.1212 + }
15.1213 + rmag[0] = (int)carry;
15.1214 + }
15.1215 + if (carry == 0L)
15.1216 + rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length);
15.1217 + return new BigInteger(rmag, rsign);
15.1218 + }
15.1219 +
15.1220 + /**
15.1221 + * Multiplies int arrays x and y to the specified lengths and places
15.1222 + * the result into z. There will be no leading zeros in the resultant array.
15.1223 + */
15.1224 + private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
15.1225 + int xstart = xlen - 1;
15.1226 + int ystart = ylen - 1;
15.1227 +
15.1228 + if (z == null || z.length < (xlen+ ylen))
15.1229 + z = new int[xlen+ylen];
15.1230 +
15.1231 + long carry = 0;
15.1232 + for (int j=ystart, k=ystart+1+xstart; j>=0; j--, k--) {
15.1233 + long product = (y[j] & LONG_MASK) *
15.1234 + (x[xstart] & LONG_MASK) + carry;
15.1235 + z[k] = (int)product;
15.1236 + carry = product >>> 32;
15.1237 + }
15.1238 + z[xstart] = (int)carry;
15.1239 +
15.1240 + for (int i = xstart-1; i >= 0; i--) {
15.1241 + carry = 0;
15.1242 + for (int j=ystart, k=ystart+1+i; j>=0; j--, k--) {
15.1243 + long product = (y[j] & LONG_MASK) *
15.1244 + (x[i] & LONG_MASK) +
15.1245 + (z[k] & LONG_MASK) + carry;
15.1246 + z[k] = (int)product;
15.1247 + carry = product >>> 32;
15.1248 + }
15.1249 + z[i] = (int)carry;
15.1250 + }
15.1251 + return z;
15.1252 + }
15.1253 +
15.1254 + /**
15.1255 + * Returns a BigInteger whose value is {@code (this<sup>2</sup>)}.
15.1256 + *
15.1257 + * @return {@code this<sup>2</sup>}
15.1258 + */
15.1259 + private BigInteger square() {
15.1260 + if (signum == 0)
15.1261 + return ZERO;
15.1262 + int[] z = squareToLen(mag, mag.length, null);
15.1263 + return new BigInteger(trustedStripLeadingZeroInts(z), 1);
15.1264 + }
15.1265 +
15.1266 + /**
15.1267 + * Squares the contents of the int array x. The result is placed into the
15.1268 + * int array z. The contents of x are not changed.
15.1269 + */
15.1270 + private static final int[] squareToLen(int[] x, int len, int[] z) {
15.1271 + /*
15.1272 + * The algorithm used here is adapted from Colin Plumb's C library.
15.1273 + * Technique: Consider the partial products in the multiplication
15.1274 + * of "abcde" by itself:
15.1275 + *
15.1276 + * a b c d e
15.1277 + * * a b c d e
15.1278 + * ==================
15.1279 + * ae be ce de ee
15.1280 + * ad bd cd dd de
15.1281 + * ac bc cc cd ce
15.1282 + * ab bb bc bd be
15.1283 + * aa ab ac ad ae
15.1284 + *
15.1285 + * Note that everything above the main diagonal:
15.1286 + * ae be ce de = (abcd) * e
15.1287 + * ad bd cd = (abc) * d
15.1288 + * ac bc = (ab) * c
15.1289 + * ab = (a) * b
15.1290 + *
15.1291 + * is a copy of everything below the main diagonal:
15.1292 + * de
15.1293 + * cd ce
15.1294 + * bc bd be
15.1295 + * ab ac ad ae
15.1296 + *
15.1297 + * Thus, the sum is 2 * (off the diagonal) + diagonal.
15.1298 + *
15.1299 + * This is accumulated beginning with the diagonal (which
15.1300 + * consist of the squares of the digits of the input), which is then
15.1301 + * divided by two, the off-diagonal added, and multiplied by two
15.1302 + * again. The low bit is simply a copy of the low bit of the
15.1303 + * input, so it doesn't need special care.
15.1304 + */
15.1305 + int zlen = len << 1;
15.1306 + if (z == null || z.length < zlen)
15.1307 + z = new int[zlen];
15.1308 +
15.1309 + // Store the squares, right shifted one bit (i.e., divided by 2)
15.1310 + int lastProductLowWord = 0;
15.1311 + for (int j=0, i=0; j<len; j++) {
15.1312 + long piece = (x[j] & LONG_MASK);
15.1313 + long product = piece * piece;
15.1314 + z[i++] = (lastProductLowWord << 31) | (int)(product >>> 33);
15.1315 + z[i++] = (int)(product >>> 1);
15.1316 + lastProductLowWord = (int)product;
15.1317 + }
15.1318 +
15.1319 + // Add in off-diagonal sums
15.1320 + for (int i=len, offset=1; i>0; i--, offset+=2) {
15.1321 + int t = x[i-1];
15.1322 + t = mulAdd(z, x, offset, i-1, t);
15.1323 + addOne(z, offset-1, i, t);
15.1324 + }
15.1325 +
15.1326 + // Shift back up and set low bit
15.1327 + primitiveLeftShift(z, zlen, 1);
15.1328 + z[zlen-1] |= x[len-1] & 1;
15.1329 +
15.1330 + return z;
15.1331 + }
15.1332 +
15.1333 + /**
15.1334 + * Returns a BigInteger whose value is {@code (this / val)}.
15.1335 + *
15.1336 + * @param val value by which this BigInteger is to be divided.
15.1337 + * @return {@code this / val}
15.1338 + * @throws ArithmeticException if {@code val} is zero.
15.1339 + */
15.1340 + public BigInteger divide(BigInteger val) {
15.1341 + MutableBigInteger q = new MutableBigInteger(),
15.1342 + a = new MutableBigInteger(this.mag),
15.1343 + b = new MutableBigInteger(val.mag);
15.1344 +
15.1345 + a.divide(b, q);
15.1346 + return q.toBigInteger(this.signum == val.signum ? 1 : -1);
15.1347 + }
15.1348 +
15.1349 + /**
15.1350 + * Returns an array of two BigIntegers containing {@code (this / val)}
15.1351 + * followed by {@code (this % val)}.
15.1352 + *
15.1353 + * @param val value by which this BigInteger is to be divided, and the
15.1354 + * remainder computed.
15.1355 + * @return an array of two BigIntegers: the quotient {@code (this / val)}
15.1356 + * is the initial element, and the remainder {@code (this % val)}
15.1357 + * is the final element.
15.1358 + * @throws ArithmeticException if {@code val} is zero.
15.1359 + */
15.1360 + public BigInteger[] divideAndRemainder(BigInteger val) {
15.1361 + BigInteger[] result = new BigInteger[2];
15.1362 + MutableBigInteger q = new MutableBigInteger(),
15.1363 + a = new MutableBigInteger(this.mag),
15.1364 + b = new MutableBigInteger(val.mag);
15.1365 + MutableBigInteger r = a.divide(b, q);
15.1366 + result[0] = q.toBigInteger(this.signum == val.signum ? 1 : -1);
15.1367 + result[1] = r.toBigInteger(this.signum);
15.1368 + return result;
15.1369 + }
15.1370 +
15.1371 + /**
15.1372 + * Returns a BigInteger whose value is {@code (this % val)}.
15.1373 + *
15.1374 + * @param val value by which this BigInteger is to be divided, and the
15.1375 + * remainder computed.
15.1376 + * @return {@code this % val}
15.1377 + * @throws ArithmeticException if {@code val} is zero.
15.1378 + */
15.1379 + public BigInteger remainder(BigInteger val) {
15.1380 + MutableBigInteger q = new MutableBigInteger(),
15.1381 + a = new MutableBigInteger(this.mag),
15.1382 + b = new MutableBigInteger(val.mag);
15.1383 +
15.1384 + return a.divide(b, q).toBigInteger(this.signum);
15.1385 + }
15.1386 +
15.1387 + /**
15.1388 + * Returns a BigInteger whose value is <tt>(this<sup>exponent</sup>)</tt>.
15.1389 + * Note that {@code exponent} is an integer rather than a BigInteger.
15.1390 + *
15.1391 + * @param exponent exponent to which this BigInteger is to be raised.
15.1392 + * @return <tt>this<sup>exponent</sup></tt>
15.1393 + * @throws ArithmeticException {@code exponent} is negative. (This would
15.1394 + * cause the operation to yield a non-integer value.)
15.1395 + */
15.1396 + public BigInteger pow(int exponent) {
15.1397 + if (exponent < 0)
15.1398 + throw new ArithmeticException("Negative exponent");
15.1399 + if (signum==0)
15.1400 + return (exponent==0 ? ONE : this);
15.1401 +
15.1402 + // Perform exponentiation using repeated squaring trick
15.1403 + int newSign = (signum<0 && (exponent&1)==1 ? -1 : 1);
15.1404 + int[] baseToPow2 = this.mag;
15.1405 + int[] result = {1};
15.1406 +
15.1407 + while (exponent != 0) {
15.1408 + if ((exponent & 1)==1) {
15.1409 + result = multiplyToLen(result, result.length,
15.1410 + baseToPow2, baseToPow2.length, null);
15.1411 + result = trustedStripLeadingZeroInts(result);
15.1412 + }
15.1413 + if ((exponent >>>= 1) != 0) {
15.1414 + baseToPow2 = squareToLen(baseToPow2, baseToPow2.length, null);
15.1415 + baseToPow2 = trustedStripLeadingZeroInts(baseToPow2);
15.1416 + }
15.1417 + }
15.1418 + return new BigInteger(result, newSign);
15.1419 + }
15.1420 +
15.1421 + /**
15.1422 + * Returns a BigInteger whose value is the greatest common divisor of
15.1423 + * {@code abs(this)} and {@code abs(val)}. Returns 0 if
15.1424 + * {@code this==0 && val==0}.
15.1425 + *
15.1426 + * @param val value with which the GCD is to be computed.
15.1427 + * @return {@code GCD(abs(this), abs(val))}
15.1428 + */
15.1429 + public BigInteger gcd(BigInteger val) {
15.1430 + if (val.signum == 0)
15.1431 + return this.abs();
15.1432 + else if (this.signum == 0)
15.1433 + return val.abs();
15.1434 +
15.1435 + MutableBigInteger a = new MutableBigInteger(this);
15.1436 + MutableBigInteger b = new MutableBigInteger(val);
15.1437 +
15.1438 + MutableBigInteger result = a.hybridGCD(b);
15.1439 +
15.1440 + return result.toBigInteger(1);
15.1441 + }
15.1442 +
15.1443 + /**
15.1444 + * Package private method to return bit length for an integer.
15.1445 + */
15.1446 + static int bitLengthForInt(int n) {
15.1447 + return 32 - Integer.numberOfLeadingZeros(n);
15.1448 + }
15.1449 +
15.1450 + /**
15.1451 + * Left shift int array a up to len by n bits. Returns the array that
15.1452 + * results from the shift since space may have to be reallocated.
15.1453 + */
15.1454 + private static int[] leftShift(int[] a, int len, int n) {
15.1455 + int nInts = n >>> 5;
15.1456 + int nBits = n&0x1F;
15.1457 + int bitsInHighWord = bitLengthForInt(a[0]);
15.1458 +
15.1459 + // If shift can be done without recopy, do so
15.1460 + if (n <= (32-bitsInHighWord)) {
15.1461 + primitiveLeftShift(a, len, nBits);
15.1462 + return a;
15.1463 + } else { // Array must be resized
15.1464 + if (nBits <= (32-bitsInHighWord)) {
15.1465 + int result[] = new int[nInts+len];
15.1466 + for (int i=0; i<len; i++)
15.1467 + result[i] = a[i];
15.1468 + primitiveLeftShift(result, result.length, nBits);
15.1469 + return result;
15.1470 + } else {
15.1471 + int result[] = new int[nInts+len+1];
15.1472 + for (int i=0; i<len; i++)
15.1473 + result[i] = a[i];
15.1474 + primitiveRightShift(result, result.length, 32 - nBits);
15.1475 + return result;
15.1476 + }
15.1477 + }
15.1478 + }
15.1479 +
15.1480 + // shifts a up to len right n bits assumes no leading zeros, 0<n<32
15.1481 + static void primitiveRightShift(int[] a, int len, int n) {
15.1482 + int n2 = 32 - n;
15.1483 + for (int i=len-1, c=a[i]; i>0; i--) {
15.1484 + int b = c;
15.1485 + c = a[i-1];
15.1486 + a[i] = (c << n2) | (b >>> n);
15.1487 + }
15.1488 + a[0] >>>= n;
15.1489 + }
15.1490 +
15.1491 + // shifts a up to len left n bits assumes no leading zeros, 0<=n<32
15.1492 + static void primitiveLeftShift(int[] a, int len, int n) {
15.1493 + if (len == 0 || n == 0)
15.1494 + return;
15.1495 +
15.1496 + int n2 = 32 - n;
15.1497 + for (int i=0, c=a[i], m=i+len-1; i<m; i++) {
15.1498 + int b = c;
15.1499 + c = a[i+1];
15.1500 + a[i] = (b << n) | (c >>> n2);
15.1501 + }
15.1502 + a[len-1] <<= n;
15.1503 + }
15.1504 +
15.1505 + /**
15.1506 + * Calculate bitlength of contents of the first len elements an int array,
15.1507 + * assuming there are no leading zero ints.
15.1508 + */
15.1509 + private static int bitLength(int[] val, int len) {
15.1510 + if (len == 0)
15.1511 + return 0;
15.1512 + return ((len - 1) << 5) + bitLengthForInt(val[0]);
15.1513 + }
15.1514 +
15.1515 + /**
15.1516 + * Returns a BigInteger whose value is the absolute value of this
15.1517 + * BigInteger.
15.1518 + *
15.1519 + * @return {@code abs(this)}
15.1520 + */
15.1521 + public BigInteger abs() {
15.1522 + return (signum >= 0 ? this : this.negate());
15.1523 + }
15.1524 +
15.1525 + /**
15.1526 + * Returns a BigInteger whose value is {@code (-this)}.
15.1527 + *
15.1528 + * @return {@code -this}
15.1529 + */
15.1530 + public BigInteger negate() {
15.1531 + return new BigInteger(this.mag, -this.signum);
15.1532 + }
15.1533 +
15.1534 + /**
15.1535 + * Returns the signum function of this BigInteger.
15.1536 + *
15.1537 + * @return -1, 0 or 1 as the value of this BigInteger is negative, zero or
15.1538 + * positive.
15.1539 + */
15.1540 + public int signum() {
15.1541 + return this.signum;
15.1542 + }
15.1543 +
15.1544 + // Modular Arithmetic Operations
15.1545 +
15.1546 + /**
15.1547 + * Returns a BigInteger whose value is {@code (this mod m}). This method
15.1548 + * differs from {@code remainder} in that it always returns a
15.1549 + * <i>non-negative</i> BigInteger.
15.1550 + *
15.1551 + * @param m the modulus.
15.1552 + * @return {@code this mod m}
15.1553 + * @throws ArithmeticException {@code m} ≤ 0
15.1554 + * @see #remainder
15.1555 + */
15.1556 + public BigInteger mod(BigInteger m) {
15.1557 + if (m.signum <= 0)
15.1558 + throw new ArithmeticException("BigInteger: modulus not positive");
15.1559 +
15.1560 + BigInteger result = this.remainder(m);
15.1561 + return (result.signum >= 0 ? result : result.add(m));
15.1562 + }
15.1563 +
15.1564 + /**
15.1565 + * Returns a BigInteger whose value is
15.1566 + * <tt>(this<sup>exponent</sup> mod m)</tt>. (Unlike {@code pow}, this
15.1567 + * method permits negative exponents.)
15.1568 + *
15.1569 + * @param exponent the exponent.
15.1570 + * @param m the modulus.
15.1571 + * @return <tt>this<sup>exponent</sup> mod m</tt>
15.1572 + * @throws ArithmeticException {@code m} ≤ 0 or the exponent is
15.1573 + * negative and this BigInteger is not <i>relatively
15.1574 + * prime</i> to {@code m}.
15.1575 + * @see #modInverse
15.1576 + */
15.1577 + public BigInteger modPow(BigInteger exponent, BigInteger m) {
15.1578 + if (m.signum <= 0)
15.1579 + throw new ArithmeticException("BigInteger: modulus not positive");
15.1580 +
15.1581 + // Trivial cases
15.1582 + if (exponent.signum == 0)
15.1583 + return (m.equals(ONE) ? ZERO : ONE);
15.1584 +
15.1585 + if (this.equals(ONE))
15.1586 + return (m.equals(ONE) ? ZERO : ONE);
15.1587 +
15.1588 + if (this.equals(ZERO) && exponent.signum >= 0)
15.1589 + return ZERO;
15.1590 +
15.1591 + if (this.equals(negConst[1]) && (!exponent.testBit(0)))
15.1592 + return (m.equals(ONE) ? ZERO : ONE);
15.1593 +
15.1594 + boolean invertResult;
15.1595 + if ((invertResult = (exponent.signum < 0)))
15.1596 + exponent = exponent.negate();
15.1597 +
15.1598 + BigInteger base = (this.signum < 0 || this.compareTo(m) >= 0
15.1599 + ? this.mod(m) : this);
15.1600 + BigInteger result;
15.1601 + if (m.testBit(0)) { // odd modulus
15.1602 + result = base.oddModPow(exponent, m);
15.1603 + } else {
15.1604 + /*
15.1605 + * Even modulus. Tear it into an "odd part" (m1) and power of two
15.1606 + * (m2), exponentiate mod m1, manually exponentiate mod m2, and
15.1607 + * use Chinese Remainder Theorem to combine results.
15.1608 + */
15.1609 +
15.1610 + // Tear m apart into odd part (m1) and power of 2 (m2)
15.1611 + int p = m.getLowestSetBit(); // Max pow of 2 that divides m
15.1612 +
15.1613 + BigInteger m1 = m.shiftRight(p); // m/2**p
15.1614 + BigInteger m2 = ONE.shiftLeft(p); // 2**p
15.1615 +
15.1616 + // Calculate new base from m1
15.1617 + BigInteger base2 = (this.signum < 0 || this.compareTo(m1) >= 0
15.1618 + ? this.mod(m1) : this);
15.1619 +
15.1620 + // Caculate (base ** exponent) mod m1.
15.1621 + BigInteger a1 = (m1.equals(ONE) ? ZERO :
15.1622 + base2.oddModPow(exponent, m1));
15.1623 +
15.1624 + // Calculate (this ** exponent) mod m2
15.1625 + BigInteger a2 = base.modPow2(exponent, p);
15.1626 +
15.1627 + // Combine results using Chinese Remainder Theorem
15.1628 + BigInteger y1 = m2.modInverse(m1);
15.1629 + BigInteger y2 = m1.modInverse(m2);
15.1630 +
15.1631 + result = a1.multiply(m2).multiply(y1).add
15.1632 + (a2.multiply(m1).multiply(y2)).mod(m);
15.1633 + }
15.1634 +
15.1635 + return (invertResult ? result.modInverse(m) : result);
15.1636 + }
15.1637 +
15.1638 + static int[] bnExpModThreshTable = {7, 25, 81, 241, 673, 1793,
15.1639 + Integer.MAX_VALUE}; // Sentinel
15.1640 +
15.1641 + /**
15.1642 + * Returns a BigInteger whose value is x to the power of y mod z.
15.1643 + * Assumes: z is odd && x < z.
15.1644 + */
15.1645 + private BigInteger oddModPow(BigInteger y, BigInteger z) {
15.1646 + /*
15.1647 + * The algorithm is adapted from Colin Plumb's C library.
15.1648 + *
15.1649 + * The window algorithm:
15.1650 + * The idea is to keep a running product of b1 = n^(high-order bits of exp)
15.1651 + * and then keep appending exponent bits to it. The following patterns
15.1652 + * apply to a 3-bit window (k = 3):
15.1653 + * To append 0: square
15.1654 + * To append 1: square, multiply by n^1
15.1655 + * To append 10: square, multiply by n^1, square
15.1656 + * To append 11: square, square, multiply by n^3
15.1657 + * To append 100: square, multiply by n^1, square, square
15.1658 + * To append 101: square, square, square, multiply by n^5
15.1659 + * To append 110: square, square, multiply by n^3, square
15.1660 + * To append 111: square, square, square, multiply by n^7
15.1661 + *
15.1662 + * Since each pattern involves only one multiply, the longer the pattern
15.1663 + * the better, except that a 0 (no multiplies) can be appended directly.
15.1664 + * We precompute a table of odd powers of n, up to 2^k, and can then
15.1665 + * multiply k bits of exponent at a time. Actually, assuming random
15.1666 + * exponents, there is on average one zero bit between needs to
15.1667 + * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
15.1668 + * 1/8 of the time, there's 2, 1/32 of the time, there's 3, etc.), so
15.1669 + * you have to do one multiply per k+1 bits of exponent.
15.1670 + *
15.1671 + * The loop walks down the exponent, squaring the result buffer as
15.1672 + * it goes. There is a wbits+1 bit lookahead buffer, buf, that is
15.1673 + * filled with the upcoming exponent bits. (What is read after the
15.1674 + * end of the exponent is unimportant, but it is filled with zero here.)
15.1675 + * When the most-significant bit of this buffer becomes set, i.e.
15.1676 + * (buf & tblmask) != 0, we have to decide what pattern to multiply
15.1677 + * by, and when to do it. We decide, remember to do it in future
15.1678 + * after a suitable number of squarings have passed (e.g. a pattern
15.1679 + * of "100" in the buffer requires that we multiply by n^1 immediately;
15.1680 + * a pattern of "110" calls for multiplying by n^3 after one more
15.1681 + * squaring), clear the buffer, and continue.
15.1682 + *
15.1683 + * When we start, there is one more optimization: the result buffer
15.1684 + * is implcitly one, so squaring it or multiplying by it can be
15.1685 + * optimized away. Further, if we start with a pattern like "100"
15.1686 + * in the lookahead window, rather than placing n into the buffer
15.1687 + * and then starting to square it, we have already computed n^2
15.1688 + * to compute the odd-powers table, so we can place that into
15.1689 + * the buffer and save a squaring.
15.1690 + *
15.1691 + * This means that if you have a k-bit window, to compute n^z,
15.1692 + * where z is the high k bits of the exponent, 1/2 of the time
15.1693 + * it requires no squarings. 1/4 of the time, it requires 1
15.1694 + * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
15.1695 + * And the remaining 1/2^(k-1) of the time, the top k bits are a
15.1696 + * 1 followed by k-1 0 bits, so it again only requires k-2
15.1697 + * squarings, not k-1. The average of these is 1. Add that
15.1698 + * to the one squaring we have to do to compute the table,
15.1699 + * and you'll see that a k-bit window saves k-2 squarings
15.1700 + * as well as reducing the multiplies. (It actually doesn't
15.1701 + * hurt in the case k = 1, either.)
15.1702 + */
15.1703 + // Special case for exponent of one
15.1704 + if (y.equals(ONE))
15.1705 + return this;
15.1706 +
15.1707 + // Special case for base of zero
15.1708 + if (signum==0)
15.1709 + return ZERO;
15.1710 +
15.1711 + int[] base = mag.clone();
15.1712 + int[] exp = y.mag;
15.1713 + int[] mod = z.mag;
15.1714 + int modLen = mod.length;
15.1715 +
15.1716 + // Select an appropriate window size
15.1717 + int wbits = 0;
15.1718 + int ebits = bitLength(exp, exp.length);
15.1719 + // if exponent is 65537 (0x10001), use minimum window size
15.1720 + if ((ebits != 17) || (exp[0] != 65537)) {
15.1721 + while (ebits > bnExpModThreshTable[wbits]) {
15.1722 + wbits++;
15.1723 + }
15.1724 + }
15.1725 +
15.1726 + // Calculate appropriate table size
15.1727 + int tblmask = 1 << wbits;
15.1728 +
15.1729 + // Allocate table for precomputed odd powers of base in Montgomery form
15.1730 + int[][] table = new int[tblmask][];
15.1731 + for (int i=0; i<tblmask; i++)
15.1732 + table[i] = new int[modLen];
15.1733 +
15.1734 + // Compute the modular inverse
15.1735 + int inv = -MutableBigInteger.inverseMod32(mod[modLen-1]);
15.1736 +
15.1737 + // Convert base to Montgomery form
15.1738 + int[] a = leftShift(base, base.length, modLen << 5);
15.1739 +
15.1740 + MutableBigInteger q = new MutableBigInteger(),
15.1741 + a2 = new MutableBigInteger(a),
15.1742 + b2 = new MutableBigInteger(mod);
15.1743 +
15.1744 + MutableBigInteger r= a2.divide(b2, q);
15.1745 + table[0] = r.toIntArray();
15.1746 +
15.1747 + // Pad table[0] with leading zeros so its length is at least modLen
15.1748 + if (table[0].length < modLen) {
15.1749 + int offset = modLen - table[0].length;
15.1750 + int[] t2 = new int[modLen];
15.1751 + for (int i=0; i<table[0].length; i++)
15.1752 + t2[i+offset] = table[0][i];
15.1753 + table[0] = t2;
15.1754 + }
15.1755 +
15.1756 + // Set b to the square of the base
15.1757 + int[] b = squareToLen(table[0], modLen, null);
15.1758 + b = montReduce(b, mod, modLen, inv);
15.1759 +
15.1760 + // Set t to high half of b
15.1761 + int[] t = new int[modLen];
15.1762 + for(int i=0; i<modLen; i++)
15.1763 + t[i] = b[i];
15.1764 +
15.1765 + // Fill in the table with odd powers of the base
15.1766 + for (int i=1; i<tblmask; i++) {
15.1767 + int[] prod = multiplyToLen(t, modLen, table[i-1], modLen, null);
15.1768 + table[i] = montReduce(prod, mod, modLen, inv);
15.1769 + }
15.1770 +
15.1771 + // Pre load the window that slides over the exponent
15.1772 + int bitpos = 1 << ((ebits-1) & (32-1));
15.1773 +
15.1774 + int buf = 0;
15.1775 + int elen = exp.length;
15.1776 + int eIndex = 0;
15.1777 + for (int i = 0; i <= wbits; i++) {
15.1778 + buf = (buf << 1) | (((exp[eIndex] & bitpos) != 0)?1:0);
15.1779 + bitpos >>>= 1;
15.1780 + if (bitpos == 0) {
15.1781 + eIndex++;
15.1782 + bitpos = 1 << (32-1);
15.1783 + elen--;
15.1784 + }
15.1785 + }
15.1786 +
15.1787 + int multpos = ebits;
15.1788 +
15.1789 + // The first iteration, which is hoisted out of the main loop
15.1790 + ebits--;
15.1791 + boolean isone = true;
15.1792 +
15.1793 + multpos = ebits - wbits;
15.1794 + while ((buf & 1) == 0) {
15.1795 + buf >>>= 1;
15.1796 + multpos++;
15.1797 + }
15.1798 +
15.1799 + int[] mult = table[buf >>> 1];
15.1800 +
15.1801 + buf = 0;
15.1802 + if (multpos == ebits)
15.1803 + isone = false;
15.1804 +
15.1805 + // The main loop
15.1806 + while(true) {
15.1807 + ebits--;
15.1808 + // Advance the window
15.1809 + buf <<= 1;
15.1810 +
15.1811 + if (elen != 0) {
15.1812 + buf |= ((exp[eIndex] & bitpos) != 0) ? 1 : 0;
15.1813 + bitpos >>>= 1;
15.1814 + if (bitpos == 0) {
15.1815 + eIndex++;
15.1816 + bitpos = 1 << (32-1);
15.1817 + elen--;
15.1818 + }
15.1819 + }
15.1820 +
15.1821 + // Examine the window for pending multiplies
15.1822 + if ((buf & tblmask) != 0) {
15.1823 + multpos = ebits - wbits;
15.1824 + while ((buf & 1) == 0) {
15.1825 + buf >>>= 1;
15.1826 + multpos++;
15.1827 + }
15.1828 + mult = table[buf >>> 1];
15.1829 + buf = 0;
15.1830 + }
15.1831 +
15.1832 + // Perform multiply
15.1833 + if (ebits == multpos) {
15.1834 + if (isone) {
15.1835 + b = mult.clone();
15.1836 + isone = false;
15.1837 + } else {
15.1838 + t = b;
15.1839 + a = multiplyToLen(t, modLen, mult, modLen, a);
15.1840 + a = montReduce(a, mod, modLen, inv);
15.1841 + t = a; a = b; b = t;
15.1842 + }
15.1843 + }
15.1844 +
15.1845 + // Check if done
15.1846 + if (ebits == 0)
15.1847 + break;
15.1848 +
15.1849 + // Square the input
15.1850 + if (!isone) {
15.1851 + t = b;
15.1852 + a = squareToLen(t, modLen, a);
15.1853 + a = montReduce(a, mod, modLen, inv);
15.1854 + t = a; a = b; b = t;
15.1855 + }
15.1856 + }
15.1857 +
15.1858 + // Convert result out of Montgomery form and return
15.1859 + int[] t2 = new int[2*modLen];
15.1860 + for(int i=0; i<modLen; i++)
15.1861 + t2[i+modLen] = b[i];
15.1862 +
15.1863 + b = montReduce(t2, mod, modLen, inv);
15.1864 +
15.1865 + t2 = new int[modLen];
15.1866 + for(int i=0; i<modLen; i++)
15.1867 + t2[i] = b[i];
15.1868 +
15.1869 + return new BigInteger(1, t2);
15.1870 + }
15.1871 +
15.1872 + /**
15.1873 + * Montgomery reduce n, modulo mod. This reduces modulo mod and divides
15.1874 + * by 2^(32*mlen). Adapted from Colin Plumb's C library.
15.1875 + */
15.1876 + private static int[] montReduce(int[] n, int[] mod, int mlen, int inv) {
15.1877 + int c=0;
15.1878 + int len = mlen;
15.1879 + int offset=0;
15.1880 +
15.1881 + do {
15.1882 + int nEnd = n[n.length-1-offset];
15.1883 + int carry = mulAdd(n, mod, offset, mlen, inv * nEnd);
15.1884 + c += addOne(n, offset, mlen, carry);
15.1885 + offset++;
15.1886 + } while(--len > 0);
15.1887 +
15.1888 + while(c>0)
15.1889 + c += subN(n, mod, mlen);
15.1890 +
15.1891 + while (intArrayCmpToLen(n, mod, mlen) >= 0)
15.1892 + subN(n, mod, mlen);
15.1893 +
15.1894 + return n;
15.1895 + }
15.1896 +
15.1897 +
15.1898 + /*
15.1899 + * Returns -1, 0 or +1 as big-endian unsigned int array arg1 is less than,
15.1900 + * equal to, or greater than arg2 up to length len.
15.1901 + */
15.1902 + private static int intArrayCmpToLen(int[] arg1, int[] arg2, int len) {
15.1903 + for (int i=0; i<len; i++) {
15.1904 + long b1 = arg1[i] & LONG_MASK;
15.1905 + long b2 = arg2[i] & LONG_MASK;
15.1906 + if (b1 < b2)
15.1907 + return -1;
15.1908 + if (b1 > b2)
15.1909 + return 1;
15.1910 + }
15.1911 + return 0;
15.1912 + }
15.1913 +
15.1914 + /**
15.1915 + * Subtracts two numbers of same length, returning borrow.
15.1916 + */
15.1917 + private static int subN(int[] a, int[] b, int len) {
15.1918 + long sum = 0;
15.1919 +
15.1920 + while(--len >= 0) {
15.1921 + sum = (a[len] & LONG_MASK) -
15.1922 + (b[len] & LONG_MASK) + (sum >> 32);
15.1923 + a[len] = (int)sum;
15.1924 + }
15.1925 +
15.1926 + return (int)(sum >> 32);
15.1927 + }
15.1928 +
15.1929 + /**
15.1930 + * Multiply an array by one word k and add to result, return the carry
15.1931 + */
15.1932 + static int mulAdd(int[] out, int[] in, int offset, int len, int k) {
15.1933 + long kLong = k & LONG_MASK;
15.1934 + long carry = 0;
15.1935 +
15.1936 + offset = out.length-offset - 1;
15.1937 + for (int j=len-1; j >= 0; j--) {
15.1938 + long product = (in[j] & LONG_MASK) * kLong +
15.1939 + (out[offset] & LONG_MASK) + carry;
15.1940 + out[offset--] = (int)product;
15.1941 + carry = product >>> 32;
15.1942 + }
15.1943 + return (int)carry;
15.1944 + }
15.1945 +
15.1946 + /**
15.1947 + * Add one word to the number a mlen words into a. Return the resulting
15.1948 + * carry.
15.1949 + */
15.1950 + static int addOne(int[] a, int offset, int mlen, int carry) {
15.1951 + offset = a.length-1-mlen-offset;
15.1952 + long t = (a[offset] & LONG_MASK) + (carry & LONG_MASK);
15.1953 +
15.1954 + a[offset] = (int)t;
15.1955 + if ((t >>> 32) == 0)
15.1956 + return 0;
15.1957 + while (--mlen >= 0) {
15.1958 + if (--offset < 0) { // Carry out of number
15.1959 + return 1;
15.1960 + } else {
15.1961 + a[offset]++;
15.1962 + if (a[offset] != 0)
15.1963 + return 0;
15.1964 + }
15.1965 + }
15.1966 + return 1;
15.1967 + }
15.1968 +
15.1969 + /**
15.1970 + * Returns a BigInteger whose value is (this ** exponent) mod (2**p)
15.1971 + */
15.1972 + private BigInteger modPow2(BigInteger exponent, int p) {
15.1973 + /*
15.1974 + * Perform exponentiation using repeated squaring trick, chopping off
15.1975 + * high order bits as indicated by modulus.
15.1976 + */
15.1977 + BigInteger result = valueOf(1);
15.1978 + BigInteger baseToPow2 = this.mod2(p);
15.1979 + int expOffset = 0;
15.1980 +
15.1981 + int limit = exponent.bitLength();
15.1982 +
15.1983 + if (this.testBit(0))
15.1984 + limit = (p-1) < limit ? (p-1) : limit;
15.1985 +
15.1986 + while (expOffset < limit) {
15.1987 + if (exponent.testBit(expOffset))
15.1988 + result = result.multiply(baseToPow2).mod2(p);
15.1989 + expOffset++;
15.1990 + if (expOffset < limit)
15.1991 + baseToPow2 = baseToPow2.square().mod2(p);
15.1992 + }
15.1993 +
15.1994 + return result;
15.1995 + }
15.1996 +
15.1997 + /**
15.1998 + * Returns a BigInteger whose value is this mod(2**p).
15.1999 + * Assumes that this {@code BigInteger >= 0} and {@code p > 0}.
15.2000 + */
15.2001 + private BigInteger mod2(int p) {
15.2002 + if (bitLength() <= p)
15.2003 + return this;
15.2004 +
15.2005 + // Copy remaining ints of mag
15.2006 + int numInts = (p + 31) >>> 5;
15.2007 + int[] mag = new int[numInts];
15.2008 + for (int i=0; i<numInts; i++)
15.2009 + mag[i] = this.mag[i + (this.mag.length - numInts)];
15.2010 +
15.2011 + // Mask out any excess bits
15.2012 + int excessBits = (numInts << 5) - p;
15.2013 + mag[0] &= (1L << (32-excessBits)) - 1;
15.2014 +
15.2015 + return (mag[0]==0 ? new BigInteger(1, mag) : new BigInteger(mag, 1));
15.2016 + }
15.2017 +
15.2018 + /**
15.2019 + * Returns a BigInteger whose value is {@code (this}<sup>-1</sup> {@code mod m)}.
15.2020 + *
15.2021 + * @param m the modulus.
15.2022 + * @return {@code this}<sup>-1</sup> {@code mod m}.
15.2023 + * @throws ArithmeticException {@code m} ≤ 0, or this BigInteger
15.2024 + * has no multiplicative inverse mod m (that is, this BigInteger
15.2025 + * is not <i>relatively prime</i> to m).
15.2026 + */
15.2027 + public BigInteger modInverse(BigInteger m) {
15.2028 + if (m.signum != 1)
15.2029 + throw new ArithmeticException("BigInteger: modulus not positive");
15.2030 +
15.2031 + if (m.equals(ONE))
15.2032 + return ZERO;
15.2033 +
15.2034 + // Calculate (this mod m)
15.2035 + BigInteger modVal = this;
15.2036 + if (signum < 0 || (this.compareMagnitude(m) >= 0))
15.2037 + modVal = this.mod(m);
15.2038 +
15.2039 + if (modVal.equals(ONE))
15.2040 + return ONE;
15.2041 +
15.2042 + MutableBigInteger a = new MutableBigInteger(modVal);
15.2043 + MutableBigInteger b = new MutableBigInteger(m);
15.2044 +
15.2045 + MutableBigInteger result = a.mutableModInverse(b);
15.2046 + return result.toBigInteger(1);
15.2047 + }
15.2048 +
15.2049 + // Shift Operations
15.2050 +
15.2051 + /**
15.2052 + * Returns a BigInteger whose value is {@code (this << n)}.
15.2053 + * The shift distance, {@code n}, may be negative, in which case
15.2054 + * this method performs a right shift.
15.2055 + * (Computes <tt>floor(this * 2<sup>n</sup>)</tt>.)
15.2056 + *
15.2057 + * @param n shift distance, in bits.
15.2058 + * @return {@code this << n}
15.2059 + * @throws ArithmeticException if the shift distance is {@code
15.2060 + * Integer.MIN_VALUE}.
15.2061 + * @see #shiftRight
15.2062 + */
15.2063 + public BigInteger shiftLeft(int n) {
15.2064 + if (signum == 0)
15.2065 + return ZERO;
15.2066 + if (n==0)
15.2067 + return this;
15.2068 + if (n<0) {
15.2069 + if (n == Integer.MIN_VALUE) {
15.2070 + throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported.");
15.2071 + } else {
15.2072 + return shiftRight(-n);
15.2073 + }
15.2074 + }
15.2075 +
15.2076 + int nInts = n >>> 5;
15.2077 + int nBits = n & 0x1f;
15.2078 + int magLen = mag.length;
15.2079 + int newMag[] = null;
15.2080 +
15.2081 + if (nBits == 0) {
15.2082 + newMag = new int[magLen + nInts];
15.2083 + for (int i=0; i<magLen; i++)
15.2084 + newMag[i] = mag[i];
15.2085 + } else {
15.2086 + int i = 0;
15.2087 + int nBits2 = 32 - nBits;
15.2088 + int highBits = mag[0] >>> nBits2;
15.2089 + if (highBits != 0) {
15.2090 + newMag = new int[magLen + nInts + 1];
15.2091 + newMag[i++] = highBits;
15.2092 + } else {
15.2093 + newMag = new int[magLen + nInts];
15.2094 + }
15.2095 + int j=0;
15.2096 + while (j < magLen-1)
15.2097 + newMag[i++] = mag[j++] << nBits | mag[j] >>> nBits2;
15.2098 + newMag[i] = mag[j] << nBits;
15.2099 + }
15.2100 +
15.2101 + return new BigInteger(newMag, signum);
15.2102 + }
15.2103 +
15.2104 + /**
15.2105 + * Returns a BigInteger whose value is {@code (this >> n)}. Sign
15.2106 + * extension is performed. The shift distance, {@code n}, may be
15.2107 + * negative, in which case this method performs a left shift.
15.2108 + * (Computes <tt>floor(this / 2<sup>n</sup>)</tt>.)
15.2109 + *
15.2110 + * @param n shift distance, in bits.
15.2111 + * @return {@code this >> n}
15.2112 + * @throws ArithmeticException if the shift distance is {@code
15.2113 + * Integer.MIN_VALUE}.
15.2114 + * @see #shiftLeft
15.2115 + */
15.2116 + public BigInteger shiftRight(int n) {
15.2117 + if (n==0)
15.2118 + return this;
15.2119 + if (n<0) {
15.2120 + if (n == Integer.MIN_VALUE) {
15.2121 + throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported.");
15.2122 + } else {
15.2123 + return shiftLeft(-n);
15.2124 + }
15.2125 + }
15.2126 +
15.2127 + int nInts = n >>> 5;
15.2128 + int nBits = n & 0x1f;
15.2129 + int magLen = mag.length;
15.2130 + int newMag[] = null;
15.2131 +
15.2132 + // Special case: entire contents shifted off the end
15.2133 + if (nInts >= magLen)
15.2134 + return (signum >= 0 ? ZERO : negConst[1]);
15.2135 +
15.2136 + if (nBits == 0) {
15.2137 + int newMagLen = magLen - nInts;
15.2138 + newMag = new int[newMagLen];
15.2139 + for (int i=0; i<newMagLen; i++)
15.2140 + newMag[i] = mag[i];
15.2141 + } else {
15.2142 + int i = 0;
15.2143 + int highBits = mag[0] >>> nBits;
15.2144 + if (highBits != 0) {
15.2145 + newMag = new int[magLen - nInts];
15.2146 + newMag[i++] = highBits;
15.2147 + } else {
15.2148 + newMag = new int[magLen - nInts -1];
15.2149 + }
15.2150 +
15.2151 + int nBits2 = 32 - nBits;
15.2152 + int j=0;
15.2153 + while (j < magLen - nInts - 1)
15.2154 + newMag[i++] = (mag[j++] << nBits2) | (mag[j] >>> nBits);
15.2155 + }
15.2156 +
15.2157 + if (signum < 0) {
15.2158 + // Find out whether any one-bits were shifted off the end.
15.2159 + boolean onesLost = false;
15.2160 + for (int i=magLen-1, j=magLen-nInts; i>=j && !onesLost; i--)
15.2161 + onesLost = (mag[i] != 0);
15.2162 + if (!onesLost && nBits != 0)
15.2163 + onesLost = (mag[magLen - nInts - 1] << (32 - nBits) != 0);
15.2164 +
15.2165 + if (onesLost)
15.2166 + newMag = javaIncrement(newMag);
15.2167 + }
15.2168 +
15.2169 + return new BigInteger(newMag, signum);
15.2170 + }
15.2171 +
15.2172 + int[] javaIncrement(int[] val) {
15.2173 + int lastSum = 0;
15.2174 + for (int i=val.length-1; i >= 0 && lastSum == 0; i--)
15.2175 + lastSum = (val[i] += 1);
15.2176 + if (lastSum == 0) {
15.2177 + val = new int[val.length+1];
15.2178 + val[0] = 1;
15.2179 + }
15.2180 + return val;
15.2181 + }
15.2182 +
15.2183 + // Bitwise Operations
15.2184 +
15.2185 + /**
15.2186 + * Returns a BigInteger whose value is {@code (this & val)}. (This
15.2187 + * method returns a negative BigInteger if and only if this and val are
15.2188 + * both negative.)
15.2189 + *
15.2190 + * @param val value to be AND'ed with this BigInteger.
15.2191 + * @return {@code this & val}
15.2192 + */
15.2193 + public BigInteger and(BigInteger val) {
15.2194 + int[] result = new int[Math.max(intLength(), val.intLength())];
15.2195 + for (int i=0; i<result.length; i++)
15.2196 + result[i] = (getInt(result.length-i-1)
15.2197 + & val.getInt(result.length-i-1));
15.2198 +
15.2199 + return valueOf(result);
15.2200 + }
15.2201 +
15.2202 + /**
15.2203 + * Returns a BigInteger whose value is {@code (this | val)}. (This method
15.2204 + * returns a negative BigInteger if and only if either this or val is
15.2205 + * negative.)
15.2206 + *
15.2207 + * @param val value to be OR'ed with this BigInteger.
15.2208 + * @return {@code this | val}
15.2209 + */
15.2210 + public BigInteger or(BigInteger val) {
15.2211 + int[] result = new int[Math.max(intLength(), val.intLength())];
15.2212 + for (int i=0; i<result.length; i++)
15.2213 + result[i] = (getInt(result.length-i-1)
15.2214 + | val.getInt(result.length-i-1));
15.2215 +
15.2216 + return valueOf(result);
15.2217 + }
15.2218 +
15.2219 + /**
15.2220 + * Returns a BigInteger whose value is {@code (this ^ val)}. (This method
15.2221 + * returns a negative BigInteger if and only if exactly one of this and
15.2222 + * val are negative.)
15.2223 + *
15.2224 + * @param val value to be XOR'ed with this BigInteger.
15.2225 + * @return {@code this ^ val}
15.2226 + */
15.2227 + public BigInteger xor(BigInteger val) {
15.2228 + int[] result = new int[Math.max(intLength(), val.intLength())];
15.2229 + for (int i=0; i<result.length; i++)
15.2230 + result[i] = (getInt(result.length-i-1)
15.2231 + ^ val.getInt(result.length-i-1));
15.2232 +
15.2233 + return valueOf(result);
15.2234 + }
15.2235 +
15.2236 + /**
15.2237 + * Returns a BigInteger whose value is {@code (~this)}. (This method
15.2238 + * returns a negative value if and only if this BigInteger is
15.2239 + * non-negative.)
15.2240 + *
15.2241 + * @return {@code ~this}
15.2242 + */
15.2243 + public BigInteger not() {
15.2244 + int[] result = new int[intLength()];
15.2245 + for (int i=0; i<result.length; i++)
15.2246 + result[i] = ~getInt(result.length-i-1);
15.2247 +
15.2248 + return valueOf(result);
15.2249 + }
15.2250 +
15.2251 + /**
15.2252 + * Returns a BigInteger whose value is {@code (this & ~val)}. This
15.2253 + * method, which is equivalent to {@code and(val.not())}, is provided as
15.2254 + * a convenience for masking operations. (This method returns a negative
15.2255 + * BigInteger if and only if {@code this} is negative and {@code val} is
15.2256 + * positive.)
15.2257 + *
15.2258 + * @param val value to be complemented and AND'ed with this BigInteger.
15.2259 + * @return {@code this & ~val}
15.2260 + */
15.2261 + public BigInteger andNot(BigInteger val) {
15.2262 + int[] result = new int[Math.max(intLength(), val.intLength())];
15.2263 + for (int i=0; i<result.length; i++)
15.2264 + result[i] = (getInt(result.length-i-1)
15.2265 + & ~val.getInt(result.length-i-1));
15.2266 +
15.2267 + return valueOf(result);
15.2268 + }
15.2269 +
15.2270 +
15.2271 + // Single Bit Operations
15.2272 +
15.2273 + /**
15.2274 + * Returns {@code true} if and only if the designated bit is set.
15.2275 + * (Computes {@code ((this & (1<<n)) != 0)}.)
15.2276 + *
15.2277 + * @param n index of bit to test.
15.2278 + * @return {@code true} if and only if the designated bit is set.
15.2279 + * @throws ArithmeticException {@code n} is negative.
15.2280 + */
15.2281 + public boolean testBit(int n) {
15.2282 + if (n<0)
15.2283 + throw new ArithmeticException("Negative bit address");
15.2284 +
15.2285 + return (getInt(n >>> 5) & (1 << (n & 31))) != 0;
15.2286 + }
15.2287 +
15.2288 + /**
15.2289 + * Returns a BigInteger whose value is equivalent to this BigInteger
15.2290 + * with the designated bit set. (Computes {@code (this | (1<<n))}.)
15.2291 + *
15.2292 + * @param n index of bit to set.
15.2293 + * @return {@code this | (1<<n)}
15.2294 + * @throws ArithmeticException {@code n} is negative.
15.2295 + */
15.2296 + public BigInteger setBit(int n) {
15.2297 + if (n<0)
15.2298 + throw new ArithmeticException("Negative bit address");
15.2299 +
15.2300 + int intNum = n >>> 5;
15.2301 + int[] result = new int[Math.max(intLength(), intNum+2)];
15.2302 +
15.2303 + for (int i=0; i<result.length; i++)
15.2304 + result[result.length-i-1] = getInt(i);
15.2305 +
15.2306 + result[result.length-intNum-1] |= (1 << (n & 31));
15.2307 +
15.2308 + return valueOf(result);
15.2309 + }
15.2310 +
15.2311 + /**
15.2312 + * Returns a BigInteger whose value is equivalent to this BigInteger
15.2313 + * with the designated bit cleared.
15.2314 + * (Computes {@code (this & ~(1<<n))}.)
15.2315 + *
15.2316 + * @param n index of bit to clear.
15.2317 + * @return {@code this & ~(1<<n)}
15.2318 + * @throws ArithmeticException {@code n} is negative.
15.2319 + */
15.2320 + public BigInteger clearBit(int n) {
15.2321 + if (n<0)
15.2322 + throw new ArithmeticException("Negative bit address");
15.2323 +
15.2324 + int intNum = n >>> 5;
15.2325 + int[] result = new int[Math.max(intLength(), ((n + 1) >>> 5) + 1)];
15.2326 +
15.2327 + for (int i=0; i<result.length; i++)
15.2328 + result[result.length-i-1] = getInt(i);
15.2329 +
15.2330 + result[result.length-intNum-1] &= ~(1 << (n & 31));
15.2331 +
15.2332 + return valueOf(result);
15.2333 + }
15.2334 +
15.2335 + /**
15.2336 + * Returns a BigInteger whose value is equivalent to this BigInteger
15.2337 + * with the designated bit flipped.
15.2338 + * (Computes {@code (this ^ (1<<n))}.)
15.2339 + *
15.2340 + * @param n index of bit to flip.
15.2341 + * @return {@code this ^ (1<<n)}
15.2342 + * @throws ArithmeticException {@code n} is negative.
15.2343 + */
15.2344 + public BigInteger flipBit(int n) {
15.2345 + if (n<0)
15.2346 + throw new ArithmeticException("Negative bit address");
15.2347 +
15.2348 + int intNum = n >>> 5;
15.2349 + int[] result = new int[Math.max(intLength(), intNum+2)];
15.2350 +
15.2351 + for (int i=0; i<result.length; i++)
15.2352 + result[result.length-i-1] = getInt(i);
15.2353 +
15.2354 + result[result.length-intNum-1] ^= (1 << (n & 31));
15.2355 +
15.2356 + return valueOf(result);
15.2357 + }
15.2358 +
15.2359 + /**
15.2360 + * Returns the index of the rightmost (lowest-order) one bit in this
15.2361 + * BigInteger (the number of zero bits to the right of the rightmost
15.2362 + * one bit). Returns -1 if this BigInteger contains no one bits.
15.2363 + * (Computes {@code (this==0? -1 : log2(this & -this))}.)
15.2364 + *
15.2365 + * @return index of the rightmost one bit in this BigInteger.
15.2366 + */
15.2367 + public int getLowestSetBit() {
15.2368 + @SuppressWarnings("deprecation") int lsb = lowestSetBit - 2;
15.2369 + if (lsb == -2) { // lowestSetBit not initialized yet
15.2370 + lsb = 0;
15.2371 + if (signum == 0) {
15.2372 + lsb -= 1;
15.2373 + } else {
15.2374 + // Search for lowest order nonzero int
15.2375 + int i,b;
15.2376 + for (i=0; (b = getInt(i))==0; i++)
15.2377 + ;
15.2378 + lsb += (i << 5) + Integer.numberOfTrailingZeros(b);
15.2379 + }
15.2380 + lowestSetBit = lsb + 2;
15.2381 + }
15.2382 + return lsb;
15.2383 + }
15.2384 +
15.2385 +
15.2386 + // Miscellaneous Bit Operations
15.2387 +
15.2388 + /**
15.2389 + * Returns the number of bits in the minimal two's-complement
15.2390 + * representation of this BigInteger, <i>excluding</i> a sign bit.
15.2391 + * For positive BigIntegers, this is equivalent to the number of bits in
15.2392 + * the ordinary binary representation. (Computes
15.2393 + * {@code (ceil(log2(this < 0 ? -this : this+1)))}.)
15.2394 + *
15.2395 + * @return number of bits in the minimal two's-complement
15.2396 + * representation of this BigInteger, <i>excluding</i> a sign bit.
15.2397 + */
15.2398 + public int bitLength() {
15.2399 + @SuppressWarnings("deprecation") int n = bitLength - 1;
15.2400 + if (n == -1) { // bitLength not initialized yet
15.2401 + int[] m = mag;
15.2402 + int len = m.length;
15.2403 + if (len == 0) {
15.2404 + n = 0; // offset by one to initialize
15.2405 + } else {
15.2406 + // Calculate the bit length of the magnitude
15.2407 + int magBitLength = ((len - 1) << 5) + bitLengthForInt(mag[0]);
15.2408 + if (signum < 0) {
15.2409 + // Check if magnitude is a power of two
15.2410 + boolean pow2 = (Integer.bitCount(mag[0]) == 1);
15.2411 + for(int i=1; i< len && pow2; i++)
15.2412 + pow2 = (mag[i] == 0);
15.2413 +
15.2414 + n = (pow2 ? magBitLength -1 : magBitLength);
15.2415 + } else {
15.2416 + n = magBitLength;
15.2417 + }
15.2418 + }
15.2419 + bitLength = n + 1;
15.2420 + }
15.2421 + return n;
15.2422 + }
15.2423 +
15.2424 + /**
15.2425 + * Returns the number of bits in the two's complement representation
15.2426 + * of this BigInteger that differ from its sign bit. This method is
15.2427 + * useful when implementing bit-vector style sets atop BigIntegers.
15.2428 + *
15.2429 + * @return number of bits in the two's complement representation
15.2430 + * of this BigInteger that differ from its sign bit.
15.2431 + */
15.2432 + public int bitCount() {
15.2433 + @SuppressWarnings("deprecation") int bc = bitCount - 1;
15.2434 + if (bc == -1) { // bitCount not initialized yet
15.2435 + bc = 0; // offset by one to initialize
15.2436 + // Count the bits in the magnitude
15.2437 + for (int i=0; i<mag.length; i++)
15.2438 + bc += Integer.bitCount(mag[i]);
15.2439 + if (signum < 0) {
15.2440 + // Count the trailing zeros in the magnitude
15.2441 + int magTrailingZeroCount = 0, j;
15.2442 + for (j=mag.length-1; mag[j]==0; j--)
15.2443 + magTrailingZeroCount += 32;
15.2444 + magTrailingZeroCount += Integer.numberOfTrailingZeros(mag[j]);
15.2445 + bc += magTrailingZeroCount - 1;
15.2446 + }
15.2447 + bitCount = bc + 1;
15.2448 + }
15.2449 + return bc;
15.2450 + }
15.2451 +
15.2452 + // Primality Testing
15.2453 +
15.2454 + /**
15.2455 + * Returns {@code true} if this BigInteger is probably prime,
15.2456 + * {@code false} if it's definitely composite. If
15.2457 + * {@code certainty} is ≤ 0, {@code true} is
15.2458 + * returned.
15.2459 + *
15.2460 + * @param certainty a measure of the uncertainty that the caller is
15.2461 + * willing to tolerate: if the call returns {@code true}
15.2462 + * the probability that this BigInteger is prime exceeds
15.2463 + * (1 - 1/2<sup>{@code certainty}</sup>). The execution time of
15.2464 + * this method is proportional to the value of this parameter.
15.2465 + * @return {@code true} if this BigInteger is probably prime,
15.2466 + * {@code false} if it's definitely composite.
15.2467 + */
15.2468 + public boolean isProbablePrime(int certainty) {
15.2469 + if (certainty <= 0)
15.2470 + return true;
15.2471 + BigInteger w = this.abs();
15.2472 + if (w.equals(TWO))
15.2473 + return true;
15.2474 + if (!w.testBit(0) || w.equals(ONE))
15.2475 + return false;
15.2476 +
15.2477 + return w.primeToCertainty(certainty, null);
15.2478 + }
15.2479 +
15.2480 + // Comparison Operations
15.2481 +
15.2482 + /**
15.2483 + * Compares this BigInteger with the specified BigInteger. This
15.2484 + * method is provided in preference to individual methods for each
15.2485 + * of the six boolean comparison operators ({@literal <}, ==,
15.2486 + * {@literal >}, {@literal >=}, !=, {@literal <=}). The suggested
15.2487 + * idiom for performing these comparisons is: {@code
15.2488 + * (x.compareTo(y)} <<i>op</i>> {@code 0)}, where
15.2489 + * <<i>op</i>> is one of the six comparison operators.
15.2490 + *
15.2491 + * @param val BigInteger to which this BigInteger is to be compared.
15.2492 + * @return -1, 0 or 1 as this BigInteger is numerically less than, equal
15.2493 + * to, or greater than {@code val}.
15.2494 + */
15.2495 + public int compareTo(BigInteger val) {
15.2496 + if (signum == val.signum) {
15.2497 + switch (signum) {
15.2498 + case 1:
15.2499 + return compareMagnitude(val);
15.2500 + case -1:
15.2501 + return val.compareMagnitude(this);
15.2502 + default:
15.2503 + return 0;
15.2504 + }
15.2505 + }
15.2506 + return signum > val.signum ? 1 : -1;
15.2507 + }
15.2508 +
15.2509 + /**
15.2510 + * Compares the magnitude array of this BigInteger with the specified
15.2511 + * BigInteger's. This is the version of compareTo ignoring sign.
15.2512 + *
15.2513 + * @param val BigInteger whose magnitude array to be compared.
15.2514 + * @return -1, 0 or 1 as this magnitude array is less than, equal to or
15.2515 + * greater than the magnitude aray for the specified BigInteger's.
15.2516 + */
15.2517 + final int compareMagnitude(BigInteger val) {
15.2518 + int[] m1 = mag;
15.2519 + int len1 = m1.length;
15.2520 + int[] m2 = val.mag;
15.2521 + int len2 = m2.length;
15.2522 + if (len1 < len2)
15.2523 + return -1;
15.2524 + if (len1 > len2)
15.2525 + return 1;
15.2526 + for (int i = 0; i < len1; i++) {
15.2527 + int a = m1[i];
15.2528 + int b = m2[i];
15.2529 + if (a != b)
15.2530 + return ((a & LONG_MASK) < (b & LONG_MASK)) ? -1 : 1;
15.2531 + }
15.2532 + return 0;
15.2533 + }
15.2534 +
15.2535 + /**
15.2536 + * Compares this BigInteger with the specified Object for equality.
15.2537 + *
15.2538 + * @param x Object to which this BigInteger is to be compared.
15.2539 + * @return {@code true} if and only if the specified Object is a
15.2540 + * BigInteger whose value is numerically equal to this BigInteger.
15.2541 + */
15.2542 + public boolean equals(Object x) {
15.2543 + // This test is just an optimization, which may or may not help
15.2544 + if (x == this)
15.2545 + return true;
15.2546 +
15.2547 + if (!(x instanceof BigInteger))
15.2548 + return false;
15.2549 +
15.2550 + BigInteger xInt = (BigInteger) x;
15.2551 + if (xInt.signum != signum)
15.2552 + return false;
15.2553 +
15.2554 + int[] m = mag;
15.2555 + int len = m.length;
15.2556 + int[] xm = xInt.mag;
15.2557 + if (len != xm.length)
15.2558 + return false;
15.2559 +
15.2560 + for (int i = 0; i < len; i++)
15.2561 + if (xm[i] != m[i])
15.2562 + return false;
15.2563 +
15.2564 + return true;
15.2565 + }
15.2566 +
15.2567 + /**
15.2568 + * Returns the minimum of this BigInteger and {@code val}.
15.2569 + *
15.2570 + * @param val value with which the minimum is to be computed.
15.2571 + * @return the BigInteger whose value is the lesser of this BigInteger and
15.2572 + * {@code val}. If they are equal, either may be returned.
15.2573 + */
15.2574 + public BigInteger min(BigInteger val) {
15.2575 + return (compareTo(val)<0 ? this : val);
15.2576 + }
15.2577 +
15.2578 + /**
15.2579 + * Returns the maximum of this BigInteger and {@code val}.
15.2580 + *
15.2581 + * @param val value with which the maximum is to be computed.
15.2582 + * @return the BigInteger whose value is the greater of this and
15.2583 + * {@code val}. If they are equal, either may be returned.
15.2584 + */
15.2585 + public BigInteger max(BigInteger val) {
15.2586 + return (compareTo(val)>0 ? this : val);
15.2587 + }
15.2588 +
15.2589 +
15.2590 + // Hash Function
15.2591 +
15.2592 + /**
15.2593 + * Returns the hash code for this BigInteger.
15.2594 + *
15.2595 + * @return hash code for this BigInteger.
15.2596 + */
15.2597 + public int hashCode() {
15.2598 + int hashCode = 0;
15.2599 +
15.2600 + for (int i=0; i<mag.length; i++)
15.2601 + hashCode = (int)(31*hashCode + (mag[i] & LONG_MASK));
15.2602 +
15.2603 + return hashCode * signum;
15.2604 + }
15.2605 +
15.2606 + /**
15.2607 + * Returns the String representation of this BigInteger in the
15.2608 + * given radix. If the radix is outside the range from {@link
15.2609 + * Character#MIN_RADIX} to {@link Character#MAX_RADIX} inclusive,
15.2610 + * it will default to 10 (as is the case for
15.2611 + * {@code Integer.toString}). The digit-to-character mapping
15.2612 + * provided by {@code Character.forDigit} is used, and a minus
15.2613 + * sign is prepended if appropriate. (This representation is
15.2614 + * compatible with the {@link #BigInteger(String, int) (String,
15.2615 + * int)} constructor.)
15.2616 + *
15.2617 + * @param radix radix of the String representation.
15.2618 + * @return String representation of this BigInteger in the given radix.
15.2619 + * @see Integer#toString
15.2620 + * @see Character#forDigit
15.2621 + * @see #BigInteger(java.lang.String, int)
15.2622 + */
15.2623 + public String toString(int radix) {
15.2624 + if (signum == 0)
15.2625 + return "0";
15.2626 + if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
15.2627 + radix = 10;
15.2628 +
15.2629 + // Compute upper bound on number of digit groups and allocate space
15.2630 + int maxNumDigitGroups = (4*mag.length + 6)/7;
15.2631 + String digitGroup[] = new String[maxNumDigitGroups];
15.2632 +
15.2633 + // Translate number to string, a digit group at a time
15.2634 + BigInteger tmp = this.abs();
15.2635 + int numGroups = 0;
15.2636 + while (tmp.signum != 0) {
15.2637 + BigInteger d = longRadix[radix];
15.2638 +
15.2639 + MutableBigInteger q = new MutableBigInteger(),
15.2640 + a = new MutableBigInteger(tmp.mag),
15.2641 + b = new MutableBigInteger(d.mag);
15.2642 + MutableBigInteger r = a.divide(b, q);
15.2643 + BigInteger q2 = q.toBigInteger(tmp.signum * d.signum);
15.2644 + BigInteger r2 = r.toBigInteger(tmp.signum * d.signum);
15.2645 +
15.2646 + digitGroup[numGroups++] = Long.toString(r2.longValue(), radix);
15.2647 + tmp = q2;
15.2648 + }
15.2649 +
15.2650 + // Put sign (if any) and first digit group into result buffer
15.2651 + StringBuilder buf = new StringBuilder(numGroups*digitsPerLong[radix]+1);
15.2652 + if (signum<0)
15.2653 + buf.append('-');
15.2654 + buf.append(digitGroup[numGroups-1]);
15.2655 +
15.2656 + // Append remaining digit groups padded with leading zeros
15.2657 + for (int i=numGroups-2; i>=0; i--) {
15.2658 + // Prepend (any) leading zeros for this digit group
15.2659 + int numLeadingZeros = digitsPerLong[radix]-digitGroup[i].length();
15.2660 + if (numLeadingZeros != 0)
15.2661 + buf.append(zeros[numLeadingZeros]);
15.2662 + buf.append(digitGroup[i]);
15.2663 + }
15.2664 + return buf.toString();
15.2665 + }
15.2666 +
15.2667 + /* zero[i] is a string of i consecutive zeros. */
15.2668 + private static String zeros[] = new String[64];
15.2669 + static {
15.2670 + zeros[63] =
15.2671 + "000000000000000000000000000000000000000000000000000000000000000";
15.2672 + for (int i=0; i<63; i++)
15.2673 + zeros[i] = zeros[63].substring(0, i);
15.2674 + }
15.2675 +
15.2676 + /**
15.2677 + * Returns the decimal String representation of this BigInteger.
15.2678 + * The digit-to-character mapping provided by
15.2679 + * {@code Character.forDigit} is used, and a minus sign is
15.2680 + * prepended if appropriate. (This representation is compatible
15.2681 + * with the {@link #BigInteger(String) (String)} constructor, and
15.2682 + * allows for String concatenation with Java's + operator.)
15.2683 + *
15.2684 + * @return decimal String representation of this BigInteger.
15.2685 + * @see Character#forDigit
15.2686 + * @see #BigInteger(java.lang.String)
15.2687 + */
15.2688 + public String toString() {
15.2689 + return toString(10);
15.2690 + }
15.2691 +
15.2692 + /**
15.2693 + * Returns a byte array containing the two's-complement
15.2694 + * representation of this BigInteger. The byte array will be in
15.2695 + * <i>big-endian</i> byte-order: the most significant byte is in
15.2696 + * the zeroth element. The array will contain the minimum number
15.2697 + * of bytes required to represent this BigInteger, including at
15.2698 + * least one sign bit, which is {@code (ceil((this.bitLength() +
15.2699 + * 1)/8))}. (This representation is compatible with the
15.2700 + * {@link #BigInteger(byte[]) (byte[])} constructor.)
15.2701 + *
15.2702 + * @return a byte array containing the two's-complement representation of
15.2703 + * this BigInteger.
15.2704 + * @see #BigInteger(byte[])
15.2705 + */
15.2706 + public byte[] toByteArray() {
15.2707 + int byteLen = bitLength()/8 + 1;
15.2708 + byte[] byteArray = new byte[byteLen];
15.2709 +
15.2710 + for (int i=byteLen-1, bytesCopied=4, nextInt=0, intIndex=0; i>=0; i--) {
15.2711 + if (bytesCopied == 4) {
15.2712 + nextInt = getInt(intIndex++);
15.2713 + bytesCopied = 1;
15.2714 + } else {
15.2715 + nextInt >>>= 8;
15.2716 + bytesCopied++;
15.2717 + }
15.2718 + byteArray[i] = (byte)nextInt;
15.2719 + }
15.2720 + return byteArray;
15.2721 + }
15.2722 +
15.2723 + /**
15.2724 + * Converts this BigInteger to an {@code int}. This
15.2725 + * conversion is analogous to a
15.2726 + * <i>narrowing primitive conversion</i> from {@code long} to
15.2727 + * {@code int} as defined in section 5.1.3 of
15.2728 + * <cite>The Java™ Language Specification</cite>:
15.2729 + * if this BigInteger is too big to fit in an
15.2730 + * {@code int}, only the low-order 32 bits are returned.
15.2731 + * Note that this conversion can lose information about the
15.2732 + * overall magnitude of the BigInteger value as well as return a
15.2733 + * result with the opposite sign.
15.2734 + *
15.2735 + * @return this BigInteger converted to an {@code int}.
15.2736 + */
15.2737 + public int intValue() {
15.2738 + int result = 0;
15.2739 + result = getInt(0);
15.2740 + return result;
15.2741 + }
15.2742 +
15.2743 + /**
15.2744 + * Converts this BigInteger to a {@code long}. This
15.2745 + * conversion is analogous to a
15.2746 + * <i>narrowing primitive conversion</i> from {@code long} to
15.2747 + * {@code int} as defined in section 5.1.3 of
15.2748 + * <cite>The Java™ Language Specification</cite>:
15.2749 + * if this BigInteger is too big to fit in a
15.2750 + * {@code long}, only the low-order 64 bits are returned.
15.2751 + * Note that this conversion can lose information about the
15.2752 + * overall magnitude of the BigInteger value as well as return a
15.2753 + * result with the opposite sign.
15.2754 + *
15.2755 + * @return this BigInteger converted to a {@code long}.
15.2756 + */
15.2757 + public long longValue() {
15.2758 + long result = 0;
15.2759 +
15.2760 + for (int i=1; i>=0; i--)
15.2761 + result = (result << 32) + (getInt(i) & LONG_MASK);
15.2762 + return result;
15.2763 + }
15.2764 +
15.2765 + /**
15.2766 + * Converts this BigInteger to a {@code float}. This
15.2767 + * conversion is similar to the
15.2768 + * <i>narrowing primitive conversion</i> from {@code double} to
15.2769 + * {@code float} as defined in section 5.1.3 of
15.2770 + * <cite>The Java™ Language Specification</cite>:
15.2771 + * if this BigInteger has too great a magnitude
15.2772 + * to represent as a {@code float}, it will be converted to
15.2773 + * {@link Float#NEGATIVE_INFINITY} or {@link
15.2774 + * Float#POSITIVE_INFINITY} as appropriate. Note that even when
15.2775 + * the return value is finite, this conversion can lose
15.2776 + * information about the precision of the BigInteger value.
15.2777 + *
15.2778 + * @return this BigInteger converted to a {@code float}.
15.2779 + */
15.2780 + public float floatValue() {
15.2781 + // Somewhat inefficient, but guaranteed to work.
15.2782 + return Float.parseFloat(this.toString());
15.2783 + }
15.2784 +
15.2785 + /**
15.2786 + * Converts this BigInteger to a {@code double}. This
15.2787 + * conversion is similar to the
15.2788 + * <i>narrowing primitive conversion</i> from {@code double} to
15.2789 + * {@code float} as defined in section 5.1.3 of
15.2790 + * <cite>The Java™ Language Specification</cite>:
15.2791 + * if this BigInteger has too great a magnitude
15.2792 + * to represent as a {@code double}, it will be converted to
15.2793 + * {@link Double#NEGATIVE_INFINITY} or {@link
15.2794 + * Double#POSITIVE_INFINITY} as appropriate. Note that even when
15.2795 + * the return value is finite, this conversion can lose
15.2796 + * information about the precision of the BigInteger value.
15.2797 + *
15.2798 + * @return this BigInteger converted to a {@code double}.
15.2799 + */
15.2800 + public double doubleValue() {
15.2801 + // Somewhat inefficient, but guaranteed to work.
15.2802 + return Double.parseDouble(this.toString());
15.2803 + }
15.2804 +
15.2805 + /**
15.2806 + * Returns a copy of the input array stripped of any leading zero bytes.
15.2807 + */
15.2808 + private static int[] stripLeadingZeroInts(int val[]) {
15.2809 + int vlen = val.length;
15.2810 + int keep;
15.2811 +
15.2812 + // Find first nonzero byte
15.2813 + for (keep = 0; keep < vlen && val[keep] == 0; keep++)
15.2814 + ;
15.2815 + return java.util.Arrays.copyOfRange(val, keep, vlen);
15.2816 + }
15.2817 +
15.2818 + /**
15.2819 + * Returns the input array stripped of any leading zero bytes.
15.2820 + * Since the source is trusted the copying may be skipped.
15.2821 + */
15.2822 + private static int[] trustedStripLeadingZeroInts(int val[]) {
15.2823 + int vlen = val.length;
15.2824 + int keep;
15.2825 +
15.2826 + // Find first nonzero byte
15.2827 + for (keep = 0; keep < vlen && val[keep] == 0; keep++)
15.2828 + ;
15.2829 + return keep == 0 ? val : java.util.Arrays.copyOfRange(val, keep, vlen);
15.2830 + }
15.2831 +
15.2832 + /**
15.2833 + * Returns a copy of the input array stripped of any leading zero bytes.
15.2834 + */
15.2835 + private static int[] stripLeadingZeroBytes(byte a[]) {
15.2836 + int byteLength = a.length;
15.2837 + int keep;
15.2838 +
15.2839 + // Find first nonzero byte
15.2840 + for (keep = 0; keep < byteLength && a[keep]==0; keep++)
15.2841 + ;
15.2842 +
15.2843 + // Allocate new array and copy relevant part of input array
15.2844 + int intLength = ((byteLength - keep) + 3) >>> 2;
15.2845 + int[] result = new int[intLength];
15.2846 + int b = byteLength - 1;
15.2847 + for (int i = intLength-1; i >= 0; i--) {
15.2848 + result[i] = a[b--] & 0xff;
15.2849 + int bytesRemaining = b - keep + 1;
15.2850 + int bytesToTransfer = Math.min(3, bytesRemaining);
15.2851 + for (int j=8; j <= (bytesToTransfer << 3); j += 8)
15.2852 + result[i] |= ((a[b--] & 0xff) << j);
15.2853 + }
15.2854 + return result;
15.2855 + }
15.2856 +
15.2857 + /**
15.2858 + * Takes an array a representing a negative 2's-complement number and
15.2859 + * returns the minimal (no leading zero bytes) unsigned whose value is -a.
15.2860 + */
15.2861 + private static int[] makePositive(byte a[]) {
15.2862 + int keep, k;
15.2863 + int byteLength = a.length;
15.2864 +
15.2865 + // Find first non-sign (0xff) byte of input
15.2866 + for (keep=0; keep<byteLength && a[keep]==-1; keep++)
15.2867 + ;
15.2868 +
15.2869 +
15.2870 + /* Allocate output array. If all non-sign bytes are 0x00, we must
15.2871 + * allocate space for one extra output byte. */
15.2872 + for (k=keep; k<byteLength && a[k]==0; k++)
15.2873 + ;
15.2874 +
15.2875 + int extraByte = (k==byteLength) ? 1 : 0;
15.2876 + int intLength = ((byteLength - keep + extraByte) + 3)/4;
15.2877 + int result[] = new int[intLength];
15.2878 +
15.2879 + /* Copy one's complement of input into output, leaving extra
15.2880 + * byte (if it exists) == 0x00 */
15.2881 + int b = byteLength - 1;
15.2882 + for (int i = intLength-1; i >= 0; i--) {
15.2883 + result[i] = a[b--] & 0xff;
15.2884 + int numBytesToTransfer = Math.min(3, b-keep+1);
15.2885 + if (numBytesToTransfer < 0)
15.2886 + numBytesToTransfer = 0;
15.2887 + for (int j=8; j <= 8*numBytesToTransfer; j += 8)
15.2888 + result[i] |= ((a[b--] & 0xff) << j);
15.2889 +
15.2890 + // Mask indicates which bits must be complemented
15.2891 + int mask = -1 >>> (8*(3-numBytesToTransfer));
15.2892 + result[i] = ~result[i] & mask;
15.2893 + }
15.2894 +
15.2895 + // Add one to one's complement to generate two's complement
15.2896 + for (int i=result.length-1; i>=0; i--) {
15.2897 + result[i] = (int)((result[i] & LONG_MASK) + 1);
15.2898 + if (result[i] != 0)
15.2899 + break;
15.2900 + }
15.2901 +
15.2902 + return result;
15.2903 + }
15.2904 +
15.2905 + /**
15.2906 + * Takes an array a representing a negative 2's-complement number and
15.2907 + * returns the minimal (no leading zero ints) unsigned whose value is -a.
15.2908 + */
15.2909 + private static int[] makePositive(int a[]) {
15.2910 + int keep, j;
15.2911 +
15.2912 + // Find first non-sign (0xffffffff) int of input
15.2913 + for (keep=0; keep<a.length && a[keep]==-1; keep++)
15.2914 + ;
15.2915 +
15.2916 + /* Allocate output array. If all non-sign ints are 0x00, we must
15.2917 + * allocate space for one extra output int. */
15.2918 + for (j=keep; j<a.length && a[j]==0; j++)
15.2919 + ;
15.2920 + int extraInt = (j==a.length ? 1 : 0);
15.2921 + int result[] = new int[a.length - keep + extraInt];
15.2922 +
15.2923 + /* Copy one's complement of input into output, leaving extra
15.2924 + * int (if it exists) == 0x00 */
15.2925 + for (int i = keep; i<a.length; i++)
15.2926 + result[i - keep + extraInt] = ~a[i];
15.2927 +
15.2928 + // Add one to one's complement to generate two's complement
15.2929 + for (int i=result.length-1; ++result[i]==0; i--)
15.2930 + ;
15.2931 +
15.2932 + return result;
15.2933 + }
15.2934 +
15.2935 + /*
15.2936 + * The following two arrays are used for fast String conversions. Both
15.2937 + * are indexed by radix. The first is the number of digits of the given
15.2938 + * radix that can fit in a Java long without "going negative", i.e., the
15.2939 + * highest integer n such that radix**n < 2**63. The second is the
15.2940 + * "long radix" that tears each number into "long digits", each of which
15.2941 + * consists of the number of digits in the corresponding element in
15.2942 + * digitsPerLong (longRadix[i] = i**digitPerLong[i]). Both arrays have
15.2943 + * nonsense values in their 0 and 1 elements, as radixes 0 and 1 are not
15.2944 + * used.
15.2945 + */
15.2946 + private static int digitsPerLong[] = {0, 0,
15.2947 + 62, 39, 31, 27, 24, 22, 20, 19, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14,
15.2948 + 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12};
15.2949 +
15.2950 + private static BigInteger longRadix[] = {null, null,
15.2951 + valueOf(0x4000000000000000L), valueOf(0x383d9170b85ff80bL),
15.2952 + valueOf(0x4000000000000000L), valueOf(0x6765c793fa10079dL),
15.2953 + valueOf(0x41c21cb8e1000000L), valueOf(0x3642798750226111L),
15.2954 + valueOf(0x1000000000000000L), valueOf(0x12bf307ae81ffd59L),
15.2955 + valueOf( 0xde0b6b3a7640000L), valueOf(0x4d28cb56c33fa539L),
15.2956 + valueOf(0x1eca170c00000000L), valueOf(0x780c7372621bd74dL),
15.2957 + valueOf(0x1e39a5057d810000L), valueOf(0x5b27ac993df97701L),
15.2958 + valueOf(0x1000000000000000L), valueOf(0x27b95e997e21d9f1L),
15.2959 + valueOf(0x5da0e1e53c5c8000L), valueOf( 0xb16a458ef403f19L),
15.2960 + valueOf(0x16bcc41e90000000L), valueOf(0x2d04b7fdd9c0ef49L),
15.2961 + valueOf(0x5658597bcaa24000L), valueOf( 0x6feb266931a75b7L),
15.2962 + valueOf( 0xc29e98000000000L), valueOf(0x14adf4b7320334b9L),
15.2963 + valueOf(0x226ed36478bfa000L), valueOf(0x383d9170b85ff80bL),
15.2964 + valueOf(0x5a3c23e39c000000L), valueOf( 0x4e900abb53e6b71L),
15.2965 + valueOf( 0x7600ec618141000L), valueOf( 0xaee5720ee830681L),
15.2966 + valueOf(0x1000000000000000L), valueOf(0x172588ad4f5f0981L),
15.2967 + valueOf(0x211e44f7d02c1000L), valueOf(0x2ee56725f06e5c71L),
15.2968 + valueOf(0x41c21cb8e1000000L)};
15.2969 +
15.2970 + /*
15.2971 + * These two arrays are the integer analogue of above.
15.2972 + */
15.2973 + private static int digitsPerInt[] = {0, 0, 30, 19, 15, 13, 11,
15.2974 + 11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
15.2975 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5};
15.2976 +
15.2977 + private static int intRadix[] = {0, 0,
15.2978 + 0x40000000, 0x4546b3db, 0x40000000, 0x48c27395, 0x159fd800,
15.2979 + 0x75db9c97, 0x40000000, 0x17179149, 0x3b9aca00, 0xcc6db61,
15.2980 + 0x19a10000, 0x309f1021, 0x57f6c100, 0xa2f1b6f, 0x10000000,
15.2981 + 0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d,
15.2982 + 0x6c20a40, 0x8d2d931, 0xb640000, 0xe8d4a51, 0x1269ae40,
15.2983 + 0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41,
15.2984 + 0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x39aa400
15.2985 + };
15.2986 +
15.2987 + /**
15.2988 + * These routines provide access to the two's complement representation
15.2989 + * of BigIntegers.
15.2990 + */
15.2991 +
15.2992 + /**
15.2993 + * Returns the length of the two's complement representation in ints,
15.2994 + * including space for at least one sign bit.
15.2995 + */
15.2996 + private int intLength() {
15.2997 + return (bitLength() >>> 5) + 1;
15.2998 + }
15.2999 +
15.3000 + /* Returns sign bit */
15.3001 + private int signBit() {
15.3002 + return signum < 0 ? 1 : 0;
15.3003 + }
15.3004 +
15.3005 + /* Returns an int of sign bits */
15.3006 + private int signInt() {
15.3007 + return signum < 0 ? -1 : 0;
15.3008 + }
15.3009 +
15.3010 + /**
15.3011 + * Returns the specified int of the little-endian two's complement
15.3012 + * representation (int 0 is the least significant). The int number can
15.3013 + * be arbitrarily high (values are logically preceded by infinitely many
15.3014 + * sign ints).
15.3015 + */
15.3016 + private int getInt(int n) {
15.3017 + if (n < 0)
15.3018 + return 0;
15.3019 + if (n >= mag.length)
15.3020 + return signInt();
15.3021 +
15.3022 + int magInt = mag[mag.length-n-1];
15.3023 +
15.3024 + return (signum >= 0 ? magInt :
15.3025 + (n <= firstNonzeroIntNum() ? -magInt : ~magInt));
15.3026 + }
15.3027 +
15.3028 + /**
15.3029 + * Returns the index of the int that contains the first nonzero int in the
15.3030 + * little-endian binary representation of the magnitude (int 0 is the
15.3031 + * least significant). If the magnitude is zero, return value is undefined.
15.3032 + */
15.3033 + private int firstNonzeroIntNum() {
15.3034 + int fn = firstNonzeroIntNum - 2;
15.3035 + if (fn == -2) { // firstNonzeroIntNum not initialized yet
15.3036 + fn = 0;
15.3037 +
15.3038 + // Search for the first nonzero int
15.3039 + int i;
15.3040 + int mlen = mag.length;
15.3041 + for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
15.3042 + ;
15.3043 + fn = mlen - i - 1;
15.3044 + firstNonzeroIntNum = fn + 2; // offset by two to initialize
15.3045 + }
15.3046 + return fn;
15.3047 + }
15.3048 +
15.3049 + /** use serialVersionUID from JDK 1.1. for interoperability */
15.3050 + private static final long serialVersionUID = -8287574255936472291L;
15.3051 +
15.3052 + /**
15.3053 + * Serializable fields for BigInteger.
15.3054 + *
15.3055 + * @serialField signum int
15.3056 + * signum of this BigInteger.
15.3057 + * @serialField magnitude int[]
15.3058 + * magnitude array of this BigInteger.
15.3059 + * @serialField bitCount int
15.3060 + * number of bits in this BigInteger
15.3061 + * @serialField bitLength int
15.3062 + * the number of bits in the minimal two's-complement
15.3063 + * representation of this BigInteger
15.3064 + * @serialField lowestSetBit int
15.3065 + * lowest set bit in the twos complement representation
15.3066 + */
15.3067 + private static final ObjectStreamField[] serialPersistentFields = {
15.3068 + new ObjectStreamField("signum", Integer.TYPE),
15.3069 + new ObjectStreamField("magnitude", byte[].class),
15.3070 + new ObjectStreamField("bitCount", Integer.TYPE),
15.3071 + new ObjectStreamField("bitLength", Integer.TYPE),
15.3072 + new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE),
15.3073 + new ObjectStreamField("lowestSetBit", Integer.TYPE)
15.3074 + };
15.3075 +
15.3076 + /**
15.3077 + * Reconstitute the {@code BigInteger} instance from a stream (that is,
15.3078 + * deserialize it). The magnitude is read in as an array of bytes
15.3079 + * for historical reasons, but it is converted to an array of ints
15.3080 + * and the byte array is discarded.
15.3081 + * Note:
15.3082 + * The current convention is to initialize the cache fields, bitCount,
15.3083 + * bitLength and lowestSetBit, to 0 rather than some other marker value.
15.3084 + * Therefore, no explicit action to set these fields needs to be taken in
15.3085 + * readObject because those fields already have a 0 value be default since
15.3086 + * defaultReadObject is not being used.
15.3087 + */
15.3088 + private void readObject(java.io.ObjectInputStream s)
15.3089 + throws java.io.IOException, ClassNotFoundException {
15.3090 + /*
15.3091 + * In order to maintain compatibility with previous serialized forms,
15.3092 + * the magnitude of a BigInteger is serialized as an array of bytes.
15.3093 + * The magnitude field is used as a temporary store for the byte array
15.3094 + * that is deserialized. The cached computation fields should be
15.3095 + * transient but are serialized for compatibility reasons.
15.3096 + */
15.3097 +
15.3098 + // prepare to read the alternate persistent fields
15.3099 + ObjectInputStream.GetField fields = s.readFields();
15.3100 +
15.3101 + // Read the alternate persistent fields that we care about
15.3102 + int sign = fields.get("signum", -2);
15.3103 + byte[] magnitude = (byte[])fields.get("magnitude", null);
15.3104 +
15.3105 + // Validate signum
15.3106 + if (sign < -1 || sign > 1) {
15.3107 + String message = "BigInteger: Invalid signum value";
15.3108 + if (fields.defaulted("signum"))
15.3109 + message = "BigInteger: Signum not present in stream";
15.3110 + throw new java.io.StreamCorruptedException(message);
15.3111 + }
15.3112 + if ((magnitude.length == 0) != (sign == 0)) {
15.3113 + String message = "BigInteger: signum-magnitude mismatch";
15.3114 + if (fields.defaulted("magnitude"))
15.3115 + message = "BigInteger: Magnitude not present in stream";
15.3116 + throw new java.io.StreamCorruptedException(message);
15.3117 + }
15.3118 +
15.3119 + // Commit final fields via Unsafe
15.3120 + unsafe.putIntVolatile(this, signumOffset, sign);
15.3121 +
15.3122 + // Calculate mag field from magnitude and discard magnitude
15.3123 + unsafe.putObjectVolatile(this, magOffset,
15.3124 + stripLeadingZeroBytes(magnitude));
15.3125 + }
15.3126 +
15.3127 + // Support for resetting final fields while deserializing
15.3128 + private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
15.3129 + private static final long signumOffset;
15.3130 + private static final long magOffset;
15.3131 + static {
15.3132 + try {
15.3133 + signumOffset = unsafe.objectFieldOffset
15.3134 + (BigInteger.class.getDeclaredField("signum"));
15.3135 + magOffset = unsafe.objectFieldOffset
15.3136 + (BigInteger.class.getDeclaredField("mag"));
15.3137 + } catch (Exception ex) {
15.3138 + throw new Error(ex);
15.3139 + }
15.3140 + }
15.3141 +
15.3142 + /**
15.3143 + * Save the {@code BigInteger} instance to a stream.
15.3144 + * The magnitude of a BigInteger is serialized as a byte array for
15.3145 + * historical reasons.
15.3146 + *
15.3147 + * @serialData two necessary fields are written as well as obsolete
15.3148 + * fields for compatibility with older versions.
15.3149 + */
15.3150 + private void writeObject(ObjectOutputStream s) throws IOException {
15.3151 + // set the values of the Serializable fields
15.3152 + ObjectOutputStream.PutField fields = s.putFields();
15.3153 + fields.put("signum", signum);
15.3154 + fields.put("magnitude", magSerializedForm());
15.3155 + // The values written for cached fields are compatible with older
15.3156 + // versions, but are ignored in readObject so don't otherwise matter.
15.3157 + fields.put("bitCount", -1);
15.3158 + fields.put("bitLength", -1);
15.3159 + fields.put("lowestSetBit", -2);
15.3160 + fields.put("firstNonzeroByteNum", -2);
15.3161 +
15.3162 + // save them
15.3163 + s.writeFields();
15.3164 +}
15.3165 +
15.3166 + /**
15.3167 + * Returns the mag array as an array of bytes.
15.3168 + */
15.3169 + private byte[] magSerializedForm() {
15.3170 + int len = mag.length;
15.3171 +
15.3172 + int bitLen = (len == 0 ? 0 : ((len - 1) << 5) + bitLengthForInt(mag[0]));
15.3173 + int byteLen = (bitLen + 7) >>> 3;
15.3174 + byte[] result = new byte[byteLen];
15.3175 +
15.3176 + for (int i = byteLen - 1, bytesCopied = 4, intIndex = len - 1, nextInt = 0;
15.3177 + i>=0; i--) {
15.3178 + if (bytesCopied == 4) {
15.3179 + nextInt = mag[intIndex--];
15.3180 + bytesCopied = 1;
15.3181 + } else {
15.3182 + nextInt >>>= 8;
15.3183 + bytesCopied++;
15.3184 + }
15.3185 + result[i] = (byte)nextInt;
15.3186 + }
15.3187 + return result;
15.3188 + }
15.3189 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/emul/compact/src/main/java/java/math/BitSieve.java Sat Sep 07 13:51:24 2013 +0200
16.3 @@ -0,0 +1,212 @@
16.4 +/*
16.5 + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
16.7 + *
16.8 + * This code is free software; you can redistribute it and/or modify it
16.9 + * under the terms of the GNU General Public License version 2 only, as
16.10 + * published by the Free Software Foundation. Oracle designates this
16.11 + * particular file as subject to the "Classpath" exception as provided
16.12 + * by Oracle in the LICENSE file that accompanied this code.
16.13 + *
16.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
16.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16.17 + * version 2 for more details (a copy is included in the LICENSE file that
16.18 + * accompanied this code).
16.19 + *
16.20 + * You should have received a copy of the GNU General Public License version
16.21 + * 2 along with this work; if not, write to the Free Software Foundation,
16.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
16.23 + *
16.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
16.25 + * or visit www.oracle.com if you need additional information or have any
16.26 + * questions.
16.27 + */
16.28 +
16.29 +package java.math;
16.30 +
16.31 +/**
16.32 + * A simple bit sieve used for finding prime number candidates. Allows setting
16.33 + * and clearing of bits in a storage array. The size of the sieve is assumed to
16.34 + * be constant to reduce overhead. All the bits of a new bitSieve are zero, and
16.35 + * bits are removed from it by setting them.
16.36 + *
16.37 + * To reduce storage space and increase efficiency, no even numbers are
16.38 + * represented in the sieve (each bit in the sieve represents an odd number).
16.39 + * The relationship between the index of a bit and the number it represents is
16.40 + * given by
16.41 + * N = offset + (2*index + 1);
16.42 + * Where N is the integer represented by a bit in the sieve, offset is some
16.43 + * even integer offset indicating where the sieve begins, and index is the
16.44 + * index of a bit in the sieve array.
16.45 + *
16.46 + * @see BigInteger
16.47 + * @author Michael McCloskey
16.48 + * @since 1.3
16.49 + */
16.50 +class BitSieve {
16.51 + /**
16.52 + * Stores the bits in this bitSieve.
16.53 + */
16.54 + private long bits[];
16.55 +
16.56 + /**
16.57 + * Length is how many bits this sieve holds.
16.58 + */
16.59 + private int length;
16.60 +
16.61 + /**
16.62 + * A small sieve used to filter out multiples of small primes in a search
16.63 + * sieve.
16.64 + */
16.65 + private static BitSieve smallSieve = new BitSieve();
16.66 +
16.67 + /**
16.68 + * Construct a "small sieve" with a base of 0. This constructor is
16.69 + * used internally to generate the set of "small primes" whose multiples
16.70 + * are excluded from sieves generated by the main (package private)
16.71 + * constructor, BitSieve(BigInteger base, int searchLen). The length
16.72 + * of the sieve generated by this constructor was chosen for performance;
16.73 + * it controls a tradeoff between how much time is spent constructing
16.74 + * other sieves, and how much time is wasted testing composite candidates
16.75 + * for primality. The length was chosen experimentally to yield good
16.76 + * performance.
16.77 + */
16.78 + private BitSieve() {
16.79 + length = 150 * 64;
16.80 + bits = new long[(unitIndex(length - 1) + 1)];
16.81 +
16.82 + // Mark 1 as composite
16.83 + set(0);
16.84 + int nextIndex = 1;
16.85 + int nextPrime = 3;
16.86 +
16.87 + // Find primes and remove their multiples from sieve
16.88 + do {
16.89 + sieveSingle(length, nextIndex + nextPrime, nextPrime);
16.90 + nextIndex = sieveSearch(length, nextIndex + 1);
16.91 + nextPrime = 2*nextIndex + 1;
16.92 + } while((nextIndex > 0) && (nextPrime < length));
16.93 + }
16.94 +
16.95 + /**
16.96 + * Construct a bit sieve of searchLen bits used for finding prime number
16.97 + * candidates. The new sieve begins at the specified base, which must
16.98 + * be even.
16.99 + */
16.100 + BitSieve(BigInteger base, int searchLen) {
16.101 + /*
16.102 + * Candidates are indicated by clear bits in the sieve. As a candidates
16.103 + * nonprimality is calculated, a bit is set in the sieve to eliminate
16.104 + * it. To reduce storage space and increase efficiency, no even numbers
16.105 + * are represented in the sieve (each bit in the sieve represents an
16.106 + * odd number).
16.107 + */
16.108 + bits = new long[(unitIndex(searchLen-1) + 1)];
16.109 + length = searchLen;
16.110 + int start = 0;
16.111 +
16.112 + int step = smallSieve.sieveSearch(smallSieve.length, start);
16.113 + int convertedStep = (step *2) + 1;
16.114 +
16.115 + // Construct the large sieve at an even offset specified by base
16.116 + MutableBigInteger b = new MutableBigInteger(base);
16.117 + MutableBigInteger q = new MutableBigInteger();
16.118 + do {
16.119 + // Calculate base mod convertedStep
16.120 + start = b.divideOneWord(convertedStep, q);
16.121 +
16.122 + // Take each multiple of step out of sieve
16.123 + start = convertedStep - start;
16.124 + if (start%2 == 0)
16.125 + start += convertedStep;
16.126 + sieveSingle(searchLen, (start-1)/2, convertedStep);
16.127 +
16.128 + // Find next prime from small sieve
16.129 + step = smallSieve.sieveSearch(smallSieve.length, step+1);
16.130 + convertedStep = (step *2) + 1;
16.131 + } while (step > 0);
16.132 + }
16.133 +
16.134 + /**
16.135 + * Given a bit index return unit index containing it.
16.136 + */
16.137 + private static int unitIndex(int bitIndex) {
16.138 + return bitIndex >>> 6;
16.139 + }
16.140 +
16.141 + /**
16.142 + * Return a unit that masks the specified bit in its unit.
16.143 + */
16.144 + private static long bit(int bitIndex) {
16.145 + return 1L << (bitIndex & ((1<<6) - 1));
16.146 + }
16.147 +
16.148 + /**
16.149 + * Get the value of the bit at the specified index.
16.150 + */
16.151 + private boolean get(int bitIndex) {
16.152 + int unitIndex = unitIndex(bitIndex);
16.153 + return ((bits[unitIndex] & bit(bitIndex)) != 0);
16.154 + }
16.155 +
16.156 + /**
16.157 + * Set the bit at the specified index.
16.158 + */
16.159 + private void set(int bitIndex) {
16.160 + int unitIndex = unitIndex(bitIndex);
16.161 + bits[unitIndex] |= bit(bitIndex);
16.162 + }
16.163 +
16.164 + /**
16.165 + * This method returns the index of the first clear bit in the search
16.166 + * array that occurs at or after start. It will not search past the
16.167 + * specified limit. It returns -1 if there is no such clear bit.
16.168 + */
16.169 + private int sieveSearch(int limit, int start) {
16.170 + if (start >= limit)
16.171 + return -1;
16.172 +
16.173 + int index = start;
16.174 + do {
16.175 + if (!get(index))
16.176 + return index;
16.177 + index++;
16.178 + } while(index < limit-1);
16.179 + return -1;
16.180 + }
16.181 +
16.182 + /**
16.183 + * Sieve a single set of multiples out of the sieve. Begin to remove
16.184 + * multiples of the specified step starting at the specified start index,
16.185 + * up to the specified limit.
16.186 + */
16.187 + private void sieveSingle(int limit, int start, int step) {
16.188 + while(start < limit) {
16.189 + set(start);
16.190 + start += step;
16.191 + }
16.192 + }
16.193 +
16.194 + /**
16.195 + * Test probable primes in the sieve and return successful candidates.
16.196 + */
16.197 + BigInteger retrieve(BigInteger initValue, int certainty, java.util.Random random) {
16.198 + // Examine the sieve one long at a time to find possible primes
16.199 + int offset = 1;
16.200 + for (int i=0; i<bits.length; i++) {
16.201 + long nextLong = ~bits[i];
16.202 + for (int j=0; j<64; j++) {
16.203 + if ((nextLong & 1) == 1) {
16.204 + BigInteger candidate = initValue.add(
16.205 + BigInteger.valueOf(offset));
16.206 + if (candidate.primeToCertainty(certainty, random))
16.207 + return candidate;
16.208 + }
16.209 + nextLong >>>= 1;
16.210 + offset+=2;
16.211 + }
16.212 + }
16.213 + return null;
16.214 + }
16.215 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/emul/compact/src/main/java/java/math/MathContext.java Sat Sep 07 13:51:24 2013 +0200
17.3 @@ -0,0 +1,326 @@
17.4 +/*
17.5 + * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.7 + *
17.8 + * This code is free software; you can redistribute it and/or modify it
17.9 + * under the terms of the GNU General Public License version 2 only, as
17.10 + * published by the Free Software Foundation. Oracle designates this
17.11 + * particular file as subject to the "Classpath" exception as provided
17.12 + * by Oracle in the LICENSE file that accompanied this code.
17.13 + *
17.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
17.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17.17 + * version 2 for more details (a copy is included in the LICENSE file that
17.18 + * accompanied this code).
17.19 + *
17.20 + * You should have received a copy of the GNU General Public License version
17.21 + * 2 along with this work; if not, write to the Free Software Foundation,
17.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17.23 + *
17.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
17.25 + * or visit www.oracle.com if you need additional information or have any
17.26 + * questions.
17.27 + */
17.28 +
17.29 +/*
17.30 + * Portions Copyright IBM Corporation, 1997, 2001. All Rights Reserved.
17.31 + */
17.32 +
17.33 +package java.math;
17.34 +import java.io.*;
17.35 +
17.36 +/**
17.37 + * Immutable objects which encapsulate the context settings which
17.38 + * describe certain rules for numerical operators, such as those
17.39 + * implemented by the {@link BigDecimal} class.
17.40 + *
17.41 + * <p>The base-independent settings are:
17.42 + * <ol>
17.43 + * <li>{@code precision}:
17.44 + * the number of digits to be used for an operation; results are
17.45 + * rounded to this precision
17.46 + *
17.47 + * <li>{@code roundingMode}:
17.48 + * a {@link RoundingMode} object which specifies the algorithm to be
17.49 + * used for rounding.
17.50 + * </ol>
17.51 + *
17.52 + * @see BigDecimal
17.53 + * @see RoundingMode
17.54 + * @author Mike Cowlishaw
17.55 + * @author Joseph D. Darcy
17.56 + * @since 1.5
17.57 + */
17.58 +
17.59 +public final class MathContext implements Serializable {
17.60 +
17.61 + /* ----- Constants ----- */
17.62 +
17.63 + // defaults for constructors
17.64 + private static final int DEFAULT_DIGITS = 9;
17.65 + private static final RoundingMode DEFAULT_ROUNDINGMODE = RoundingMode.HALF_UP;
17.66 + // Smallest values for digits (Maximum is Integer.MAX_VALUE)
17.67 + private static final int MIN_DIGITS = 0;
17.68 +
17.69 + // Serialization version
17.70 + private static final long serialVersionUID = 5579720004786848255L;
17.71 +
17.72 + /* ----- Public Properties ----- */
17.73 + /**
17.74 + * A {@code MathContext} object whose settings have the values
17.75 + * required for unlimited precision arithmetic.
17.76 + * The values of the settings are:
17.77 + * <code>
17.78 + * precision=0 roundingMode=HALF_UP
17.79 + * </code>
17.80 + */
17.81 + public static final MathContext UNLIMITED =
17.82 + new MathContext(0, RoundingMode.HALF_UP);
17.83 +
17.84 + /**
17.85 + * A {@code MathContext} object with a precision setting
17.86 + * matching the IEEE 754R Decimal32 format, 7 digits, and a
17.87 + * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
17.88 + * IEEE 754R default.
17.89 + */
17.90 + public static final MathContext DECIMAL32 =
17.91 + new MathContext(7, RoundingMode.HALF_EVEN);
17.92 +
17.93 + /**
17.94 + * A {@code MathContext} object with a precision setting
17.95 + * matching the IEEE 754R Decimal64 format, 16 digits, and a
17.96 + * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
17.97 + * IEEE 754R default.
17.98 + */
17.99 + public static final MathContext DECIMAL64 =
17.100 + new MathContext(16, RoundingMode.HALF_EVEN);
17.101 +
17.102 + /**
17.103 + * A {@code MathContext} object with a precision setting
17.104 + * matching the IEEE 754R Decimal128 format, 34 digits, and a
17.105 + * rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
17.106 + * IEEE 754R default.
17.107 + */
17.108 + public static final MathContext DECIMAL128 =
17.109 + new MathContext(34, RoundingMode.HALF_EVEN);
17.110 +
17.111 + /* ----- Shared Properties ----- */
17.112 + /**
17.113 + * The number of digits to be used for an operation. A value of 0
17.114 + * indicates that unlimited precision (as many digits as are
17.115 + * required) will be used. Note that leading zeros (in the
17.116 + * coefficient of a number) are never significant.
17.117 + *
17.118 + * <p>{@code precision} will always be non-negative.
17.119 + *
17.120 + * @serial
17.121 + */
17.122 + final int precision;
17.123 +
17.124 + /**
17.125 + * The rounding algorithm to be used for an operation.
17.126 + *
17.127 + * @see RoundingMode
17.128 + * @serial
17.129 + */
17.130 + final RoundingMode roundingMode;
17.131 +
17.132 + /* ----- Constructors ----- */
17.133 +
17.134 + /**
17.135 + * Constructs a new {@code MathContext} with the specified
17.136 + * precision and the {@link RoundingMode#HALF_UP HALF_UP} rounding
17.137 + * mode.
17.138 + *
17.139 + * @param setPrecision The non-negative {@code int} precision setting.
17.140 + * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
17.141 + * than zero.
17.142 + */
17.143 + public MathContext(int setPrecision) {
17.144 + this(setPrecision, DEFAULT_ROUNDINGMODE);
17.145 + return;
17.146 + }
17.147 +
17.148 + /**
17.149 + * Constructs a new {@code MathContext} with a specified
17.150 + * precision and rounding mode.
17.151 + *
17.152 + * @param setPrecision The non-negative {@code int} precision setting.
17.153 + * @param setRoundingMode The rounding mode to use.
17.154 + * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
17.155 + * than zero.
17.156 + * @throws NullPointerException if the rounding mode argument is {@code null}
17.157 + */
17.158 + public MathContext(int setPrecision,
17.159 + RoundingMode setRoundingMode) {
17.160 + if (setPrecision < MIN_DIGITS)
17.161 + throw new IllegalArgumentException("Digits < 0");
17.162 + if (setRoundingMode == null)
17.163 + throw new NullPointerException("null RoundingMode");
17.164 +
17.165 + precision = setPrecision;
17.166 + roundingMode = setRoundingMode;
17.167 + return;
17.168 + }
17.169 +
17.170 + /**
17.171 + * Constructs a new {@code MathContext} from a string.
17.172 + *
17.173 + * The string must be in the same format as that produced by the
17.174 + * {@link #toString} method.
17.175 + *
17.176 + * <p>An {@code IllegalArgumentException} is thrown if the precision
17.177 + * section of the string is out of range ({@code < 0}) or the string is
17.178 + * not in the format created by the {@link #toString} method.
17.179 + *
17.180 + * @param val The string to be parsed
17.181 + * @throws IllegalArgumentException if the precision section is out of range
17.182 + * or of incorrect format
17.183 + * @throws NullPointerException if the argument is {@code null}
17.184 + */
17.185 + public MathContext(String val) {
17.186 + boolean bad = false;
17.187 + int setPrecision;
17.188 + if (val == null)
17.189 + throw new NullPointerException("null String");
17.190 + try { // any error here is a string format problem
17.191 + if (!val.startsWith("precision=")) throw new RuntimeException();
17.192 + int fence = val.indexOf(' '); // could be -1
17.193 + int off = 10; // where value starts
17.194 + setPrecision = Integer.parseInt(val.substring(10, fence));
17.195 +
17.196 + if (!val.startsWith("roundingMode=", fence+1))
17.197 + throw new RuntimeException();
17.198 + off = fence + 1 + 13;
17.199 + String str = val.substring(off, val.length());
17.200 + roundingMode = RoundingMode.valueOf(str);
17.201 + } catch (RuntimeException re) {
17.202 + throw new IllegalArgumentException("bad string format");
17.203 + }
17.204 +
17.205 + if (setPrecision < MIN_DIGITS)
17.206 + throw new IllegalArgumentException("Digits < 0");
17.207 + // the other parameters cannot be invalid if we got here
17.208 + precision = setPrecision;
17.209 + }
17.210 +
17.211 + /**
17.212 + * Returns the {@code precision} setting.
17.213 + * This value is always non-negative.
17.214 + *
17.215 + * @return an {@code int} which is the value of the {@code precision}
17.216 + * setting
17.217 + */
17.218 + public int getPrecision() {
17.219 + return precision;
17.220 + }
17.221 +
17.222 + /**
17.223 + * Returns the roundingMode setting.
17.224 + * This will be one of
17.225 + * {@link RoundingMode#CEILING},
17.226 + * {@link RoundingMode#DOWN},
17.227 + * {@link RoundingMode#FLOOR},
17.228 + * {@link RoundingMode#HALF_DOWN},
17.229 + * {@link RoundingMode#HALF_EVEN},
17.230 + * {@link RoundingMode#HALF_UP},
17.231 + * {@link RoundingMode#UNNECESSARY}, or
17.232 + * {@link RoundingMode#UP}.
17.233 + *
17.234 + * @return a {@code RoundingMode} object which is the value of the
17.235 + * {@code roundingMode} setting
17.236 + */
17.237 +
17.238 + public RoundingMode getRoundingMode() {
17.239 + return roundingMode;
17.240 + }
17.241 +
17.242 + /**
17.243 + * Compares this {@code MathContext} with the specified
17.244 + * {@code Object} for equality.
17.245 + *
17.246 + * @param x {@code Object} to which this {@code MathContext} is to
17.247 + * be compared.
17.248 + * @return {@code true} if and only if the specified {@code Object} is
17.249 + * a {@code MathContext} object which has exactly the same
17.250 + * settings as this object
17.251 + */
17.252 + public boolean equals(Object x){
17.253 + MathContext mc;
17.254 + if (!(x instanceof MathContext))
17.255 + return false;
17.256 + mc = (MathContext) x;
17.257 + return mc.precision == this.precision
17.258 + && mc.roundingMode == this.roundingMode; // no need for .equals()
17.259 + }
17.260 +
17.261 + /**
17.262 + * Returns the hash code for this {@code MathContext}.
17.263 + *
17.264 + * @return hash code for this {@code MathContext}
17.265 + */
17.266 + public int hashCode() {
17.267 + return this.precision + roundingMode.hashCode() * 59;
17.268 + }
17.269 +
17.270 + /**
17.271 + * Returns the string representation of this {@code MathContext}.
17.272 + * The {@code String} returned represents the settings of the
17.273 + * {@code MathContext} object as two space-delimited words
17.274 + * (separated by a single space character, <tt>'\u0020'</tt>,
17.275 + * and with no leading or trailing white space), as follows:
17.276 + * <ol>
17.277 + * <li>
17.278 + * The string {@code "precision="}, immediately followed
17.279 + * by the value of the precision setting as a numeric string as if
17.280 + * generated by the {@link Integer#toString(int) Integer.toString}
17.281 + * method.
17.282 + *
17.283 + * <li>
17.284 + * The string {@code "roundingMode="}, immediately
17.285 + * followed by the value of the {@code roundingMode} setting as a
17.286 + * word. This word will be the same as the name of the
17.287 + * corresponding public constant in the {@link RoundingMode}
17.288 + * enum.
17.289 + * </ol>
17.290 + * <p>
17.291 + * For example:
17.292 + * <pre>
17.293 + * precision=9 roundingMode=HALF_UP
17.294 + * </pre>
17.295 + *
17.296 + * Additional words may be appended to the result of
17.297 + * {@code toString} in the future if more properties are added to
17.298 + * this class.
17.299 + *
17.300 + * @return a {@code String} representing the context settings
17.301 + */
17.302 + public java.lang.String toString() {
17.303 + return "precision=" + precision + " " +
17.304 + "roundingMode=" + roundingMode.toString();
17.305 + }
17.306 +
17.307 + // Private methods
17.308 +
17.309 + /**
17.310 + * Reconstitute the {@code MathContext} instance from a stream (that is,
17.311 + * deserialize it).
17.312 + *
17.313 + * @param s the stream being read.
17.314 + */
17.315 + private void readObject(java.io.ObjectInputStream s)
17.316 + throws java.io.IOException, ClassNotFoundException {
17.317 + s.defaultReadObject(); // read in all fields
17.318 + // validate possibly bad fields
17.319 + if (precision < MIN_DIGITS) {
17.320 + String message = "MathContext: invalid digits in stream";
17.321 + throw new java.io.StreamCorruptedException(message);
17.322 + }
17.323 + if (roundingMode == null) {
17.324 + String message = "MathContext: null roundingMode in stream";
17.325 + throw new java.io.StreamCorruptedException(message);
17.326 + }
17.327 + }
17.328 +
17.329 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/emul/compact/src/main/java/java/math/MutableBigInteger.java Sat Sep 07 13:51:24 2013 +0200
18.3 @@ -0,0 +1,1477 @@
18.4 +/*
18.5 + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.7 + *
18.8 + * This code is free software; you can redistribute it and/or modify it
18.9 + * under the terms of the GNU General Public License version 2 only, as
18.10 + * published by the Free Software Foundation. Oracle designates this
18.11 + * particular file as subject to the "Classpath" exception as provided
18.12 + * by Oracle in the LICENSE file that accompanied this code.
18.13 + *
18.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
18.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18.17 + * version 2 for more details (a copy is included in the LICENSE file that
18.18 + * accompanied this code).
18.19 + *
18.20 + * You should have received a copy of the GNU General Public License version
18.21 + * 2 along with this work; if not, write to the Free Software Foundation,
18.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18.23 + *
18.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
18.25 + * or visit www.oracle.com if you need additional information or have any
18.26 + * questions.
18.27 + */
18.28 +
18.29 +package java.math;
18.30 +
18.31 +/**
18.32 + * A class used to represent multiprecision integers that makes efficient
18.33 + * use of allocated space by allowing a number to occupy only part of
18.34 + * an array so that the arrays do not have to be reallocated as often.
18.35 + * When performing an operation with many iterations the array used to
18.36 + * hold a number is only reallocated when necessary and does not have to
18.37 + * be the same size as the number it represents. A mutable number allows
18.38 + * calculations to occur on the same number without having to create
18.39 + * a new number for every step of the calculation as occurs with
18.40 + * BigIntegers.
18.41 + *
18.42 + * @see BigInteger
18.43 + * @author Michael McCloskey
18.44 + * @since 1.3
18.45 + */
18.46 +
18.47 +import java.util.Arrays;
18.48 +
18.49 +import static java.math.BigInteger.LONG_MASK;
18.50 +import static java.math.BigDecimal.INFLATED;
18.51 +
18.52 +class MutableBigInteger {
18.53 + /**
18.54 + * Holds the magnitude of this MutableBigInteger in big endian order.
18.55 + * The magnitude may start at an offset into the value array, and it may
18.56 + * end before the length of the value array.
18.57 + */
18.58 + int[] value;
18.59 +
18.60 + /**
18.61 + * The number of ints of the value array that are currently used
18.62 + * to hold the magnitude of this MutableBigInteger. The magnitude starts
18.63 + * at an offset and offset + intLen may be less than value.length.
18.64 + */
18.65 + int intLen;
18.66 +
18.67 + /**
18.68 + * The offset into the value array where the magnitude of this
18.69 + * MutableBigInteger begins.
18.70 + */
18.71 + int offset = 0;
18.72 +
18.73 + // Constants
18.74 + /**
18.75 + * MutableBigInteger with one element value array with the value 1. Used by
18.76 + * BigDecimal divideAndRound to increment the quotient. Use this constant
18.77 + * only when the method is not going to modify this object.
18.78 + */
18.79 + static final MutableBigInteger ONE = new MutableBigInteger(1);
18.80 +
18.81 + // Constructors
18.82 +
18.83 + /**
18.84 + * The default constructor. An empty MutableBigInteger is created with
18.85 + * a one word capacity.
18.86 + */
18.87 + MutableBigInteger() {
18.88 + value = new int[1];
18.89 + intLen = 0;
18.90 + }
18.91 +
18.92 + /**
18.93 + * Construct a new MutableBigInteger with a magnitude specified by
18.94 + * the int val.
18.95 + */
18.96 + MutableBigInteger(int val) {
18.97 + value = new int[1];
18.98 + intLen = 1;
18.99 + value[0] = val;
18.100 + }
18.101 +
18.102 + /**
18.103 + * Construct a new MutableBigInteger with the specified value array
18.104 + * up to the length of the array supplied.
18.105 + */
18.106 + MutableBigInteger(int[] val) {
18.107 + value = val;
18.108 + intLen = val.length;
18.109 + }
18.110 +
18.111 + /**
18.112 + * Construct a new MutableBigInteger with a magnitude equal to the
18.113 + * specified BigInteger.
18.114 + */
18.115 + MutableBigInteger(BigInteger b) {
18.116 + intLen = b.mag.length;
18.117 + value = Arrays.copyOf(b.mag, intLen);
18.118 + }
18.119 +
18.120 + /**
18.121 + * Construct a new MutableBigInteger with a magnitude equal to the
18.122 + * specified MutableBigInteger.
18.123 + */
18.124 + MutableBigInteger(MutableBigInteger val) {
18.125 + intLen = val.intLen;
18.126 + value = Arrays.copyOfRange(val.value, val.offset, val.offset + intLen);
18.127 + }
18.128 +
18.129 + /**
18.130 + * Internal helper method to return the magnitude array. The caller is not
18.131 + * supposed to modify the returned array.
18.132 + */
18.133 + private int[] getMagnitudeArray() {
18.134 + if (offset > 0 || value.length != intLen)
18.135 + return Arrays.copyOfRange(value, offset, offset + intLen);
18.136 + return value;
18.137 + }
18.138 +
18.139 + /**
18.140 + * Convert this MutableBigInteger to a long value. The caller has to make
18.141 + * sure this MutableBigInteger can be fit into long.
18.142 + */
18.143 + private long toLong() {
18.144 + assert (intLen <= 2) : "this MutableBigInteger exceeds the range of long";
18.145 + if (intLen == 0)
18.146 + return 0;
18.147 + long d = value[offset] & LONG_MASK;
18.148 + return (intLen == 2) ? d << 32 | (value[offset + 1] & LONG_MASK) : d;
18.149 + }
18.150 +
18.151 + /**
18.152 + * Convert this MutableBigInteger to a BigInteger object.
18.153 + */
18.154 + BigInteger toBigInteger(int sign) {
18.155 + if (intLen == 0 || sign == 0)
18.156 + return BigInteger.ZERO;
18.157 + return new BigInteger(getMagnitudeArray(), sign);
18.158 + }
18.159 +
18.160 + /**
18.161 + * Convert this MutableBigInteger to BigDecimal object with the specified sign
18.162 + * and scale.
18.163 + */
18.164 + BigDecimal toBigDecimal(int sign, int scale) {
18.165 + if (intLen == 0 || sign == 0)
18.166 + return BigDecimal.valueOf(0, scale);
18.167 + int[] mag = getMagnitudeArray();
18.168 + int len = mag.length;
18.169 + int d = mag[0];
18.170 + // If this MutableBigInteger can't be fit into long, we need to
18.171 + // make a BigInteger object for the resultant BigDecimal object.
18.172 + if (len > 2 || (d < 0 && len == 2))
18.173 + return new BigDecimal(new BigInteger(mag, sign), INFLATED, scale, 0);
18.174 + long v = (len == 2) ?
18.175 + ((mag[1] & LONG_MASK) | (d & LONG_MASK) << 32) :
18.176 + d & LONG_MASK;
18.177 + return new BigDecimal(null, sign == -1 ? -v : v, scale, 0);
18.178 + }
18.179 +
18.180 + /**
18.181 + * Clear out a MutableBigInteger for reuse.
18.182 + */
18.183 + void clear() {
18.184 + offset = intLen = 0;
18.185 + for (int index=0, n=value.length; index < n; index++)
18.186 + value[index] = 0;
18.187 + }
18.188 +
18.189 + /**
18.190 + * Set a MutableBigInteger to zero, removing its offset.
18.191 + */
18.192 + void reset() {
18.193 + offset = intLen = 0;
18.194 + }
18.195 +
18.196 + /**
18.197 + * Compare the magnitude of two MutableBigIntegers. Returns -1, 0 or 1
18.198 + * as this MutableBigInteger is numerically less than, equal to, or
18.199 + * greater than <tt>b</tt>.
18.200 + */
18.201 + final int compare(MutableBigInteger b) {
18.202 + int blen = b.intLen;
18.203 + if (intLen < blen)
18.204 + return -1;
18.205 + if (intLen > blen)
18.206 + return 1;
18.207 +
18.208 + // Add Integer.MIN_VALUE to make the comparison act as unsigned integer
18.209 + // comparison.
18.210 + int[] bval = b.value;
18.211 + for (int i = offset, j = b.offset; i < intLen + offset; i++, j++) {
18.212 + int b1 = value[i] + 0x80000000;
18.213 + int b2 = bval[j] + 0x80000000;
18.214 + if (b1 < b2)
18.215 + return -1;
18.216 + if (b1 > b2)
18.217 + return 1;
18.218 + }
18.219 + return 0;
18.220 + }
18.221 +
18.222 + /**
18.223 + * Compare this against half of a MutableBigInteger object (Needed for
18.224 + * remainder tests).
18.225 + * Assumes no leading unnecessary zeros, which holds for results
18.226 + * from divide().
18.227 + */
18.228 + final int compareHalf(MutableBigInteger b) {
18.229 + int blen = b.intLen;
18.230 + int len = intLen;
18.231 + if (len <= 0)
18.232 + return blen <=0 ? 0 : -1;
18.233 + if (len > blen)
18.234 + return 1;
18.235 + if (len < blen - 1)
18.236 + return -1;
18.237 + int[] bval = b.value;
18.238 + int bstart = 0;
18.239 + int carry = 0;
18.240 + // Only 2 cases left:len == blen or len == blen - 1
18.241 + if (len != blen) { // len == blen - 1
18.242 + if (bval[bstart] == 1) {
18.243 + ++bstart;
18.244 + carry = 0x80000000;
18.245 + } else
18.246 + return -1;
18.247 + }
18.248 + // compare values with right-shifted values of b,
18.249 + // carrying shifted-out bits across words
18.250 + int[] val = value;
18.251 + for (int i = offset, j = bstart; i < len + offset;) {
18.252 + int bv = bval[j++];
18.253 + long hb = ((bv >>> 1) + carry) & LONG_MASK;
18.254 + long v = val[i++] & LONG_MASK;
18.255 + if (v != hb)
18.256 + return v < hb ? -1 : 1;
18.257 + carry = (bv & 1) << 31; // carray will be either 0x80000000 or 0
18.258 + }
18.259 + return carry == 0? 0 : -1;
18.260 + }
18.261 +
18.262 + /**
18.263 + * Return the index of the lowest set bit in this MutableBigInteger. If the
18.264 + * magnitude of this MutableBigInteger is zero, -1 is returned.
18.265 + */
18.266 + private final int getLowestSetBit() {
18.267 + if (intLen == 0)
18.268 + return -1;
18.269 + int j, b;
18.270 + for (j=intLen-1; (j>0) && (value[j+offset]==0); j--)
18.271 + ;
18.272 + b = value[j+offset];
18.273 + if (b==0)
18.274 + return -1;
18.275 + return ((intLen-1-j)<<5) + Integer.numberOfTrailingZeros(b);
18.276 + }
18.277 +
18.278 + /**
18.279 + * Return the int in use in this MutableBigInteger at the specified
18.280 + * index. This method is not used because it is not inlined on all
18.281 + * platforms.
18.282 + */
18.283 + private final int getInt(int index) {
18.284 + return value[offset+index];
18.285 + }
18.286 +
18.287 + /**
18.288 + * Return a long which is equal to the unsigned value of the int in
18.289 + * use in this MutableBigInteger at the specified index. This method is
18.290 + * not used because it is not inlined on all platforms.
18.291 + */
18.292 + private final long getLong(int index) {
18.293 + return value[offset+index] & LONG_MASK;
18.294 + }
18.295 +
18.296 + /**
18.297 + * Ensure that the MutableBigInteger is in normal form, specifically
18.298 + * making sure that there are no leading zeros, and that if the
18.299 + * magnitude is zero, then intLen is zero.
18.300 + */
18.301 + final void normalize() {
18.302 + if (intLen == 0) {
18.303 + offset = 0;
18.304 + return;
18.305 + }
18.306 +
18.307 + int index = offset;
18.308 + if (value[index] != 0)
18.309 + return;
18.310 +
18.311 + int indexBound = index+intLen;
18.312 + do {
18.313 + index++;
18.314 + } while(index < indexBound && value[index]==0);
18.315 +
18.316 + int numZeros = index - offset;
18.317 + intLen -= numZeros;
18.318 + offset = (intLen==0 ? 0 : offset+numZeros);
18.319 + }
18.320 +
18.321 + /**
18.322 + * If this MutableBigInteger cannot hold len words, increase the size
18.323 + * of the value array to len words.
18.324 + */
18.325 + private final void ensureCapacity(int len) {
18.326 + if (value.length < len) {
18.327 + value = new int[len];
18.328 + offset = 0;
18.329 + intLen = len;
18.330 + }
18.331 + }
18.332 +
18.333 + /**
18.334 + * Convert this MutableBigInteger into an int array with no leading
18.335 + * zeros, of a length that is equal to this MutableBigInteger's intLen.
18.336 + */
18.337 + int[] toIntArray() {
18.338 + int[] result = new int[intLen];
18.339 + for(int i=0; i<intLen; i++)
18.340 + result[i] = value[offset+i];
18.341 + return result;
18.342 + }
18.343 +
18.344 + /**
18.345 + * Sets the int at index+offset in this MutableBigInteger to val.
18.346 + * This does not get inlined on all platforms so it is not used
18.347 + * as often as originally intended.
18.348 + */
18.349 + void setInt(int index, int val) {
18.350 + value[offset + index] = val;
18.351 + }
18.352 +
18.353 + /**
18.354 + * Sets this MutableBigInteger's value array to the specified array.
18.355 + * The intLen is set to the specified length.
18.356 + */
18.357 + void setValue(int[] val, int length) {
18.358 + value = val;
18.359 + intLen = length;
18.360 + offset = 0;
18.361 + }
18.362 +
18.363 + /**
18.364 + * Sets this MutableBigInteger's value array to a copy of the specified
18.365 + * array. The intLen is set to the length of the new array.
18.366 + */
18.367 + void copyValue(MutableBigInteger src) {
18.368 + int len = src.intLen;
18.369 + if (value.length < len)
18.370 + value = new int[len];
18.371 + System.arraycopy(src.value, src.offset, value, 0, len);
18.372 + intLen = len;
18.373 + offset = 0;
18.374 + }
18.375 +
18.376 + /**
18.377 + * Sets this MutableBigInteger's value array to a copy of the specified
18.378 + * array. The intLen is set to the length of the specified array.
18.379 + */
18.380 + void copyValue(int[] val) {
18.381 + int len = val.length;
18.382 + if (value.length < len)
18.383 + value = new int[len];
18.384 + System.arraycopy(val, 0, value, 0, len);
18.385 + intLen = len;
18.386 + offset = 0;
18.387 + }
18.388 +
18.389 + /**
18.390 + * Returns true iff this MutableBigInteger has a value of one.
18.391 + */
18.392 + boolean isOne() {
18.393 + return (intLen == 1) && (value[offset] == 1);
18.394 + }
18.395 +
18.396 + /**
18.397 + * Returns true iff this MutableBigInteger has a value of zero.
18.398 + */
18.399 + boolean isZero() {
18.400 + return (intLen == 0);
18.401 + }
18.402 +
18.403 + /**
18.404 + * Returns true iff this MutableBigInteger is even.
18.405 + */
18.406 + boolean isEven() {
18.407 + return (intLen == 0) || ((value[offset + intLen - 1] & 1) == 0);
18.408 + }
18.409 +
18.410 + /**
18.411 + * Returns true iff this MutableBigInteger is odd.
18.412 + */
18.413 + boolean isOdd() {
18.414 + return isZero() ? false : ((value[offset + intLen - 1] & 1) == 1);
18.415 + }
18.416 +
18.417 + /**
18.418 + * Returns true iff this MutableBigInteger is in normal form. A
18.419 + * MutableBigInteger is in normal form if it has no leading zeros
18.420 + * after the offset, and intLen + offset <= value.length.
18.421 + */
18.422 + boolean isNormal() {
18.423 + if (intLen + offset > value.length)
18.424 + return false;
18.425 + if (intLen ==0)
18.426 + return true;
18.427 + return (value[offset] != 0);
18.428 + }
18.429 +
18.430 + /**
18.431 + * Returns a String representation of this MutableBigInteger in radix 10.
18.432 + */
18.433 + public String toString() {
18.434 + BigInteger b = toBigInteger(1);
18.435 + return b.toString();
18.436 + }
18.437 +
18.438 + /**
18.439 + * Right shift this MutableBigInteger n bits. The MutableBigInteger is left
18.440 + * in normal form.
18.441 + */
18.442 + void rightShift(int n) {
18.443 + if (intLen == 0)
18.444 + return;
18.445 + int nInts = n >>> 5;
18.446 + int nBits = n & 0x1F;
18.447 + this.intLen -= nInts;
18.448 + if (nBits == 0)
18.449 + return;
18.450 + int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
18.451 + if (nBits >= bitsInHighWord) {
18.452 + this.primitiveLeftShift(32 - nBits);
18.453 + this.intLen--;
18.454 + } else {
18.455 + primitiveRightShift(nBits);
18.456 + }
18.457 + }
18.458 +
18.459 + /**
18.460 + * Left shift this MutableBigInteger n bits.
18.461 + */
18.462 + void leftShift(int n) {
18.463 + /*
18.464 + * If there is enough storage space in this MutableBigInteger already
18.465 + * the available space will be used. Space to the right of the used
18.466 + * ints in the value array is faster to utilize, so the extra space
18.467 + * will be taken from the right if possible.
18.468 + */
18.469 + if (intLen == 0)
18.470 + return;
18.471 + int nInts = n >>> 5;
18.472 + int nBits = n&0x1F;
18.473 + int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
18.474 +
18.475 + // If shift can be done without moving words, do so
18.476 + if (n <= (32-bitsInHighWord)) {
18.477 + primitiveLeftShift(nBits);
18.478 + return;
18.479 + }
18.480 +
18.481 + int newLen = intLen + nInts +1;
18.482 + if (nBits <= (32-bitsInHighWord))
18.483 + newLen--;
18.484 + if (value.length < newLen) {
18.485 + // The array must grow
18.486 + int[] result = new int[newLen];
18.487 + for (int i=0; i<intLen; i++)
18.488 + result[i] = value[offset+i];
18.489 + setValue(result, newLen);
18.490 + } else if (value.length - offset >= newLen) {
18.491 + // Use space on right
18.492 + for(int i=0; i<newLen - intLen; i++)
18.493 + value[offset+intLen+i] = 0;
18.494 + } else {
18.495 + // Must use space on left
18.496 + for (int i=0; i<intLen; i++)
18.497 + value[i] = value[offset+i];
18.498 + for (int i=intLen; i<newLen; i++)
18.499 + value[i] = 0;
18.500 + offset = 0;
18.501 + }
18.502 + intLen = newLen;
18.503 + if (nBits == 0)
18.504 + return;
18.505 + if (nBits <= (32-bitsInHighWord))
18.506 + primitiveLeftShift(nBits);
18.507 + else
18.508 + primitiveRightShift(32 -nBits);
18.509 + }
18.510 +
18.511 + /**
18.512 + * A primitive used for division. This method adds in one multiple of the
18.513 + * divisor a back to the dividend result at a specified offset. It is used
18.514 + * when qhat was estimated too large, and must be adjusted.
18.515 + */
18.516 + private int divadd(int[] a, int[] result, int offset) {
18.517 + long carry = 0;
18.518 +
18.519 + for (int j=a.length-1; j >= 0; j--) {
18.520 + long sum = (a[j] & LONG_MASK) +
18.521 + (result[j+offset] & LONG_MASK) + carry;
18.522 + result[j+offset] = (int)sum;
18.523 + carry = sum >>> 32;
18.524 + }
18.525 + return (int)carry;
18.526 + }
18.527 +
18.528 + /**
18.529 + * This method is used for division. It multiplies an n word input a by one
18.530 + * word input x, and subtracts the n word product from q. This is needed
18.531 + * when subtracting qhat*divisor from dividend.
18.532 + */
18.533 + private int mulsub(int[] q, int[] a, int x, int len, int offset) {
18.534 + long xLong = x & LONG_MASK;
18.535 + long carry = 0;
18.536 + offset += len;
18.537 +
18.538 + for (int j=len-1; j >= 0; j--) {
18.539 + long product = (a[j] & LONG_MASK) * xLong + carry;
18.540 + long difference = q[offset] - product;
18.541 + q[offset--] = (int)difference;
18.542 + carry = (product >>> 32)
18.543 + + (((difference & LONG_MASK) >
18.544 + (((~(int)product) & LONG_MASK))) ? 1:0);
18.545 + }
18.546 + return (int)carry;
18.547 + }
18.548 +
18.549 + /**
18.550 + * Right shift this MutableBigInteger n bits, where n is
18.551 + * less than 32.
18.552 + * Assumes that intLen > 0, n > 0 for speed
18.553 + */
18.554 + private final void primitiveRightShift(int n) {
18.555 + int[] val = value;
18.556 + int n2 = 32 - n;
18.557 + for (int i=offset+intLen-1, c=val[i]; i>offset; i--) {
18.558 + int b = c;
18.559 + c = val[i-1];
18.560 + val[i] = (c << n2) | (b >>> n);
18.561 + }
18.562 + val[offset] >>>= n;
18.563 + }
18.564 +
18.565 + /**
18.566 + * Left shift this MutableBigInteger n bits, where n is
18.567 + * less than 32.
18.568 + * Assumes that intLen > 0, n > 0 for speed
18.569 + */
18.570 + private final void primitiveLeftShift(int n) {
18.571 + int[] val = value;
18.572 + int n2 = 32 - n;
18.573 + for (int i=offset, c=val[i], m=i+intLen-1; i<m; i++) {
18.574 + int b = c;
18.575 + c = val[i+1];
18.576 + val[i] = (b << n) | (c >>> n2);
18.577 + }
18.578 + val[offset+intLen-1] <<= n;
18.579 + }
18.580 +
18.581 + /**
18.582 + * Adds the contents of two MutableBigInteger objects.The result
18.583 + * is placed within this MutableBigInteger.
18.584 + * The contents of the addend are not changed.
18.585 + */
18.586 + void add(MutableBigInteger addend) {
18.587 + int x = intLen;
18.588 + int y = addend.intLen;
18.589 + int resultLen = (intLen > addend.intLen ? intLen : addend.intLen);
18.590 + int[] result = (value.length < resultLen ? new int[resultLen] : value);
18.591 +
18.592 + int rstart = result.length-1;
18.593 + long sum;
18.594 + long carry = 0;
18.595 +
18.596 + // Add common parts of both numbers
18.597 + while(x>0 && y>0) {
18.598 + x--; y--;
18.599 + sum = (value[x+offset] & LONG_MASK) +
18.600 + (addend.value[y+addend.offset] & LONG_MASK) + carry;
18.601 + result[rstart--] = (int)sum;
18.602 + carry = sum >>> 32;
18.603 + }
18.604 +
18.605 + // Add remainder of the longer number
18.606 + while(x>0) {
18.607 + x--;
18.608 + if (carry == 0 && result == value && rstart == (x + offset))
18.609 + return;
18.610 + sum = (value[x+offset] & LONG_MASK) + carry;
18.611 + result[rstart--] = (int)sum;
18.612 + carry = sum >>> 32;
18.613 + }
18.614 + while(y>0) {
18.615 + y--;
18.616 + sum = (addend.value[y+addend.offset] & LONG_MASK) + carry;
18.617 + result[rstart--] = (int)sum;
18.618 + carry = sum >>> 32;
18.619 + }
18.620 +
18.621 + if (carry > 0) { // Result must grow in length
18.622 + resultLen++;
18.623 + if (result.length < resultLen) {
18.624 + int temp[] = new int[resultLen];
18.625 + // Result one word longer from carry-out; copy low-order
18.626 + // bits into new result.
18.627 + System.arraycopy(result, 0, temp, 1, result.length);
18.628 + temp[0] = 1;
18.629 + result = temp;
18.630 + } else {
18.631 + result[rstart--] = 1;
18.632 + }
18.633 + }
18.634 +
18.635 + value = result;
18.636 + intLen = resultLen;
18.637 + offset = result.length - resultLen;
18.638 + }
18.639 +
18.640 +
18.641 + /**
18.642 + * Subtracts the smaller of this and b from the larger and places the
18.643 + * result into this MutableBigInteger.
18.644 + */
18.645 + int subtract(MutableBigInteger b) {
18.646 + MutableBigInteger a = this;
18.647 +
18.648 + int[] result = value;
18.649 + int sign = a.compare(b);
18.650 +
18.651 + if (sign == 0) {
18.652 + reset();
18.653 + return 0;
18.654 + }
18.655 + if (sign < 0) {
18.656 + MutableBigInteger tmp = a;
18.657 + a = b;
18.658 + b = tmp;
18.659 + }
18.660 +
18.661 + int resultLen = a.intLen;
18.662 + if (result.length < resultLen)
18.663 + result = new int[resultLen];
18.664 +
18.665 + long diff = 0;
18.666 + int x = a.intLen;
18.667 + int y = b.intLen;
18.668 + int rstart = result.length - 1;
18.669 +
18.670 + // Subtract common parts of both numbers
18.671 + while (y>0) {
18.672 + x--; y--;
18.673 +
18.674 + diff = (a.value[x+a.offset] & LONG_MASK) -
18.675 + (b.value[y+b.offset] & LONG_MASK) - ((int)-(diff>>32));
18.676 + result[rstart--] = (int)diff;
18.677 + }
18.678 + // Subtract remainder of longer number
18.679 + while (x>0) {
18.680 + x--;
18.681 + diff = (a.value[x+a.offset] & LONG_MASK) - ((int)-(diff>>32));
18.682 + result[rstart--] = (int)diff;
18.683 + }
18.684 +
18.685 + value = result;
18.686 + intLen = resultLen;
18.687 + offset = value.length - resultLen;
18.688 + normalize();
18.689 + return sign;
18.690 + }
18.691 +
18.692 + /**
18.693 + * Subtracts the smaller of a and b from the larger and places the result
18.694 + * into the larger. Returns 1 if the answer is in a, -1 if in b, 0 if no
18.695 + * operation was performed.
18.696 + */
18.697 + private int difference(MutableBigInteger b) {
18.698 + MutableBigInteger a = this;
18.699 + int sign = a.compare(b);
18.700 + if (sign ==0)
18.701 + return 0;
18.702 + if (sign < 0) {
18.703 + MutableBigInteger tmp = a;
18.704 + a = b;
18.705 + b = tmp;
18.706 + }
18.707 +
18.708 + long diff = 0;
18.709 + int x = a.intLen;
18.710 + int y = b.intLen;
18.711 +
18.712 + // Subtract common parts of both numbers
18.713 + while (y>0) {
18.714 + x--; y--;
18.715 + diff = (a.value[a.offset+ x] & LONG_MASK) -
18.716 + (b.value[b.offset+ y] & LONG_MASK) - ((int)-(diff>>32));
18.717 + a.value[a.offset+x] = (int)diff;
18.718 + }
18.719 + // Subtract remainder of longer number
18.720 + while (x>0) {
18.721 + x--;
18.722 + diff = (a.value[a.offset+ x] & LONG_MASK) - ((int)-(diff>>32));
18.723 + a.value[a.offset+x] = (int)diff;
18.724 + }
18.725 +
18.726 + a.normalize();
18.727 + return sign;
18.728 + }
18.729 +
18.730 + /**
18.731 + * Multiply the contents of two MutableBigInteger objects. The result is
18.732 + * placed into MutableBigInteger z. The contents of y are not changed.
18.733 + */
18.734 + void multiply(MutableBigInteger y, MutableBigInteger z) {
18.735 + int xLen = intLen;
18.736 + int yLen = y.intLen;
18.737 + int newLen = xLen + yLen;
18.738 +
18.739 + // Put z into an appropriate state to receive product
18.740 + if (z.value.length < newLen)
18.741 + z.value = new int[newLen];
18.742 + z.offset = 0;
18.743 + z.intLen = newLen;
18.744 +
18.745 + // The first iteration is hoisted out of the loop to avoid extra add
18.746 + long carry = 0;
18.747 + for (int j=yLen-1, k=yLen+xLen-1; j >= 0; j--, k--) {
18.748 + long product = (y.value[j+y.offset] & LONG_MASK) *
18.749 + (value[xLen-1+offset] & LONG_MASK) + carry;
18.750 + z.value[k] = (int)product;
18.751 + carry = product >>> 32;
18.752 + }
18.753 + z.value[xLen-1] = (int)carry;
18.754 +
18.755 + // Perform the multiplication word by word
18.756 + for (int i = xLen-2; i >= 0; i--) {
18.757 + carry = 0;
18.758 + for (int j=yLen-1, k=yLen+i; j >= 0; j--, k--) {
18.759 + long product = (y.value[j+y.offset] & LONG_MASK) *
18.760 + (value[i+offset] & LONG_MASK) +
18.761 + (z.value[k] & LONG_MASK) + carry;
18.762 + z.value[k] = (int)product;
18.763 + carry = product >>> 32;
18.764 + }
18.765 + z.value[i] = (int)carry;
18.766 + }
18.767 +
18.768 + // Remove leading zeros from product
18.769 + z.normalize();
18.770 + }
18.771 +
18.772 + /**
18.773 + * Multiply the contents of this MutableBigInteger by the word y. The
18.774 + * result is placed into z.
18.775 + */
18.776 + void mul(int y, MutableBigInteger z) {
18.777 + if (y == 1) {
18.778 + z.copyValue(this);
18.779 + return;
18.780 + }
18.781 +
18.782 + if (y == 0) {
18.783 + z.clear();
18.784 + return;
18.785 + }
18.786 +
18.787 + // Perform the multiplication word by word
18.788 + long ylong = y & LONG_MASK;
18.789 + int[] zval = (z.value.length<intLen+1 ? new int[intLen + 1]
18.790 + : z.value);
18.791 + long carry = 0;
18.792 + for (int i = intLen-1; i >= 0; i--) {
18.793 + long product = ylong * (value[i+offset] & LONG_MASK) + carry;
18.794 + zval[i+1] = (int)product;
18.795 + carry = product >>> 32;
18.796 + }
18.797 +
18.798 + if (carry == 0) {
18.799 + z.offset = 1;
18.800 + z.intLen = intLen;
18.801 + } else {
18.802 + z.offset = 0;
18.803 + z.intLen = intLen + 1;
18.804 + zval[0] = (int)carry;
18.805 + }
18.806 + z.value = zval;
18.807 + }
18.808 +
18.809 + /**
18.810 + * This method is used for division of an n word dividend by a one word
18.811 + * divisor. The quotient is placed into quotient. The one word divisor is
18.812 + * specified by divisor.
18.813 + *
18.814 + * @return the remainder of the division is returned.
18.815 + *
18.816 + */
18.817 + int divideOneWord(int divisor, MutableBigInteger quotient) {
18.818 + long divisorLong = divisor & LONG_MASK;
18.819 +
18.820 + // Special case of one word dividend
18.821 + if (intLen == 1) {
18.822 + long dividendValue = value[offset] & LONG_MASK;
18.823 + int q = (int) (dividendValue / divisorLong);
18.824 + int r = (int) (dividendValue - q * divisorLong);
18.825 + quotient.value[0] = q;
18.826 + quotient.intLen = (q == 0) ? 0 : 1;
18.827 + quotient.offset = 0;
18.828 + return r;
18.829 + }
18.830 +
18.831 + if (quotient.value.length < intLen)
18.832 + quotient.value = new int[intLen];
18.833 + quotient.offset = 0;
18.834 + quotient.intLen = intLen;
18.835 +
18.836 + // Normalize the divisor
18.837 + int shift = Integer.numberOfLeadingZeros(divisor);
18.838 +
18.839 + int rem = value[offset];
18.840 + long remLong = rem & LONG_MASK;
18.841 + if (remLong < divisorLong) {
18.842 + quotient.value[0] = 0;
18.843 + } else {
18.844 + quotient.value[0] = (int)(remLong / divisorLong);
18.845 + rem = (int) (remLong - (quotient.value[0] * divisorLong));
18.846 + remLong = rem & LONG_MASK;
18.847 + }
18.848 +
18.849 + int xlen = intLen;
18.850 + int[] qWord = new int[2];
18.851 + while (--xlen > 0) {
18.852 + long dividendEstimate = (remLong<<32) |
18.853 + (value[offset + intLen - xlen] & LONG_MASK);
18.854 + if (dividendEstimate >= 0) {
18.855 + qWord[0] = (int) (dividendEstimate / divisorLong);
18.856 + qWord[1] = (int) (dividendEstimate - qWord[0] * divisorLong);
18.857 + } else {
18.858 + divWord(qWord, dividendEstimate, divisor);
18.859 + }
18.860 + quotient.value[intLen - xlen] = qWord[0];
18.861 + rem = qWord[1];
18.862 + remLong = rem & LONG_MASK;
18.863 + }
18.864 +
18.865 + quotient.normalize();
18.866 + // Unnormalize
18.867 + if (shift > 0)
18.868 + return rem % divisor;
18.869 + else
18.870 + return rem;
18.871 + }
18.872 +
18.873 + /**
18.874 + * Calculates the quotient of this div b and places the quotient in the
18.875 + * provided MutableBigInteger objects and the remainder object is returned.
18.876 + *
18.877 + * Uses Algorithm D in Knuth section 4.3.1.
18.878 + * Many optimizations to that algorithm have been adapted from the Colin
18.879 + * Plumb C library.
18.880 + * It special cases one word divisors for speed. The content of b is not
18.881 + * changed.
18.882 + *
18.883 + */
18.884 + MutableBigInteger divide(MutableBigInteger b, MutableBigInteger quotient) {
18.885 + if (b.intLen == 0)
18.886 + throw new ArithmeticException("BigInteger divide by zero");
18.887 +
18.888 + // Dividend is zero
18.889 + if (intLen == 0) {
18.890 + quotient.intLen = quotient.offset;
18.891 + return new MutableBigInteger();
18.892 + }
18.893 +
18.894 + int cmp = compare(b);
18.895 + // Dividend less than divisor
18.896 + if (cmp < 0) {
18.897 + quotient.intLen = quotient.offset = 0;
18.898 + return new MutableBigInteger(this);
18.899 + }
18.900 + // Dividend equal to divisor
18.901 + if (cmp == 0) {
18.902 + quotient.value[0] = quotient.intLen = 1;
18.903 + quotient.offset = 0;
18.904 + return new MutableBigInteger();
18.905 + }
18.906 +
18.907 + quotient.clear();
18.908 + // Special case one word divisor
18.909 + if (b.intLen == 1) {
18.910 + int r = divideOneWord(b.value[b.offset], quotient);
18.911 + if (r == 0)
18.912 + return new MutableBigInteger();
18.913 + return new MutableBigInteger(r);
18.914 + }
18.915 +
18.916 + // Copy divisor value to protect divisor
18.917 + int[] div = Arrays.copyOfRange(b.value, b.offset, b.offset + b.intLen);
18.918 + return divideMagnitude(div, quotient);
18.919 + }
18.920 +
18.921 + /**
18.922 + * Internally used to calculate the quotient of this div v and places the
18.923 + * quotient in the provided MutableBigInteger object and the remainder is
18.924 + * returned.
18.925 + *
18.926 + * @return the remainder of the division will be returned.
18.927 + */
18.928 + long divide(long v, MutableBigInteger quotient) {
18.929 + if (v == 0)
18.930 + throw new ArithmeticException("BigInteger divide by zero");
18.931 +
18.932 + // Dividend is zero
18.933 + if (intLen == 0) {
18.934 + quotient.intLen = quotient.offset = 0;
18.935 + return 0;
18.936 + }
18.937 + if (v < 0)
18.938 + v = -v;
18.939 +
18.940 + int d = (int)(v >>> 32);
18.941 + quotient.clear();
18.942 + // Special case on word divisor
18.943 + if (d == 0)
18.944 + return divideOneWord((int)v, quotient) & LONG_MASK;
18.945 + else {
18.946 + int[] div = new int[]{ d, (int)(v & LONG_MASK) };
18.947 + return divideMagnitude(div, quotient).toLong();
18.948 + }
18.949 + }
18.950 +
18.951 + /**
18.952 + * Divide this MutableBigInteger by the divisor represented by its magnitude
18.953 + * array. The quotient will be placed into the provided quotient object &
18.954 + * the remainder object is returned.
18.955 + */
18.956 + private MutableBigInteger divideMagnitude(int[] divisor,
18.957 + MutableBigInteger quotient) {
18.958 +
18.959 + // Remainder starts as dividend with space for a leading zero
18.960 + MutableBigInteger rem = new MutableBigInteger(new int[intLen + 1]);
18.961 + System.arraycopy(value, offset, rem.value, 1, intLen);
18.962 + rem.intLen = intLen;
18.963 + rem.offset = 1;
18.964 +
18.965 + int nlen = rem.intLen;
18.966 +
18.967 + // Set the quotient size
18.968 + int dlen = divisor.length;
18.969 + int limit = nlen - dlen + 1;
18.970 + if (quotient.value.length < limit) {
18.971 + quotient.value = new int[limit];
18.972 + quotient.offset = 0;
18.973 + }
18.974 + quotient.intLen = limit;
18.975 + int[] q = quotient.value;
18.976 +
18.977 + // D1 normalize the divisor
18.978 + int shift = Integer.numberOfLeadingZeros(divisor[0]);
18.979 + if (shift > 0) {
18.980 + // First shift will not grow array
18.981 + BigInteger.primitiveLeftShift(divisor, dlen, shift);
18.982 + // But this one might
18.983 + rem.leftShift(shift);
18.984 + }
18.985 +
18.986 + // Must insert leading 0 in rem if its length did not change
18.987 + if (rem.intLen == nlen) {
18.988 + rem.offset = 0;
18.989 + rem.value[0] = 0;
18.990 + rem.intLen++;
18.991 + }
18.992 +
18.993 + int dh = divisor[0];
18.994 + long dhLong = dh & LONG_MASK;
18.995 + int dl = divisor[1];
18.996 + int[] qWord = new int[2];
18.997 +
18.998 + // D2 Initialize j
18.999 + for(int j=0; j<limit; j++) {
18.1000 + // D3 Calculate qhat
18.1001 + // estimate qhat
18.1002 + int qhat = 0;
18.1003 + int qrem = 0;
18.1004 + boolean skipCorrection = false;
18.1005 + int nh = rem.value[j+rem.offset];
18.1006 + int nh2 = nh + 0x80000000;
18.1007 + int nm = rem.value[j+1+rem.offset];
18.1008 +
18.1009 + if (nh == dh) {
18.1010 + qhat = ~0;
18.1011 + qrem = nh + nm;
18.1012 + skipCorrection = qrem + 0x80000000 < nh2;
18.1013 + } else {
18.1014 + long nChunk = (((long)nh) << 32) | (nm & LONG_MASK);
18.1015 + if (nChunk >= 0) {
18.1016 + qhat = (int) (nChunk / dhLong);
18.1017 + qrem = (int) (nChunk - (qhat * dhLong));
18.1018 + } else {
18.1019 + divWord(qWord, nChunk, dh);
18.1020 + qhat = qWord[0];
18.1021 + qrem = qWord[1];
18.1022 + }
18.1023 + }
18.1024 +
18.1025 + if (qhat == 0)
18.1026 + continue;
18.1027 +
18.1028 + if (!skipCorrection) { // Correct qhat
18.1029 + long nl = rem.value[j+2+rem.offset] & LONG_MASK;
18.1030 + long rs = ((qrem & LONG_MASK) << 32) | nl;
18.1031 + long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
18.1032 +
18.1033 + if (unsignedLongCompare(estProduct, rs)) {
18.1034 + qhat--;
18.1035 + qrem = (int)((qrem & LONG_MASK) + dhLong);
18.1036 + if ((qrem & LONG_MASK) >= dhLong) {
18.1037 + estProduct -= (dl & LONG_MASK);
18.1038 + rs = ((qrem & LONG_MASK) << 32) | nl;
18.1039 + if (unsignedLongCompare(estProduct, rs))
18.1040 + qhat--;
18.1041 + }
18.1042 + }
18.1043 + }
18.1044 +
18.1045 + // D4 Multiply and subtract
18.1046 + rem.value[j+rem.offset] = 0;
18.1047 + int borrow = mulsub(rem.value, divisor, qhat, dlen, j+rem.offset);
18.1048 +
18.1049 + // D5 Test remainder
18.1050 + if (borrow + 0x80000000 > nh2) {
18.1051 + // D6 Add back
18.1052 + divadd(divisor, rem.value, j+1+rem.offset);
18.1053 + qhat--;
18.1054 + }
18.1055 +
18.1056 + // Store the quotient digit
18.1057 + q[j] = qhat;
18.1058 + } // D7 loop on j
18.1059 +
18.1060 + // D8 Unnormalize
18.1061 + if (shift > 0)
18.1062 + rem.rightShift(shift);
18.1063 +
18.1064 + quotient.normalize();
18.1065 + rem.normalize();
18.1066 + return rem;
18.1067 + }
18.1068 +
18.1069 + /**
18.1070 + * Compare two longs as if they were unsigned.
18.1071 + * Returns true iff one is bigger than two.
18.1072 + */
18.1073 + private boolean unsignedLongCompare(long one, long two) {
18.1074 + return (one+Long.MIN_VALUE) > (two+Long.MIN_VALUE);
18.1075 + }
18.1076 +
18.1077 + /**
18.1078 + * This method divides a long quantity by an int to estimate
18.1079 + * qhat for two multi precision numbers. It is used when
18.1080 + * the signed value of n is less than zero.
18.1081 + */
18.1082 + private void divWord(int[] result, long n, int d) {
18.1083 + long dLong = d & LONG_MASK;
18.1084 +
18.1085 + if (dLong == 1) {
18.1086 + result[0] = (int)n;
18.1087 + result[1] = 0;
18.1088 + return;
18.1089 + }
18.1090 +
18.1091 + // Approximate the quotient and remainder
18.1092 + long q = (n >>> 1) / (dLong >>> 1);
18.1093 + long r = n - q*dLong;
18.1094 +
18.1095 + // Correct the approximation
18.1096 + while (r < 0) {
18.1097 + r += dLong;
18.1098 + q--;
18.1099 + }
18.1100 + while (r >= dLong) {
18.1101 + r -= dLong;
18.1102 + q++;
18.1103 + }
18.1104 +
18.1105 + // n - q*dlong == r && 0 <= r <dLong, hence we're done.
18.1106 + result[0] = (int)q;
18.1107 + result[1] = (int)r;
18.1108 + }
18.1109 +
18.1110 + /**
18.1111 + * Calculate GCD of this and b. This and b are changed by the computation.
18.1112 + */
18.1113 + MutableBigInteger hybridGCD(MutableBigInteger b) {
18.1114 + // Use Euclid's algorithm until the numbers are approximately the
18.1115 + // same length, then use the binary GCD algorithm to find the GCD.
18.1116 + MutableBigInteger a = this;
18.1117 + MutableBigInteger q = new MutableBigInteger();
18.1118 +
18.1119 + while (b.intLen != 0) {
18.1120 + if (Math.abs(a.intLen - b.intLen) < 2)
18.1121 + return a.binaryGCD(b);
18.1122 +
18.1123 + MutableBigInteger r = a.divide(b, q);
18.1124 + a = b;
18.1125 + b = r;
18.1126 + }
18.1127 + return a;
18.1128 + }
18.1129 +
18.1130 + /**
18.1131 + * Calculate GCD of this and v.
18.1132 + * Assumes that this and v are not zero.
18.1133 + */
18.1134 + private MutableBigInteger binaryGCD(MutableBigInteger v) {
18.1135 + // Algorithm B from Knuth section 4.5.2
18.1136 + MutableBigInteger u = this;
18.1137 + MutableBigInteger r = new MutableBigInteger();
18.1138 +
18.1139 + // step B1
18.1140 + int s1 = u.getLowestSetBit();
18.1141 + int s2 = v.getLowestSetBit();
18.1142 + int k = (s1 < s2) ? s1 : s2;
18.1143 + if (k != 0) {
18.1144 + u.rightShift(k);
18.1145 + v.rightShift(k);
18.1146 + }
18.1147 +
18.1148 + // step B2
18.1149 + boolean uOdd = (k==s1);
18.1150 + MutableBigInteger t = uOdd ? v: u;
18.1151 + int tsign = uOdd ? -1 : 1;
18.1152 +
18.1153 + int lb;
18.1154 + while ((lb = t.getLowestSetBit()) >= 0) {
18.1155 + // steps B3 and B4
18.1156 + t.rightShift(lb);
18.1157 + // step B5
18.1158 + if (tsign > 0)
18.1159 + u = t;
18.1160 + else
18.1161 + v = t;
18.1162 +
18.1163 + // Special case one word numbers
18.1164 + if (u.intLen < 2 && v.intLen < 2) {
18.1165 + int x = u.value[u.offset];
18.1166 + int y = v.value[v.offset];
18.1167 + x = binaryGcd(x, y);
18.1168 + r.value[0] = x;
18.1169 + r.intLen = 1;
18.1170 + r.offset = 0;
18.1171 + if (k > 0)
18.1172 + r.leftShift(k);
18.1173 + return r;
18.1174 + }
18.1175 +
18.1176 + // step B6
18.1177 + if ((tsign = u.difference(v)) == 0)
18.1178 + break;
18.1179 + t = (tsign >= 0) ? u : v;
18.1180 + }
18.1181 +
18.1182 + if (k > 0)
18.1183 + u.leftShift(k);
18.1184 + return u;
18.1185 + }
18.1186 +
18.1187 + /**
18.1188 + * Calculate GCD of a and b interpreted as unsigned integers.
18.1189 + */
18.1190 + static int binaryGcd(int a, int b) {
18.1191 + if (b==0)
18.1192 + return a;
18.1193 + if (a==0)
18.1194 + return b;
18.1195 +
18.1196 + // Right shift a & b till their last bits equal to 1.
18.1197 + int aZeros = Integer.numberOfTrailingZeros(a);
18.1198 + int bZeros = Integer.numberOfTrailingZeros(b);
18.1199 + a >>>= aZeros;
18.1200 + b >>>= bZeros;
18.1201 +
18.1202 + int t = (aZeros < bZeros ? aZeros : bZeros);
18.1203 +
18.1204 + while (a != b) {
18.1205 + if ((a+0x80000000) > (b+0x80000000)) { // a > b as unsigned
18.1206 + a -= b;
18.1207 + a >>>= Integer.numberOfTrailingZeros(a);
18.1208 + } else {
18.1209 + b -= a;
18.1210 + b >>>= Integer.numberOfTrailingZeros(b);
18.1211 + }
18.1212 + }
18.1213 + return a<<t;
18.1214 + }
18.1215 +
18.1216 + /**
18.1217 + * Returns the modInverse of this mod p. This and p are not affected by
18.1218 + * the operation.
18.1219 + */
18.1220 + MutableBigInteger mutableModInverse(MutableBigInteger p) {
18.1221 + // Modulus is odd, use Schroeppel's algorithm
18.1222 + if (p.isOdd())
18.1223 + return modInverse(p);
18.1224 +
18.1225 + // Base and modulus are even, throw exception
18.1226 + if (isEven())
18.1227 + throw new ArithmeticException("BigInteger not invertible.");
18.1228 +
18.1229 + // Get even part of modulus expressed as a power of 2
18.1230 + int powersOf2 = p.getLowestSetBit();
18.1231 +
18.1232 + // Construct odd part of modulus
18.1233 + MutableBigInteger oddMod = new MutableBigInteger(p);
18.1234 + oddMod.rightShift(powersOf2);
18.1235 +
18.1236 + if (oddMod.isOne())
18.1237 + return modInverseMP2(powersOf2);
18.1238 +
18.1239 + // Calculate 1/a mod oddMod
18.1240 + MutableBigInteger oddPart = modInverse(oddMod);
18.1241 +
18.1242 + // Calculate 1/a mod evenMod
18.1243 + MutableBigInteger evenPart = modInverseMP2(powersOf2);
18.1244 +
18.1245 + // Combine the results using Chinese Remainder Theorem
18.1246 + MutableBigInteger y1 = modInverseBP2(oddMod, powersOf2);
18.1247 + MutableBigInteger y2 = oddMod.modInverseMP2(powersOf2);
18.1248 +
18.1249 + MutableBigInteger temp1 = new MutableBigInteger();
18.1250 + MutableBigInteger temp2 = new MutableBigInteger();
18.1251 + MutableBigInteger result = new MutableBigInteger();
18.1252 +
18.1253 + oddPart.leftShift(powersOf2);
18.1254 + oddPart.multiply(y1, result);
18.1255 +
18.1256 + evenPart.multiply(oddMod, temp1);
18.1257 + temp1.multiply(y2, temp2);
18.1258 +
18.1259 + result.add(temp2);
18.1260 + return result.divide(p, temp1);
18.1261 + }
18.1262 +
18.1263 + /*
18.1264 + * Calculate the multiplicative inverse of this mod 2^k.
18.1265 + */
18.1266 + MutableBigInteger modInverseMP2(int k) {
18.1267 + if (isEven())
18.1268 + throw new ArithmeticException("Non-invertible. (GCD != 1)");
18.1269 +
18.1270 + if (k > 64)
18.1271 + return euclidModInverse(k);
18.1272 +
18.1273 + int t = inverseMod32(value[offset+intLen-1]);
18.1274 +
18.1275 + if (k < 33) {
18.1276 + t = (k == 32 ? t : t & ((1 << k) - 1));
18.1277 + return new MutableBigInteger(t);
18.1278 + }
18.1279 +
18.1280 + long pLong = (value[offset+intLen-1] & LONG_MASK);
18.1281 + if (intLen > 1)
18.1282 + pLong |= ((long)value[offset+intLen-2] << 32);
18.1283 + long tLong = t & LONG_MASK;
18.1284 + tLong = tLong * (2 - pLong * tLong); // 1 more Newton iter step
18.1285 + tLong = (k == 64 ? tLong : tLong & ((1L << k) - 1));
18.1286 +
18.1287 + MutableBigInteger result = new MutableBigInteger(new int[2]);
18.1288 + result.value[0] = (int)(tLong >>> 32);
18.1289 + result.value[1] = (int)tLong;
18.1290 + result.intLen = 2;
18.1291 + result.normalize();
18.1292 + return result;
18.1293 + }
18.1294 +
18.1295 + /*
18.1296 + * Returns the multiplicative inverse of val mod 2^32. Assumes val is odd.
18.1297 + */
18.1298 + static int inverseMod32(int val) {
18.1299 + // Newton's iteration!
18.1300 + int t = val;
18.1301 + t *= 2 - val*t;
18.1302 + t *= 2 - val*t;
18.1303 + t *= 2 - val*t;
18.1304 + t *= 2 - val*t;
18.1305 + return t;
18.1306 + }
18.1307 +
18.1308 + /*
18.1309 + * Calculate the multiplicative inverse of 2^k mod mod, where mod is odd.
18.1310 + */
18.1311 + static MutableBigInteger modInverseBP2(MutableBigInteger mod, int k) {
18.1312 + // Copy the mod to protect original
18.1313 + return fixup(new MutableBigInteger(1), new MutableBigInteger(mod), k);
18.1314 + }
18.1315 +
18.1316 + /**
18.1317 + * Calculate the multiplicative inverse of this mod mod, where mod is odd.
18.1318 + * This and mod are not changed by the calculation.
18.1319 + *
18.1320 + * This method implements an algorithm due to Richard Schroeppel, that uses
18.1321 + * the same intermediate representation as Montgomery Reduction
18.1322 + * ("Montgomery Form"). The algorithm is described in an unpublished
18.1323 + * manuscript entitled "Fast Modular Reciprocals."
18.1324 + */
18.1325 + private MutableBigInteger modInverse(MutableBigInteger mod) {
18.1326 + MutableBigInteger p = new MutableBigInteger(mod);
18.1327 + MutableBigInteger f = new MutableBigInteger(this);
18.1328 + MutableBigInteger g = new MutableBigInteger(p);
18.1329 + SignedMutableBigInteger c = new SignedMutableBigInteger(1);
18.1330 + SignedMutableBigInteger d = new SignedMutableBigInteger();
18.1331 + MutableBigInteger temp = null;
18.1332 + SignedMutableBigInteger sTemp = null;
18.1333 +
18.1334 + int k = 0;
18.1335 + // Right shift f k times until odd, left shift d k times
18.1336 + if (f.isEven()) {
18.1337 + int trailingZeros = f.getLowestSetBit();
18.1338 + f.rightShift(trailingZeros);
18.1339 + d.leftShift(trailingZeros);
18.1340 + k = trailingZeros;
18.1341 + }
18.1342 +
18.1343 + // The Almost Inverse Algorithm
18.1344 + while(!f.isOne()) {
18.1345 + // If gcd(f, g) != 1, number is not invertible modulo mod
18.1346 + if (f.isZero())
18.1347 + throw new ArithmeticException("BigInteger not invertible.");
18.1348 +
18.1349 + // If f < g exchange f, g and c, d
18.1350 + if (f.compare(g) < 0) {
18.1351 + temp = f; f = g; g = temp;
18.1352 + sTemp = d; d = c; c = sTemp;
18.1353 + }
18.1354 +
18.1355 + // If f == g (mod 4)
18.1356 + if (((f.value[f.offset + f.intLen - 1] ^
18.1357 + g.value[g.offset + g.intLen - 1]) & 3) == 0) {
18.1358 + f.subtract(g);
18.1359 + c.signedSubtract(d);
18.1360 + } else { // If f != g (mod 4)
18.1361 + f.add(g);
18.1362 + c.signedAdd(d);
18.1363 + }
18.1364 +
18.1365 + // Right shift f k times until odd, left shift d k times
18.1366 + int trailingZeros = f.getLowestSetBit();
18.1367 + f.rightShift(trailingZeros);
18.1368 + d.leftShift(trailingZeros);
18.1369 + k += trailingZeros;
18.1370 + }
18.1371 +
18.1372 + while (c.sign < 0)
18.1373 + c.signedAdd(p);
18.1374 +
18.1375 + return fixup(c, p, k);
18.1376 + }
18.1377 +
18.1378 + /*
18.1379 + * The Fixup Algorithm
18.1380 + * Calculates X such that X = C * 2^(-k) (mod P)
18.1381 + * Assumes C<P and P is odd.
18.1382 + */
18.1383 + static MutableBigInteger fixup(MutableBigInteger c, MutableBigInteger p,
18.1384 + int k) {
18.1385 + MutableBigInteger temp = new MutableBigInteger();
18.1386 + // Set r to the multiplicative inverse of p mod 2^32
18.1387 + int r = -inverseMod32(p.value[p.offset+p.intLen-1]);
18.1388 +
18.1389 + for(int i=0, numWords = k >> 5; i<numWords; i++) {
18.1390 + // V = R * c (mod 2^j)
18.1391 + int v = r * c.value[c.offset + c.intLen-1];
18.1392 + // c = c + (v * p)
18.1393 + p.mul(v, temp);
18.1394 + c.add(temp);
18.1395 + // c = c / 2^j
18.1396 + c.intLen--;
18.1397 + }
18.1398 + int numBits = k & 0x1f;
18.1399 + if (numBits != 0) {
18.1400 + // V = R * c (mod 2^j)
18.1401 + int v = r * c.value[c.offset + c.intLen-1];
18.1402 + v &= ((1<<numBits) - 1);
18.1403 + // c = c + (v * p)
18.1404 + p.mul(v, temp);
18.1405 + c.add(temp);
18.1406 + // c = c / 2^j
18.1407 + c.rightShift(numBits);
18.1408 + }
18.1409 +
18.1410 + // In theory, c may be greater than p at this point (Very rare!)
18.1411 + while (c.compare(p) >= 0)
18.1412 + c.subtract(p);
18.1413 +
18.1414 + return c;
18.1415 + }
18.1416 +
18.1417 + /**
18.1418 + * Uses the extended Euclidean algorithm to compute the modInverse of base
18.1419 + * mod a modulus that is a power of 2. The modulus is 2^k.
18.1420 + */
18.1421 + MutableBigInteger euclidModInverse(int k) {
18.1422 + MutableBigInteger b = new MutableBigInteger(1);
18.1423 + b.leftShift(k);
18.1424 + MutableBigInteger mod = new MutableBigInteger(b);
18.1425 +
18.1426 + MutableBigInteger a = new MutableBigInteger(this);
18.1427 + MutableBigInteger q = new MutableBigInteger();
18.1428 + MutableBigInteger r = b.divide(a, q);
18.1429 +
18.1430 + MutableBigInteger swapper = b;
18.1431 + // swap b & r
18.1432 + b = r;
18.1433 + r = swapper;
18.1434 +
18.1435 + MutableBigInteger t1 = new MutableBigInteger(q);
18.1436 + MutableBigInteger t0 = new MutableBigInteger(1);
18.1437 + MutableBigInteger temp = new MutableBigInteger();
18.1438 +
18.1439 + while (!b.isOne()) {
18.1440 + r = a.divide(b, q);
18.1441 +
18.1442 + if (r.intLen == 0)
18.1443 + throw new ArithmeticException("BigInteger not invertible.");
18.1444 +
18.1445 + swapper = r;
18.1446 + a = swapper;
18.1447 +
18.1448 + if (q.intLen == 1)
18.1449 + t1.mul(q.value[q.offset], temp);
18.1450 + else
18.1451 + q.multiply(t1, temp);
18.1452 + swapper = q;
18.1453 + q = temp;
18.1454 + temp = swapper;
18.1455 + t0.add(q);
18.1456 +
18.1457 + if (a.isOne())
18.1458 + return t0;
18.1459 +
18.1460 + r = b.divide(a, q);
18.1461 +
18.1462 + if (r.intLen == 0)
18.1463 + throw new ArithmeticException("BigInteger not invertible.");
18.1464 +
18.1465 + swapper = b;
18.1466 + b = r;
18.1467 +
18.1468 + if (q.intLen == 1)
18.1469 + t0.mul(q.value[q.offset], temp);
18.1470 + else
18.1471 + q.multiply(t0, temp);
18.1472 + swapper = q; q = temp; temp = swapper;
18.1473 +
18.1474 + t1.add(q);
18.1475 + }
18.1476 + mod.subtract(t1);
18.1477 + return mod;
18.1478 + }
18.1479 +
18.1480 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/emul/compact/src/main/java/java/math/RoundingMode.java Sat Sep 07 13:51:24 2013 +0200
19.3 @@ -0,0 +1,349 @@
19.4 +/*
19.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19.7 + *
19.8 + * This code is free software; you can redistribute it and/or modify it
19.9 + * under the terms of the GNU General Public License version 2 only, as
19.10 + * published by the Free Software Foundation. Oracle designates this
19.11 + * particular file as subject to the "Classpath" exception as provided
19.12 + * by Oracle in the LICENSE file that accompanied this code.
19.13 + *
19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19.17 + * version 2 for more details (a copy is included in the LICENSE file that
19.18 + * accompanied this code).
19.19 + *
19.20 + * You should have received a copy of the GNU General Public License version
19.21 + * 2 along with this work; if not, write to the Free Software Foundation,
19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19.23 + *
19.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19.25 + * or visit www.oracle.com if you need additional information or have any
19.26 + * questions.
19.27 + */
19.28 +
19.29 +/*
19.30 + * Portions Copyright IBM Corporation, 2001. All Rights Reserved.
19.31 + */
19.32 +package java.math;
19.33 +
19.34 +/**
19.35 + * Specifies a <i>rounding behavior</i> for numerical operations
19.36 + * capable of discarding precision. Each rounding mode indicates how
19.37 + * the least significant returned digit of a rounded result is to be
19.38 + * calculated. If fewer digits are returned than the digits needed to
19.39 + * represent the exact numerical result, the discarded digits will be
19.40 + * referred to as the <i>discarded fraction</i> regardless the digits'
19.41 + * contribution to the value of the number. In other words,
19.42 + * considered as a numerical value, the discarded fraction could have
19.43 + * an absolute value greater than one.
19.44 + *
19.45 + * <p>Each rounding mode description includes a table listing how
19.46 + * different two-digit decimal values would round to a one digit
19.47 + * decimal value under the rounding mode in question. The result
19.48 + * column in the tables could be gotten by creating a
19.49 + * {@code BigDecimal} number with the specified value, forming a
19.50 + * {@link MathContext} object with the proper settings
19.51 + * ({@code precision} set to {@code 1}, and the
19.52 + * {@code roundingMode} set to the rounding mode in question), and
19.53 + * calling {@link BigDecimal#round round} on this number with the
19.54 + * proper {@code MathContext}. A summary table showing the results
19.55 + * of these rounding operations for all rounding modes appears below.
19.56 + *
19.57 + *<p>
19.58 + *<table border>
19.59 + * <caption><b>Summary of Rounding Operations Under Different Rounding Modes</b></caption>
19.60 + * <tr><th></th><th colspan=8>Result of rounding input to one digit with the given
19.61 + * rounding mode</th>
19.62 + * <tr valign=top>
19.63 + * <th>Input Number</th> <th>{@code UP}</th>
19.64 + * <th>{@code DOWN}</th>
19.65 + * <th>{@code CEILING}</th>
19.66 + * <th>{@code FLOOR}</th>
19.67 + * <th>{@code HALF_UP}</th>
19.68 + * <th>{@code HALF_DOWN}</th>
19.69 + * <th>{@code HALF_EVEN}</th>
19.70 + * <th>{@code UNNECESSARY}</th>
19.71 + *
19.72 + * <tr align=right><td>5.5</td> <td>6</td> <td>5</td> <td>6</td> <td>5</td> <td>6</td> <td>5</td> <td>6</td> <td>throw {@code ArithmeticException}</td>
19.73 + * <tr align=right><td>2.5</td> <td>3</td> <td>2</td> <td>3</td> <td>2</td> <td>3</td> <td>2</td> <td>2</td> <td>throw {@code ArithmeticException}</td>
19.74 + * <tr align=right><td>1.6</td> <td>2</td> <td>1</td> <td>2</td> <td>1</td> <td>2</td> <td>2</td> <td>2</td> <td>throw {@code ArithmeticException}</td>
19.75 + * <tr align=right><td>1.1</td> <td>2</td> <td>1</td> <td>2</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>throw {@code ArithmeticException}</td>
19.76 + * <tr align=right><td>1.0</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td> <td>1</td>
19.77 + * <tr align=right><td>-1.0</td> <td>-1</td> <td>-1</td> <td>-1</td> <td>-1</td> <td>-1</td> <td>-1</td> <td>-1</td> <td>-1</td>
19.78 + * <tr align=right><td>-1.1</td> <td>-2</td> <td>-1</td> <td>-1</td> <td>-2</td> <td>-1</td> <td>-1</td> <td>-1</td> <td>throw {@code ArithmeticException}</td>
19.79 + * <tr align=right><td>-1.6</td> <td>-2</td> <td>-1</td> <td>-1</td> <td>-2</td> <td>-2</td> <td>-2</td> <td>-2</td> <td>throw {@code ArithmeticException}</td>
19.80 + * <tr align=right><td>-2.5</td> <td>-3</td> <td>-2</td> <td>-2</td> <td>-3</td> <td>-3</td> <td>-2</td> <td>-2</td> <td>throw {@code ArithmeticException}</td>
19.81 + * <tr align=right><td>-5.5</td> <td>-6</td> <td>-5</td> <td>-5</td> <td>-6</td> <td>-6</td> <td>-5</td> <td>-6</td> <td>throw {@code ArithmeticException}</td>
19.82 + *</table>
19.83 + *
19.84 + *
19.85 + * <p>This {@code enum} is intended to replace the integer-based
19.86 + * enumeration of rounding mode constants in {@link BigDecimal}
19.87 + * ({@link BigDecimal#ROUND_UP}, {@link BigDecimal#ROUND_DOWN},
19.88 + * etc. ).
19.89 + *
19.90 + * @see BigDecimal
19.91 + * @see MathContext
19.92 + * @author Josh Bloch
19.93 + * @author Mike Cowlishaw
19.94 + * @author Joseph D. Darcy
19.95 + * @since 1.5
19.96 + */
19.97 +public enum RoundingMode {
19.98 +
19.99 + /**
19.100 + * Rounding mode to round away from zero. Always increments the
19.101 + * digit prior to a non-zero discarded fraction. Note that this
19.102 + * rounding mode never decreases the magnitude of the calculated
19.103 + * value.
19.104 + *
19.105 + *<p>Example:
19.106 + *<table border>
19.107 + *<tr valign=top><th>Input Number</th>
19.108 + * <th>Input rounded to one digit<br> with {@code UP} rounding
19.109 + *<tr align=right><td>5.5</td> <td>6</td>
19.110 + *<tr align=right><td>2.5</td> <td>3</td>
19.111 + *<tr align=right><td>1.6</td> <td>2</td>
19.112 + *<tr align=right><td>1.1</td> <td>2</td>
19.113 + *<tr align=right><td>1.0</td> <td>1</td>
19.114 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.115 + *<tr align=right><td>-1.1</td> <td>-2</td>
19.116 + *<tr align=right><td>-1.6</td> <td>-2</td>
19.117 + *<tr align=right><td>-2.5</td> <td>-3</td>
19.118 + *<tr align=right><td>-5.5</td> <td>-6</td>
19.119 + *</table>
19.120 + */
19.121 + UP(BigDecimal.ROUND_UP),
19.122 +
19.123 + /**
19.124 + * Rounding mode to round towards zero. Never increments the digit
19.125 + * prior to a discarded fraction (i.e., truncates). Note that this
19.126 + * rounding mode never increases the magnitude of the calculated value.
19.127 + *
19.128 + *<p>Example:
19.129 + *<table border>
19.130 + *<tr valign=top><th>Input Number</th>
19.131 + * <th>Input rounded to one digit<br> with {@code DOWN} rounding
19.132 + *<tr align=right><td>5.5</td> <td>5</td>
19.133 + *<tr align=right><td>2.5</td> <td>2</td>
19.134 + *<tr align=right><td>1.6</td> <td>1</td>
19.135 + *<tr align=right><td>1.1</td> <td>1</td>
19.136 + *<tr align=right><td>1.0</td> <td>1</td>
19.137 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.138 + *<tr align=right><td>-1.1</td> <td>-1</td>
19.139 + *<tr align=right><td>-1.6</td> <td>-1</td>
19.140 + *<tr align=right><td>-2.5</td> <td>-2</td>
19.141 + *<tr align=right><td>-5.5</td> <td>-5</td>
19.142 + *</table>
19.143 + */
19.144 + DOWN(BigDecimal.ROUND_DOWN),
19.145 +
19.146 + /**
19.147 + * Rounding mode to round towards positive infinity. If the
19.148 + * result is positive, behaves as for {@code RoundingMode.UP};
19.149 + * if negative, behaves as for {@code RoundingMode.DOWN}. Note
19.150 + * that this rounding mode never decreases the calculated value.
19.151 + *
19.152 + *<p>Example:
19.153 + *<table border>
19.154 + *<tr valign=top><th>Input Number</th>
19.155 + * <th>Input rounded to one digit<br> with {@code CEILING} rounding
19.156 + *<tr align=right><td>5.5</td> <td>6</td>
19.157 + *<tr align=right><td>2.5</td> <td>3</td>
19.158 + *<tr align=right><td>1.6</td> <td>2</td>
19.159 + *<tr align=right><td>1.1</td> <td>2</td>
19.160 + *<tr align=right><td>1.0</td> <td>1</td>
19.161 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.162 + *<tr align=right><td>-1.1</td> <td>-1</td>
19.163 + *<tr align=right><td>-1.6</td> <td>-1</td>
19.164 + *<tr align=right><td>-2.5</td> <td>-2</td>
19.165 + *<tr align=right><td>-5.5</td> <td>-5</td>
19.166 + *</table>
19.167 + */
19.168 + CEILING(BigDecimal.ROUND_CEILING),
19.169 +
19.170 + /**
19.171 + * Rounding mode to round towards negative infinity. If the
19.172 + * result is positive, behave as for {@code RoundingMode.DOWN};
19.173 + * if negative, behave as for {@code RoundingMode.UP}. Note that
19.174 + * this rounding mode never increases the calculated value.
19.175 + *
19.176 + *<p>Example:
19.177 + *<table border>
19.178 + *<tr valign=top><th>Input Number</th>
19.179 + * <th>Input rounded to one digit<br> with {@code FLOOR} rounding
19.180 + *<tr align=right><td>5.5</td> <td>5</td>
19.181 + *<tr align=right><td>2.5</td> <td>2</td>
19.182 + *<tr align=right><td>1.6</td> <td>1</td>
19.183 + *<tr align=right><td>1.1</td> <td>1</td>
19.184 + *<tr align=right><td>1.0</td> <td>1</td>
19.185 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.186 + *<tr align=right><td>-1.1</td> <td>-2</td>
19.187 + *<tr align=right><td>-1.6</td> <td>-2</td>
19.188 + *<tr align=right><td>-2.5</td> <td>-3</td>
19.189 + *<tr align=right><td>-5.5</td> <td>-6</td>
19.190 + *</table>
19.191 + */
19.192 + FLOOR(BigDecimal.ROUND_FLOOR),
19.193 +
19.194 + /**
19.195 + * Rounding mode to round towards {@literal "nearest neighbor"}
19.196 + * unless both neighbors are equidistant, in which case round up.
19.197 + * Behaves as for {@code RoundingMode.UP} if the discarded
19.198 + * fraction is ≥ 0.5; otherwise, behaves as for
19.199 + * {@code RoundingMode.DOWN}. Note that this is the rounding
19.200 + * mode commonly taught at school.
19.201 + *
19.202 + *<p>Example:
19.203 + *<table border>
19.204 + *<tr valign=top><th>Input Number</th>
19.205 + * <th>Input rounded to one digit<br> with {@code HALF_UP} rounding
19.206 + *<tr align=right><td>5.5</td> <td>6</td>
19.207 + *<tr align=right><td>2.5</td> <td>3</td>
19.208 + *<tr align=right><td>1.6</td> <td>2</td>
19.209 + *<tr align=right><td>1.1</td> <td>1</td>
19.210 + *<tr align=right><td>1.0</td> <td>1</td>
19.211 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.212 + *<tr align=right><td>-1.1</td> <td>-1</td>
19.213 + *<tr align=right><td>-1.6</td> <td>-2</td>
19.214 + *<tr align=right><td>-2.5</td> <td>-3</td>
19.215 + *<tr align=right><td>-5.5</td> <td>-6</td>
19.216 + *</table>
19.217 + */
19.218 + HALF_UP(BigDecimal.ROUND_HALF_UP),
19.219 +
19.220 + /**
19.221 + * Rounding mode to round towards {@literal "nearest neighbor"}
19.222 + * unless both neighbors are equidistant, in which case round
19.223 + * down. Behaves as for {@code RoundingMode.UP} if the discarded
19.224 + * fraction is > 0.5; otherwise, behaves as for
19.225 + * {@code RoundingMode.DOWN}.
19.226 + *
19.227 + *<p>Example:
19.228 + *<table border>
19.229 + *<tr valign=top><th>Input Number</th>
19.230 + * <th>Input rounded to one digit<br> with {@code HALF_DOWN} rounding
19.231 + *<tr align=right><td>5.5</td> <td>5</td>
19.232 + *<tr align=right><td>2.5</td> <td>2</td>
19.233 + *<tr align=right><td>1.6</td> <td>2</td>
19.234 + *<tr align=right><td>1.1</td> <td>1</td>
19.235 + *<tr align=right><td>1.0</td> <td>1</td>
19.236 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.237 + *<tr align=right><td>-1.1</td> <td>-1</td>
19.238 + *<tr align=right><td>-1.6</td> <td>-2</td>
19.239 + *<tr align=right><td>-2.5</td> <td>-2</td>
19.240 + *<tr align=right><td>-5.5</td> <td>-5</td>
19.241 + *</table>
19.242 + */
19.243 + HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
19.244 +
19.245 + /**
19.246 + * Rounding mode to round towards the {@literal "nearest neighbor"}
19.247 + * unless both neighbors are equidistant, in which case, round
19.248 + * towards the even neighbor. Behaves as for
19.249 + * {@code RoundingMode.HALF_UP} if the digit to the left of the
19.250 + * discarded fraction is odd; behaves as for
19.251 + * {@code RoundingMode.HALF_DOWN} if it's even. Note that this
19.252 + * is the rounding mode that statistically minimizes cumulative
19.253 + * error when applied repeatedly over a sequence of calculations.
19.254 + * It is sometimes known as {@literal "Banker's rounding,"} and is
19.255 + * chiefly used in the USA. This rounding mode is analogous to
19.256 + * the rounding policy used for {@code float} and {@code double}
19.257 + * arithmetic in Java.
19.258 + *
19.259 + *<p>Example:
19.260 + *<table border>
19.261 + *<tr valign=top><th>Input Number</th>
19.262 + * <th>Input rounded to one digit<br> with {@code HALF_EVEN} rounding
19.263 + *<tr align=right><td>5.5</td> <td>6</td>
19.264 + *<tr align=right><td>2.5</td> <td>2</td>
19.265 + *<tr align=right><td>1.6</td> <td>2</td>
19.266 + *<tr align=right><td>1.1</td> <td>1</td>
19.267 + *<tr align=right><td>1.0</td> <td>1</td>
19.268 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.269 + *<tr align=right><td>-1.1</td> <td>-1</td>
19.270 + *<tr align=right><td>-1.6</td> <td>-2</td>
19.271 + *<tr align=right><td>-2.5</td> <td>-2</td>
19.272 + *<tr align=right><td>-5.5</td> <td>-6</td>
19.273 + *</table>
19.274 + */
19.275 + HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
19.276 +
19.277 + /**
19.278 + * Rounding mode to assert that the requested operation has an exact
19.279 + * result, hence no rounding is necessary. If this rounding mode is
19.280 + * specified on an operation that yields an inexact result, an
19.281 + * {@code ArithmeticException} is thrown.
19.282 + *<p>Example:
19.283 + *<table border>
19.284 + *<tr valign=top><th>Input Number</th>
19.285 + * <th>Input rounded to one digit<br> with {@code UNNECESSARY} rounding
19.286 + *<tr align=right><td>5.5</td> <td>throw {@code ArithmeticException}</td>
19.287 + *<tr align=right><td>2.5</td> <td>throw {@code ArithmeticException}</td>
19.288 + *<tr align=right><td>1.6</td> <td>throw {@code ArithmeticException}</td>
19.289 + *<tr align=right><td>1.1</td> <td>throw {@code ArithmeticException}</td>
19.290 + *<tr align=right><td>1.0</td> <td>1</td>
19.291 + *<tr align=right><td>-1.0</td> <td>-1</td>
19.292 + *<tr align=right><td>-1.1</td> <td>throw {@code ArithmeticException}</td>
19.293 + *<tr align=right><td>-1.6</td> <td>throw {@code ArithmeticException}</td>
19.294 + *<tr align=right><td>-2.5</td> <td>throw {@code ArithmeticException}</td>
19.295 + *<tr align=right><td>-5.5</td> <td>throw {@code ArithmeticException}</td>
19.296 + *</table>
19.297 + */
19.298 + UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
19.299 +
19.300 + // Corresponding BigDecimal rounding constant
19.301 + final int oldMode;
19.302 +
19.303 + /**
19.304 + * Constructor
19.305 + *
19.306 + * @param oldMode The {@code BigDecimal} constant corresponding to
19.307 + * this mode
19.308 + */
19.309 + private RoundingMode(int oldMode) {
19.310 + this.oldMode = oldMode;
19.311 + }
19.312 +
19.313 + /**
19.314 + * Returns the {@code RoundingMode} object corresponding to a
19.315 + * legacy integer rounding mode constant in {@link BigDecimal}.
19.316 + *
19.317 + * @param rm legacy integer rounding mode to convert
19.318 + * @return {@code RoundingMode} corresponding to the given integer.
19.319 + * @throws IllegalArgumentException integer is out of range
19.320 + */
19.321 + public static RoundingMode valueOf(int rm) {
19.322 + switch(rm) {
19.323 +
19.324 + case BigDecimal.ROUND_UP:
19.325 + return UP;
19.326 +
19.327 + case BigDecimal.ROUND_DOWN:
19.328 + return DOWN;
19.329 +
19.330 + case BigDecimal.ROUND_CEILING:
19.331 + return CEILING;
19.332 +
19.333 + case BigDecimal.ROUND_FLOOR:
19.334 + return FLOOR;
19.335 +
19.336 + case BigDecimal.ROUND_HALF_UP:
19.337 + return HALF_UP;
19.338 +
19.339 + case BigDecimal.ROUND_HALF_DOWN:
19.340 + return HALF_DOWN;
19.341 +
19.342 + case BigDecimal.ROUND_HALF_EVEN:
19.343 + return HALF_EVEN;
19.344 +
19.345 + case BigDecimal.ROUND_UNNECESSARY:
19.346 + return UNNECESSARY;
19.347 +
19.348 + default:
19.349 + throw new IllegalArgumentException("argument out of range");
19.350 + }
19.351 + }
19.352 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/emul/compact/src/main/java/java/math/SignedMutableBigInteger.java Sat Sep 07 13:51:24 2013 +0200
20.3 @@ -0,0 +1,135 @@
20.4 +/*
20.5 + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
20.7 + *
20.8 + * This code is free software; you can redistribute it and/or modify it
20.9 + * under the terms of the GNU General Public License version 2 only, as
20.10 + * published by the Free Software Foundation. Oracle designates this
20.11 + * particular file as subject to the "Classpath" exception as provided
20.12 + * by Oracle in the LICENSE file that accompanied this code.
20.13 + *
20.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
20.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20.17 + * version 2 for more details (a copy is included in the LICENSE file that
20.18 + * accompanied this code).
20.19 + *
20.20 + * You should have received a copy of the GNU General Public License version
20.21 + * 2 along with this work; if not, write to the Free Software Foundation,
20.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20.23 + *
20.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20.25 + * or visit www.oracle.com if you need additional information or have any
20.26 + * questions.
20.27 + */
20.28 +
20.29 +package java.math;
20.30 +
20.31 +/**
20.32 + * A class used to represent multiprecision integers that makes efficient
20.33 + * use of allocated space by allowing a number to occupy only part of
20.34 + * an array so that the arrays do not have to be reallocated as often.
20.35 + * When performing an operation with many iterations the array used to
20.36 + * hold a number is only increased when necessary and does not have to
20.37 + * be the same size as the number it represents. A mutable number allows
20.38 + * calculations to occur on the same number without having to create
20.39 + * a new number for every step of the calculation as occurs with
20.40 + * BigIntegers.
20.41 + *
20.42 + * Note that SignedMutableBigIntegers only support signed addition and
20.43 + * subtraction. All other operations occur as with MutableBigIntegers.
20.44 + *
20.45 + * @see BigInteger
20.46 + * @author Michael McCloskey
20.47 + * @since 1.3
20.48 + */
20.49 +
20.50 +class SignedMutableBigInteger extends MutableBigInteger {
20.51 +
20.52 + /**
20.53 + * The sign of this MutableBigInteger.
20.54 + */
20.55 + int sign = 1;
20.56 +
20.57 + // Constructors
20.58 +
20.59 + /**
20.60 + * The default constructor. An empty MutableBigInteger is created with
20.61 + * a one word capacity.
20.62 + */
20.63 + SignedMutableBigInteger() {
20.64 + super();
20.65 + }
20.66 +
20.67 + /**
20.68 + * Construct a new MutableBigInteger with a magnitude specified by
20.69 + * the int val.
20.70 + */
20.71 + SignedMutableBigInteger(int val) {
20.72 + super(val);
20.73 + }
20.74 +
20.75 + /**
20.76 + * Construct a new MutableBigInteger with a magnitude equal to the
20.77 + * specified MutableBigInteger.
20.78 + */
20.79 + SignedMutableBigInteger(MutableBigInteger val) {
20.80 + super(val);
20.81 + }
20.82 +
20.83 + // Arithmetic Operations
20.84 +
20.85 + /**
20.86 + * Signed addition built upon unsigned add and subtract.
20.87 + */
20.88 + void signedAdd(SignedMutableBigInteger addend) {
20.89 + if (sign == addend.sign)
20.90 + add(addend);
20.91 + else
20.92 + sign = sign * subtract(addend);
20.93 +
20.94 + }
20.95 +
20.96 + /**
20.97 + * Signed addition built upon unsigned add and subtract.
20.98 + */
20.99 + void signedAdd(MutableBigInteger addend) {
20.100 + if (sign == 1)
20.101 + add(addend);
20.102 + else
20.103 + sign = sign * subtract(addend);
20.104 +
20.105 + }
20.106 +
20.107 + /**
20.108 + * Signed subtraction built upon unsigned add and subtract.
20.109 + */
20.110 + void signedSubtract(SignedMutableBigInteger addend) {
20.111 + if (sign == addend.sign)
20.112 + sign = sign * subtract(addend);
20.113 + else
20.114 + add(addend);
20.115 +
20.116 + }
20.117 +
20.118 + /**
20.119 + * Signed subtraction built upon unsigned add and subtract.
20.120 + */
20.121 + void signedSubtract(MutableBigInteger addend) {
20.122 + if (sign == 1)
20.123 + sign = sign * subtract(addend);
20.124 + else
20.125 + add(addend);
20.126 + if (intLen == 0)
20.127 + sign = 1;
20.128 + }
20.129 +
20.130 + /**
20.131 + * Print out the first intLen ints of this MutableBigInteger's value
20.132 + * array starting at offset.
20.133 + */
20.134 + public String toString() {
20.135 + return this.toBigInteger(sign).toString();
20.136 + }
20.137 +
20.138 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/emul/compact/src/main/java/java/math/package-info.java Sat Sep 07 13:51:24 2013 +0200
21.3 @@ -0,0 +1,45 @@
21.4 +/*
21.5 + * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.7 + *
21.8 + * This code is free software; you can redistribute it and/or modify it
21.9 + * under the terms of the GNU General Public License version 2 only, as
21.10 + * published by the Free Software Foundation. Oracle designates this
21.11 + * particular file as subject to the "Classpath" exception as provided
21.12 + * by Oracle in the LICENSE file that accompanied this code.
21.13 + *
21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21.17 + * version 2 for more details (a copy is included in the LICENSE file that
21.18 + * accompanied this code).
21.19 + *
21.20 + * You should have received a copy of the GNU General Public License version
21.21 + * 2 along with this work; if not, write to the Free Software Foundation,
21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21.23 + *
21.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21.25 + * or visit www.oracle.com if you need additional information or have any
21.26 + * questions.
21.27 + */
21.28 +
21.29 +/**
21.30 + * Provides classes for performing arbitrary-precision integer
21.31 + * arithmetic ({@code BigInteger}) and arbitrary-precision decimal
21.32 + * arithmetic ({@code BigDecimal}). {@code BigInteger} is analogous
21.33 + * to the primitive integer types except that it provides arbitrary
21.34 + * precision, hence operations on {@code BigInteger}s do not overflow
21.35 + * or lose precision. In addition to standard arithmetic operations,
21.36 + * {@code BigInteger} provides modular arithmetic, GCD calculation,
21.37 + * primality testing, prime generation, bit manipulation, and a few
21.38 + * other miscellaneous operations.
21.39 + *
21.40 + * {@code BigDecimal} provides arbitrary-precision signed decimal
21.41 + * numbers suitable for currency calculations and the like. {@code
21.42 + * BigDecimal} gives the user complete control over rounding behavior,
21.43 + * allowing the user to choose from a comprehensive set of eight
21.44 + * rounding modes.
21.45 + *
21.46 + * @since JDK1.1
21.47 + */
21.48 +package java.math;
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/emul/compact/src/main/java/java/net/URI.java Sat Sep 07 13:51:24 2013 +0200
22.3 @@ -0,0 +1,3524 @@
22.4 +/*
22.5 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
22.7 + *
22.8 + * This code is free software; you can redistribute it and/or modify it
22.9 + * under the terms of the GNU General Public License version 2 only, as
22.10 + * published by the Free Software Foundation. Oracle designates this
22.11 + * particular file as subject to the "Classpath" exception as provided
22.12 + * by Oracle in the LICENSE file that accompanied this code.
22.13 + *
22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22.17 + * version 2 for more details (a copy is included in the LICENSE file that
22.18 + * accompanied this code).
22.19 + *
22.20 + * You should have received a copy of the GNU General Public License version
22.21 + * 2 along with this work; if not, write to the Free Software Foundation,
22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22.23 + *
22.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22.25 + * or visit www.oracle.com if you need additional information or have any
22.26 + * questions.
22.27 + */
22.28 +
22.29 +package java.net;
22.30 +
22.31 +import java.io.IOException;
22.32 +import java.io.InvalidObjectException;
22.33 +import java.io.ObjectInputStream;
22.34 +import java.io.ObjectOutputStream;
22.35 +import java.io.Serializable;
22.36 +import java.nio.ByteBuffer;
22.37 +import java.nio.CharBuffer;
22.38 +import java.nio.charset.CharsetDecoder;
22.39 +import java.nio.charset.CharsetEncoder;
22.40 +import java.nio.charset.CoderResult;
22.41 +import java.nio.charset.CodingErrorAction;
22.42 +import java.nio.charset.CharacterCodingException;
22.43 +import java.text.Normalizer;
22.44 +import sun.nio.cs.ThreadLocalCoders;
22.45 +
22.46 +import java.lang.Character; // for javadoc
22.47 +import java.lang.NullPointerException; // for javadoc
22.48 +
22.49 +
22.50 +/**
22.51 + * Represents a Uniform Resource Identifier (URI) reference.
22.52 + *
22.53 + * <p> Aside from some minor deviations noted below, an instance of this
22.54 + * class represents a URI reference as defined by
22.55 + * <a href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC 2396: Uniform
22.56 + * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a
22.57 + * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC 2732: Format for
22.58 + * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format
22.59 + * also supports scope_ids. The syntax and usage of scope_ids is described
22.60 + * <a href="Inet6Address.html#scoped">here</a>.
22.61 + * This class provides constructors for creating URI instances from
22.62 + * their components or by parsing their string forms, methods for accessing the
22.63 + * various components of an instance, and methods for normalizing, resolving,
22.64 + * and relativizing URI instances. Instances of this class are immutable.
22.65 + *
22.66 + *
22.67 + * <h4> URI syntax and components </h4>
22.68 + *
22.69 + * At the highest level a URI reference (hereinafter simply "URI") in string
22.70 + * form has the syntax
22.71 + *
22.72 + * <blockquote>
22.73 + * [<i>scheme</i><tt><b>:</b></tt><i></i>]<i>scheme-specific-part</i>[<tt><b>#</b></tt><i>fragment</i>]
22.74 + * </blockquote>
22.75 + *
22.76 + * where square brackets [...] delineate optional components and the characters
22.77 + * <tt><b>:</b></tt> and <tt><b>#</b></tt> stand for themselves.
22.78 + *
22.79 + * <p> An <i>absolute</i> URI specifies a scheme; a URI that is not absolute is
22.80 + * said to be <i>relative</i>. URIs are also classified according to whether
22.81 + * they are <i>opaque</i> or <i>hierarchical</i>.
22.82 + *
22.83 + * <p> An <i>opaque</i> URI is an absolute URI whose scheme-specific part does
22.84 + * not begin with a slash character (<tt>'/'</tt>). Opaque URIs are not
22.85 + * subject to further parsing. Some examples of opaque URIs are:
22.86 + *
22.87 + * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
22.88 + * <tr><td><tt>mailto:java-net@java.sun.com</tt><td></tr>
22.89 + * <tr><td><tt>news:comp.lang.java</tt><td></tr>
22.90 + * <tr><td><tt>urn:isbn:096139210x</tt></td></tr>
22.91 + * </table></blockquote>
22.92 + *
22.93 + * <p> A <i>hierarchical</i> URI is either an absolute URI whose
22.94 + * scheme-specific part begins with a slash character, or a relative URI, that
22.95 + * is, a URI that does not specify a scheme. Some examples of hierarchical
22.96 + * URIs are:
22.97 + *
22.98 + * <blockquote>
22.99 + * <tt>http://java.sun.com/j2se/1.3/</tt><br>
22.100 + * <tt>docs/guide/collections/designfaq.html#28</tt><br>
22.101 + * <tt>../../../demo/jfc/SwingSet2/src/SwingSet2.java</tt><br>
22.102 + * <tt>file:///~/calendar</tt>
22.103 + * </blockquote>
22.104 + *
22.105 + * <p> A hierarchical URI is subject to further parsing according to the syntax
22.106 + *
22.107 + * <blockquote>
22.108 + * [<i>scheme</i><tt><b>:</b></tt>][<tt><b>//</b></tt><i>authority</i>][<i>path</i>][<tt><b>?</b></tt><i>query</i>][<tt><b>#</b></tt><i>fragment</i>]
22.109 + * </blockquote>
22.110 + *
22.111 + * where the characters <tt><b>:</b></tt>, <tt><b>/</b></tt>,
22.112 + * <tt><b>?</b></tt>, and <tt><b>#</b></tt> stand for themselves. The
22.113 + * scheme-specific part of a hierarchical URI consists of the characters
22.114 + * between the scheme and fragment components.
22.115 + *
22.116 + * <p> The authority component of a hierarchical URI is, if specified, either
22.117 + * <i>server-based</i> or <i>registry-based</i>. A server-based authority
22.118 + * parses according to the familiar syntax
22.119 + *
22.120 + * <blockquote>
22.121 + * [<i>user-info</i><tt><b>@</b></tt>]<i>host</i>[<tt><b>:</b></tt><i>port</i>]
22.122 + * </blockquote>
22.123 + *
22.124 + * where the characters <tt><b>@</b></tt> and <tt><b>:</b></tt> stand for
22.125 + * themselves. Nearly all URI schemes currently in use are server-based. An
22.126 + * authority component that does not parse in this way is considered to be
22.127 + * registry-based.
22.128 + *
22.129 + * <p> The path component of a hierarchical URI is itself said to be absolute
22.130 + * if it begins with a slash character (<tt>'/'</tt>); otherwise it is
22.131 + * relative. The path of a hierarchical URI that is either absolute or
22.132 + * specifies an authority is always absolute.
22.133 + *
22.134 + * <p> All told, then, a URI instance has the following nine components:
22.135 + *
22.136 + * <blockquote><table summary="Describes the components of a URI:scheme,scheme-specific-part,authority,user-info,host,port,path,query,fragment">
22.137 + * <tr><th><i>Component</i></th><th><i>Type</i></th></tr>
22.138 + * <tr><td>scheme</td><td><tt>String</tt></td></tr>
22.139 + * <tr><td>scheme-specific-part </td><td><tt>String</tt></td></tr>
22.140 + * <tr><td>authority</td><td><tt>String</tt></td></tr>
22.141 + * <tr><td>user-info</td><td><tt>String</tt></td></tr>
22.142 + * <tr><td>host</td><td><tt>String</tt></td></tr>
22.143 + * <tr><td>port</td><td><tt>int</tt></td></tr>
22.144 + * <tr><td>path</td><td><tt>String</tt></td></tr>
22.145 + * <tr><td>query</td><td><tt>String</tt></td></tr>
22.146 + * <tr><td>fragment</td><td><tt>String</tt></td></tr>
22.147 + * </table></blockquote>
22.148 + *
22.149 + * In a given instance any particular component is either <i>undefined</i> or
22.150 + * <i>defined</i> with a distinct value. Undefined string components are
22.151 + * represented by <tt>null</tt>, while undefined integer components are
22.152 + * represented by <tt>-1</tt>. A string component may be defined to have the
22.153 + * empty string as its value; this is not equivalent to that component being
22.154 + * undefined.
22.155 + *
22.156 + * <p> Whether a particular component is or is not defined in an instance
22.157 + * depends upon the type of the URI being represented. An absolute URI has a
22.158 + * scheme component. An opaque URI has a scheme, a scheme-specific part, and
22.159 + * possibly a fragment, but has no other components. A hierarchical URI always
22.160 + * has a path (though it may be empty) and a scheme-specific-part (which at
22.161 + * least contains the path), and may have any of the other components. If the
22.162 + * authority component is present and is server-based then the host component
22.163 + * will be defined and the user-information and port components may be defined.
22.164 + *
22.165 + *
22.166 + * <h4> Operations on URI instances </h4>
22.167 + *
22.168 + * The key operations supported by this class are those of
22.169 + * <i>normalization</i>, <i>resolution</i>, and <i>relativization</i>.
22.170 + *
22.171 + * <p> <i>Normalization</i> is the process of removing unnecessary <tt>"."</tt>
22.172 + * and <tt>".."</tt> segments from the path component of a hierarchical URI.
22.173 + * Each <tt>"."</tt> segment is simply removed. A <tt>".."</tt> segment is
22.174 + * removed only if it is preceded by a non-<tt>".."</tt> segment.
22.175 + * Normalization has no effect upon opaque URIs.
22.176 + *
22.177 + * <p> <i>Resolution</i> is the process of resolving one URI against another,
22.178 + * <i>base</i> URI. The resulting URI is constructed from components of both
22.179 + * URIs in the manner specified by RFC 2396, taking components from the
22.180 + * base URI for those not specified in the original. For hierarchical URIs,
22.181 + * the path of the original is resolved against the path of the base and then
22.182 + * normalized. The result, for example, of resolving
22.183 + *
22.184 + * <blockquote>
22.185 + * <tt>docs/guide/collections/designfaq.html#28 </tt>(1)
22.186 + * </blockquote>
22.187 + *
22.188 + * against the base URI <tt>http://java.sun.com/j2se/1.3/</tt> is the result
22.189 + * URI
22.190 + *
22.191 + * <blockquote>
22.192 + * <tt>http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28</tt>
22.193 + * </blockquote>
22.194 + *
22.195 + * Resolving the relative URI
22.196 + *
22.197 + * <blockquote>
22.198 + * <tt>../../../demo/jfc/SwingSet2/src/SwingSet2.java </tt>(2)
22.199 + * </blockquote>
22.200 + *
22.201 + * against this result yields, in turn,
22.202 + *
22.203 + * <blockquote>
22.204 + * <tt>http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java</tt>
22.205 + * </blockquote>
22.206 + *
22.207 + * Resolution of both absolute and relative URIs, and of both absolute and
22.208 + * relative paths in the case of hierarchical URIs, is supported. Resolving
22.209 + * the URI <tt>file:///~calendar</tt> against any other URI simply yields the
22.210 + * original URI, since it is absolute. Resolving the relative URI (2) above
22.211 + * against the relative base URI (1) yields the normalized, but still relative,
22.212 + * URI
22.213 + *
22.214 + * <blockquote>
22.215 + * <tt>demo/jfc/SwingSet2/src/SwingSet2.java</tt>
22.216 + * </blockquote>
22.217 + *
22.218 + * <p> <i>Relativization</i>, finally, is the inverse of resolution: For any
22.219 + * two normalized URIs <i>u</i> and <i>v</i>,
22.220 + *
22.221 + * <blockquote>
22.222 + * <i>u</i><tt>.relativize(</tt><i>u</i><tt>.resolve(</tt><i>v</i><tt>)).equals(</tt><i>v</i><tt>)</tt> and<br>
22.223 + * <i>u</i><tt>.resolve(</tt><i>u</i><tt>.relativize(</tt><i>v</i><tt>)).equals(</tt><i>v</i><tt>)</tt> .<br>
22.224 + * </blockquote>
22.225 + *
22.226 + * This operation is often useful when constructing a document containing URIs
22.227 + * that must be made relative to the base URI of the document wherever
22.228 + * possible. For example, relativizing the URI
22.229 + *
22.230 + * <blockquote>
22.231 + * <tt>http://java.sun.com/j2se/1.3/docs/guide/index.html</tt>
22.232 + * </blockquote>
22.233 + *
22.234 + * against the base URI
22.235 + *
22.236 + * <blockquote>
22.237 + * <tt>http://java.sun.com/j2se/1.3</tt>
22.238 + * </blockquote>
22.239 + *
22.240 + * yields the relative URI <tt>docs/guide/index.html</tt>.
22.241 + *
22.242 + *
22.243 + * <h4> Character categories </h4>
22.244 + *
22.245 + * RFC 2396 specifies precisely which characters are permitted in the
22.246 + * various components of a URI reference. The following categories, most of
22.247 + * which are taken from that specification, are used below to describe these
22.248 + * constraints:
22.249 + *
22.250 + * <blockquote><table cellspacing=2 summary="Describes categories alpha,digit,alphanum,unreserved,punct,reserved,escaped,and other">
22.251 + * <tr><th valign=top><i>alpha</i></th>
22.252 + * <td>The US-ASCII alphabetic characters,
22.253 + * <tt>'A'</tt> through <tt>'Z'</tt>
22.254 + * and <tt>'a'</tt> through <tt>'z'</tt></td></tr>
22.255 + * <tr><th valign=top><i>digit</i></th>
22.256 + * <td>The US-ASCII decimal digit characters,
22.257 + * <tt>'0'</tt> through <tt>'9'</tt></td></tr>
22.258 + * <tr><th valign=top><i>alphanum</i></th>
22.259 + * <td>All <i>alpha</i> and <i>digit</i> characters</td></tr>
22.260 + * <tr><th valign=top><i>unreserved</i> </th>
22.261 + * <td>All <i>alphanum</i> characters together with those in the string
22.262 + * <tt>"_-!.~'()*"</tt></td></tr>
22.263 + * <tr><th valign=top><i>punct</i></th>
22.264 + * <td>The characters in the string <tt>",;:$&+="</tt></td></tr>
22.265 + * <tr><th valign=top><i>reserved</i></th>
22.266 + * <td>All <i>punct</i> characters together with those in the string
22.267 + * <tt>"?/[]@"</tt></td></tr>
22.268 + * <tr><th valign=top><i>escaped</i></th>
22.269 + * <td>Escaped octets, that is, triplets consisting of the percent
22.270 + * character (<tt>'%'</tt>) followed by two hexadecimal digits
22.271 + * (<tt>'0'</tt>-<tt>'9'</tt>, <tt>'A'</tt>-<tt>'F'</tt>, and
22.272 + * <tt>'a'</tt>-<tt>'f'</tt>)</td></tr>
22.273 + * <tr><th valign=top><i>other</i></th>
22.274 + * <td>The Unicode characters that are not in the US-ASCII character set,
22.275 + * are not control characters (according to the {@link
22.276 + * java.lang.Character#isISOControl(char) Character.isISOControl}
22.277 + * method), and are not space characters (according to the {@link
22.278 + * java.lang.Character#isSpaceChar(char) Character.isSpaceChar}
22.279 + * method) <i>(<b>Deviation from RFC 2396</b>, which is
22.280 + * limited to US-ASCII)</i></td></tr>
22.281 + * </table></blockquote>
22.282 + *
22.283 + * <p><a name="legal-chars"></a> The set of all legal URI characters consists of
22.284 + * the <i>unreserved</i>, <i>reserved</i>, <i>escaped</i>, and <i>other</i>
22.285 + * characters.
22.286 + *
22.287 + *
22.288 + * <h4> Escaped octets, quotation, encoding, and decoding </h4>
22.289 + *
22.290 + * RFC 2396 allows escaped octets to appear in the user-info, path, query, and
22.291 + * fragment components. Escaping serves two purposes in URIs:
22.292 + *
22.293 + * <ul>
22.294 + *
22.295 + * <li><p> To <i>encode</i> non-US-ASCII characters when a URI is required to
22.296 + * conform strictly to RFC 2396 by not containing any <i>other</i>
22.297 + * characters. </p></li>
22.298 + *
22.299 + * <li><p> To <i>quote</i> characters that are otherwise illegal in a
22.300 + * component. The user-info, path, query, and fragment components differ
22.301 + * slightly in terms of which characters are considered legal and illegal.
22.302 + * </p></li>
22.303 + *
22.304 + * </ul>
22.305 + *
22.306 + * These purposes are served in this class by three related operations:
22.307 + *
22.308 + * <ul>
22.309 + *
22.310 + * <li><p><a name="encode"></a> A character is <i>encoded</i> by replacing it
22.311 + * with the sequence of escaped octets that represent that character in the
22.312 + * UTF-8 character set. The Euro currency symbol (<tt>'\u20AC'</tt>),
22.313 + * for example, is encoded as <tt>"%E2%82%AC"</tt>. <i>(<b>Deviation from
22.314 + * RFC 2396</b>, which does not specify any particular character
22.315 + * set.)</i> </p></li>
22.316 + *
22.317 + * <li><p><a name="quote"></a> An illegal character is <i>quoted</i> simply by
22.318 + * encoding it. The space character, for example, is quoted by replacing it
22.319 + * with <tt>"%20"</tt>. UTF-8 contains US-ASCII, hence for US-ASCII
22.320 + * characters this transformation has exactly the effect required by
22.321 + * RFC 2396. </p></li>
22.322 + *
22.323 + * <li><p><a name="decode"></a>
22.324 + * A sequence of escaped octets is <i>decoded</i> by
22.325 + * replacing it with the sequence of characters that it represents in the
22.326 + * UTF-8 character set. UTF-8 contains US-ASCII, hence decoding has the
22.327 + * effect of de-quoting any quoted US-ASCII characters as well as that of
22.328 + * decoding any encoded non-US-ASCII characters. If a <a
22.329 + * href="../nio/charset/CharsetDecoder.html#ce">decoding error</a> occurs
22.330 + * when decoding the escaped octets then the erroneous octets are replaced by
22.331 + * <tt>'\uFFFD'</tt>, the Unicode replacement character. </p></li>
22.332 + *
22.333 + * </ul>
22.334 + *
22.335 + * These operations are exposed in the constructors and methods of this class
22.336 + * as follows:
22.337 + *
22.338 + * <ul>
22.339 + *
22.340 + * <li><p> The {@link #URI(java.lang.String) <code>single-argument
22.341 + * constructor</code>} requires any illegal characters in its argument to be
22.342 + * quoted and preserves any escaped octets and <i>other</i> characters that
22.343 + * are present. </p></li>
22.344 + *
22.345 + * <li><p> The {@link
22.346 + * #URI(java.lang.String,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String,java.lang.String)
22.347 + * <code>multi-argument constructors</code>} quote illegal characters as
22.348 + * required by the components in which they appear. The percent character
22.349 + * (<tt>'%'</tt>) is always quoted by these constructors. Any <i>other</i>
22.350 + * characters are preserved. </p></li>
22.351 + *
22.352 + * <li><p> The {@link #getRawUserInfo() getRawUserInfo}, {@link #getRawPath()
22.353 + * getRawPath}, {@link #getRawQuery() getRawQuery}, {@link #getRawFragment()
22.354 + * getRawFragment}, {@link #getRawAuthority() getRawAuthority}, and {@link
22.355 + * #getRawSchemeSpecificPart() getRawSchemeSpecificPart} methods return the
22.356 + * values of their corresponding components in raw form, without interpreting
22.357 + * any escaped octets. The strings returned by these methods may contain
22.358 + * both escaped octets and <i>other</i> characters, and will not contain any
22.359 + * illegal characters. </p></li>
22.360 + *
22.361 + * <li><p> The {@link #getUserInfo() getUserInfo}, {@link #getPath()
22.362 + * getPath}, {@link #getQuery() getQuery}, {@link #getFragment()
22.363 + * getFragment}, {@link #getAuthority() getAuthority}, and {@link
22.364 + * #getSchemeSpecificPart() getSchemeSpecificPart} methods decode any escaped
22.365 + * octets in their corresponding components. The strings returned by these
22.366 + * methods may contain both <i>other</i> characters and illegal characters,
22.367 + * and will not contain any escaped octets. </p></li>
22.368 + *
22.369 + * <li><p> The {@link #toString() toString} method returns a URI string with
22.370 + * all necessary quotation but which may contain <i>other</i> characters.
22.371 + * </p></li>
22.372 + *
22.373 + * <li><p> The {@link #toASCIIString() toASCIIString} method returns a fully
22.374 + * quoted and encoded URI string that does not contain any <i>other</i>
22.375 + * characters. </p></li>
22.376 + *
22.377 + * </ul>
22.378 + *
22.379 + *
22.380 + * <h4> Identities </h4>
22.381 + *
22.382 + * For any URI <i>u</i>, it is always the case that
22.383 + *
22.384 + * <blockquote>
22.385 + * <tt>new URI(</tt><i>u</i><tt>.toString()).equals(</tt><i>u</i><tt>)</tt> .
22.386 + * </blockquote>
22.387 + *
22.388 + * For any URI <i>u</i> that does not contain redundant syntax such as two
22.389 + * slashes before an empty authority (as in <tt>file:///tmp/</tt> ) or a
22.390 + * colon following a host name but no port (as in
22.391 + * <tt>http://java.sun.com:</tt> ), and that does not encode characters
22.392 + * except those that must be quoted, the following identities also hold:
22.393 + *
22.394 + * <blockquote>
22.395 + * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br>
22.396 + * </tt><i>u</i><tt>.getSchemeSpecificPart(),<br>
22.397 + * </tt><i>u</i><tt>.getFragment())<br>
22.398 + * .equals(</tt><i>u</i><tt>)</tt>
22.399 + * </blockquote>
22.400 + *
22.401 + * in all cases,
22.402 + *
22.403 + * <blockquote>
22.404 + * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br>
22.405 + * </tt><i>u</i><tt>.getUserInfo(), </tt><i>u</i><tt>.getAuthority(),<br>
22.406 + * </tt><i>u</i><tt>.getPath(), </tt><i>u</i><tt>.getQuery(),<br>
22.407 + * </tt><i>u</i><tt>.getFragment())<br>
22.408 + * .equals(</tt><i>u</i><tt>)</tt>
22.409 + * </blockquote>
22.410 + *
22.411 + * if <i>u</i> is hierarchical, and
22.412 + *
22.413 + * <blockquote>
22.414 + * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br>
22.415 + * </tt><i>u</i><tt>.getUserInfo(), </tt><i>u</i><tt>.getHost(), </tt><i>u</i><tt>.getPort(),<br>
22.416 + * </tt><i>u</i><tt>.getPath(), </tt><i>u</i><tt>.getQuery(),<br>
22.417 + * </tt><i>u</i><tt>.getFragment())<br>
22.418 + * .equals(</tt><i>u</i><tt>)</tt>
22.419 + * </blockquote>
22.420 + *
22.421 + * if <i>u</i> is hierarchical and has either no authority or a server-based
22.422 + * authority.
22.423 + *
22.424 + *
22.425 + * <h4> URIs, URLs, and URNs </h4>
22.426 + *
22.427 + * A URI is a uniform resource <i>identifier</i> while a URL is a uniform
22.428 + * resource <i>locator</i>. Hence every URL is a URI, abstractly speaking, but
22.429 + * not every URI is a URL. This is because there is another subcategory of
22.430 + * URIs, uniform resource <i>names</i> (URNs), which name resources but do not
22.431 + * specify how to locate them. The <tt>mailto</tt>, <tt>news</tt>, and
22.432 + * <tt>isbn</tt> URIs shown above are examples of URNs.
22.433 + *
22.434 + * <p> The conceptual distinction between URIs and URLs is reflected in the
22.435 + * differences between this class and the {@link URL} class.
22.436 + *
22.437 + * <p> An instance of this class represents a URI reference in the syntactic
22.438 + * sense defined by RFC 2396. A URI may be either absolute or relative.
22.439 + * A URI string is parsed according to the generic syntax without regard to the
22.440 + * scheme, if any, that it specifies. No lookup of the host, if any, is
22.441 + * performed, and no scheme-dependent stream handler is constructed. Equality,
22.442 + * hashing, and comparison are defined strictly in terms of the character
22.443 + * content of the instance. In other words, a URI instance is little more than
22.444 + * a structured string that supports the syntactic, scheme-independent
22.445 + * operations of comparison, normalization, resolution, and relativization.
22.446 + *
22.447 + * <p> An instance of the {@link URL} class, by contrast, represents the
22.448 + * syntactic components of a URL together with some of the information required
22.449 + * to access the resource that it describes. A URL must be absolute, that is,
22.450 + * it must always specify a scheme. A URL string is parsed according to its
22.451 + * scheme. A stream handler is always established for a URL, and in fact it is
22.452 + * impossible to create a URL instance for a scheme for which no handler is
22.453 + * available. Equality and hashing depend upon both the scheme and the
22.454 + * Internet address of the host, if any; comparison is not defined. In other
22.455 + * words, a URL is a structured string that supports the syntactic operation of
22.456 + * resolution as well as the network I/O operations of looking up the host and
22.457 + * opening a connection to the specified resource.
22.458 + *
22.459 + *
22.460 + * @author Mark Reinhold
22.461 + * @since 1.4
22.462 + *
22.463 + * @see <a href="http://www.ietf.org/rfc/rfc2279.txt"><i>RFC 2279: UTF-8, a
22.464 + * transformation format of ISO 10646</i></a>, <br><a
22.465 + * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IPv6 Addressing
22.466 + * Architecture</i></a>, <br><a
22.467 + * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC 2396: Uniform
22.468 + * Resource Identifiers (URI): Generic Syntax</i></a>, <br><a
22.469 + * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC 2732: Format for
22.470 + * Literal IPv6 Addresses in URLs</i></a>, <br><a
22.471 + * href="URISyntaxException.html">URISyntaxException</a>
22.472 + */
22.473 +
22.474 +public final class URI
22.475 + implements Comparable<URI>, Serializable
22.476 +{
22.477 +
22.478 + // Note: Comments containing the word "ASSERT" indicate places where a
22.479 + // throw of an InternalError should be replaced by an appropriate assertion
22.480 + // statement once asserts are enabled in the build.
22.481 +
22.482 + static final long serialVersionUID = -6052424284110960213L;
22.483 +
22.484 +
22.485 + // -- Properties and components of this instance --
22.486 +
22.487 + // Components of all URIs: [<scheme>:]<scheme-specific-part>[#<fragment>]
22.488 + private transient String scheme; // null ==> relative URI
22.489 + private transient String fragment;
22.490 +
22.491 + // Hierarchical URI components: [//<authority>]<path>[?<query>]
22.492 + private transient String authority; // Registry or server
22.493 +
22.494 + // Server-based authority: [<userInfo>@]<host>[:<port>]
22.495 + private transient String userInfo;
22.496 + private transient String host; // null ==> registry-based
22.497 + private transient int port = -1; // -1 ==> undefined
22.498 +
22.499 + // Remaining components of hierarchical URIs
22.500 + private transient String path; // null ==> opaque
22.501 + private transient String query;
22.502 +
22.503 + // The remaining fields may be computed on demand
22.504 +
22.505 + private volatile transient String schemeSpecificPart;
22.506 + private volatile transient int hash; // Zero ==> undefined
22.507 +
22.508 + private volatile transient String decodedUserInfo = null;
22.509 + private volatile transient String decodedAuthority = null;
22.510 + private volatile transient String decodedPath = null;
22.511 + private volatile transient String decodedQuery = null;
22.512 + private volatile transient String decodedFragment = null;
22.513 + private volatile transient String decodedSchemeSpecificPart = null;
22.514 +
22.515 + /**
22.516 + * The string form of this URI.
22.517 + *
22.518 + * @serial
22.519 + */
22.520 + private volatile String string; // The only serializable field
22.521 +
22.522 +
22.523 +
22.524 + // -- Constructors and factories --
22.525 +
22.526 + private URI() { } // Used internally
22.527 +
22.528 + /**
22.529 + * Constructs a URI by parsing the given string.
22.530 + *
22.531 + * <p> This constructor parses the given string exactly as specified by the
22.532 + * grammar in <a
22.533 + * href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>,
22.534 + * Appendix A, <b><i>except for the following deviations:</i></b> </p>
22.535 + *
22.536 + * <ul type=disc>
22.537 + *
22.538 + * <li><p> An empty authority component is permitted as long as it is
22.539 + * followed by a non-empty path, a query component, or a fragment
22.540 + * component. This allows the parsing of URIs such as
22.541 + * <tt>"file:///foo/bar"</tt>, which seems to be the intent of
22.542 + * RFC 2396 although the grammar does not permit it. If the
22.543 + * authority component is empty then the user-information, host, and port
22.544 + * components are undefined. </p></li>
22.545 + *
22.546 + * <li><p> Empty relative paths are permitted; this seems to be the
22.547 + * intent of RFC 2396 although the grammar does not permit it. The
22.548 + * primary consequence of this deviation is that a standalone fragment
22.549 + * such as <tt>"#foo"</tt> parses as a relative URI with an empty path
22.550 + * and the given fragment, and can be usefully <a
22.551 + * href="#resolve-frag">resolved</a> against a base URI.
22.552 + *
22.553 + * <li><p> IPv4 addresses in host components are parsed rigorously, as
22.554 + * specified by <a
22.555 + * href="http://www.ietf.org/rfc/rfc2732.txt">RFC 2732</a>: Each
22.556 + * element of a dotted-quad address must contain no more than three
22.557 + * decimal digits. Each element is further constrained to have a value
22.558 + * no greater than 255. </p></li>
22.559 + *
22.560 + * <li> <p> Hostnames in host components that comprise only a single
22.561 + * domain label are permitted to start with an <i>alphanum</i>
22.562 + * character. This seems to be the intent of <a
22.563 + * href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>
22.564 + * section 3.2.2 although the grammar does not permit it. The
22.565 + * consequence of this deviation is that the authority component of a
22.566 + * hierarchical URI such as <tt>s://123</tt>, will parse as a server-based
22.567 + * authority. </p></li>
22.568 + *
22.569 + * <li><p> IPv6 addresses are permitted for the host component. An IPv6
22.570 + * address must be enclosed in square brackets (<tt>'['</tt> and
22.571 + * <tt>']'</tt>) as specified by <a
22.572 + * href="http://www.ietf.org/rfc/rfc2732.txt">RFC 2732</a>. The
22.573 + * IPv6 address itself must parse according to <a
22.574 + * href="http://www.ietf.org/rfc/rfc2373.txt">RFC 2373</a>. IPv6
22.575 + * addresses are further constrained to describe no more than sixteen
22.576 + * bytes of address information, a constraint implicit in RFC 2373
22.577 + * but not expressible in the grammar. </p></li>
22.578 + *
22.579 + * <li><p> Characters in the <i>other</i> category are permitted wherever
22.580 + * RFC 2396 permits <i>escaped</i> octets, that is, in the
22.581 + * user-information, path, query, and fragment components, as well as in
22.582 + * the authority component if the authority is registry-based. This
22.583 + * allows URIs to contain Unicode characters beyond those in the US-ASCII
22.584 + * character set. </p></li>
22.585 + *
22.586 + * </ul>
22.587 + *
22.588 + * @param str The string to be parsed into a URI
22.589 + *
22.590 + * @throws NullPointerException
22.591 + * If <tt>str</tt> is <tt>null</tt>
22.592 + *
22.593 + * @throws URISyntaxException
22.594 + * If the given string violates RFC 2396, as augmented
22.595 + * by the above deviations
22.596 + */
22.597 + public URI(String str) throws URISyntaxException {
22.598 + new Parser(str).parse(false);
22.599 + }
22.600 +
22.601 + /**
22.602 + * Constructs a hierarchical URI from the given components.
22.603 + *
22.604 + * <p> If a scheme is given then the path, if also given, must either be
22.605 + * empty or begin with a slash character (<tt>'/'</tt>). Otherwise a
22.606 + * component of the new URI may be left undefined by passing <tt>null</tt>
22.607 + * for the corresponding parameter or, in the case of the <tt>port</tt>
22.608 + * parameter, by passing <tt>-1</tt>.
22.609 + *
22.610 + * <p> This constructor first builds a URI string from the given components
22.611 + * according to the rules specified in <a
22.612 + * href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>,
22.613 + * section 5.2, step 7: </p>
22.614 + *
22.615 + * <ol>
22.616 + *
22.617 + * <li><p> Initially, the result string is empty. </p></li>
22.618 + *
22.619 + * <li><p> If a scheme is given then it is appended to the result,
22.620 + * followed by a colon character (<tt>':'</tt>). </p></li>
22.621 + *
22.622 + * <li><p> If user information, a host, or a port are given then the
22.623 + * string <tt>"//"</tt> is appended. </p></li>
22.624 + *
22.625 + * <li><p> If user information is given then it is appended, followed by
22.626 + * a commercial-at character (<tt>'@'</tt>). Any character not in the
22.627 + * <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
22.628 + * categories is <a href="#quote">quoted</a>. </p></li>
22.629 + *
22.630 + * <li><p> If a host is given then it is appended. If the host is a
22.631 + * literal IPv6 address but is not enclosed in square brackets
22.632 + * (<tt>'['</tt> and <tt>']'</tt>) then the square brackets are added.
22.633 + * </p></li>
22.634 + *
22.635 + * <li><p> If a port number is given then a colon character
22.636 + * (<tt>':'</tt>) is appended, followed by the port number in decimal.
22.637 + * </p></li>
22.638 + *
22.639 + * <li><p> If a path is given then it is appended. Any character not in
22.640 + * the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
22.641 + * categories, and not equal to the slash character (<tt>'/'</tt>) or the
22.642 + * commercial-at character (<tt>'@'</tt>), is quoted. </p></li>
22.643 + *
22.644 + * <li><p> If a query is given then a question-mark character
22.645 + * (<tt>'?'</tt>) is appended, followed by the query. Any character that
22.646 + * is not a <a href="#legal-chars">legal URI character</a> is quoted.
22.647 + * </p></li>
22.648 + *
22.649 + * <li><p> Finally, if a fragment is given then a hash character
22.650 + * (<tt>'#'</tt>) is appended, followed by the fragment. Any character
22.651 + * that is not a legal URI character is quoted. </p></li>
22.652 + *
22.653 + * </ol>
22.654 + *
22.655 + * <p> The resulting URI string is then parsed as if by invoking the {@link
22.656 + * #URI(String)} constructor and then invoking the {@link
22.657 + * #parseServerAuthority()} method upon the result; this may cause a {@link
22.658 + * URISyntaxException} to be thrown. </p>
22.659 + *
22.660 + * @param scheme Scheme name
22.661 + * @param userInfo User name and authorization information
22.662 + * @param host Host name
22.663 + * @param port Port number
22.664 + * @param path Path
22.665 + * @param query Query
22.666 + * @param fragment Fragment
22.667 + *
22.668 + * @throws URISyntaxException
22.669 + * If both a scheme and a path are given but the path is relative,
22.670 + * if the URI string constructed from the given components violates
22.671 + * RFC 2396, or if the authority component of the string is
22.672 + * present but cannot be parsed as a server-based authority
22.673 + */
22.674 + public URI(String scheme,
22.675 + String userInfo, String host, int port,
22.676 + String path, String query, String fragment)
22.677 + throws URISyntaxException
22.678 + {
22.679 + String s = toString(scheme, null,
22.680 + null, userInfo, host, port,
22.681 + path, query, fragment);
22.682 + checkPath(s, scheme, path);
22.683 + new Parser(s).parse(true);
22.684 + }
22.685 +
22.686 + /**
22.687 + * Constructs a hierarchical URI from the given components.
22.688 + *
22.689 + * <p> If a scheme is given then the path, if also given, must either be
22.690 + * empty or begin with a slash character (<tt>'/'</tt>). Otherwise a
22.691 + * component of the new URI may be left undefined by passing <tt>null</tt>
22.692 + * for the corresponding parameter.
22.693 + *
22.694 + * <p> This constructor first builds a URI string from the given components
22.695 + * according to the rules specified in <a
22.696 + * href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>,
22.697 + * section 5.2, step 7: </p>
22.698 + *
22.699 + * <ol>
22.700 + *
22.701 + * <li><p> Initially, the result string is empty. </p></li>
22.702 + *
22.703 + * <li><p> If a scheme is given then it is appended to the result,
22.704 + * followed by a colon character (<tt>':'</tt>). </p></li>
22.705 + *
22.706 + * <li><p> If an authority is given then the string <tt>"//"</tt> is
22.707 + * appended, followed by the authority. If the authority contains a
22.708 + * literal IPv6 address then the address must be enclosed in square
22.709 + * brackets (<tt>'['</tt> and <tt>']'</tt>). Any character not in the
22.710 + * <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
22.711 + * categories, and not equal to the commercial-at character
22.712 + * (<tt>'@'</tt>), is <a href="#quote">quoted</a>. </p></li>
22.713 + *
22.714 + * <li><p> If a path is given then it is appended. Any character not in
22.715 + * the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
22.716 + * categories, and not equal to the slash character (<tt>'/'</tt>) or the
22.717 + * commercial-at character (<tt>'@'</tt>), is quoted. </p></li>
22.718 + *
22.719 + * <li><p> If a query is given then a question-mark character
22.720 + * (<tt>'?'</tt>) is appended, followed by the query. Any character that
22.721 + * is not a <a href="#legal-chars">legal URI character</a> is quoted.
22.722 + * </p></li>
22.723 + *
22.724 + * <li><p> Finally, if a fragment is given then a hash character
22.725 + * (<tt>'#'</tt>) is appended, followed by the fragment. Any character
22.726 + * that is not a legal URI character is quoted. </p></li>
22.727 + *
22.728 + * </ol>
22.729 + *
22.730 + * <p> The resulting URI string is then parsed as if by invoking the {@link
22.731 + * #URI(String)} constructor and then invoking the {@link
22.732 + * #parseServerAuthority()} method upon the result; this may cause a {@link
22.733 + * URISyntaxException} to be thrown. </p>
22.734 + *
22.735 + * @param scheme Scheme name
22.736 + * @param authority Authority
22.737 + * @param path Path
22.738 + * @param query Query
22.739 + * @param fragment Fragment
22.740 + *
22.741 + * @throws URISyntaxException
22.742 + * If both a scheme and a path are given but the path is relative,
22.743 + * if the URI string constructed from the given components violates
22.744 + * RFC 2396, or if the authority component of the string is
22.745 + * present but cannot be parsed as a server-based authority
22.746 + */
22.747 + public URI(String scheme,
22.748 + String authority,
22.749 + String path, String query, String fragment)
22.750 + throws URISyntaxException
22.751 + {
22.752 + String s = toString(scheme, null,
22.753 + authority, null, null, -1,
22.754 + path, query, fragment);
22.755 + checkPath(s, scheme, path);
22.756 + new Parser(s).parse(false);
22.757 + }
22.758 +
22.759 + /**
22.760 + * Constructs a hierarchical URI from the given components.
22.761 + *
22.762 + * <p> A component may be left undefined by passing <tt>null</tt>.
22.763 + *
22.764 + * <p> This convenience constructor works as if by invoking the
22.765 + * seven-argument constructor as follows:
22.766 + *
22.767 + * <blockquote><tt>
22.768 + * new {@link #URI(String, String, String, int, String, String, String)
22.769 + * URI}(scheme, null, host, -1, path, null, fragment);
22.770 + * </tt></blockquote>
22.771 + *
22.772 + * @param scheme Scheme name
22.773 + * @param host Host name
22.774 + * @param path Path
22.775 + * @param fragment Fragment
22.776 + *
22.777 + * @throws URISyntaxException
22.778 + * If the URI string constructed from the given components
22.779 + * violates RFC 2396
22.780 + */
22.781 + public URI(String scheme, String host, String path, String fragment)
22.782 + throws URISyntaxException
22.783 + {
22.784 + this(scheme, null, host, -1, path, null, fragment);
22.785 + }
22.786 +
22.787 + /**
22.788 + * Constructs a URI from the given components.
22.789 + *
22.790 + * <p> A component may be left undefined by passing <tt>null</tt>.
22.791 + *
22.792 + * <p> This constructor first builds a URI in string form using the given
22.793 + * components as follows: </p>
22.794 + *
22.795 + * <ol>
22.796 + *
22.797 + * <li><p> Initially, the result string is empty. </p></li>
22.798 + *
22.799 + * <li><p> If a scheme is given then it is appended to the result,
22.800 + * followed by a colon character (<tt>':'</tt>). </p></li>
22.801 + *
22.802 + * <li><p> If a scheme-specific part is given then it is appended. Any
22.803 + * character that is not a <a href="#legal-chars">legal URI character</a>
22.804 + * is <a href="#quote">quoted</a>. </p></li>
22.805 + *
22.806 + * <li><p> Finally, if a fragment is given then a hash character
22.807 + * (<tt>'#'</tt>) is appended to the string, followed by the fragment.
22.808 + * Any character that is not a legal URI character is quoted. </p></li>
22.809 + *
22.810 + * </ol>
22.811 + *
22.812 + * <p> The resulting URI string is then parsed in order to create the new
22.813 + * URI instance as if by invoking the {@link #URI(String)} constructor;
22.814 + * this may cause a {@link URISyntaxException} to be thrown. </p>
22.815 + *
22.816 + * @param scheme Scheme name
22.817 + * @param ssp Scheme-specific part
22.818 + * @param fragment Fragment
22.819 + *
22.820 + * @throws URISyntaxException
22.821 + * If the URI string constructed from the given components
22.822 + * violates RFC 2396
22.823 + */
22.824 + public URI(String scheme, String ssp, String fragment)
22.825 + throws URISyntaxException
22.826 + {
22.827 + new Parser(toString(scheme, ssp,
22.828 + null, null, null, -1,
22.829 + null, null, fragment))
22.830 + .parse(false);
22.831 + }
22.832 +
22.833 + /**
22.834 + * Creates a URI by parsing the given string.
22.835 + *
22.836 + * <p> This convenience factory method works as if by invoking the {@link
22.837 + * #URI(String)} constructor; any {@link URISyntaxException} thrown by the
22.838 + * constructor is caught and wrapped in a new {@link
22.839 + * IllegalArgumentException} object, which is then thrown.
22.840 + *
22.841 + * <p> This method is provided for use in situations where it is known that
22.842 + * the given string is a legal URI, for example for URI constants declared
22.843 + * within in a program, and so it would be considered a programming error
22.844 + * for the string not to parse as such. The constructors, which throw
22.845 + * {@link URISyntaxException} directly, should be used situations where a
22.846 + * URI is being constructed from user input or from some other source that
22.847 + * may be prone to errors. </p>
22.848 + *
22.849 + * @param str The string to be parsed into a URI
22.850 + * @return The new URI
22.851 + *
22.852 + * @throws NullPointerException
22.853 + * If <tt>str</tt> is <tt>null</tt>
22.854 + *
22.855 + * @throws IllegalArgumentException
22.856 + * If the given string violates RFC 2396
22.857 + */
22.858 + public static URI create(String str) {
22.859 + try {
22.860 + return new URI(str);
22.861 + } catch (URISyntaxException x) {
22.862 + throw new IllegalArgumentException(x.getMessage(), x);
22.863 + }
22.864 + }
22.865 +
22.866 +
22.867 + // -- Operations --
22.868 +
22.869 + /**
22.870 + * Attempts to parse this URI's authority component, if defined, into
22.871 + * user-information, host, and port components.
22.872 + *
22.873 + * <p> If this URI's authority component has already been recognized as
22.874 + * being server-based then it will already have been parsed into
22.875 + * user-information, host, and port components. In this case, or if this
22.876 + * URI has no authority component, this method simply returns this URI.
22.877 + *
22.878 + * <p> Otherwise this method attempts once more to parse the authority
22.879 + * component into user-information, host, and port components, and throws
22.880 + * an exception describing why the authority component could not be parsed
22.881 + * in that way.
22.882 + *
22.883 + * <p> This method is provided because the generic URI syntax specified in
22.884 + * <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>
22.885 + * cannot always distinguish a malformed server-based authority from a
22.886 + * legitimate registry-based authority. It must therefore treat some
22.887 + * instances of the former as instances of the latter. The authority
22.888 + * component in the URI string <tt>"//foo:bar"</tt>, for example, is not a
22.889 + * legal server-based authority but it is legal as a registry-based
22.890 + * authority.
22.891 + *
22.892 + * <p> In many common situations, for example when working URIs that are
22.893 + * known to be either URNs or URLs, the hierarchical URIs being used will
22.894 + * always be server-based. They therefore must either be parsed as such or
22.895 + * treated as an error. In these cases a statement such as
22.896 + *
22.897 + * <blockquote>
22.898 + * <tt>URI </tt><i>u</i><tt> = new URI(str).parseServerAuthority();</tt>
22.899 + * </blockquote>
22.900 + *
22.901 + * <p> can be used to ensure that <i>u</i> always refers to a URI that, if
22.902 + * it has an authority component, has a server-based authority with proper
22.903 + * user-information, host, and port components. Invoking this method also
22.904 + * ensures that if the authority could not be parsed in that way then an
22.905 + * appropriate diagnostic message can be issued based upon the exception
22.906 + * that is thrown. </p>
22.907 + *
22.908 + * @return A URI whose authority field has been parsed
22.909 + * as a server-based authority
22.910 + *
22.911 + * @throws URISyntaxException
22.912 + * If the authority component of this URI is defined
22.913 + * but cannot be parsed as a server-based authority
22.914 + * according to RFC 2396
22.915 + */
22.916 + public URI parseServerAuthority()
22.917 + throws URISyntaxException
22.918 + {
22.919 + // We could be clever and cache the error message and index from the
22.920 + // exception thrown during the original parse, but that would require
22.921 + // either more fields or a more-obscure representation.
22.922 + if ((host != null) || (authority == null))
22.923 + return this;
22.924 + defineString();
22.925 + new Parser(string).parse(true);
22.926 + return this;
22.927 + }
22.928 +
22.929 + /**
22.930 + * Normalizes this URI's path.
22.931 + *
22.932 + * <p> If this URI is opaque, or if its path is already in normal form,
22.933 + * then this URI is returned. Otherwise a new URI is constructed that is
22.934 + * identical to this URI except that its path is computed by normalizing
22.935 + * this URI's path in a manner consistent with <a
22.936 + * href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>,
22.937 + * section 5.2, step 6, sub-steps c through f; that is:
22.938 + * </p>
22.939 + *
22.940 + * <ol>
22.941 + *
22.942 + * <li><p> All <tt>"."</tt> segments are removed. </p></li>
22.943 + *
22.944 + * <li><p> If a <tt>".."</tt> segment is preceded by a non-<tt>".."</tt>
22.945 + * segment then both of these segments are removed. This step is
22.946 + * repeated until it is no longer applicable. </p></li>
22.947 + *
22.948 + * <li><p> If the path is relative, and if its first segment contains a
22.949 + * colon character (<tt>':'</tt>), then a <tt>"."</tt> segment is
22.950 + * prepended. This prevents a relative URI with a path such as
22.951 + * <tt>"a:b/c/d"</tt> from later being re-parsed as an opaque URI with a
22.952 + * scheme of <tt>"a"</tt> and a scheme-specific part of <tt>"b/c/d"</tt>.
22.953 + * <b><i>(Deviation from RFC 2396)</i></b> </p></li>
22.954 + *
22.955 + * </ol>
22.956 + *
22.957 + * <p> A normalized path will begin with one or more <tt>".."</tt> segments
22.958 + * if there were insufficient non-<tt>".."</tt> segments preceding them to
22.959 + * allow their removal. A normalized path will begin with a <tt>"."</tt>
22.960 + * segment if one was inserted by step 3 above. Otherwise, a normalized
22.961 + * path will not contain any <tt>"."</tt> or <tt>".."</tt> segments. </p>
22.962 + *
22.963 + * @return A URI equivalent to this URI,
22.964 + * but whose path is in normal form
22.965 + */
22.966 + public URI normalize() {
22.967 + return normalize(this);
22.968 + }
22.969 +
22.970 + /**
22.971 + * Resolves the given URI against this URI.
22.972 + *
22.973 + * <p> If the given URI is already absolute, or if this URI is opaque, then
22.974 + * the given URI is returned.
22.975 + *
22.976 + * <p><a name="resolve-frag"></a> If the given URI's fragment component is
22.977 + * defined, its path component is empty, and its scheme, authority, and
22.978 + * query components are undefined, then a URI with the given fragment but
22.979 + * with all other components equal to those of this URI is returned. This
22.980 + * allows a URI representing a standalone fragment reference, such as
22.981 + * <tt>"#foo"</tt>, to be usefully resolved against a base URI.
22.982 + *
22.983 + * <p> Otherwise this method constructs a new hierarchical URI in a manner
22.984 + * consistent with <a
22.985 + * href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>,
22.986 + * section 5.2; that is: </p>
22.987 + *
22.988 + * <ol>
22.989 + *
22.990 + * <li><p> A new URI is constructed with this URI's scheme and the given
22.991 + * URI's query and fragment components. </p></li>
22.992 + *
22.993 + * <li><p> If the given URI has an authority component then the new URI's
22.994 + * authority and path are taken from the given URI. </p></li>
22.995 + *
22.996 + * <li><p> Otherwise the new URI's authority component is copied from
22.997 + * this URI, and its path is computed as follows: </p>
22.998 + *
22.999 + * <ol type=a>
22.1000 + *
22.1001 + * <li><p> If the given URI's path is absolute then the new URI's path
22.1002 + * is taken from the given URI. </p></li>
22.1003 + *
22.1004 + * <li><p> Otherwise the given URI's path is relative, and so the new
22.1005 + * URI's path is computed by resolving the path of the given URI
22.1006 + * against the path of this URI. This is done by concatenating all but
22.1007 + * the last segment of this URI's path, if any, with the given URI's
22.1008 + * path and then normalizing the result as if by invoking the {@link
22.1009 + * #normalize() normalize} method. </p></li>
22.1010 + *
22.1011 + * </ol></li>
22.1012 + *
22.1013 + * </ol>
22.1014 + *
22.1015 + * <p> The result of this method is absolute if, and only if, either this
22.1016 + * URI is absolute or the given URI is absolute. </p>
22.1017 + *
22.1018 + * @param uri The URI to be resolved against this URI
22.1019 + * @return The resulting URI
22.1020 + *
22.1021 + * @throws NullPointerException
22.1022 + * If <tt>uri</tt> is <tt>null</tt>
22.1023 + */
22.1024 + public URI resolve(URI uri) {
22.1025 + return resolve(this, uri);
22.1026 + }
22.1027 +
22.1028 + /**
22.1029 + * Constructs a new URI by parsing the given string and then resolving it
22.1030 + * against this URI.
22.1031 + *
22.1032 + * <p> This convenience method works as if invoking it were equivalent to
22.1033 + * evaluating the expression <tt>{@link #resolve(java.net.URI)
22.1034 + * resolve}(URI.{@link #create(String) create}(str))</tt>. </p>
22.1035 + *
22.1036 + * @param str The string to be parsed into a URI
22.1037 + * @return The resulting URI
22.1038 + *
22.1039 + * @throws NullPointerException
22.1040 + * If <tt>str</tt> is <tt>null</tt>
22.1041 + *
22.1042 + * @throws IllegalArgumentException
22.1043 + * If the given string violates RFC 2396
22.1044 + */
22.1045 + public URI resolve(String str) {
22.1046 + return resolve(URI.create(str));
22.1047 + }
22.1048 +
22.1049 + /**
22.1050 + * Relativizes the given URI against this URI.
22.1051 + *
22.1052 + * <p> The relativization of the given URI against this URI is computed as
22.1053 + * follows: </p>
22.1054 + *
22.1055 + * <ol>
22.1056 + *
22.1057 + * <li><p> If either this URI or the given URI are opaque, or if the
22.1058 + * scheme and authority components of the two URIs are not identical, or
22.1059 + * if the path of this URI is not a prefix of the path of the given URI,
22.1060 + * then the given URI is returned. </p></li>
22.1061 + *
22.1062 + * <li><p> Otherwise a new relative hierarchical URI is constructed with
22.1063 + * query and fragment components taken from the given URI and with a path
22.1064 + * component computed by removing this URI's path from the beginning of
22.1065 + * the given URI's path. </p></li>
22.1066 + *
22.1067 + * </ol>
22.1068 + *
22.1069 + * @param uri The URI to be relativized against this URI
22.1070 + * @return The resulting URI
22.1071 + *
22.1072 + * @throws NullPointerException
22.1073 + * If <tt>uri</tt> is <tt>null</tt>
22.1074 + */
22.1075 + public URI relativize(URI uri) {
22.1076 + return relativize(this, uri);
22.1077 + }
22.1078 +
22.1079 + /**
22.1080 + * Constructs a URL from this URI.
22.1081 + *
22.1082 + * <p> This convenience method works as if invoking it were equivalent to
22.1083 + * evaluating the expression <tt>new URL(this.toString())</tt> after
22.1084 + * first checking that this URI is absolute. </p>
22.1085 + *
22.1086 + * @return A URL constructed from this URI
22.1087 + *
22.1088 + * @throws IllegalArgumentException
22.1089 + * If this URL is not absolute
22.1090 + *
22.1091 + * @throws MalformedURLException
22.1092 + * If a protocol handler for the URL could not be found,
22.1093 + * or if some other error occurred while constructing the URL
22.1094 + */
22.1095 + public URL toURL()
22.1096 + throws MalformedURLException {
22.1097 + if (!isAbsolute())
22.1098 + throw new IllegalArgumentException("URI is not absolute");
22.1099 + return new URL(toString());
22.1100 + }
22.1101 +
22.1102 + // -- Component access methods --
22.1103 +
22.1104 + /**
22.1105 + * Returns the scheme component of this URI.
22.1106 + *
22.1107 + * <p> The scheme component of a URI, if defined, only contains characters
22.1108 + * in the <i>alphanum</i> category and in the string <tt>"-.+"</tt>. A
22.1109 + * scheme always starts with an <i>alpha</i> character. <p>
22.1110 + *
22.1111 + * The scheme component of a URI cannot contain escaped octets, hence this
22.1112 + * method does not perform any decoding.
22.1113 + *
22.1114 + * @return The scheme component of this URI,
22.1115 + * or <tt>null</tt> if the scheme is undefined
22.1116 + */
22.1117 + public String getScheme() {
22.1118 + return scheme;
22.1119 + }
22.1120 +
22.1121 + /**
22.1122 + * Tells whether or not this URI is absolute.
22.1123 + *
22.1124 + * <p> A URI is absolute if, and only if, it has a scheme component. </p>
22.1125 + *
22.1126 + * @return <tt>true</tt> if, and only if, this URI is absolute
22.1127 + */
22.1128 + public boolean isAbsolute() {
22.1129 + return scheme != null;
22.1130 + }
22.1131 +
22.1132 + /**
22.1133 + * Tells whether or not this URI is opaque.
22.1134 + *
22.1135 + * <p> A URI is opaque if, and only if, it is absolute and its
22.1136 + * scheme-specific part does not begin with a slash character ('/').
22.1137 + * An opaque URI has a scheme, a scheme-specific part, and possibly
22.1138 + * a fragment; all other components are undefined. </p>
22.1139 + *
22.1140 + * @return <tt>true</tt> if, and only if, this URI is opaque
22.1141 + */
22.1142 + public boolean isOpaque() {
22.1143 + return path == null;
22.1144 + }
22.1145 +
22.1146 + /**
22.1147 + * Returns the raw scheme-specific part of this URI. The scheme-specific
22.1148 + * part is never undefined, though it may be empty.
22.1149 + *
22.1150 + * <p> The scheme-specific part of a URI only contains legal URI
22.1151 + * characters. </p>
22.1152 + *
22.1153 + * @return The raw scheme-specific part of this URI
22.1154 + * (never <tt>null</tt>)
22.1155 + */
22.1156 + public String getRawSchemeSpecificPart() {
22.1157 + defineSchemeSpecificPart();
22.1158 + return schemeSpecificPart;
22.1159 + }
22.1160 +
22.1161 + /**
22.1162 + * Returns the decoded scheme-specific part of this URI.
22.1163 + *
22.1164 + * <p> The string returned by this method is equal to that returned by the
22.1165 + * {@link #getRawSchemeSpecificPart() getRawSchemeSpecificPart} method
22.1166 + * except that all sequences of escaped octets are <a
22.1167 + * href="#decode">decoded</a>. </p>
22.1168 + *
22.1169 + * @return The decoded scheme-specific part of this URI
22.1170 + * (never <tt>null</tt>)
22.1171 + */
22.1172 + public String getSchemeSpecificPart() {
22.1173 + if (decodedSchemeSpecificPart == null)
22.1174 + decodedSchemeSpecificPart = decode(getRawSchemeSpecificPart());
22.1175 + return decodedSchemeSpecificPart;
22.1176 + }
22.1177 +
22.1178 + /**
22.1179 + * Returns the raw authority component of this URI.
22.1180 + *
22.1181 + * <p> The authority component of a URI, if defined, only contains the
22.1182 + * commercial-at character (<tt>'@'</tt>) and characters in the
22.1183 + * <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, and <i>other</i>
22.1184 + * categories. If the authority is server-based then it is further
22.1185 + * constrained to have valid user-information, host, and port
22.1186 + * components. </p>
22.1187 + *
22.1188 + * @return The raw authority component of this URI,
22.1189 + * or <tt>null</tt> if the authority is undefined
22.1190 + */
22.1191 + public String getRawAuthority() {
22.1192 + return authority;
22.1193 + }
22.1194 +
22.1195 + /**
22.1196 + * Returns the decoded authority component of this URI.
22.1197 + *
22.1198 + * <p> The string returned by this method is equal to that returned by the
22.1199 + * {@link #getRawAuthority() getRawAuthority} method except that all
22.1200 + * sequences of escaped octets are <a href="#decode">decoded</a>. </p>
22.1201 + *
22.1202 + * @return The decoded authority component of this URI,
22.1203 + * or <tt>null</tt> if the authority is undefined
22.1204 + */
22.1205 + public String getAuthority() {
22.1206 + if (decodedAuthority == null)
22.1207 + decodedAuthority = decode(authority);
22.1208 + return decodedAuthority;
22.1209 + }
22.1210 +
22.1211 + /**
22.1212 + * Returns the raw user-information component of this URI.
22.1213 + *
22.1214 + * <p> The user-information component of a URI, if defined, only contains
22.1215 + * characters in the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, and
22.1216 + * <i>other</i> categories. </p>
22.1217 + *
22.1218 + * @return The raw user-information component of this URI,
22.1219 + * or <tt>null</tt> if the user information is undefined
22.1220 + */
22.1221 + public String getRawUserInfo() {
22.1222 + return userInfo;
22.1223 + }
22.1224 +
22.1225 + /**
22.1226 + * Returns the decoded user-information component of this URI.
22.1227 + *
22.1228 + * <p> The string returned by this method is equal to that returned by the
22.1229 + * {@link #getRawUserInfo() getRawUserInfo} method except that all
22.1230 + * sequences of escaped octets are <a href="#decode">decoded</a>. </p>
22.1231 + *
22.1232 + * @return The decoded user-information component of this URI,
22.1233 + * or <tt>null</tt> if the user information is undefined
22.1234 + */
22.1235 + public String getUserInfo() {
22.1236 + if ((decodedUserInfo == null) && (userInfo != null))
22.1237 + decodedUserInfo = decode(userInfo);
22.1238 + return decodedUserInfo;
22.1239 + }
22.1240 +
22.1241 + /**
22.1242 + * Returns the host component of this URI.
22.1243 + *
22.1244 + * <p> The host component of a URI, if defined, will have one of the
22.1245 + * following forms: </p>
22.1246 + *
22.1247 + * <ul type=disc>
22.1248 + *
22.1249 + * <li><p> A domain name consisting of one or more <i>labels</i>
22.1250 + * separated by period characters (<tt>'.'</tt>), optionally followed by
22.1251 + * a period character. Each label consists of <i>alphanum</i> characters
22.1252 + * as well as hyphen characters (<tt>'-'</tt>), though hyphens never
22.1253 + * occur as the first or last characters in a label. The rightmost
22.1254 + * label of a domain name consisting of two or more labels, begins
22.1255 + * with an <i>alpha</i> character. </li>
22.1256 + *
22.1257 + * <li><p> A dotted-quad IPv4 address of the form
22.1258 + * <i>digit</i><tt>+.</tt><i>digit</i><tt>+.</tt><i>digit</i><tt>+.</tt><i>digit</i><tt>+</tt>,
22.1259 + * where no <i>digit</i> sequence is longer than three characters and no
22.1260 + * sequence has a value larger than 255. </p></li>
22.1261 + *
22.1262 + * <li><p> An IPv6 address enclosed in square brackets (<tt>'['</tt> and
22.1263 + * <tt>']'</tt>) and consisting of hexadecimal digits, colon characters
22.1264 + * (<tt>':'</tt>), and possibly an embedded IPv4 address. The full
22.1265 + * syntax of IPv6 addresses is specified in <a
22.1266 + * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC 2373: IPv6
22.1267 + * Addressing Architecture</i></a>. </p></li>
22.1268 + *
22.1269 + * </ul>
22.1270 + *
22.1271 + * The host component of a URI cannot contain escaped octets, hence this
22.1272 + * method does not perform any decoding.
22.1273 + *
22.1274 + * @return The host component of this URI,
22.1275 + * or <tt>null</tt> if the host is undefined
22.1276 + */
22.1277 + public String getHost() {
22.1278 + return host;
22.1279 + }
22.1280 +
22.1281 + /**
22.1282 + * Returns the port number of this URI.
22.1283 + *
22.1284 + * <p> The port component of a URI, if defined, is a non-negative
22.1285 + * integer. </p>
22.1286 + *
22.1287 + * @return The port component of this URI,
22.1288 + * or <tt>-1</tt> if the port is undefined
22.1289 + */
22.1290 + public int getPort() {
22.1291 + return port;
22.1292 + }
22.1293 +
22.1294 + /**
22.1295 + * Returns the raw path component of this URI.
22.1296 + *
22.1297 + * <p> The path component of a URI, if defined, only contains the slash
22.1298 + * character (<tt>'/'</tt>), the commercial-at character (<tt>'@'</tt>),
22.1299 + * and characters in the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>,
22.1300 + * and <i>other</i> categories. </p>
22.1301 + *
22.1302 + * @return The path component of this URI,
22.1303 + * or <tt>null</tt> if the path is undefined
22.1304 + */
22.1305 + public String getRawPath() {
22.1306 + return path;
22.1307 + }
22.1308 +
22.1309 + /**
22.1310 + * Returns the decoded path component of this URI.
22.1311 + *
22.1312 + * <p> The string returned by this method is equal to that returned by the
22.1313 + * {@link #getRawPath() getRawPath} method except that all sequences of
22.1314 + * escaped octets are <a href="#decode">decoded</a>. </p>
22.1315 + *
22.1316 + * @return The decoded path component of this URI,
22.1317 + * or <tt>null</tt> if the path is undefined
22.1318 + */
22.1319 + public String getPath() {
22.1320 + if ((decodedPath == null) && (path != null))
22.1321 + decodedPath = decode(path);
22.1322 + return decodedPath;
22.1323 + }
22.1324 +
22.1325 + /**
22.1326 + * Returns the raw query component of this URI.
22.1327 + *
22.1328 + * <p> The query component of a URI, if defined, only contains legal URI
22.1329 + * characters. </p>
22.1330 + *
22.1331 + * @return The raw query component of this URI,
22.1332 + * or <tt>null</tt> if the query is undefined
22.1333 + */
22.1334 + public String getRawQuery() {
22.1335 + return query;
22.1336 + }
22.1337 +
22.1338 + /**
22.1339 + * Returns the decoded query component of this URI.
22.1340 + *
22.1341 + * <p> The string returned by this method is equal to that returned by the
22.1342 + * {@link #getRawQuery() getRawQuery} method except that all sequences of
22.1343 + * escaped octets are <a href="#decode">decoded</a>. </p>
22.1344 + *
22.1345 + * @return The decoded query component of this URI,
22.1346 + * or <tt>null</tt> if the query is undefined
22.1347 + */
22.1348 + public String getQuery() {
22.1349 + if ((decodedQuery == null) && (query != null))
22.1350 + decodedQuery = decode(query);
22.1351 + return decodedQuery;
22.1352 + }
22.1353 +
22.1354 + /**
22.1355 + * Returns the raw fragment component of this URI.
22.1356 + *
22.1357 + * <p> The fragment component of a URI, if defined, only contains legal URI
22.1358 + * characters. </p>
22.1359 + *
22.1360 + * @return The raw fragment component of this URI,
22.1361 + * or <tt>null</tt> if the fragment is undefined
22.1362 + */
22.1363 + public String getRawFragment() {
22.1364 + return fragment;
22.1365 + }
22.1366 +
22.1367 + /**
22.1368 + * Returns the decoded fragment component of this URI.
22.1369 + *
22.1370 + * <p> The string returned by this method is equal to that returned by the
22.1371 + * {@link #getRawFragment() getRawFragment} method except that all
22.1372 + * sequences of escaped octets are <a href="#decode">decoded</a>. </p>
22.1373 + *
22.1374 + * @return The decoded fragment component of this URI,
22.1375 + * or <tt>null</tt> if the fragment is undefined
22.1376 + */
22.1377 + public String getFragment() {
22.1378 + if ((decodedFragment == null) && (fragment != null))
22.1379 + decodedFragment = decode(fragment);
22.1380 + return decodedFragment;
22.1381 + }
22.1382 +
22.1383 +
22.1384 + // -- Equality, comparison, hash code, toString, and serialization --
22.1385 +
22.1386 + /**
22.1387 + * Tests this URI for equality with another object.
22.1388 + *
22.1389 + * <p> If the given object is not a URI then this method immediately
22.1390 + * returns <tt>false</tt>.
22.1391 + *
22.1392 + * <p> For two URIs to be considered equal requires that either both are
22.1393 + * opaque or both are hierarchical. Their schemes must either both be
22.1394 + * undefined or else be equal without regard to case. Their fragments
22.1395 + * must either both be undefined or else be equal.
22.1396 + *
22.1397 + * <p> For two opaque URIs to be considered equal, their scheme-specific
22.1398 + * parts must be equal.
22.1399 + *
22.1400 + * <p> For two hierarchical URIs to be considered equal, their paths must
22.1401 + * be equal and their queries must either both be undefined or else be
22.1402 + * equal. Their authorities must either both be undefined, or both be
22.1403 + * registry-based, or both be server-based. If their authorities are
22.1404 + * defined and are registry-based, then they must be equal. If their
22.1405 + * authorities are defined and are server-based, then their hosts must be
22.1406 + * equal without regard to case, their port numbers must be equal, and
22.1407 + * their user-information components must be equal.
22.1408 + *
22.1409 + * <p> When testing the user-information, path, query, fragment, authority,
22.1410 + * or scheme-specific parts of two URIs for equality, the raw forms rather
22.1411 + * than the encoded forms of these components are compared and the
22.1412 + * hexadecimal digits of escaped octets are compared without regard to
22.1413 + * case.
22.1414 + *
22.1415 + * <p> This method satisfies the general contract of the {@link
22.1416 + * java.lang.Object#equals(Object) Object.equals} method. </p>
22.1417 + *
22.1418 + * @param ob The object to which this object is to be compared
22.1419 + *
22.1420 + * @return <tt>true</tt> if, and only if, the given object is a URI that
22.1421 + * is identical to this URI
22.1422 + */
22.1423 + public boolean equals(Object ob) {
22.1424 + if (ob == this)
22.1425 + return true;
22.1426 + if (!(ob instanceof URI))
22.1427 + return false;
22.1428 + URI that = (URI)ob;
22.1429 + if (this.isOpaque() != that.isOpaque()) return false;
22.1430 + if (!equalIgnoringCase(this.scheme, that.scheme)) return false;
22.1431 + if (!equal(this.fragment, that.fragment)) return false;
22.1432 +
22.1433 + // Opaque
22.1434 + if (this.isOpaque())
22.1435 + return equal(this.schemeSpecificPart, that.schemeSpecificPart);
22.1436 +
22.1437 + // Hierarchical
22.1438 + if (!equal(this.path, that.path)) return false;
22.1439 + if (!equal(this.query, that.query)) return false;
22.1440 +
22.1441 + // Authorities
22.1442 + if (this.authority == that.authority) return true;
22.1443 + if (this.host != null) {
22.1444 + // Server-based
22.1445 + if (!equal(this.userInfo, that.userInfo)) return false;
22.1446 + if (!equalIgnoringCase(this.host, that.host)) return false;
22.1447 + if (this.port != that.port) return false;
22.1448 + } else if (this.authority != null) {
22.1449 + // Registry-based
22.1450 + if (!equal(this.authority, that.authority)) return false;
22.1451 + } else if (this.authority != that.authority) {
22.1452 + return false;
22.1453 + }
22.1454 +
22.1455 + return true;
22.1456 + }
22.1457 +
22.1458 + /**
22.1459 + * Returns a hash-code value for this URI. The hash code is based upon all
22.1460 + * of the URI's components, and satisfies the general contract of the
22.1461 + * {@link java.lang.Object#hashCode() Object.hashCode} method.
22.1462 + *
22.1463 + * @return A hash-code value for this URI
22.1464 + */
22.1465 + public int hashCode() {
22.1466 + if (hash != 0)
22.1467 + return hash;
22.1468 + int h = hashIgnoringCase(0, scheme);
22.1469 + h = hash(h, fragment);
22.1470 + if (isOpaque()) {
22.1471 + h = hash(h, schemeSpecificPart);
22.1472 + } else {
22.1473 + h = hash(h, path);
22.1474 + h = hash(h, query);
22.1475 + if (host != null) {
22.1476 + h = hash(h, userInfo);
22.1477 + h = hashIgnoringCase(h, host);
22.1478 + h += 1949 * port;
22.1479 + } else {
22.1480 + h = hash(h, authority);
22.1481 + }
22.1482 + }
22.1483 + hash = h;
22.1484 + return h;
22.1485 + }
22.1486 +
22.1487 + /**
22.1488 + * Compares this URI to another object, which must be a URI.
22.1489 + *
22.1490 + * <p> When comparing corresponding components of two URIs, if one
22.1491 + * component is undefined but the other is defined then the first is
22.1492 + * considered to be less than the second. Unless otherwise noted, string
22.1493 + * components are ordered according to their natural, case-sensitive
22.1494 + * ordering as defined by the {@link java.lang.String#compareTo(Object)
22.1495 + * String.compareTo} method. String components that are subject to
22.1496 + * encoding are compared by comparing their raw forms rather than their
22.1497 + * encoded forms.
22.1498 + *
22.1499 + * <p> The ordering of URIs is defined as follows: </p>
22.1500 + *
22.1501 + * <ul type=disc>
22.1502 + *
22.1503 + * <li><p> Two URIs with different schemes are ordered according the
22.1504 + * ordering of their schemes, without regard to case. </p></li>
22.1505 + *
22.1506 + * <li><p> A hierarchical URI is considered to be less than an opaque URI
22.1507 + * with an identical scheme. </p></li>
22.1508 + *
22.1509 + * <li><p> Two opaque URIs with identical schemes are ordered according
22.1510 + * to the ordering of their scheme-specific parts. </p></li>
22.1511 + *
22.1512 + * <li><p> Two opaque URIs with identical schemes and scheme-specific
22.1513 + * parts are ordered according to the ordering of their
22.1514 + * fragments. </p></li>
22.1515 + *
22.1516 + * <li><p> Two hierarchical URIs with identical schemes are ordered
22.1517 + * according to the ordering of their authority components: </p>
22.1518 + *
22.1519 + * <ul type=disc>
22.1520 + *
22.1521 + * <li><p> If both authority components are server-based then the URIs
22.1522 + * are ordered according to their user-information components; if these
22.1523 + * components are identical then the URIs are ordered according to the
22.1524 + * ordering of their hosts, without regard to case; if the hosts are
22.1525 + * identical then the URIs are ordered according to the ordering of
22.1526 + * their ports. </p></li>
22.1527 + *
22.1528 + * <li><p> If one or both authority components are registry-based then
22.1529 + * the URIs are ordered according to the ordering of their authority
22.1530 + * components. </p></li>
22.1531 + *
22.1532 + * </ul></li>
22.1533 + *
22.1534 + * <li><p> Finally, two hierarchical URIs with identical schemes and
22.1535 + * authority components are ordered according to the ordering of their
22.1536 + * paths; if their paths are identical then they are ordered according to
22.1537 + * the ordering of their queries; if the queries are identical then they
22.1538 + * are ordered according to the order of their fragments. </p></li>
22.1539 + *
22.1540 + * </ul>
22.1541 + *
22.1542 + * <p> This method satisfies the general contract of the {@link
22.1543 + * java.lang.Comparable#compareTo(Object) Comparable.compareTo}
22.1544 + * method. </p>
22.1545 + *
22.1546 + * @param that
22.1547 + * The object to which this URI is to be compared
22.1548 + *
22.1549 + * @return A negative integer, zero, or a positive integer as this URI is
22.1550 + * less than, equal to, or greater than the given URI
22.1551 + *
22.1552 + * @throws ClassCastException
22.1553 + * If the given object is not a URI
22.1554 + */
22.1555 + public int compareTo(URI that) {
22.1556 + int c;
22.1557 +
22.1558 + if ((c = compareIgnoringCase(this.scheme, that.scheme)) != 0)
22.1559 + return c;
22.1560 +
22.1561 + if (this.isOpaque()) {
22.1562 + if (that.isOpaque()) {
22.1563 + // Both opaque
22.1564 + if ((c = compare(this.schemeSpecificPart,
22.1565 + that.schemeSpecificPart)) != 0)
22.1566 + return c;
22.1567 + return compare(this.fragment, that.fragment);
22.1568 + }
22.1569 + return +1; // Opaque > hierarchical
22.1570 + } else if (that.isOpaque()) {
22.1571 + return -1; // Hierarchical < opaque
22.1572 + }
22.1573 +
22.1574 + // Hierarchical
22.1575 + if ((this.host != null) && (that.host != null)) {
22.1576 + // Both server-based
22.1577 + if ((c = compare(this.userInfo, that.userInfo)) != 0)
22.1578 + return c;
22.1579 + if ((c = compareIgnoringCase(this.host, that.host)) != 0)
22.1580 + return c;
22.1581 + if ((c = this.port - that.port) != 0)
22.1582 + return c;
22.1583 + } else {
22.1584 + // If one or both authorities are registry-based then we simply
22.1585 + // compare them in the usual, case-sensitive way. If one is
22.1586 + // registry-based and one is server-based then the strings are
22.1587 + // guaranteed to be unequal, hence the comparison will never return
22.1588 + // zero and the compareTo and equals methods will remain
22.1589 + // consistent.
22.1590 + if ((c = compare(this.authority, that.authority)) != 0) return c;
22.1591 + }
22.1592 +
22.1593 + if ((c = compare(this.path, that.path)) != 0) return c;
22.1594 + if ((c = compare(this.query, that.query)) != 0) return c;
22.1595 + return compare(this.fragment, that.fragment);
22.1596 + }
22.1597 +
22.1598 + /**
22.1599 + * Returns the content of this URI as a string.
22.1600 + *
22.1601 + * <p> If this URI was created by invoking one of the constructors in this
22.1602 + * class then a string equivalent to the original input string, or to the
22.1603 + * string computed from the originally-given components, as appropriate, is
22.1604 + * returned. Otherwise this URI was created by normalization, resolution,
22.1605 + * or relativization, and so a string is constructed from this URI's
22.1606 + * components according to the rules specified in <a
22.1607 + * href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>,
22.1608 + * section 5.2, step 7. </p>
22.1609 + *
22.1610 + * @return The string form of this URI
22.1611 + */
22.1612 + public String toString() {
22.1613 + defineString();
22.1614 + return string;
22.1615 + }
22.1616 +
22.1617 + /**
22.1618 + * Returns the content of this URI as a US-ASCII string.
22.1619 + *
22.1620 + * <p> If this URI does not contain any characters in the <i>other</i>
22.1621 + * category then an invocation of this method will return the same value as
22.1622 + * an invocation of the {@link #toString() toString} method. Otherwise
22.1623 + * this method works as if by invoking that method and then <a
22.1624 + * href="#encode">encoding</a> the result. </p>
22.1625 + *
22.1626 + * @return The string form of this URI, encoded as needed
22.1627 + * so that it only contains characters in the US-ASCII
22.1628 + * charset
22.1629 + */
22.1630 + public String toASCIIString() {
22.1631 + defineString();
22.1632 + return encode(string);
22.1633 + }
22.1634 +
22.1635 +
22.1636 + // -- Serialization support --
22.1637 +
22.1638 + /**
22.1639 + * Saves the content of this URI to the given serial stream.
22.1640 + *
22.1641 + * <p> The only serializable field of a URI instance is its <tt>string</tt>
22.1642 + * field. That field is given a value, if it does not have one already,
22.1643 + * and then the {@link java.io.ObjectOutputStream#defaultWriteObject()}
22.1644 + * method of the given object-output stream is invoked. </p>
22.1645 + *
22.1646 + * @param os The object-output stream to which this object
22.1647 + * is to be written
22.1648 + */
22.1649 + private void writeObject(ObjectOutputStream os)
22.1650 + throws IOException
22.1651 + {
22.1652 + defineString();
22.1653 + os.defaultWriteObject(); // Writes the string field only
22.1654 + }
22.1655 +
22.1656 + /**
22.1657 + * Reconstitutes a URI from the given serial stream.
22.1658 + *
22.1659 + * <p> The {@link java.io.ObjectInputStream#defaultReadObject()} method is
22.1660 + * invoked to read the value of the <tt>string</tt> field. The result is
22.1661 + * then parsed in the usual way.
22.1662 + *
22.1663 + * @param is The object-input stream from which this object
22.1664 + * is being read
22.1665 + */
22.1666 + private void readObject(ObjectInputStream is)
22.1667 + throws ClassNotFoundException, IOException
22.1668 + {
22.1669 + port = -1; // Argh
22.1670 + is.defaultReadObject();
22.1671 + try {
22.1672 + new Parser(string).parse(false);
22.1673 + } catch (URISyntaxException x) {
22.1674 + IOException y = new InvalidObjectException("Invalid URI");
22.1675 + y.initCause(x);
22.1676 + throw y;
22.1677 + }
22.1678 + }
22.1679 +
22.1680 +
22.1681 + // -- End of public methods --
22.1682 +
22.1683 +
22.1684 + // -- Utility methods for string-field comparison and hashing --
22.1685 +
22.1686 + // These methods return appropriate values for null string arguments,
22.1687 + // thereby simplifying the equals, hashCode, and compareTo methods.
22.1688 + //
22.1689 + // The case-ignoring methods should only be applied to strings whose
22.1690 + // characters are all known to be US-ASCII. Because of this restriction,
22.1691 + // these methods are faster than the similar methods in the String class.
22.1692 +
22.1693 + // US-ASCII only
22.1694 + private static int toLower(char c) {
22.1695 + if ((c >= 'A') && (c <= 'Z'))
22.1696 + return c + ('a' - 'A');
22.1697 + return c;
22.1698 + }
22.1699 +
22.1700 + private static boolean equal(String s, String t) {
22.1701 + if (s == t) return true;
22.1702 + if ((s != null) && (t != null)) {
22.1703 + if (s.length() != t.length())
22.1704 + return false;
22.1705 + if (s.indexOf('%') < 0)
22.1706 + return s.equals(t);
22.1707 + int n = s.length();
22.1708 + for (int i = 0; i < n;) {
22.1709 + char c = s.charAt(i);
22.1710 + char d = t.charAt(i);
22.1711 + if (c != '%') {
22.1712 + if (c != d)
22.1713 + return false;
22.1714 + i++;
22.1715 + continue;
22.1716 + }
22.1717 + i++;
22.1718 + if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
22.1719 + return false;
22.1720 + i++;
22.1721 + if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
22.1722 + return false;
22.1723 + i++;
22.1724 + }
22.1725 + return true;
22.1726 + }
22.1727 + return false;
22.1728 + }
22.1729 +
22.1730 + // US-ASCII only
22.1731 + private static boolean equalIgnoringCase(String s, String t) {
22.1732 + if (s == t) return true;
22.1733 + if ((s != null) && (t != null)) {
22.1734 + int n = s.length();
22.1735 + if (t.length() != n)
22.1736 + return false;
22.1737 + for (int i = 0; i < n; i++) {
22.1738 + if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
22.1739 + return false;
22.1740 + }
22.1741 + return true;
22.1742 + }
22.1743 + return false;
22.1744 + }
22.1745 +
22.1746 + private static int hash(int hash, String s) {
22.1747 + if (s == null) return hash;
22.1748 + return hash * 127 + s.hashCode();
22.1749 + }
22.1750 +
22.1751 + // US-ASCII only
22.1752 + private static int hashIgnoringCase(int hash, String s) {
22.1753 + if (s == null) return hash;
22.1754 + int h = hash;
22.1755 + int n = s.length();
22.1756 + for (int i = 0; i < n; i++)
22.1757 + h = 31 * h + toLower(s.charAt(i));
22.1758 + return h;
22.1759 + }
22.1760 +
22.1761 + private static int compare(String s, String t) {
22.1762 + if (s == t) return 0;
22.1763 + if (s != null) {
22.1764 + if (t != null)
22.1765 + return s.compareTo(t);
22.1766 + else
22.1767 + return +1;
22.1768 + } else {
22.1769 + return -1;
22.1770 + }
22.1771 + }
22.1772 +
22.1773 + // US-ASCII only
22.1774 + private static int compareIgnoringCase(String s, String t) {
22.1775 + if (s == t) return 0;
22.1776 + if (s != null) {
22.1777 + if (t != null) {
22.1778 + int sn = s.length();
22.1779 + int tn = t.length();
22.1780 + int n = sn < tn ? sn : tn;
22.1781 + for (int i = 0; i < n; i++) {
22.1782 + int c = toLower(s.charAt(i)) - toLower(t.charAt(i));
22.1783 + if (c != 0)
22.1784 + return c;
22.1785 + }
22.1786 + return sn - tn;
22.1787 + }
22.1788 + return +1;
22.1789 + } else {
22.1790 + return -1;
22.1791 + }
22.1792 + }
22.1793 +
22.1794 +
22.1795 + // -- String construction --
22.1796 +
22.1797 + // If a scheme is given then the path, if given, must be absolute
22.1798 + //
22.1799 + private static void checkPath(String s, String scheme, String path)
22.1800 + throws URISyntaxException
22.1801 + {
22.1802 + if (scheme != null) {
22.1803 + if ((path != null)
22.1804 + && ((path.length() > 0) && (path.charAt(0) != '/')))
22.1805 + throw new URISyntaxException(s,
22.1806 + "Relative path in absolute URI");
22.1807 + }
22.1808 + }
22.1809 +
22.1810 + private void appendAuthority(StringBuffer sb,
22.1811 + String authority,
22.1812 + String userInfo,
22.1813 + String host,
22.1814 + int port)
22.1815 + {
22.1816 + if (host != null) {
22.1817 + sb.append("//");
22.1818 + if (userInfo != null) {
22.1819 + sb.append(quote(userInfo, L_USERINFO, H_USERINFO));
22.1820 + sb.append('@');
22.1821 + }
22.1822 + boolean needBrackets = ((host.indexOf(':') >= 0)
22.1823 + && !host.startsWith("[")
22.1824 + && !host.endsWith("]"));
22.1825 + if (needBrackets) sb.append('[');
22.1826 + sb.append(host);
22.1827 + if (needBrackets) sb.append(']');
22.1828 + if (port != -1) {
22.1829 + sb.append(':');
22.1830 + sb.append(port);
22.1831 + }
22.1832 + } else if (authority != null) {
22.1833 + sb.append("//");
22.1834 + if (authority.startsWith("[")) {
22.1835 + // authority should (but may not) contain an embedded IPv6 address
22.1836 + int end = authority.indexOf("]");
22.1837 + String doquote = authority, dontquote = "";
22.1838 + if (end != -1 && authority.indexOf(":") != -1) {
22.1839 + // the authority contains an IPv6 address
22.1840 + if (end == authority.length()) {
22.1841 + dontquote = authority;
22.1842 + doquote = "";
22.1843 + } else {
22.1844 + dontquote = authority.substring(0 , end + 1);
22.1845 + doquote = authority.substring(end + 1);
22.1846 + }
22.1847 + }
22.1848 + sb.append(dontquote);
22.1849 + sb.append(quote(doquote,
22.1850 + L_REG_NAME | L_SERVER,
22.1851 + H_REG_NAME | H_SERVER));
22.1852 + } else {
22.1853 + sb.append(quote(authority,
22.1854 + L_REG_NAME | L_SERVER,
22.1855 + H_REG_NAME | H_SERVER));
22.1856 + }
22.1857 + }
22.1858 + }
22.1859 +
22.1860 + private void appendSchemeSpecificPart(StringBuffer sb,
22.1861 + String opaquePart,
22.1862 + String authority,
22.1863 + String userInfo,
22.1864 + String host,
22.1865 + int port,
22.1866 + String path,
22.1867 + String query)
22.1868 + {
22.1869 + if (opaquePart != null) {
22.1870 + /* check if SSP begins with an IPv6 address
22.1871 + * because we must not quote a literal IPv6 address
22.1872 + */
22.1873 + if (opaquePart.startsWith("//[")) {
22.1874 + int end = opaquePart.indexOf("]");
22.1875 + if (end != -1 && opaquePart.indexOf(":")!=-1) {
22.1876 + String doquote, dontquote;
22.1877 + if (end == opaquePart.length()) {
22.1878 + dontquote = opaquePart;
22.1879 + doquote = "";
22.1880 + } else {
22.1881 + dontquote = opaquePart.substring(0,end+1);
22.1882 + doquote = opaquePart.substring(end+1);
22.1883 + }
22.1884 + sb.append (dontquote);
22.1885 + sb.append(quote(doquote, L_URIC, H_URIC));
22.1886 + }
22.1887 + } else {
22.1888 + sb.append(quote(opaquePart, L_URIC, H_URIC));
22.1889 + }
22.1890 + } else {
22.1891 + appendAuthority(sb, authority, userInfo, host, port);
22.1892 + if (path != null)
22.1893 + sb.append(quote(path, L_PATH, H_PATH));
22.1894 + if (query != null) {
22.1895 + sb.append('?');
22.1896 + sb.append(quote(query, L_URIC, H_URIC));
22.1897 + }
22.1898 + }
22.1899 + }
22.1900 +
22.1901 + private void appendFragment(StringBuffer sb, String fragment) {
22.1902 + if (fragment != null) {
22.1903 + sb.append('#');
22.1904 + sb.append(quote(fragment, L_URIC, H_URIC));
22.1905 + }
22.1906 + }
22.1907 +
22.1908 + private String toString(String scheme,
22.1909 + String opaquePart,
22.1910 + String authority,
22.1911 + String userInfo,
22.1912 + String host,
22.1913 + int port,
22.1914 + String path,
22.1915 + String query,
22.1916 + String fragment)
22.1917 + {
22.1918 + StringBuffer sb = new StringBuffer();
22.1919 + if (scheme != null) {
22.1920 + sb.append(scheme);
22.1921 + sb.append(':');
22.1922 + }
22.1923 + appendSchemeSpecificPart(sb, opaquePart,
22.1924 + authority, userInfo, host, port,
22.1925 + path, query);
22.1926 + appendFragment(sb, fragment);
22.1927 + return sb.toString();
22.1928 + }
22.1929 +
22.1930 + private void defineSchemeSpecificPart() {
22.1931 + if (schemeSpecificPart != null) return;
22.1932 + StringBuffer sb = new StringBuffer();
22.1933 + appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
22.1934 + host, port, getPath(), getQuery());
22.1935 + if (sb.length() == 0) return;
22.1936 + schemeSpecificPart = sb.toString();
22.1937 + }
22.1938 +
22.1939 + private void defineString() {
22.1940 + if (string != null) return;
22.1941 +
22.1942 + StringBuffer sb = new StringBuffer();
22.1943 + if (scheme != null) {
22.1944 + sb.append(scheme);
22.1945 + sb.append(':');
22.1946 + }
22.1947 + if (isOpaque()) {
22.1948 + sb.append(schemeSpecificPart);
22.1949 + } else {
22.1950 + if (host != null) {
22.1951 + sb.append("//");
22.1952 + if (userInfo != null) {
22.1953 + sb.append(userInfo);
22.1954 + sb.append('@');
22.1955 + }
22.1956 + boolean needBrackets = ((host.indexOf(':') >= 0)
22.1957 + && !host.startsWith("[")
22.1958 + && !host.endsWith("]"));
22.1959 + if (needBrackets) sb.append('[');
22.1960 + sb.append(host);
22.1961 + if (needBrackets) sb.append(']');
22.1962 + if (port != -1) {
22.1963 + sb.append(':');
22.1964 + sb.append(port);
22.1965 + }
22.1966 + } else if (authority != null) {
22.1967 + sb.append("//");
22.1968 + sb.append(authority);
22.1969 + }
22.1970 + if (path != null)
22.1971 + sb.append(path);
22.1972 + if (query != null) {
22.1973 + sb.append('?');
22.1974 + sb.append(query);
22.1975 + }
22.1976 + }
22.1977 + if (fragment != null) {
22.1978 + sb.append('#');
22.1979 + sb.append(fragment);
22.1980 + }
22.1981 + string = sb.toString();
22.1982 + }
22.1983 +
22.1984 +
22.1985 + // -- Normalization, resolution, and relativization --
22.1986 +
22.1987 + // RFC2396 5.2 (6)
22.1988 + private static String resolvePath(String base, String child,
22.1989 + boolean absolute)
22.1990 + {
22.1991 + int i = base.lastIndexOf('/');
22.1992 + int cn = child.length();
22.1993 + String path = "";
22.1994 +
22.1995 + if (cn == 0) {
22.1996 + // 5.2 (6a)
22.1997 + if (i >= 0)
22.1998 + path = base.substring(0, i + 1);
22.1999 + } else {
22.2000 + StringBuffer sb = new StringBuffer(base.length() + cn);
22.2001 + // 5.2 (6a)
22.2002 + if (i >= 0)
22.2003 + sb.append(base.substring(0, i + 1));
22.2004 + // 5.2 (6b)
22.2005 + sb.append(child);
22.2006 + path = sb.toString();
22.2007 + }
22.2008 +
22.2009 + // 5.2 (6c-f)
22.2010 + String np = normalize(path);
22.2011 +
22.2012 + // 5.2 (6g): If the result is absolute but the path begins with "../",
22.2013 + // then we simply leave the path as-is
22.2014 +
22.2015 + return np;
22.2016 + }
22.2017 +
22.2018 + // RFC2396 5.2
22.2019 + private static URI resolve(URI base, URI child) {
22.2020 + // check if child if opaque first so that NPE is thrown
22.2021 + // if child is null.
22.2022 + if (child.isOpaque() || base.isOpaque())
22.2023 + return child;
22.2024 +
22.2025 + // 5.2 (2): Reference to current document (lone fragment)
22.2026 + if ((child.scheme == null) && (child.authority == null)
22.2027 + && child.path.equals("") && (child.fragment != null)
22.2028 + && (child.query == null)) {
22.2029 + if ((base.fragment != null)
22.2030 + && child.fragment.equals(base.fragment)) {
22.2031 + return base;
22.2032 + }
22.2033 + URI ru = new URI();
22.2034 + ru.scheme = base.scheme;
22.2035 + ru.authority = base.authority;
22.2036 + ru.userInfo = base.userInfo;
22.2037 + ru.host = base.host;
22.2038 + ru.port = base.port;
22.2039 + ru.path = base.path;
22.2040 + ru.fragment = child.fragment;
22.2041 + ru.query = base.query;
22.2042 + return ru;
22.2043 + }
22.2044 +
22.2045 + // 5.2 (3): Child is absolute
22.2046 + if (child.scheme != null)
22.2047 + return child;
22.2048 +
22.2049 + URI ru = new URI(); // Resolved URI
22.2050 + ru.scheme = base.scheme;
22.2051 + ru.query = child.query;
22.2052 + ru.fragment = child.fragment;
22.2053 +
22.2054 + // 5.2 (4): Authority
22.2055 + if (child.authority == null) {
22.2056 + ru.authority = base.authority;
22.2057 + ru.host = base.host;
22.2058 + ru.userInfo = base.userInfo;
22.2059 + ru.port = base.port;
22.2060 +
22.2061 + String cp = (child.path == null) ? "" : child.path;
22.2062 + if ((cp.length() > 0) && (cp.charAt(0) == '/')) {
22.2063 + // 5.2 (5): Child path is absolute
22.2064 + ru.path = child.path;
22.2065 + } else {
22.2066 + // 5.2 (6): Resolve relative path
22.2067 + ru.path = resolvePath(base.path, cp, base.isAbsolute());
22.2068 + }
22.2069 + } else {
22.2070 + ru.authority = child.authority;
22.2071 + ru.host = child.host;
22.2072 + ru.userInfo = child.userInfo;
22.2073 + ru.host = child.host;
22.2074 + ru.port = child.port;
22.2075 + ru.path = child.path;
22.2076 + }
22.2077 +
22.2078 + // 5.2 (7): Recombine (nothing to do here)
22.2079 + return ru;
22.2080 + }
22.2081 +
22.2082 + // If the given URI's path is normal then return the URI;
22.2083 + // o.w., return a new URI containing the normalized path.
22.2084 + //
22.2085 + private static URI normalize(URI u) {
22.2086 + if (u.isOpaque() || (u.path == null) || (u.path.length() == 0))
22.2087 + return u;
22.2088 +
22.2089 + String np = normalize(u.path);
22.2090 + if (np == u.path)
22.2091 + return u;
22.2092 +
22.2093 + URI v = new URI();
22.2094 + v.scheme = u.scheme;
22.2095 + v.fragment = u.fragment;
22.2096 + v.authority = u.authority;
22.2097 + v.userInfo = u.userInfo;
22.2098 + v.host = u.host;
22.2099 + v.port = u.port;
22.2100 + v.path = np;
22.2101 + v.query = u.query;
22.2102 + return v;
22.2103 + }
22.2104 +
22.2105 + // If both URIs are hierarchical, their scheme and authority components are
22.2106 + // identical, and the base path is a prefix of the child's path, then
22.2107 + // return a relative URI that, when resolved against the base, yields the
22.2108 + // child; otherwise, return the child.
22.2109 + //
22.2110 + private static URI relativize(URI base, URI child) {
22.2111 + // check if child if opaque first so that NPE is thrown
22.2112 + // if child is null.
22.2113 + if (child.isOpaque() || base.isOpaque())
22.2114 + return child;
22.2115 + if (!equalIgnoringCase(base.scheme, child.scheme)
22.2116 + || !equal(base.authority, child.authority))
22.2117 + return child;
22.2118 +
22.2119 + String bp = normalize(base.path);
22.2120 + String cp = normalize(child.path);
22.2121 + if (!bp.equals(cp)) {
22.2122 + if (!bp.endsWith("/"))
22.2123 + bp = bp + "/";
22.2124 + if (!cp.startsWith(bp))
22.2125 + return child;
22.2126 + }
22.2127 +
22.2128 + URI v = new URI();
22.2129 + v.path = cp.substring(bp.length());
22.2130 + v.query = child.query;
22.2131 + v.fragment = child.fragment;
22.2132 + return v;
22.2133 + }
22.2134 +
22.2135 +
22.2136 +
22.2137 + // -- Path normalization --
22.2138 +
22.2139 + // The following algorithm for path normalization avoids the creation of a
22.2140 + // string object for each segment, as well as the use of a string buffer to
22.2141 + // compute the final result, by using a single char array and editing it in
22.2142 + // place. The array is first split into segments, replacing each slash
22.2143 + // with '\0' and creating a segment-index array, each element of which is
22.2144 + // the index of the first char in the corresponding segment. We then walk
22.2145 + // through both arrays, removing ".", "..", and other segments as necessary
22.2146 + // by setting their entries in the index array to -1. Finally, the two
22.2147 + // arrays are used to rejoin the segments and compute the final result.
22.2148 + //
22.2149 + // This code is based upon src/solaris/native/java/io/canonicalize_md.c
22.2150 +
22.2151 +
22.2152 + // Check the given path to see if it might need normalization. A path
22.2153 + // might need normalization if it contains duplicate slashes, a "."
22.2154 + // segment, or a ".." segment. Return -1 if no further normalization is
22.2155 + // possible, otherwise return the number of segments found.
22.2156 + //
22.2157 + // This method takes a string argument rather than a char array so that
22.2158 + // this test can be performed without invoking path.toCharArray().
22.2159 + //
22.2160 + static private int needsNormalization(String path) {
22.2161 + boolean normal = true;
22.2162 + int ns = 0; // Number of segments
22.2163 + int end = path.length() - 1; // Index of last char in path
22.2164 + int p = 0; // Index of next char in path
22.2165 +
22.2166 + // Skip initial slashes
22.2167 + while (p <= end) {
22.2168 + if (path.charAt(p) != '/') break;
22.2169 + p++;
22.2170 + }
22.2171 + if (p > 1) normal = false;
22.2172 +
22.2173 + // Scan segments
22.2174 + while (p <= end) {
22.2175 +
22.2176 + // Looking at "." or ".." ?
22.2177 + if ((path.charAt(p) == '.')
22.2178 + && ((p == end)
22.2179 + || ((path.charAt(p + 1) == '/')
22.2180 + || ((path.charAt(p + 1) == '.')
22.2181 + && ((p + 1 == end)
22.2182 + || (path.charAt(p + 2) == '/')))))) {
22.2183 + normal = false;
22.2184 + }
22.2185 + ns++;
22.2186 +
22.2187 + // Find beginning of next segment
22.2188 + while (p <= end) {
22.2189 + if (path.charAt(p++) != '/')
22.2190 + continue;
22.2191 +
22.2192 + // Skip redundant slashes
22.2193 + while (p <= end) {
22.2194 + if (path.charAt(p) != '/') break;
22.2195 + normal = false;
22.2196 + p++;
22.2197 + }
22.2198 +
22.2199 + break;
22.2200 + }
22.2201 + }
22.2202 +
22.2203 + return normal ? -1 : ns;
22.2204 + }
22.2205 +
22.2206 +
22.2207 + // Split the given path into segments, replacing slashes with nulls and
22.2208 + // filling in the given segment-index array.
22.2209 + //
22.2210 + // Preconditions:
22.2211 + // segs.length == Number of segments in path
22.2212 + //
22.2213 + // Postconditions:
22.2214 + // All slashes in path replaced by '\0'
22.2215 + // segs[i] == Index of first char in segment i (0 <= i < segs.length)
22.2216 + //
22.2217 + static private void split(char[] path, int[] segs) {
22.2218 + int end = path.length - 1; // Index of last char in path
22.2219 + int p = 0; // Index of next char in path
22.2220 + int i = 0; // Index of current segment
22.2221 +
22.2222 + // Skip initial slashes
22.2223 + while (p <= end) {
22.2224 + if (path[p] != '/') break;
22.2225 + path[p] = '\0';
22.2226 + p++;
22.2227 + }
22.2228 +
22.2229 + while (p <= end) {
22.2230 +
22.2231 + // Note start of segment
22.2232 + segs[i++] = p++;
22.2233 +
22.2234 + // Find beginning of next segment
22.2235 + while (p <= end) {
22.2236 + if (path[p++] != '/')
22.2237 + continue;
22.2238 + path[p - 1] = '\0';
22.2239 +
22.2240 + // Skip redundant slashes
22.2241 + while (p <= end) {
22.2242 + if (path[p] != '/') break;
22.2243 + path[p++] = '\0';
22.2244 + }
22.2245 + break;
22.2246 + }
22.2247 + }
22.2248 +
22.2249 + if (i != segs.length)
22.2250 + throw new InternalError(); // ASSERT
22.2251 + }
22.2252 +
22.2253 +
22.2254 + // Join the segments in the given path according to the given segment-index
22.2255 + // array, ignoring those segments whose index entries have been set to -1,
22.2256 + // and inserting slashes as needed. Return the length of the resulting
22.2257 + // path.
22.2258 + //
22.2259 + // Preconditions:
22.2260 + // segs[i] == -1 implies segment i is to be ignored
22.2261 + // path computed by split, as above, with '\0' having replaced '/'
22.2262 + //
22.2263 + // Postconditions:
22.2264 + // path[0] .. path[return value] == Resulting path
22.2265 + //
22.2266 + static private int join(char[] path, int[] segs) {
22.2267 + int ns = segs.length; // Number of segments
22.2268 + int end = path.length - 1; // Index of last char in path
22.2269 + int p = 0; // Index of next path char to write
22.2270 +
22.2271 + if (path[p] == '\0') {
22.2272 + // Restore initial slash for absolute paths
22.2273 + path[p++] = '/';
22.2274 + }
22.2275 +
22.2276 + for (int i = 0; i < ns; i++) {
22.2277 + int q = segs[i]; // Current segment
22.2278 + if (q == -1)
22.2279 + // Ignore this segment
22.2280 + continue;
22.2281 +
22.2282 + if (p == q) {
22.2283 + // We're already at this segment, so just skip to its end
22.2284 + while ((p <= end) && (path[p] != '\0'))
22.2285 + p++;
22.2286 + if (p <= end) {
22.2287 + // Preserve trailing slash
22.2288 + path[p++] = '/';
22.2289 + }
22.2290 + } else if (p < q) {
22.2291 + // Copy q down to p
22.2292 + while ((q <= end) && (path[q] != '\0'))
22.2293 + path[p++] = path[q++];
22.2294 + if (q <= end) {
22.2295 + // Preserve trailing slash
22.2296 + path[p++] = '/';
22.2297 + }
22.2298 + } else
22.2299 + throw new InternalError(); // ASSERT false
22.2300 + }
22.2301 +
22.2302 + return p;
22.2303 + }
22.2304 +
22.2305 +
22.2306 + // Remove "." segments from the given path, and remove segment pairs
22.2307 + // consisting of a non-".." segment followed by a ".." segment.
22.2308 + //
22.2309 + private static void removeDots(char[] path, int[] segs) {
22.2310 + int ns = segs.length;
22.2311 + int end = path.length - 1;
22.2312 +
22.2313 + for (int i = 0; i < ns; i++) {
22.2314 + int dots = 0; // Number of dots found (0, 1, or 2)
22.2315 +
22.2316 + // Find next occurrence of "." or ".."
22.2317 + do {
22.2318 + int p = segs[i];
22.2319 + if (path[p] == '.') {
22.2320 + if (p == end) {
22.2321 + dots = 1;
22.2322 + break;
22.2323 + } else if (path[p + 1] == '\0') {
22.2324 + dots = 1;
22.2325 + break;
22.2326 + } else if ((path[p + 1] == '.')
22.2327 + && ((p + 1 == end)
22.2328 + || (path[p + 2] == '\0'))) {
22.2329 + dots = 2;
22.2330 + break;
22.2331 + }
22.2332 + }
22.2333 + i++;
22.2334 + } while (i < ns);
22.2335 + if ((i > ns) || (dots == 0))
22.2336 + break;
22.2337 +
22.2338 + if (dots == 1) {
22.2339 + // Remove this occurrence of "."
22.2340 + segs[i] = -1;
22.2341 + } else {
22.2342 + // If there is a preceding non-".." segment, remove both that
22.2343 + // segment and this occurrence of ".."; otherwise, leave this
22.2344 + // ".." segment as-is.
22.2345 + int j;
22.2346 + for (j = i - 1; j >= 0; j--) {
22.2347 + if (segs[j] != -1) break;
22.2348 + }
22.2349 + if (j >= 0) {
22.2350 + int q = segs[j];
22.2351 + if (!((path[q] == '.')
22.2352 + && (path[q + 1] == '.')
22.2353 + && (path[q + 2] == '\0'))) {
22.2354 + segs[i] = -1;
22.2355 + segs[j] = -1;
22.2356 + }
22.2357 + }
22.2358 + }
22.2359 + }
22.2360 + }
22.2361 +
22.2362 +
22.2363 + // DEVIATION: If the normalized path is relative, and if the first
22.2364 + // segment could be parsed as a scheme name, then prepend a "." segment
22.2365 + //
22.2366 + private static void maybeAddLeadingDot(char[] path, int[] segs) {
22.2367 +
22.2368 + if (path[0] == '\0')
22.2369 + // The path is absolute
22.2370 + return;
22.2371 +
22.2372 + int ns = segs.length;
22.2373 + int f = 0; // Index of first segment
22.2374 + while (f < ns) {
22.2375 + if (segs[f] >= 0)
22.2376 + break;
22.2377 + f++;
22.2378 + }
22.2379 + if ((f >= ns) || (f == 0))
22.2380 + // The path is empty, or else the original first segment survived,
22.2381 + // in which case we already know that no leading "." is needed
22.2382 + return;
22.2383 +
22.2384 + int p = segs[f];
22.2385 + while ((p < path.length) && (path[p] != ':') && (path[p] != '\0')) p++;
22.2386 + if (p >= path.length || path[p] == '\0')
22.2387 + // No colon in first segment, so no "." needed
22.2388 + return;
22.2389 +
22.2390 + // At this point we know that the first segment is unused,
22.2391 + // hence we can insert a "." segment at that position
22.2392 + path[0] = '.';
22.2393 + path[1] = '\0';
22.2394 + segs[0] = 0;
22.2395 + }
22.2396 +
22.2397 +
22.2398 + // Normalize the given path string. A normal path string has no empty
22.2399 + // segments (i.e., occurrences of "//"), no segments equal to ".", and no
22.2400 + // segments equal to ".." that are preceded by a segment not equal to "..".
22.2401 + // In contrast to Unix-style pathname normalization, for URI paths we
22.2402 + // always retain trailing slashes.
22.2403 + //
22.2404 + private static String normalize(String ps) {
22.2405 +
22.2406 + // Does this path need normalization?
22.2407 + int ns = needsNormalization(ps); // Number of segments
22.2408 + if (ns < 0)
22.2409 + // Nope -- just return it
22.2410 + return ps;
22.2411 +
22.2412 + char[] path = ps.toCharArray(); // Path in char-array form
22.2413 +
22.2414 + // Split path into segments
22.2415 + int[] segs = new int[ns]; // Segment-index array
22.2416 + split(path, segs);
22.2417 +
22.2418 + // Remove dots
22.2419 + removeDots(path, segs);
22.2420 +
22.2421 + // Prevent scheme-name confusion
22.2422 + maybeAddLeadingDot(path, segs);
22.2423 +
22.2424 + // Join the remaining segments and return the result
22.2425 + String s = new String(path, 0, join(path, segs));
22.2426 + if (s.equals(ps)) {
22.2427 + // string was already normalized
22.2428 + return ps;
22.2429 + }
22.2430 + return s;
22.2431 + }
22.2432 +
22.2433 +
22.2434 +
22.2435 + // -- Character classes for parsing --
22.2436 +
22.2437 + // RFC2396 precisely specifies which characters in the US-ASCII charset are
22.2438 + // permissible in the various components of a URI reference. We here
22.2439 + // define a set of mask pairs to aid in enforcing these restrictions. Each
22.2440 + // mask pair consists of two longs, a low mask and a high mask. Taken
22.2441 + // together they represent a 128-bit mask, where bit i is set iff the
22.2442 + // character with value i is permitted.
22.2443 + //
22.2444 + // This approach is more efficient than sequentially searching arrays of
22.2445 + // permitted characters. It could be made still more efficient by
22.2446 + // precompiling the mask information so that a character's presence in a
22.2447 + // given mask could be determined by a single table lookup.
22.2448 +
22.2449 + // Compute the low-order mask for the characters in the given string
22.2450 + private static long lowMask(String chars) {
22.2451 + int n = chars.length();
22.2452 + long m = 0;
22.2453 + for (int i = 0; i < n; i++) {
22.2454 + char c = chars.charAt(i);
22.2455 + if (c < 64)
22.2456 + m |= (1L << c);
22.2457 + }
22.2458 + return m;
22.2459 + }
22.2460 +
22.2461 + // Compute the high-order mask for the characters in the given string
22.2462 + private static long highMask(String chars) {
22.2463 + int n = chars.length();
22.2464 + long m = 0;
22.2465 + for (int i = 0; i < n; i++) {
22.2466 + char c = chars.charAt(i);
22.2467 + if ((c >= 64) && (c < 128))
22.2468 + m |= (1L << (c - 64));
22.2469 + }
22.2470 + return m;
22.2471 + }
22.2472 +
22.2473 + // Compute a low-order mask for the characters
22.2474 + // between first and last, inclusive
22.2475 + private static long lowMask(char first, char last) {
22.2476 + long m = 0;
22.2477 + int f = Math.max(Math.min(first, 63), 0);
22.2478 + int l = Math.max(Math.min(last, 63), 0);
22.2479 + for (int i = f; i <= l; i++)
22.2480 + m |= 1L << i;
22.2481 + return m;
22.2482 + }
22.2483 +
22.2484 + // Compute a high-order mask for the characters
22.2485 + // between first and last, inclusive
22.2486 + private static long highMask(char first, char last) {
22.2487 + long m = 0;
22.2488 + int f = Math.max(Math.min(first, 127), 64) - 64;
22.2489 + int l = Math.max(Math.min(last, 127), 64) - 64;
22.2490 + for (int i = f; i <= l; i++)
22.2491 + m |= 1L << i;
22.2492 + return m;
22.2493 + }
22.2494 +
22.2495 + // Tell whether the given character is permitted by the given mask pair
22.2496 + private static boolean match(char c, long lowMask, long highMask) {
22.2497 + if (c == 0) // 0 doesn't have a slot in the mask. So, it never matches.
22.2498 + return false;
22.2499 + if (c < 64)
22.2500 + return ((1L << c) & lowMask) != 0;
22.2501 + if (c < 128)
22.2502 + return ((1L << (c - 64)) & highMask) != 0;
22.2503 + return false;
22.2504 + }
22.2505 +
22.2506 + // Character-class masks, in reverse order from RFC2396 because
22.2507 + // initializers for static fields cannot make forward references.
22.2508 +
22.2509 + // digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
22.2510 + // "8" | "9"
22.2511 + private static final long L_DIGIT = lowMask('0', '9');
22.2512 + private static final long H_DIGIT = 0L;
22.2513 +
22.2514 + // upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
22.2515 + // "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
22.2516 + // "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
22.2517 + private static final long L_UPALPHA = 0L;
22.2518 + private static final long H_UPALPHA = highMask('A', 'Z');
22.2519 +
22.2520 + // lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
22.2521 + // "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
22.2522 + // "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
22.2523 + private static final long L_LOWALPHA = 0L;
22.2524 + private static final long H_LOWALPHA = highMask('a', 'z');
22.2525 +
22.2526 + // alpha = lowalpha | upalpha
22.2527 + private static final long L_ALPHA = L_LOWALPHA | L_UPALPHA;
22.2528 + private static final long H_ALPHA = H_LOWALPHA | H_UPALPHA;
22.2529 +
22.2530 + // alphanum = alpha | digit
22.2531 + private static final long L_ALPHANUM = L_DIGIT | L_ALPHA;
22.2532 + private static final long H_ALPHANUM = H_DIGIT | H_ALPHA;
22.2533 +
22.2534 + // hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
22.2535 + // "a" | "b" | "c" | "d" | "e" | "f"
22.2536 + private static final long L_HEX = L_DIGIT;
22.2537 + private static final long H_HEX = highMask('A', 'F') | highMask('a', 'f');
22.2538 +
22.2539 + // mark = "-" | "_" | "." | "!" | "~" | "*" | "'" |
22.2540 + // "(" | ")"
22.2541 + private static final long L_MARK = lowMask("-_.!~*'()");
22.2542 + private static final long H_MARK = highMask("-_.!~*'()");
22.2543 +
22.2544 + // unreserved = alphanum | mark
22.2545 + private static final long L_UNRESERVED = L_ALPHANUM | L_MARK;
22.2546 + private static final long H_UNRESERVED = H_ALPHANUM | H_MARK;
22.2547 +
22.2548 + // reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
22.2549 + // "$" | "," | "[" | "]"
22.2550 + // Added per RFC2732: "[", "]"
22.2551 + private static final long L_RESERVED = lowMask(";/?:@&=+$,[]");
22.2552 + private static final long H_RESERVED = highMask(";/?:@&=+$,[]");
22.2553 +
22.2554 + // The zero'th bit is used to indicate that escape pairs and non-US-ASCII
22.2555 + // characters are allowed; this is handled by the scanEscape method below.
22.2556 + private static final long L_ESCAPED = 1L;
22.2557 + private static final long H_ESCAPED = 0L;
22.2558 +
22.2559 + // uric = reserved | unreserved | escaped
22.2560 + private static final long L_URIC = L_RESERVED | L_UNRESERVED | L_ESCAPED;
22.2561 + private static final long H_URIC = H_RESERVED | H_UNRESERVED | H_ESCAPED;
22.2562 +
22.2563 + // pchar = unreserved | escaped |
22.2564 + // ":" | "@" | "&" | "=" | "+" | "$" | ","
22.2565 + private static final long L_PCHAR
22.2566 + = L_UNRESERVED | L_ESCAPED | lowMask(":@&=+$,");
22.2567 + private static final long H_PCHAR
22.2568 + = H_UNRESERVED | H_ESCAPED | highMask(":@&=+$,");
22.2569 +
22.2570 + // All valid path characters
22.2571 + private static final long L_PATH = L_PCHAR | lowMask(";/");
22.2572 + private static final long H_PATH = H_PCHAR | highMask(";/");
22.2573 +
22.2574 + // Dash, for use in domainlabel and toplabel
22.2575 + private static final long L_DASH = lowMask("-");
22.2576 + private static final long H_DASH = highMask("-");
22.2577 +
22.2578 + // Dot, for use in hostnames
22.2579 + private static final long L_DOT = lowMask(".");
22.2580 + private static final long H_DOT = highMask(".");
22.2581 +
22.2582 + // userinfo = *( unreserved | escaped |
22.2583 + // ";" | ":" | "&" | "=" | "+" | "$" | "," )
22.2584 + private static final long L_USERINFO
22.2585 + = L_UNRESERVED | L_ESCAPED | lowMask(";:&=+$,");
22.2586 + private static final long H_USERINFO
22.2587 + = H_UNRESERVED | H_ESCAPED | highMask(";:&=+$,");
22.2588 +
22.2589 + // reg_name = 1*( unreserved | escaped | "$" | "," |
22.2590 + // ";" | ":" | "@" | "&" | "=" | "+" )
22.2591 + private static final long L_REG_NAME
22.2592 + = L_UNRESERVED | L_ESCAPED | lowMask("$,;:@&=+");
22.2593 + private static final long H_REG_NAME
22.2594 + = H_UNRESERVED | H_ESCAPED | highMask("$,;:@&=+");
22.2595 +
22.2596 + // All valid characters for server-based authorities
22.2597 + private static final long L_SERVER
22.2598 + = L_USERINFO | L_ALPHANUM | L_DASH | lowMask(".:@[]");
22.2599 + private static final long H_SERVER
22.2600 + = H_USERINFO | H_ALPHANUM | H_DASH | highMask(".:@[]");
22.2601 +
22.2602 + // Special case of server authority that represents an IPv6 address
22.2603 + // In this case, a % does not signify an escape sequence
22.2604 + private static final long L_SERVER_PERCENT
22.2605 + = L_SERVER | lowMask("%");
22.2606 + private static final long H_SERVER_PERCENT
22.2607 + = H_SERVER | highMask("%");
22.2608 + private static final long L_LEFT_BRACKET = lowMask("[");
22.2609 + private static final long H_LEFT_BRACKET = highMask("[");
22.2610 +
22.2611 + // scheme = alpha *( alpha | digit | "+" | "-" | "." )
22.2612 + private static final long L_SCHEME = L_ALPHA | L_DIGIT | lowMask("+-.");
22.2613 + private static final long H_SCHEME = H_ALPHA | H_DIGIT | highMask("+-.");
22.2614 +
22.2615 + // uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
22.2616 + // "&" | "=" | "+" | "$" | ","
22.2617 + private static final long L_URIC_NO_SLASH
22.2618 + = L_UNRESERVED | L_ESCAPED | lowMask(";?:@&=+$,");
22.2619 + private static final long H_URIC_NO_SLASH
22.2620 + = H_UNRESERVED | H_ESCAPED | highMask(";?:@&=+$,");
22.2621 +
22.2622 +
22.2623 + // -- Escaping and encoding --
22.2624 +
22.2625 + private final static char[] hexDigits = {
22.2626 + '0', '1', '2', '3', '4', '5', '6', '7',
22.2627 + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
22.2628 + };
22.2629 +
22.2630 + private static void appendEscape(StringBuffer sb, byte b) {
22.2631 + sb.append('%');
22.2632 + sb.append(hexDigits[(b >> 4) & 0x0f]);
22.2633 + sb.append(hexDigits[(b >> 0) & 0x0f]);
22.2634 + }
22.2635 +
22.2636 + private static void appendEncoded(StringBuffer sb, char c) {
22.2637 + ByteBuffer bb = null;
22.2638 + try {
22.2639 + bb = ThreadLocalCoders.encoderFor("UTF-8")
22.2640 + .encode(CharBuffer.wrap("" + c));
22.2641 + } catch (CharacterCodingException x) {
22.2642 + assert false;
22.2643 + }
22.2644 + while (bb.hasRemaining()) {
22.2645 + int b = bb.get() & 0xff;
22.2646 + if (b >= 0x80)
22.2647 + appendEscape(sb, (byte)b);
22.2648 + else
22.2649 + sb.append((char)b);
22.2650 + }
22.2651 + }
22.2652 +
22.2653 + // Quote any characters in s that are not permitted
22.2654 + // by the given mask pair
22.2655 + //
22.2656 + private static String quote(String s, long lowMask, long highMask) {
22.2657 + int n = s.length();
22.2658 + StringBuffer sb = null;
22.2659 + boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
22.2660 + for (int i = 0; i < s.length(); i++) {
22.2661 + char c = s.charAt(i);
22.2662 + if (c < '\u0080') {
22.2663 + if (!match(c, lowMask, highMask)) {
22.2664 + if (sb == null) {
22.2665 + sb = new StringBuffer();
22.2666 + sb.append(s.substring(0, i));
22.2667 + }
22.2668 + appendEscape(sb, (byte)c);
22.2669 + } else {
22.2670 + if (sb != null)
22.2671 + sb.append(c);
22.2672 + }
22.2673 + } else if (allowNonASCII
22.2674 + && (Character.isSpaceChar(c)
22.2675 + || Character.isISOControl(c))) {
22.2676 + if (sb == null) {
22.2677 + sb = new StringBuffer();
22.2678 + sb.append(s.substring(0, i));
22.2679 + }
22.2680 + appendEncoded(sb, c);
22.2681 + } else {
22.2682 + if (sb != null)
22.2683 + sb.append(c);
22.2684 + }
22.2685 + }
22.2686 + return (sb == null) ? s : sb.toString();
22.2687 + }
22.2688 +
22.2689 + // Encodes all characters >= \u0080 into escaped, normalized UTF-8 octets,
22.2690 + // assuming that s is otherwise legal
22.2691 + //
22.2692 + private static String encode(String s) {
22.2693 + int n = s.length();
22.2694 + if (n == 0)
22.2695 + return s;
22.2696 +
22.2697 + // First check whether we actually need to encode
22.2698 + for (int i = 0;;) {
22.2699 + if (s.charAt(i) >= '\u0080')
22.2700 + break;
22.2701 + if (++i >= n)
22.2702 + return s;
22.2703 + }
22.2704 +
22.2705 + String ns = Normalizer.normalize(s, Normalizer.Form.NFC);
22.2706 + ByteBuffer bb = null;
22.2707 + try {
22.2708 + bb = ThreadLocalCoders.encoderFor("UTF-8")
22.2709 + .encode(CharBuffer.wrap(ns));
22.2710 + } catch (CharacterCodingException x) {
22.2711 + assert false;
22.2712 + }
22.2713 +
22.2714 + StringBuffer sb = new StringBuffer();
22.2715 + while (bb.hasRemaining()) {
22.2716 + int b = bb.get() & 0xff;
22.2717 + if (b >= 0x80)
22.2718 + appendEscape(sb, (byte)b);
22.2719 + else
22.2720 + sb.append((char)b);
22.2721 + }
22.2722 + return sb.toString();
22.2723 + }
22.2724 +
22.2725 + private static int decode(char c) {
22.2726 + if ((c >= '0') && (c <= '9'))
22.2727 + return c - '0';
22.2728 + if ((c >= 'a') && (c <= 'f'))
22.2729 + return c - 'a' + 10;
22.2730 + if ((c >= 'A') && (c <= 'F'))
22.2731 + return c - 'A' + 10;
22.2732 + assert false;
22.2733 + return -1;
22.2734 + }
22.2735 +
22.2736 + private static byte decode(char c1, char c2) {
22.2737 + return (byte)( ((decode(c1) & 0xf) << 4)
22.2738 + | ((decode(c2) & 0xf) << 0));
22.2739 + }
22.2740 +
22.2741 + // Evaluates all escapes in s, applying UTF-8 decoding if needed. Assumes
22.2742 + // that escapes are well-formed syntactically, i.e., of the form %XX. If a
22.2743 + // sequence of escaped octets is not valid UTF-8 then the erroneous octets
22.2744 + // are replaced with '\uFFFD'.
22.2745 + // Exception: any "%" found between "[]" is left alone. It is an IPv6 literal
22.2746 + // with a scope_id
22.2747 + //
22.2748 + private static String decode(String s) {
22.2749 + if (s == null)
22.2750 + return s;
22.2751 + int n = s.length();
22.2752 + if (n == 0)
22.2753 + return s;
22.2754 + if (s.indexOf('%') < 0)
22.2755 + return s;
22.2756 +
22.2757 + StringBuffer sb = new StringBuffer(n);
22.2758 + ByteBuffer bb = ByteBuffer.allocate(n);
22.2759 + CharBuffer cb = CharBuffer.allocate(n);
22.2760 + CharsetDecoder dec = ThreadLocalCoders.decoderFor("UTF-8")
22.2761 + .onMalformedInput(CodingErrorAction.REPLACE)
22.2762 + .onUnmappableCharacter(CodingErrorAction.REPLACE);
22.2763 +
22.2764 + // This is not horribly efficient, but it will do for now
22.2765 + char c = s.charAt(0);
22.2766 + boolean betweenBrackets = false;
22.2767 +
22.2768 + for (int i = 0; i < n;) {
22.2769 + assert c == s.charAt(i); // Loop invariant
22.2770 + if (c == '[') {
22.2771 + betweenBrackets = true;
22.2772 + } else if (betweenBrackets && c == ']') {
22.2773 + betweenBrackets = false;
22.2774 + }
22.2775 + if (c != '%' || betweenBrackets) {
22.2776 + sb.append(c);
22.2777 + if (++i >= n)
22.2778 + break;
22.2779 + c = s.charAt(i);
22.2780 + continue;
22.2781 + }
22.2782 + bb.clear();
22.2783 + int ui = i;
22.2784 + for (;;) {
22.2785 + assert (n - i >= 2);
22.2786 + bb.put(decode(s.charAt(++i), s.charAt(++i)));
22.2787 + if (++i >= n)
22.2788 + break;
22.2789 + c = s.charAt(i);
22.2790 + if (c != '%')
22.2791 + break;
22.2792 + }
22.2793 + bb.flip();
22.2794 + cb.clear();
22.2795 + dec.reset();
22.2796 + CoderResult cr = dec.decode(bb, cb, true);
22.2797 + assert cr.isUnderflow();
22.2798 + cr = dec.flush(cb);
22.2799 + assert cr.isUnderflow();
22.2800 + sb.append(cb.flip().toString());
22.2801 + }
22.2802 +
22.2803 + return sb.toString();
22.2804 + }
22.2805 +
22.2806 +
22.2807 + // -- Parsing --
22.2808 +
22.2809 + // For convenience we wrap the input URI string in a new instance of the
22.2810 + // following internal class. This saves always having to pass the input
22.2811 + // string as an argument to each internal scan/parse method.
22.2812 +
22.2813 + private class Parser {
22.2814 +
22.2815 + private String input; // URI input string
22.2816 + private boolean requireServerAuthority = false;
22.2817 +
22.2818 + Parser(String s) {
22.2819 + input = s;
22.2820 + string = s;
22.2821 + }
22.2822 +
22.2823 + // -- Methods for throwing URISyntaxException in various ways --
22.2824 +
22.2825 + private void fail(String reason) throws URISyntaxException {
22.2826 + throw new URISyntaxException(input, reason);
22.2827 + }
22.2828 +
22.2829 + private void fail(String reason, int p) throws URISyntaxException {
22.2830 + throw new URISyntaxException(input, reason, p);
22.2831 + }
22.2832 +
22.2833 + private void failExpecting(String expected, int p)
22.2834 + throws URISyntaxException
22.2835 + {
22.2836 + fail("Expected " + expected, p);
22.2837 + }
22.2838 +
22.2839 + private void failExpecting(String expected, String prior, int p)
22.2840 + throws URISyntaxException
22.2841 + {
22.2842 + fail("Expected " + expected + " following " + prior, p);
22.2843 + }
22.2844 +
22.2845 +
22.2846 + // -- Simple access to the input string --
22.2847 +
22.2848 + // Return a substring of the input string
22.2849 + //
22.2850 + private String substring(int start, int end) {
22.2851 + return input.substring(start, end);
22.2852 + }
22.2853 +
22.2854 + // Return the char at position p,
22.2855 + // assuming that p < input.length()
22.2856 + //
22.2857 + private char charAt(int p) {
22.2858 + return input.charAt(p);
22.2859 + }
22.2860 +
22.2861 + // Tells whether start < end and, if so, whether charAt(start) == c
22.2862 + //
22.2863 + private boolean at(int start, int end, char c) {
22.2864 + return (start < end) && (charAt(start) == c);
22.2865 + }
22.2866 +
22.2867 + // Tells whether start + s.length() < end and, if so,
22.2868 + // whether the chars at the start position match s exactly
22.2869 + //
22.2870 + private boolean at(int start, int end, String s) {
22.2871 + int p = start;
22.2872 + int sn = s.length();
22.2873 + if (sn > end - p)
22.2874 + return false;
22.2875 + int i = 0;
22.2876 + while (i < sn) {
22.2877 + if (charAt(p++) != s.charAt(i)) {
22.2878 + break;
22.2879 + }
22.2880 + i++;
22.2881 + }
22.2882 + return (i == sn);
22.2883 + }
22.2884 +
22.2885 +
22.2886 + // -- Scanning --
22.2887 +
22.2888 + // The various scan and parse methods that follow use a uniform
22.2889 + // convention of taking the current start position and end index as
22.2890 + // their first two arguments. The start is inclusive while the end is
22.2891 + // exclusive, just as in the String class, i.e., a start/end pair
22.2892 + // denotes the left-open interval [start, end) of the input string.
22.2893 + //
22.2894 + // These methods never proceed past the end position. They may return
22.2895 + // -1 to indicate outright failure, but more often they simply return
22.2896 + // the position of the first char after the last char scanned. Thus
22.2897 + // a typical idiom is
22.2898 + //
22.2899 + // int p = start;
22.2900 + // int q = scan(p, end, ...);
22.2901 + // if (q > p)
22.2902 + // // We scanned something
22.2903 + // ...;
22.2904 + // else if (q == p)
22.2905 + // // We scanned nothing
22.2906 + // ...;
22.2907 + // else if (q == -1)
22.2908 + // // Something went wrong
22.2909 + // ...;
22.2910 +
22.2911 +
22.2912 + // Scan a specific char: If the char at the given start position is
22.2913 + // equal to c, return the index of the next char; otherwise, return the
22.2914 + // start position.
22.2915 + //
22.2916 + private int scan(int start, int end, char c) {
22.2917 + if ((start < end) && (charAt(start) == c))
22.2918 + return start + 1;
22.2919 + return start;
22.2920 + }
22.2921 +
22.2922 + // Scan forward from the given start position. Stop at the first char
22.2923 + // in the err string (in which case -1 is returned), or the first char
22.2924 + // in the stop string (in which case the index of the preceding char is
22.2925 + // returned), or the end of the input string (in which case the length
22.2926 + // of the input string is returned). May return the start position if
22.2927 + // nothing matches.
22.2928 + //
22.2929 + private int scan(int start, int end, String err, String stop) {
22.2930 + int p = start;
22.2931 + while (p < end) {
22.2932 + char c = charAt(p);
22.2933 + if (err.indexOf(c) >= 0)
22.2934 + return -1;
22.2935 + if (stop.indexOf(c) >= 0)
22.2936 + break;
22.2937 + p++;
22.2938 + }
22.2939 + return p;
22.2940 + }
22.2941 +
22.2942 + // Scan a potential escape sequence, starting at the given position,
22.2943 + // with the given first char (i.e., charAt(start) == c).
22.2944 + //
22.2945 + // This method assumes that if escapes are allowed then visible
22.2946 + // non-US-ASCII chars are also allowed.
22.2947 + //
22.2948 + private int scanEscape(int start, int n, char first)
22.2949 + throws URISyntaxException
22.2950 + {
22.2951 + int p = start;
22.2952 + char c = first;
22.2953 + if (c == '%') {
22.2954 + // Process escape pair
22.2955 + if ((p + 3 <= n)
22.2956 + && match(charAt(p + 1), L_HEX, H_HEX)
22.2957 + && match(charAt(p + 2), L_HEX, H_HEX)) {
22.2958 + return p + 3;
22.2959 + }
22.2960 + fail("Malformed escape pair", p);
22.2961 + } else if ((c > 128)
22.2962 + && !Character.isSpaceChar(c)
22.2963 + && !Character.isISOControl(c)) {
22.2964 + // Allow unescaped but visible non-US-ASCII chars
22.2965 + return p + 1;
22.2966 + }
22.2967 + return p;
22.2968 + }
22.2969 +
22.2970 + // Scan chars that match the given mask pair
22.2971 + //
22.2972 + private int scan(int start, int n, long lowMask, long highMask)
22.2973 + throws URISyntaxException
22.2974 + {
22.2975 + int p = start;
22.2976 + while (p < n) {
22.2977 + char c = charAt(p);
22.2978 + if (match(c, lowMask, highMask)) {
22.2979 + p++;
22.2980 + continue;
22.2981 + }
22.2982 + if ((lowMask & L_ESCAPED) != 0) {
22.2983 + int q = scanEscape(p, n, c);
22.2984 + if (q > p) {
22.2985 + p = q;
22.2986 + continue;
22.2987 + }
22.2988 + }
22.2989 + break;
22.2990 + }
22.2991 + return p;
22.2992 + }
22.2993 +
22.2994 + // Check that each of the chars in [start, end) matches the given mask
22.2995 + //
22.2996 + private void checkChars(int start, int end,
22.2997 + long lowMask, long highMask,
22.2998 + String what)
22.2999 + throws URISyntaxException
22.3000 + {
22.3001 + int p = scan(start, end, lowMask, highMask);
22.3002 + if (p < end)
22.3003 + fail("Illegal character in " + what, p);
22.3004 + }
22.3005 +
22.3006 + // Check that the char at position p matches the given mask
22.3007 + //
22.3008 + private void checkChar(int p,
22.3009 + long lowMask, long highMask,
22.3010 + String what)
22.3011 + throws URISyntaxException
22.3012 + {
22.3013 + checkChars(p, p + 1, lowMask, highMask, what);
22.3014 + }
22.3015 +
22.3016 +
22.3017 + // -- Parsing --
22.3018 +
22.3019 + // [<scheme>:]<scheme-specific-part>[#<fragment>]
22.3020 + //
22.3021 + void parse(boolean rsa) throws URISyntaxException {
22.3022 + requireServerAuthority = rsa;
22.3023 + int ssp; // Start of scheme-specific part
22.3024 + int n = input.length();
22.3025 + int p = scan(0, n, "/?#", ":");
22.3026 + if ((p >= 0) && at(p, n, ':')) {
22.3027 + if (p == 0)
22.3028 + failExpecting("scheme name", 0);
22.3029 + checkChar(0, L_ALPHA, H_ALPHA, "scheme name");
22.3030 + checkChars(1, p, L_SCHEME, H_SCHEME, "scheme name");
22.3031 + scheme = substring(0, p);
22.3032 + p++; // Skip ':'
22.3033 + ssp = p;
22.3034 + if (at(p, n, '/')) {
22.3035 + p = parseHierarchical(p, n);
22.3036 + } else {
22.3037 + int q = scan(p, n, "", "#");
22.3038 + if (q <= p)
22.3039 + failExpecting("scheme-specific part", p);
22.3040 + checkChars(p, q, L_URIC, H_URIC, "opaque part");
22.3041 + p = q;
22.3042 + }
22.3043 + } else {
22.3044 + ssp = 0;
22.3045 + p = parseHierarchical(0, n);
22.3046 + }
22.3047 + schemeSpecificPart = substring(ssp, p);
22.3048 + if (at(p, n, '#')) {
22.3049 + checkChars(p + 1, n, L_URIC, H_URIC, "fragment");
22.3050 + fragment = substring(p + 1, n);
22.3051 + p = n;
22.3052 + }
22.3053 + if (p < n)
22.3054 + fail("end of URI", p);
22.3055 + }
22.3056 +
22.3057 + // [//authority]<path>[?<query>]
22.3058 + //
22.3059 + // DEVIATION from RFC2396: We allow an empty authority component as
22.3060 + // long as it's followed by a non-empty path, query component, or
22.3061 + // fragment component. This is so that URIs such as "file:///foo/bar"
22.3062 + // will parse. This seems to be the intent of RFC2396, though the
22.3063 + // grammar does not permit it. If the authority is empty then the
22.3064 + // userInfo, host, and port components are undefined.
22.3065 + //
22.3066 + // DEVIATION from RFC2396: We allow empty relative paths. This seems
22.3067 + // to be the intent of RFC2396, but the grammar does not permit it.
22.3068 + // The primary consequence of this deviation is that "#f" parses as a
22.3069 + // relative URI with an empty path.
22.3070 + //
22.3071 + private int parseHierarchical(int start, int n)
22.3072 + throws URISyntaxException
22.3073 + {
22.3074 + int p = start;
22.3075 + if (at(p, n, '/') && at(p + 1, n, '/')) {
22.3076 + p += 2;
22.3077 + int q = scan(p, n, "", "/?#");
22.3078 + if (q > p) {
22.3079 + p = parseAuthority(p, q);
22.3080 + } else if (q < n) {
22.3081 + // DEVIATION: Allow empty authority prior to non-empty
22.3082 + // path, query component or fragment identifier
22.3083 + } else
22.3084 + failExpecting("authority", p);
22.3085 + }
22.3086 + int q = scan(p, n, "", "?#"); // DEVIATION: May be empty
22.3087 + checkChars(p, q, L_PATH, H_PATH, "path");
22.3088 + path = substring(p, q);
22.3089 + p = q;
22.3090 + if (at(p, n, '?')) {
22.3091 + p++;
22.3092 + q = scan(p, n, "", "#");
22.3093 + checkChars(p, q, L_URIC, H_URIC, "query");
22.3094 + query = substring(p, q);
22.3095 + p = q;
22.3096 + }
22.3097 + return p;
22.3098 + }
22.3099 +
22.3100 + // authority = server | reg_name
22.3101 + //
22.3102 + // Ambiguity: An authority that is a registry name rather than a server
22.3103 + // might have a prefix that parses as a server. We use the fact that
22.3104 + // the authority component is always followed by '/' or the end of the
22.3105 + // input string to resolve this: If the complete authority did not
22.3106 + // parse as a server then we try to parse it as a registry name.
22.3107 + //
22.3108 + private int parseAuthority(int start, int n)
22.3109 + throws URISyntaxException
22.3110 + {
22.3111 + int p = start;
22.3112 + int q = p;
22.3113 + URISyntaxException ex = null;
22.3114 +
22.3115 + boolean serverChars;
22.3116 + boolean regChars;
22.3117 +
22.3118 + if (scan(p, n, "", "]") > p) {
22.3119 + // contains a literal IPv6 address, therefore % is allowed
22.3120 + serverChars = (scan(p, n, L_SERVER_PERCENT, H_SERVER_PERCENT) == n);
22.3121 + } else {
22.3122 + serverChars = (scan(p, n, L_SERVER, H_SERVER) == n);
22.3123 + }
22.3124 + regChars = (scan(p, n, L_REG_NAME, H_REG_NAME) == n);
22.3125 +
22.3126 + if (regChars && !serverChars) {
22.3127 + // Must be a registry-based authority
22.3128 + authority = substring(p, n);
22.3129 + return n;
22.3130 + }
22.3131 +
22.3132 + if (serverChars) {
22.3133 + // Might be (probably is) a server-based authority, so attempt
22.3134 + // to parse it as such. If the attempt fails, try to treat it
22.3135 + // as a registry-based authority.
22.3136 + try {
22.3137 + q = parseServer(p, n);
22.3138 + if (q < n)
22.3139 + failExpecting("end of authority", q);
22.3140 + authority = substring(p, n);
22.3141 + } catch (URISyntaxException x) {
22.3142 + // Undo results of failed parse
22.3143 + userInfo = null;
22.3144 + host = null;
22.3145 + port = -1;
22.3146 + if (requireServerAuthority) {
22.3147 + // If we're insisting upon a server-based authority,
22.3148 + // then just re-throw the exception
22.3149 + throw x;
22.3150 + } else {
22.3151 + // Save the exception in case it doesn't parse as a
22.3152 + // registry either
22.3153 + ex = x;
22.3154 + q = p;
22.3155 + }
22.3156 + }
22.3157 + }
22.3158 +
22.3159 + if (q < n) {
22.3160 + if (regChars) {
22.3161 + // Registry-based authority
22.3162 + authority = substring(p, n);
22.3163 + } else if (ex != null) {
22.3164 + // Re-throw exception; it was probably due to
22.3165 + // a malformed IPv6 address
22.3166 + throw ex;
22.3167 + } else {
22.3168 + fail("Illegal character in authority", q);
22.3169 + }
22.3170 + }
22.3171 +
22.3172 + return n;
22.3173 + }
22.3174 +
22.3175 +
22.3176 + // [<userinfo>@]<host>[:<port>]
22.3177 + //
22.3178 + private int parseServer(int start, int n)
22.3179 + throws URISyntaxException
22.3180 + {
22.3181 + int p = start;
22.3182 + int q;
22.3183 +
22.3184 + // userinfo
22.3185 + q = scan(p, n, "/?#", "@");
22.3186 + if ((q >= p) && at(q, n, '@')) {
22.3187 + checkChars(p, q, L_USERINFO, H_USERINFO, "user info");
22.3188 + userInfo = substring(p, q);
22.3189 + p = q + 1; // Skip '@'
22.3190 + }
22.3191 +
22.3192 + // hostname, IPv4 address, or IPv6 address
22.3193 + if (at(p, n, '[')) {
22.3194 + // DEVIATION from RFC2396: Support IPv6 addresses, per RFC2732
22.3195 + p++;
22.3196 + q = scan(p, n, "/?#", "]");
22.3197 + if ((q > p) && at(q, n, ']')) {
22.3198 + // look for a "%" scope id
22.3199 + int r = scan (p, q, "", "%");
22.3200 + if (r > p) {
22.3201 + parseIPv6Reference(p, r);
22.3202 + if (r+1 == q) {
22.3203 + fail ("scope id expected");
22.3204 + }
22.3205 + checkChars (r+1, q, L_ALPHANUM, H_ALPHANUM,
22.3206 + "scope id");
22.3207 + } else {
22.3208 + parseIPv6Reference(p, q);
22.3209 + }
22.3210 + host = substring(p-1, q+1);
22.3211 + p = q + 1;
22.3212 + } else {
22.3213 + failExpecting("closing bracket for IPv6 address", q);
22.3214 + }
22.3215 + } else {
22.3216 + q = parseIPv4Address(p, n);
22.3217 + if (q <= p)
22.3218 + q = parseHostname(p, n);
22.3219 + p = q;
22.3220 + }
22.3221 +
22.3222 + // port
22.3223 + if (at(p, n, ':')) {
22.3224 + p++;
22.3225 + q = scan(p, n, "", "/");
22.3226 + if (q > p) {
22.3227 + checkChars(p, q, L_DIGIT, H_DIGIT, "port number");
22.3228 + try {
22.3229 + port = Integer.parseInt(substring(p, q));
22.3230 + } catch (NumberFormatException x) {
22.3231 + fail("Malformed port number", p);
22.3232 + }
22.3233 + p = q;
22.3234 + }
22.3235 + }
22.3236 + if (p < n)
22.3237 + failExpecting("port number", p);
22.3238 +
22.3239 + return p;
22.3240 + }
22.3241 +
22.3242 + // Scan a string of decimal digits whose value fits in a byte
22.3243 + //
22.3244 + private int scanByte(int start, int n)
22.3245 + throws URISyntaxException
22.3246 + {
22.3247 + int p = start;
22.3248 + int q = scan(p, n, L_DIGIT, H_DIGIT);
22.3249 + if (q <= p) return q;
22.3250 + if (Integer.parseInt(substring(p, q)) > 255) return p;
22.3251 + return q;
22.3252 + }
22.3253 +
22.3254 + // Scan an IPv4 address.
22.3255 + //
22.3256 + // If the strict argument is true then we require that the given
22.3257 + // interval contain nothing besides an IPv4 address; if it is false
22.3258 + // then we only require that it start with an IPv4 address.
22.3259 + //
22.3260 + // If the interval does not contain or start with (depending upon the
22.3261 + // strict argument) a legal IPv4 address characters then we return -1
22.3262 + // immediately; otherwise we insist that these characters parse as a
22.3263 + // legal IPv4 address and throw an exception on failure.
22.3264 + //
22.3265 + // We assume that any string of decimal digits and dots must be an IPv4
22.3266 + // address. It won't parse as a hostname anyway, so making that
22.3267 + // assumption here allows more meaningful exceptions to be thrown.
22.3268 + //
22.3269 + private int scanIPv4Address(int start, int n, boolean strict)
22.3270 + throws URISyntaxException
22.3271 + {
22.3272 + int p = start;
22.3273 + int q;
22.3274 + int m = scan(p, n, L_DIGIT | L_DOT, H_DIGIT | H_DOT);
22.3275 + if ((m <= p) || (strict && (m != n)))
22.3276 + return -1;
22.3277 + for (;;) {
22.3278 + // Per RFC2732: At most three digits per byte
22.3279 + // Further constraint: Each element fits in a byte
22.3280 + if ((q = scanByte(p, m)) <= p) break; p = q;
22.3281 + if ((q = scan(p, m, '.')) <= p) break; p = q;
22.3282 + if ((q = scanByte(p, m)) <= p) break; p = q;
22.3283 + if ((q = scan(p, m, '.')) <= p) break; p = q;
22.3284 + if ((q = scanByte(p, m)) <= p) break; p = q;
22.3285 + if ((q = scan(p, m, '.')) <= p) break; p = q;
22.3286 + if ((q = scanByte(p, m)) <= p) break; p = q;
22.3287 + if (q < m) break;
22.3288 + return q;
22.3289 + }
22.3290 + fail("Malformed IPv4 address", q);
22.3291 + return -1;
22.3292 + }
22.3293 +
22.3294 + // Take an IPv4 address: Throw an exception if the given interval
22.3295 + // contains anything except an IPv4 address
22.3296 + //
22.3297 + private int takeIPv4Address(int start, int n, String expected)
22.3298 + throws URISyntaxException
22.3299 + {
22.3300 + int p = scanIPv4Address(start, n, true);
22.3301 + if (p <= start)
22.3302 + failExpecting(expected, start);
22.3303 + return p;
22.3304 + }
22.3305 +
22.3306 + // Attempt to parse an IPv4 address, returning -1 on failure but
22.3307 + // allowing the given interval to contain [:<characters>] after
22.3308 + // the IPv4 address.
22.3309 + //
22.3310 + private int parseIPv4Address(int start, int n) {
22.3311 + int p;
22.3312 +
22.3313 + try {
22.3314 + p = scanIPv4Address(start, n, false);
22.3315 + } catch (URISyntaxException x) {
22.3316 + return -1;
22.3317 + } catch (NumberFormatException nfe) {
22.3318 + return -1;
22.3319 + }
22.3320 +
22.3321 + if (p > start && p < n) {
22.3322 + // IPv4 address is followed by something - check that
22.3323 + // it's a ":" as this is the only valid character to
22.3324 + // follow an address.
22.3325 + if (charAt(p) != ':') {
22.3326 + p = -1;
22.3327 + }
22.3328 + }
22.3329 +
22.3330 + if (p > start)
22.3331 + host = substring(start, p);
22.3332 +
22.3333 + return p;
22.3334 + }
22.3335 +
22.3336 + // hostname = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
22.3337 + // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
22.3338 + // toplabel = alpha | alpha *( alphanum | "-" ) alphanum
22.3339 + //
22.3340 + private int parseHostname(int start, int n)
22.3341 + throws URISyntaxException
22.3342 + {
22.3343 + int p = start;
22.3344 + int q;
22.3345 + int l = -1; // Start of last parsed label
22.3346 +
22.3347 + do {
22.3348 + // domainlabel = alphanum [ *( alphanum | "-" ) alphanum ]
22.3349 + q = scan(p, n, L_ALPHANUM, H_ALPHANUM);
22.3350 + if (q <= p)
22.3351 + break;
22.3352 + l = p;
22.3353 + if (q > p) {
22.3354 + p = q;
22.3355 + q = scan(p, n, L_ALPHANUM | L_DASH, H_ALPHANUM | H_DASH);
22.3356 + if (q > p) {
22.3357 + if (charAt(q - 1) == '-')
22.3358 + fail("Illegal character in hostname", q - 1);
22.3359 + p = q;
22.3360 + }
22.3361 + }
22.3362 + q = scan(p, n, '.');
22.3363 + if (q <= p)
22.3364 + break;
22.3365 + p = q;
22.3366 + } while (p < n);
22.3367 +
22.3368 + if ((p < n) && !at(p, n, ':'))
22.3369 + fail("Illegal character in hostname", p);
22.3370 +
22.3371 + if (l < 0)
22.3372 + failExpecting("hostname", start);
22.3373 +
22.3374 + // for a fully qualified hostname check that the rightmost
22.3375 + // label starts with an alpha character.
22.3376 + if (l > start && !match(charAt(l), L_ALPHA, H_ALPHA)) {
22.3377 + fail("Illegal character in hostname", l);
22.3378 + }
22.3379 +
22.3380 + host = substring(start, p);
22.3381 + return p;
22.3382 + }
22.3383 +
22.3384 +
22.3385 + // IPv6 address parsing, from RFC2373: IPv6 Addressing Architecture
22.3386 + //
22.3387 + // Bug: The grammar in RFC2373 Appendix B does not allow addresses of
22.3388 + // the form ::12.34.56.78, which are clearly shown in the examples
22.3389 + // earlier in the document. Here is the original grammar:
22.3390 + //
22.3391 + // IPv6address = hexpart [ ":" IPv4address ]
22.3392 + // hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
22.3393 + // hexseq = hex4 *( ":" hex4)
22.3394 + // hex4 = 1*4HEXDIG
22.3395 + //
22.3396 + // We therefore use the following revised grammar:
22.3397 + //
22.3398 + // IPv6address = hexseq [ ":" IPv4address ]
22.3399 + // | hexseq [ "::" [ hexpost ] ]
22.3400 + // | "::" [ hexpost ]
22.3401 + // hexpost = hexseq | hexseq ":" IPv4address | IPv4address
22.3402 + // hexseq = hex4 *( ":" hex4)
22.3403 + // hex4 = 1*4HEXDIG
22.3404 + //
22.3405 + // This covers all and only the following cases:
22.3406 + //
22.3407 + // hexseq
22.3408 + // hexseq : IPv4address
22.3409 + // hexseq ::
22.3410 + // hexseq :: hexseq
22.3411 + // hexseq :: hexseq : IPv4address
22.3412 + // hexseq :: IPv4address
22.3413 + // :: hexseq
22.3414 + // :: hexseq : IPv4address
22.3415 + // :: IPv4address
22.3416 + // ::
22.3417 + //
22.3418 + // Additionally we constrain the IPv6 address as follows :-
22.3419 + //
22.3420 + // i. IPv6 addresses without compressed zeros should contain
22.3421 + // exactly 16 bytes.
22.3422 + //
22.3423 + // ii. IPv6 addresses with compressed zeros should contain
22.3424 + // less than 16 bytes.
22.3425 +
22.3426 + private int ipv6byteCount = 0;
22.3427 +
22.3428 + private int parseIPv6Reference(int start, int n)
22.3429 + throws URISyntaxException
22.3430 + {
22.3431 + int p = start;
22.3432 + int q;
22.3433 + boolean compressedZeros = false;
22.3434 +
22.3435 + q = scanHexSeq(p, n);
22.3436 +
22.3437 + if (q > p) {
22.3438 + p = q;
22.3439 + if (at(p, n, "::")) {
22.3440 + compressedZeros = true;
22.3441 + p = scanHexPost(p + 2, n);
22.3442 + } else if (at(p, n, ':')) {
22.3443 + p = takeIPv4Address(p + 1, n, "IPv4 address");
22.3444 + ipv6byteCount += 4;
22.3445 + }
22.3446 + } else if (at(p, n, "::")) {
22.3447 + compressedZeros = true;
22.3448 + p = scanHexPost(p + 2, n);
22.3449 + }
22.3450 + if (p < n)
22.3451 + fail("Malformed IPv6 address", start);
22.3452 + if (ipv6byteCount > 16)
22.3453 + fail("IPv6 address too long", start);
22.3454 + if (!compressedZeros && ipv6byteCount < 16)
22.3455 + fail("IPv6 address too short", start);
22.3456 + if (compressedZeros && ipv6byteCount == 16)
22.3457 + fail("Malformed IPv6 address", start);
22.3458 +
22.3459 + return p;
22.3460 + }
22.3461 +
22.3462 + private int scanHexPost(int start, int n)
22.3463 + throws URISyntaxException
22.3464 + {
22.3465 + int p = start;
22.3466 + int q;
22.3467 +
22.3468 + if (p == n)
22.3469 + return p;
22.3470 +
22.3471 + q = scanHexSeq(p, n);
22.3472 + if (q > p) {
22.3473 + p = q;
22.3474 + if (at(p, n, ':')) {
22.3475 + p++;
22.3476 + p = takeIPv4Address(p, n, "hex digits or IPv4 address");
22.3477 + ipv6byteCount += 4;
22.3478 + }
22.3479 + } else {
22.3480 + p = takeIPv4Address(p, n, "hex digits or IPv4 address");
22.3481 + ipv6byteCount += 4;
22.3482 + }
22.3483 + return p;
22.3484 + }
22.3485 +
22.3486 + // Scan a hex sequence; return -1 if one could not be scanned
22.3487 + //
22.3488 + private int scanHexSeq(int start, int n)
22.3489 + throws URISyntaxException
22.3490 + {
22.3491 + int p = start;
22.3492 + int q;
22.3493 +
22.3494 + q = scan(p, n, L_HEX, H_HEX);
22.3495 + if (q <= p)
22.3496 + return -1;
22.3497 + if (at(q, n, '.')) // Beginning of IPv4 address
22.3498 + return -1;
22.3499 + if (q > p + 4)
22.3500 + fail("IPv6 hexadecimal digit sequence too long", p);
22.3501 + ipv6byteCount += 2;
22.3502 + p = q;
22.3503 + while (p < n) {
22.3504 + if (!at(p, n, ':'))
22.3505 + break;
22.3506 + if (at(p + 1, n, ':'))
22.3507 + break; // "::"
22.3508 + p++;
22.3509 + q = scan(p, n, L_HEX, H_HEX);
22.3510 + if (q <= p)
22.3511 + failExpecting("digits for an IPv6 address", p);
22.3512 + if (at(q, n, '.')) { // Beginning of IPv4 address
22.3513 + p--;
22.3514 + break;
22.3515 + }
22.3516 + if (q > p + 4)
22.3517 + fail("IPv6 hexadecimal digit sequence too long", p);
22.3518 + ipv6byteCount += 2;
22.3519 + p = q;
22.3520 + }
22.3521 +
22.3522 + return p;
22.3523 + }
22.3524 +
22.3525 + }
22.3526 +
22.3527 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/emul/compact/src/main/java/java/net/URISyntaxException.java Sat Sep 07 13:51:24 2013 +0200
23.3 @@ -0,0 +1,135 @@
23.4 +/*
23.5 + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
23.7 + *
23.8 + * This code is free software; you can redistribute it and/or modify it
23.9 + * under the terms of the GNU General Public License version 2 only, as
23.10 + * published by the Free Software Foundation. Oracle designates this
23.11 + * particular file as subject to the "Classpath" exception as provided
23.12 + * by Oracle in the LICENSE file that accompanied this code.
23.13 + *
23.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
23.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23.17 + * version 2 for more details (a copy is included in the LICENSE file that
23.18 + * accompanied this code).
23.19 + *
23.20 + * You should have received a copy of the GNU General Public License version
23.21 + * 2 along with this work; if not, write to the Free Software Foundation,
23.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23.23 + *
23.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23.25 + * or visit www.oracle.com if you need additional information or have any
23.26 + * questions.
23.27 + */
23.28 +
23.29 +package java.net;
23.30 +
23.31 +
23.32 +/**
23.33 + * Checked exception thrown to indicate that a string could not be parsed as a
23.34 + * URI reference.
23.35 + *
23.36 + * @author Mark Reinhold
23.37 + * @see URI
23.38 + * @since 1.4
23.39 + */
23.40 +
23.41 +public class URISyntaxException
23.42 + extends Exception
23.43 +{
23.44 + private static final long serialVersionUID = 2137979680897488891L;
23.45 +
23.46 + private String input;
23.47 + private int index;
23.48 +
23.49 + /**
23.50 + * Constructs an instance from the given input string, reason, and error
23.51 + * index.
23.52 + *
23.53 + * @param input The input string
23.54 + * @param reason A string explaining why the input could not be parsed
23.55 + * @param index The index at which the parse error occurred,
23.56 + * or <tt>-1</tt> if the index is not known
23.57 + *
23.58 + * @throws NullPointerException
23.59 + * If either the input or reason strings are <tt>null</tt>
23.60 + *
23.61 + * @throws IllegalArgumentException
23.62 + * If the error index is less than <tt>-1</tt>
23.63 + */
23.64 + public URISyntaxException(String input, String reason, int index) {
23.65 + super(reason);
23.66 + if ((input == null) || (reason == null))
23.67 + throw new NullPointerException();
23.68 + if (index < -1)
23.69 + throw new IllegalArgumentException();
23.70 + this.input = input;
23.71 + this.index = index;
23.72 + }
23.73 +
23.74 + /**
23.75 + * Constructs an instance from the given input string and reason. The
23.76 + * resulting object will have an error index of <tt>-1</tt>.
23.77 + *
23.78 + * @param input The input string
23.79 + * @param reason A string explaining why the input could not be parsed
23.80 + *
23.81 + * @throws NullPointerException
23.82 + * If either the input or reason strings are <tt>null</tt>
23.83 + */
23.84 + public URISyntaxException(String input, String reason) {
23.85 + this(input, reason, -1);
23.86 + }
23.87 +
23.88 + /**
23.89 + * Returns the input string.
23.90 + *
23.91 + * @return The input string
23.92 + */
23.93 + public String getInput() {
23.94 + return input;
23.95 + }
23.96 +
23.97 + /**
23.98 + * Returns a string explaining why the input string could not be parsed.
23.99 + *
23.100 + * @return The reason string
23.101 + */
23.102 + public String getReason() {
23.103 + return super.getMessage();
23.104 + }
23.105 +
23.106 + /**
23.107 + * Returns an index into the input string of the position at which the
23.108 + * parse error occurred, or <tt>-1</tt> if this position is not known.
23.109 + *
23.110 + * @return The error index
23.111 + */
23.112 + public int getIndex() {
23.113 + return index;
23.114 + }
23.115 +
23.116 + /**
23.117 + * Returns a string describing the parse error. The resulting string
23.118 + * consists of the reason string followed by a colon character
23.119 + * (<tt>':'</tt>), a space, and the input string. If the error index is
23.120 + * defined then the string <tt>" at index "</tt> followed by the index, in
23.121 + * decimal, is inserted after the reason string and before the colon
23.122 + * character.
23.123 + *
23.124 + * @return A string describing the parse error
23.125 + */
23.126 + public String getMessage() {
23.127 + StringBuffer sb = new StringBuffer();
23.128 + sb.append(getReason());
23.129 + if (index > -1) {
23.130 + sb.append(" at index ");
23.131 + sb.append(index);
23.132 + }
23.133 + sb.append(": ");
23.134 + sb.append(input);
23.135 + return sb.toString();
23.136 + }
23.137 +
23.138 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/emul/compact/src/main/java/java/util/IdentityHashMap.java Sat Sep 07 13:51:24 2013 +0200
24.3 @@ -0,0 +1,1243 @@
24.4 +/*
24.5 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
24.7 + *
24.8 + * This code is free software; you can redistribute it and/or modify it
24.9 + * under the terms of the GNU General Public License version 2 only, as
24.10 + * published by the Free Software Foundation. Oracle designates this
24.11 + * particular file as subject to the "Classpath" exception as provided
24.12 + * by Oracle in the LICENSE file that accompanied this code.
24.13 + *
24.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
24.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24.17 + * version 2 for more details (a copy is included in the LICENSE file that
24.18 + * accompanied this code).
24.19 + *
24.20 + * You should have received a copy of the GNU General Public License version
24.21 + * 2 along with this work; if not, write to the Free Software Foundation,
24.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24.23 + *
24.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
24.25 + * or visit www.oracle.com if you need additional information or have any
24.26 + * questions.
24.27 + */
24.28 +
24.29 +package java.util;
24.30 +import java.io.*;
24.31 +
24.32 +/**
24.33 + * This class implements the <tt>Map</tt> interface with a hash table, using
24.34 + * reference-equality in place of object-equality when comparing keys (and
24.35 + * values). In other words, in an <tt>IdentityHashMap</tt>, two keys
24.36 + * <tt>k1</tt> and <tt>k2</tt> are considered equal if and only if
24.37 + * <tt>(k1==k2)</tt>. (In normal <tt>Map</tt> implementations (like
24.38 + * <tt>HashMap</tt>) two keys <tt>k1</tt> and <tt>k2</tt> are considered equal
24.39 + * if and only if <tt>(k1==null ? k2==null : k1.equals(k2))</tt>.)
24.40 + *
24.41 + * <p><b>This class is <i>not</i> a general-purpose <tt>Map</tt>
24.42 + * implementation! While this class implements the <tt>Map</tt> interface, it
24.43 + * intentionally violates <tt>Map's</tt> general contract, which mandates the
24.44 + * use of the <tt>equals</tt> method when comparing objects. This class is
24.45 + * designed for use only in the rare cases wherein reference-equality
24.46 + * semantics are required.</b>
24.47 + *
24.48 + * <p>A typical use of this class is <i>topology-preserving object graph
24.49 + * transformations</i>, such as serialization or deep-copying. To perform such
24.50 + * a transformation, a program must maintain a "node table" that keeps track
24.51 + * of all the object references that have already been processed. The node
24.52 + * table must not equate distinct objects even if they happen to be equal.
24.53 + * Another typical use of this class is to maintain <i>proxy objects</i>. For
24.54 + * example, a debugging facility might wish to maintain a proxy object for
24.55 + * each object in the program being debugged.
24.56 + *
24.57 + * <p>This class provides all of the optional map operations, and permits
24.58 + * <tt>null</tt> values and the <tt>null</tt> key. This class makes no
24.59 + * guarantees as to the order of the map; in particular, it does not guarantee
24.60 + * that the order will remain constant over time.
24.61 + *
24.62 + * <p>This class provides constant-time performance for the basic
24.63 + * operations (<tt>get</tt> and <tt>put</tt>), assuming the system
24.64 + * identity hash function ({@link System#identityHashCode(Object)})
24.65 + * disperses elements properly among the buckets.
24.66 + *
24.67 + * <p>This class has one tuning parameter (which affects performance but not
24.68 + * semantics): <i>expected maximum size</i>. This parameter is the maximum
24.69 + * number of key-value mappings that the map is expected to hold. Internally,
24.70 + * this parameter is used to determine the number of buckets initially
24.71 + * comprising the hash table. The precise relationship between the expected
24.72 + * maximum size and the number of buckets is unspecified.
24.73 + *
24.74 + * <p>If the size of the map (the number of key-value mappings) sufficiently
24.75 + * exceeds the expected maximum size, the number of buckets is increased
24.76 + * Increasing the number of buckets ("rehashing") may be fairly expensive, so
24.77 + * it pays to create identity hash maps with a sufficiently large expected
24.78 + * maximum size. On the other hand, iteration over collection views requires
24.79 + * time proportional to the number of buckets in the hash table, so it
24.80 + * pays not to set the expected maximum size too high if you are especially
24.81 + * concerned with iteration performance or memory usage.
24.82 + *
24.83 + * <p><strong>Note that this implementation is not synchronized.</strong>
24.84 + * If multiple threads access an identity hash map concurrently, and at
24.85 + * least one of the threads modifies the map structurally, it <i>must</i>
24.86 + * be synchronized externally. (A structural modification is any operation
24.87 + * that adds or deletes one or more mappings; merely changing the value
24.88 + * associated with a key that an instance already contains is not a
24.89 + * structural modification.) This is typically accomplished by
24.90 + * synchronizing on some object that naturally encapsulates the map.
24.91 + *
24.92 + * If no such object exists, the map should be "wrapped" using the
24.93 + * {@link Collections#synchronizedMap Collections.synchronizedMap}
24.94 + * method. This is best done at creation time, to prevent accidental
24.95 + * unsynchronized access to the map:<pre>
24.96 + * Map m = Collections.synchronizedMap(new IdentityHashMap(...));</pre>
24.97 + *
24.98 + * <p>The iterators returned by the <tt>iterator</tt> method of the
24.99 + * collections returned by all of this class's "collection view
24.100 + * methods" are <i>fail-fast</i>: if the map is structurally modified
24.101 + * at any time after the iterator is created, in any way except
24.102 + * through the iterator's own <tt>remove</tt> method, the iterator
24.103 + * will throw a {@link ConcurrentModificationException}. Thus, in the
24.104 + * face of concurrent modification, the iterator fails quickly and
24.105 + * cleanly, rather than risking arbitrary, non-deterministic behavior
24.106 + * at an undetermined time in the future.
24.107 + *
24.108 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
24.109 + * as it is, generally speaking, impossible to make any hard guarantees in the
24.110 + * presence of unsynchronized concurrent modification. Fail-fast iterators
24.111 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
24.112 + * Therefore, it would be wrong to write a program that depended on this
24.113 + * exception for its correctness: <i>fail-fast iterators should be used only
24.114 + * to detect bugs.</i>
24.115 + *
24.116 + * <p>Implementation note: This is a simple <i>linear-probe</i> hash table,
24.117 + * as described for example in texts by Sedgewick and Knuth. The array
24.118 + * alternates holding keys and values. (This has better locality for large
24.119 + * tables than does using separate arrays.) For many JRE implementations
24.120 + * and operation mixes, this class will yield better performance than
24.121 + * {@link HashMap} (which uses <i>chaining</i> rather than linear-probing).
24.122 + *
24.123 + * <p>This class is a member of the
24.124 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
24.125 + * Java Collections Framework</a>.
24.126 + *
24.127 + * @see System#identityHashCode(Object)
24.128 + * @see Object#hashCode()
24.129 + * @see Collection
24.130 + * @see Map
24.131 + * @see HashMap
24.132 + * @see TreeMap
24.133 + * @author Doug Lea and Josh Bloch
24.134 + * @since 1.4
24.135 + */
24.136 +
24.137 +public class IdentityHashMap<K,V>
24.138 + extends AbstractMap<K,V>
24.139 + implements Map<K,V>, java.io.Serializable, Cloneable
24.140 +{
24.141 + /**
24.142 + * The initial capacity used by the no-args constructor.
24.143 + * MUST be a power of two. The value 32 corresponds to the
24.144 + * (specified) expected maximum size of 21, given a load factor
24.145 + * of 2/3.
24.146 + */
24.147 + private static final int DEFAULT_CAPACITY = 32;
24.148 +
24.149 + /**
24.150 + * The minimum capacity, used if a lower value is implicitly specified
24.151 + * by either of the constructors with arguments. The value 4 corresponds
24.152 + * to an expected maximum size of 2, given a load factor of 2/3.
24.153 + * MUST be a power of two.
24.154 + */
24.155 + private static final int MINIMUM_CAPACITY = 4;
24.156 +
24.157 + /**
24.158 + * The maximum capacity, used if a higher value is implicitly specified
24.159 + * by either of the constructors with arguments.
24.160 + * MUST be a power of two <= 1<<29.
24.161 + */
24.162 + private static final int MAXIMUM_CAPACITY = 1 << 29;
24.163 +
24.164 + /**
24.165 + * The table, resized as necessary. Length MUST always be a power of two.
24.166 + */
24.167 + private transient Object[] table;
24.168 +
24.169 + /**
24.170 + * The number of key-value mappings contained in this identity hash map.
24.171 + *
24.172 + * @serial
24.173 + */
24.174 + private int size;
24.175 +
24.176 + /**
24.177 + * The number of modifications, to support fast-fail iterators
24.178 + */
24.179 + private transient int modCount;
24.180 +
24.181 + /**
24.182 + * The next size value at which to resize (capacity * load factor).
24.183 + */
24.184 + private transient int threshold;
24.185 +
24.186 + /**
24.187 + * Value representing null keys inside tables.
24.188 + */
24.189 + private static final Object NULL_KEY = new Object();
24.190 +
24.191 + /**
24.192 + * Use NULL_KEY for key if it is null.
24.193 + */
24.194 + private static Object maskNull(Object key) {
24.195 + return (key == null ? NULL_KEY : key);
24.196 + }
24.197 +
24.198 + /**
24.199 + * Returns internal representation of null key back to caller as null.
24.200 + */
24.201 + private static Object unmaskNull(Object key) {
24.202 + return (key == NULL_KEY ? null : key);
24.203 + }
24.204 +
24.205 + /**
24.206 + * Constructs a new, empty identity hash map with a default expected
24.207 + * maximum size (21).
24.208 + */
24.209 + public IdentityHashMap() {
24.210 + init(DEFAULT_CAPACITY);
24.211 + }
24.212 +
24.213 + /**
24.214 + * Constructs a new, empty map with the specified expected maximum size.
24.215 + * Putting more than the expected number of key-value mappings into
24.216 + * the map may cause the internal data structure to grow, which may be
24.217 + * somewhat time-consuming.
24.218 + *
24.219 + * @param expectedMaxSize the expected maximum size of the map
24.220 + * @throws IllegalArgumentException if <tt>expectedMaxSize</tt> is negative
24.221 + */
24.222 + public IdentityHashMap(int expectedMaxSize) {
24.223 + if (expectedMaxSize < 0)
24.224 + throw new IllegalArgumentException("expectedMaxSize is negative: "
24.225 + + expectedMaxSize);
24.226 + init(capacity(expectedMaxSize));
24.227 + }
24.228 +
24.229 + /**
24.230 + * Returns the appropriate capacity for the specified expected maximum
24.231 + * size. Returns the smallest power of two between MINIMUM_CAPACITY
24.232 + * and MAXIMUM_CAPACITY, inclusive, that is greater than
24.233 + * (3 * expectedMaxSize)/2, if such a number exists. Otherwise
24.234 + * returns MAXIMUM_CAPACITY. If (3 * expectedMaxSize)/2 is negative, it
24.235 + * is assumed that overflow has occurred, and MAXIMUM_CAPACITY is returned.
24.236 + */
24.237 + private int capacity(int expectedMaxSize) {
24.238 + // Compute min capacity for expectedMaxSize given a load factor of 2/3
24.239 + int minCapacity = (3 * expectedMaxSize)/2;
24.240 +
24.241 + // Compute the appropriate capacity
24.242 + int result;
24.243 + if (minCapacity > MAXIMUM_CAPACITY || minCapacity < 0) {
24.244 + result = MAXIMUM_CAPACITY;
24.245 + } else {
24.246 + result = MINIMUM_CAPACITY;
24.247 + while (result < minCapacity)
24.248 + result <<= 1;
24.249 + }
24.250 + return result;
24.251 + }
24.252 +
24.253 + /**
24.254 + * Initializes object to be an empty map with the specified initial
24.255 + * capacity, which is assumed to be a power of two between
24.256 + * MINIMUM_CAPACITY and MAXIMUM_CAPACITY inclusive.
24.257 + */
24.258 + private void init(int initCapacity) {
24.259 + // assert (initCapacity & -initCapacity) == initCapacity; // power of 2
24.260 + // assert initCapacity >= MINIMUM_CAPACITY;
24.261 + // assert initCapacity <= MAXIMUM_CAPACITY;
24.262 +
24.263 + threshold = (initCapacity * 2)/3;
24.264 + table = new Object[2 * initCapacity];
24.265 + }
24.266 +
24.267 + /**
24.268 + * Constructs a new identity hash map containing the keys-value mappings
24.269 + * in the specified map.
24.270 + *
24.271 + * @param m the map whose mappings are to be placed into this map
24.272 + * @throws NullPointerException if the specified map is null
24.273 + */
24.274 + public IdentityHashMap(Map<? extends K, ? extends V> m) {
24.275 + // Allow for a bit of growth
24.276 + this((int) ((1 + m.size()) * 1.1));
24.277 + putAll(m);
24.278 + }
24.279 +
24.280 + /**
24.281 + * Returns the number of key-value mappings in this identity hash map.
24.282 + *
24.283 + * @return the number of key-value mappings in this map
24.284 + */
24.285 + public int size() {
24.286 + return size;
24.287 + }
24.288 +
24.289 + /**
24.290 + * Returns <tt>true</tt> if this identity hash map contains no key-value
24.291 + * mappings.
24.292 + *
24.293 + * @return <tt>true</tt> if this identity hash map contains no key-value
24.294 + * mappings
24.295 + */
24.296 + public boolean isEmpty() {
24.297 + return size == 0;
24.298 + }
24.299 +
24.300 + /**
24.301 + * Returns index for Object x.
24.302 + */
24.303 + private static int hash(Object x, int length) {
24.304 + int h = System.identityHashCode(x);
24.305 + // Multiply by -127, and left-shift to use least bit as part of hash
24.306 + return ((h << 1) - (h << 8)) & (length - 1);
24.307 + }
24.308 +
24.309 + /**
24.310 + * Circularly traverses table of size len.
24.311 + */
24.312 + private static int nextKeyIndex(int i, int len) {
24.313 + return (i + 2 < len ? i + 2 : 0);
24.314 + }
24.315 +
24.316 + /**
24.317 + * Returns the value to which the specified key is mapped,
24.318 + * or {@code null} if this map contains no mapping for the key.
24.319 + *
24.320 + * <p>More formally, if this map contains a mapping from a key
24.321 + * {@code k} to a value {@code v} such that {@code (key == k)},
24.322 + * then this method returns {@code v}; otherwise it returns
24.323 + * {@code null}. (There can be at most one such mapping.)
24.324 + *
24.325 + * <p>A return value of {@code null} does not <i>necessarily</i>
24.326 + * indicate that the map contains no mapping for the key; it's also
24.327 + * possible that the map explicitly maps the key to {@code null}.
24.328 + * The {@link #containsKey containsKey} operation may be used to
24.329 + * distinguish these two cases.
24.330 + *
24.331 + * @see #put(Object, Object)
24.332 + */
24.333 + public V get(Object key) {
24.334 + Object k = maskNull(key);
24.335 + Object[] tab = table;
24.336 + int len = tab.length;
24.337 + int i = hash(k, len);
24.338 + while (true) {
24.339 + Object item = tab[i];
24.340 + if (item == k)
24.341 + return (V) tab[i + 1];
24.342 + if (item == null)
24.343 + return null;
24.344 + i = nextKeyIndex(i, len);
24.345 + }
24.346 + }
24.347 +
24.348 + /**
24.349 + * Tests whether the specified object reference is a key in this identity
24.350 + * hash map.
24.351 + *
24.352 + * @param key possible key
24.353 + * @return <code>true</code> if the specified object reference is a key
24.354 + * in this map
24.355 + * @see #containsValue(Object)
24.356 + */
24.357 + public boolean containsKey(Object key) {
24.358 + Object k = maskNull(key);
24.359 + Object[] tab = table;
24.360 + int len = tab.length;
24.361 + int i = hash(k, len);
24.362 + while (true) {
24.363 + Object item = tab[i];
24.364 + if (item == k)
24.365 + return true;
24.366 + if (item == null)
24.367 + return false;
24.368 + i = nextKeyIndex(i, len);
24.369 + }
24.370 + }
24.371 +
24.372 + /**
24.373 + * Tests whether the specified object reference is a value in this identity
24.374 + * hash map.
24.375 + *
24.376 + * @param value value whose presence in this map is to be tested
24.377 + * @return <tt>true</tt> if this map maps one or more keys to the
24.378 + * specified object reference
24.379 + * @see #containsKey(Object)
24.380 + */
24.381 + public boolean containsValue(Object value) {
24.382 + Object[] tab = table;
24.383 + for (int i = 1; i < tab.length; i += 2)
24.384 + if (tab[i] == value && tab[i - 1] != null)
24.385 + return true;
24.386 +
24.387 + return false;
24.388 + }
24.389 +
24.390 + /**
24.391 + * Tests if the specified key-value mapping is in the map.
24.392 + *
24.393 + * @param key possible key
24.394 + * @param value possible value
24.395 + * @return <code>true</code> if and only if the specified key-value
24.396 + * mapping is in the map
24.397 + */
24.398 + private boolean containsMapping(Object key, Object value) {
24.399 + Object k = maskNull(key);
24.400 + Object[] tab = table;
24.401 + int len = tab.length;
24.402 + int i = hash(k, len);
24.403 + while (true) {
24.404 + Object item = tab[i];
24.405 + if (item == k)
24.406 + return tab[i + 1] == value;
24.407 + if (item == null)
24.408 + return false;
24.409 + i = nextKeyIndex(i, len);
24.410 + }
24.411 + }
24.412 +
24.413 + /**
24.414 + * Associates the specified value with the specified key in this identity
24.415 + * hash map. If the map previously contained a mapping for the key, the
24.416 + * old value is replaced.
24.417 + *
24.418 + * @param key the key with which the specified value is to be associated
24.419 + * @param value the value to be associated with the specified key
24.420 + * @return the previous value associated with <tt>key</tt>, or
24.421 + * <tt>null</tt> if there was no mapping for <tt>key</tt>.
24.422 + * (A <tt>null</tt> return can also indicate that the map
24.423 + * previously associated <tt>null</tt> with <tt>key</tt>.)
24.424 + * @see Object#equals(Object)
24.425 + * @see #get(Object)
24.426 + * @see #containsKey(Object)
24.427 + */
24.428 + public V put(K key, V value) {
24.429 + Object k = maskNull(key);
24.430 + Object[] tab = table;
24.431 + int len = tab.length;
24.432 + int i = hash(k, len);
24.433 +
24.434 + Object item;
24.435 + while ( (item = tab[i]) != null) {
24.436 + if (item == k) {
24.437 + V oldValue = (V) tab[i + 1];
24.438 + tab[i + 1] = value;
24.439 + return oldValue;
24.440 + }
24.441 + i = nextKeyIndex(i, len);
24.442 + }
24.443 +
24.444 + modCount++;
24.445 + tab[i] = k;
24.446 + tab[i + 1] = value;
24.447 + if (++size >= threshold)
24.448 + resize(len); // len == 2 * current capacity.
24.449 + return null;
24.450 + }
24.451 +
24.452 + /**
24.453 + * Resize the table to hold given capacity.
24.454 + *
24.455 + * @param newCapacity the new capacity, must be a power of two.
24.456 + */
24.457 + private void resize(int newCapacity) {
24.458 + // assert (newCapacity & -newCapacity) == newCapacity; // power of 2
24.459 + int newLength = newCapacity * 2;
24.460 +
24.461 + Object[] oldTable = table;
24.462 + int oldLength = oldTable.length;
24.463 + if (oldLength == 2*MAXIMUM_CAPACITY) { // can't expand any further
24.464 + if (threshold == MAXIMUM_CAPACITY-1)
24.465 + throw new IllegalStateException("Capacity exhausted.");
24.466 + threshold = MAXIMUM_CAPACITY-1; // Gigantic map!
24.467 + return;
24.468 + }
24.469 + if (oldLength >= newLength)
24.470 + return;
24.471 +
24.472 + Object[] newTable = new Object[newLength];
24.473 + threshold = newLength / 3;
24.474 +
24.475 + for (int j = 0; j < oldLength; j += 2) {
24.476 + Object key = oldTable[j];
24.477 + if (key != null) {
24.478 + Object value = oldTable[j+1];
24.479 + oldTable[j] = null;
24.480 + oldTable[j+1] = null;
24.481 + int i = hash(key, newLength);
24.482 + while (newTable[i] != null)
24.483 + i = nextKeyIndex(i, newLength);
24.484 + newTable[i] = key;
24.485 + newTable[i + 1] = value;
24.486 + }
24.487 + }
24.488 + table = newTable;
24.489 + }
24.490 +
24.491 + /**
24.492 + * Copies all of the mappings from the specified map to this map.
24.493 + * These mappings will replace any mappings that this map had for
24.494 + * any of the keys currently in the specified map.
24.495 + *
24.496 + * @param m mappings to be stored in this map
24.497 + * @throws NullPointerException if the specified map is null
24.498 + */
24.499 + public void putAll(Map<? extends K, ? extends V> m) {
24.500 + int n = m.size();
24.501 + if (n == 0)
24.502 + return;
24.503 + if (n > threshold) // conservatively pre-expand
24.504 + resize(capacity(n));
24.505 +
24.506 + for (Entry<? extends K, ? extends V> e : m.entrySet())
24.507 + put(e.getKey(), e.getValue());
24.508 + }
24.509 +
24.510 + /**
24.511 + * Removes the mapping for this key from this map if present.
24.512 + *
24.513 + * @param key key whose mapping is to be removed from the map
24.514 + * @return the previous value associated with <tt>key</tt>, or
24.515 + * <tt>null</tt> if there was no mapping for <tt>key</tt>.
24.516 + * (A <tt>null</tt> return can also indicate that the map
24.517 + * previously associated <tt>null</tt> with <tt>key</tt>.)
24.518 + */
24.519 + public V remove(Object key) {
24.520 + Object k = maskNull(key);
24.521 + Object[] tab = table;
24.522 + int len = tab.length;
24.523 + int i = hash(k, len);
24.524 +
24.525 + while (true) {
24.526 + Object item = tab[i];
24.527 + if (item == k) {
24.528 + modCount++;
24.529 + size--;
24.530 + V oldValue = (V) tab[i + 1];
24.531 + tab[i + 1] = null;
24.532 + tab[i] = null;
24.533 + closeDeletion(i);
24.534 + return oldValue;
24.535 + }
24.536 + if (item == null)
24.537 + return null;
24.538 + i = nextKeyIndex(i, len);
24.539 + }
24.540 +
24.541 + }
24.542 +
24.543 + /**
24.544 + * Removes the specified key-value mapping from the map if it is present.
24.545 + *
24.546 + * @param key possible key
24.547 + * @param value possible value
24.548 + * @return <code>true</code> if and only if the specified key-value
24.549 + * mapping was in the map
24.550 + */
24.551 + private boolean removeMapping(Object key, Object value) {
24.552 + Object k = maskNull(key);
24.553 + Object[] tab = table;
24.554 + int len = tab.length;
24.555 + int i = hash(k, len);
24.556 +
24.557 + while (true) {
24.558 + Object item = tab[i];
24.559 + if (item == k) {
24.560 + if (tab[i + 1] != value)
24.561 + return false;
24.562 + modCount++;
24.563 + size--;
24.564 + tab[i] = null;
24.565 + tab[i + 1] = null;
24.566 + closeDeletion(i);
24.567 + return true;
24.568 + }
24.569 + if (item == null)
24.570 + return false;
24.571 + i = nextKeyIndex(i, len);
24.572 + }
24.573 + }
24.574 +
24.575 + /**
24.576 + * Rehash all possibly-colliding entries following a
24.577 + * deletion. This preserves the linear-probe
24.578 + * collision properties required by get, put, etc.
24.579 + *
24.580 + * @param d the index of a newly empty deleted slot
24.581 + */
24.582 + private void closeDeletion(int d) {
24.583 + // Adapted from Knuth Section 6.4 Algorithm R
24.584 + Object[] tab = table;
24.585 + int len = tab.length;
24.586 +
24.587 + // Look for items to swap into newly vacated slot
24.588 + // starting at index immediately following deletion,
24.589 + // and continuing until a null slot is seen, indicating
24.590 + // the end of a run of possibly-colliding keys.
24.591 + Object item;
24.592 + for (int i = nextKeyIndex(d, len); (item = tab[i]) != null;
24.593 + i = nextKeyIndex(i, len) ) {
24.594 + // The following test triggers if the item at slot i (which
24.595 + // hashes to be at slot r) should take the spot vacated by d.
24.596 + // If so, we swap it in, and then continue with d now at the
24.597 + // newly vacated i. This process will terminate when we hit
24.598 + // the null slot at the end of this run.
24.599 + // The test is messy because we are using a circular table.
24.600 + int r = hash(item, len);
24.601 + if ((i < r && (r <= d || d <= i)) || (r <= d && d <= i)) {
24.602 + tab[d] = item;
24.603 + tab[d + 1] = tab[i + 1];
24.604 + tab[i] = null;
24.605 + tab[i + 1] = null;
24.606 + d = i;
24.607 + }
24.608 + }
24.609 + }
24.610 +
24.611 + /**
24.612 + * Removes all of the mappings from this map.
24.613 + * The map will be empty after this call returns.
24.614 + */
24.615 + public void clear() {
24.616 + modCount++;
24.617 + Object[] tab = table;
24.618 + for (int i = 0; i < tab.length; i++)
24.619 + tab[i] = null;
24.620 + size = 0;
24.621 + }
24.622 +
24.623 + /**
24.624 + * Compares the specified object with this map for equality. Returns
24.625 + * <tt>true</tt> if the given object is also a map and the two maps
24.626 + * represent identical object-reference mappings. More formally, this
24.627 + * map is equal to another map <tt>m</tt> if and only if
24.628 + * <tt>this.entrySet().equals(m.entrySet())</tt>.
24.629 + *
24.630 + * <p><b>Owing to the reference-equality-based semantics of this map it is
24.631 + * possible that the symmetry and transitivity requirements of the
24.632 + * <tt>Object.equals</tt> contract may be violated if this map is compared
24.633 + * to a normal map. However, the <tt>Object.equals</tt> contract is
24.634 + * guaranteed to hold among <tt>IdentityHashMap</tt> instances.</b>
24.635 + *
24.636 + * @param o object to be compared for equality with this map
24.637 + * @return <tt>true</tt> if the specified object is equal to this map
24.638 + * @see Object#equals(Object)
24.639 + */
24.640 + public boolean equals(Object o) {
24.641 + if (o == this) {
24.642 + return true;
24.643 + } else if (o instanceof IdentityHashMap) {
24.644 + IdentityHashMap m = (IdentityHashMap) o;
24.645 + if (m.size() != size)
24.646 + return false;
24.647 +
24.648 + Object[] tab = m.table;
24.649 + for (int i = 0; i < tab.length; i+=2) {
24.650 + Object k = tab[i];
24.651 + if (k != null && !containsMapping(k, tab[i + 1]))
24.652 + return false;
24.653 + }
24.654 + return true;
24.655 + } else if (o instanceof Map) {
24.656 + Map m = (Map)o;
24.657 + return entrySet().equals(m.entrySet());
24.658 + } else {
24.659 + return false; // o is not a Map
24.660 + }
24.661 + }
24.662 +
24.663 + /**
24.664 + * Returns the hash code value for this map. The hash code of a map is
24.665 + * defined to be the sum of the hash codes of each entry in the map's
24.666 + * <tt>entrySet()</tt> view. This ensures that <tt>m1.equals(m2)</tt>
24.667 + * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two
24.668 + * <tt>IdentityHashMap</tt> instances <tt>m1</tt> and <tt>m2</tt>, as
24.669 + * required by the general contract of {@link Object#hashCode}.
24.670 + *
24.671 + * <p><b>Owing to the reference-equality-based semantics of the
24.672 + * <tt>Map.Entry</tt> instances in the set returned by this map's
24.673 + * <tt>entrySet</tt> method, it is possible that the contractual
24.674 + * requirement of <tt>Object.hashCode</tt> mentioned in the previous
24.675 + * paragraph will be violated if one of the two objects being compared is
24.676 + * an <tt>IdentityHashMap</tt> instance and the other is a normal map.</b>
24.677 + *
24.678 + * @return the hash code value for this map
24.679 + * @see Object#equals(Object)
24.680 + * @see #equals(Object)
24.681 + */
24.682 + public int hashCode() {
24.683 + int result = 0;
24.684 + Object[] tab = table;
24.685 + for (int i = 0; i < tab.length; i +=2) {
24.686 + Object key = tab[i];
24.687 + if (key != null) {
24.688 + Object k = unmaskNull(key);
24.689 + result += System.identityHashCode(k) ^
24.690 + System.identityHashCode(tab[i + 1]);
24.691 + }
24.692 + }
24.693 + return result;
24.694 + }
24.695 +
24.696 + /**
24.697 + * Returns a shallow copy of this identity hash map: the keys and values
24.698 + * themselves are not cloned.
24.699 + *
24.700 + * @return a shallow copy of this map
24.701 + */
24.702 + public Object clone() {
24.703 + try {
24.704 + IdentityHashMap<K,V> m = (IdentityHashMap<K,V>) super.clone();
24.705 + m.entrySet = null;
24.706 + m.table = table.clone();
24.707 + return m;
24.708 + } catch (CloneNotSupportedException e) {
24.709 + throw new InternalError();
24.710 + }
24.711 + }
24.712 +
24.713 + private abstract class IdentityHashMapIterator<T> implements Iterator<T> {
24.714 + int index = (size != 0 ? 0 : table.length); // current slot.
24.715 + int expectedModCount = modCount; // to support fast-fail
24.716 + int lastReturnedIndex = -1; // to allow remove()
24.717 + boolean indexValid; // To avoid unnecessary next computation
24.718 + Object[] traversalTable = table; // reference to main table or copy
24.719 +
24.720 + public boolean hasNext() {
24.721 + Object[] tab = traversalTable;
24.722 + for (int i = index; i < tab.length; i+=2) {
24.723 + Object key = tab[i];
24.724 + if (key != null) {
24.725 + index = i;
24.726 + return indexValid = true;
24.727 + }
24.728 + }
24.729 + index = tab.length;
24.730 + return false;
24.731 + }
24.732 +
24.733 + protected int nextIndex() {
24.734 + if (modCount != expectedModCount)
24.735 + throw new ConcurrentModificationException();
24.736 + if (!indexValid && !hasNext())
24.737 + throw new NoSuchElementException();
24.738 +
24.739 + indexValid = false;
24.740 + lastReturnedIndex = index;
24.741 + index += 2;
24.742 + return lastReturnedIndex;
24.743 + }
24.744 +
24.745 + public void remove() {
24.746 + if (lastReturnedIndex == -1)
24.747 + throw new IllegalStateException();
24.748 + if (modCount != expectedModCount)
24.749 + throw new ConcurrentModificationException();
24.750 +
24.751 + expectedModCount = ++modCount;
24.752 + int deletedSlot = lastReturnedIndex;
24.753 + lastReturnedIndex = -1;
24.754 + // back up index to revisit new contents after deletion
24.755 + index = deletedSlot;
24.756 + indexValid = false;
24.757 +
24.758 + // Removal code proceeds as in closeDeletion except that
24.759 + // it must catch the rare case where an element already
24.760 + // seen is swapped into a vacant slot that will be later
24.761 + // traversed by this iterator. We cannot allow future
24.762 + // next() calls to return it again. The likelihood of
24.763 + // this occurring under 2/3 load factor is very slim, but
24.764 + // when it does happen, we must make a copy of the rest of
24.765 + // the table to use for the rest of the traversal. Since
24.766 + // this can only happen when we are near the end of the table,
24.767 + // even in these rare cases, this is not very expensive in
24.768 + // time or space.
24.769 +
24.770 + Object[] tab = traversalTable;
24.771 + int len = tab.length;
24.772 +
24.773 + int d = deletedSlot;
24.774 + K key = (K) tab[d];
24.775 + tab[d] = null; // vacate the slot
24.776 + tab[d + 1] = null;
24.777 +
24.778 + // If traversing a copy, remove in real table.
24.779 + // We can skip gap-closure on copy.
24.780 + if (tab != IdentityHashMap.this.table) {
24.781 + IdentityHashMap.this.remove(key);
24.782 + expectedModCount = modCount;
24.783 + return;
24.784 + }
24.785 +
24.786 + size--;
24.787 +
24.788 + Object item;
24.789 + for (int i = nextKeyIndex(d, len); (item = tab[i]) != null;
24.790 + i = nextKeyIndex(i, len)) {
24.791 + int r = hash(item, len);
24.792 + // See closeDeletion for explanation of this conditional
24.793 + if ((i < r && (r <= d || d <= i)) ||
24.794 + (r <= d && d <= i)) {
24.795 +
24.796 + // If we are about to swap an already-seen element
24.797 + // into a slot that may later be returned by next(),
24.798 + // then clone the rest of table for use in future
24.799 + // next() calls. It is OK that our copy will have
24.800 + // a gap in the "wrong" place, since it will never
24.801 + // be used for searching anyway.
24.802 +
24.803 + if (i < deletedSlot && d >= deletedSlot &&
24.804 + traversalTable == IdentityHashMap.this.table) {
24.805 + int remaining = len - deletedSlot;
24.806 + Object[] newTable = new Object[remaining];
24.807 + System.arraycopy(tab, deletedSlot,
24.808 + newTable, 0, remaining);
24.809 + traversalTable = newTable;
24.810 + index = 0;
24.811 + }
24.812 +
24.813 + tab[d] = item;
24.814 + tab[d + 1] = tab[i + 1];
24.815 + tab[i] = null;
24.816 + tab[i + 1] = null;
24.817 + d = i;
24.818 + }
24.819 + }
24.820 + }
24.821 + }
24.822 +
24.823 + private class KeyIterator extends IdentityHashMapIterator<K> {
24.824 + public K next() {
24.825 + return (K) unmaskNull(traversalTable[nextIndex()]);
24.826 + }
24.827 + }
24.828 +
24.829 + private class ValueIterator extends IdentityHashMapIterator<V> {
24.830 + public V next() {
24.831 + return (V) traversalTable[nextIndex() + 1];
24.832 + }
24.833 + }
24.834 +
24.835 + private class EntryIterator
24.836 + extends IdentityHashMapIterator<Map.Entry<K,V>>
24.837 + {
24.838 + private Entry lastReturnedEntry = null;
24.839 +
24.840 + public Map.Entry<K,V> next() {
24.841 + lastReturnedEntry = new Entry(nextIndex());
24.842 + return lastReturnedEntry;
24.843 + }
24.844 +
24.845 + public void remove() {
24.846 + lastReturnedIndex =
24.847 + ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
24.848 + super.remove();
24.849 + lastReturnedEntry.index = lastReturnedIndex;
24.850 + lastReturnedEntry = null;
24.851 + }
24.852 +
24.853 + private class Entry implements Map.Entry<K,V> {
24.854 + private int index;
24.855 +
24.856 + private Entry(int index) {
24.857 + this.index = index;
24.858 + }
24.859 +
24.860 + public K getKey() {
24.861 + checkIndexForEntryUse();
24.862 + return (K) unmaskNull(traversalTable[index]);
24.863 + }
24.864 +
24.865 + public V getValue() {
24.866 + checkIndexForEntryUse();
24.867 + return (V) traversalTable[index+1];
24.868 + }
24.869 +
24.870 + public V setValue(V value) {
24.871 + checkIndexForEntryUse();
24.872 + V oldValue = (V) traversalTable[index+1];
24.873 + traversalTable[index+1] = value;
24.874 + // if shadowing, force into main table
24.875 + if (traversalTable != IdentityHashMap.this.table)
24.876 + put((K) traversalTable[index], value);
24.877 + return oldValue;
24.878 + }
24.879 +
24.880 + public boolean equals(Object o) {
24.881 + if (index < 0)
24.882 + return super.equals(o);
24.883 +
24.884 + if (!(o instanceof Map.Entry))
24.885 + return false;
24.886 + Map.Entry e = (Map.Entry)o;
24.887 + return (e.getKey() == unmaskNull(traversalTable[index]) &&
24.888 + e.getValue() == traversalTable[index+1]);
24.889 + }
24.890 +
24.891 + public int hashCode() {
24.892 + if (lastReturnedIndex < 0)
24.893 + return super.hashCode();
24.894 +
24.895 + return (System.identityHashCode(unmaskNull(traversalTable[index])) ^
24.896 + System.identityHashCode(traversalTable[index+1]));
24.897 + }
24.898 +
24.899 + public String toString() {
24.900 + if (index < 0)
24.901 + return super.toString();
24.902 +
24.903 + return (unmaskNull(traversalTable[index]) + "="
24.904 + + traversalTable[index+1]);
24.905 + }
24.906 +
24.907 + private void checkIndexForEntryUse() {
24.908 + if (index < 0)
24.909 + throw new IllegalStateException("Entry was removed");
24.910 + }
24.911 + }
24.912 + }
24.913 +
24.914 + // Views
24.915 +
24.916 + /**
24.917 + * This field is initialized to contain an instance of the entry set
24.918 + * view the first time this view is requested. The view is stateless,
24.919 + * so there's no reason to create more than one.
24.920 + */
24.921 + private transient Set<Map.Entry<K,V>> entrySet = null;
24.922 +
24.923 + /**
24.924 + * Returns an identity-based set view of the keys contained in this map.
24.925 + * The set is backed by the map, so changes to the map are reflected in
24.926 + * the set, and vice-versa. If the map is modified while an iteration
24.927 + * over the set is in progress, the results of the iteration are
24.928 + * undefined. The set supports element removal, which removes the
24.929 + * corresponding mapping from the map, via the <tt>Iterator.remove</tt>,
24.930 + * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
24.931 + * <tt>clear</tt> methods. It does not support the <tt>add</tt> or
24.932 + * <tt>addAll</tt> methods.
24.933 + *
24.934 + * <p><b>While the object returned by this method implements the
24.935 + * <tt>Set</tt> interface, it does <i>not</i> obey <tt>Set's</tt> general
24.936 + * contract. Like its backing map, the set returned by this method
24.937 + * defines element equality as reference-equality rather than
24.938 + * object-equality. This affects the behavior of its <tt>contains</tt>,
24.939 + * <tt>remove</tt>, <tt>containsAll</tt>, <tt>equals</tt>, and
24.940 + * <tt>hashCode</tt> methods.</b>
24.941 + *
24.942 + * <p><b>The <tt>equals</tt> method of the returned set returns <tt>true</tt>
24.943 + * only if the specified object is a set containing exactly the same
24.944 + * object references as the returned set. The symmetry and transitivity
24.945 + * requirements of the <tt>Object.equals</tt> contract may be violated if
24.946 + * the set returned by this method is compared to a normal set. However,
24.947 + * the <tt>Object.equals</tt> contract is guaranteed to hold among sets
24.948 + * returned by this method.</b>
24.949 + *
24.950 + * <p>The <tt>hashCode</tt> method of the returned set returns the sum of
24.951 + * the <i>identity hashcodes</i> of the elements in the set, rather than
24.952 + * the sum of their hashcodes. This is mandated by the change in the
24.953 + * semantics of the <tt>equals</tt> method, in order to enforce the
24.954 + * general contract of the <tt>Object.hashCode</tt> method among sets
24.955 + * returned by this method.
24.956 + *
24.957 + * @return an identity-based set view of the keys contained in this map
24.958 + * @see Object#equals(Object)
24.959 + * @see System#identityHashCode(Object)
24.960 + */
24.961 + public Set<K> keySet() {
24.962 + Set<K> ks = keySet;
24.963 + if (ks != null)
24.964 + return ks;
24.965 + else
24.966 + return keySet = new KeySet();
24.967 + }
24.968 +
24.969 + private class KeySet extends AbstractSet<K> {
24.970 + public Iterator<K> iterator() {
24.971 + return new KeyIterator();
24.972 + }
24.973 + public int size() {
24.974 + return size;
24.975 + }
24.976 + public boolean contains(Object o) {
24.977 + return containsKey(o);
24.978 + }
24.979 + public boolean remove(Object o) {
24.980 + int oldSize = size;
24.981 + IdentityHashMap.this.remove(o);
24.982 + return size != oldSize;
24.983 + }
24.984 + /*
24.985 + * Must revert from AbstractSet's impl to AbstractCollection's, as
24.986 + * the former contains an optimization that results in incorrect
24.987 + * behavior when c is a smaller "normal" (non-identity-based) Set.
24.988 + */
24.989 + public boolean removeAll(Collection<?> c) {
24.990 + boolean modified = false;
24.991 + for (Iterator<K> i = iterator(); i.hasNext(); ) {
24.992 + if (c.contains(i.next())) {
24.993 + i.remove();
24.994 + modified = true;
24.995 + }
24.996 + }
24.997 + return modified;
24.998 + }
24.999 + public void clear() {
24.1000 + IdentityHashMap.this.clear();
24.1001 + }
24.1002 + public int hashCode() {
24.1003 + int result = 0;
24.1004 + for (K key : this)
24.1005 + result += System.identityHashCode(key);
24.1006 + return result;
24.1007 + }
24.1008 + }
24.1009 +
24.1010 + /**
24.1011 + * Returns a {@link Collection} view of the values contained in this map.
24.1012 + * The collection is backed by the map, so changes to the map are
24.1013 + * reflected in the collection, and vice-versa. If the map is
24.1014 + * modified while an iteration over the collection is in progress,
24.1015 + * the results of the iteration are undefined. The collection
24.1016 + * supports element removal, which removes the corresponding
24.1017 + * mapping from the map, via the <tt>Iterator.remove</tt>,
24.1018 + * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
24.1019 + * <tt>retainAll</tt> and <tt>clear</tt> methods. It does not
24.1020 + * support the <tt>add</tt> or <tt>addAll</tt> methods.
24.1021 + *
24.1022 + * <p><b>While the object returned by this method implements the
24.1023 + * <tt>Collection</tt> interface, it does <i>not</i> obey
24.1024 + * <tt>Collection's</tt> general contract. Like its backing map,
24.1025 + * the collection returned by this method defines element equality as
24.1026 + * reference-equality rather than object-equality. This affects the
24.1027 + * behavior of its <tt>contains</tt>, <tt>remove</tt> and
24.1028 + * <tt>containsAll</tt> methods.</b>
24.1029 + */
24.1030 + public Collection<V> values() {
24.1031 + Collection<V> vs = values;
24.1032 + if (vs != null)
24.1033 + return vs;
24.1034 + else
24.1035 + return values = new Values();
24.1036 + }
24.1037 +
24.1038 + private class Values extends AbstractCollection<V> {
24.1039 + public Iterator<V> iterator() {
24.1040 + return new ValueIterator();
24.1041 + }
24.1042 + public int size() {
24.1043 + return size;
24.1044 + }
24.1045 + public boolean contains(Object o) {
24.1046 + return containsValue(o);
24.1047 + }
24.1048 + public boolean remove(Object o) {
24.1049 + for (Iterator<V> i = iterator(); i.hasNext(); ) {
24.1050 + if (i.next() == o) {
24.1051 + i.remove();
24.1052 + return true;
24.1053 + }
24.1054 + }
24.1055 + return false;
24.1056 + }
24.1057 + public void clear() {
24.1058 + IdentityHashMap.this.clear();
24.1059 + }
24.1060 + }
24.1061 +
24.1062 + /**
24.1063 + * Returns a {@link Set} view of the mappings contained in this map.
24.1064 + * Each element in the returned set is a reference-equality-based
24.1065 + * <tt>Map.Entry</tt>. The set is backed by the map, so changes
24.1066 + * to the map are reflected in the set, and vice-versa. If the
24.1067 + * map is modified while an iteration over the set is in progress,
24.1068 + * the results of the iteration are undefined. The set supports
24.1069 + * element removal, which removes the corresponding mapping from
24.1070 + * the map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
24.1071 + * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt>
24.1072 + * methods. It does not support the <tt>add</tt> or
24.1073 + * <tt>addAll</tt> methods.
24.1074 + *
24.1075 + * <p>Like the backing map, the <tt>Map.Entry</tt> objects in the set
24.1076 + * returned by this method define key and value equality as
24.1077 + * reference-equality rather than object-equality. This affects the
24.1078 + * behavior of the <tt>equals</tt> and <tt>hashCode</tt> methods of these
24.1079 + * <tt>Map.Entry</tt> objects. A reference-equality based <tt>Map.Entry
24.1080 + * e</tt> is equal to an object <tt>o</tt> if and only if <tt>o</tt> is a
24.1081 + * <tt>Map.Entry</tt> and <tt>e.getKey()==o.getKey() &&
24.1082 + * e.getValue()==o.getValue()</tt>. To accommodate these equals
24.1083 + * semantics, the <tt>hashCode</tt> method returns
24.1084 + * <tt>System.identityHashCode(e.getKey()) ^
24.1085 + * System.identityHashCode(e.getValue())</tt>.
24.1086 + *
24.1087 + * <p><b>Owing to the reference-equality-based semantics of the
24.1088 + * <tt>Map.Entry</tt> instances in the set returned by this method,
24.1089 + * it is possible that the symmetry and transitivity requirements of
24.1090 + * the {@link Object#equals(Object)} contract may be violated if any of
24.1091 + * the entries in the set is compared to a normal map entry, or if
24.1092 + * the set returned by this method is compared to a set of normal map
24.1093 + * entries (such as would be returned by a call to this method on a normal
24.1094 + * map). However, the <tt>Object.equals</tt> contract is guaranteed to
24.1095 + * hold among identity-based map entries, and among sets of such entries.
24.1096 + * </b>
24.1097 + *
24.1098 + * @return a set view of the identity-mappings contained in this map
24.1099 + */
24.1100 + public Set<Map.Entry<K,V>> entrySet() {
24.1101 + Set<Map.Entry<K,V>> es = entrySet;
24.1102 + if (es != null)
24.1103 + return es;
24.1104 + else
24.1105 + return entrySet = new EntrySet();
24.1106 + }
24.1107 +
24.1108 + private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
24.1109 + public Iterator<Map.Entry<K,V>> iterator() {
24.1110 + return new EntryIterator();
24.1111 + }
24.1112 + public boolean contains(Object o) {
24.1113 + if (!(o instanceof Map.Entry))
24.1114 + return false;
24.1115 + Map.Entry entry = (Map.Entry)o;
24.1116 + return containsMapping(entry.getKey(), entry.getValue());
24.1117 + }
24.1118 + public boolean remove(Object o) {
24.1119 + if (!(o instanceof Map.Entry))
24.1120 + return false;
24.1121 + Map.Entry entry = (Map.Entry)o;
24.1122 + return removeMapping(entry.getKey(), entry.getValue());
24.1123 + }
24.1124 + public int size() {
24.1125 + return size;
24.1126 + }
24.1127 + public void clear() {
24.1128 + IdentityHashMap.this.clear();
24.1129 + }
24.1130 + /*
24.1131 + * Must revert from AbstractSet's impl to AbstractCollection's, as
24.1132 + * the former contains an optimization that results in incorrect
24.1133 + * behavior when c is a smaller "normal" (non-identity-based) Set.
24.1134 + */
24.1135 + public boolean removeAll(Collection<?> c) {
24.1136 + boolean modified = false;
24.1137 + for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); ) {
24.1138 + if (c.contains(i.next())) {
24.1139 + i.remove();
24.1140 + modified = true;
24.1141 + }
24.1142 + }
24.1143 + return modified;
24.1144 + }
24.1145 +
24.1146 + public Object[] toArray() {
24.1147 + int size = size();
24.1148 + Object[] result = new Object[size];
24.1149 + Iterator<Map.Entry<K,V>> it = iterator();
24.1150 + for (int i = 0; i < size; i++)
24.1151 + result[i] = new AbstractMap.SimpleEntry<>(it.next());
24.1152 + return result;
24.1153 + }
24.1154 +
24.1155 + @SuppressWarnings("unchecked")
24.1156 + public <T> T[] toArray(T[] a) {
24.1157 + int size = size();
24.1158 + if (a.length < size)
24.1159 + a = (T[])java.lang.reflect.Array
24.1160 + .newInstance(a.getClass().getComponentType(), size);
24.1161 + Iterator<Map.Entry<K,V>> it = iterator();
24.1162 + for (int i = 0; i < size; i++)
24.1163 + a[i] = (T) new AbstractMap.SimpleEntry<>(it.next());
24.1164 + if (a.length > size)
24.1165 + a[size] = null;
24.1166 + return a;
24.1167 + }
24.1168 + }
24.1169 +
24.1170 +
24.1171 + private static final long serialVersionUID = 8188218128353913216L;
24.1172 +
24.1173 + /**
24.1174 + * Save the state of the <tt>IdentityHashMap</tt> instance to a stream
24.1175 + * (i.e., serialize it).
24.1176 + *
24.1177 + * @serialData The <i>size</i> of the HashMap (the number of key-value
24.1178 + * mappings) (<tt>int</tt>), followed by the key (Object) and
24.1179 + * value (Object) for each key-value mapping represented by the
24.1180 + * IdentityHashMap. The key-value mappings are emitted in no
24.1181 + * particular order.
24.1182 + */
24.1183 + private void writeObject(java.io.ObjectOutputStream s)
24.1184 + throws java.io.IOException {
24.1185 + // Write out and any hidden stuff
24.1186 + s.defaultWriteObject();
24.1187 +
24.1188 + // Write out size (number of Mappings)
24.1189 + s.writeInt(size);
24.1190 +
24.1191 + // Write out keys and values (alternating)
24.1192 + Object[] tab = table;
24.1193 + for (int i = 0; i < tab.length; i += 2) {
24.1194 + Object key = tab[i];
24.1195 + if (key != null) {
24.1196 + s.writeObject(unmaskNull(key));
24.1197 + s.writeObject(tab[i + 1]);
24.1198 + }
24.1199 + }
24.1200 + }
24.1201 +
24.1202 + /**
24.1203 + * Reconstitute the <tt>IdentityHashMap</tt> instance from a stream (i.e.,
24.1204 + * deserialize it).
24.1205 + */
24.1206 + private void readObject(java.io.ObjectInputStream s)
24.1207 + throws java.io.IOException, ClassNotFoundException {
24.1208 + // Read in any hidden stuff
24.1209 + s.defaultReadObject();
24.1210 +
24.1211 + // Read in size (number of Mappings)
24.1212 + int size = s.readInt();
24.1213 +
24.1214 + // Allow for 33% growth (i.e., capacity is >= 2* size()).
24.1215 + init(capacity((size*4)/3));
24.1216 +
24.1217 + // Read the keys and values, and put the mappings in the table
24.1218 + for (int i=0; i<size; i++) {
24.1219 + K key = (K) s.readObject();
24.1220 + V value = (V) s.readObject();
24.1221 + putForCreate(key, value);
24.1222 + }
24.1223 + }
24.1224 +
24.1225 + /**
24.1226 + * The put method for readObject. It does not resize the table,
24.1227 + * update modCount, etc.
24.1228 + */
24.1229 + private void putForCreate(K key, V value)
24.1230 + throws IOException
24.1231 + {
24.1232 + K k = (K)maskNull(key);
24.1233 + Object[] tab = table;
24.1234 + int len = tab.length;
24.1235 + int i = hash(k, len);
24.1236 +
24.1237 + Object item;
24.1238 + while ( (item = tab[i]) != null) {
24.1239 + if (item == k)
24.1240 + throw new java.io.StreamCorruptedException();
24.1241 + i = nextKeyIndex(i, len);
24.1242 + }
24.1243 + tab[i] = k;
24.1244 + tab[i + 1] = value;
24.1245 + }
24.1246 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/emul/compact/src/main/java/java/util/LinkedHashSet.java Sat Sep 07 13:51:24 2013 +0200
25.3 @@ -0,0 +1,171 @@
25.4 +/*
25.5 + * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
25.7 + *
25.8 + * This code is free software; you can redistribute it and/or modify it
25.9 + * under the terms of the GNU General Public License version 2 only, as
25.10 + * published by the Free Software Foundation. Oracle designates this
25.11 + * particular file as subject to the "Classpath" exception as provided
25.12 + * by Oracle in the LICENSE file that accompanied this code.
25.13 + *
25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25.17 + * version 2 for more details (a copy is included in the LICENSE file that
25.18 + * accompanied this code).
25.19 + *
25.20 + * You should have received a copy of the GNU General Public License version
25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25.23 + *
25.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
25.25 + * or visit www.oracle.com if you need additional information or have any
25.26 + * questions.
25.27 + */
25.28 +
25.29 +package java.util;
25.30 +
25.31 +/**
25.32 + * <p>Hash table and linked list implementation of the <tt>Set</tt> interface,
25.33 + * with predictable iteration order. This implementation differs from
25.34 + * <tt>HashSet</tt> in that it maintains a doubly-linked list running through
25.35 + * all of its entries. This linked list defines the iteration ordering,
25.36 + * which is the order in which elements were inserted into the set
25.37 + * (<i>insertion-order</i>). Note that insertion order is <i>not</i> affected
25.38 + * if an element is <i>re-inserted</i> into the set. (An element <tt>e</tt>
25.39 + * is reinserted into a set <tt>s</tt> if <tt>s.add(e)</tt> is invoked when
25.40 + * <tt>s.contains(e)</tt> would return <tt>true</tt> immediately prior to
25.41 + * the invocation.)
25.42 + *
25.43 + * <p>This implementation spares its clients from the unspecified, generally
25.44 + * chaotic ordering provided by {@link HashSet}, without incurring the
25.45 + * increased cost associated with {@link TreeSet}. It can be used to
25.46 + * produce a copy of a set that has the same order as the original, regardless
25.47 + * of the original set's implementation:
25.48 + * <pre>
25.49 + * void foo(Set s) {
25.50 + * Set copy = new LinkedHashSet(s);
25.51 + * ...
25.52 + * }
25.53 + * </pre>
25.54 + * This technique is particularly useful if a module takes a set on input,
25.55 + * copies it, and later returns results whose order is determined by that of
25.56 + * the copy. (Clients generally appreciate having things returned in the same
25.57 + * order they were presented.)
25.58 + *
25.59 + * <p>This class provides all of the optional <tt>Set</tt> operations, and
25.60 + * permits null elements. Like <tt>HashSet</tt>, it provides constant-time
25.61 + * performance for the basic operations (<tt>add</tt>, <tt>contains</tt> and
25.62 + * <tt>remove</tt>), assuming the hash function disperses elements
25.63 + * properly among the buckets. Performance is likely to be just slightly
25.64 + * below that of <tt>HashSet</tt>, due to the added expense of maintaining the
25.65 + * linked list, with one exception: Iteration over a <tt>LinkedHashSet</tt>
25.66 + * requires time proportional to the <i>size</i> of the set, regardless of
25.67 + * its capacity. Iteration over a <tt>HashSet</tt> is likely to be more
25.68 + * expensive, requiring time proportional to its <i>capacity</i>.
25.69 + *
25.70 + * <p>A linked hash set has two parameters that affect its performance:
25.71 + * <i>initial capacity</i> and <i>load factor</i>. They are defined precisely
25.72 + * as for <tt>HashSet</tt>. Note, however, that the penalty for choosing an
25.73 + * excessively high value for initial capacity is less severe for this class
25.74 + * than for <tt>HashSet</tt>, as iteration times for this class are unaffected
25.75 + * by capacity.
25.76 + *
25.77 + * <p><strong>Note that this implementation is not synchronized.</strong>
25.78 + * If multiple threads access a linked hash set concurrently, and at least
25.79 + * one of the threads modifies the set, it <em>must</em> be synchronized
25.80 + * externally. This is typically accomplished by synchronizing on some
25.81 + * object that naturally encapsulates the set.
25.82 + *
25.83 + * If no such object exists, the set should be "wrapped" using the
25.84 + * {@link Collections#synchronizedSet Collections.synchronizedSet}
25.85 + * method. This is best done at creation time, to prevent accidental
25.86 + * unsynchronized access to the set: <pre>
25.87 + * Set s = Collections.synchronizedSet(new LinkedHashSet(...));</pre>
25.88 + *
25.89 + * <p>The iterators returned by this class's <tt>iterator</tt> method are
25.90 + * <em>fail-fast</em>: if the set is modified at any time after the iterator
25.91 + * is created, in any way except through the iterator's own <tt>remove</tt>
25.92 + * method, the iterator will throw a {@link ConcurrentModificationException}.
25.93 + * Thus, in the face of concurrent modification, the iterator fails quickly
25.94 + * and cleanly, rather than risking arbitrary, non-deterministic behavior at
25.95 + * an undetermined time in the future.
25.96 + *
25.97 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
25.98 + * as it is, generally speaking, impossible to make any hard guarantees in the
25.99 + * presence of unsynchronized concurrent modification. Fail-fast iterators
25.100 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
25.101 + * Therefore, it would be wrong to write a program that depended on this
25.102 + * exception for its correctness: <i>the fail-fast behavior of iterators
25.103 + * should be used only to detect bugs.</i>
25.104 + *
25.105 + * <p>This class is a member of the
25.106 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
25.107 + * Java Collections Framework</a>.
25.108 + *
25.109 + * @param <E> the type of elements maintained by this set
25.110 + *
25.111 + * @author Josh Bloch
25.112 + * @see Object#hashCode()
25.113 + * @see Collection
25.114 + * @see Set
25.115 + * @see HashSet
25.116 + * @see TreeSet
25.117 + * @see Hashtable
25.118 + * @since 1.4
25.119 + */
25.120 +
25.121 +public class LinkedHashSet<E>
25.122 + extends HashSet<E>
25.123 + implements Set<E>, Cloneable, java.io.Serializable {
25.124 +
25.125 + private static final long serialVersionUID = -2851667679971038690L;
25.126 +
25.127 + /**
25.128 + * Constructs a new, empty linked hash set with the specified initial
25.129 + * capacity and load factor.
25.130 + *
25.131 + * @param initialCapacity the initial capacity of the linked hash set
25.132 + * @param loadFactor the load factor of the linked hash set
25.133 + * @throws IllegalArgumentException if the initial capacity is less
25.134 + * than zero, or if the load factor is nonpositive
25.135 + */
25.136 + public LinkedHashSet(int initialCapacity, float loadFactor) {
25.137 + super(initialCapacity, loadFactor, true);
25.138 + }
25.139 +
25.140 + /**
25.141 + * Constructs a new, empty linked hash set with the specified initial
25.142 + * capacity and the default load factor (0.75).
25.143 + *
25.144 + * @param initialCapacity the initial capacity of the LinkedHashSet
25.145 + * @throws IllegalArgumentException if the initial capacity is less
25.146 + * than zero
25.147 + */
25.148 + public LinkedHashSet(int initialCapacity) {
25.149 + super(initialCapacity, .75f, true);
25.150 + }
25.151 +
25.152 + /**
25.153 + * Constructs a new, empty linked hash set with the default initial
25.154 + * capacity (16) and load factor (0.75).
25.155 + */
25.156 + public LinkedHashSet() {
25.157 + super(16, .75f, true);
25.158 + }
25.159 +
25.160 + /**
25.161 + * Constructs a new linked hash set with the same elements as the
25.162 + * specified collection. The linked hash set is created with an initial
25.163 + * capacity sufficient to hold the elements in the specified collection
25.164 + * and the default load factor (0.75).
25.165 + *
25.166 + * @param c the collection whose elements are to be placed into
25.167 + * this set
25.168 + * @throws NullPointerException if the specified collection is null
25.169 + */
25.170 + public LinkedHashSet(Collection<? extends E> c) {
25.171 + super(Math.max(2*c.size(), 11), .75f, true);
25.172 + addAll(c);
25.173 + }
25.174 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/emul/compact/src/main/java/java/util/NavigableMap.java Sat Sep 07 13:51:24 2013 +0200
26.3 @@ -0,0 +1,424 @@
26.4 +/*
26.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
26.6 + *
26.7 + * This code is free software; you can redistribute it and/or modify it
26.8 + * under the terms of the GNU General Public License version 2 only, as
26.9 + * published by the Free Software Foundation. Oracle designates this
26.10 + * particular file as subject to the "Classpath" exception as provided
26.11 + * by Oracle in the LICENSE file that accompanied this code.
26.12 + *
26.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
26.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26.16 + * version 2 for more details (a copy is included in the LICENSE file that
26.17 + * accompanied this code).
26.18 + *
26.19 + * You should have received a copy of the GNU General Public License version
26.20 + * 2 along with this work; if not, write to the Free Software Foundation,
26.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26.22 + *
26.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
26.24 + * or visit www.oracle.com if you need additional information or have any
26.25 + * questions.
26.26 + */
26.27 +
26.28 +/*
26.29 + * This file is available under and governed by the GNU General Public
26.30 + * License version 2 only, as published by the Free Software Foundation.
26.31 + * However, the following notice accompanied the original version of this
26.32 + * file:
26.33 + *
26.34 + * Written by Doug Lea and Josh Bloch with assistance from members of JCP
26.35 + * JSR-166 Expert Group and released to the public domain, as explained at
26.36 + * http://creativecommons.org/publicdomain/zero/1.0/
26.37 + */
26.38 +
26.39 +package java.util;
26.40 +
26.41 +/**
26.42 + * A {@link SortedMap} extended with navigation methods returning the
26.43 + * closest matches for given search targets. Methods
26.44 + * {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry},
26.45 + * and {@code higherEntry} return {@code Map.Entry} objects
26.46 + * associated with keys respectively less than, less than or equal,
26.47 + * greater than or equal, and greater than a given key, returning
26.48 + * {@code null} if there is no such key. Similarly, methods
26.49 + * {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and
26.50 + * {@code higherKey} return only the associated keys. All of these
26.51 + * methods are designed for locating, not traversing entries.
26.52 + *
26.53 + * <p>A {@code NavigableMap} may be accessed and traversed in either
26.54 + * ascending or descending key order. The {@code descendingMap}
26.55 + * method returns a view of the map with the senses of all relational
26.56 + * and directional methods inverted. The performance of ascending
26.57 + * operations and views is likely to be faster than that of descending
26.58 + * ones. Methods {@code subMap}, {@code headMap},
26.59 + * and {@code tailMap} differ from the like-named {@code
26.60 + * SortedMap} methods in accepting additional arguments describing
26.61 + * whether lower and upper bounds are inclusive versus exclusive.
26.62 + * Submaps of any {@code NavigableMap} must implement the {@code
26.63 + * NavigableMap} interface.
26.64 + *
26.65 + * <p>This interface additionally defines methods {@code firstEntry},
26.66 + * {@code pollFirstEntry}, {@code lastEntry}, and
26.67 + * {@code pollLastEntry} that return and/or remove the least and
26.68 + * greatest mappings, if any exist, else returning {@code null}.
26.69 + *
26.70 + * <p>Implementations of entry-returning methods are expected to
26.71 + * return {@code Map.Entry} pairs representing snapshots of mappings
26.72 + * at the time they were produced, and thus generally do <em>not</em>
26.73 + * support the optional {@code Entry.setValue} method. Note however
26.74 + * that it is possible to change mappings in the associated map using
26.75 + * method {@code put}.
26.76 + *
26.77 + * <p>Methods
26.78 + * {@link #subMap(Object, Object) subMap(K, K)},
26.79 + * {@link #headMap(Object) headMap(K)}, and
26.80 + * {@link #tailMap(Object) tailMap(K)}
26.81 + * are specified to return {@code SortedMap} to allow existing
26.82 + * implementations of {@code SortedMap} to be compatibly retrofitted to
26.83 + * implement {@code NavigableMap}, but extensions and implementations
26.84 + * of this interface are encouraged to override these methods to return
26.85 + * {@code NavigableMap}. Similarly,
26.86 + * {@link #keySet()} can be overriden to return {@code NavigableSet}.
26.87 + *
26.88 + * <p>This interface is a member of the
26.89 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
26.90 + * Java Collections Framework</a>.
26.91 + *
26.92 + * @author Doug Lea
26.93 + * @author Josh Bloch
26.94 + * @param <K> the type of keys maintained by this map
26.95 + * @param <V> the type of mapped values
26.96 + * @since 1.6
26.97 + */
26.98 +public interface NavigableMap<K,V> extends SortedMap<K,V> {
26.99 + /**
26.100 + * Returns a key-value mapping associated with the greatest key
26.101 + * strictly less than the given key, or {@code null} if there is
26.102 + * no such key.
26.103 + *
26.104 + * @param key the key
26.105 + * @return an entry with the greatest key less than {@code key},
26.106 + * or {@code null} if there is no such key
26.107 + * @throws ClassCastException if the specified key cannot be compared
26.108 + * with the keys currently in the map
26.109 + * @throws NullPointerException if the specified key is null
26.110 + * and this map does not permit null keys
26.111 + */
26.112 + Map.Entry<K,V> lowerEntry(K key);
26.113 +
26.114 + /**
26.115 + * Returns the greatest key strictly less than the given key, or
26.116 + * {@code null} if there is no such key.
26.117 + *
26.118 + * @param key the key
26.119 + * @return the greatest key less than {@code key},
26.120 + * or {@code null} if there is no such key
26.121 + * @throws ClassCastException if the specified key cannot be compared
26.122 + * with the keys currently in the map
26.123 + * @throws NullPointerException if the specified key is null
26.124 + * and this map does not permit null keys
26.125 + */
26.126 + K lowerKey(K key);
26.127 +
26.128 + /**
26.129 + * Returns a key-value mapping associated with the greatest key
26.130 + * less than or equal to the given key, or {@code null} if there
26.131 + * is no such key.
26.132 + *
26.133 + * @param key the key
26.134 + * @return an entry with the greatest key less than or equal to
26.135 + * {@code key}, or {@code null} if there is no such key
26.136 + * @throws ClassCastException if the specified key cannot be compared
26.137 + * with the keys currently in the map
26.138 + * @throws NullPointerException if the specified key is null
26.139 + * and this map does not permit null keys
26.140 + */
26.141 + Map.Entry<K,V> floorEntry(K key);
26.142 +
26.143 + /**
26.144 + * Returns the greatest key less than or equal to the given key,
26.145 + * or {@code null} if there is no such key.
26.146 + *
26.147 + * @param key the key
26.148 + * @return the greatest key less than or equal to {@code key},
26.149 + * or {@code null} if there is no such key
26.150 + * @throws ClassCastException if the specified key cannot be compared
26.151 + * with the keys currently in the map
26.152 + * @throws NullPointerException if the specified key is null
26.153 + * and this map does not permit null keys
26.154 + */
26.155 + K floorKey(K key);
26.156 +
26.157 + /**
26.158 + * Returns a key-value mapping associated with the least key
26.159 + * greater than or equal to the given key, or {@code null} if
26.160 + * there is no such key.
26.161 + *
26.162 + * @param key the key
26.163 + * @return an entry with the least key greater than or equal to
26.164 + * {@code key}, or {@code null} if there is no such key
26.165 + * @throws ClassCastException if the specified key cannot be compared
26.166 + * with the keys currently in the map
26.167 + * @throws NullPointerException if the specified key is null
26.168 + * and this map does not permit null keys
26.169 + */
26.170 + Map.Entry<K,V> ceilingEntry(K key);
26.171 +
26.172 + /**
26.173 + * Returns the least key greater than or equal to the given key,
26.174 + * or {@code null} if there is no such key.
26.175 + *
26.176 + * @param key the key
26.177 + * @return the least key greater than or equal to {@code key},
26.178 + * or {@code null} if there is no such key
26.179 + * @throws ClassCastException if the specified key cannot be compared
26.180 + * with the keys currently in the map
26.181 + * @throws NullPointerException if the specified key is null
26.182 + * and this map does not permit null keys
26.183 + */
26.184 + K ceilingKey(K key);
26.185 +
26.186 + /**
26.187 + * Returns a key-value mapping associated with the least key
26.188 + * strictly greater than the given key, or {@code null} if there
26.189 + * is no such key.
26.190 + *
26.191 + * @param key the key
26.192 + * @return an entry with the least key greater than {@code key},
26.193 + * or {@code null} if there is no such key
26.194 + * @throws ClassCastException if the specified key cannot be compared
26.195 + * with the keys currently in the map
26.196 + * @throws NullPointerException if the specified key is null
26.197 + * and this map does not permit null keys
26.198 + */
26.199 + Map.Entry<K,V> higherEntry(K key);
26.200 +
26.201 + /**
26.202 + * Returns the least key strictly greater than the given key, or
26.203 + * {@code null} if there is no such key.
26.204 + *
26.205 + * @param key the key
26.206 + * @return the least key greater than {@code key},
26.207 + * or {@code null} if there is no such key
26.208 + * @throws ClassCastException if the specified key cannot be compared
26.209 + * with the keys currently in the map
26.210 + * @throws NullPointerException if the specified key is null
26.211 + * and this map does not permit null keys
26.212 + */
26.213 + K higherKey(K key);
26.214 +
26.215 + /**
26.216 + * Returns a key-value mapping associated with the least
26.217 + * key in this map, or {@code null} if the map is empty.
26.218 + *
26.219 + * @return an entry with the least key,
26.220 + * or {@code null} if this map is empty
26.221 + */
26.222 + Map.Entry<K,V> firstEntry();
26.223 +
26.224 + /**
26.225 + * Returns a key-value mapping associated with the greatest
26.226 + * key in this map, or {@code null} if the map is empty.
26.227 + *
26.228 + * @return an entry with the greatest key,
26.229 + * or {@code null} if this map is empty
26.230 + */
26.231 + Map.Entry<K,V> lastEntry();
26.232 +
26.233 + /**
26.234 + * Removes and returns a key-value mapping associated with
26.235 + * the least key in this map, or {@code null} if the map is empty.
26.236 + *
26.237 + * @return the removed first entry of this map,
26.238 + * or {@code null} if this map is empty
26.239 + */
26.240 + Map.Entry<K,V> pollFirstEntry();
26.241 +
26.242 + /**
26.243 + * Removes and returns a key-value mapping associated with
26.244 + * the greatest key in this map, or {@code null} if the map is empty.
26.245 + *
26.246 + * @return the removed last entry of this map,
26.247 + * or {@code null} if this map is empty
26.248 + */
26.249 + Map.Entry<K,V> pollLastEntry();
26.250 +
26.251 + /**
26.252 + * Returns a reverse order view of the mappings contained in this map.
26.253 + * The descending map is backed by this map, so changes to the map are
26.254 + * reflected in the descending map, and vice-versa. If either map is
26.255 + * modified while an iteration over a collection view of either map
26.256 + * is in progress (except through the iterator's own {@code remove}
26.257 + * operation), the results of the iteration are undefined.
26.258 + *
26.259 + * <p>The returned map has an ordering equivalent to
26.260 + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
26.261 + * The expression {@code m.descendingMap().descendingMap()} returns a
26.262 + * view of {@code m} essentially equivalent to {@code m}.
26.263 + *
26.264 + * @return a reverse order view of this map
26.265 + */
26.266 + NavigableMap<K,V> descendingMap();
26.267 +
26.268 + /**
26.269 + * Returns a {@link NavigableSet} view of the keys contained in this map.
26.270 + * The set's iterator returns the keys in ascending order.
26.271 + * The set is backed by the map, so changes to the map are reflected in
26.272 + * the set, and vice-versa. If the map is modified while an iteration
26.273 + * over the set is in progress (except through the iterator's own {@code
26.274 + * remove} operation), the results of the iteration are undefined. The
26.275 + * set supports element removal, which removes the corresponding mapping
26.276 + * from the map, via the {@code Iterator.remove}, {@code Set.remove},
26.277 + * {@code removeAll}, {@code retainAll}, and {@code clear} operations.
26.278 + * It does not support the {@code add} or {@code addAll} operations.
26.279 + *
26.280 + * @return a navigable set view of the keys in this map
26.281 + */
26.282 + NavigableSet<K> navigableKeySet();
26.283 +
26.284 + /**
26.285 + * Returns a reverse order {@link NavigableSet} view of the keys contained in this map.
26.286 + * The set's iterator returns the keys in descending order.
26.287 + * The set is backed by the map, so changes to the map are reflected in
26.288 + * the set, and vice-versa. If the map is modified while an iteration
26.289 + * over the set is in progress (except through the iterator's own {@code
26.290 + * remove} operation), the results of the iteration are undefined. The
26.291 + * set supports element removal, which removes the corresponding mapping
26.292 + * from the map, via the {@code Iterator.remove}, {@code Set.remove},
26.293 + * {@code removeAll}, {@code retainAll}, and {@code clear} operations.
26.294 + * It does not support the {@code add} or {@code addAll} operations.
26.295 + *
26.296 + * @return a reverse order navigable set view of the keys in this map
26.297 + */
26.298 + NavigableSet<K> descendingKeySet();
26.299 +
26.300 + /**
26.301 + * Returns a view of the portion of this map whose keys range from
26.302 + * {@code fromKey} to {@code toKey}. If {@code fromKey} and
26.303 + * {@code toKey} are equal, the returned map is empty unless
26.304 + * {@code fromInclusive} and {@code toInclusive} are both true. The
26.305 + * returned map is backed by this map, so changes in the returned map are
26.306 + * reflected in this map, and vice-versa. The returned map supports all
26.307 + * optional map operations that this map supports.
26.308 + *
26.309 + * <p>The returned map will throw an {@code IllegalArgumentException}
26.310 + * on an attempt to insert a key outside of its range, or to construct a
26.311 + * submap either of whose endpoints lie outside its range.
26.312 + *
26.313 + * @param fromKey low endpoint of the keys in the returned map
26.314 + * @param fromInclusive {@code true} if the low endpoint
26.315 + * is to be included in the returned view
26.316 + * @param toKey high endpoint of the keys in the returned map
26.317 + * @param toInclusive {@code true} if the high endpoint
26.318 + * is to be included in the returned view
26.319 + * @return a view of the portion of this map whose keys range from
26.320 + * {@code fromKey} to {@code toKey}
26.321 + * @throws ClassCastException if {@code fromKey} and {@code toKey}
26.322 + * cannot be compared to one another using this map's comparator
26.323 + * (or, if the map has no comparator, using natural ordering).
26.324 + * Implementations may, but are not required to, throw this
26.325 + * exception if {@code fromKey} or {@code toKey}
26.326 + * cannot be compared to keys currently in the map.
26.327 + * @throws NullPointerException if {@code fromKey} or {@code toKey}
26.328 + * is null and this map does not permit null keys
26.329 + * @throws IllegalArgumentException if {@code fromKey} is greater than
26.330 + * {@code toKey}; or if this map itself has a restricted
26.331 + * range, and {@code fromKey} or {@code toKey} lies
26.332 + * outside the bounds of the range
26.333 + */
26.334 + NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
26.335 + K toKey, boolean toInclusive);
26.336 +
26.337 + /**
26.338 + * Returns a view of the portion of this map whose keys are less than (or
26.339 + * equal to, if {@code inclusive} is true) {@code toKey}. The returned
26.340 + * map is backed by this map, so changes in the returned map are reflected
26.341 + * in this map, and vice-versa. The returned map supports all optional
26.342 + * map operations that this map supports.
26.343 + *
26.344 + * <p>The returned map will throw an {@code IllegalArgumentException}
26.345 + * on an attempt to insert a key outside its range.
26.346 + *
26.347 + * @param toKey high endpoint of the keys in the returned map
26.348 + * @param inclusive {@code true} if the high endpoint
26.349 + * is to be included in the returned view
26.350 + * @return a view of the portion of this map whose keys are less than
26.351 + * (or equal to, if {@code inclusive} is true) {@code toKey}
26.352 + * @throws ClassCastException if {@code toKey} is not compatible
26.353 + * with this map's comparator (or, if the map has no comparator,
26.354 + * if {@code toKey} does not implement {@link Comparable}).
26.355 + * Implementations may, but are not required to, throw this
26.356 + * exception if {@code toKey} cannot be compared to keys
26.357 + * currently in the map.
26.358 + * @throws NullPointerException if {@code toKey} is null
26.359 + * and this map does not permit null keys
26.360 + * @throws IllegalArgumentException if this map itself has a
26.361 + * restricted range, and {@code toKey} lies outside the
26.362 + * bounds of the range
26.363 + */
26.364 + NavigableMap<K,V> headMap(K toKey, boolean inclusive);
26.365 +
26.366 + /**
26.367 + * Returns a view of the portion of this map whose keys are greater than (or
26.368 + * equal to, if {@code inclusive} is true) {@code fromKey}. The returned
26.369 + * map is backed by this map, so changes in the returned map are reflected
26.370 + * in this map, and vice-versa. The returned map supports all optional
26.371 + * map operations that this map supports.
26.372 + *
26.373 + * <p>The returned map will throw an {@code IllegalArgumentException}
26.374 + * on an attempt to insert a key outside its range.
26.375 + *
26.376 + * @param fromKey low endpoint of the keys in the returned map
26.377 + * @param inclusive {@code true} if the low endpoint
26.378 + * is to be included in the returned view
26.379 + * @return a view of the portion of this map whose keys are greater than
26.380 + * (or equal to, if {@code inclusive} is true) {@code fromKey}
26.381 + * @throws ClassCastException if {@code fromKey} is not compatible
26.382 + * with this map's comparator (or, if the map has no comparator,
26.383 + * if {@code fromKey} does not implement {@link Comparable}).
26.384 + * Implementations may, but are not required to, throw this
26.385 + * exception if {@code fromKey} cannot be compared to keys
26.386 + * currently in the map.
26.387 + * @throws NullPointerException if {@code fromKey} is null
26.388 + * and this map does not permit null keys
26.389 + * @throws IllegalArgumentException if this map itself has a
26.390 + * restricted range, and {@code fromKey} lies outside the
26.391 + * bounds of the range
26.392 + */
26.393 + NavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
26.394 +
26.395 + /**
26.396 + * {@inheritDoc}
26.397 + *
26.398 + * <p>Equivalent to {@code subMap(fromKey, true, toKey, false)}.
26.399 + *
26.400 + * @throws ClassCastException {@inheritDoc}
26.401 + * @throws NullPointerException {@inheritDoc}
26.402 + * @throws IllegalArgumentException {@inheritDoc}
26.403 + */
26.404 + SortedMap<K,V> subMap(K fromKey, K toKey);
26.405 +
26.406 + /**
26.407 + * {@inheritDoc}
26.408 + *
26.409 + * <p>Equivalent to {@code headMap(toKey, false)}.
26.410 + *
26.411 + * @throws ClassCastException {@inheritDoc}
26.412 + * @throws NullPointerException {@inheritDoc}
26.413 + * @throws IllegalArgumentException {@inheritDoc}
26.414 + */
26.415 + SortedMap<K,V> headMap(K toKey);
26.416 +
26.417 + /**
26.418 + * {@inheritDoc}
26.419 + *
26.420 + * <p>Equivalent to {@code tailMap(fromKey, true)}.
26.421 + *
26.422 + * @throws ClassCastException {@inheritDoc}
26.423 + * @throws NullPointerException {@inheritDoc}
26.424 + * @throws IllegalArgumentException {@inheritDoc}
26.425 + */
26.426 + SortedMap<K,V> tailMap(K fromKey);
26.427 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/emul/compact/src/main/java/java/util/NavigableSet.java Sat Sep 07 13:51:24 2013 +0200
27.3 @@ -0,0 +1,319 @@
27.4 +/*
27.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
27.6 + *
27.7 + * This code is free software; you can redistribute it and/or modify it
27.8 + * under the terms of the GNU General Public License version 2 only, as
27.9 + * published by the Free Software Foundation. Oracle designates this
27.10 + * particular file as subject to the "Classpath" exception as provided
27.11 + * by Oracle in the LICENSE file that accompanied this code.
27.12 + *
27.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
27.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27.16 + * version 2 for more details (a copy is included in the LICENSE file that
27.17 + * accompanied this code).
27.18 + *
27.19 + * You should have received a copy of the GNU General Public License version
27.20 + * 2 along with this work; if not, write to the Free Software Foundation,
27.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27.22 + *
27.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
27.24 + * or visit www.oracle.com if you need additional information or have any
27.25 + * questions.
27.26 + */
27.27 +
27.28 +/*
27.29 + * This file is available under and governed by the GNU General Public
27.30 + * License version 2 only, as published by the Free Software Foundation.
27.31 + * However, the following notice accompanied the original version of this
27.32 + * file:
27.33 + *
27.34 + * Written by Doug Lea and Josh Bloch with assistance from members of JCP
27.35 + * JSR-166 Expert Group and released to the public domain, as explained at
27.36 + * http://creativecommons.org/publicdomain/zero/1.0/
27.37 + */
27.38 +
27.39 +package java.util;
27.40 +
27.41 +/**
27.42 + * A {@link SortedSet} extended with navigation methods reporting
27.43 + * closest matches for given search targets. Methods {@code lower},
27.44 + * {@code floor}, {@code ceiling}, and {@code higher} return elements
27.45 + * respectively less than, less than or equal, greater than or equal,
27.46 + * and greater than a given element, returning {@code null} if there
27.47 + * is no such element. A {@code NavigableSet} may be accessed and
27.48 + * traversed in either ascending or descending order. The {@code
27.49 + * descendingSet} method returns a view of the set with the senses of
27.50 + * all relational and directional methods inverted. The performance of
27.51 + * ascending operations and views is likely to be faster than that of
27.52 + * descending ones. This interface additionally defines methods
27.53 + * {@code pollFirst} and {@code pollLast} that return and remove the
27.54 + * lowest and highest element, if one exists, else returning {@code
27.55 + * null}. Methods {@code subSet}, {@code headSet},
27.56 + * and {@code tailSet} differ from the like-named {@code
27.57 + * SortedSet} methods in accepting additional arguments describing
27.58 + * whether lower and upper bounds are inclusive versus exclusive.
27.59 + * Subsets of any {@code NavigableSet} must implement the {@code
27.60 + * NavigableSet} interface.
27.61 + *
27.62 + * <p> The return values of navigation methods may be ambiguous in
27.63 + * implementations that permit {@code null} elements. However, even
27.64 + * in this case the result can be disambiguated by checking
27.65 + * {@code contains(null)}. To avoid such issues, implementations of
27.66 + * this interface are encouraged to <em>not</em> permit insertion of
27.67 + * {@code null} elements. (Note that sorted sets of {@link
27.68 + * Comparable} elements intrinsically do not permit {@code null}.)
27.69 + *
27.70 + * <p>Methods
27.71 + * {@link #subSet(Object, Object) subSet(E, E)},
27.72 + * {@link #headSet(Object) headSet(E)}, and
27.73 + * {@link #tailSet(Object) tailSet(E)}
27.74 + * are specified to return {@code SortedSet} to allow existing
27.75 + * implementations of {@code SortedSet} to be compatibly retrofitted to
27.76 + * implement {@code NavigableSet}, but extensions and implementations
27.77 + * of this interface are encouraged to override these methods to return
27.78 + * {@code NavigableSet}.
27.79 + *
27.80 + * <p>This interface is a member of the
27.81 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
27.82 + * Java Collections Framework</a>.
27.83 + *
27.84 + * @author Doug Lea
27.85 + * @author Josh Bloch
27.86 + * @param <E> the type of elements maintained by this set
27.87 + * @since 1.6
27.88 + */
27.89 +public interface NavigableSet<E> extends SortedSet<E> {
27.90 + /**
27.91 + * Returns the greatest element in this set strictly less than the
27.92 + * given element, or {@code null} if there is no such element.
27.93 + *
27.94 + * @param e the value to match
27.95 + * @return the greatest element less than {@code e},
27.96 + * or {@code null} if there is no such element
27.97 + * @throws ClassCastException if the specified element cannot be
27.98 + * compared with the elements currently in the set
27.99 + * @throws NullPointerException if the specified element is null
27.100 + * and this set does not permit null elements
27.101 + */
27.102 + E lower(E e);
27.103 +
27.104 + /**
27.105 + * Returns the greatest element in this set less than or equal to
27.106 + * the given element, or {@code null} if there is no such element.
27.107 + *
27.108 + * @param e the value to match
27.109 + * @return the greatest element less than or equal to {@code e},
27.110 + * or {@code null} if there is no such element
27.111 + * @throws ClassCastException if the specified element cannot be
27.112 + * compared with the elements currently in the set
27.113 + * @throws NullPointerException if the specified element is null
27.114 + * and this set does not permit null elements
27.115 + */
27.116 + E floor(E e);
27.117 +
27.118 + /**
27.119 + * Returns the least element in this set greater than or equal to
27.120 + * the given element, or {@code null} if there is no such element.
27.121 + *
27.122 + * @param e the value to match
27.123 + * @return the least element greater than or equal to {@code e},
27.124 + * or {@code null} if there is no such element
27.125 + * @throws ClassCastException if the specified element cannot be
27.126 + * compared with the elements currently in the set
27.127 + * @throws NullPointerException if the specified element is null
27.128 + * and this set does not permit null elements
27.129 + */
27.130 + E ceiling(E e);
27.131 +
27.132 + /**
27.133 + * Returns the least element in this set strictly greater than the
27.134 + * given element, or {@code null} if there is no such element.
27.135 + *
27.136 + * @param e the value to match
27.137 + * @return the least element greater than {@code e},
27.138 + * or {@code null} if there is no such element
27.139 + * @throws ClassCastException if the specified element cannot be
27.140 + * compared with the elements currently in the set
27.141 + * @throws NullPointerException if the specified element is null
27.142 + * and this set does not permit null elements
27.143 + */
27.144 + E higher(E e);
27.145 +
27.146 + /**
27.147 + * Retrieves and removes the first (lowest) element,
27.148 + * or returns {@code null} if this set is empty.
27.149 + *
27.150 + * @return the first element, or {@code null} if this set is empty
27.151 + */
27.152 + E pollFirst();
27.153 +
27.154 + /**
27.155 + * Retrieves and removes the last (highest) element,
27.156 + * or returns {@code null} if this set is empty.
27.157 + *
27.158 + * @return the last element, or {@code null} if this set is empty
27.159 + */
27.160 + E pollLast();
27.161 +
27.162 + /**
27.163 + * Returns an iterator over the elements in this set, in ascending order.
27.164 + *
27.165 + * @return an iterator over the elements in this set, in ascending order
27.166 + */
27.167 + Iterator<E> iterator();
27.168 +
27.169 + /**
27.170 + * Returns a reverse order view of the elements contained in this set.
27.171 + * The descending set is backed by this set, so changes to the set are
27.172 + * reflected in the descending set, and vice-versa. If either set is
27.173 + * modified while an iteration over either set is in progress (except
27.174 + * through the iterator's own {@code remove} operation), the results of
27.175 + * the iteration are undefined.
27.176 + *
27.177 + * <p>The returned set has an ordering equivalent to
27.178 + * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
27.179 + * The expression {@code s.descendingSet().descendingSet()} returns a
27.180 + * view of {@code s} essentially equivalent to {@code s}.
27.181 + *
27.182 + * @return a reverse order view of this set
27.183 + */
27.184 + NavigableSet<E> descendingSet();
27.185 +
27.186 + /**
27.187 + * Returns an iterator over the elements in this set, in descending order.
27.188 + * Equivalent in effect to {@code descendingSet().iterator()}.
27.189 + *
27.190 + * @return an iterator over the elements in this set, in descending order
27.191 + */
27.192 + Iterator<E> descendingIterator();
27.193 +
27.194 + /**
27.195 + * Returns a view of the portion of this set whose elements range from
27.196 + * {@code fromElement} to {@code toElement}. If {@code fromElement} and
27.197 + * {@code toElement} are equal, the returned set is empty unless {@code
27.198 + * fromInclusive} and {@code toInclusive} are both true. The returned set
27.199 + * is backed by this set, so changes in the returned set are reflected in
27.200 + * this set, and vice-versa. The returned set supports all optional set
27.201 + * operations that this set supports.
27.202 + *
27.203 + * <p>The returned set will throw an {@code IllegalArgumentException}
27.204 + * on an attempt to insert an element outside its range.
27.205 + *
27.206 + * @param fromElement low endpoint of the returned set
27.207 + * @param fromInclusive {@code true} if the low endpoint
27.208 + * is to be included in the returned view
27.209 + * @param toElement high endpoint of the returned set
27.210 + * @param toInclusive {@code true} if the high endpoint
27.211 + * is to be included in the returned view
27.212 + * @return a view of the portion of this set whose elements range from
27.213 + * {@code fromElement}, inclusive, to {@code toElement}, exclusive
27.214 + * @throws ClassCastException if {@code fromElement} and
27.215 + * {@code toElement} cannot be compared to one another using this
27.216 + * set's comparator (or, if the set has no comparator, using
27.217 + * natural ordering). Implementations may, but are not required
27.218 + * to, throw this exception if {@code fromElement} or
27.219 + * {@code toElement} cannot be compared to elements currently in
27.220 + * the set.
27.221 + * @throws NullPointerException if {@code fromElement} or
27.222 + * {@code toElement} is null and this set does
27.223 + * not permit null elements
27.224 + * @throws IllegalArgumentException if {@code fromElement} is
27.225 + * greater than {@code toElement}; or if this set itself
27.226 + * has a restricted range, and {@code fromElement} or
27.227 + * {@code toElement} lies outside the bounds of the range.
27.228 + */
27.229 + NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
27.230 + E toElement, boolean toInclusive);
27.231 +
27.232 + /**
27.233 + * Returns a view of the portion of this set whose elements are less than
27.234 + * (or equal to, if {@code inclusive} is true) {@code toElement}. The
27.235 + * returned set is backed by this set, so changes in the returned set are
27.236 + * reflected in this set, and vice-versa. The returned set supports all
27.237 + * optional set operations that this set supports.
27.238 + *
27.239 + * <p>The returned set will throw an {@code IllegalArgumentException}
27.240 + * on an attempt to insert an element outside its range.
27.241 + *
27.242 + * @param toElement high endpoint of the returned set
27.243 + * @param inclusive {@code true} if the high endpoint
27.244 + * is to be included in the returned view
27.245 + * @return a view of the portion of this set whose elements are less than
27.246 + * (or equal to, if {@code inclusive} is true) {@code toElement}
27.247 + * @throws ClassCastException if {@code toElement} is not compatible
27.248 + * with this set's comparator (or, if the set has no comparator,
27.249 + * if {@code toElement} does not implement {@link Comparable}).
27.250 + * Implementations may, but are not required to, throw this
27.251 + * exception if {@code toElement} cannot be compared to elements
27.252 + * currently in the set.
27.253 + * @throws NullPointerException if {@code toElement} is null and
27.254 + * this set does not permit null elements
27.255 + * @throws IllegalArgumentException if this set itself has a
27.256 + * restricted range, and {@code toElement} lies outside the
27.257 + * bounds of the range
27.258 + */
27.259 + NavigableSet<E> headSet(E toElement, boolean inclusive);
27.260 +
27.261 + /**
27.262 + * Returns a view of the portion of this set whose elements are greater
27.263 + * than (or equal to, if {@code inclusive} is true) {@code fromElement}.
27.264 + * The returned set is backed by this set, so changes in the returned set
27.265 + * are reflected in this set, and vice-versa. The returned set supports
27.266 + * all optional set operations that this set supports.
27.267 + *
27.268 + * <p>The returned set will throw an {@code IllegalArgumentException}
27.269 + * on an attempt to insert an element outside its range.
27.270 + *
27.271 + * @param fromElement low endpoint of the returned set
27.272 + * @param inclusive {@code true} if the low endpoint
27.273 + * is to be included in the returned view
27.274 + * @return a view of the portion of this set whose elements are greater
27.275 + * than or equal to {@code fromElement}
27.276 + * @throws ClassCastException if {@code fromElement} is not compatible
27.277 + * with this set's comparator (or, if the set has no comparator,
27.278 + * if {@code fromElement} does not implement {@link Comparable}).
27.279 + * Implementations may, but are not required to, throw this
27.280 + * exception if {@code fromElement} cannot be compared to elements
27.281 + * currently in the set.
27.282 + * @throws NullPointerException if {@code fromElement} is null
27.283 + * and this set does not permit null elements
27.284 + * @throws IllegalArgumentException if this set itself has a
27.285 + * restricted range, and {@code fromElement} lies outside the
27.286 + * bounds of the range
27.287 + */
27.288 + NavigableSet<E> tailSet(E fromElement, boolean inclusive);
27.289 +
27.290 + /**
27.291 + * {@inheritDoc}
27.292 + *
27.293 + * <p>Equivalent to {@code subSet(fromElement, true, toElement, false)}.
27.294 + *
27.295 + * @throws ClassCastException {@inheritDoc}
27.296 + * @throws NullPointerException {@inheritDoc}
27.297 + * @throws IllegalArgumentException {@inheritDoc}
27.298 + */
27.299 + SortedSet<E> subSet(E fromElement, E toElement);
27.300 +
27.301 + /**
27.302 + * {@inheritDoc}
27.303 + *
27.304 + * <p>Equivalent to {@code headSet(toElement, false)}.
27.305 + *
27.306 + * @throws ClassCastException {@inheritDoc}
27.307 + * @throws NullPointerException {@inheritDoc}
27.308 + * @throws IllegalArgumentException {@inheritDoc}
27.309 +na */
27.310 + SortedSet<E> headSet(E toElement);
27.311 +
27.312 + /**
27.313 + * {@inheritDoc}
27.314 + *
27.315 + * <p>Equivalent to {@code tailSet(fromElement, true)}.
27.316 + *
27.317 + * @throws ClassCastException {@inheritDoc}
27.318 + * @throws NullPointerException {@inheritDoc}
27.319 + * @throws IllegalArgumentException {@inheritDoc}
27.320 + */
27.321 + SortedSet<E> tailSet(E fromElement);
27.322 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/emul/compact/src/main/java/java/util/TreeMap.java Sat Sep 07 13:51:24 2013 +0200
28.3 @@ -0,0 +1,2442 @@
28.4 +/*
28.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
28.7 + *
28.8 + * This code is free software; you can redistribute it and/or modify it
28.9 + * under the terms of the GNU General Public License version 2 only, as
28.10 + * published by the Free Software Foundation. Oracle designates this
28.11 + * particular file as subject to the "Classpath" exception as provided
28.12 + * by Oracle in the LICENSE file that accompanied this code.
28.13 + *
28.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
28.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28.17 + * version 2 for more details (a copy is included in the LICENSE file that
28.18 + * accompanied this code).
28.19 + *
28.20 + * You should have received a copy of the GNU General Public License version
28.21 + * 2 along with this work; if not, write to the Free Software Foundation,
28.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28.23 + *
28.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28.25 + * or visit www.oracle.com if you need additional information or have any
28.26 + * questions.
28.27 + */
28.28 +
28.29 +package java.util;
28.30 +
28.31 +/**
28.32 + * A Red-Black tree based {@link NavigableMap} implementation.
28.33 + * The map is sorted according to the {@linkplain Comparable natural
28.34 + * ordering} of its keys, or by a {@link Comparator} provided at map
28.35 + * creation time, depending on which constructor is used.
28.36 + *
28.37 + * <p>This implementation provides guaranteed log(n) time cost for the
28.38 + * {@code containsKey}, {@code get}, {@code put} and {@code remove}
28.39 + * operations. Algorithms are adaptations of those in Cormen, Leiserson, and
28.40 + * Rivest's <em>Introduction to Algorithms</em>.
28.41 + *
28.42 + * <p>Note that the ordering maintained by a tree map, like any sorted map, and
28.43 + * whether or not an explicit comparator is provided, must be <em>consistent
28.44 + * with {@code equals}</em> if this sorted map is to correctly implement the
28.45 + * {@code Map} interface. (See {@code Comparable} or {@code Comparator} for a
28.46 + * precise definition of <em>consistent with equals</em>.) This is so because
28.47 + * the {@code Map} interface is defined in terms of the {@code equals}
28.48 + * operation, but a sorted map performs all key comparisons using its {@code
28.49 + * compareTo} (or {@code compare}) method, so two keys that are deemed equal by
28.50 + * this method are, from the standpoint of the sorted map, equal. The behavior
28.51 + * of a sorted map <em>is</em> well-defined even if its ordering is
28.52 + * inconsistent with {@code equals}; it just fails to obey the general contract
28.53 + * of the {@code Map} interface.
28.54 + *
28.55 + * <p><strong>Note that this implementation is not synchronized.</strong>
28.56 + * If multiple threads access a map concurrently, and at least one of the
28.57 + * threads modifies the map structurally, it <em>must</em> be synchronized
28.58 + * externally. (A structural modification is any operation that adds or
28.59 + * deletes one or more mappings; merely changing the value associated
28.60 + * with an existing key is not a structural modification.) This is
28.61 + * typically accomplished by synchronizing on some object that naturally
28.62 + * encapsulates the map.
28.63 + * If no such object exists, the map should be "wrapped" using the
28.64 + * {@link Collections#synchronizedSortedMap Collections.synchronizedSortedMap}
28.65 + * method. This is best done at creation time, to prevent accidental
28.66 + * unsynchronized access to the map: <pre>
28.67 + * SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));</pre>
28.68 + *
28.69 + * <p>The iterators returned by the {@code iterator} method of the collections
28.70 + * returned by all of this class's "collection view methods" are
28.71 + * <em>fail-fast</em>: if the map is structurally modified at any time after
28.72 + * the iterator is created, in any way except through the iterator's own
28.73 + * {@code remove} method, the iterator will throw a {@link
28.74 + * ConcurrentModificationException}. Thus, in the face of concurrent
28.75 + * modification, the iterator fails quickly and cleanly, rather than risking
28.76 + * arbitrary, non-deterministic behavior at an undetermined time in the future.
28.77 + *
28.78 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
28.79 + * as it is, generally speaking, impossible to make any hard guarantees in the
28.80 + * presence of unsynchronized concurrent modification. Fail-fast iterators
28.81 + * throw {@code ConcurrentModificationException} on a best-effort basis.
28.82 + * Therefore, it would be wrong to write a program that depended on this
28.83 + * exception for its correctness: <em>the fail-fast behavior of iterators
28.84 + * should be used only to detect bugs.</em>
28.85 + *
28.86 + * <p>All {@code Map.Entry} pairs returned by methods in this class
28.87 + * and its views represent snapshots of mappings at the time they were
28.88 + * produced. They do <strong>not</strong> support the {@code Entry.setValue}
28.89 + * method. (Note however that it is possible to change mappings in the
28.90 + * associated map using {@code put}.)
28.91 + *
28.92 + * <p>This class is a member of the
28.93 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
28.94 + * Java Collections Framework</a>.
28.95 + *
28.96 + * @param <K> the type of keys maintained by this map
28.97 + * @param <V> the type of mapped values
28.98 + *
28.99 + * @author Josh Bloch and Doug Lea
28.100 + * @see Map
28.101 + * @see HashMap
28.102 + * @see Hashtable
28.103 + * @see Comparable
28.104 + * @see Comparator
28.105 + * @see Collection
28.106 + * @since 1.2
28.107 + */
28.108 +
28.109 +public class TreeMap<K,V>
28.110 + extends AbstractMap<K,V>
28.111 + implements NavigableMap<K,V>, Cloneable, java.io.Serializable
28.112 +{
28.113 + /**
28.114 + * The comparator used to maintain order in this tree map, or
28.115 + * null if it uses the natural ordering of its keys.
28.116 + *
28.117 + * @serial
28.118 + */
28.119 + private final Comparator<? super K> comparator;
28.120 +
28.121 + private transient Entry<K,V> root = null;
28.122 +
28.123 + /**
28.124 + * The number of entries in the tree
28.125 + */
28.126 + private transient int size = 0;
28.127 +
28.128 + /**
28.129 + * The number of structural modifications to the tree.
28.130 + */
28.131 + private transient int modCount = 0;
28.132 +
28.133 + /**
28.134 + * Constructs a new, empty tree map, using the natural ordering of its
28.135 + * keys. All keys inserted into the map must implement the {@link
28.136 + * Comparable} interface. Furthermore, all such keys must be
28.137 + * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
28.138 + * a {@code ClassCastException} for any keys {@code k1} and
28.139 + * {@code k2} in the map. If the user attempts to put a key into the
28.140 + * map that violates this constraint (for example, the user attempts to
28.141 + * put a string key into a map whose keys are integers), the
28.142 + * {@code put(Object key, Object value)} call will throw a
28.143 + * {@code ClassCastException}.
28.144 + */
28.145 + public TreeMap() {
28.146 + comparator = null;
28.147 + }
28.148 +
28.149 + /**
28.150 + * Constructs a new, empty tree map, ordered according to the given
28.151 + * comparator. All keys inserted into the map must be <em>mutually
28.152 + * comparable</em> by the given comparator: {@code comparator.compare(k1,
28.153 + * k2)} must not throw a {@code ClassCastException} for any keys
28.154 + * {@code k1} and {@code k2} in the map. If the user attempts to put
28.155 + * a key into the map that violates this constraint, the {@code put(Object
28.156 + * key, Object value)} call will throw a
28.157 + * {@code ClassCastException}.
28.158 + *
28.159 + * @param comparator the comparator that will be used to order this map.
28.160 + * If {@code null}, the {@linkplain Comparable natural
28.161 + * ordering} of the keys will be used.
28.162 + */
28.163 + public TreeMap(Comparator<? super K> comparator) {
28.164 + this.comparator = comparator;
28.165 + }
28.166 +
28.167 + /**
28.168 + * Constructs a new tree map containing the same mappings as the given
28.169 + * map, ordered according to the <em>natural ordering</em> of its keys.
28.170 + * All keys inserted into the new map must implement the {@link
28.171 + * Comparable} interface. Furthermore, all such keys must be
28.172 + * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
28.173 + * a {@code ClassCastException} for any keys {@code k1} and
28.174 + * {@code k2} in the map. This method runs in n*log(n) time.
28.175 + *
28.176 + * @param m the map whose mappings are to be placed in this map
28.177 + * @throws ClassCastException if the keys in m are not {@link Comparable},
28.178 + * or are not mutually comparable
28.179 + * @throws NullPointerException if the specified map is null
28.180 + */
28.181 + public TreeMap(Map<? extends K, ? extends V> m) {
28.182 + comparator = null;
28.183 + putAll(m);
28.184 + }
28.185 +
28.186 + /**
28.187 + * Constructs a new tree map containing the same mappings and
28.188 + * using the same ordering as the specified sorted map. This
28.189 + * method runs in linear time.
28.190 + *
28.191 + * @param m the sorted map whose mappings are to be placed in this map,
28.192 + * and whose comparator is to be used to sort this map
28.193 + * @throws NullPointerException if the specified map is null
28.194 + */
28.195 + public TreeMap(SortedMap<K, ? extends V> m) {
28.196 + comparator = m.comparator();
28.197 + try {
28.198 + buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
28.199 + } catch (java.io.IOException cannotHappen) {
28.200 + } catch (ClassNotFoundException cannotHappen) {
28.201 + }
28.202 + }
28.203 +
28.204 +
28.205 + // Query Operations
28.206 +
28.207 + /**
28.208 + * Returns the number of key-value mappings in this map.
28.209 + *
28.210 + * @return the number of key-value mappings in this map
28.211 + */
28.212 + public int size() {
28.213 + return size;
28.214 + }
28.215 +
28.216 + /**
28.217 + * Returns {@code true} if this map contains a mapping for the specified
28.218 + * key.
28.219 + *
28.220 + * @param key key whose presence in this map is to be tested
28.221 + * @return {@code true} if this map contains a mapping for the
28.222 + * specified key
28.223 + * @throws ClassCastException if the specified key cannot be compared
28.224 + * with the keys currently in the map
28.225 + * @throws NullPointerException if the specified key is null
28.226 + * and this map uses natural ordering, or its comparator
28.227 + * does not permit null keys
28.228 + */
28.229 + public boolean containsKey(Object key) {
28.230 + return getEntry(key) != null;
28.231 + }
28.232 +
28.233 + /**
28.234 + * Returns {@code true} if this map maps one or more keys to the
28.235 + * specified value. More formally, returns {@code true} if and only if
28.236 + * this map contains at least one mapping to a value {@code v} such
28.237 + * that {@code (value==null ? v==null : value.equals(v))}. This
28.238 + * operation will probably require time linear in the map size for
28.239 + * most implementations.
28.240 + *
28.241 + * @param value value whose presence in this map is to be tested
28.242 + * @return {@code true} if a mapping to {@code value} exists;
28.243 + * {@code false} otherwise
28.244 + * @since 1.2
28.245 + */
28.246 + public boolean containsValue(Object value) {
28.247 + for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
28.248 + if (valEquals(value, e.value))
28.249 + return true;
28.250 + return false;
28.251 + }
28.252 +
28.253 + /**
28.254 + * Returns the value to which the specified key is mapped,
28.255 + * or {@code null} if this map contains no mapping for the key.
28.256 + *
28.257 + * <p>More formally, if this map contains a mapping from a key
28.258 + * {@code k} to a value {@code v} such that {@code key} compares
28.259 + * equal to {@code k} according to the map's ordering, then this
28.260 + * method returns {@code v}; otherwise it returns {@code null}.
28.261 + * (There can be at most one such mapping.)
28.262 + *
28.263 + * <p>A return value of {@code null} does not <em>necessarily</em>
28.264 + * indicate that the map contains no mapping for the key; it's also
28.265 + * possible that the map explicitly maps the key to {@code null}.
28.266 + * The {@link #containsKey containsKey} operation may be used to
28.267 + * distinguish these two cases.
28.268 + *
28.269 + * @throws ClassCastException if the specified key cannot be compared
28.270 + * with the keys currently in the map
28.271 + * @throws NullPointerException if the specified key is null
28.272 + * and this map uses natural ordering, or its comparator
28.273 + * does not permit null keys
28.274 + */
28.275 + public V get(Object key) {
28.276 + Entry<K,V> p = getEntry(key);
28.277 + return (p==null ? null : p.value);
28.278 + }
28.279 +
28.280 + public Comparator<? super K> comparator() {
28.281 + return comparator;
28.282 + }
28.283 +
28.284 + /**
28.285 + * @throws NoSuchElementException {@inheritDoc}
28.286 + */
28.287 + public K firstKey() {
28.288 + return key(getFirstEntry());
28.289 + }
28.290 +
28.291 + /**
28.292 + * @throws NoSuchElementException {@inheritDoc}
28.293 + */
28.294 + public K lastKey() {
28.295 + return key(getLastEntry());
28.296 + }
28.297 +
28.298 + /**
28.299 + * Copies all of the mappings from the specified map to this map.
28.300 + * These mappings replace any mappings that this map had for any
28.301 + * of the keys currently in the specified map.
28.302 + *
28.303 + * @param map mappings to be stored in this map
28.304 + * @throws ClassCastException if the class of a key or value in
28.305 + * the specified map prevents it from being stored in this map
28.306 + * @throws NullPointerException if the specified map is null or
28.307 + * the specified map contains a null key and this map does not
28.308 + * permit null keys
28.309 + */
28.310 + public void putAll(Map<? extends K, ? extends V> map) {
28.311 + int mapSize = map.size();
28.312 + if (size==0 && mapSize!=0 && map instanceof SortedMap) {
28.313 + Comparator c = ((SortedMap)map).comparator();
28.314 + if (c == comparator || (c != null && c.equals(comparator))) {
28.315 + ++modCount;
28.316 + try {
28.317 + buildFromSorted(mapSize, map.entrySet().iterator(),
28.318 + null, null);
28.319 + } catch (java.io.IOException cannotHappen) {
28.320 + } catch (ClassNotFoundException cannotHappen) {
28.321 + }
28.322 + return;
28.323 + }
28.324 + }
28.325 + super.putAll(map);
28.326 + }
28.327 +
28.328 + /**
28.329 + * Returns this map's entry for the given key, or {@code null} if the map
28.330 + * does not contain an entry for the key.
28.331 + *
28.332 + * @return this map's entry for the given key, or {@code null} if the map
28.333 + * does not contain an entry for the key
28.334 + * @throws ClassCastException if the specified key cannot be compared
28.335 + * with the keys currently in the map
28.336 + * @throws NullPointerException if the specified key is null
28.337 + * and this map uses natural ordering, or its comparator
28.338 + * does not permit null keys
28.339 + */
28.340 + final Entry<K,V> getEntry(Object key) {
28.341 + // Offload comparator-based version for sake of performance
28.342 + if (comparator != null)
28.343 + return getEntryUsingComparator(key);
28.344 + if (key == null)
28.345 + throw new NullPointerException();
28.346 + Comparable<? super K> k = (Comparable<? super K>) key;
28.347 + Entry<K,V> p = root;
28.348 + while (p != null) {
28.349 + int cmp = k.compareTo(p.key);
28.350 + if (cmp < 0)
28.351 + p = p.left;
28.352 + else if (cmp > 0)
28.353 + p = p.right;
28.354 + else
28.355 + return p;
28.356 + }
28.357 + return null;
28.358 + }
28.359 +
28.360 + /**
28.361 + * Version of getEntry using comparator. Split off from getEntry
28.362 + * for performance. (This is not worth doing for most methods,
28.363 + * that are less dependent on comparator performance, but is
28.364 + * worthwhile here.)
28.365 + */
28.366 + final Entry<K,V> getEntryUsingComparator(Object key) {
28.367 + K k = (K) key;
28.368 + Comparator<? super K> cpr = comparator;
28.369 + if (cpr != null) {
28.370 + Entry<K,V> p = root;
28.371 + while (p != null) {
28.372 + int cmp = cpr.compare(k, p.key);
28.373 + if (cmp < 0)
28.374 + p = p.left;
28.375 + else if (cmp > 0)
28.376 + p = p.right;
28.377 + else
28.378 + return p;
28.379 + }
28.380 + }
28.381 + return null;
28.382 + }
28.383 +
28.384 + /**
28.385 + * Gets the entry corresponding to the specified key; if no such entry
28.386 + * exists, returns the entry for the least key greater than the specified
28.387 + * key; if no such entry exists (i.e., the greatest key in the Tree is less
28.388 + * than the specified key), returns {@code null}.
28.389 + */
28.390 + final Entry<K,V> getCeilingEntry(K key) {
28.391 + Entry<K,V> p = root;
28.392 + while (p != null) {
28.393 + int cmp = compare(key, p.key);
28.394 + if (cmp < 0) {
28.395 + if (p.left != null)
28.396 + p = p.left;
28.397 + else
28.398 + return p;
28.399 + } else if (cmp > 0) {
28.400 + if (p.right != null) {
28.401 + p = p.right;
28.402 + } else {
28.403 + Entry<K,V> parent = p.parent;
28.404 + Entry<K,V> ch = p;
28.405 + while (parent != null && ch == parent.right) {
28.406 + ch = parent;
28.407 + parent = parent.parent;
28.408 + }
28.409 + return parent;
28.410 + }
28.411 + } else
28.412 + return p;
28.413 + }
28.414 + return null;
28.415 + }
28.416 +
28.417 + /**
28.418 + * Gets the entry corresponding to the specified key; if no such entry
28.419 + * exists, returns the entry for the greatest key less than the specified
28.420 + * key; if no such entry exists, returns {@code null}.
28.421 + */
28.422 + final Entry<K,V> getFloorEntry(K key) {
28.423 + Entry<K,V> p = root;
28.424 + while (p != null) {
28.425 + int cmp = compare(key, p.key);
28.426 + if (cmp > 0) {
28.427 + if (p.right != null)
28.428 + p = p.right;
28.429 + else
28.430 + return p;
28.431 + } else if (cmp < 0) {
28.432 + if (p.left != null) {
28.433 + p = p.left;
28.434 + } else {
28.435 + Entry<K,V> parent = p.parent;
28.436 + Entry<K,V> ch = p;
28.437 + while (parent != null && ch == parent.left) {
28.438 + ch = parent;
28.439 + parent = parent.parent;
28.440 + }
28.441 + return parent;
28.442 + }
28.443 + } else
28.444 + return p;
28.445 +
28.446 + }
28.447 + return null;
28.448 + }
28.449 +
28.450 + /**
28.451 + * Gets the entry for the least key greater than the specified
28.452 + * key; if no such entry exists, returns the entry for the least
28.453 + * key greater than the specified key; if no such entry exists
28.454 + * returns {@code null}.
28.455 + */
28.456 + final Entry<K,V> getHigherEntry(K key) {
28.457 + Entry<K,V> p = root;
28.458 + while (p != null) {
28.459 + int cmp = compare(key, p.key);
28.460 + if (cmp < 0) {
28.461 + if (p.left != null)
28.462 + p = p.left;
28.463 + else
28.464 + return p;
28.465 + } else {
28.466 + if (p.right != null) {
28.467 + p = p.right;
28.468 + } else {
28.469 + Entry<K,V> parent = p.parent;
28.470 + Entry<K,V> ch = p;
28.471 + while (parent != null && ch == parent.right) {
28.472 + ch = parent;
28.473 + parent = parent.parent;
28.474 + }
28.475 + return parent;
28.476 + }
28.477 + }
28.478 + }
28.479 + return null;
28.480 + }
28.481 +
28.482 + /**
28.483 + * Returns the entry for the greatest key less than the specified key; if
28.484 + * no such entry exists (i.e., the least key in the Tree is greater than
28.485 + * the specified key), returns {@code null}.
28.486 + */
28.487 + final Entry<K,V> getLowerEntry(K key) {
28.488 + Entry<K,V> p = root;
28.489 + while (p != null) {
28.490 + int cmp = compare(key, p.key);
28.491 + if (cmp > 0) {
28.492 + if (p.right != null)
28.493 + p = p.right;
28.494 + else
28.495 + return p;
28.496 + } else {
28.497 + if (p.left != null) {
28.498 + p = p.left;
28.499 + } else {
28.500 + Entry<K,V> parent = p.parent;
28.501 + Entry<K,V> ch = p;
28.502 + while (parent != null && ch == parent.left) {
28.503 + ch = parent;
28.504 + parent = parent.parent;
28.505 + }
28.506 + return parent;
28.507 + }
28.508 + }
28.509 + }
28.510 + return null;
28.511 + }
28.512 +
28.513 + /**
28.514 + * Associates the specified value with the specified key in this map.
28.515 + * If the map previously contained a mapping for the key, the old
28.516 + * value is replaced.
28.517 + *
28.518 + * @param key key with which the specified value is to be associated
28.519 + * @param value value to be associated with the specified key
28.520 + *
28.521 + * @return the previous value associated with {@code key}, or
28.522 + * {@code null} if there was no mapping for {@code key}.
28.523 + * (A {@code null} return can also indicate that the map
28.524 + * previously associated {@code null} with {@code key}.)
28.525 + * @throws ClassCastException if the specified key cannot be compared
28.526 + * with the keys currently in the map
28.527 + * @throws NullPointerException if the specified key is null
28.528 + * and this map uses natural ordering, or its comparator
28.529 + * does not permit null keys
28.530 + */
28.531 + public V put(K key, V value) {
28.532 + Entry<K,V> t = root;
28.533 + if (t == null) {
28.534 + compare(key, key); // type (and possibly null) check
28.535 +
28.536 + root = new Entry<>(key, value, null);
28.537 + size = 1;
28.538 + modCount++;
28.539 + return null;
28.540 + }
28.541 + int cmp;
28.542 + Entry<K,V> parent;
28.543 + // split comparator and comparable paths
28.544 + Comparator<? super K> cpr = comparator;
28.545 + if (cpr != null) {
28.546 + do {
28.547 + parent = t;
28.548 + cmp = cpr.compare(key, t.key);
28.549 + if (cmp < 0)
28.550 + t = t.left;
28.551 + else if (cmp > 0)
28.552 + t = t.right;
28.553 + else
28.554 + return t.setValue(value);
28.555 + } while (t != null);
28.556 + }
28.557 + else {
28.558 + if (key == null)
28.559 + throw new NullPointerException();
28.560 + Comparable<? super K> k = (Comparable<? super K>) key;
28.561 + do {
28.562 + parent = t;
28.563 + cmp = k.compareTo(t.key);
28.564 + if (cmp < 0)
28.565 + t = t.left;
28.566 + else if (cmp > 0)
28.567 + t = t.right;
28.568 + else
28.569 + return t.setValue(value);
28.570 + } while (t != null);
28.571 + }
28.572 + Entry<K,V> e = new Entry<>(key, value, parent);
28.573 + if (cmp < 0)
28.574 + parent.left = e;
28.575 + else
28.576 + parent.right = e;
28.577 + fixAfterInsertion(e);
28.578 + size++;
28.579 + modCount++;
28.580 + return null;
28.581 + }
28.582 +
28.583 + /**
28.584 + * Removes the mapping for this key from this TreeMap if present.
28.585 + *
28.586 + * @param key key for which mapping should be removed
28.587 + * @return the previous value associated with {@code key}, or
28.588 + * {@code null} if there was no mapping for {@code key}.
28.589 + * (A {@code null} return can also indicate that the map
28.590 + * previously associated {@code null} with {@code key}.)
28.591 + * @throws ClassCastException if the specified key cannot be compared
28.592 + * with the keys currently in the map
28.593 + * @throws NullPointerException if the specified key is null
28.594 + * and this map uses natural ordering, or its comparator
28.595 + * does not permit null keys
28.596 + */
28.597 + public V remove(Object key) {
28.598 + Entry<K,V> p = getEntry(key);
28.599 + if (p == null)
28.600 + return null;
28.601 +
28.602 + V oldValue = p.value;
28.603 + deleteEntry(p);
28.604 + return oldValue;
28.605 + }
28.606 +
28.607 + /**
28.608 + * Removes all of the mappings from this map.
28.609 + * The map will be empty after this call returns.
28.610 + */
28.611 + public void clear() {
28.612 + modCount++;
28.613 + size = 0;
28.614 + root = null;
28.615 + }
28.616 +
28.617 + /**
28.618 + * Returns a shallow copy of this {@code TreeMap} instance. (The keys and
28.619 + * values themselves are not cloned.)
28.620 + *
28.621 + * @return a shallow copy of this map
28.622 + */
28.623 + public Object clone() {
28.624 + TreeMap<K,V> clone = null;
28.625 + try {
28.626 + clone = (TreeMap<K,V>) super.clone();
28.627 + } catch (CloneNotSupportedException e) {
28.628 + throw new InternalError();
28.629 + }
28.630 +
28.631 + // Put clone into "virgin" state (except for comparator)
28.632 + clone.root = null;
28.633 + clone.size = 0;
28.634 + clone.modCount = 0;
28.635 + clone.entrySet = null;
28.636 + clone.navigableKeySet = null;
28.637 + clone.descendingMap = null;
28.638 +
28.639 + // Initialize clone with our mappings
28.640 + try {
28.641 + clone.buildFromSorted(size, entrySet().iterator(), null, null);
28.642 + } catch (java.io.IOException cannotHappen) {
28.643 + } catch (ClassNotFoundException cannotHappen) {
28.644 + }
28.645 +
28.646 + return clone;
28.647 + }
28.648 +
28.649 + // NavigableMap API methods
28.650 +
28.651 + /**
28.652 + * @since 1.6
28.653 + */
28.654 + public Map.Entry<K,V> firstEntry() {
28.655 + return exportEntry(getFirstEntry());
28.656 + }
28.657 +
28.658 + /**
28.659 + * @since 1.6
28.660 + */
28.661 + public Map.Entry<K,V> lastEntry() {
28.662 + return exportEntry(getLastEntry());
28.663 + }
28.664 +
28.665 + /**
28.666 + * @since 1.6
28.667 + */
28.668 + public Map.Entry<K,V> pollFirstEntry() {
28.669 + Entry<K,V> p = getFirstEntry();
28.670 + Map.Entry<K,V> result = exportEntry(p);
28.671 + if (p != null)
28.672 + deleteEntry(p);
28.673 + return result;
28.674 + }
28.675 +
28.676 + /**
28.677 + * @since 1.6
28.678 + */
28.679 + public Map.Entry<K,V> pollLastEntry() {
28.680 + Entry<K,V> p = getLastEntry();
28.681 + Map.Entry<K,V> result = exportEntry(p);
28.682 + if (p != null)
28.683 + deleteEntry(p);
28.684 + return result;
28.685 + }
28.686 +
28.687 + /**
28.688 + * @throws ClassCastException {@inheritDoc}
28.689 + * @throws NullPointerException if the specified key is null
28.690 + * and this map uses natural ordering, or its comparator
28.691 + * does not permit null keys
28.692 + * @since 1.6
28.693 + */
28.694 + public Map.Entry<K,V> lowerEntry(K key) {
28.695 + return exportEntry(getLowerEntry(key));
28.696 + }
28.697 +
28.698 + /**
28.699 + * @throws ClassCastException {@inheritDoc}
28.700 + * @throws NullPointerException if the specified key is null
28.701 + * and this map uses natural ordering, or its comparator
28.702 + * does not permit null keys
28.703 + * @since 1.6
28.704 + */
28.705 + public K lowerKey(K key) {
28.706 + return keyOrNull(getLowerEntry(key));
28.707 + }
28.708 +
28.709 + /**
28.710 + * @throws ClassCastException {@inheritDoc}
28.711 + * @throws NullPointerException if the specified key is null
28.712 + * and this map uses natural ordering, or its comparator
28.713 + * does not permit null keys
28.714 + * @since 1.6
28.715 + */
28.716 + public Map.Entry<K,V> floorEntry(K key) {
28.717 + return exportEntry(getFloorEntry(key));
28.718 + }
28.719 +
28.720 + /**
28.721 + * @throws ClassCastException {@inheritDoc}
28.722 + * @throws NullPointerException if the specified key is null
28.723 + * and this map uses natural ordering, or its comparator
28.724 + * does not permit null keys
28.725 + * @since 1.6
28.726 + */
28.727 + public K floorKey(K key) {
28.728 + return keyOrNull(getFloorEntry(key));
28.729 + }
28.730 +
28.731 + /**
28.732 + * @throws ClassCastException {@inheritDoc}
28.733 + * @throws NullPointerException if the specified key is null
28.734 + * and this map uses natural ordering, or its comparator
28.735 + * does not permit null keys
28.736 + * @since 1.6
28.737 + */
28.738 + public Map.Entry<K,V> ceilingEntry(K key) {
28.739 + return exportEntry(getCeilingEntry(key));
28.740 + }
28.741 +
28.742 + /**
28.743 + * @throws ClassCastException {@inheritDoc}
28.744 + * @throws NullPointerException if the specified key is null
28.745 + * and this map uses natural ordering, or its comparator
28.746 + * does not permit null keys
28.747 + * @since 1.6
28.748 + */
28.749 + public K ceilingKey(K key) {
28.750 + return keyOrNull(getCeilingEntry(key));
28.751 + }
28.752 +
28.753 + /**
28.754 + * @throws ClassCastException {@inheritDoc}
28.755 + * @throws NullPointerException if the specified key is null
28.756 + * and this map uses natural ordering, or its comparator
28.757 + * does not permit null keys
28.758 + * @since 1.6
28.759 + */
28.760 + public Map.Entry<K,V> higherEntry(K key) {
28.761 + return exportEntry(getHigherEntry(key));
28.762 + }
28.763 +
28.764 + /**
28.765 + * @throws ClassCastException {@inheritDoc}
28.766 + * @throws NullPointerException if the specified key is null
28.767 + * and this map uses natural ordering, or its comparator
28.768 + * does not permit null keys
28.769 + * @since 1.6
28.770 + */
28.771 + public K higherKey(K key) {
28.772 + return keyOrNull(getHigherEntry(key));
28.773 + }
28.774 +
28.775 + // Views
28.776 +
28.777 + /**
28.778 + * Fields initialized to contain an instance of the entry set view
28.779 + * the first time this view is requested. Views are stateless, so
28.780 + * there's no reason to create more than one.
28.781 + */
28.782 + private transient EntrySet entrySet = null;
28.783 + private transient KeySet<K> navigableKeySet = null;
28.784 + private transient NavigableMap<K,V> descendingMap = null;
28.785 +
28.786 + /**
28.787 + * Returns a {@link Set} view of the keys contained in this map.
28.788 + * The set's iterator returns the keys in ascending order.
28.789 + * The set is backed by the map, so changes to the map are
28.790 + * reflected in the set, and vice-versa. If the map is modified
28.791 + * while an iteration over the set is in progress (except through
28.792 + * the iterator's own {@code remove} operation), the results of
28.793 + * the iteration are undefined. The set supports element removal,
28.794 + * which removes the corresponding mapping from the map, via the
28.795 + * {@code Iterator.remove}, {@code Set.remove},
28.796 + * {@code removeAll}, {@code retainAll}, and {@code clear}
28.797 + * operations. It does not support the {@code add} or {@code addAll}
28.798 + * operations.
28.799 + */
28.800 + public Set<K> keySet() {
28.801 + return navigableKeySet();
28.802 + }
28.803 +
28.804 + /**
28.805 + * @since 1.6
28.806 + */
28.807 + public NavigableSet<K> navigableKeySet() {
28.808 + KeySet<K> nks = navigableKeySet;
28.809 + return (nks != null) ? nks : (navigableKeySet = new KeySet(this));
28.810 + }
28.811 +
28.812 + /**
28.813 + * @since 1.6
28.814 + */
28.815 + public NavigableSet<K> descendingKeySet() {
28.816 + return descendingMap().navigableKeySet();
28.817 + }
28.818 +
28.819 + /**
28.820 + * Returns a {@link Collection} view of the values contained in this map.
28.821 + * The collection's iterator returns the values in ascending order
28.822 + * of the corresponding keys.
28.823 + * The collection is backed by the map, so changes to the map are
28.824 + * reflected in the collection, and vice-versa. If the map is
28.825 + * modified while an iteration over the collection is in progress
28.826 + * (except through the iterator's own {@code remove} operation),
28.827 + * the results of the iteration are undefined. The collection
28.828 + * supports element removal, which removes the corresponding
28.829 + * mapping from the map, via the {@code Iterator.remove},
28.830 + * {@code Collection.remove}, {@code removeAll},
28.831 + * {@code retainAll} and {@code clear} operations. It does not
28.832 + * support the {@code add} or {@code addAll} operations.
28.833 + */
28.834 + public Collection<V> values() {
28.835 + Collection<V> vs = values;
28.836 + return (vs != null) ? vs : (values = new Values());
28.837 + }
28.838 +
28.839 + /**
28.840 + * Returns a {@link Set} view of the mappings contained in this map.
28.841 + * The set's iterator returns the entries in ascending key order.
28.842 + * The set is backed by the map, so changes to the map are
28.843 + * reflected in the set, and vice-versa. If the map is modified
28.844 + * while an iteration over the set is in progress (except through
28.845 + * the iterator's own {@code remove} operation, or through the
28.846 + * {@code setValue} operation on a map entry returned by the
28.847 + * iterator) the results of the iteration are undefined. The set
28.848 + * supports element removal, which removes the corresponding
28.849 + * mapping from the map, via the {@code Iterator.remove},
28.850 + * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
28.851 + * {@code clear} operations. It does not support the
28.852 + * {@code add} or {@code addAll} operations.
28.853 + */
28.854 + public Set<Map.Entry<K,V>> entrySet() {
28.855 + EntrySet es = entrySet;
28.856 + return (es != null) ? es : (entrySet = new EntrySet());
28.857 + }
28.858 +
28.859 + /**
28.860 + * @since 1.6
28.861 + */
28.862 + public NavigableMap<K, V> descendingMap() {
28.863 + NavigableMap<K, V> km = descendingMap;
28.864 + return (km != null) ? km :
28.865 + (descendingMap = new DescendingSubMap(this,
28.866 + true, null, true,
28.867 + true, null, true));
28.868 + }
28.869 +
28.870 + /**
28.871 + * @throws ClassCastException {@inheritDoc}
28.872 + * @throws NullPointerException if {@code fromKey} or {@code toKey} is
28.873 + * null and this map uses natural ordering, or its comparator
28.874 + * does not permit null keys
28.875 + * @throws IllegalArgumentException {@inheritDoc}
28.876 + * @since 1.6
28.877 + */
28.878 + public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
28.879 + K toKey, boolean toInclusive) {
28.880 + return new AscendingSubMap(this,
28.881 + false, fromKey, fromInclusive,
28.882 + false, toKey, toInclusive);
28.883 + }
28.884 +
28.885 + /**
28.886 + * @throws ClassCastException {@inheritDoc}
28.887 + * @throws NullPointerException if {@code toKey} is null
28.888 + * and this map uses natural ordering, or its comparator
28.889 + * does not permit null keys
28.890 + * @throws IllegalArgumentException {@inheritDoc}
28.891 + * @since 1.6
28.892 + */
28.893 + public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
28.894 + return new AscendingSubMap(this,
28.895 + true, null, true,
28.896 + false, toKey, inclusive);
28.897 + }
28.898 +
28.899 + /**
28.900 + * @throws ClassCastException {@inheritDoc}
28.901 + * @throws NullPointerException if {@code fromKey} is null
28.902 + * and this map uses natural ordering, or its comparator
28.903 + * does not permit null keys
28.904 + * @throws IllegalArgumentException {@inheritDoc}
28.905 + * @since 1.6
28.906 + */
28.907 + public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
28.908 + return new AscendingSubMap(this,
28.909 + false, fromKey, inclusive,
28.910 + true, null, true);
28.911 + }
28.912 +
28.913 + /**
28.914 + * @throws ClassCastException {@inheritDoc}
28.915 + * @throws NullPointerException if {@code fromKey} or {@code toKey} is
28.916 + * null and this map uses natural ordering, or its comparator
28.917 + * does not permit null keys
28.918 + * @throws IllegalArgumentException {@inheritDoc}
28.919 + */
28.920 + public SortedMap<K,V> subMap(K fromKey, K toKey) {
28.921 + return subMap(fromKey, true, toKey, false);
28.922 + }
28.923 +
28.924 + /**
28.925 + * @throws ClassCastException {@inheritDoc}
28.926 + * @throws NullPointerException if {@code toKey} is null
28.927 + * and this map uses natural ordering, or its comparator
28.928 + * does not permit null keys
28.929 + * @throws IllegalArgumentException {@inheritDoc}
28.930 + */
28.931 + public SortedMap<K,V> headMap(K toKey) {
28.932 + return headMap(toKey, false);
28.933 + }
28.934 +
28.935 + /**
28.936 + * @throws ClassCastException {@inheritDoc}
28.937 + * @throws NullPointerException if {@code fromKey} is null
28.938 + * and this map uses natural ordering, or its comparator
28.939 + * does not permit null keys
28.940 + * @throws IllegalArgumentException {@inheritDoc}
28.941 + */
28.942 + public SortedMap<K,V> tailMap(K fromKey) {
28.943 + return tailMap(fromKey, true);
28.944 + }
28.945 +
28.946 + // View class support
28.947 +
28.948 + class Values extends AbstractCollection<V> {
28.949 + public Iterator<V> iterator() {
28.950 + return new ValueIterator(getFirstEntry());
28.951 + }
28.952 +
28.953 + public int size() {
28.954 + return TreeMap.this.size();
28.955 + }
28.956 +
28.957 + public boolean contains(Object o) {
28.958 + return TreeMap.this.containsValue(o);
28.959 + }
28.960 +
28.961 + public boolean remove(Object o) {
28.962 + for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {
28.963 + if (valEquals(e.getValue(), o)) {
28.964 + deleteEntry(e);
28.965 + return true;
28.966 + }
28.967 + }
28.968 + return false;
28.969 + }
28.970 +
28.971 + public void clear() {
28.972 + TreeMap.this.clear();
28.973 + }
28.974 + }
28.975 +
28.976 + class EntrySet extends AbstractSet<Map.Entry<K,V>> {
28.977 + public Iterator<Map.Entry<K,V>> iterator() {
28.978 + return new EntryIterator(getFirstEntry());
28.979 + }
28.980 +
28.981 + public boolean contains(Object o) {
28.982 + if (!(o instanceof Map.Entry))
28.983 + return false;
28.984 + Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
28.985 + V value = entry.getValue();
28.986 + Entry<K,V> p = getEntry(entry.getKey());
28.987 + return p != null && valEquals(p.getValue(), value);
28.988 + }
28.989 +
28.990 + public boolean remove(Object o) {
28.991 + if (!(o instanceof Map.Entry))
28.992 + return false;
28.993 + Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
28.994 + V value = entry.getValue();
28.995 + Entry<K,V> p = getEntry(entry.getKey());
28.996 + if (p != null && valEquals(p.getValue(), value)) {
28.997 + deleteEntry(p);
28.998 + return true;
28.999 + }
28.1000 + return false;
28.1001 + }
28.1002 +
28.1003 + public int size() {
28.1004 + return TreeMap.this.size();
28.1005 + }
28.1006 +
28.1007 + public void clear() {
28.1008 + TreeMap.this.clear();
28.1009 + }
28.1010 + }
28.1011 +
28.1012 + /*
28.1013 + * Unlike Values and EntrySet, the KeySet class is static,
28.1014 + * delegating to a NavigableMap to allow use by SubMaps, which
28.1015 + * outweighs the ugliness of needing type-tests for the following
28.1016 + * Iterator methods that are defined appropriately in main versus
28.1017 + * submap classes.
28.1018 + */
28.1019 +
28.1020 + Iterator<K> keyIterator() {
28.1021 + return new KeyIterator(getFirstEntry());
28.1022 + }
28.1023 +
28.1024 + Iterator<K> descendingKeyIterator() {
28.1025 + return new DescendingKeyIterator(getLastEntry());
28.1026 + }
28.1027 +
28.1028 + static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
28.1029 + private final NavigableMap<E, Object> m;
28.1030 + KeySet(NavigableMap<E,Object> map) { m = map; }
28.1031 +
28.1032 + public Iterator<E> iterator() {
28.1033 + if (m instanceof TreeMap)
28.1034 + return ((TreeMap<E,Object>)m).keyIterator();
28.1035 + else
28.1036 + return (Iterator<E>)(((TreeMap.NavigableSubMap)m).keyIterator());
28.1037 + }
28.1038 +
28.1039 + public Iterator<E> descendingIterator() {
28.1040 + if (m instanceof TreeMap)
28.1041 + return ((TreeMap<E,Object>)m).descendingKeyIterator();
28.1042 + else
28.1043 + return (Iterator<E>)(((TreeMap.NavigableSubMap)m).descendingKeyIterator());
28.1044 + }
28.1045 +
28.1046 + public int size() { return m.size(); }
28.1047 + public boolean isEmpty() { return m.isEmpty(); }
28.1048 + public boolean contains(Object o) { return m.containsKey(o); }
28.1049 + public void clear() { m.clear(); }
28.1050 + public E lower(E e) { return m.lowerKey(e); }
28.1051 + public E floor(E e) { return m.floorKey(e); }
28.1052 + public E ceiling(E e) { return m.ceilingKey(e); }
28.1053 + public E higher(E e) { return m.higherKey(e); }
28.1054 + public E first() { return m.firstKey(); }
28.1055 + public E last() { return m.lastKey(); }
28.1056 + public Comparator<? super E> comparator() { return m.comparator(); }
28.1057 + public E pollFirst() {
28.1058 + Map.Entry<E,Object> e = m.pollFirstEntry();
28.1059 + return (e == null) ? null : e.getKey();
28.1060 + }
28.1061 + public E pollLast() {
28.1062 + Map.Entry<E,Object> e = m.pollLastEntry();
28.1063 + return (e == null) ? null : e.getKey();
28.1064 + }
28.1065 + public boolean remove(Object o) {
28.1066 + int oldSize = size();
28.1067 + m.remove(o);
28.1068 + return size() != oldSize;
28.1069 + }
28.1070 + public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
28.1071 + E toElement, boolean toInclusive) {
28.1072 + return new KeySet<>(m.subMap(fromElement, fromInclusive,
28.1073 + toElement, toInclusive));
28.1074 + }
28.1075 + public NavigableSet<E> headSet(E toElement, boolean inclusive) {
28.1076 + return new KeySet<>(m.headMap(toElement, inclusive));
28.1077 + }
28.1078 + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
28.1079 + return new KeySet<>(m.tailMap(fromElement, inclusive));
28.1080 + }
28.1081 + public SortedSet<E> subSet(E fromElement, E toElement) {
28.1082 + return subSet(fromElement, true, toElement, false);
28.1083 + }
28.1084 + public SortedSet<E> headSet(E toElement) {
28.1085 + return headSet(toElement, false);
28.1086 + }
28.1087 + public SortedSet<E> tailSet(E fromElement) {
28.1088 + return tailSet(fromElement, true);
28.1089 + }
28.1090 + public NavigableSet<E> descendingSet() {
28.1091 + return new KeySet(m.descendingMap());
28.1092 + }
28.1093 + }
28.1094 +
28.1095 + /**
28.1096 + * Base class for TreeMap Iterators
28.1097 + */
28.1098 + abstract class PrivateEntryIterator<T> implements Iterator<T> {
28.1099 + Entry<K,V> next;
28.1100 + Entry<K,V> lastReturned;
28.1101 + int expectedModCount;
28.1102 +
28.1103 + PrivateEntryIterator(Entry<K,V> first) {
28.1104 + expectedModCount = modCount;
28.1105 + lastReturned = null;
28.1106 + next = first;
28.1107 + }
28.1108 +
28.1109 + public final boolean hasNext() {
28.1110 + return next != null;
28.1111 + }
28.1112 +
28.1113 + final Entry<K,V> nextEntry() {
28.1114 + Entry<K,V> e = next;
28.1115 + if (e == null)
28.1116 + throw new NoSuchElementException();
28.1117 + if (modCount != expectedModCount)
28.1118 + throw new ConcurrentModificationException();
28.1119 + next = successor(e);
28.1120 + lastReturned = e;
28.1121 + return e;
28.1122 + }
28.1123 +
28.1124 + final Entry<K,V> prevEntry() {
28.1125 + Entry<K,V> e = next;
28.1126 + if (e == null)
28.1127 + throw new NoSuchElementException();
28.1128 + if (modCount != expectedModCount)
28.1129 + throw new ConcurrentModificationException();
28.1130 + next = predecessor(e);
28.1131 + lastReturned = e;
28.1132 + return e;
28.1133 + }
28.1134 +
28.1135 + public void remove() {
28.1136 + if (lastReturned == null)
28.1137 + throw new IllegalStateException();
28.1138 + if (modCount != expectedModCount)
28.1139 + throw new ConcurrentModificationException();
28.1140 + // deleted entries are replaced by their successors
28.1141 + if (lastReturned.left != null && lastReturned.right != null)
28.1142 + next = lastReturned;
28.1143 + deleteEntry(lastReturned);
28.1144 + expectedModCount = modCount;
28.1145 + lastReturned = null;
28.1146 + }
28.1147 + }
28.1148 +
28.1149 + final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
28.1150 + EntryIterator(Entry<K,V> first) {
28.1151 + super(first);
28.1152 + }
28.1153 + public Map.Entry<K,V> next() {
28.1154 + return nextEntry();
28.1155 + }
28.1156 + }
28.1157 +
28.1158 + final class ValueIterator extends PrivateEntryIterator<V> {
28.1159 + ValueIterator(Entry<K,V> first) {
28.1160 + super(first);
28.1161 + }
28.1162 + public V next() {
28.1163 + return nextEntry().value;
28.1164 + }
28.1165 + }
28.1166 +
28.1167 + final class KeyIterator extends PrivateEntryIterator<K> {
28.1168 + KeyIterator(Entry<K,V> first) {
28.1169 + super(first);
28.1170 + }
28.1171 + public K next() {
28.1172 + return nextEntry().key;
28.1173 + }
28.1174 + }
28.1175 +
28.1176 + final class DescendingKeyIterator extends PrivateEntryIterator<K> {
28.1177 + DescendingKeyIterator(Entry<K,V> first) {
28.1178 + super(first);
28.1179 + }
28.1180 + public K next() {
28.1181 + return prevEntry().key;
28.1182 + }
28.1183 + }
28.1184 +
28.1185 + // Little utilities
28.1186 +
28.1187 + /**
28.1188 + * Compares two keys using the correct comparison method for this TreeMap.
28.1189 + */
28.1190 + final int compare(Object k1, Object k2) {
28.1191 + return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
28.1192 + : comparator.compare((K)k1, (K)k2);
28.1193 + }
28.1194 +
28.1195 + /**
28.1196 + * Test two values for equality. Differs from o1.equals(o2) only in
28.1197 + * that it copes with {@code null} o1 properly.
28.1198 + */
28.1199 + static final boolean valEquals(Object o1, Object o2) {
28.1200 + return (o1==null ? o2==null : o1.equals(o2));
28.1201 + }
28.1202 +
28.1203 + /**
28.1204 + * Return SimpleImmutableEntry for entry, or null if null
28.1205 + */
28.1206 + static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
28.1207 + return (e == null) ? null :
28.1208 + new AbstractMap.SimpleImmutableEntry<>(e);
28.1209 + }
28.1210 +
28.1211 + /**
28.1212 + * Return key for entry, or null if null
28.1213 + */
28.1214 + static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) {
28.1215 + return (e == null) ? null : e.key;
28.1216 + }
28.1217 +
28.1218 + /**
28.1219 + * Returns the key corresponding to the specified Entry.
28.1220 + * @throws NoSuchElementException if the Entry is null
28.1221 + */
28.1222 + static <K> K key(Entry<K,?> e) {
28.1223 + if (e==null)
28.1224 + throw new NoSuchElementException();
28.1225 + return e.key;
28.1226 + }
28.1227 +
28.1228 +
28.1229 + // SubMaps
28.1230 +
28.1231 + /**
28.1232 + * Dummy value serving as unmatchable fence key for unbounded
28.1233 + * SubMapIterators
28.1234 + */
28.1235 + private static final Object UNBOUNDED = new Object();
28.1236 +
28.1237 + /**
28.1238 + * @serial include
28.1239 + */
28.1240 + abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
28.1241 + implements NavigableMap<K,V>, java.io.Serializable {
28.1242 + /**
28.1243 + * The backing map.
28.1244 + */
28.1245 + final TreeMap<K,V> m;
28.1246 +
28.1247 + /**
28.1248 + * Endpoints are represented as triples (fromStart, lo,
28.1249 + * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is
28.1250 + * true, then the low (absolute) bound is the start of the
28.1251 + * backing map, and the other values are ignored. Otherwise,
28.1252 + * if loInclusive is true, lo is the inclusive bound, else lo
28.1253 + * is the exclusive bound. Similarly for the upper bound.
28.1254 + */
28.1255 + final K lo, hi;
28.1256 + final boolean fromStart, toEnd;
28.1257 + final boolean loInclusive, hiInclusive;
28.1258 +
28.1259 + NavigableSubMap(TreeMap<K,V> m,
28.1260 + boolean fromStart, K lo, boolean loInclusive,
28.1261 + boolean toEnd, K hi, boolean hiInclusive) {
28.1262 + if (!fromStart && !toEnd) {
28.1263 + if (m.compare(lo, hi) > 0)
28.1264 + throw new IllegalArgumentException("fromKey > toKey");
28.1265 + } else {
28.1266 + if (!fromStart) // type check
28.1267 + m.compare(lo, lo);
28.1268 + if (!toEnd)
28.1269 + m.compare(hi, hi);
28.1270 + }
28.1271 +
28.1272 + this.m = m;
28.1273 + this.fromStart = fromStart;
28.1274 + this.lo = lo;
28.1275 + this.loInclusive = loInclusive;
28.1276 + this.toEnd = toEnd;
28.1277 + this.hi = hi;
28.1278 + this.hiInclusive = hiInclusive;
28.1279 + }
28.1280 +
28.1281 + // internal utilities
28.1282 +
28.1283 + final boolean tooLow(Object key) {
28.1284 + if (!fromStart) {
28.1285 + int c = m.compare(key, lo);
28.1286 + if (c < 0 || (c == 0 && !loInclusive))
28.1287 + return true;
28.1288 + }
28.1289 + return false;
28.1290 + }
28.1291 +
28.1292 + final boolean tooHigh(Object key) {
28.1293 + if (!toEnd) {
28.1294 + int c = m.compare(key, hi);
28.1295 + if (c > 0 || (c == 0 && !hiInclusive))
28.1296 + return true;
28.1297 + }
28.1298 + return false;
28.1299 + }
28.1300 +
28.1301 + final boolean inRange(Object key) {
28.1302 + return !tooLow(key) && !tooHigh(key);
28.1303 + }
28.1304 +
28.1305 + final boolean inClosedRange(Object key) {
28.1306 + return (fromStart || m.compare(key, lo) >= 0)
28.1307 + && (toEnd || m.compare(hi, key) >= 0);
28.1308 + }
28.1309 +
28.1310 + final boolean inRange(Object key, boolean inclusive) {
28.1311 + return inclusive ? inRange(key) : inClosedRange(key);
28.1312 + }
28.1313 +
28.1314 + /*
28.1315 + * Absolute versions of relation operations.
28.1316 + * Subclasses map to these using like-named "sub"
28.1317 + * versions that invert senses for descending maps
28.1318 + */
28.1319 +
28.1320 + final TreeMap.Entry<K,V> absLowest() {
28.1321 + TreeMap.Entry<K,V> e =
28.1322 + (fromStart ? m.getFirstEntry() :
28.1323 + (loInclusive ? m.getCeilingEntry(lo) :
28.1324 + m.getHigherEntry(lo)));
28.1325 + return (e == null || tooHigh(e.key)) ? null : e;
28.1326 + }
28.1327 +
28.1328 + final TreeMap.Entry<K,V> absHighest() {
28.1329 + TreeMap.Entry<K,V> e =
28.1330 + (toEnd ? m.getLastEntry() :
28.1331 + (hiInclusive ? m.getFloorEntry(hi) :
28.1332 + m.getLowerEntry(hi)));
28.1333 + return (e == null || tooLow(e.key)) ? null : e;
28.1334 + }
28.1335 +
28.1336 + final TreeMap.Entry<K,V> absCeiling(K key) {
28.1337 + if (tooLow(key))
28.1338 + return absLowest();
28.1339 + TreeMap.Entry<K,V> e = m.getCeilingEntry(key);
28.1340 + return (e == null || tooHigh(e.key)) ? null : e;
28.1341 + }
28.1342 +
28.1343 + final TreeMap.Entry<K,V> absHigher(K key) {
28.1344 + if (tooLow(key))
28.1345 + return absLowest();
28.1346 + TreeMap.Entry<K,V> e = m.getHigherEntry(key);
28.1347 + return (e == null || tooHigh(e.key)) ? null : e;
28.1348 + }
28.1349 +
28.1350 + final TreeMap.Entry<K,V> absFloor(K key) {
28.1351 + if (tooHigh(key))
28.1352 + return absHighest();
28.1353 + TreeMap.Entry<K,V> e = m.getFloorEntry(key);
28.1354 + return (e == null || tooLow(e.key)) ? null : e;
28.1355 + }
28.1356 +
28.1357 + final TreeMap.Entry<K,V> absLower(K key) {
28.1358 + if (tooHigh(key))
28.1359 + return absHighest();
28.1360 + TreeMap.Entry<K,V> e = m.getLowerEntry(key);
28.1361 + return (e == null || tooLow(e.key)) ? null : e;
28.1362 + }
28.1363 +
28.1364 + /** Returns the absolute high fence for ascending traversal */
28.1365 + final TreeMap.Entry<K,V> absHighFence() {
28.1366 + return (toEnd ? null : (hiInclusive ?
28.1367 + m.getHigherEntry(hi) :
28.1368 + m.getCeilingEntry(hi)));
28.1369 + }
28.1370 +
28.1371 + /** Return the absolute low fence for descending traversal */
28.1372 + final TreeMap.Entry<K,V> absLowFence() {
28.1373 + return (fromStart ? null : (loInclusive ?
28.1374 + m.getLowerEntry(lo) :
28.1375 + m.getFloorEntry(lo)));
28.1376 + }
28.1377 +
28.1378 + // Abstract methods defined in ascending vs descending classes
28.1379 + // These relay to the appropriate absolute versions
28.1380 +
28.1381 + abstract TreeMap.Entry<K,V> subLowest();
28.1382 + abstract TreeMap.Entry<K,V> subHighest();
28.1383 + abstract TreeMap.Entry<K,V> subCeiling(K key);
28.1384 + abstract TreeMap.Entry<K,V> subHigher(K key);
28.1385 + abstract TreeMap.Entry<K,V> subFloor(K key);
28.1386 + abstract TreeMap.Entry<K,V> subLower(K key);
28.1387 +
28.1388 + /** Returns ascending iterator from the perspective of this submap */
28.1389 + abstract Iterator<K> keyIterator();
28.1390 +
28.1391 + /** Returns descending iterator from the perspective of this submap */
28.1392 + abstract Iterator<K> descendingKeyIterator();
28.1393 +
28.1394 + // public methods
28.1395 +
28.1396 + public boolean isEmpty() {
28.1397 + return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty();
28.1398 + }
28.1399 +
28.1400 + public int size() {
28.1401 + return (fromStart && toEnd) ? m.size() : entrySet().size();
28.1402 + }
28.1403 +
28.1404 + public final boolean containsKey(Object key) {
28.1405 + return inRange(key) && m.containsKey(key);
28.1406 + }
28.1407 +
28.1408 + public final V put(K key, V value) {
28.1409 + if (!inRange(key))
28.1410 + throw new IllegalArgumentException("key out of range");
28.1411 + return m.put(key, value);
28.1412 + }
28.1413 +
28.1414 + public final V get(Object key) {
28.1415 + return !inRange(key) ? null : m.get(key);
28.1416 + }
28.1417 +
28.1418 + public final V remove(Object key) {
28.1419 + return !inRange(key) ? null : m.remove(key);
28.1420 + }
28.1421 +
28.1422 + public final Map.Entry<K,V> ceilingEntry(K key) {
28.1423 + return exportEntry(subCeiling(key));
28.1424 + }
28.1425 +
28.1426 + public final K ceilingKey(K key) {
28.1427 + return keyOrNull(subCeiling(key));
28.1428 + }
28.1429 +
28.1430 + public final Map.Entry<K,V> higherEntry(K key) {
28.1431 + return exportEntry(subHigher(key));
28.1432 + }
28.1433 +
28.1434 + public final K higherKey(K key) {
28.1435 + return keyOrNull(subHigher(key));
28.1436 + }
28.1437 +
28.1438 + public final Map.Entry<K,V> floorEntry(K key) {
28.1439 + return exportEntry(subFloor(key));
28.1440 + }
28.1441 +
28.1442 + public final K floorKey(K key) {
28.1443 + return keyOrNull(subFloor(key));
28.1444 + }
28.1445 +
28.1446 + public final Map.Entry<K,V> lowerEntry(K key) {
28.1447 + return exportEntry(subLower(key));
28.1448 + }
28.1449 +
28.1450 + public final K lowerKey(K key) {
28.1451 + return keyOrNull(subLower(key));
28.1452 + }
28.1453 +
28.1454 + public final K firstKey() {
28.1455 + return key(subLowest());
28.1456 + }
28.1457 +
28.1458 + public final K lastKey() {
28.1459 + return key(subHighest());
28.1460 + }
28.1461 +
28.1462 + public final Map.Entry<K,V> firstEntry() {
28.1463 + return exportEntry(subLowest());
28.1464 + }
28.1465 +
28.1466 + public final Map.Entry<K,V> lastEntry() {
28.1467 + return exportEntry(subHighest());
28.1468 + }
28.1469 +
28.1470 + public final Map.Entry<K,V> pollFirstEntry() {
28.1471 + TreeMap.Entry<K,V> e = subLowest();
28.1472 + Map.Entry<K,V> result = exportEntry(e);
28.1473 + if (e != null)
28.1474 + m.deleteEntry(e);
28.1475 + return result;
28.1476 + }
28.1477 +
28.1478 + public final Map.Entry<K,V> pollLastEntry() {
28.1479 + TreeMap.Entry<K,V> e = subHighest();
28.1480 + Map.Entry<K,V> result = exportEntry(e);
28.1481 + if (e != null)
28.1482 + m.deleteEntry(e);
28.1483 + return result;
28.1484 + }
28.1485 +
28.1486 + // Views
28.1487 + transient NavigableMap<K,V> descendingMapView = null;
28.1488 + transient EntrySetView entrySetView = null;
28.1489 + transient KeySet<K> navigableKeySetView = null;
28.1490 +
28.1491 + public final NavigableSet<K> navigableKeySet() {
28.1492 + KeySet<K> nksv = navigableKeySetView;
28.1493 + return (nksv != null) ? nksv :
28.1494 + (navigableKeySetView = new TreeMap.KeySet(this));
28.1495 + }
28.1496 +
28.1497 + public final Set<K> keySet() {
28.1498 + return navigableKeySet();
28.1499 + }
28.1500 +
28.1501 + public NavigableSet<K> descendingKeySet() {
28.1502 + return descendingMap().navigableKeySet();
28.1503 + }
28.1504 +
28.1505 + public final SortedMap<K,V> subMap(K fromKey, K toKey) {
28.1506 + return subMap(fromKey, true, toKey, false);
28.1507 + }
28.1508 +
28.1509 + public final SortedMap<K,V> headMap(K toKey) {
28.1510 + return headMap(toKey, false);
28.1511 + }
28.1512 +
28.1513 + public final SortedMap<K,V> tailMap(K fromKey) {
28.1514 + return tailMap(fromKey, true);
28.1515 + }
28.1516 +
28.1517 + // View classes
28.1518 +
28.1519 + abstract class EntrySetView extends AbstractSet<Map.Entry<K,V>> {
28.1520 + private transient int size = -1, sizeModCount;
28.1521 +
28.1522 + public int size() {
28.1523 + if (fromStart && toEnd)
28.1524 + return m.size();
28.1525 + if (size == -1 || sizeModCount != m.modCount) {
28.1526 + sizeModCount = m.modCount;
28.1527 + size = 0;
28.1528 + Iterator i = iterator();
28.1529 + while (i.hasNext()) {
28.1530 + size++;
28.1531 + i.next();
28.1532 + }
28.1533 + }
28.1534 + return size;
28.1535 + }
28.1536 +
28.1537 + public boolean isEmpty() {
28.1538 + TreeMap.Entry<K,V> n = absLowest();
28.1539 + return n == null || tooHigh(n.key);
28.1540 + }
28.1541 +
28.1542 + public boolean contains(Object o) {
28.1543 + if (!(o instanceof Map.Entry))
28.1544 + return false;
28.1545 + Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
28.1546 + K key = entry.getKey();
28.1547 + if (!inRange(key))
28.1548 + return false;
28.1549 + TreeMap.Entry node = m.getEntry(key);
28.1550 + return node != null &&
28.1551 + valEquals(node.getValue(), entry.getValue());
28.1552 + }
28.1553 +
28.1554 + public boolean remove(Object o) {
28.1555 + if (!(o instanceof Map.Entry))
28.1556 + return false;
28.1557 + Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
28.1558 + K key = entry.getKey();
28.1559 + if (!inRange(key))
28.1560 + return false;
28.1561 + TreeMap.Entry<K,V> node = m.getEntry(key);
28.1562 + if (node!=null && valEquals(node.getValue(),
28.1563 + entry.getValue())) {
28.1564 + m.deleteEntry(node);
28.1565 + return true;
28.1566 + }
28.1567 + return false;
28.1568 + }
28.1569 + }
28.1570 +
28.1571 + /**
28.1572 + * Iterators for SubMaps
28.1573 + */
28.1574 + abstract class SubMapIterator<T> implements Iterator<T> {
28.1575 + TreeMap.Entry<K,V> lastReturned;
28.1576 + TreeMap.Entry<K,V> next;
28.1577 + final Object fenceKey;
28.1578 + int expectedModCount;
28.1579 +
28.1580 + SubMapIterator(TreeMap.Entry<K,V> first,
28.1581 + TreeMap.Entry<K,V> fence) {
28.1582 + expectedModCount = m.modCount;
28.1583 + lastReturned = null;
28.1584 + next = first;
28.1585 + fenceKey = fence == null ? UNBOUNDED : fence.key;
28.1586 + }
28.1587 +
28.1588 + public final boolean hasNext() {
28.1589 + return next != null && next.key != fenceKey;
28.1590 + }
28.1591 +
28.1592 + final TreeMap.Entry<K,V> nextEntry() {
28.1593 + TreeMap.Entry<K,V> e = next;
28.1594 + if (e == null || e.key == fenceKey)
28.1595 + throw new NoSuchElementException();
28.1596 + if (m.modCount != expectedModCount)
28.1597 + throw new ConcurrentModificationException();
28.1598 + next = successor(e);
28.1599 + lastReturned = e;
28.1600 + return e;
28.1601 + }
28.1602 +
28.1603 + final TreeMap.Entry<K,V> prevEntry() {
28.1604 + TreeMap.Entry<K,V> e = next;
28.1605 + if (e == null || e.key == fenceKey)
28.1606 + throw new NoSuchElementException();
28.1607 + if (m.modCount != expectedModCount)
28.1608 + throw new ConcurrentModificationException();
28.1609 + next = predecessor(e);
28.1610 + lastReturned = e;
28.1611 + return e;
28.1612 + }
28.1613 +
28.1614 + final void removeAscending() {
28.1615 + if (lastReturned == null)
28.1616 + throw new IllegalStateException();
28.1617 + if (m.modCount != expectedModCount)
28.1618 + throw new ConcurrentModificationException();
28.1619 + // deleted entries are replaced by their successors
28.1620 + if (lastReturned.left != null && lastReturned.right != null)
28.1621 + next = lastReturned;
28.1622 + m.deleteEntry(lastReturned);
28.1623 + lastReturned = null;
28.1624 + expectedModCount = m.modCount;
28.1625 + }
28.1626 +
28.1627 + final void removeDescending() {
28.1628 + if (lastReturned == null)
28.1629 + throw new IllegalStateException();
28.1630 + if (m.modCount != expectedModCount)
28.1631 + throw new ConcurrentModificationException();
28.1632 + m.deleteEntry(lastReturned);
28.1633 + lastReturned = null;
28.1634 + expectedModCount = m.modCount;
28.1635 + }
28.1636 +
28.1637 + }
28.1638 +
28.1639 + final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
28.1640 + SubMapEntryIterator(TreeMap.Entry<K,V> first,
28.1641 + TreeMap.Entry<K,V> fence) {
28.1642 + super(first, fence);
28.1643 + }
28.1644 + public Map.Entry<K,V> next() {
28.1645 + return nextEntry();
28.1646 + }
28.1647 + public void remove() {
28.1648 + removeAscending();
28.1649 + }
28.1650 + }
28.1651 +
28.1652 + final class SubMapKeyIterator extends SubMapIterator<K> {
28.1653 + SubMapKeyIterator(TreeMap.Entry<K,V> first,
28.1654 + TreeMap.Entry<K,V> fence) {
28.1655 + super(first, fence);
28.1656 + }
28.1657 + public K next() {
28.1658 + return nextEntry().key;
28.1659 + }
28.1660 + public void remove() {
28.1661 + removeAscending();
28.1662 + }
28.1663 + }
28.1664 +
28.1665 + final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
28.1666 + DescendingSubMapEntryIterator(TreeMap.Entry<K,V> last,
28.1667 + TreeMap.Entry<K,V> fence) {
28.1668 + super(last, fence);
28.1669 + }
28.1670 +
28.1671 + public Map.Entry<K,V> next() {
28.1672 + return prevEntry();
28.1673 + }
28.1674 + public void remove() {
28.1675 + removeDescending();
28.1676 + }
28.1677 + }
28.1678 +
28.1679 + final class DescendingSubMapKeyIterator extends SubMapIterator<K> {
28.1680 + DescendingSubMapKeyIterator(TreeMap.Entry<K,V> last,
28.1681 + TreeMap.Entry<K,V> fence) {
28.1682 + super(last, fence);
28.1683 + }
28.1684 + public K next() {
28.1685 + return prevEntry().key;
28.1686 + }
28.1687 + public void remove() {
28.1688 + removeDescending();
28.1689 + }
28.1690 + }
28.1691 + }
28.1692 +
28.1693 + /**
28.1694 + * @serial include
28.1695 + */
28.1696 + static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> {
28.1697 + private static final long serialVersionUID = 912986545866124060L;
28.1698 +
28.1699 + AscendingSubMap(TreeMap<K,V> m,
28.1700 + boolean fromStart, K lo, boolean loInclusive,
28.1701 + boolean toEnd, K hi, boolean hiInclusive) {
28.1702 + super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
28.1703 + }
28.1704 +
28.1705 + public Comparator<? super K> comparator() {
28.1706 + return m.comparator();
28.1707 + }
28.1708 +
28.1709 + public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
28.1710 + K toKey, boolean toInclusive) {
28.1711 + if (!inRange(fromKey, fromInclusive))
28.1712 + throw new IllegalArgumentException("fromKey out of range");
28.1713 + if (!inRange(toKey, toInclusive))
28.1714 + throw new IllegalArgumentException("toKey out of range");
28.1715 + return new AscendingSubMap(m,
28.1716 + false, fromKey, fromInclusive,
28.1717 + false, toKey, toInclusive);
28.1718 + }
28.1719 +
28.1720 + public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
28.1721 + if (!inRange(toKey, inclusive))
28.1722 + throw new IllegalArgumentException("toKey out of range");
28.1723 + return new AscendingSubMap(m,
28.1724 + fromStart, lo, loInclusive,
28.1725 + false, toKey, inclusive);
28.1726 + }
28.1727 +
28.1728 + public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
28.1729 + if (!inRange(fromKey, inclusive))
28.1730 + throw new IllegalArgumentException("fromKey out of range");
28.1731 + return new AscendingSubMap(m,
28.1732 + false, fromKey, inclusive,
28.1733 + toEnd, hi, hiInclusive);
28.1734 + }
28.1735 +
28.1736 + public NavigableMap<K,V> descendingMap() {
28.1737 + NavigableMap<K,V> mv = descendingMapView;
28.1738 + return (mv != null) ? mv :
28.1739 + (descendingMapView =
28.1740 + new DescendingSubMap(m,
28.1741 + fromStart, lo, loInclusive,
28.1742 + toEnd, hi, hiInclusive));
28.1743 + }
28.1744 +
28.1745 + Iterator<K> keyIterator() {
28.1746 + return new SubMapKeyIterator(absLowest(), absHighFence());
28.1747 + }
28.1748 +
28.1749 + Iterator<K> descendingKeyIterator() {
28.1750 + return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
28.1751 + }
28.1752 +
28.1753 + final class AscendingEntrySetView extends EntrySetView {
28.1754 + public Iterator<Map.Entry<K,V>> iterator() {
28.1755 + return new SubMapEntryIterator(absLowest(), absHighFence());
28.1756 + }
28.1757 + }
28.1758 +
28.1759 + public Set<Map.Entry<K,V>> entrySet() {
28.1760 + EntrySetView es = entrySetView;
28.1761 + return (es != null) ? es : new AscendingEntrySetView();
28.1762 + }
28.1763 +
28.1764 + TreeMap.Entry<K,V> subLowest() { return absLowest(); }
28.1765 + TreeMap.Entry<K,V> subHighest() { return absHighest(); }
28.1766 + TreeMap.Entry<K,V> subCeiling(K key) { return absCeiling(key); }
28.1767 + TreeMap.Entry<K,V> subHigher(K key) { return absHigher(key); }
28.1768 + TreeMap.Entry<K,V> subFloor(K key) { return absFloor(key); }
28.1769 + TreeMap.Entry<K,V> subLower(K key) { return absLower(key); }
28.1770 + }
28.1771 +
28.1772 + /**
28.1773 + * @serial include
28.1774 + */
28.1775 + static final class DescendingSubMap<K,V> extends NavigableSubMap<K,V> {
28.1776 + private static final long serialVersionUID = 912986545866120460L;
28.1777 + DescendingSubMap(TreeMap<K,V> m,
28.1778 + boolean fromStart, K lo, boolean loInclusive,
28.1779 + boolean toEnd, K hi, boolean hiInclusive) {
28.1780 + super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
28.1781 + }
28.1782 +
28.1783 + private final Comparator<? super K> reverseComparator =
28.1784 + Collections.reverseOrder(m.comparator);
28.1785 +
28.1786 + public Comparator<? super K> comparator() {
28.1787 + return reverseComparator;
28.1788 + }
28.1789 +
28.1790 + public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
28.1791 + K toKey, boolean toInclusive) {
28.1792 + if (!inRange(fromKey, fromInclusive))
28.1793 + throw new IllegalArgumentException("fromKey out of range");
28.1794 + if (!inRange(toKey, toInclusive))
28.1795 + throw new IllegalArgumentException("toKey out of range");
28.1796 + return new DescendingSubMap(m,
28.1797 + false, toKey, toInclusive,
28.1798 + false, fromKey, fromInclusive);
28.1799 + }
28.1800 +
28.1801 + public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
28.1802 + if (!inRange(toKey, inclusive))
28.1803 + throw new IllegalArgumentException("toKey out of range");
28.1804 + return new DescendingSubMap(m,
28.1805 + false, toKey, inclusive,
28.1806 + toEnd, hi, hiInclusive);
28.1807 + }
28.1808 +
28.1809 + public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
28.1810 + if (!inRange(fromKey, inclusive))
28.1811 + throw new IllegalArgumentException("fromKey out of range");
28.1812 + return new DescendingSubMap(m,
28.1813 + fromStart, lo, loInclusive,
28.1814 + false, fromKey, inclusive);
28.1815 + }
28.1816 +
28.1817 + public NavigableMap<K,V> descendingMap() {
28.1818 + NavigableMap<K,V> mv = descendingMapView;
28.1819 + return (mv != null) ? mv :
28.1820 + (descendingMapView =
28.1821 + new AscendingSubMap(m,
28.1822 + fromStart, lo, loInclusive,
28.1823 + toEnd, hi, hiInclusive));
28.1824 + }
28.1825 +
28.1826 + Iterator<K> keyIterator() {
28.1827 + return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
28.1828 + }
28.1829 +
28.1830 + Iterator<K> descendingKeyIterator() {
28.1831 + return new SubMapKeyIterator(absLowest(), absHighFence());
28.1832 + }
28.1833 +
28.1834 + final class DescendingEntrySetView extends EntrySetView {
28.1835 + public Iterator<Map.Entry<K,V>> iterator() {
28.1836 + return new DescendingSubMapEntryIterator(absHighest(), absLowFence());
28.1837 + }
28.1838 + }
28.1839 +
28.1840 + public Set<Map.Entry<K,V>> entrySet() {
28.1841 + EntrySetView es = entrySetView;
28.1842 + return (es != null) ? es : new DescendingEntrySetView();
28.1843 + }
28.1844 +
28.1845 + TreeMap.Entry<K,V> subLowest() { return absHighest(); }
28.1846 + TreeMap.Entry<K,V> subHighest() { return absLowest(); }
28.1847 + TreeMap.Entry<K,V> subCeiling(K key) { return absFloor(key); }
28.1848 + TreeMap.Entry<K,V> subHigher(K key) { return absLower(key); }
28.1849 + TreeMap.Entry<K,V> subFloor(K key) { return absCeiling(key); }
28.1850 + TreeMap.Entry<K,V> subLower(K key) { return absHigher(key); }
28.1851 + }
28.1852 +
28.1853 + /**
28.1854 + * This class exists solely for the sake of serialization
28.1855 + * compatibility with previous releases of TreeMap that did not
28.1856 + * support NavigableMap. It translates an old-version SubMap into
28.1857 + * a new-version AscendingSubMap. This class is never otherwise
28.1858 + * used.
28.1859 + *
28.1860 + * @serial include
28.1861 + */
28.1862 + private class SubMap extends AbstractMap<K,V>
28.1863 + implements SortedMap<K,V>, java.io.Serializable {
28.1864 + private static final long serialVersionUID = -6520786458950516097L;
28.1865 + private boolean fromStart = false, toEnd = false;
28.1866 + private K fromKey, toKey;
28.1867 + private Object readResolve() {
28.1868 + return new AscendingSubMap(TreeMap.this,
28.1869 + fromStart, fromKey, true,
28.1870 + toEnd, toKey, false);
28.1871 + }
28.1872 + public Set<Map.Entry<K,V>> entrySet() { throw new InternalError(); }
28.1873 + public K lastKey() { throw new InternalError(); }
28.1874 + public K firstKey() { throw new InternalError(); }
28.1875 + public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); }
28.1876 + public SortedMap<K,V> headMap(K toKey) { throw new InternalError(); }
28.1877 + public SortedMap<K,V> tailMap(K fromKey) { throw new InternalError(); }
28.1878 + public Comparator<? super K> comparator() { throw new InternalError(); }
28.1879 + }
28.1880 +
28.1881 +
28.1882 + // Red-black mechanics
28.1883 +
28.1884 + private static final boolean RED = false;
28.1885 + private static final boolean BLACK = true;
28.1886 +
28.1887 + /**
28.1888 + * Node in the Tree. Doubles as a means to pass key-value pairs back to
28.1889 + * user (see Map.Entry).
28.1890 + */
28.1891 +
28.1892 + static final class Entry<K,V> implements Map.Entry<K,V> {
28.1893 + K key;
28.1894 + V value;
28.1895 + Entry<K,V> left = null;
28.1896 + Entry<K,V> right = null;
28.1897 + Entry<K,V> parent;
28.1898 + boolean color = BLACK;
28.1899 +
28.1900 + /**
28.1901 + * Make a new cell with given key, value, and parent, and with
28.1902 + * {@code null} child links, and BLACK color.
28.1903 + */
28.1904 + Entry(K key, V value, Entry<K,V> parent) {
28.1905 + this.key = key;
28.1906 + this.value = value;
28.1907 + this.parent = parent;
28.1908 + }
28.1909 +
28.1910 + /**
28.1911 + * Returns the key.
28.1912 + *
28.1913 + * @return the key
28.1914 + */
28.1915 + public K getKey() {
28.1916 + return key;
28.1917 + }
28.1918 +
28.1919 + /**
28.1920 + * Returns the value associated with the key.
28.1921 + *
28.1922 + * @return the value associated with the key
28.1923 + */
28.1924 + public V getValue() {
28.1925 + return value;
28.1926 + }
28.1927 +
28.1928 + /**
28.1929 + * Replaces the value currently associated with the key with the given
28.1930 + * value.
28.1931 + *
28.1932 + * @return the value associated with the key before this method was
28.1933 + * called
28.1934 + */
28.1935 + public V setValue(V value) {
28.1936 + V oldValue = this.value;
28.1937 + this.value = value;
28.1938 + return oldValue;
28.1939 + }
28.1940 +
28.1941 + public boolean equals(Object o) {
28.1942 + if (!(o instanceof Map.Entry))
28.1943 + return false;
28.1944 + Map.Entry<?,?> e = (Map.Entry<?,?>)o;
28.1945 +
28.1946 + return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
28.1947 + }
28.1948 +
28.1949 + public int hashCode() {
28.1950 + int keyHash = (key==null ? 0 : key.hashCode());
28.1951 + int valueHash = (value==null ? 0 : value.hashCode());
28.1952 + return keyHash ^ valueHash;
28.1953 + }
28.1954 +
28.1955 + public String toString() {
28.1956 + return key + "=" + value;
28.1957 + }
28.1958 + }
28.1959 +
28.1960 + /**
28.1961 + * Returns the first Entry in the TreeMap (according to the TreeMap's
28.1962 + * key-sort function). Returns null if the TreeMap is empty.
28.1963 + */
28.1964 + final Entry<K,V> getFirstEntry() {
28.1965 + Entry<K,V> p = root;
28.1966 + if (p != null)
28.1967 + while (p.left != null)
28.1968 + p = p.left;
28.1969 + return p;
28.1970 + }
28.1971 +
28.1972 + /**
28.1973 + * Returns the last Entry in the TreeMap (according to the TreeMap's
28.1974 + * key-sort function). Returns null if the TreeMap is empty.
28.1975 + */
28.1976 + final Entry<K,V> getLastEntry() {
28.1977 + Entry<K,V> p = root;
28.1978 + if (p != null)
28.1979 + while (p.right != null)
28.1980 + p = p.right;
28.1981 + return p;
28.1982 + }
28.1983 +
28.1984 + /**
28.1985 + * Returns the successor of the specified Entry, or null if no such.
28.1986 + */
28.1987 + static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
28.1988 + if (t == null)
28.1989 + return null;
28.1990 + else if (t.right != null) {
28.1991 + Entry<K,V> p = t.right;
28.1992 + while (p.left != null)
28.1993 + p = p.left;
28.1994 + return p;
28.1995 + } else {
28.1996 + Entry<K,V> p = t.parent;
28.1997 + Entry<K,V> ch = t;
28.1998 + while (p != null && ch == p.right) {
28.1999 + ch = p;
28.2000 + p = p.parent;
28.2001 + }
28.2002 + return p;
28.2003 + }
28.2004 + }
28.2005 +
28.2006 + /**
28.2007 + * Returns the predecessor of the specified Entry, or null if no such.
28.2008 + */
28.2009 + static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {
28.2010 + if (t == null)
28.2011 + return null;
28.2012 + else if (t.left != null) {
28.2013 + Entry<K,V> p = t.left;
28.2014 + while (p.right != null)
28.2015 + p = p.right;
28.2016 + return p;
28.2017 + } else {
28.2018 + Entry<K,V> p = t.parent;
28.2019 + Entry<K,V> ch = t;
28.2020 + while (p != null && ch == p.left) {
28.2021 + ch = p;
28.2022 + p = p.parent;
28.2023 + }
28.2024 + return p;
28.2025 + }
28.2026 + }
28.2027 +
28.2028 + /**
28.2029 + * Balancing operations.
28.2030 + *
28.2031 + * Implementations of rebalancings during insertion and deletion are
28.2032 + * slightly different than the CLR version. Rather than using dummy
28.2033 + * nilnodes, we use a set of accessors that deal properly with null. They
28.2034 + * are used to avoid messiness surrounding nullness checks in the main
28.2035 + * algorithms.
28.2036 + */
28.2037 +
28.2038 + private static <K,V> boolean colorOf(Entry<K,V> p) {
28.2039 + return (p == null ? BLACK : p.color);
28.2040 + }
28.2041 +
28.2042 + private static <K,V> Entry<K,V> parentOf(Entry<K,V> p) {
28.2043 + return (p == null ? null: p.parent);
28.2044 + }
28.2045 +
28.2046 + private static <K,V> void setColor(Entry<K,V> p, boolean c) {
28.2047 + if (p != null)
28.2048 + p.color = c;
28.2049 + }
28.2050 +
28.2051 + private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) {
28.2052 + return (p == null) ? null: p.left;
28.2053 + }
28.2054 +
28.2055 + private static <K,V> Entry<K,V> rightOf(Entry<K,V> p) {
28.2056 + return (p == null) ? null: p.right;
28.2057 + }
28.2058 +
28.2059 + /** From CLR */
28.2060 + private void rotateLeft(Entry<K,V> p) {
28.2061 + if (p != null) {
28.2062 + Entry<K,V> r = p.right;
28.2063 + p.right = r.left;
28.2064 + if (r.left != null)
28.2065 + r.left.parent = p;
28.2066 + r.parent = p.parent;
28.2067 + if (p.parent == null)
28.2068 + root = r;
28.2069 + else if (p.parent.left == p)
28.2070 + p.parent.left = r;
28.2071 + else
28.2072 + p.parent.right = r;
28.2073 + r.left = p;
28.2074 + p.parent = r;
28.2075 + }
28.2076 + }
28.2077 +
28.2078 + /** From CLR */
28.2079 + private void rotateRight(Entry<K,V> p) {
28.2080 + if (p != null) {
28.2081 + Entry<K,V> l = p.left;
28.2082 + p.left = l.right;
28.2083 + if (l.right != null) l.right.parent = p;
28.2084 + l.parent = p.parent;
28.2085 + if (p.parent == null)
28.2086 + root = l;
28.2087 + else if (p.parent.right == p)
28.2088 + p.parent.right = l;
28.2089 + else p.parent.left = l;
28.2090 + l.right = p;
28.2091 + p.parent = l;
28.2092 + }
28.2093 + }
28.2094 +
28.2095 + /** From CLR */
28.2096 + private void fixAfterInsertion(Entry<K,V> x) {
28.2097 + x.color = RED;
28.2098 +
28.2099 + while (x != null && x != root && x.parent.color == RED) {
28.2100 + if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
28.2101 + Entry<K,V> y = rightOf(parentOf(parentOf(x)));
28.2102 + if (colorOf(y) == RED) {
28.2103 + setColor(parentOf(x), BLACK);
28.2104 + setColor(y, BLACK);
28.2105 + setColor(parentOf(parentOf(x)), RED);
28.2106 + x = parentOf(parentOf(x));
28.2107 + } else {
28.2108 + if (x == rightOf(parentOf(x))) {
28.2109 + x = parentOf(x);
28.2110 + rotateLeft(x);
28.2111 + }
28.2112 + setColor(parentOf(x), BLACK);
28.2113 + setColor(parentOf(parentOf(x)), RED);
28.2114 + rotateRight(parentOf(parentOf(x)));
28.2115 + }
28.2116 + } else {
28.2117 + Entry<K,V> y = leftOf(parentOf(parentOf(x)));
28.2118 + if (colorOf(y) == RED) {
28.2119 + setColor(parentOf(x), BLACK);
28.2120 + setColor(y, BLACK);
28.2121 + setColor(parentOf(parentOf(x)), RED);
28.2122 + x = parentOf(parentOf(x));
28.2123 + } else {
28.2124 + if (x == leftOf(parentOf(x))) {
28.2125 + x = parentOf(x);
28.2126 + rotateRight(x);
28.2127 + }
28.2128 + setColor(parentOf(x), BLACK);
28.2129 + setColor(parentOf(parentOf(x)), RED);
28.2130 + rotateLeft(parentOf(parentOf(x)));
28.2131 + }
28.2132 + }
28.2133 + }
28.2134 + root.color = BLACK;
28.2135 + }
28.2136 +
28.2137 + /**
28.2138 + * Delete node p, and then rebalance the tree.
28.2139 + */
28.2140 + private void deleteEntry(Entry<K,V> p) {
28.2141 + modCount++;
28.2142 + size--;
28.2143 +
28.2144 + // If strictly internal, copy successor's element to p and then make p
28.2145 + // point to successor.
28.2146 + if (p.left != null && p.right != null) {
28.2147 + Entry<K,V> s = successor(p);
28.2148 + p.key = s.key;
28.2149 + p.value = s.value;
28.2150 + p = s;
28.2151 + } // p has 2 children
28.2152 +
28.2153 + // Start fixup at replacement node, if it exists.
28.2154 + Entry<K,V> replacement = (p.left != null ? p.left : p.right);
28.2155 +
28.2156 + if (replacement != null) {
28.2157 + // Link replacement to parent
28.2158 + replacement.parent = p.parent;
28.2159 + if (p.parent == null)
28.2160 + root = replacement;
28.2161 + else if (p == p.parent.left)
28.2162 + p.parent.left = replacement;
28.2163 + else
28.2164 + p.parent.right = replacement;
28.2165 +
28.2166 + // Null out links so they are OK to use by fixAfterDeletion.
28.2167 + p.left = p.right = p.parent = null;
28.2168 +
28.2169 + // Fix replacement
28.2170 + if (p.color == BLACK)
28.2171 + fixAfterDeletion(replacement);
28.2172 + } else if (p.parent == null) { // return if we are the only node.
28.2173 + root = null;
28.2174 + } else { // No children. Use self as phantom replacement and unlink.
28.2175 + if (p.color == BLACK)
28.2176 + fixAfterDeletion(p);
28.2177 +
28.2178 + if (p.parent != null) {
28.2179 + if (p == p.parent.left)
28.2180 + p.parent.left = null;
28.2181 + else if (p == p.parent.right)
28.2182 + p.parent.right = null;
28.2183 + p.parent = null;
28.2184 + }
28.2185 + }
28.2186 + }
28.2187 +
28.2188 + /** From CLR */
28.2189 + private void fixAfterDeletion(Entry<K,V> x) {
28.2190 + while (x != root && colorOf(x) == BLACK) {
28.2191 + if (x == leftOf(parentOf(x))) {
28.2192 + Entry<K,V> sib = rightOf(parentOf(x));
28.2193 +
28.2194 + if (colorOf(sib) == RED) {
28.2195 + setColor(sib, BLACK);
28.2196 + setColor(parentOf(x), RED);
28.2197 + rotateLeft(parentOf(x));
28.2198 + sib = rightOf(parentOf(x));
28.2199 + }
28.2200 +
28.2201 + if (colorOf(leftOf(sib)) == BLACK &&
28.2202 + colorOf(rightOf(sib)) == BLACK) {
28.2203 + setColor(sib, RED);
28.2204 + x = parentOf(x);
28.2205 + } else {
28.2206 + if (colorOf(rightOf(sib)) == BLACK) {
28.2207 + setColor(leftOf(sib), BLACK);
28.2208 + setColor(sib, RED);
28.2209 + rotateRight(sib);
28.2210 + sib = rightOf(parentOf(x));
28.2211 + }
28.2212 + setColor(sib, colorOf(parentOf(x)));
28.2213 + setColor(parentOf(x), BLACK);
28.2214 + setColor(rightOf(sib), BLACK);
28.2215 + rotateLeft(parentOf(x));
28.2216 + x = root;
28.2217 + }
28.2218 + } else { // symmetric
28.2219 + Entry<K,V> sib = leftOf(parentOf(x));
28.2220 +
28.2221 + if (colorOf(sib) == RED) {
28.2222 + setColor(sib, BLACK);
28.2223 + setColor(parentOf(x), RED);
28.2224 + rotateRight(parentOf(x));
28.2225 + sib = leftOf(parentOf(x));
28.2226 + }
28.2227 +
28.2228 + if (colorOf(rightOf(sib)) == BLACK &&
28.2229 + colorOf(leftOf(sib)) == BLACK) {
28.2230 + setColor(sib, RED);
28.2231 + x = parentOf(x);
28.2232 + } else {
28.2233 + if (colorOf(leftOf(sib)) == BLACK) {
28.2234 + setColor(rightOf(sib), BLACK);
28.2235 + setColor(sib, RED);
28.2236 + rotateLeft(sib);
28.2237 + sib = leftOf(parentOf(x));
28.2238 + }
28.2239 + setColor(sib, colorOf(parentOf(x)));
28.2240 + setColor(parentOf(x), BLACK);
28.2241 + setColor(leftOf(sib), BLACK);
28.2242 + rotateRight(parentOf(x));
28.2243 + x = root;
28.2244 + }
28.2245 + }
28.2246 + }
28.2247 +
28.2248 + setColor(x, BLACK);
28.2249 + }
28.2250 +
28.2251 + private static final long serialVersionUID = 919286545866124006L;
28.2252 +
28.2253 + /**
28.2254 + * Save the state of the {@code TreeMap} instance to a stream (i.e.,
28.2255 + * serialize it).
28.2256 + *
28.2257 + * @serialData The <em>size</em> of the TreeMap (the number of key-value
28.2258 + * mappings) is emitted (int), followed by the key (Object)
28.2259 + * and value (Object) for each key-value mapping represented
28.2260 + * by the TreeMap. The key-value mappings are emitted in
28.2261 + * key-order (as determined by the TreeMap's Comparator,
28.2262 + * or by the keys' natural ordering if the TreeMap has no
28.2263 + * Comparator).
28.2264 + */
28.2265 + private void writeObject(java.io.ObjectOutputStream s)
28.2266 + throws java.io.IOException {
28.2267 + // Write out the Comparator and any hidden stuff
28.2268 + s.defaultWriteObject();
28.2269 +
28.2270 + // Write out size (number of Mappings)
28.2271 + s.writeInt(size);
28.2272 +
28.2273 + // Write out keys and values (alternating)
28.2274 + for (Iterator<Map.Entry<K,V>> i = entrySet().iterator(); i.hasNext(); ) {
28.2275 + Map.Entry<K,V> e = i.next();
28.2276 + s.writeObject(e.getKey());
28.2277 + s.writeObject(e.getValue());
28.2278 + }
28.2279 + }
28.2280 +
28.2281 + /**
28.2282 + * Reconstitute the {@code TreeMap} instance from a stream (i.e.,
28.2283 + * deserialize it).
28.2284 + */
28.2285 + private void readObject(final java.io.ObjectInputStream s)
28.2286 + throws java.io.IOException, ClassNotFoundException {
28.2287 + // Read in the Comparator and any hidden stuff
28.2288 + s.defaultReadObject();
28.2289 +
28.2290 + // Read in size
28.2291 + int size = s.readInt();
28.2292 +
28.2293 + buildFromSorted(size, null, s, null);
28.2294 + }
28.2295 +
28.2296 + /** Intended to be called only from TreeSet.readObject */
28.2297 + void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal)
28.2298 + throws java.io.IOException, ClassNotFoundException {
28.2299 + buildFromSorted(size, null, s, defaultVal);
28.2300 + }
28.2301 +
28.2302 + /** Intended to be called only from TreeSet.addAll */
28.2303 + void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) {
28.2304 + try {
28.2305 + buildFromSorted(set.size(), set.iterator(), null, defaultVal);
28.2306 + } catch (java.io.IOException cannotHappen) {
28.2307 + } catch (ClassNotFoundException cannotHappen) {
28.2308 + }
28.2309 + }
28.2310 +
28.2311 +
28.2312 + /**
28.2313 + * Linear time tree building algorithm from sorted data. Can accept keys
28.2314 + * and/or values from iterator or stream. This leads to too many
28.2315 + * parameters, but seems better than alternatives. The four formats
28.2316 + * that this method accepts are:
28.2317 + *
28.2318 + * 1) An iterator of Map.Entries. (it != null, defaultVal == null).
28.2319 + * 2) An iterator of keys. (it != null, defaultVal != null).
28.2320 + * 3) A stream of alternating serialized keys and values.
28.2321 + * (it == null, defaultVal == null).
28.2322 + * 4) A stream of serialized keys. (it == null, defaultVal != null).
28.2323 + *
28.2324 + * It is assumed that the comparator of the TreeMap is already set prior
28.2325 + * to calling this method.
28.2326 + *
28.2327 + * @param size the number of keys (or key-value pairs) to be read from
28.2328 + * the iterator or stream
28.2329 + * @param it If non-null, new entries are created from entries
28.2330 + * or keys read from this iterator.
28.2331 + * @param str If non-null, new entries are created from keys and
28.2332 + * possibly values read from this stream in serialized form.
28.2333 + * Exactly one of it and str should be non-null.
28.2334 + * @param defaultVal if non-null, this default value is used for
28.2335 + * each value in the map. If null, each value is read from
28.2336 + * iterator or stream, as described above.
28.2337 + * @throws IOException propagated from stream reads. This cannot
28.2338 + * occur if str is null.
28.2339 + * @throws ClassNotFoundException propagated from readObject.
28.2340 + * This cannot occur if str is null.
28.2341 + */
28.2342 + private void buildFromSorted(int size, Iterator it,
28.2343 + java.io.ObjectInputStream str,
28.2344 + V defaultVal)
28.2345 + throws java.io.IOException, ClassNotFoundException {
28.2346 + this.size = size;
28.2347 + root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
28.2348 + it, str, defaultVal);
28.2349 + }
28.2350 +
28.2351 + /**
28.2352 + * Recursive "helper method" that does the real work of the
28.2353 + * previous method. Identically named parameters have
28.2354 + * identical definitions. Additional parameters are documented below.
28.2355 + * It is assumed that the comparator and size fields of the TreeMap are
28.2356 + * already set prior to calling this method. (It ignores both fields.)
28.2357 + *
28.2358 + * @param level the current level of tree. Initial call should be 0.
28.2359 + * @param lo the first element index of this subtree. Initial should be 0.
28.2360 + * @param hi the last element index of this subtree. Initial should be
28.2361 + * size-1.
28.2362 + * @param redLevel the level at which nodes should be red.
28.2363 + * Must be equal to computeRedLevel for tree of this size.
28.2364 + */
28.2365 + private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
28.2366 + int redLevel,
28.2367 + Iterator it,
28.2368 + java.io.ObjectInputStream str,
28.2369 + V defaultVal)
28.2370 + throws java.io.IOException, ClassNotFoundException {
28.2371 + /*
28.2372 + * Strategy: The root is the middlemost element. To get to it, we
28.2373 + * have to first recursively construct the entire left subtree,
28.2374 + * so as to grab all of its elements. We can then proceed with right
28.2375 + * subtree.
28.2376 + *
28.2377 + * The lo and hi arguments are the minimum and maximum
28.2378 + * indices to pull out of the iterator or stream for current subtree.
28.2379 + * They are not actually indexed, we just proceed sequentially,
28.2380 + * ensuring that items are extracted in corresponding order.
28.2381 + */
28.2382 +
28.2383 + if (hi < lo) return null;
28.2384 +
28.2385 + int mid = (lo + hi) >>> 1;
28.2386 +
28.2387 + Entry<K,V> left = null;
28.2388 + if (lo < mid)
28.2389 + left = buildFromSorted(level+1, lo, mid - 1, redLevel,
28.2390 + it, str, defaultVal);
28.2391 +
28.2392 + // extract key and/or value from iterator or stream
28.2393 + K key;
28.2394 + V value;
28.2395 + if (it != null) {
28.2396 + if (defaultVal==null) {
28.2397 + Map.Entry<K,V> entry = (Map.Entry<K,V>)it.next();
28.2398 + key = entry.getKey();
28.2399 + value = entry.getValue();
28.2400 + } else {
28.2401 + key = (K)it.next();
28.2402 + value = defaultVal;
28.2403 + }
28.2404 + } else { // use stream
28.2405 + key = (K) str.readObject();
28.2406 + value = (defaultVal != null ? defaultVal : (V) str.readObject());
28.2407 + }
28.2408 +
28.2409 + Entry<K,V> middle = new Entry<>(key, value, null);
28.2410 +
28.2411 + // color nodes in non-full bottommost level red
28.2412 + if (level == redLevel)
28.2413 + middle.color = RED;
28.2414 +
28.2415 + if (left != null) {
28.2416 + middle.left = left;
28.2417 + left.parent = middle;
28.2418 + }
28.2419 +
28.2420 + if (mid < hi) {
28.2421 + Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
28.2422 + it, str, defaultVal);
28.2423 + middle.right = right;
28.2424 + right.parent = middle;
28.2425 + }
28.2426 +
28.2427 + return middle;
28.2428 + }
28.2429 +
28.2430 + /**
28.2431 + * Find the level down to which to assign all nodes BLACK. This is the
28.2432 + * last `full' level of the complete binary tree produced by
28.2433 + * buildTree. The remaining nodes are colored RED. (This makes a `nice'
28.2434 + * set of color assignments wrt future insertions.) This level number is
28.2435 + * computed by finding the number of splits needed to reach the zeroeth
28.2436 + * node. (The answer is ~lg(N), but in any case must be computed by same
28.2437 + * quick O(lg(N)) loop.)
28.2438 + */
28.2439 + private static int computeRedLevel(int sz) {
28.2440 + int level = 0;
28.2441 + for (int m = sz - 1; m >= 0; m = m / 2 - 1)
28.2442 + level++;
28.2443 + return level;
28.2444 + }
28.2445 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/emul/compact/src/main/java/java/util/TreeSet.java Sat Sep 07 13:51:24 2013 +0200
29.3 @@ -0,0 +1,539 @@
29.4 +/*
29.5 + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
29.7 + *
29.8 + * This code is free software; you can redistribute it and/or modify it
29.9 + * under the terms of the GNU General Public License version 2 only, as
29.10 + * published by the Free Software Foundation. Oracle designates this
29.11 + * particular file as subject to the "Classpath" exception as provided
29.12 + * by Oracle in the LICENSE file that accompanied this code.
29.13 + *
29.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
29.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29.17 + * version 2 for more details (a copy is included in the LICENSE file that
29.18 + * accompanied this code).
29.19 + *
29.20 + * You should have received a copy of the GNU General Public License version
29.21 + * 2 along with this work; if not, write to the Free Software Foundation,
29.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29.23 + *
29.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
29.25 + * or visit www.oracle.com if you need additional information or have any
29.26 + * questions.
29.27 + */
29.28 +
29.29 +package java.util;
29.30 +
29.31 +/**
29.32 + * A {@link NavigableSet} implementation based on a {@link TreeMap}.
29.33 + * The elements are ordered using their {@linkplain Comparable natural
29.34 + * ordering}, or by a {@link Comparator} provided at set creation
29.35 + * time, depending on which constructor is used.
29.36 + *
29.37 + * <p>This implementation provides guaranteed log(n) time cost for the basic
29.38 + * operations ({@code add}, {@code remove} and {@code contains}).
29.39 + *
29.40 + * <p>Note that the ordering maintained by a set (whether or not an explicit
29.41 + * comparator is provided) must be <i>consistent with equals</i> if it is to
29.42 + * correctly implement the {@code Set} interface. (See {@code Comparable}
29.43 + * or {@code Comparator} for a precise definition of <i>consistent with
29.44 + * equals</i>.) This is so because the {@code Set} interface is defined in
29.45 + * terms of the {@code equals} operation, but a {@code TreeSet} instance
29.46 + * performs all element comparisons using its {@code compareTo} (or
29.47 + * {@code compare}) method, so two elements that are deemed equal by this method
29.48 + * are, from the standpoint of the set, equal. The behavior of a set
29.49 + * <i>is</i> well-defined even if its ordering is inconsistent with equals; it
29.50 + * just fails to obey the general contract of the {@code Set} interface.
29.51 + *
29.52 + * <p><strong>Note that this implementation is not synchronized.</strong>
29.53 + * If multiple threads access a tree set concurrently, and at least one
29.54 + * of the threads modifies the set, it <i>must</i> be synchronized
29.55 + * externally. This is typically accomplished by synchronizing on some
29.56 + * object that naturally encapsulates the set.
29.57 + * If no such object exists, the set should be "wrapped" using the
29.58 + * {@link Collections#synchronizedSortedSet Collections.synchronizedSortedSet}
29.59 + * method. This is best done at creation time, to prevent accidental
29.60 + * unsynchronized access to the set: <pre>
29.61 + * SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));</pre>
29.62 + *
29.63 + * <p>The iterators returned by this class's {@code iterator} method are
29.64 + * <i>fail-fast</i>: if the set is modified at any time after the iterator is
29.65 + * created, in any way except through the iterator's own {@code remove}
29.66 + * method, the iterator will throw a {@link ConcurrentModificationException}.
29.67 + * Thus, in the face of concurrent modification, the iterator fails quickly
29.68 + * and cleanly, rather than risking arbitrary, non-deterministic behavior at
29.69 + * an undetermined time in the future.
29.70 + *
29.71 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
29.72 + * as it is, generally speaking, impossible to make any hard guarantees in the
29.73 + * presence of unsynchronized concurrent modification. Fail-fast iterators
29.74 + * throw {@code ConcurrentModificationException} on a best-effort basis.
29.75 + * Therefore, it would be wrong to write a program that depended on this
29.76 + * exception for its correctness: <i>the fail-fast behavior of iterators
29.77 + * should be used only to detect bugs.</i>
29.78 + *
29.79 + * <p>This class is a member of the
29.80 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
29.81 + * Java Collections Framework</a>.
29.82 + *
29.83 + * @param <E> the type of elements maintained by this set
29.84 + *
29.85 + * @author Josh Bloch
29.86 + * @see Collection
29.87 + * @see Set
29.88 + * @see HashSet
29.89 + * @see Comparable
29.90 + * @see Comparator
29.91 + * @see TreeMap
29.92 + * @since 1.2
29.93 + */
29.94 +
29.95 +public class TreeSet<E> extends AbstractSet<E>
29.96 + implements NavigableSet<E>, Cloneable, java.io.Serializable
29.97 +{
29.98 + /**
29.99 + * The backing map.
29.100 + */
29.101 + private transient NavigableMap<E,Object> m;
29.102 +
29.103 + // Dummy value to associate with an Object in the backing Map
29.104 + private static final Object PRESENT = new Object();
29.105 +
29.106 + /**
29.107 + * Constructs a set backed by the specified navigable map.
29.108 + */
29.109 + TreeSet(NavigableMap<E,Object> m) {
29.110 + this.m = m;
29.111 + }
29.112 +
29.113 + /**
29.114 + * Constructs a new, empty tree set, sorted according to the
29.115 + * natural ordering of its elements. All elements inserted into
29.116 + * the set must implement the {@link Comparable} interface.
29.117 + * Furthermore, all such elements must be <i>mutually
29.118 + * comparable</i>: {@code e1.compareTo(e2)} must not throw a
29.119 + * {@code ClassCastException} for any elements {@code e1} and
29.120 + * {@code e2} in the set. If the user attempts to add an element
29.121 + * to the set that violates this constraint (for example, the user
29.122 + * attempts to add a string element to a set whose elements are
29.123 + * integers), the {@code add} call will throw a
29.124 + * {@code ClassCastException}.
29.125 + */
29.126 + public TreeSet() {
29.127 + this(new TreeMap<E,Object>());
29.128 + }
29.129 +
29.130 + /**
29.131 + * Constructs a new, empty tree set, sorted according to the specified
29.132 + * comparator. All elements inserted into the set must be <i>mutually
29.133 + * comparable</i> by the specified comparator: {@code comparator.compare(e1,
29.134 + * e2)} must not throw a {@code ClassCastException} for any elements
29.135 + * {@code e1} and {@code e2} in the set. If the user attempts to add
29.136 + * an element to the set that violates this constraint, the
29.137 + * {@code add} call will throw a {@code ClassCastException}.
29.138 + *
29.139 + * @param comparator the comparator that will be used to order this set.
29.140 + * If {@code null}, the {@linkplain Comparable natural
29.141 + * ordering} of the elements will be used.
29.142 + */
29.143 + public TreeSet(Comparator<? super E> comparator) {
29.144 + this(new TreeMap<>(comparator));
29.145 + }
29.146 +
29.147 + /**
29.148 + * Constructs a new tree set containing the elements in the specified
29.149 + * collection, sorted according to the <i>natural ordering</i> of its
29.150 + * elements. All elements inserted into the set must implement the
29.151 + * {@link Comparable} interface. Furthermore, all such elements must be
29.152 + * <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
29.153 + * {@code ClassCastException} for any elements {@code e1} and
29.154 + * {@code e2} in the set.
29.155 + *
29.156 + * @param c collection whose elements will comprise the new set
29.157 + * @throws ClassCastException if the elements in {@code c} are
29.158 + * not {@link Comparable}, or are not mutually comparable
29.159 + * @throws NullPointerException if the specified collection is null
29.160 + */
29.161 + public TreeSet(Collection<? extends E> c) {
29.162 + this();
29.163 + addAll(c);
29.164 + }
29.165 +
29.166 + /**
29.167 + * Constructs a new tree set containing the same elements and
29.168 + * using the same ordering as the specified sorted set.
29.169 + *
29.170 + * @param s sorted set whose elements will comprise the new set
29.171 + * @throws NullPointerException if the specified sorted set is null
29.172 + */
29.173 + public TreeSet(SortedSet<E> s) {
29.174 + this(s.comparator());
29.175 + addAll(s);
29.176 + }
29.177 +
29.178 + /**
29.179 + * Returns an iterator over the elements in this set in ascending order.
29.180 + *
29.181 + * @return an iterator over the elements in this set in ascending order
29.182 + */
29.183 + public Iterator<E> iterator() {
29.184 + return m.navigableKeySet().iterator();
29.185 + }
29.186 +
29.187 + /**
29.188 + * Returns an iterator over the elements in this set in descending order.
29.189 + *
29.190 + * @return an iterator over the elements in this set in descending order
29.191 + * @since 1.6
29.192 + */
29.193 + public Iterator<E> descendingIterator() {
29.194 + return m.descendingKeySet().iterator();
29.195 + }
29.196 +
29.197 + /**
29.198 + * @since 1.6
29.199 + */
29.200 + public NavigableSet<E> descendingSet() {
29.201 + return new TreeSet<>(m.descendingMap());
29.202 + }
29.203 +
29.204 + /**
29.205 + * Returns the number of elements in this set (its cardinality).
29.206 + *
29.207 + * @return the number of elements in this set (its cardinality)
29.208 + */
29.209 + public int size() {
29.210 + return m.size();
29.211 + }
29.212 +
29.213 + /**
29.214 + * Returns {@code true} if this set contains no elements.
29.215 + *
29.216 + * @return {@code true} if this set contains no elements
29.217 + */
29.218 + public boolean isEmpty() {
29.219 + return m.isEmpty();
29.220 + }
29.221 +
29.222 + /**
29.223 + * Returns {@code true} if this set contains the specified element.
29.224 + * More formally, returns {@code true} if and only if this set
29.225 + * contains an element {@code e} such that
29.226 + * <tt>(o==null ? e==null : o.equals(e))</tt>.
29.227 + *
29.228 + * @param o object to be checked for containment in this set
29.229 + * @return {@code true} if this set contains the specified element
29.230 + * @throws ClassCastException if the specified object cannot be compared
29.231 + * with the elements currently in the set
29.232 + * @throws NullPointerException if the specified element is null
29.233 + * and this set uses natural ordering, or its comparator
29.234 + * does not permit null elements
29.235 + */
29.236 + public boolean contains(Object o) {
29.237 + return m.containsKey(o);
29.238 + }
29.239 +
29.240 + /**
29.241 + * Adds the specified element to this set if it is not already present.
29.242 + * More formally, adds the specified element {@code e} to this set if
29.243 + * the set contains no element {@code e2} such that
29.244 + * <tt>(e==null ? e2==null : e.equals(e2))</tt>.
29.245 + * If this set already contains the element, the call leaves the set
29.246 + * unchanged and returns {@code false}.
29.247 + *
29.248 + * @param e element to be added to this set
29.249 + * @return {@code true} if this set did not already contain the specified
29.250 + * element
29.251 + * @throws ClassCastException if the specified object cannot be compared
29.252 + * with the elements currently in this set
29.253 + * @throws NullPointerException if the specified element is null
29.254 + * and this set uses natural ordering, or its comparator
29.255 + * does not permit null elements
29.256 + */
29.257 + public boolean add(E e) {
29.258 + return m.put(e, PRESENT)==null;
29.259 + }
29.260 +
29.261 + /**
29.262 + * Removes the specified element from this set if it is present.
29.263 + * More formally, removes an element {@code e} such that
29.264 + * <tt>(o==null ? e==null : o.equals(e))</tt>,
29.265 + * if this set contains such an element. Returns {@code true} if
29.266 + * this set contained the element (or equivalently, if this set
29.267 + * changed as a result of the call). (This set will not contain the
29.268 + * element once the call returns.)
29.269 + *
29.270 + * @param o object to be removed from this set, if present
29.271 + * @return {@code true} if this set contained the specified element
29.272 + * @throws ClassCastException if the specified object cannot be compared
29.273 + * with the elements currently in this set
29.274 + * @throws NullPointerException if the specified element is null
29.275 + * and this set uses natural ordering, or its comparator
29.276 + * does not permit null elements
29.277 + */
29.278 + public boolean remove(Object o) {
29.279 + return m.remove(o)==PRESENT;
29.280 + }
29.281 +
29.282 + /**
29.283 + * Removes all of the elements from this set.
29.284 + * The set will be empty after this call returns.
29.285 + */
29.286 + public void clear() {
29.287 + m.clear();
29.288 + }
29.289 +
29.290 + /**
29.291 + * Adds all of the elements in the specified collection to this set.
29.292 + *
29.293 + * @param c collection containing elements to be added to this set
29.294 + * @return {@code true} if this set changed as a result of the call
29.295 + * @throws ClassCastException if the elements provided cannot be compared
29.296 + * with the elements currently in the set
29.297 + * @throws NullPointerException if the specified collection is null or
29.298 + * if any element is null and this set uses natural ordering, or
29.299 + * its comparator does not permit null elements
29.300 + */
29.301 + public boolean addAll(Collection<? extends E> c) {
29.302 + // Use linear-time version if applicable
29.303 + if (m.size()==0 && c.size() > 0 &&
29.304 + c instanceof SortedSet &&
29.305 + m instanceof TreeMap) {
29.306 + SortedSet<? extends E> set = (SortedSet<? extends E>) c;
29.307 + TreeMap<E,Object> map = (TreeMap<E, Object>) m;
29.308 + Comparator<? super E> cc = (Comparator<? super E>) set.comparator();
29.309 + Comparator<? super E> mc = map.comparator();
29.310 + if (cc==mc || (cc != null && cc.equals(mc))) {
29.311 + map.addAllForTreeSet(set, PRESENT);
29.312 + return true;
29.313 + }
29.314 + }
29.315 + return super.addAll(c);
29.316 + }
29.317 +
29.318 + /**
29.319 + * @throws ClassCastException {@inheritDoc}
29.320 + * @throws NullPointerException if {@code fromElement} or {@code toElement}
29.321 + * is null and this set uses natural ordering, or its comparator
29.322 + * does not permit null elements
29.323 + * @throws IllegalArgumentException {@inheritDoc}
29.324 + * @since 1.6
29.325 + */
29.326 + public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
29.327 + E toElement, boolean toInclusive) {
29.328 + return new TreeSet<>(m.subMap(fromElement, fromInclusive,
29.329 + toElement, toInclusive));
29.330 + }
29.331 +
29.332 + /**
29.333 + * @throws ClassCastException {@inheritDoc}
29.334 + * @throws NullPointerException if {@code toElement} is null and
29.335 + * this set uses natural ordering, or its comparator does
29.336 + * not permit null elements
29.337 + * @throws IllegalArgumentException {@inheritDoc}
29.338 + * @since 1.6
29.339 + */
29.340 + public NavigableSet<E> headSet(E toElement, boolean inclusive) {
29.341 + return new TreeSet<>(m.headMap(toElement, inclusive));
29.342 + }
29.343 +
29.344 + /**
29.345 + * @throws ClassCastException {@inheritDoc}
29.346 + * @throws NullPointerException if {@code fromElement} is null and
29.347 + * this set uses natural ordering, or its comparator does
29.348 + * not permit null elements
29.349 + * @throws IllegalArgumentException {@inheritDoc}
29.350 + * @since 1.6
29.351 + */
29.352 + public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
29.353 + return new TreeSet<>(m.tailMap(fromElement, inclusive));
29.354 + }
29.355 +
29.356 + /**
29.357 + * @throws ClassCastException {@inheritDoc}
29.358 + * @throws NullPointerException if {@code fromElement} or
29.359 + * {@code toElement} is null and this set uses natural ordering,
29.360 + * or its comparator does not permit null elements
29.361 + * @throws IllegalArgumentException {@inheritDoc}
29.362 + */
29.363 + public SortedSet<E> subSet(E fromElement, E toElement) {
29.364 + return subSet(fromElement, true, toElement, false);
29.365 + }
29.366 +
29.367 + /**
29.368 + * @throws ClassCastException {@inheritDoc}
29.369 + * @throws NullPointerException if {@code toElement} is null
29.370 + * and this set uses natural ordering, or its comparator does
29.371 + * not permit null elements
29.372 + * @throws IllegalArgumentException {@inheritDoc}
29.373 + */
29.374 + public SortedSet<E> headSet(E toElement) {
29.375 + return headSet(toElement, false);
29.376 + }
29.377 +
29.378 + /**
29.379 + * @throws ClassCastException {@inheritDoc}
29.380 + * @throws NullPointerException if {@code fromElement} is null
29.381 + * and this set uses natural ordering, or its comparator does
29.382 + * not permit null elements
29.383 + * @throws IllegalArgumentException {@inheritDoc}
29.384 + */
29.385 + public SortedSet<E> tailSet(E fromElement) {
29.386 + return tailSet(fromElement, true);
29.387 + }
29.388 +
29.389 + public Comparator<? super E> comparator() {
29.390 + return m.comparator();
29.391 + }
29.392 +
29.393 + /**
29.394 + * @throws NoSuchElementException {@inheritDoc}
29.395 + */
29.396 + public E first() {
29.397 + return m.firstKey();
29.398 + }
29.399 +
29.400 + /**
29.401 + * @throws NoSuchElementException {@inheritDoc}
29.402 + */
29.403 + public E last() {
29.404 + return m.lastKey();
29.405 + }
29.406 +
29.407 + // NavigableSet API methods
29.408 +
29.409 + /**
29.410 + * @throws ClassCastException {@inheritDoc}
29.411 + * @throws NullPointerException if the specified element is null
29.412 + * and this set uses natural ordering, or its comparator
29.413 + * does not permit null elements
29.414 + * @since 1.6
29.415 + */
29.416 + public E lower(E e) {
29.417 + return m.lowerKey(e);
29.418 + }
29.419 +
29.420 + /**
29.421 + * @throws ClassCastException {@inheritDoc}
29.422 + * @throws NullPointerException if the specified element is null
29.423 + * and this set uses natural ordering, or its comparator
29.424 + * does not permit null elements
29.425 + * @since 1.6
29.426 + */
29.427 + public E floor(E e) {
29.428 + return m.floorKey(e);
29.429 + }
29.430 +
29.431 + /**
29.432 + * @throws ClassCastException {@inheritDoc}
29.433 + * @throws NullPointerException if the specified element is null
29.434 + * and this set uses natural ordering, or its comparator
29.435 + * does not permit null elements
29.436 + * @since 1.6
29.437 + */
29.438 + public E ceiling(E e) {
29.439 + return m.ceilingKey(e);
29.440 + }
29.441 +
29.442 + /**
29.443 + * @throws ClassCastException {@inheritDoc}
29.444 + * @throws NullPointerException if the specified element is null
29.445 + * and this set uses natural ordering, or its comparator
29.446 + * does not permit null elements
29.447 + * @since 1.6
29.448 + */
29.449 + public E higher(E e) {
29.450 + return m.higherKey(e);
29.451 + }
29.452 +
29.453 + /**
29.454 + * @since 1.6
29.455 + */
29.456 + public E pollFirst() {
29.457 + Map.Entry<E,?> e = m.pollFirstEntry();
29.458 + return (e == null) ? null : e.getKey();
29.459 + }
29.460 +
29.461 + /**
29.462 + * @since 1.6
29.463 + */
29.464 + public E pollLast() {
29.465 + Map.Entry<E,?> e = m.pollLastEntry();
29.466 + return (e == null) ? null : e.getKey();
29.467 + }
29.468 +
29.469 + /**
29.470 + * Returns a shallow copy of this {@code TreeSet} instance. (The elements
29.471 + * themselves are not cloned.)
29.472 + *
29.473 + * @return a shallow copy of this set
29.474 + */
29.475 + public Object clone() {
29.476 + TreeSet<E> clone = null;
29.477 + try {
29.478 + clone = (TreeSet<E>) super.clone();
29.479 + } catch (CloneNotSupportedException e) {
29.480 + throw new InternalError();
29.481 + }
29.482 +
29.483 + clone.m = new TreeMap<>(m);
29.484 + return clone;
29.485 + }
29.486 +
29.487 + /**
29.488 + * Save the state of the {@code TreeSet} instance to a stream (that is,
29.489 + * serialize it).
29.490 + *
29.491 + * @serialData Emits the comparator used to order this set, or
29.492 + * {@code null} if it obeys its elements' natural ordering
29.493 + * (Object), followed by the size of the set (the number of
29.494 + * elements it contains) (int), followed by all of its
29.495 + * elements (each an Object) in order (as determined by the
29.496 + * set's Comparator, or by the elements' natural ordering if
29.497 + * the set has no Comparator).
29.498 + */
29.499 + private void writeObject(java.io.ObjectOutputStream s)
29.500 + throws java.io.IOException {
29.501 + // Write out any hidden stuff
29.502 + s.defaultWriteObject();
29.503 +
29.504 + // Write out Comparator
29.505 + s.writeObject(m.comparator());
29.506 +
29.507 + // Write out size
29.508 + s.writeInt(m.size());
29.509 +
29.510 + // Write out all elements in the proper order.
29.511 + for (E e : m.keySet())
29.512 + s.writeObject(e);
29.513 + }
29.514 +
29.515 + /**
29.516 + * Reconstitute the {@code TreeSet} instance from a stream (that is,
29.517 + * deserialize it).
29.518 + */
29.519 + private void readObject(java.io.ObjectInputStream s)
29.520 + throws java.io.IOException, ClassNotFoundException {
29.521 + // Read in any hidden stuff
29.522 + s.defaultReadObject();
29.523 +
29.524 + // Read in Comparator
29.525 + Comparator<? super E> c = (Comparator<? super E>) s.readObject();
29.526 +
29.527 + // Create backing TreeMap
29.528 + TreeMap<E,Object> tm;
29.529 + if (c==null)
29.530 + tm = new TreeMap<>();
29.531 + else
29.532 + tm = new TreeMap<>(c);
29.533 + m = tm;
29.534 +
29.535 + // Read in size
29.536 + int size = s.readInt();
29.537 +
29.538 + tm.readTreeSet(size, s, PRESENT);
29.539 + }
29.540 +
29.541 + private static final long serialVersionUID = -2479143000061671589L;
29.542 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/emul/compact/src/main/java/java/util/WeakHashMap.java Sat Sep 07 13:51:24 2013 +0200
30.3 @@ -0,0 +1,972 @@
30.4 +/*
30.5 + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
30.7 + *
30.8 + * This code is free software; you can redistribute it and/or modify it
30.9 + * under the terms of the GNU General Public License version 2 only, as
30.10 + * published by the Free Software Foundation. Oracle designates this
30.11 + * particular file as subject to the "Classpath" exception as provided
30.12 + * by Oracle in the LICENSE file that accompanied this code.
30.13 + *
30.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
30.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30.17 + * version 2 for more details (a copy is included in the LICENSE file that
30.18 + * accompanied this code).
30.19 + *
30.20 + * You should have received a copy of the GNU General Public License version
30.21 + * 2 along with this work; if not, write to the Free Software Foundation,
30.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30.23 + *
30.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
30.25 + * or visit www.oracle.com if you need additional information or have any
30.26 + * questions.
30.27 + */
30.28 +
30.29 +package java.util;
30.30 +import java.lang.ref.WeakReference;
30.31 +import java.lang.ref.ReferenceQueue;
30.32 +
30.33 +
30.34 +/**
30.35 + * Hash table based implementation of the <tt>Map</tt> interface, with
30.36 + * <em>weak keys</em>.
30.37 + * An entry in a <tt>WeakHashMap</tt> will automatically be removed when
30.38 + * its key is no longer in ordinary use. More precisely, the presence of a
30.39 + * mapping for a given key will not prevent the key from being discarded by the
30.40 + * garbage collector, that is, made finalizable, finalized, and then reclaimed.
30.41 + * When a key has been discarded its entry is effectively removed from the map,
30.42 + * so this class behaves somewhat differently from other <tt>Map</tt>
30.43 + * implementations.
30.44 + *
30.45 + * <p> Both null values and the null key are supported. This class has
30.46 + * performance characteristics similar to those of the <tt>HashMap</tt>
30.47 + * class, and has the same efficiency parameters of <em>initial capacity</em>
30.48 + * and <em>load factor</em>.
30.49 + *
30.50 + * <p> Like most collection classes, this class is not synchronized.
30.51 + * A synchronized <tt>WeakHashMap</tt> may be constructed using the
30.52 + * {@link Collections#synchronizedMap Collections.synchronizedMap}
30.53 + * method.
30.54 + *
30.55 + * <p> This class is intended primarily for use with key objects whose
30.56 + * <tt>equals</tt> methods test for object identity using the
30.57 + * <tt>==</tt> operator. Once such a key is discarded it can never be
30.58 + * recreated, so it is impossible to do a lookup of that key in a
30.59 + * <tt>WeakHashMap</tt> at some later time and be surprised that its entry
30.60 + * has been removed. This class will work perfectly well with key objects
30.61 + * whose <tt>equals</tt> methods are not based upon object identity, such
30.62 + * as <tt>String</tt> instances. With such recreatable key objects,
30.63 + * however, the automatic removal of <tt>WeakHashMap</tt> entries whose
30.64 + * keys have been discarded may prove to be confusing.
30.65 + *
30.66 + * <p> The behavior of the <tt>WeakHashMap</tt> class depends in part upon
30.67 + * the actions of the garbage collector, so several familiar (though not
30.68 + * required) <tt>Map</tt> invariants do not hold for this class. Because
30.69 + * the garbage collector may discard keys at any time, a
30.70 + * <tt>WeakHashMap</tt> may behave as though an unknown thread is silently
30.71 + * removing entries. In particular, even if you synchronize on a
30.72 + * <tt>WeakHashMap</tt> instance and invoke none of its mutator methods, it
30.73 + * is possible for the <tt>size</tt> method to return smaller values over
30.74 + * time, for the <tt>isEmpty</tt> method to return <tt>false</tt> and
30.75 + * then <tt>true</tt>, for the <tt>containsKey</tt> method to return
30.76 + * <tt>true</tt> and later <tt>false</tt> for a given key, for the
30.77 + * <tt>get</tt> method to return a value for a given key but later return
30.78 + * <tt>null</tt>, for the <tt>put</tt> method to return
30.79 + * <tt>null</tt> and the <tt>remove</tt> method to return
30.80 + * <tt>false</tt> for a key that previously appeared to be in the map, and
30.81 + * for successive examinations of the key set, the value collection, and
30.82 + * the entry set to yield successively smaller numbers of elements.
30.83 + *
30.84 + * <p> Each key object in a <tt>WeakHashMap</tt> is stored indirectly as
30.85 + * the referent of a weak reference. Therefore a key will automatically be
30.86 + * removed only after the weak references to it, both inside and outside of the
30.87 + * map, have been cleared by the garbage collector.
30.88 + *
30.89 + * <p> <strong>Implementation note:</strong> The value objects in a
30.90 + * <tt>WeakHashMap</tt> are held by ordinary strong references. Thus care
30.91 + * should be taken to ensure that value objects do not strongly refer to their
30.92 + * own keys, either directly or indirectly, since that will prevent the keys
30.93 + * from being discarded. Note that a value object may refer indirectly to its
30.94 + * key via the <tt>WeakHashMap</tt> itself; that is, a value object may
30.95 + * strongly refer to some other key object whose associated value object, in
30.96 + * turn, strongly refers to the key of the first value object. One way
30.97 + * to deal with this is to wrap values themselves within
30.98 + * <tt>WeakReferences</tt> before
30.99 + * inserting, as in: <tt>m.put(key, new WeakReference(value))</tt>,
30.100 + * and then unwrapping upon each <tt>get</tt>.
30.101 + *
30.102 + * <p>The iterators returned by the <tt>iterator</tt> method of the collections
30.103 + * returned by all of this class's "collection view methods" are
30.104 + * <i>fail-fast</i>: if the map is structurally modified at any time after the
30.105 + * iterator is created, in any way except through the iterator's own
30.106 + * <tt>remove</tt> method, the iterator will throw a {@link
30.107 + * ConcurrentModificationException}. Thus, in the face of concurrent
30.108 + * modification, the iterator fails quickly and cleanly, rather than risking
30.109 + * arbitrary, non-deterministic behavior at an undetermined time in the future.
30.110 + *
30.111 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
30.112 + * as it is, generally speaking, impossible to make any hard guarantees in the
30.113 + * presence of unsynchronized concurrent modification. Fail-fast iterators
30.114 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
30.115 + * Therefore, it would be wrong to write a program that depended on this
30.116 + * exception for its correctness: <i>the fail-fast behavior of iterators
30.117 + * should be used only to detect bugs.</i>
30.118 + *
30.119 + * <p>This class is a member of the
30.120 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
30.121 + * Java Collections Framework</a>.
30.122 + *
30.123 + * @param <K> the type of keys maintained by this map
30.124 + * @param <V> the type of mapped values
30.125 + *
30.126 + * @author Doug Lea
30.127 + * @author Josh Bloch
30.128 + * @author Mark Reinhold
30.129 + * @since 1.2
30.130 + * @see java.util.HashMap
30.131 + * @see java.lang.ref.WeakReference
30.132 + */
30.133 +public class WeakHashMap<K,V>
30.134 + extends AbstractMap<K,V>
30.135 + implements Map<K,V> {
30.136 +
30.137 + /**
30.138 + * The default initial capacity -- MUST be a power of two.
30.139 + */
30.140 + private static final int DEFAULT_INITIAL_CAPACITY = 16;
30.141 +
30.142 + /**
30.143 + * The maximum capacity, used if a higher value is implicitly specified
30.144 + * by either of the constructors with arguments.
30.145 + * MUST be a power of two <= 1<<30.
30.146 + */
30.147 + private static final int MAXIMUM_CAPACITY = 1 << 30;
30.148 +
30.149 + /**
30.150 + * The load factor used when none specified in constructor.
30.151 + */
30.152 + private static final float DEFAULT_LOAD_FACTOR = 0.75f;
30.153 +
30.154 + /**
30.155 + * The table, resized as necessary. Length MUST Always be a power of two.
30.156 + */
30.157 + Entry<K,V>[] table;
30.158 +
30.159 + /**
30.160 + * The number of key-value mappings contained in this weak hash map.
30.161 + */
30.162 + private int size;
30.163 +
30.164 + /**
30.165 + * The next size value at which to resize (capacity * load factor).
30.166 + */
30.167 + private int threshold;
30.168 +
30.169 + /**
30.170 + * The load factor for the hash table.
30.171 + */
30.172 + private final float loadFactor;
30.173 +
30.174 + /**
30.175 + * Reference queue for cleared WeakEntries
30.176 + */
30.177 + private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
30.178 +
30.179 + /**
30.180 + * The number of times this WeakHashMap has been structurally modified.
30.181 + * Structural modifications are those that change the number of
30.182 + * mappings in the map or otherwise modify its internal structure
30.183 + * (e.g., rehash). This field is used to make iterators on
30.184 + * Collection-views of the map fail-fast.
30.185 + *
30.186 + * @see ConcurrentModificationException
30.187 + */
30.188 + int modCount;
30.189 +
30.190 + @SuppressWarnings("unchecked")
30.191 + private Entry<K,V>[] newTable(int n) {
30.192 + return (Entry<K,V>[]) new Entry[n];
30.193 + }
30.194 +
30.195 + /**
30.196 + * Constructs a new, empty <tt>WeakHashMap</tt> with the given initial
30.197 + * capacity and the given load factor.
30.198 + *
30.199 + * @param initialCapacity The initial capacity of the <tt>WeakHashMap</tt>
30.200 + * @param loadFactor The load factor of the <tt>WeakHashMap</tt>
30.201 + * @throws IllegalArgumentException if the initial capacity is negative,
30.202 + * or if the load factor is nonpositive.
30.203 + */
30.204 + public WeakHashMap(int initialCapacity, float loadFactor) {
30.205 + if (initialCapacity < 0)
30.206 + throw new IllegalArgumentException("Illegal Initial Capacity: "+
30.207 + initialCapacity);
30.208 + if (initialCapacity > MAXIMUM_CAPACITY)
30.209 + initialCapacity = MAXIMUM_CAPACITY;
30.210 +
30.211 + if (loadFactor <= 0 || Float.isNaN(loadFactor))
30.212 + throw new IllegalArgumentException("Illegal Load factor: "+
30.213 + loadFactor);
30.214 + int capacity = 1;
30.215 + while (capacity < initialCapacity)
30.216 + capacity <<= 1;
30.217 + table = newTable(capacity);
30.218 + this.loadFactor = loadFactor;
30.219 + threshold = (int)(capacity * loadFactor);
30.220 + }
30.221 +
30.222 + /**
30.223 + * Constructs a new, empty <tt>WeakHashMap</tt> with the given initial
30.224 + * capacity and the default load factor (0.75).
30.225 + *
30.226 + * @param initialCapacity The initial capacity of the <tt>WeakHashMap</tt>
30.227 + * @throws IllegalArgumentException if the initial capacity is negative
30.228 + */
30.229 + public WeakHashMap(int initialCapacity) {
30.230 + this(initialCapacity, DEFAULT_LOAD_FACTOR);
30.231 + }
30.232 +
30.233 + /**
30.234 + * Constructs a new, empty <tt>WeakHashMap</tt> with the default initial
30.235 + * capacity (16) and load factor (0.75).
30.236 + */
30.237 + public WeakHashMap() {
30.238 + this.loadFactor = DEFAULT_LOAD_FACTOR;
30.239 + threshold = DEFAULT_INITIAL_CAPACITY;
30.240 + table = newTable(DEFAULT_INITIAL_CAPACITY);
30.241 + }
30.242 +
30.243 + /**
30.244 + * Constructs a new <tt>WeakHashMap</tt> with the same mappings as the
30.245 + * specified map. The <tt>WeakHashMap</tt> is created with the default
30.246 + * load factor (0.75) and an initial capacity sufficient to hold the
30.247 + * mappings in the specified map.
30.248 + *
30.249 + * @param m the map whose mappings are to be placed in this map
30.250 + * @throws NullPointerException if the specified map is null
30.251 + * @since 1.3
30.252 + */
30.253 + public WeakHashMap(Map<? extends K, ? extends V> m) {
30.254 + this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, 16),
30.255 + DEFAULT_LOAD_FACTOR);
30.256 + putAll(m);
30.257 + }
30.258 +
30.259 + // internal utilities
30.260 +
30.261 + /**
30.262 + * Value representing null keys inside tables.
30.263 + */
30.264 + private static final Object NULL_KEY = new Object();
30.265 +
30.266 + /**
30.267 + * Use NULL_KEY for key if it is null.
30.268 + */
30.269 + private static Object maskNull(Object key) {
30.270 + return (key == null) ? NULL_KEY : key;
30.271 + }
30.272 +
30.273 + /**
30.274 + * Returns internal representation of null key back to caller as null.
30.275 + */
30.276 + static Object unmaskNull(Object key) {
30.277 + return (key == NULL_KEY) ? null : key;
30.278 + }
30.279 +
30.280 + /**
30.281 + * Checks for equality of non-null reference x and possibly-null y. By
30.282 + * default uses Object.equals.
30.283 + */
30.284 + private static boolean eq(Object x, Object y) {
30.285 + return x == y || x.equals(y);
30.286 + }
30.287 +
30.288 + /**
30.289 + * Returns index for hash code h.
30.290 + */
30.291 + private static int indexFor(int h, int length) {
30.292 + return h & (length-1);
30.293 + }
30.294 +
30.295 + /**
30.296 + * Expunges stale entries from the table.
30.297 + */
30.298 + private void expungeStaleEntries() {
30.299 + for (Object x; (x = queue.poll()) != null; ) {
30.300 + synchronized (queue) {
30.301 + @SuppressWarnings("unchecked")
30.302 + Entry<K,V> e = (Entry<K,V>) x;
30.303 + int i = indexFor(e.hash, table.length);
30.304 +
30.305 + Entry<K,V> prev = table[i];
30.306 + Entry<K,V> p = prev;
30.307 + while (p != null) {
30.308 + Entry<K,V> next = p.next;
30.309 + if (p == e) {
30.310 + if (prev == e)
30.311 + table[i] = next;
30.312 + else
30.313 + prev.next = next;
30.314 + // Must not null out e.next;
30.315 + // stale entries may be in use by a HashIterator
30.316 + e.value = null; // Help GC
30.317 + size--;
30.318 + break;
30.319 + }
30.320 + prev = p;
30.321 + p = next;
30.322 + }
30.323 + }
30.324 + }
30.325 + }
30.326 +
30.327 + /**
30.328 + * Returns the table after first expunging stale entries.
30.329 + */
30.330 + private Entry<K,V>[] getTable() {
30.331 + expungeStaleEntries();
30.332 + return table;
30.333 + }
30.334 +
30.335 + /**
30.336 + * Returns the number of key-value mappings in this map.
30.337 + * This result is a snapshot, and may not reflect unprocessed
30.338 + * entries that will be removed before next attempted access
30.339 + * because they are no longer referenced.
30.340 + */
30.341 + public int size() {
30.342 + if (size == 0)
30.343 + return 0;
30.344 + expungeStaleEntries();
30.345 + return size;
30.346 + }
30.347 +
30.348 + /**
30.349 + * Returns <tt>true</tt> if this map contains no key-value mappings.
30.350 + * This result is a snapshot, and may not reflect unprocessed
30.351 + * entries that will be removed before next attempted access
30.352 + * because they are no longer referenced.
30.353 + */
30.354 + public boolean isEmpty() {
30.355 + return size() == 0;
30.356 + }
30.357 +
30.358 + /**
30.359 + * Returns the value to which the specified key is mapped,
30.360 + * or {@code null} if this map contains no mapping for the key.
30.361 + *
30.362 + * <p>More formally, if this map contains a mapping from a key
30.363 + * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
30.364 + * key.equals(k))}, then this method returns {@code v}; otherwise
30.365 + * it returns {@code null}. (There can be at most one such mapping.)
30.366 + *
30.367 + * <p>A return value of {@code null} does not <i>necessarily</i>
30.368 + * indicate that the map contains no mapping for the key; it's also
30.369 + * possible that the map explicitly maps the key to {@code null}.
30.370 + * The {@link #containsKey containsKey} operation may be used to
30.371 + * distinguish these two cases.
30.372 + *
30.373 + * @see #put(Object, Object)
30.374 + */
30.375 + public V get(Object key) {
30.376 + Object k = maskNull(key);
30.377 + int h = HashMap.hash(k.hashCode());
30.378 + Entry<K,V>[] tab = getTable();
30.379 + int index = indexFor(h, tab.length);
30.380 + Entry<K,V> e = tab[index];
30.381 + while (e != null) {
30.382 + if (e.hash == h && eq(k, e.get()))
30.383 + return e.value;
30.384 + e = e.next;
30.385 + }
30.386 + return null;
30.387 + }
30.388 +
30.389 + /**
30.390 + * Returns <tt>true</tt> if this map contains a mapping for the
30.391 + * specified key.
30.392 + *
30.393 + * @param key The key whose presence in this map is to be tested
30.394 + * @return <tt>true</tt> if there is a mapping for <tt>key</tt>;
30.395 + * <tt>false</tt> otherwise
30.396 + */
30.397 + public boolean containsKey(Object key) {
30.398 + return getEntry(key) != null;
30.399 + }
30.400 +
30.401 + /**
30.402 + * Returns the entry associated with the specified key in this map.
30.403 + * Returns null if the map contains no mapping for this key.
30.404 + */
30.405 + Entry<K,V> getEntry(Object key) {
30.406 + Object k = maskNull(key);
30.407 + int h = HashMap.hash(k.hashCode());
30.408 + Entry<K,V>[] tab = getTable();
30.409 + int index = indexFor(h, tab.length);
30.410 + Entry<K,V> e = tab[index];
30.411 + while (e != null && !(e.hash == h && eq(k, e.get())))
30.412 + e = e.next;
30.413 + return e;
30.414 + }
30.415 +
30.416 + /**
30.417 + * Associates the specified value with the specified key in this map.
30.418 + * If the map previously contained a mapping for this key, the old
30.419 + * value is replaced.
30.420 + *
30.421 + * @param key key with which the specified value is to be associated.
30.422 + * @param value value to be associated with the specified key.
30.423 + * @return the previous value associated with <tt>key</tt>, or
30.424 + * <tt>null</tt> if there was no mapping for <tt>key</tt>.
30.425 + * (A <tt>null</tt> return can also indicate that the map
30.426 + * previously associated <tt>null</tt> with <tt>key</tt>.)
30.427 + */
30.428 + public V put(K key, V value) {
30.429 + Object k = maskNull(key);
30.430 + int h = HashMap.hash(k.hashCode());
30.431 + Entry<K,V>[] tab = getTable();
30.432 + int i = indexFor(h, tab.length);
30.433 +
30.434 + for (Entry<K,V> e = tab[i]; e != null; e = e.next) {
30.435 + if (h == e.hash && eq(k, e.get())) {
30.436 + V oldValue = e.value;
30.437 + if (value != oldValue)
30.438 + e.value = value;
30.439 + return oldValue;
30.440 + }
30.441 + }
30.442 +
30.443 + modCount++;
30.444 + Entry<K,V> e = tab[i];
30.445 + tab[i] = new Entry<>(k, value, queue, h, e);
30.446 + if (++size >= threshold)
30.447 + resize(tab.length * 2);
30.448 + return null;
30.449 + }
30.450 +
30.451 + /**
30.452 + * Rehashes the contents of this map into a new array with a
30.453 + * larger capacity. This method is called automatically when the
30.454 + * number of keys in this map reaches its threshold.
30.455 + *
30.456 + * If current capacity is MAXIMUM_CAPACITY, this method does not
30.457 + * resize the map, but sets threshold to Integer.MAX_VALUE.
30.458 + * This has the effect of preventing future calls.
30.459 + *
30.460 + * @param newCapacity the new capacity, MUST be a power of two;
30.461 + * must be greater than current capacity unless current
30.462 + * capacity is MAXIMUM_CAPACITY (in which case value
30.463 + * is irrelevant).
30.464 + */
30.465 + void resize(int newCapacity) {
30.466 + Entry<K,V>[] oldTable = getTable();
30.467 + int oldCapacity = oldTable.length;
30.468 + if (oldCapacity == MAXIMUM_CAPACITY) {
30.469 + threshold = Integer.MAX_VALUE;
30.470 + return;
30.471 + }
30.472 +
30.473 + Entry<K,V>[] newTable = newTable(newCapacity);
30.474 + transfer(oldTable, newTable);
30.475 + table = newTable;
30.476 +
30.477 + /*
30.478 + * If ignoring null elements and processing ref queue caused massive
30.479 + * shrinkage, then restore old table. This should be rare, but avoids
30.480 + * unbounded expansion of garbage-filled tables.
30.481 + */
30.482 + if (size >= threshold / 2) {
30.483 + threshold = (int)(newCapacity * loadFactor);
30.484 + } else {
30.485 + expungeStaleEntries();
30.486 + transfer(newTable, oldTable);
30.487 + table = oldTable;
30.488 + }
30.489 + }
30.490 +
30.491 + /** Transfers all entries from src to dest tables */
30.492 + private void transfer(Entry<K,V>[] src, Entry<K,V>[] dest) {
30.493 + for (int j = 0; j < src.length; ++j) {
30.494 + Entry<K,V> e = src[j];
30.495 + src[j] = null;
30.496 + while (e != null) {
30.497 + Entry<K,V> next = e.next;
30.498 + Object key = e.get();
30.499 + if (key == null) {
30.500 + e.next = null; // Help GC
30.501 + e.value = null; // " "
30.502 + size--;
30.503 + } else {
30.504 + int i = indexFor(e.hash, dest.length);
30.505 + e.next = dest[i];
30.506 + dest[i] = e;
30.507 + }
30.508 + e = next;
30.509 + }
30.510 + }
30.511 + }
30.512 +
30.513 + /**
30.514 + * Copies all of the mappings from the specified map to this map.
30.515 + * These mappings will replace any mappings that this map had for any
30.516 + * of the keys currently in the specified map.
30.517 + *
30.518 + * @param m mappings to be stored in this map.
30.519 + * @throws NullPointerException if the specified map is null.
30.520 + */
30.521 + public void putAll(Map<? extends K, ? extends V> m) {
30.522 + int numKeysToBeAdded = m.size();
30.523 + if (numKeysToBeAdded == 0)
30.524 + return;
30.525 +
30.526 + /*
30.527 + * Expand the map if the map if the number of mappings to be added
30.528 + * is greater than or equal to threshold. This is conservative; the
30.529 + * obvious condition is (m.size() + size) >= threshold, but this
30.530 + * condition could result in a map with twice the appropriate capacity,
30.531 + * if the keys to be added overlap with the keys already in this map.
30.532 + * By using the conservative calculation, we subject ourself
30.533 + * to at most one extra resize.
30.534 + */
30.535 + if (numKeysToBeAdded > threshold) {
30.536 + int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
30.537 + if (targetCapacity > MAXIMUM_CAPACITY)
30.538 + targetCapacity = MAXIMUM_CAPACITY;
30.539 + int newCapacity = table.length;
30.540 + while (newCapacity < targetCapacity)
30.541 + newCapacity <<= 1;
30.542 + if (newCapacity > table.length)
30.543 + resize(newCapacity);
30.544 + }
30.545 +
30.546 + for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
30.547 + put(e.getKey(), e.getValue());
30.548 + }
30.549 +
30.550 + /**
30.551 + * Removes the mapping for a key from this weak hash map if it is present.
30.552 + * More formally, if this map contains a mapping from key <tt>k</tt> to
30.553 + * value <tt>v</tt> such that <code>(key==null ? k==null :
30.554 + * key.equals(k))</code>, that mapping is removed. (The map can contain
30.555 + * at most one such mapping.)
30.556 + *
30.557 + * <p>Returns the value to which this map previously associated the key,
30.558 + * or <tt>null</tt> if the map contained no mapping for the key. A
30.559 + * return value of <tt>null</tt> does not <i>necessarily</i> indicate
30.560 + * that the map contained no mapping for the key; it's also possible
30.561 + * that the map explicitly mapped the key to <tt>null</tt>.
30.562 + *
30.563 + * <p>The map will not contain a mapping for the specified key once the
30.564 + * call returns.
30.565 + *
30.566 + * @param key key whose mapping is to be removed from the map
30.567 + * @return the previous value associated with <tt>key</tt>, or
30.568 + * <tt>null</tt> if there was no mapping for <tt>key</tt>
30.569 + */
30.570 + public V remove(Object key) {
30.571 + Object k = maskNull(key);
30.572 + int h = HashMap.hash(k.hashCode());
30.573 + Entry<K,V>[] tab = getTable();
30.574 + int i = indexFor(h, tab.length);
30.575 + Entry<K,V> prev = tab[i];
30.576 + Entry<K,V> e = prev;
30.577 +
30.578 + while (e != null) {
30.579 + Entry<K,V> next = e.next;
30.580 + if (h == e.hash && eq(k, e.get())) {
30.581 + modCount++;
30.582 + size--;
30.583 + if (prev == e)
30.584 + tab[i] = next;
30.585 + else
30.586 + prev.next = next;
30.587 + return e.value;
30.588 + }
30.589 + prev = e;
30.590 + e = next;
30.591 + }
30.592 +
30.593 + return null;
30.594 + }
30.595 +
30.596 + /** Special version of remove needed by Entry set */
30.597 + boolean removeMapping(Object o) {
30.598 + if (!(o instanceof Map.Entry))
30.599 + return false;
30.600 + Entry<K,V>[] tab = getTable();
30.601 + Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
30.602 + Object k = maskNull(entry.getKey());
30.603 + int h = HashMap.hash(k.hashCode());
30.604 + int i = indexFor(h, tab.length);
30.605 + Entry<K,V> prev = tab[i];
30.606 + Entry<K,V> e = prev;
30.607 +
30.608 + while (e != null) {
30.609 + Entry<K,V> next = e.next;
30.610 + if (h == e.hash && e.equals(entry)) {
30.611 + modCount++;
30.612 + size--;
30.613 + if (prev == e)
30.614 + tab[i] = next;
30.615 + else
30.616 + prev.next = next;
30.617 + return true;
30.618 + }
30.619 + prev = e;
30.620 + e = next;
30.621 + }
30.622 +
30.623 + return false;
30.624 + }
30.625 +
30.626 + /**
30.627 + * Removes all of the mappings from this map.
30.628 + * The map will be empty after this call returns.
30.629 + */
30.630 + public void clear() {
30.631 + // clear out ref queue. We don't need to expunge entries
30.632 + // since table is getting cleared.
30.633 + while (queue.poll() != null)
30.634 + ;
30.635 +
30.636 + modCount++;
30.637 + Arrays.fill(table, null);
30.638 + size = 0;
30.639 +
30.640 + // Allocation of array may have caused GC, which may have caused
30.641 + // additional entries to go stale. Removing these entries from the
30.642 + // reference queue will make them eligible for reclamation.
30.643 + while (queue.poll() != null)
30.644 + ;
30.645 + }
30.646 +
30.647 + /**
30.648 + * Returns <tt>true</tt> if this map maps one or more keys to the
30.649 + * specified value.
30.650 + *
30.651 + * @param value value whose presence in this map is to be tested
30.652 + * @return <tt>true</tt> if this map maps one or more keys to the
30.653 + * specified value
30.654 + */
30.655 + public boolean containsValue(Object value) {
30.656 + if (value==null)
30.657 + return containsNullValue();
30.658 +
30.659 + Entry<K,V>[] tab = getTable();
30.660 + for (int i = tab.length; i-- > 0;)
30.661 + for (Entry<K,V> e = tab[i]; e != null; e = e.next)
30.662 + if (value.equals(e.value))
30.663 + return true;
30.664 + return false;
30.665 + }
30.666 +
30.667 + /**
30.668 + * Special-case code for containsValue with null argument
30.669 + */
30.670 + private boolean containsNullValue() {
30.671 + Entry<K,V>[] tab = getTable();
30.672 + for (int i = tab.length; i-- > 0;)
30.673 + for (Entry<K,V> e = tab[i]; e != null; e = e.next)
30.674 + if (e.value==null)
30.675 + return true;
30.676 + return false;
30.677 + }
30.678 +
30.679 + /**
30.680 + * The entries in this hash table extend WeakReference, using its main ref
30.681 + * field as the key.
30.682 + */
30.683 + private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
30.684 + V value;
30.685 + final int hash;
30.686 + Entry<K,V> next;
30.687 +
30.688 + /**
30.689 + * Creates new entry.
30.690 + */
30.691 + Entry(Object key, V value,
30.692 + ReferenceQueue<Object> queue,
30.693 + int hash, Entry<K,V> next) {
30.694 + super(key, queue);
30.695 + this.value = value;
30.696 + this.hash = hash;
30.697 + this.next = next;
30.698 + }
30.699 +
30.700 + @SuppressWarnings("unchecked")
30.701 + public K getKey() {
30.702 + return (K) WeakHashMap.unmaskNull(get());
30.703 + }
30.704 +
30.705 + public V getValue() {
30.706 + return value;
30.707 + }
30.708 +
30.709 + public V setValue(V newValue) {
30.710 + V oldValue = value;
30.711 + value = newValue;
30.712 + return oldValue;
30.713 + }
30.714 +
30.715 + public boolean equals(Object o) {
30.716 + if (!(o instanceof Map.Entry))
30.717 + return false;
30.718 + Map.Entry<?,?> e = (Map.Entry<?,?>)o;
30.719 + K k1 = getKey();
30.720 + Object k2 = e.getKey();
30.721 + if (k1 == k2 || (k1 != null && k1.equals(k2))) {
30.722 + V v1 = getValue();
30.723 + Object v2 = e.getValue();
30.724 + if (v1 == v2 || (v1 != null && v1.equals(v2)))
30.725 + return true;
30.726 + }
30.727 + return false;
30.728 + }
30.729 +
30.730 + public int hashCode() {
30.731 + K k = getKey();
30.732 + V v = getValue();
30.733 + return ((k==null ? 0 : k.hashCode()) ^
30.734 + (v==null ? 0 : v.hashCode()));
30.735 + }
30.736 +
30.737 + public String toString() {
30.738 + return getKey() + "=" + getValue();
30.739 + }
30.740 + }
30.741 +
30.742 + private abstract class HashIterator<T> implements Iterator<T> {
30.743 + private int index;
30.744 + private Entry<K,V> entry = null;
30.745 + private Entry<K,V> lastReturned = null;
30.746 + private int expectedModCount = modCount;
30.747 +
30.748 + /**
30.749 + * Strong reference needed to avoid disappearance of key
30.750 + * between hasNext and next
30.751 + */
30.752 + private Object nextKey = null;
30.753 +
30.754 + /**
30.755 + * Strong reference needed to avoid disappearance of key
30.756 + * between nextEntry() and any use of the entry
30.757 + */
30.758 + private Object currentKey = null;
30.759 +
30.760 + HashIterator() {
30.761 + index = isEmpty() ? 0 : table.length;
30.762 + }
30.763 +
30.764 + public boolean hasNext() {
30.765 + Entry<K,V>[] t = table;
30.766 +
30.767 + while (nextKey == null) {
30.768 + Entry<K,V> e = entry;
30.769 + int i = index;
30.770 + while (e == null && i > 0)
30.771 + e = t[--i];
30.772 + entry = e;
30.773 + index = i;
30.774 + if (e == null) {
30.775 + currentKey = null;
30.776 + return false;
30.777 + }
30.778 + nextKey = e.get(); // hold on to key in strong ref
30.779 + if (nextKey == null)
30.780 + entry = entry.next;
30.781 + }
30.782 + return true;
30.783 + }
30.784 +
30.785 + /** The common parts of next() across different types of iterators */
30.786 + protected Entry<K,V> nextEntry() {
30.787 + if (modCount != expectedModCount)
30.788 + throw new ConcurrentModificationException();
30.789 + if (nextKey == null && !hasNext())
30.790 + throw new NoSuchElementException();
30.791 +
30.792 + lastReturned = entry;
30.793 + entry = entry.next;
30.794 + currentKey = nextKey;
30.795 + nextKey = null;
30.796 + return lastReturned;
30.797 + }
30.798 +
30.799 + public void remove() {
30.800 + if (lastReturned == null)
30.801 + throw new IllegalStateException();
30.802 + if (modCount != expectedModCount)
30.803 + throw new ConcurrentModificationException();
30.804 +
30.805 + WeakHashMap.this.remove(currentKey);
30.806 + expectedModCount = modCount;
30.807 + lastReturned = null;
30.808 + currentKey = null;
30.809 + }
30.810 +
30.811 + }
30.812 +
30.813 + private class ValueIterator extends HashIterator<V> {
30.814 + public V next() {
30.815 + return nextEntry().value;
30.816 + }
30.817 + }
30.818 +
30.819 + private class KeyIterator extends HashIterator<K> {
30.820 + public K next() {
30.821 + return nextEntry().getKey();
30.822 + }
30.823 + }
30.824 +
30.825 + private class EntryIterator extends HashIterator<Map.Entry<K,V>> {
30.826 + public Map.Entry<K,V> next() {
30.827 + return nextEntry();
30.828 + }
30.829 + }
30.830 +
30.831 + // Views
30.832 +
30.833 + private transient Set<Map.Entry<K,V>> entrySet = null;
30.834 +
30.835 + /**
30.836 + * Returns a {@link Set} view of the keys contained in this map.
30.837 + * The set is backed by the map, so changes to the map are
30.838 + * reflected in the set, and vice-versa. If the map is modified
30.839 + * while an iteration over the set is in progress (except through
30.840 + * the iterator's own <tt>remove</tt> operation), the results of
30.841 + * the iteration are undefined. The set supports element removal,
30.842 + * which removes the corresponding mapping from the map, via the
30.843 + * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
30.844 + * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
30.845 + * operations. It does not support the <tt>add</tt> or <tt>addAll</tt>
30.846 + * operations.
30.847 + */
30.848 + public Set<K> keySet() {
30.849 + Set<K> ks = keySet;
30.850 + return (ks != null ? ks : (keySet = new KeySet()));
30.851 + }
30.852 +
30.853 + private class KeySet extends AbstractSet<K> {
30.854 + public Iterator<K> iterator() {
30.855 + return new KeyIterator();
30.856 + }
30.857 +
30.858 + public int size() {
30.859 + return WeakHashMap.this.size();
30.860 + }
30.861 +
30.862 + public boolean contains(Object o) {
30.863 + return containsKey(o);
30.864 + }
30.865 +
30.866 + public boolean remove(Object o) {
30.867 + if (containsKey(o)) {
30.868 + WeakHashMap.this.remove(o);
30.869 + return true;
30.870 + }
30.871 + else
30.872 + return false;
30.873 + }
30.874 +
30.875 + public void clear() {
30.876 + WeakHashMap.this.clear();
30.877 + }
30.878 + }
30.879 +
30.880 + /**
30.881 + * Returns a {@link Collection} view of the values contained in this map.
30.882 + * The collection is backed by the map, so changes to the map are
30.883 + * reflected in the collection, and vice-versa. If the map is
30.884 + * modified while an iteration over the collection is in progress
30.885 + * (except through the iterator's own <tt>remove</tt> operation),
30.886 + * the results of the iteration are undefined. The collection
30.887 + * supports element removal, which removes the corresponding
30.888 + * mapping from the map, via the <tt>Iterator.remove</tt>,
30.889 + * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
30.890 + * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not
30.891 + * support the <tt>add</tt> or <tt>addAll</tt> operations.
30.892 + */
30.893 + public Collection<V> values() {
30.894 + Collection<V> vs = values;
30.895 + return (vs != null) ? vs : (values = new Values());
30.896 + }
30.897 +
30.898 + private class Values extends AbstractCollection<V> {
30.899 + public Iterator<V> iterator() {
30.900 + return new ValueIterator();
30.901 + }
30.902 +
30.903 + public int size() {
30.904 + return WeakHashMap.this.size();
30.905 + }
30.906 +
30.907 + public boolean contains(Object o) {
30.908 + return containsValue(o);
30.909 + }
30.910 +
30.911 + public void clear() {
30.912 + WeakHashMap.this.clear();
30.913 + }
30.914 + }
30.915 +
30.916 + /**
30.917 + * Returns a {@link Set} view of the mappings contained in this map.
30.918 + * The set is backed by the map, so changes to the map are
30.919 + * reflected in the set, and vice-versa. If the map is modified
30.920 + * while an iteration over the set is in progress (except through
30.921 + * the iterator's own <tt>remove</tt> operation, or through the
30.922 + * <tt>setValue</tt> operation on a map entry returned by the
30.923 + * iterator) the results of the iteration are undefined. The set
30.924 + * supports element removal, which removes the corresponding
30.925 + * mapping from the map, via the <tt>Iterator.remove</tt>,
30.926 + * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
30.927 + * <tt>clear</tt> operations. It does not support the
30.928 + * <tt>add</tt> or <tt>addAll</tt> operations.
30.929 + */
30.930 + public Set<Map.Entry<K,V>> entrySet() {
30.931 + Set<Map.Entry<K,V>> es = entrySet;
30.932 + return es != null ? es : (entrySet = new EntrySet());
30.933 + }
30.934 +
30.935 + private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
30.936 + public Iterator<Map.Entry<K,V>> iterator() {
30.937 + return new EntryIterator();
30.938 + }
30.939 +
30.940 + public boolean contains(Object o) {
30.941 + if (!(o instanceof Map.Entry))
30.942 + return false;
30.943 + Map.Entry<?,?> e = (Map.Entry<?,?>)o;
30.944 + Entry<K,V> candidate = getEntry(e.getKey());
30.945 + return candidate != null && candidate.equals(e);
30.946 + }
30.947 +
30.948 + public boolean remove(Object o) {
30.949 + return removeMapping(o);
30.950 + }
30.951 +
30.952 + public int size() {
30.953 + return WeakHashMap.this.size();
30.954 + }
30.955 +
30.956 + public void clear() {
30.957 + WeakHashMap.this.clear();
30.958 + }
30.959 +
30.960 + private List<Map.Entry<K,V>> deepCopy() {
30.961 + List<Map.Entry<K,V>> list = new ArrayList<>(size());
30.962 + for (Map.Entry<K,V> e : this)
30.963 + list.add(new AbstractMap.SimpleEntry<>(e));
30.964 + return list;
30.965 + }
30.966 +
30.967 + public Object[] toArray() {
30.968 + return deepCopy().toArray();
30.969 + }
30.970 +
30.971 + public <T> T[] toArray(T[] a) {
30.972 + return deepCopy().toArray(a);
30.973 + }
30.974 + }
30.975 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/emul/compact/src/main/java/java/util/concurrent/Executor.java Sat Sep 07 13:51:24 2013 +0200
31.3 @@ -0,0 +1,141 @@
31.4 +/*
31.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
31.6 + *
31.7 + * This code is free software; you can redistribute it and/or modify it
31.8 + * under the terms of the GNU General Public License version 2 only, as
31.9 + * published by the Free Software Foundation. Oracle designates this
31.10 + * particular file as subject to the "Classpath" exception as provided
31.11 + * by Oracle in the LICENSE file that accompanied this code.
31.12 + *
31.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
31.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31.16 + * version 2 for more details (a copy is included in the LICENSE file that
31.17 + * accompanied this code).
31.18 + *
31.19 + * You should have received a copy of the GNU General Public License version
31.20 + * 2 along with this work; if not, write to the Free Software Foundation,
31.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
31.22 + *
31.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
31.24 + * or visit www.oracle.com if you need additional information or have any
31.25 + * questions.
31.26 + */
31.27 +
31.28 +/*
31.29 + * This file is available under and governed by the GNU General Public
31.30 + * License version 2 only, as published by the Free Software Foundation.
31.31 + * However, the following notice accompanied the original version of this
31.32 + * file:
31.33 + *
31.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
31.35 + * Expert Group and released to the public domain, as explained at
31.36 + * http://creativecommons.org/publicdomain/zero/1.0/
31.37 + */
31.38 +
31.39 +package java.util.concurrent;
31.40 +
31.41 +/**
31.42 + * An object that executes submitted {@link Runnable} tasks. This
31.43 + * interface provides a way of decoupling task submission from the
31.44 + * mechanics of how each task will be run, including details of thread
31.45 + * use, scheduling, etc. An <tt>Executor</tt> is normally used
31.46 + * instead of explicitly creating threads. For example, rather than
31.47 + * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each
31.48 + * of a set of tasks, you might use:
31.49 + *
31.50 + * <pre>
31.51 + * Executor executor = <em>anExecutor</em>;
31.52 + * executor.execute(new RunnableTask1());
31.53 + * executor.execute(new RunnableTask2());
31.54 + * ...
31.55 + * </pre>
31.56 + *
31.57 + * However, the <tt>Executor</tt> interface does not strictly
31.58 + * require that execution be asynchronous. In the simplest case, an
31.59 + * executor can run the submitted task immediately in the caller's
31.60 + * thread:
31.61 + *
31.62 + * <pre>
31.63 + * class DirectExecutor implements Executor {
31.64 + * public void execute(Runnable r) {
31.65 + * r.run();
31.66 + * }
31.67 + * }</pre>
31.68 + *
31.69 + * More typically, tasks are executed in some thread other
31.70 + * than the caller's thread. The executor below spawns a new thread
31.71 + * for each task.
31.72 + *
31.73 + * <pre>
31.74 + * class ThreadPerTaskExecutor implements Executor {
31.75 + * public void execute(Runnable r) {
31.76 + * new Thread(r).start();
31.77 + * }
31.78 + * }</pre>
31.79 + *
31.80 + * Many <tt>Executor</tt> implementations impose some sort of
31.81 + * limitation on how and when tasks are scheduled. The executor below
31.82 + * serializes the submission of tasks to a second executor,
31.83 + * illustrating a composite executor.
31.84 + *
31.85 + * <pre> {@code
31.86 + * class SerialExecutor implements Executor {
31.87 + * final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
31.88 + * final Executor executor;
31.89 + * Runnable active;
31.90 + *
31.91 + * SerialExecutor(Executor executor) {
31.92 + * this.executor = executor;
31.93 + * }
31.94 + *
31.95 + * public synchronized void execute(final Runnable r) {
31.96 + * tasks.offer(new Runnable() {
31.97 + * public void run() {
31.98 + * try {
31.99 + * r.run();
31.100 + * } finally {
31.101 + * scheduleNext();
31.102 + * }
31.103 + * }
31.104 + * });
31.105 + * if (active == null) {
31.106 + * scheduleNext();
31.107 + * }
31.108 + * }
31.109 + *
31.110 + * protected synchronized void scheduleNext() {
31.111 + * if ((active = tasks.poll()) != null) {
31.112 + * executor.execute(active);
31.113 + * }
31.114 + * }
31.115 + * }}</pre>
31.116 + *
31.117 + * The <tt>Executor</tt> implementations provided in this package
31.118 + * implement {@link ExecutorService}, which is a more extensive
31.119 + * interface. The {@link ThreadPoolExecutor} class provides an
31.120 + * extensible thread pool implementation. The {@link Executors} class
31.121 + * provides convenient factory methods for these Executors.
31.122 + *
31.123 + * <p>Memory consistency effects: Actions in a thread prior to
31.124 + * submitting a {@code Runnable} object to an {@code Executor}
31.125 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
31.126 + * its execution begins, perhaps in another thread.
31.127 + *
31.128 + * @since 1.5
31.129 + * @author Doug Lea
31.130 + */
31.131 +public interface Executor {
31.132 +
31.133 + /**
31.134 + * Executes the given command at some time in the future. The command
31.135 + * may execute in a new thread, in a pooled thread, or in the calling
31.136 + * thread, at the discretion of the <tt>Executor</tt> implementation.
31.137 + *
31.138 + * @param command the runnable task
31.139 + * @throws RejectedExecutionException if this task cannot be
31.140 + * accepted for execution.
31.141 + * @throws NullPointerException if command is null
31.142 + */
31.143 + void execute(Runnable command);
31.144 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/emul/compact/src/main/java/java/util/logging/Level.java Sat Sep 07 13:51:24 2013 +0200
32.3 @@ -0,0 +1,378 @@
32.4 +/*
32.5 + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
32.7 + *
32.8 + * This code is free software; you can redistribute it and/or modify it
32.9 + * under the terms of the GNU General Public License version 2 only, as
32.10 + * published by the Free Software Foundation. Oracle designates this
32.11 + * particular file as subject to the "Classpath" exception as provided
32.12 + * by Oracle in the LICENSE file that accompanied this code.
32.13 + *
32.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
32.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32.17 + * version 2 for more details (a copy is included in the LICENSE file that
32.18 + * accompanied this code).
32.19 + *
32.20 + * You should have received a copy of the GNU General Public License version
32.21 + * 2 along with this work; if not, write to the Free Software Foundation,
32.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
32.23 + *
32.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
32.25 + * or visit www.oracle.com if you need additional information or have any
32.26 + * questions.
32.27 + */
32.28 +
32.29 +package java.util.logging;
32.30 +import java.util.ResourceBundle;
32.31 +
32.32 +/**
32.33 + * The Level class defines a set of standard logging levels that
32.34 + * can be used to control logging output. The logging Level objects
32.35 + * are ordered and are specified by ordered integers. Enabling logging
32.36 + * at a given level also enables logging at all higher levels.
32.37 + * <p>
32.38 + * Clients should normally use the predefined Level constants such
32.39 + * as Level.SEVERE.
32.40 + * <p>
32.41 + * The levels in descending order are:
32.42 + * <ul>
32.43 + * <li>SEVERE (highest value)
32.44 + * <li>WARNING
32.45 + * <li>INFO
32.46 + * <li>CONFIG
32.47 + * <li>FINE
32.48 + * <li>FINER
32.49 + * <li>FINEST (lowest value)
32.50 + * </ul>
32.51 + * In addition there is a level OFF that can be used to turn
32.52 + * off logging, and a level ALL that can be used to enable
32.53 + * logging of all messages.
32.54 + * <p>
32.55 + * It is possible for third parties to define additional logging
32.56 + * levels by subclassing Level. In such cases subclasses should
32.57 + * take care to chose unique integer level values and to ensure that
32.58 + * they maintain the Object uniqueness property across serialization
32.59 + * by defining a suitable readResolve method.
32.60 + *
32.61 + * @since 1.4
32.62 + */
32.63 +
32.64 +public class Level implements java.io.Serializable {
32.65 + private static java.util.ArrayList<Level> known = new java.util.ArrayList<>();
32.66 + private static String defaultBundle = "sun.util.logging.resources.logging";
32.67 +
32.68 + /**
32.69 + * @serial The non-localized name of the level.
32.70 + */
32.71 + private final String name;
32.72 +
32.73 + /**
32.74 + * @serial The integer value of the level.
32.75 + */
32.76 + private final int value;
32.77 +
32.78 + /**
32.79 + * @serial The resource bundle name to be used in localizing the level name.
32.80 + */
32.81 + private final String resourceBundleName;
32.82 +
32.83 + /**
32.84 + * OFF is a special level that can be used to turn off logging.
32.85 + * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
32.86 + */
32.87 + public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);
32.88 +
32.89 + /**
32.90 + * SEVERE is a message level indicating a serious failure.
32.91 + * <p>
32.92 + * In general SEVERE messages should describe events that are
32.93 + * of considerable importance and which will prevent normal
32.94 + * program execution. They should be reasonably intelligible
32.95 + * to end users and to system administrators.
32.96 + * This level is initialized to <CODE>1000</CODE>.
32.97 + */
32.98 + public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);
32.99 +
32.100 + /**
32.101 + * WARNING is a message level indicating a potential problem.
32.102 + * <p>
32.103 + * In general WARNING messages should describe events that will
32.104 + * be of interest to end users or system managers, or which
32.105 + * indicate potential problems.
32.106 + * This level is initialized to <CODE>900</CODE>.
32.107 + */
32.108 + public static final Level WARNING = new Level("WARNING", 900, defaultBundle);
32.109 +
32.110 + /**
32.111 + * INFO is a message level for informational messages.
32.112 + * <p>
32.113 + * Typically INFO messages will be written to the console
32.114 + * or its equivalent. So the INFO level should only be
32.115 + * used for reasonably significant messages that will
32.116 + * make sense to end users and system administrators.
32.117 + * This level is initialized to <CODE>800</CODE>.
32.118 + */
32.119 + public static final Level INFO = new Level("INFO", 800, defaultBundle);
32.120 +
32.121 + /**
32.122 + * CONFIG is a message level for static configuration messages.
32.123 + * <p>
32.124 + * CONFIG messages are intended to provide a variety of static
32.125 + * configuration information, to assist in debugging problems
32.126 + * that may be associated with particular configurations.
32.127 + * For example, CONFIG message might include the CPU type,
32.128 + * the graphics depth, the GUI look-and-feel, etc.
32.129 + * This level is initialized to <CODE>700</CODE>.
32.130 + */
32.131 + public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);
32.132 +
32.133 + /**
32.134 + * FINE is a message level providing tracing information.
32.135 + * <p>
32.136 + * All of FINE, FINER, and FINEST are intended for relatively
32.137 + * detailed tracing. The exact meaning of the three levels will
32.138 + * vary between subsystems, but in general, FINEST should be used
32.139 + * for the most voluminous detailed output, FINER for somewhat
32.140 + * less detailed output, and FINE for the lowest volume (and
32.141 + * most important) messages.
32.142 + * <p>
32.143 + * In general the FINE level should be used for information
32.144 + * that will be broadly interesting to developers who do not have
32.145 + * a specialized interest in the specific subsystem.
32.146 + * <p>
32.147 + * FINE messages might include things like minor (recoverable)
32.148 + * failures. Issues indicating potential performance problems
32.149 + * are also worth logging as FINE.
32.150 + * This level is initialized to <CODE>500</CODE>.
32.151 + */
32.152 + public static final Level FINE = new Level("FINE", 500, defaultBundle);
32.153 +
32.154 + /**
32.155 + * FINER indicates a fairly detailed tracing message.
32.156 + * By default logging calls for entering, returning, or throwing
32.157 + * an exception are traced at this level.
32.158 + * This level is initialized to <CODE>400</CODE>.
32.159 + */
32.160 + public static final Level FINER = new Level("FINER", 400, defaultBundle);
32.161 +
32.162 + /**
32.163 + * FINEST indicates a highly detailed tracing message.
32.164 + * This level is initialized to <CODE>300</CODE>.
32.165 + */
32.166 + public static final Level FINEST = new Level("FINEST", 300, defaultBundle);
32.167 +
32.168 + /**
32.169 + * ALL indicates that all messages should be logged.
32.170 + * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
32.171 + */
32.172 + public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
32.173 +
32.174 + /**
32.175 + * Create a named Level with a given integer value.
32.176 + * <p>
32.177 + * Note that this constructor is "protected" to allow subclassing.
32.178 + * In general clients of logging should use one of the constant Level
32.179 + * objects such as SEVERE or FINEST. However, if clients need to
32.180 + * add new logging levels, they may subclass Level and define new
32.181 + * constants.
32.182 + * @param name the name of the Level, for example "SEVERE".
32.183 + * @param value an integer value for the level.
32.184 + * @throws NullPointerException if the name is null
32.185 + */
32.186 + protected Level(String name, int value) {
32.187 + this(name, value, null);
32.188 + }
32.189 +
32.190 + /**
32.191 + * Create a named Level with a given integer value and a
32.192 + * given localization resource name.
32.193 + * <p>
32.194 + * @param name the name of the Level, for example "SEVERE".
32.195 + * @param value an integer value for the level.
32.196 + * @param resourceBundleName name of a resource bundle to use in
32.197 + * localizing the given name. If the resourceBundleName is null
32.198 + * or an empty string, it is ignored.
32.199 + * @throws NullPointerException if the name is null
32.200 + */
32.201 + protected Level(String name, int value, String resourceBundleName) {
32.202 + if (name == null) {
32.203 + throw new NullPointerException();
32.204 + }
32.205 + this.name = name;
32.206 + this.value = value;
32.207 + this.resourceBundleName = resourceBundleName;
32.208 + synchronized (Level.class) {
32.209 + known.add(this);
32.210 + }
32.211 + }
32.212 +
32.213 + /**
32.214 + * Return the level's localization resource bundle name, or
32.215 + * null if no localization bundle is defined.
32.216 + *
32.217 + * @return localization resource bundle name
32.218 + */
32.219 + public String getResourceBundleName() {
32.220 + return resourceBundleName;
32.221 + }
32.222 +
32.223 + /**
32.224 + * Return the non-localized string name of the Level.
32.225 + *
32.226 + * @return non-localized name
32.227 + */
32.228 + public String getName() {
32.229 + return name;
32.230 + }
32.231 +
32.232 + /**
32.233 + * Return the localized string name of the Level, for
32.234 + * the current default locale.
32.235 + * <p>
32.236 + * If no localization information is available, the
32.237 + * non-localized name is returned.
32.238 + *
32.239 + * @return localized name
32.240 + */
32.241 + public String getLocalizedName() {
32.242 + try {
32.243 + ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
32.244 + return rb.getString(name);
32.245 + } catch (Exception ex) {
32.246 + return name;
32.247 + }
32.248 + }
32.249 +
32.250 + /**
32.251 + * Returns a string representation of this Level.
32.252 + *
32.253 + * @return the non-localized name of the Level, for example "INFO".
32.254 + */
32.255 + public final String toString() {
32.256 + return name;
32.257 + }
32.258 +
32.259 + /**
32.260 + * Get the integer value for this level. This integer value
32.261 + * can be used for efficient ordering comparisons between
32.262 + * Level objects.
32.263 + * @return the integer value for this level.
32.264 + */
32.265 + public final int intValue() {
32.266 + return value;
32.267 + }
32.268 +
32.269 + private static final long serialVersionUID = -8176160795706313070L;
32.270 +
32.271 + // Serialization magic to prevent "doppelgangers".
32.272 + // This is a performance optimization.
32.273 + private Object readResolve() {
32.274 + synchronized (Level.class) {
32.275 + for (int i = 0; i < known.size(); i++) {
32.276 + Level other = known.get(i);
32.277 + if (this.name.equals(other.name) && this.value == other.value
32.278 + && (this.resourceBundleName == other.resourceBundleName ||
32.279 + (this.resourceBundleName != null &&
32.280 + this.resourceBundleName.equals(other.resourceBundleName)))) {
32.281 + return other;
32.282 + }
32.283 + }
32.284 + // Woops. Whoever sent us this object knows
32.285 + // about a new log level. Add it to our list.
32.286 + known.add(this);
32.287 + return this;
32.288 + }
32.289 + }
32.290 +
32.291 + /**
32.292 + * Parse a level name string into a Level.
32.293 + * <p>
32.294 + * The argument string may consist of either a level name
32.295 + * or an integer value.
32.296 + * <p>
32.297 + * For example:
32.298 + * <ul>
32.299 + * <li> "SEVERE"
32.300 + * <li> "1000"
32.301 + * </ul>
32.302 + * @param name string to be parsed
32.303 + * @throws NullPointerException if the name is null
32.304 + * @throws IllegalArgumentException if the value is not valid.
32.305 + * Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
32.306 + * and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
32.307 + * Known names are the levels defined by this class (e.g., <CODE>FINE</CODE>,
32.308 + * <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
32.309 + * appropriate package access, or new levels defined or created
32.310 + * by subclasses.
32.311 + *
32.312 + * @return The parsed value. Passing an integer that corresponds to a known name
32.313 + * (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>).
32.314 + * Passing an integer that does not (e.g., 1) will return a new level name
32.315 + * initialized to that value.
32.316 + */
32.317 + public static synchronized Level parse(String name) throws IllegalArgumentException {
32.318 + // Check that name is not null.
32.319 + name.length();
32.320 +
32.321 + // Look for a known Level with the given non-localized name.
32.322 + for (int i = 0; i < known.size(); i++) {
32.323 + Level l = known.get(i);
32.324 + if (name.equals(l.name)) {
32.325 + return l;
32.326 + }
32.327 + }
32.328 +
32.329 + // Now, check if the given name is an integer. If so,
32.330 + // first look for a Level with the given value and then
32.331 + // if necessary create one.
32.332 + try {
32.333 + int x = Integer.parseInt(name);
32.334 + for (int i = 0; i < known.size(); i++) {
32.335 + Level l = known.get(i);
32.336 + if (l.value == x) {
32.337 + return l;
32.338 + }
32.339 + }
32.340 + // Create a new Level.
32.341 + return new Level(name, x);
32.342 + } catch (NumberFormatException ex) {
32.343 + // Not an integer.
32.344 + // Drop through.
32.345 + }
32.346 +
32.347 + // Finally, look for a known level with the given localized name,
32.348 + // in the current default locale.
32.349 + // This is relatively expensive, but not excessively so.
32.350 + for (int i = 0; i < known.size(); i++) {
32.351 + Level l = known.get(i);
32.352 + if (name.equals(l.getLocalizedName())) {
32.353 + return l;
32.354 + }
32.355 + }
32.356 +
32.357 + // OK, we've tried everything and failed
32.358 + throw new IllegalArgumentException("Bad level \"" + name + "\"");
32.359 + }
32.360 +
32.361 + /**
32.362 + * Compare two objects for value equality.
32.363 + * @return true if and only if the two objects have the same level value.
32.364 + */
32.365 + public boolean equals(Object ox) {
32.366 + try {
32.367 + Level lx = (Level)ox;
32.368 + return (lx.value == this.value);
32.369 + } catch (Exception ex) {
32.370 + return false;
32.371 + }
32.372 + }
32.373 +
32.374 + /**
32.375 + * Generate a hashcode.
32.376 + * @return a hashcode based on the level value
32.377 + */
32.378 + public int hashCode() {
32.379 + return this.value;
32.380 + }
32.381 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/emul/compact/src/main/java/java/util/logging/LogRecord.java Sat Sep 07 13:51:24 2013 +0200
33.3 @@ -0,0 +1,566 @@
33.4 +/*
33.5 + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33.7 + *
33.8 + * This code is free software; you can redistribute it and/or modify it
33.9 + * under the terms of the GNU General Public License version 2 only, as
33.10 + * published by the Free Software Foundation. Oracle designates this
33.11 + * particular file as subject to the "Classpath" exception as provided
33.12 + * by Oracle in the LICENSE file that accompanied this code.
33.13 + *
33.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
33.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33.17 + * version 2 for more details (a copy is included in the LICENSE file that
33.18 + * accompanied this code).
33.19 + *
33.20 + * You should have received a copy of the GNU General Public License version
33.21 + * 2 along with this work; if not, write to the Free Software Foundation,
33.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
33.23 + *
33.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
33.25 + * or visit www.oracle.com if you need additional information or have any
33.26 + * questions.
33.27 + */
33.28 +
33.29 +package java.util.logging;
33.30 +import java.util.*;
33.31 +import java.util.concurrent.atomic.AtomicInteger;
33.32 +import java.util.concurrent.atomic.AtomicLong;
33.33 +import java.io.*;
33.34 +
33.35 +import sun.misc.JavaLangAccess;
33.36 +import sun.misc.SharedSecrets;
33.37 +
33.38 +/**
33.39 + * LogRecord objects are used to pass logging requests between
33.40 + * the logging framework and individual log Handlers.
33.41 + * <p>
33.42 + * When a LogRecord is passed into the logging framework it
33.43 + * logically belongs to the framework and should no longer be
33.44 + * used or updated by the client application.
33.45 + * <p>
33.46 + * Note that if the client application has not specified an
33.47 + * explicit source method name and source class name, then the
33.48 + * LogRecord class will infer them automatically when they are
33.49 + * first accessed (due to a call on getSourceMethodName or
33.50 + * getSourceClassName) by analyzing the call stack. Therefore,
33.51 + * if a logging Handler wants to pass off a LogRecord to another
33.52 + * thread, or to transmit it over RMI, and if it wishes to subsequently
33.53 + * obtain method name or class name information it should call
33.54 + * one of getSourceClassName or getSourceMethodName to force
33.55 + * the values to be filled in.
33.56 + * <p>
33.57 + * <b> Serialization notes:</b>
33.58 + * <ul>
33.59 + * <li>The LogRecord class is serializable.
33.60 + *
33.61 + * <li> Because objects in the parameters array may not be serializable,
33.62 + * during serialization all objects in the parameters array are
33.63 + * written as the corresponding Strings (using Object.toString).
33.64 + *
33.65 + * <li> The ResourceBundle is not transmitted as part of the serialized
33.66 + * form, but the resource bundle name is, and the recipient object's
33.67 + * readObject method will attempt to locate a suitable resource bundle.
33.68 + *
33.69 + * </ul>
33.70 + *
33.71 + * @since 1.4
33.72 + */
33.73 +
33.74 +public class LogRecord implements java.io.Serializable {
33.75 + private static final AtomicLong globalSequenceNumber
33.76 + = new AtomicLong(0);
33.77 +
33.78 + /**
33.79 + * The default value of threadID will be the current thread's
33.80 + * thread id, for ease of correlation, unless it is greater than
33.81 + * MIN_SEQUENTIAL_THREAD_ID, in which case we try harder to keep
33.82 + * our promise to keep threadIDs unique by avoiding collisions due
33.83 + * to 32-bit wraparound. Unfortunately, LogRecord.getThreadID()
33.84 + * returns int, while Thread.getId() returns long.
33.85 + */
33.86 + private static final int MIN_SEQUENTIAL_THREAD_ID = Integer.MAX_VALUE / 2;
33.87 +
33.88 + private static final AtomicInteger nextThreadId
33.89 + = new AtomicInteger(MIN_SEQUENTIAL_THREAD_ID);
33.90 +
33.91 + private static final ThreadLocal<Integer> threadIds = new ThreadLocal<>();
33.92 +
33.93 + /**
33.94 + * @serial Logging message level
33.95 + */
33.96 + private Level level;
33.97 +
33.98 + /**
33.99 + * @serial Sequence number
33.100 + */
33.101 + private long sequenceNumber;
33.102 +
33.103 + /**
33.104 + * @serial Class that issued logging call
33.105 + */
33.106 + private String sourceClassName;
33.107 +
33.108 + /**
33.109 + * @serial Method that issued logging call
33.110 + */
33.111 + private String sourceMethodName;
33.112 +
33.113 + /**
33.114 + * @serial Non-localized raw message text
33.115 + */
33.116 + private String message;
33.117 +
33.118 + /**
33.119 + * @serial Thread ID for thread that issued logging call.
33.120 + */
33.121 + private int threadID;
33.122 +
33.123 + /**
33.124 + * @serial Event time in milliseconds since 1970
33.125 + */
33.126 + private long millis;
33.127 +
33.128 + /**
33.129 + * @serial The Throwable (if any) associated with log message
33.130 + */
33.131 + private Throwable thrown;
33.132 +
33.133 + /**
33.134 + * @serial Name of the source Logger.
33.135 + */
33.136 + private String loggerName;
33.137 +
33.138 + /**
33.139 + * @serial Resource bundle name to localized log message.
33.140 + */
33.141 + private String resourceBundleName;
33.142 +
33.143 + private transient boolean needToInferCaller;
33.144 + private transient Object parameters[];
33.145 + private transient ResourceBundle resourceBundle;
33.146 +
33.147 + /**
33.148 + * Returns the default value for a new LogRecord's threadID.
33.149 + */
33.150 + private int defaultThreadID() {
33.151 + long tid = Thread.currentThread().getId();
33.152 + if (tid < MIN_SEQUENTIAL_THREAD_ID) {
33.153 + return (int) tid;
33.154 + } else {
33.155 + Integer id = threadIds.get();
33.156 + if (id == null) {
33.157 + id = nextThreadId.getAndIncrement();
33.158 + threadIds.set(id);
33.159 + }
33.160 + return id;
33.161 + }
33.162 + }
33.163 +
33.164 + /**
33.165 + * Construct a LogRecord with the given level and message values.
33.166 + * <p>
33.167 + * The sequence property will be initialized with a new unique value.
33.168 + * These sequence values are allocated in increasing order within a VM.
33.169 + * <p>
33.170 + * The millis property will be initialized to the current time.
33.171 + * <p>
33.172 + * The thread ID property will be initialized with a unique ID for
33.173 + * the current thread.
33.174 + * <p>
33.175 + * All other properties will be initialized to "null".
33.176 + *
33.177 + * @param level a logging level value
33.178 + * @param msg the raw non-localized logging message (may be null)
33.179 + */
33.180 + public LogRecord(Level level, String msg) {
33.181 + // Make sure level isn't null, by calling random method.
33.182 + level.getClass();
33.183 + this.level = level;
33.184 + message = msg;
33.185 + // Assign a thread ID and a unique sequence number.
33.186 + sequenceNumber = globalSequenceNumber.getAndIncrement();
33.187 + threadID = defaultThreadID();
33.188 + millis = System.currentTimeMillis();
33.189 + needToInferCaller = true;
33.190 + }
33.191 +
33.192 + /**
33.193 + * Get the source Logger's name.
33.194 + *
33.195 + * @return source logger name (may be null)
33.196 + */
33.197 + public String getLoggerName() {
33.198 + return loggerName;
33.199 + }
33.200 +
33.201 + /**
33.202 + * Set the source Logger's name.
33.203 + *
33.204 + * @param name the source logger name (may be null)
33.205 + */
33.206 + public void setLoggerName(String name) {
33.207 + loggerName = name;
33.208 + }
33.209 +
33.210 + /**
33.211 + * Get the localization resource bundle
33.212 + * <p>
33.213 + * This is the ResourceBundle that should be used to localize
33.214 + * the message string before formatting it. The result may
33.215 + * be null if the message is not localizable, or if no suitable
33.216 + * ResourceBundle is available.
33.217 + */
33.218 + public ResourceBundle getResourceBundle() {
33.219 + return resourceBundle;
33.220 + }
33.221 +
33.222 + /**
33.223 + * Set the localization resource bundle.
33.224 + *
33.225 + * @param bundle localization bundle (may be null)
33.226 + */
33.227 + public void setResourceBundle(ResourceBundle bundle) {
33.228 + resourceBundle = bundle;
33.229 + }
33.230 +
33.231 + /**
33.232 + * Get the localization resource bundle name
33.233 + * <p>
33.234 + * This is the name for the ResourceBundle that should be
33.235 + * used to localize the message string before formatting it.
33.236 + * The result may be null if the message is not localizable.
33.237 + */
33.238 + public String getResourceBundleName() {
33.239 + return resourceBundleName;
33.240 + }
33.241 +
33.242 + /**
33.243 + * Set the localization resource bundle name.
33.244 + *
33.245 + * @param name localization bundle name (may be null)
33.246 + */
33.247 + public void setResourceBundleName(String name) {
33.248 + resourceBundleName = name;
33.249 + }
33.250 +
33.251 + /**
33.252 + * Get the logging message level, for example Level.SEVERE.
33.253 + * @return the logging message level
33.254 + */
33.255 + public Level getLevel() {
33.256 + return level;
33.257 + }
33.258 +
33.259 + /**
33.260 + * Set the logging message level, for example Level.SEVERE.
33.261 + * @param level the logging message level
33.262 + */
33.263 + public void setLevel(Level level) {
33.264 + if (level == null) {
33.265 + throw new NullPointerException();
33.266 + }
33.267 + this.level = level;
33.268 + }
33.269 +
33.270 + /**
33.271 + * Get the sequence number.
33.272 + * <p>
33.273 + * Sequence numbers are normally assigned in the LogRecord
33.274 + * constructor, which assigns unique sequence numbers to
33.275 + * each new LogRecord in increasing order.
33.276 + * @return the sequence number
33.277 + */
33.278 + public long getSequenceNumber() {
33.279 + return sequenceNumber;
33.280 + }
33.281 +
33.282 + /**
33.283 + * Set the sequence number.
33.284 + * <p>
33.285 + * Sequence numbers are normally assigned in the LogRecord constructor,
33.286 + * so it should not normally be necessary to use this method.
33.287 + */
33.288 + public void setSequenceNumber(long seq) {
33.289 + sequenceNumber = seq;
33.290 + }
33.291 +
33.292 + /**
33.293 + * Get the name of the class that (allegedly) issued the logging request.
33.294 + * <p>
33.295 + * Note that this sourceClassName is not verified and may be spoofed.
33.296 + * This information may either have been provided as part of the
33.297 + * logging call, or it may have been inferred automatically by the
33.298 + * logging framework. In the latter case, the information may only
33.299 + * be approximate and may in fact describe an earlier call on the
33.300 + * stack frame.
33.301 + * <p>
33.302 + * May be null if no information could be obtained.
33.303 + *
33.304 + * @return the source class name
33.305 + */
33.306 + public String getSourceClassName() {
33.307 + if (needToInferCaller) {
33.308 + inferCaller();
33.309 + }
33.310 + return sourceClassName;
33.311 + }
33.312 +
33.313 + /**
33.314 + * Set the name of the class that (allegedly) issued the logging request.
33.315 + *
33.316 + * @param sourceClassName the source class name (may be null)
33.317 + */
33.318 + public void setSourceClassName(String sourceClassName) {
33.319 + this.sourceClassName = sourceClassName;
33.320 + needToInferCaller = false;
33.321 + }
33.322 +
33.323 + /**
33.324 + * Get the name of the method that (allegedly) issued the logging request.
33.325 + * <p>
33.326 + * Note that this sourceMethodName is not verified and may be spoofed.
33.327 + * This information may either have been provided as part of the
33.328 + * logging call, or it may have been inferred automatically by the
33.329 + * logging framework. In the latter case, the information may only
33.330 + * be approximate and may in fact describe an earlier call on the
33.331 + * stack frame.
33.332 + * <p>
33.333 + * May be null if no information could be obtained.
33.334 + *
33.335 + * @return the source method name
33.336 + */
33.337 + public String getSourceMethodName() {
33.338 + if (needToInferCaller) {
33.339 + inferCaller();
33.340 + }
33.341 + return sourceMethodName;
33.342 + }
33.343 +
33.344 + /**
33.345 + * Set the name of the method that (allegedly) issued the logging request.
33.346 + *
33.347 + * @param sourceMethodName the source method name (may be null)
33.348 + */
33.349 + public void setSourceMethodName(String sourceMethodName) {
33.350 + this.sourceMethodName = sourceMethodName;
33.351 + needToInferCaller = false;
33.352 + }
33.353 +
33.354 + /**
33.355 + * Get the "raw" log message, before localization or formatting.
33.356 + * <p>
33.357 + * May be null, which is equivalent to the empty string "".
33.358 + * <p>
33.359 + * This message may be either the final text or a localization key.
33.360 + * <p>
33.361 + * During formatting, if the source logger has a localization
33.362 + * ResourceBundle and if that ResourceBundle has an entry for
33.363 + * this message string, then the message string is replaced
33.364 + * with the localized value.
33.365 + *
33.366 + * @return the raw message string
33.367 + */
33.368 + public String getMessage() {
33.369 + return message;
33.370 + }
33.371 +
33.372 + /**
33.373 + * Set the "raw" log message, before localization or formatting.
33.374 + *
33.375 + * @param message the raw message string (may be null)
33.376 + */
33.377 + public void setMessage(String message) {
33.378 + this.message = message;
33.379 + }
33.380 +
33.381 + /**
33.382 + * Get the parameters to the log message.
33.383 + *
33.384 + * @return the log message parameters. May be null if
33.385 + * there are no parameters.
33.386 + */
33.387 + public Object[] getParameters() {
33.388 + return parameters;
33.389 + }
33.390 +
33.391 + /**
33.392 + * Set the parameters to the log message.
33.393 + *
33.394 + * @param parameters the log message parameters. (may be null)
33.395 + */
33.396 + public void setParameters(Object parameters[]) {
33.397 + this.parameters = parameters;
33.398 + }
33.399 +
33.400 + /**
33.401 + * Get an identifier for the thread where the message originated.
33.402 + * <p>
33.403 + * This is a thread identifier within the Java VM and may or
33.404 + * may not map to any operating system ID.
33.405 + *
33.406 + * @return thread ID
33.407 + */
33.408 + public int getThreadID() {
33.409 + return threadID;
33.410 + }
33.411 +
33.412 + /**
33.413 + * Set an identifier for the thread where the message originated.
33.414 + * @param threadID the thread ID
33.415 + */
33.416 + public void setThreadID(int threadID) {
33.417 + this.threadID = threadID;
33.418 + }
33.419 +
33.420 + /**
33.421 + * Get event time in milliseconds since 1970.
33.422 + *
33.423 + * @return event time in millis since 1970
33.424 + */
33.425 + public long getMillis() {
33.426 + return millis;
33.427 + }
33.428 +
33.429 + /**
33.430 + * Set event time.
33.431 + *
33.432 + * @param millis event time in millis since 1970
33.433 + */
33.434 + public void setMillis(long millis) {
33.435 + this.millis = millis;
33.436 + }
33.437 +
33.438 + /**
33.439 + * Get any throwable associated with the log record.
33.440 + * <p>
33.441 + * If the event involved an exception, this will be the
33.442 + * exception object. Otherwise null.
33.443 + *
33.444 + * @return a throwable
33.445 + */
33.446 + public Throwable getThrown() {
33.447 + return thrown;
33.448 + }
33.449 +
33.450 + /**
33.451 + * Set a throwable associated with the log event.
33.452 + *
33.453 + * @param thrown a throwable (may be null)
33.454 + */
33.455 + public void setThrown(Throwable thrown) {
33.456 + this.thrown = thrown;
33.457 + }
33.458 +
33.459 + private static final long serialVersionUID = 5372048053134512534L;
33.460 +
33.461 + /**
33.462 + * @serialData Default fields, followed by a two byte version number
33.463 + * (major byte, followed by minor byte), followed by information on
33.464 + * the log record parameter array. If there is no parameter array,
33.465 + * then -1 is written. If there is a parameter array (possible of zero
33.466 + * length) then the array length is written as an integer, followed
33.467 + * by String values for each parameter. If a parameter is null, then
33.468 + * a null String is written. Otherwise the output of Object.toString()
33.469 + * is written.
33.470 + */
33.471 + private void writeObject(ObjectOutputStream out) throws IOException {
33.472 + // We have to call defaultWriteObject first.
33.473 + out.defaultWriteObject();
33.474 +
33.475 + // Write our version number.
33.476 + out.writeByte(1);
33.477 + out.writeByte(0);
33.478 + if (parameters == null) {
33.479 + out.writeInt(-1);
33.480 + return;
33.481 + }
33.482 + out.writeInt(parameters.length);
33.483 + // Write string values for the parameters.
33.484 + for (int i = 0; i < parameters.length; i++) {
33.485 + if (parameters[i] == null) {
33.486 + out.writeObject(null);
33.487 + } else {
33.488 + out.writeObject(parameters[i].toString());
33.489 + }
33.490 + }
33.491 + }
33.492 +
33.493 + private void readObject(ObjectInputStream in)
33.494 + throws IOException, ClassNotFoundException {
33.495 + // We have to call defaultReadObject first.
33.496 + in.defaultReadObject();
33.497 +
33.498 + // Read version number.
33.499 + byte major = in.readByte();
33.500 + byte minor = in.readByte();
33.501 + if (major != 1) {
33.502 + throw new IOException("LogRecord: bad version: " + major + "." + minor);
33.503 + }
33.504 + int len = in.readInt();
33.505 + if (len == -1) {
33.506 + parameters = null;
33.507 + } else {
33.508 + parameters = new Object[len];
33.509 + for (int i = 0; i < parameters.length; i++) {
33.510 + parameters[i] = in.readObject();
33.511 + }
33.512 + }
33.513 + // If necessary, try to regenerate the resource bundle.
33.514 + if (resourceBundleName != null) {
33.515 + try {
33.516 + resourceBundle = ResourceBundle.getBundle(resourceBundleName);
33.517 + } catch (MissingResourceException ex) {
33.518 + // This is not a good place to throw an exception,
33.519 + // so we simply leave the resourceBundle null.
33.520 + resourceBundle = null;
33.521 + }
33.522 + }
33.523 +
33.524 + needToInferCaller = false;
33.525 + }
33.526 +
33.527 + // Private method to infer the caller's class and method names
33.528 + private void inferCaller() {
33.529 + needToInferCaller = false;
33.530 + JavaLangAccess access = SharedSecrets.getJavaLangAccess();
33.531 + Throwable throwable = new Throwable();
33.532 + int depth = access.getStackTraceDepth(throwable);
33.533 +
33.534 + boolean lookingForLogger = true;
33.535 + for (int ix = 0; ix < depth; ix++) {
33.536 + // Calling getStackTraceElement directly prevents the VM
33.537 + // from paying the cost of building the entire stack frame.
33.538 + StackTraceElement frame =
33.539 + access.getStackTraceElement(throwable, ix);
33.540 + String cname = frame.getClassName();
33.541 + boolean isLoggerImpl = isLoggerImplFrame(cname);
33.542 + if (lookingForLogger) {
33.543 + // Skip all frames until we have found the first logger frame.
33.544 + if (isLoggerImpl) {
33.545 + lookingForLogger = false;
33.546 + }
33.547 + } else {
33.548 + if (!isLoggerImpl) {
33.549 + // skip reflection call
33.550 + if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
33.551 + // We've found the relevant frame.
33.552 + setSourceClassName(cname);
33.553 + setSourceMethodName(frame.getMethodName());
33.554 + return;
33.555 + }
33.556 + }
33.557 + }
33.558 + }
33.559 + // We haven't found a suitable frame, so just punt. This is
33.560 + // OK as we are only committed to making a "best effort" here.
33.561 + }
33.562 +
33.563 + private boolean isLoggerImplFrame(String cname) {
33.564 + // the log record could be created for a platform logger
33.565 + return (cname.equals("java.util.logging.Logger") ||
33.566 + cname.startsWith("java.util.logging.LoggingProxyImpl") ||
33.567 + cname.startsWith("sun.util.logging."));
33.568 + }
33.569 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/emul/compact/src/main/java/java/util/logging/Logger.java Sat Sep 07 13:51:24 2013 +0200
34.3 @@ -0,0 +1,1530 @@
34.4 +/*
34.5 + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
34.7 + *
34.8 + * This code is free software; you can redistribute it and/or modify it
34.9 + * under the terms of the GNU General Public License version 2 only, as
34.10 + * published by the Free Software Foundation. Oracle designates this
34.11 + * particular file as subject to the "Classpath" exception as provided
34.12 + * by Oracle in the LICENSE file that accompanied this code.
34.13 + *
34.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
34.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34.17 + * version 2 for more details (a copy is included in the LICENSE file that
34.18 + * accompanied this code).
34.19 + *
34.20 + * You should have received a copy of the GNU General Public License version
34.21 + * 2 along with this work; if not, write to the Free Software Foundation,
34.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
34.23 + *
34.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
34.25 + * or visit www.oracle.com if you need additional information or have any
34.26 + * questions.
34.27 + */
34.28 +
34.29 +
34.30 +package java.util.logging;
34.31 +
34.32 +import java.util.*;
34.33 +import java.util.concurrent.CopyOnWriteArrayList;
34.34 +import java.security.*;
34.35 +import java.lang.ref.WeakReference;
34.36 +
34.37 +/**
34.38 + * A Logger object is used to log messages for a specific
34.39 + * system or application component. Loggers are normally named,
34.40 + * using a hierarchical dot-separated namespace. Logger names
34.41 + * can be arbitrary strings, but they should normally be based on
34.42 + * the package name or class name of the logged component, such
34.43 + * as java.net or javax.swing. In addition it is possible to create
34.44 + * "anonymous" Loggers that are not stored in the Logger namespace.
34.45 + * <p>
34.46 + * Logger objects may be obtained by calls on one of the getLogger
34.47 + * factory methods. These will either create a new Logger or
34.48 + * return a suitable existing Logger. It is important to note that
34.49 + * the Logger returned by one of the {@code getLogger} factory methods
34.50 + * may be garbage collected at any time if a strong reference to the
34.51 + * Logger is not kept.
34.52 + * <p>
34.53 + * Logging messages will be forwarded to registered Handler
34.54 + * objects, which can forward the messages to a variety of
34.55 + * destinations, including consoles, files, OS logs, etc.
34.56 + * <p>
34.57 + * Each Logger keeps track of a "parent" Logger, which is its
34.58 + * nearest existing ancestor in the Logger namespace.
34.59 + * <p>
34.60 + * Each Logger has a "Level" associated with it. This reflects
34.61 + * a minimum Level that this logger cares about. If a Logger's
34.62 + * level is set to <tt>null</tt>, then its effective level is inherited
34.63 + * from its parent, which may in turn obtain it recursively from its
34.64 + * parent, and so on up the tree.
34.65 + * <p>
34.66 + * The log level can be configured based on the properties from the
34.67 + * logging configuration file, as described in the description
34.68 + * of the LogManager class. However it may also be dynamically changed
34.69 + * by calls on the Logger.setLevel method. If a logger's level is
34.70 + * changed the change may also affect child loggers, since any child
34.71 + * logger that has <tt>null</tt> as its level will inherit its
34.72 + * effective level from its parent.
34.73 + * <p>
34.74 + * On each logging call the Logger initially performs a cheap
34.75 + * check of the request level (e.g., SEVERE or FINE) against the
34.76 + * effective log level of the logger. If the request level is
34.77 + * lower than the log level, the logging call returns immediately.
34.78 + * <p>
34.79 + * After passing this initial (cheap) test, the Logger will allocate
34.80 + * a LogRecord to describe the logging message. It will then call a
34.81 + * Filter (if present) to do a more detailed check on whether the
34.82 + * record should be published. If that passes it will then publish
34.83 + * the LogRecord to its output Handlers. By default, loggers also
34.84 + * publish to their parent's Handlers, recursively up the tree.
34.85 + * <p>
34.86 + * Each Logger may have a ResourceBundle name associated with it.
34.87 + * The named bundle will be used for localizing logging messages.
34.88 + * If a Logger does not have its own ResourceBundle name, then
34.89 + * it will inherit the ResourceBundle name from its parent,
34.90 + * recursively up the tree.
34.91 + * <p>
34.92 + * Most of the logger output methods take a "msg" argument. This
34.93 + * msg argument may be either a raw value or a localization key.
34.94 + * During formatting, if the logger has (or inherits) a localization
34.95 + * ResourceBundle and if the ResourceBundle has a mapping for the msg
34.96 + * string, then the msg string is replaced by the localized value.
34.97 + * Otherwise the original msg string is used. Typically, formatters use
34.98 + * java.text.MessageFormat style formatting to format parameters, so
34.99 + * for example a format string "{0} {1}" would format two parameters
34.100 + * as strings.
34.101 + * <p>
34.102 + * When mapping ResourceBundle names to ResourceBundles, the Logger
34.103 + * will first try to use the Thread's ContextClassLoader. If that
34.104 + * is null it will try the SystemClassLoader instead. As a temporary
34.105 + * transition feature in the initial implementation, if the Logger is
34.106 + * unable to locate a ResourceBundle from the ContextClassLoader or
34.107 + * SystemClassLoader the Logger will also search up the class stack
34.108 + * and use successive calling ClassLoaders to try to locate a ResourceBundle.
34.109 + * (This call stack search is to allow containers to transition to
34.110 + * using ContextClassLoaders and is likely to be removed in future
34.111 + * versions.)
34.112 + * <p>
34.113 + * Formatting (including localization) is the responsibility of
34.114 + * the output Handler, which will typically call a Formatter.
34.115 + * <p>
34.116 + * Note that formatting need not occur synchronously. It may be delayed
34.117 + * until a LogRecord is actually written to an external sink.
34.118 + * <p>
34.119 + * The logging methods are grouped in five main categories:
34.120 + * <ul>
34.121 + * <li><p>
34.122 + * There are a set of "log" methods that take a log level, a message
34.123 + * string, and optionally some parameters to the message string.
34.124 + * <li><p>
34.125 + * There are a set of "logp" methods (for "log precise") that are
34.126 + * like the "log" methods, but also take an explicit source class name
34.127 + * and method name.
34.128 + * <li><p>
34.129 + * There are a set of "logrb" method (for "log with resource bundle")
34.130 + * that are like the "logp" method, but also take an explicit resource
34.131 + * bundle name for use in localizing the log message.
34.132 + * <li><p>
34.133 + * There are convenience methods for tracing method entries (the
34.134 + * "entering" methods), method returns (the "exiting" methods) and
34.135 + * throwing exceptions (the "throwing" methods).
34.136 + * <li><p>
34.137 + * Finally, there are a set of convenience methods for use in the
34.138 + * very simplest cases, when a developer simply wants to log a
34.139 + * simple string at a given log level. These methods are named
34.140 + * after the standard Level names ("severe", "warning", "info", etc.)
34.141 + * and take a single argument, a message string.
34.142 + * </ul>
34.143 + * <p>
34.144 + * For the methods that do not take an explicit source name and
34.145 + * method name, the Logging framework will make a "best effort"
34.146 + * to determine which class and method called into the logging method.
34.147 + * However, it is important to realize that this automatically inferred
34.148 + * information may only be approximate (or may even be quite wrong!).
34.149 + * Virtual machines are allowed to do extensive optimizations when
34.150 + * JITing and may entirely remove stack frames, making it impossible
34.151 + * to reliably locate the calling class and method.
34.152 + * <P>
34.153 + * All methods on Logger are multi-thread safe.
34.154 + * <p>
34.155 + * <b>Subclassing Information:</b> Note that a LogManager class may
34.156 + * provide its own implementation of named Loggers for any point in
34.157 + * the namespace. Therefore, any subclasses of Logger (unless they
34.158 + * are implemented in conjunction with a new LogManager class) should
34.159 + * take care to obtain a Logger instance from the LogManager class and
34.160 + * should delegate operations such as "isLoggable" and "log(LogRecord)"
34.161 + * to that instance. Note that in order to intercept all logging
34.162 + * output, subclasses need only override the log(LogRecord) method.
34.163 + * All the other logging methods are implemented as calls on this
34.164 + * log(LogRecord) method.
34.165 + *
34.166 + * @since 1.4
34.167 + */
34.168 +
34.169 +
34.170 +public class Logger {
34.171 + private static final Handler emptyHandlers[] = new Handler[0];
34.172 + private static final int offValue = Level.OFF.intValue();
34.173 + private LogManager manager;
34.174 + private String name;
34.175 + private final CopyOnWriteArrayList<Handler> handlers =
34.176 + new CopyOnWriteArrayList<>();
34.177 + private String resourceBundleName;
34.178 + private volatile boolean useParentHandlers = true;
34.179 + private volatile Filter filter;
34.180 + private boolean anonymous;
34.181 +
34.182 + private ResourceBundle catalog; // Cached resource bundle
34.183 + private String catalogName; // name associated with catalog
34.184 + private Locale catalogLocale; // locale associated with catalog
34.185 +
34.186 + // The fields relating to parent-child relationships and levels
34.187 + // are managed under a separate lock, the treeLock.
34.188 + private static Object treeLock = new Object();
34.189 + // We keep weak references from parents to children, but strong
34.190 + // references from children to parents.
34.191 + private volatile Logger parent; // our nearest parent.
34.192 + private ArrayList<LogManager.LoggerWeakRef> kids; // WeakReferences to loggers that have us as parent
34.193 + private volatile Level levelObject;
34.194 + private volatile int levelValue; // current effective level value
34.195 +
34.196 + /**
34.197 + * GLOBAL_LOGGER_NAME is a name for the global logger.
34.198 + *
34.199 + * @since 1.6
34.200 + */
34.201 + public static final String GLOBAL_LOGGER_NAME = "global";
34.202 +
34.203 + /**
34.204 + * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
34.205 + *
34.206 + * @return global logger object
34.207 + * @since 1.7
34.208 + */
34.209 + public static final Logger getGlobal() {
34.210 + return global;
34.211 + }
34.212 +
34.213 + /**
34.214 + * The "global" Logger object is provided as a convenience to developers
34.215 + * who are making casual use of the Logging package. Developers
34.216 + * who are making serious use of the logging package (for example
34.217 + * in products) should create and use their own Logger objects,
34.218 + * with appropriate names, so that logging can be controlled on a
34.219 + * suitable per-Logger granularity. Developers also need to keep a
34.220 + * strong reference to their Logger objects to prevent them from
34.221 + * being garbage collected.
34.222 + * <p>
34.223 + * @deprecated Initialization of this field is prone to deadlocks.
34.224 + * The field must be initialized by the Logger class initialization
34.225 + * which may cause deadlocks with the LogManager class initialization.
34.226 + * In such cases two class initialization wait for each other to complete.
34.227 + * The preferred way to get the global logger object is via the call
34.228 + * <code>Logger.getGlobal()</code>.
34.229 + * For compatibility with old JDK versions where the
34.230 + * <code>Logger.getGlobal()</code> is not available use the call
34.231 + * <code>Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)</code>
34.232 + * or <code>Logger.getLogger("global")</code>.
34.233 + */
34.234 + @Deprecated
34.235 + public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
34.236 +
34.237 + /**
34.238 + * Protected method to construct a logger for a named subsystem.
34.239 + * <p>
34.240 + * The logger will be initially configured with a null Level
34.241 + * and with useParentHandlers set to true.
34.242 + *
34.243 + * @param name A name for the logger. This should
34.244 + * be a dot-separated name and should normally
34.245 + * be based on the package name or class name
34.246 + * of the subsystem, such as java.net
34.247 + * or javax.swing. It may be null for anonymous Loggers.
34.248 + * @param resourceBundleName name of ResourceBundle to be used for localizing
34.249 + * messages for this logger. May be null if none
34.250 + * of the messages require localization.
34.251 + * @throws MissingResourceException if the resourceBundleName is non-null and
34.252 + * no corresponding resource can be found.
34.253 + */
34.254 + protected Logger(String name, String resourceBundleName) {
34.255 + this.manager = LogManager.getLogManager();
34.256 + if (resourceBundleName != null) {
34.257 + // Note: we may get a MissingResourceException here.
34.258 + setupResourceInfo(resourceBundleName);
34.259 + }
34.260 + this.name = name;
34.261 + levelValue = Level.INFO.intValue();
34.262 + }
34.263 +
34.264 + // This constructor is used only to create the global Logger.
34.265 + // It is needed to break a cyclic dependence between the LogManager
34.266 + // and Logger static initializers causing deadlocks.
34.267 + private Logger(String name) {
34.268 + // The manager field is not initialized here.
34.269 + this.name = name;
34.270 + levelValue = Level.INFO.intValue();
34.271 + }
34.272 +
34.273 + // It is called from the LogManager.<clinit> to complete
34.274 + // initialization of the global Logger.
34.275 + void setLogManager(LogManager manager) {
34.276 + this.manager = manager;
34.277 + }
34.278 +
34.279 + private void checkAccess() throws SecurityException {
34.280 + if (!anonymous) {
34.281 + if (manager == null) {
34.282 + // Complete initialization of the global Logger.
34.283 + manager = LogManager.getLogManager();
34.284 + }
34.285 + manager.checkAccess();
34.286 + }
34.287 + }
34.288 +
34.289 + /**
34.290 + * Find or create a logger for a named subsystem. If a logger has
34.291 + * already been created with the given name it is returned. Otherwise
34.292 + * a new logger is created.
34.293 + * <p>
34.294 + * If a new logger is created its log level will be configured
34.295 + * based on the LogManager configuration and it will configured
34.296 + * to also send logging output to its parent's Handlers. It will
34.297 + * be registered in the LogManager global namespace.
34.298 + * <p>
34.299 + * Note: The LogManager may only retain a weak reference to the newly
34.300 + * created Logger. It is important to understand that a previously
34.301 + * created Logger with the given name may be garbage collected at any
34.302 + * time if there is no strong reference to the Logger. In particular,
34.303 + * this means that two back-to-back calls like
34.304 + * {@code getLogger("MyLogger").log(...)} may use different Logger
34.305 + * objects named "MyLogger" if there is no strong reference to the
34.306 + * Logger named "MyLogger" elsewhere in the program.
34.307 + *
34.308 + * @param name A name for the logger. This should
34.309 + * be a dot-separated name and should normally
34.310 + * be based on the package name or class name
34.311 + * of the subsystem, such as java.net
34.312 + * or javax.swing
34.313 + * @return a suitable Logger
34.314 + * @throws NullPointerException if the name is null.
34.315 + */
34.316 +
34.317 + // Synchronization is not required here. All synchronization for
34.318 + // adding a new Logger object is handled by LogManager.addLogger().
34.319 + public static Logger getLogger(String name) {
34.320 + // This method is intentionally not a wrapper around a call
34.321 + // to getLogger(name, resourceBundleName). If it were then
34.322 + // this sequence:
34.323 + //
34.324 + // getLogger("Foo", "resourceBundleForFoo");
34.325 + // getLogger("Foo");
34.326 + //
34.327 + // would throw an IllegalArgumentException in the second call
34.328 + // because the wrapper would result in an attempt to replace
34.329 + // the existing "resourceBundleForFoo" with null.
34.330 + LogManager manager = LogManager.getLogManager();
34.331 + return manager.demandLogger(name);
34.332 + }
34.333 +
34.334 + /**
34.335 + * Find or create a logger for a named subsystem. If a logger has
34.336 + * already been created with the given name it is returned. Otherwise
34.337 + * a new logger is created.
34.338 + * <p>
34.339 + * If a new logger is created its log level will be configured
34.340 + * based on the LogManager and it will configured to also send logging
34.341 + * output to its parent's Handlers. It will be registered in
34.342 + * the LogManager global namespace.
34.343 + * <p>
34.344 + * Note: The LogManager may only retain a weak reference to the newly
34.345 + * created Logger. It is important to understand that a previously
34.346 + * created Logger with the given name may be garbage collected at any
34.347 + * time if there is no strong reference to the Logger. In particular,
34.348 + * this means that two back-to-back calls like
34.349 + * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
34.350 + * objects named "MyLogger" if there is no strong reference to the
34.351 + * Logger named "MyLogger" elsewhere in the program.
34.352 + * <p>
34.353 + * If the named Logger already exists and does not yet have a
34.354 + * localization resource bundle then the given resource bundle
34.355 + * name is used. If the named Logger already exists and has
34.356 + * a different resource bundle name then an IllegalArgumentException
34.357 + * is thrown.
34.358 + * <p>
34.359 + * @param name A name for the logger. This should
34.360 + * be a dot-separated name and should normally
34.361 + * be based on the package name or class name
34.362 + * of the subsystem, such as java.net
34.363 + * or javax.swing
34.364 + * @param resourceBundleName name of ResourceBundle to be used for localizing
34.365 + * messages for this logger. May be <CODE>null</CODE> if none of
34.366 + * the messages require localization.
34.367 + * @return a suitable Logger
34.368 + * @throws MissingResourceException if the resourceBundleName is non-null and
34.369 + * no corresponding resource can be found.
34.370 + * @throws IllegalArgumentException if the Logger already exists and uses
34.371 + * a different resource bundle name.
34.372 + * @throws NullPointerException if the name is null.
34.373 + */
34.374 +
34.375 + // Synchronization is not required here. All synchronization for
34.376 + // adding a new Logger object is handled by LogManager.addLogger().
34.377 + public static Logger getLogger(String name, String resourceBundleName) {
34.378 + LogManager manager = LogManager.getLogManager();
34.379 + Logger result = manager.demandLogger(name);
34.380 + if (result.resourceBundleName == null) {
34.381 + // Note: we may get a MissingResourceException here.
34.382 + result.setupResourceInfo(resourceBundleName);
34.383 + } else if (!result.resourceBundleName.equals(resourceBundleName)) {
34.384 + throw new IllegalArgumentException(result.resourceBundleName +
34.385 + " != " + resourceBundleName);
34.386 + }
34.387 + return result;
34.388 + }
34.389 +
34.390 +
34.391 + /**
34.392 + * Create an anonymous Logger. The newly created Logger is not
34.393 + * registered in the LogManager namespace. There will be no
34.394 + * access checks on updates to the logger.
34.395 + * <p>
34.396 + * This factory method is primarily intended for use from applets.
34.397 + * Because the resulting Logger is anonymous it can be kept private
34.398 + * by the creating class. This removes the need for normal security
34.399 + * checks, which in turn allows untrusted applet code to update
34.400 + * the control state of the Logger. For example an applet can do
34.401 + * a setLevel or an addHandler on an anonymous Logger.
34.402 + * <p>
34.403 + * Even although the new logger is anonymous, it is configured
34.404 + * to have the root logger ("") as its parent. This means that
34.405 + * by default it inherits its effective level and handlers
34.406 + * from the root logger.
34.407 + * <p>
34.408 + *
34.409 + * @return a newly created private Logger
34.410 + */
34.411 + public static Logger getAnonymousLogger() {
34.412 + return getAnonymousLogger(null);
34.413 + }
34.414 +
34.415 + /**
34.416 + * Create an anonymous Logger. The newly created Logger is not
34.417 + * registered in the LogManager namespace. There will be no
34.418 + * access checks on updates to the logger.
34.419 + * <p>
34.420 + * This factory method is primarily intended for use from applets.
34.421 + * Because the resulting Logger is anonymous it can be kept private
34.422 + * by the creating class. This removes the need for normal security
34.423 + * checks, which in turn allows untrusted applet code to update
34.424 + * the control state of the Logger. For example an applet can do
34.425 + * a setLevel or an addHandler on an anonymous Logger.
34.426 + * <p>
34.427 + * Even although the new logger is anonymous, it is configured
34.428 + * to have the root logger ("") as its parent. This means that
34.429 + * by default it inherits its effective level and handlers
34.430 + * from the root logger.
34.431 + * <p>
34.432 + * @param resourceBundleName name of ResourceBundle to be used for localizing
34.433 + * messages for this logger.
34.434 + * May be null if none of the messages require localization.
34.435 + * @return a newly created private Logger
34.436 + * @throws MissingResourceException if the resourceBundleName is non-null and
34.437 + * no corresponding resource can be found.
34.438 + */
34.439 +
34.440 + // Synchronization is not required here. All synchronization for
34.441 + // adding a new anonymous Logger object is handled by doSetParent().
34.442 + public static Logger getAnonymousLogger(String resourceBundleName) {
34.443 + LogManager manager = LogManager.getLogManager();
34.444 + // cleanup some Loggers that have been GC'ed
34.445 + manager.drainLoggerRefQueueBounded();
34.446 + Logger result = new Logger(null, resourceBundleName);
34.447 + result.anonymous = true;
34.448 + Logger root = manager.getLogger("");
34.449 + result.doSetParent(root);
34.450 + return result;
34.451 + }
34.452 +
34.453 + /**
34.454 + * Retrieve the localization resource bundle for this
34.455 + * logger for the current default locale. Note that if
34.456 + * the result is null, then the Logger will use a resource
34.457 + * bundle inherited from its parent.
34.458 + *
34.459 + * @return localization bundle (may be null)
34.460 + */
34.461 + public ResourceBundle getResourceBundle() {
34.462 + return findResourceBundle(getResourceBundleName());
34.463 + }
34.464 +
34.465 + /**
34.466 + * Retrieve the localization resource bundle name for this
34.467 + * logger. Note that if the result is null, then the Logger
34.468 + * will use a resource bundle name inherited from its parent.
34.469 + *
34.470 + * @return localization bundle name (may be null)
34.471 + */
34.472 + public String getResourceBundleName() {
34.473 + return resourceBundleName;
34.474 + }
34.475 +
34.476 + /**
34.477 + * Set a filter to control output on this Logger.
34.478 + * <P>
34.479 + * After passing the initial "level" check, the Logger will
34.480 + * call this Filter to check if a log record should really
34.481 + * be published.
34.482 + *
34.483 + * @param newFilter a filter object (may be null)
34.484 + * @exception SecurityException if a security manager exists and if
34.485 + * the caller does not have LoggingPermission("control").
34.486 + */
34.487 + public void setFilter(Filter newFilter) throws SecurityException {
34.488 + checkAccess();
34.489 + filter = newFilter;
34.490 + }
34.491 +
34.492 + /**
34.493 + * Get the current filter for this Logger.
34.494 + *
34.495 + * @return a filter object (may be null)
34.496 + */
34.497 + public Filter getFilter() {
34.498 + return filter;
34.499 + }
34.500 +
34.501 + /**
34.502 + * Log a LogRecord.
34.503 + * <p>
34.504 + * All the other logging methods in this class call through
34.505 + * this method to actually perform any logging. Subclasses can
34.506 + * override this single method to capture all log activity.
34.507 + *
34.508 + * @param record the LogRecord to be published
34.509 + */
34.510 + public void log(LogRecord record) {
34.511 + if (record.getLevel().intValue() < levelValue || levelValue == offValue) {
34.512 + return;
34.513 + }
34.514 + Filter theFilter = filter;
34.515 + if (theFilter != null && !theFilter.isLoggable(record)) {
34.516 + return;
34.517 + }
34.518 +
34.519 + // Post the LogRecord to all our Handlers, and then to
34.520 + // our parents' handlers, all the way up the tree.
34.521 +
34.522 + Logger logger = this;
34.523 + while (logger != null) {
34.524 + for (Handler handler : logger.getHandlers()) {
34.525 + handler.publish(record);
34.526 + }
34.527 +
34.528 + if (!logger.getUseParentHandlers()) {
34.529 + break;
34.530 + }
34.531 +
34.532 + logger = logger.getParent();
34.533 + }
34.534 + }
34.535 +
34.536 + // private support method for logging.
34.537 + // We fill in the logger name, resource bundle name, and
34.538 + // resource bundle and then call "void log(LogRecord)".
34.539 + private void doLog(LogRecord lr) {
34.540 + lr.setLoggerName(name);
34.541 + String ebname = getEffectiveResourceBundleName();
34.542 + if (ebname != null) {
34.543 + lr.setResourceBundleName(ebname);
34.544 + lr.setResourceBundle(findResourceBundle(ebname));
34.545 + }
34.546 + log(lr);
34.547 + }
34.548 +
34.549 +
34.550 + //================================================================
34.551 + // Start of convenience methods WITHOUT className and methodName
34.552 + //================================================================
34.553 +
34.554 + /**
34.555 + * Log a message, with no arguments.
34.556 + * <p>
34.557 + * If the logger is currently enabled for the given message
34.558 + * level then the given message is forwarded to all the
34.559 + * registered output Handler objects.
34.560 + * <p>
34.561 + * @param level One of the message level identifiers, e.g., SEVERE
34.562 + * @param msg The string message (or a key in the message catalog)
34.563 + */
34.564 + public void log(Level level, String msg) {
34.565 + if (level.intValue() < levelValue || levelValue == offValue) {
34.566 + return;
34.567 + }
34.568 + LogRecord lr = new LogRecord(level, msg);
34.569 + doLog(lr);
34.570 + }
34.571 +
34.572 + /**
34.573 + * Log a message, with one object parameter.
34.574 + * <p>
34.575 + * If the logger is currently enabled for the given message
34.576 + * level then a corresponding LogRecord is created and forwarded
34.577 + * to all the registered output Handler objects.
34.578 + * <p>
34.579 + * @param level One of the message level identifiers, e.g., SEVERE
34.580 + * @param msg The string message (or a key in the message catalog)
34.581 + * @param param1 parameter to the message
34.582 + */
34.583 + public void log(Level level, String msg, Object param1) {
34.584 + if (level.intValue() < levelValue || levelValue == offValue) {
34.585 + return;
34.586 + }
34.587 + LogRecord lr = new LogRecord(level, msg);
34.588 + Object params[] = { param1 };
34.589 + lr.setParameters(params);
34.590 + doLog(lr);
34.591 + }
34.592 +
34.593 + /**
34.594 + * Log a message, with an array of object arguments.
34.595 + * <p>
34.596 + * If the logger is currently enabled for the given message
34.597 + * level then a corresponding LogRecord is created and forwarded
34.598 + * to all the registered output Handler objects.
34.599 + * <p>
34.600 + * @param level One of the message level identifiers, e.g., SEVERE
34.601 + * @param msg The string message (or a key in the message catalog)
34.602 + * @param params array of parameters to the message
34.603 + */
34.604 + public void log(Level level, String msg, Object params[]) {
34.605 + if (level.intValue() < levelValue || levelValue == offValue) {
34.606 + return;
34.607 + }
34.608 + LogRecord lr = new LogRecord(level, msg);
34.609 + lr.setParameters(params);
34.610 + doLog(lr);
34.611 + }
34.612 +
34.613 + /**
34.614 + * Log a message, with associated Throwable information.
34.615 + * <p>
34.616 + * If the logger is currently enabled for the given message
34.617 + * level then the given arguments are stored in a LogRecord
34.618 + * which is forwarded to all registered output handlers.
34.619 + * <p>
34.620 + * Note that the thrown argument is stored in the LogRecord thrown
34.621 + * property, rather than the LogRecord parameters property. Thus is it
34.622 + * processed specially by output Formatters and is not treated
34.623 + * as a formatting parameter to the LogRecord message property.
34.624 + * <p>
34.625 + * @param level One of the message level identifiers, e.g., SEVERE
34.626 + * @param msg The string message (or a key in the message catalog)
34.627 + * @param thrown Throwable associated with log message.
34.628 + */
34.629 + public void log(Level level, String msg, Throwable thrown) {
34.630 + if (level.intValue() < levelValue || levelValue == offValue) {
34.631 + return;
34.632 + }
34.633 + LogRecord lr = new LogRecord(level, msg);
34.634 + lr.setThrown(thrown);
34.635 + doLog(lr);
34.636 + }
34.637 +
34.638 + //================================================================
34.639 + // Start of convenience methods WITH className and methodName
34.640 + //================================================================
34.641 +
34.642 + /**
34.643 + * Log a message, specifying source class and method,
34.644 + * with no arguments.
34.645 + * <p>
34.646 + * If the logger is currently enabled for the given message
34.647 + * level then the given message is forwarded to all the
34.648 + * registered output Handler objects.
34.649 + * <p>
34.650 + * @param level One of the message level identifiers, e.g., SEVERE
34.651 + * @param sourceClass name of class that issued the logging request
34.652 + * @param sourceMethod name of method that issued the logging request
34.653 + * @param msg The string message (or a key in the message catalog)
34.654 + */
34.655 + public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
34.656 + if (level.intValue() < levelValue || levelValue == offValue) {
34.657 + return;
34.658 + }
34.659 + LogRecord lr = new LogRecord(level, msg);
34.660 + lr.setSourceClassName(sourceClass);
34.661 + lr.setSourceMethodName(sourceMethod);
34.662 + doLog(lr);
34.663 + }
34.664 +
34.665 + /**
34.666 + * Log a message, specifying source class and method,
34.667 + * with a single object parameter to the log message.
34.668 + * <p>
34.669 + * If the logger is currently enabled for the given message
34.670 + * level then a corresponding LogRecord is created and forwarded
34.671 + * to all the registered output Handler objects.
34.672 + * <p>
34.673 + * @param level One of the message level identifiers, e.g., SEVERE
34.674 + * @param sourceClass name of class that issued the logging request
34.675 + * @param sourceMethod name of method that issued the logging request
34.676 + * @param msg The string message (or a key in the message catalog)
34.677 + * @param param1 Parameter to the log message.
34.678 + */
34.679 + public void logp(Level level, String sourceClass, String sourceMethod,
34.680 + String msg, Object param1) {
34.681 + if (level.intValue() < levelValue || levelValue == offValue) {
34.682 + return;
34.683 + }
34.684 + LogRecord lr = new LogRecord(level, msg);
34.685 + lr.setSourceClassName(sourceClass);
34.686 + lr.setSourceMethodName(sourceMethod);
34.687 + Object params[] = { param1 };
34.688 + lr.setParameters(params);
34.689 + doLog(lr);
34.690 + }
34.691 +
34.692 + /**
34.693 + * Log a message, specifying source class and method,
34.694 + * with an array of object arguments.
34.695 + * <p>
34.696 + * If the logger is currently enabled for the given message
34.697 + * level then a corresponding LogRecord is created and forwarded
34.698 + * to all the registered output Handler objects.
34.699 + * <p>
34.700 + * @param level One of the message level identifiers, e.g., SEVERE
34.701 + * @param sourceClass name of class that issued the logging request
34.702 + * @param sourceMethod name of method that issued the logging request
34.703 + * @param msg The string message (or a key in the message catalog)
34.704 + * @param params Array of parameters to the message
34.705 + */
34.706 + public void logp(Level level, String sourceClass, String sourceMethod,
34.707 + String msg, Object params[]) {
34.708 + if (level.intValue() < levelValue || levelValue == offValue) {
34.709 + return;
34.710 + }
34.711 + LogRecord lr = new LogRecord(level, msg);
34.712 + lr.setSourceClassName(sourceClass);
34.713 + lr.setSourceMethodName(sourceMethod);
34.714 + lr.setParameters(params);
34.715 + doLog(lr);
34.716 + }
34.717 +
34.718 + /**
34.719 + * Log a message, specifying source class and method,
34.720 + * with associated Throwable information.
34.721 + * <p>
34.722 + * If the logger is currently enabled for the given message
34.723 + * level then the given arguments are stored in a LogRecord
34.724 + * which is forwarded to all registered output handlers.
34.725 + * <p>
34.726 + * Note that the thrown argument is stored in the LogRecord thrown
34.727 + * property, rather than the LogRecord parameters property. Thus is it
34.728 + * processed specially by output Formatters and is not treated
34.729 + * as a formatting parameter to the LogRecord message property.
34.730 + * <p>
34.731 + * @param level One of the message level identifiers, e.g., SEVERE
34.732 + * @param sourceClass name of class that issued the logging request
34.733 + * @param sourceMethod name of method that issued the logging request
34.734 + * @param msg The string message (or a key in the message catalog)
34.735 + * @param thrown Throwable associated with log message.
34.736 + */
34.737 + public void logp(Level level, String sourceClass, String sourceMethod,
34.738 + String msg, Throwable thrown) {
34.739 + if (level.intValue() < levelValue || levelValue == offValue) {
34.740 + return;
34.741 + }
34.742 + LogRecord lr = new LogRecord(level, msg);
34.743 + lr.setSourceClassName(sourceClass);
34.744 + lr.setSourceMethodName(sourceMethod);
34.745 + lr.setThrown(thrown);
34.746 + doLog(lr);
34.747 + }
34.748 +
34.749 +
34.750 + //=========================================================================
34.751 + // Start of convenience methods WITH className, methodName and bundle name.
34.752 + //=========================================================================
34.753 +
34.754 + // Private support method for logging for "logrb" methods.
34.755 + // We fill in the logger name, resource bundle name, and
34.756 + // resource bundle and then call "void log(LogRecord)".
34.757 + private void doLog(LogRecord lr, String rbname) {
34.758 + lr.setLoggerName(name);
34.759 + if (rbname != null) {
34.760 + lr.setResourceBundleName(rbname);
34.761 + lr.setResourceBundle(findResourceBundle(rbname));
34.762 + }
34.763 + log(lr);
34.764 + }
34.765 +
34.766 + /**
34.767 + * Log a message, specifying source class, method, and resource bundle name
34.768 + * with no arguments.
34.769 + * <p>
34.770 + * If the logger is currently enabled for the given message
34.771 + * level then the given message is forwarded to all the
34.772 + * registered output Handler objects.
34.773 + * <p>
34.774 + * The msg string is localized using the named resource bundle. If the
34.775 + * resource bundle name is null, or an empty String or invalid
34.776 + * then the msg string is not localized.
34.777 + * <p>
34.778 + * @param level One of the message level identifiers, e.g., SEVERE
34.779 + * @param sourceClass name of class that issued the logging request
34.780 + * @param sourceMethod name of method that issued the logging request
34.781 + * @param bundleName name of resource bundle to localize msg,
34.782 + * can be null
34.783 + * @param msg The string message (or a key in the message catalog)
34.784 + */
34.785 +
34.786 + public void logrb(Level level, String sourceClass, String sourceMethod,
34.787 + String bundleName, String msg) {
34.788 + if (level.intValue() < levelValue || levelValue == offValue) {
34.789 + return;
34.790 + }
34.791 + LogRecord lr = new LogRecord(level, msg);
34.792 + lr.setSourceClassName(sourceClass);
34.793 + lr.setSourceMethodName(sourceMethod);
34.794 + doLog(lr, bundleName);
34.795 + }
34.796 +
34.797 + /**
34.798 + * Log a message, specifying source class, method, and resource bundle name,
34.799 + * with a single object parameter to the log message.
34.800 + * <p>
34.801 + * If the logger is currently enabled for the given message
34.802 + * level then a corresponding LogRecord is created and forwarded
34.803 + * to all the registered output Handler objects.
34.804 + * <p>
34.805 + * The msg string is localized using the named resource bundle. If the
34.806 + * resource bundle name is null, or an empty String or invalid
34.807 + * then the msg string is not localized.
34.808 + * <p>
34.809 + * @param level One of the message level identifiers, e.g., SEVERE
34.810 + * @param sourceClass name of class that issued the logging request
34.811 + * @param sourceMethod name of method that issued the logging request
34.812 + * @param bundleName name of resource bundle to localize msg,
34.813 + * can be null
34.814 + * @param msg The string message (or a key in the message catalog)
34.815 + * @param param1 Parameter to the log message.
34.816 + */
34.817 + public void logrb(Level level, String sourceClass, String sourceMethod,
34.818 + String bundleName, String msg, Object param1) {
34.819 + if (level.intValue() < levelValue || levelValue == offValue) {
34.820 + return;
34.821 + }
34.822 + LogRecord lr = new LogRecord(level, msg);
34.823 + lr.setSourceClassName(sourceClass);
34.824 + lr.setSourceMethodName(sourceMethod);
34.825 + Object params[] = { param1 };
34.826 + lr.setParameters(params);
34.827 + doLog(lr, bundleName);
34.828 + }
34.829 +
34.830 + /**
34.831 + * Log a message, specifying source class, method, and resource bundle name,
34.832 + * with an array of object arguments.
34.833 + * <p>
34.834 + * If the logger is currently enabled for the given message
34.835 + * level then a corresponding LogRecord is created and forwarded
34.836 + * to all the registered output Handler objects.
34.837 + * <p>
34.838 + * The msg string is localized using the named resource bundle. If the
34.839 + * resource bundle name is null, or an empty String or invalid
34.840 + * then the msg string is not localized.
34.841 + * <p>
34.842 + * @param level One of the message level identifiers, e.g., SEVERE
34.843 + * @param sourceClass name of class that issued the logging request
34.844 + * @param sourceMethod name of method that issued the logging request
34.845 + * @param bundleName name of resource bundle to localize msg,
34.846 + * can be null.
34.847 + * @param msg The string message (or a key in the message catalog)
34.848 + * @param params Array of parameters to the message
34.849 + */
34.850 + public void logrb(Level level, String sourceClass, String sourceMethod,
34.851 + String bundleName, String msg, Object params[]) {
34.852 + if (level.intValue() < levelValue || levelValue == offValue) {
34.853 + return;
34.854 + }
34.855 + LogRecord lr = new LogRecord(level, msg);
34.856 + lr.setSourceClassName(sourceClass);
34.857 + lr.setSourceMethodName(sourceMethod);
34.858 + lr.setParameters(params);
34.859 + doLog(lr, bundleName);
34.860 + }
34.861 +
34.862 + /**
34.863 + * Log a message, specifying source class, method, and resource bundle name,
34.864 + * with associated Throwable information.
34.865 + * <p>
34.866 + * If the logger is currently enabled for the given message
34.867 + * level then the given arguments are stored in a LogRecord
34.868 + * which is forwarded to all registered output handlers.
34.869 + * <p>
34.870 + * The msg string is localized using the named resource bundle. If the
34.871 + * resource bundle name is null, or an empty String or invalid
34.872 + * then the msg string is not localized.
34.873 + * <p>
34.874 + * Note that the thrown argument is stored in the LogRecord thrown
34.875 + * property, rather than the LogRecord parameters property. Thus is it
34.876 + * processed specially by output Formatters and is not treated
34.877 + * as a formatting parameter to the LogRecord message property.
34.878 + * <p>
34.879 + * @param level One of the message level identifiers, e.g., SEVERE
34.880 + * @param sourceClass name of class that issued the logging request
34.881 + * @param sourceMethod name of method that issued the logging request
34.882 + * @param bundleName name of resource bundle to localize msg,
34.883 + * can be null
34.884 + * @param msg The string message (or a key in the message catalog)
34.885 + * @param thrown Throwable associated with log message.
34.886 + */
34.887 + public void logrb(Level level, String sourceClass, String sourceMethod,
34.888 + String bundleName, String msg, Throwable thrown) {
34.889 + if (level.intValue() < levelValue || levelValue == offValue) {
34.890 + return;
34.891 + }
34.892 + LogRecord lr = new LogRecord(level, msg);
34.893 + lr.setSourceClassName(sourceClass);
34.894 + lr.setSourceMethodName(sourceMethod);
34.895 + lr.setThrown(thrown);
34.896 + doLog(lr, bundleName);
34.897 + }
34.898 +
34.899 +
34.900 + //======================================================================
34.901 + // Start of convenience methods for logging method entries and returns.
34.902 + //======================================================================
34.903 +
34.904 + /**
34.905 + * Log a method entry.
34.906 + * <p>
34.907 + * This is a convenience method that can be used to log entry
34.908 + * to a method. A LogRecord with message "ENTRY", log level
34.909 + * FINER, and the given sourceMethod and sourceClass is logged.
34.910 + * <p>
34.911 + * @param sourceClass name of class that issued the logging request
34.912 + * @param sourceMethod name of method that is being entered
34.913 + */
34.914 + public void entering(String sourceClass, String sourceMethod) {
34.915 + if (Level.FINER.intValue() < levelValue) {
34.916 + return;
34.917 + }
34.918 + logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
34.919 + }
34.920 +
34.921 + /**
34.922 + * Log a method entry, with one parameter.
34.923 + * <p>
34.924 + * This is a convenience method that can be used to log entry
34.925 + * to a method. A LogRecord with message "ENTRY {0}", log level
34.926 + * FINER, and the given sourceMethod, sourceClass, and parameter
34.927 + * is logged.
34.928 + * <p>
34.929 + * @param sourceClass name of class that issued the logging request
34.930 + * @param sourceMethod name of method that is being entered
34.931 + * @param param1 parameter to the method being entered
34.932 + */
34.933 + public void entering(String sourceClass, String sourceMethod, Object param1) {
34.934 + if (Level.FINER.intValue() < levelValue) {
34.935 + return;
34.936 + }
34.937 + Object params[] = { param1 };
34.938 + logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", params);
34.939 + }
34.940 +
34.941 + /**
34.942 + * Log a method entry, with an array of parameters.
34.943 + * <p>
34.944 + * This is a convenience method that can be used to log entry
34.945 + * to a method. A LogRecord with message "ENTRY" (followed by a
34.946 + * format {N} indicator for each entry in the parameter array),
34.947 + * log level FINER, and the given sourceMethod, sourceClass, and
34.948 + * parameters is logged.
34.949 + * <p>
34.950 + * @param sourceClass name of class that issued the logging request
34.951 + * @param sourceMethod name of method that is being entered
34.952 + * @param params array of parameters to the method being entered
34.953 + */
34.954 + public void entering(String sourceClass, String sourceMethod, Object params[]) {
34.955 + if (Level.FINER.intValue() < levelValue) {
34.956 + return;
34.957 + }
34.958 + String msg = "ENTRY";
34.959 + if (params == null ) {
34.960 + logp(Level.FINER, sourceClass, sourceMethod, msg);
34.961 + return;
34.962 + }
34.963 + for (int i = 0; i < params.length; i++) {
34.964 + msg = msg + " {" + i + "}";
34.965 + }
34.966 + logp(Level.FINER, sourceClass, sourceMethod, msg, params);
34.967 + }
34.968 +
34.969 + /**
34.970 + * Log a method return.
34.971 + * <p>
34.972 + * This is a convenience method that can be used to log returning
34.973 + * from a method. A LogRecord with message "RETURN", log level
34.974 + * FINER, and the given sourceMethod and sourceClass is logged.
34.975 + * <p>
34.976 + * @param sourceClass name of class that issued the logging request
34.977 + * @param sourceMethod name of the method
34.978 + */
34.979 + public void exiting(String sourceClass, String sourceMethod) {
34.980 + if (Level.FINER.intValue() < levelValue) {
34.981 + return;
34.982 + }
34.983 + logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
34.984 + }
34.985 +
34.986 +
34.987 + /**
34.988 + * Log a method return, with result object.
34.989 + * <p>
34.990 + * This is a convenience method that can be used to log returning
34.991 + * from a method. A LogRecord with message "RETURN {0}", log level
34.992 + * FINER, and the gives sourceMethod, sourceClass, and result
34.993 + * object is logged.
34.994 + * <p>
34.995 + * @param sourceClass name of class that issued the logging request
34.996 + * @param sourceMethod name of the method
34.997 + * @param result Object that is being returned
34.998 + */
34.999 + public void exiting(String sourceClass, String sourceMethod, Object result) {
34.1000 + if (Level.FINER.intValue() < levelValue) {
34.1001 + return;
34.1002 + }
34.1003 + Object params[] = { result };
34.1004 + logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
34.1005 + }
34.1006 +
34.1007 + /**
34.1008 + * Log throwing an exception.
34.1009 + * <p>
34.1010 + * This is a convenience method to log that a method is
34.1011 + * terminating by throwing an exception. The logging is done
34.1012 + * using the FINER level.
34.1013 + * <p>
34.1014 + * If the logger is currently enabled for the given message
34.1015 + * level then the given arguments are stored in a LogRecord
34.1016 + * which is forwarded to all registered output handlers. The
34.1017 + * LogRecord's message is set to "THROW".
34.1018 + * <p>
34.1019 + * Note that the thrown argument is stored in the LogRecord thrown
34.1020 + * property, rather than the LogRecord parameters property. Thus is it
34.1021 + * processed specially by output Formatters and is not treated
34.1022 + * as a formatting parameter to the LogRecord message property.
34.1023 + * <p>
34.1024 + * @param sourceClass name of class that issued the logging request
34.1025 + * @param sourceMethod name of the method.
34.1026 + * @param thrown The Throwable that is being thrown.
34.1027 + */
34.1028 + public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
34.1029 + if (Level.FINER.intValue() < levelValue || levelValue == offValue ) {
34.1030 + return;
34.1031 + }
34.1032 + LogRecord lr = new LogRecord(Level.FINER, "THROW");
34.1033 + lr.setSourceClassName(sourceClass);
34.1034 + lr.setSourceMethodName(sourceMethod);
34.1035 + lr.setThrown(thrown);
34.1036 + doLog(lr);
34.1037 + }
34.1038 +
34.1039 + //=======================================================================
34.1040 + // Start of simple convenience methods using level names as method names
34.1041 + //=======================================================================
34.1042 +
34.1043 + /**
34.1044 + * Log a SEVERE message.
34.1045 + * <p>
34.1046 + * If the logger is currently enabled for the SEVERE message
34.1047 + * level then the given message is forwarded to all the
34.1048 + * registered output Handler objects.
34.1049 + * <p>
34.1050 + * @param msg The string message (or a key in the message catalog)
34.1051 + */
34.1052 + public void severe(String msg) {
34.1053 + if (Level.SEVERE.intValue() < levelValue) {
34.1054 + return;
34.1055 + }
34.1056 + log(Level.SEVERE, msg);
34.1057 + }
34.1058 +
34.1059 + /**
34.1060 + * Log a WARNING message.
34.1061 + * <p>
34.1062 + * If the logger is currently enabled for the WARNING message
34.1063 + * level then the given message is forwarded to all the
34.1064 + * registered output Handler objects.
34.1065 + * <p>
34.1066 + * @param msg The string message (or a key in the message catalog)
34.1067 + */
34.1068 + public void warning(String msg) {
34.1069 + if (Level.WARNING.intValue() < levelValue) {
34.1070 + return;
34.1071 + }
34.1072 + log(Level.WARNING, msg);
34.1073 + }
34.1074 +
34.1075 + /**
34.1076 + * Log an INFO message.
34.1077 + * <p>
34.1078 + * If the logger is currently enabled for the INFO message
34.1079 + * level then the given message is forwarded to all the
34.1080 + * registered output Handler objects.
34.1081 + * <p>
34.1082 + * @param msg The string message (or a key in the message catalog)
34.1083 + */
34.1084 + public void info(String msg) {
34.1085 + if (Level.INFO.intValue() < levelValue) {
34.1086 + return;
34.1087 + }
34.1088 + log(Level.INFO, msg);
34.1089 + }
34.1090 +
34.1091 + /**
34.1092 + * Log a CONFIG message.
34.1093 + * <p>
34.1094 + * If the logger is currently enabled for the CONFIG message
34.1095 + * level then the given message is forwarded to all the
34.1096 + * registered output Handler objects.
34.1097 + * <p>
34.1098 + * @param msg The string message (or a key in the message catalog)
34.1099 + */
34.1100 + public void config(String msg) {
34.1101 + if (Level.CONFIG.intValue() < levelValue) {
34.1102 + return;
34.1103 + }
34.1104 + log(Level.CONFIG, msg);
34.1105 + }
34.1106 +
34.1107 + /**
34.1108 + * Log a FINE message.
34.1109 + * <p>
34.1110 + * If the logger is currently enabled for the FINE message
34.1111 + * level then the given message is forwarded to all the
34.1112 + * registered output Handler objects.
34.1113 + * <p>
34.1114 + * @param msg The string message (or a key in the message catalog)
34.1115 + */
34.1116 + public void fine(String msg) {
34.1117 + if (Level.FINE.intValue() < levelValue) {
34.1118 + return;
34.1119 + }
34.1120 + log(Level.FINE, msg);
34.1121 + }
34.1122 +
34.1123 + /**
34.1124 + * Log a FINER message.
34.1125 + * <p>
34.1126 + * If the logger is currently enabled for the FINER message
34.1127 + * level then the given message is forwarded to all the
34.1128 + * registered output Handler objects.
34.1129 + * <p>
34.1130 + * @param msg The string message (or a key in the message catalog)
34.1131 + */
34.1132 + public void finer(String msg) {
34.1133 + if (Level.FINER.intValue() < levelValue) {
34.1134 + return;
34.1135 + }
34.1136 + log(Level.FINER, msg);
34.1137 + }
34.1138 +
34.1139 + /**
34.1140 + * Log a FINEST message.
34.1141 + * <p>
34.1142 + * If the logger is currently enabled for the FINEST message
34.1143 + * level then the given message is forwarded to all the
34.1144 + * registered output Handler objects.
34.1145 + * <p>
34.1146 + * @param msg The string message (or a key in the message catalog)
34.1147 + */
34.1148 + public void finest(String msg) {
34.1149 + if (Level.FINEST.intValue() < levelValue) {
34.1150 + return;
34.1151 + }
34.1152 + log(Level.FINEST, msg);
34.1153 + }
34.1154 +
34.1155 + //================================================================
34.1156 + // End of convenience methods
34.1157 + //================================================================
34.1158 +
34.1159 + /**
34.1160 + * Set the log level specifying which message levels will be
34.1161 + * logged by this logger. Message levels lower than this
34.1162 + * value will be discarded. The level value Level.OFF
34.1163 + * can be used to turn off logging.
34.1164 + * <p>
34.1165 + * If the new level is null, it means that this node should
34.1166 + * inherit its level from its nearest ancestor with a specific
34.1167 + * (non-null) level value.
34.1168 + *
34.1169 + * @param newLevel the new value for the log level (may be null)
34.1170 + * @exception SecurityException if a security manager exists and if
34.1171 + * the caller does not have LoggingPermission("control").
34.1172 + */
34.1173 + public void setLevel(Level newLevel) throws SecurityException {
34.1174 + checkAccess();
34.1175 + synchronized (treeLock) {
34.1176 + levelObject = newLevel;
34.1177 + updateEffectiveLevel();
34.1178 + }
34.1179 + }
34.1180 +
34.1181 + /**
34.1182 + * Get the log Level that has been specified for this Logger.
34.1183 + * The result may be null, which means that this logger's
34.1184 + * effective level will be inherited from its parent.
34.1185 + *
34.1186 + * @return this Logger's level
34.1187 + */
34.1188 + public Level getLevel() {
34.1189 + return levelObject;
34.1190 + }
34.1191 +
34.1192 + /**
34.1193 + * Check if a message of the given level would actually be logged
34.1194 + * by this logger. This check is based on the Loggers effective level,
34.1195 + * which may be inherited from its parent.
34.1196 + *
34.1197 + * @param level a message logging level
34.1198 + * @return true if the given message level is currently being logged.
34.1199 + */
34.1200 + public boolean isLoggable(Level level) {
34.1201 + if (level.intValue() < levelValue || levelValue == offValue) {
34.1202 + return false;
34.1203 + }
34.1204 + return true;
34.1205 + }
34.1206 +
34.1207 + /**
34.1208 + * Get the name for this logger.
34.1209 + * @return logger name. Will be null for anonymous Loggers.
34.1210 + */
34.1211 + public String getName() {
34.1212 + return name;
34.1213 + }
34.1214 +
34.1215 + /**
34.1216 + * Add a log Handler to receive logging messages.
34.1217 + * <p>
34.1218 + * By default, Loggers also send their output to their parent logger.
34.1219 + * Typically the root Logger is configured with a set of Handlers
34.1220 + * that essentially act as default handlers for all loggers.
34.1221 + *
34.1222 + * @param handler a logging Handler
34.1223 + * @exception SecurityException if a security manager exists and if
34.1224 + * the caller does not have LoggingPermission("control").
34.1225 + */
34.1226 + public void addHandler(Handler handler) throws SecurityException {
34.1227 + // Check for null handler
34.1228 + handler.getClass();
34.1229 + checkAccess();
34.1230 + handlers.add(handler);
34.1231 + }
34.1232 +
34.1233 + /**
34.1234 + * Remove a log Handler.
34.1235 + * <P>
34.1236 + * Returns silently if the given Handler is not found or is null
34.1237 + *
34.1238 + * @param handler a logging Handler
34.1239 + * @exception SecurityException if a security manager exists and if
34.1240 + * the caller does not have LoggingPermission("control").
34.1241 + */
34.1242 + public void removeHandler(Handler handler) throws SecurityException {
34.1243 + checkAccess();
34.1244 + if (handler == null) {
34.1245 + return;
34.1246 + }
34.1247 + handlers.remove(handler);
34.1248 + }
34.1249 +
34.1250 + /**
34.1251 + * Get the Handlers associated with this logger.
34.1252 + * <p>
34.1253 + * @return an array of all registered Handlers
34.1254 + */
34.1255 + public Handler[] getHandlers() {
34.1256 + return handlers.toArray(emptyHandlers);
34.1257 + }
34.1258 +
34.1259 + /**
34.1260 + * Specify whether or not this logger should send its output
34.1261 + * to its parent Logger. This means that any LogRecords will
34.1262 + * also be written to the parent's Handlers, and potentially
34.1263 + * to its parent, recursively up the namespace.
34.1264 + *
34.1265 + * @param useParentHandlers true if output is to be sent to the
34.1266 + * logger's parent.
34.1267 + * @exception SecurityException if a security manager exists and if
34.1268 + * the caller does not have LoggingPermission("control").
34.1269 + */
34.1270 + public void setUseParentHandlers(boolean useParentHandlers) {
34.1271 + checkAccess();
34.1272 + this.useParentHandlers = useParentHandlers;
34.1273 + }
34.1274 +
34.1275 + /**
34.1276 + * Discover whether or not this logger is sending its output
34.1277 + * to its parent logger.
34.1278 + *
34.1279 + * @return true if output is to be sent to the logger's parent
34.1280 + */
34.1281 + public boolean getUseParentHandlers() {
34.1282 + return useParentHandlers;
34.1283 + }
34.1284 +
34.1285 + // Private utility method to map a resource bundle name to an
34.1286 + // actual resource bundle, using a simple one-entry cache.
34.1287 + // Returns null for a null name.
34.1288 + // May also return null if we can't find the resource bundle and
34.1289 + // there is no suitable previous cached value.
34.1290 +
34.1291 + private synchronized ResourceBundle findResourceBundle(String name) {
34.1292 + // Return a null bundle for a null name.
34.1293 + if (name == null) {
34.1294 + return null;
34.1295 + }
34.1296 +
34.1297 + Locale currentLocale = Locale.getDefault();
34.1298 +
34.1299 + // Normally we should hit on our simple one entry cache.
34.1300 + if (catalog != null && currentLocale == catalogLocale
34.1301 + && name == catalogName) {
34.1302 + return catalog;
34.1303 + }
34.1304 +
34.1305 + // Use the thread's context ClassLoader. If there isn't one,
34.1306 + // use the SystemClassloader.
34.1307 + ClassLoader cl = Thread.currentThread().getContextClassLoader();
34.1308 + if (cl == null) {
34.1309 + cl = ClassLoader.getSystemClassLoader();
34.1310 + }
34.1311 + try {
34.1312 + catalog = ResourceBundle.getBundle(name, currentLocale, cl);
34.1313 + catalogName = name;
34.1314 + catalogLocale = currentLocale;
34.1315 + return catalog;
34.1316 + } catch (MissingResourceException ex) {
34.1317 + // Woops. We can't find the ResourceBundle in the default
34.1318 + // ClassLoader. Drop through.
34.1319 + }
34.1320 +
34.1321 +
34.1322 + // Fall back to searching up the call stack and trying each
34.1323 + // calling ClassLoader.
34.1324 + for (int ix = 0; ; ix++) {
34.1325 + Class clz = sun.reflect.Reflection.getCallerClass(ix);
34.1326 + if (clz == null) {
34.1327 + break;
34.1328 + }
34.1329 + ClassLoader cl2 = clz.getClassLoader();
34.1330 + if (cl2 == null) {
34.1331 + cl2 = ClassLoader.getSystemClassLoader();
34.1332 + }
34.1333 + if (cl == cl2) {
34.1334 + // We've already checked this classloader.
34.1335 + continue;
34.1336 + }
34.1337 + cl = cl2;
34.1338 + try {
34.1339 + catalog = ResourceBundle.getBundle(name, currentLocale, cl);
34.1340 + catalogName = name;
34.1341 + catalogLocale = currentLocale;
34.1342 + return catalog;
34.1343 + } catch (MissingResourceException ex) {
34.1344 + // Ok, this one didn't work either.
34.1345 + // Drop through, and try the next one.
34.1346 + }
34.1347 + }
34.1348 +
34.1349 + if (name.equals(catalogName)) {
34.1350 + // Return the previous cached value for that name.
34.1351 + // This may be null.
34.1352 + return catalog;
34.1353 + }
34.1354 + // Sorry, we're out of luck.
34.1355 + return null;
34.1356 + }
34.1357 +
34.1358 + // Private utility method to initialize our one entry
34.1359 + // resource bundle cache.
34.1360 + // Note: for consistency reasons, we are careful to check
34.1361 + // that a suitable ResourceBundle exists before setting the
34.1362 + // ResourceBundleName.
34.1363 + private synchronized void setupResourceInfo(String name) {
34.1364 + if (name == null) {
34.1365 + return;
34.1366 + }
34.1367 + ResourceBundle rb = findResourceBundle(name);
34.1368 + if (rb == null) {
34.1369 + // We've failed to find an expected ResourceBundle.
34.1370 + throw new MissingResourceException("Can't find " + name + " bundle", name, "");
34.1371 + }
34.1372 + resourceBundleName = name;
34.1373 + }
34.1374 +
34.1375 + /**
34.1376 + * Return the parent for this Logger.
34.1377 + * <p>
34.1378 + * This method returns the nearest extant parent in the namespace.
34.1379 + * Thus if a Logger is called "a.b.c.d", and a Logger called "a.b"
34.1380 + * has been created but no logger "a.b.c" exists, then a call of
34.1381 + * getParent on the Logger "a.b.c.d" will return the Logger "a.b".
34.1382 + * <p>
34.1383 + * The result will be null if it is called on the root Logger
34.1384 + * in the namespace.
34.1385 + *
34.1386 + * @return nearest existing parent Logger
34.1387 + */
34.1388 + public Logger getParent() {
34.1389 + // Note: this used to be synchronized on treeLock. However, this only
34.1390 + // provided memory semantics, as there was no guarantee that the caller
34.1391 + // would synchronize on treeLock (in fact, there is no way for external
34.1392 + // callers to so synchronize). Therefore, we have made parent volatile
34.1393 + // instead.
34.1394 + return parent;
34.1395 + }
34.1396 +
34.1397 + /**
34.1398 + * Set the parent for this Logger. This method is used by
34.1399 + * the LogManager to update a Logger when the namespace changes.
34.1400 + * <p>
34.1401 + * It should not be called from application code.
34.1402 + * <p>
34.1403 + * @param parent the new parent logger
34.1404 + * @exception SecurityException if a security manager exists and if
34.1405 + * the caller does not have LoggingPermission("control").
34.1406 + */
34.1407 + public void setParent(Logger parent) {
34.1408 + if (parent == null) {
34.1409 + throw new NullPointerException();
34.1410 + }
34.1411 + manager.checkAccess();
34.1412 + doSetParent(parent);
34.1413 + }
34.1414 +
34.1415 + // Private method to do the work for parenting a child
34.1416 + // Logger onto a parent logger.
34.1417 + private void doSetParent(Logger newParent) {
34.1418 +
34.1419 + // System.err.println("doSetParent \"" + getName() + "\" \""
34.1420 + // + newParent.getName() + "\"");
34.1421 +
34.1422 + synchronized (treeLock) {
34.1423 +
34.1424 + // Remove ourself from any previous parent.
34.1425 + LogManager.LoggerWeakRef ref = null;
34.1426 + if (parent != null) {
34.1427 + // assert parent.kids != null;
34.1428 + for (Iterator<LogManager.LoggerWeakRef> iter = parent.kids.iterator(); iter.hasNext(); ) {
34.1429 + ref = iter.next();
34.1430 + Logger kid = ref.get();
34.1431 + if (kid == this) {
34.1432 + // ref is used down below to complete the reparenting
34.1433 + iter.remove();
34.1434 + break;
34.1435 + } else {
34.1436 + ref = null;
34.1437 + }
34.1438 + }
34.1439 + // We have now removed ourself from our parents' kids.
34.1440 + }
34.1441 +
34.1442 + // Set our new parent.
34.1443 + parent = newParent;
34.1444 + if (parent.kids == null) {
34.1445 + parent.kids = new ArrayList<>(2);
34.1446 + }
34.1447 + if (ref == null) {
34.1448 + // we didn't have a previous parent
34.1449 + ref = manager.new LoggerWeakRef(this);
34.1450 + }
34.1451 + ref.setParentRef(new WeakReference<Logger>(parent));
34.1452 + parent.kids.add(ref);
34.1453 +
34.1454 + // As a result of the reparenting, the effective level
34.1455 + // may have changed for us and our children.
34.1456 + updateEffectiveLevel();
34.1457 +
34.1458 + }
34.1459 + }
34.1460 +
34.1461 + // Package-level method.
34.1462 + // Remove the weak reference for the specified child Logger from the
34.1463 + // kid list. We should only be called from LoggerWeakRef.dispose().
34.1464 + final void removeChildLogger(LogManager.LoggerWeakRef child) {
34.1465 + synchronized (treeLock) {
34.1466 + for (Iterator<LogManager.LoggerWeakRef> iter = kids.iterator(); iter.hasNext(); ) {
34.1467 + LogManager.LoggerWeakRef ref = iter.next();
34.1468 + if (ref == child) {
34.1469 + iter.remove();
34.1470 + return;
34.1471 + }
34.1472 + }
34.1473 + }
34.1474 + }
34.1475 +
34.1476 + // Recalculate the effective level for this node and
34.1477 + // recursively for our children.
34.1478 +
34.1479 + private void updateEffectiveLevel() {
34.1480 + // assert Thread.holdsLock(treeLock);
34.1481 +
34.1482 + // Figure out our current effective level.
34.1483 + int newLevelValue;
34.1484 + if (levelObject != null) {
34.1485 + newLevelValue = levelObject.intValue();
34.1486 + } else {
34.1487 + if (parent != null) {
34.1488 + newLevelValue = parent.levelValue;
34.1489 + } else {
34.1490 + // This may happen during initialization.
34.1491 + newLevelValue = Level.INFO.intValue();
34.1492 + }
34.1493 + }
34.1494 +
34.1495 + // If our effective value hasn't changed, we're done.
34.1496 + if (levelValue == newLevelValue) {
34.1497 + return;
34.1498 + }
34.1499 +
34.1500 + levelValue = newLevelValue;
34.1501 +
34.1502 + // System.err.println("effective level: \"" + getName() + "\" := " + level);
34.1503 +
34.1504 + // Recursively update the level on each of our kids.
34.1505 + if (kids != null) {
34.1506 + for (int i = 0; i < kids.size(); i++) {
34.1507 + LogManager.LoggerWeakRef ref = kids.get(i);
34.1508 + Logger kid = ref.get();
34.1509 + if (kid != null) {
34.1510 + kid.updateEffectiveLevel();
34.1511 + }
34.1512 + }
34.1513 + }
34.1514 + }
34.1515 +
34.1516 +
34.1517 + // Private method to get the potentially inherited
34.1518 + // resource bundle name for this Logger.
34.1519 + // May return null
34.1520 + private String getEffectiveResourceBundleName() {
34.1521 + Logger target = this;
34.1522 + while (target != null) {
34.1523 + String rbn = target.getResourceBundleName();
34.1524 + if (rbn != null) {
34.1525 + return rbn;
34.1526 + }
34.1527 + target = target.getParent();
34.1528 + }
34.1529 + return null;
34.1530 + }
34.1531 +
34.1532 +
34.1533 +}