Integrate luni module (but not tests) to Harmony r772995.
Notable changes
- Stripped "@since Android 1.0" from many files. Most files
are now 100% the same in Dalvik and Harmony.
- AbstractStringBuilder.reverse() supports surrogates
- AbstractStringBuilder shares less to waste less memory
- Bitset optimized
- BufferedInputStream changed to support unsynchronized close()
- BufferedOutputStream does flushInternal
- BufferedReader supports EBCDIC NEL
- Collections.synchronizedList().indexOf() does a copy for more concurrency
- Classes in nio module changed: DatagramChannelImpl, SocketChannelImpl
and ServerSocketChannelImpl (these depend on internal APIs changed in
this update)
- DataInputStream/DataOutputStream now use a small buffer to limit the
number of times the underlying stream is accessed
- Date now has a minutes offset, more efficient toString()
- ExposedByteArrayInputStream: new internal class
- DeleteOnExit moved to top-level class
- FileDescriptor.isValid() now non-native
- Float, Double lessThan optimized (fix for compare(-0.0F, 0.0F) still pending)
- FileURLConnection now guesses content types from streams
- HashMap iterator changes
- Hashtable iterator changes
- INetworkSystem
- removes bind2(), createMulticastSocket, sendStream(),
- renames createSocket to createStreamSocket
- JarURLConnection rewritten
- LinkedHashMap: new iterator
- Locale, Currency, TimeZone: now use ICU in Harmony, plain Java in Dalvik
- ObjectInputStream: Accessor objects in Harmony, direct native in Dalvik
- ProxyClassFile - many changes
- String - optimized ascii for toLowerCase, toUpperCase, compare
- Timer - rewritten
- TreeMap - rewritten
- URLClassLoader - new
- URLConnection - new guessContentTypeFromStream(), uses org.apache.harmony.awt.www.content
to lookup content type handlers
diff --git a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
index eb2920e..d93c156 100644
--- a/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
+++ b/crypto/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/ExemptionMechanismTest.java
@@ -21,6 +21,7 @@
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.SideEffect;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
@@ -221,6 +222,7 @@
method = "finalize",
args = {}
)
+ @SideEffect("Causes OutOfMemoryError to test finalization")
public void test_finalize () {
Mock_ExemptionMechanism mem = new Mock_ExemptionMechanism(null, null, "Name");
assertNotNull(mem);
diff --git a/luni-kernel/src/main/java/java/lang/Class.java b/luni-kernel/src/main/java/java/lang/Class.java
index 70ae3c1..6adf4db 100644
--- a/luni-kernel/src/main/java/java/lang/Class.java
+++ b/luni-kernel/src/main/java/java/lang/Class.java
@@ -440,7 +440,8 @@
* @see ClassLoader#isSystemClassLoader()
*/
ClassLoader getClassLoaderImpl() {
- return getClassLoader(this);
+ ClassLoader loader = getClassLoader(this);
+ return loader == null ? BootClassLoader.getInstance() : loader;
}
/*
diff --git a/luni-kernel/src/main/java/java/lang/Thread.java b/luni-kernel/src/main/java/java/lang/Thread.java
index 89d7ed6..484c258 100644
--- a/luni-kernel/src/main/java/java/lang/Thread.java
+++ b/luni-kernel/src/main/java/java/lang/Thread.java
@@ -79,10 +79,10 @@
private static class ParkState {
/** park state indicating unparked */
private static final int UNPARKED = 1;
-
+
/** park state indicating preemptively unparked */
private static final int PREEMPTIVELY_UNPARKED = 2;
-
+
/** park state indicating parked */
private static final int PARKED = 3;
}
@@ -122,21 +122,21 @@
/**
* The maximum priority value allowed for a thread.
- *
+ *
* @since Android 1.0
*/
public final static int MAX_PRIORITY = 10;
/**
* The minimum priority value allowed for a thread.
- *
+ *
* @since Android 1.0
*/
public final static int MIN_PRIORITY = 1;
/**
* The normal (default) priority value assigned to threads.
- *
+ *
* @since Android 1.0
*/
public final static int NORM_PRIORITY = 5;
@@ -200,7 +200,7 @@
/** the park state of the thread */
private int parkState = ParkState.UNPARKED;
-
+
/**
* Constructs a new {@code Thread} with no {@code Runnable} object and a
* newly generated name. The new {@code Thread} will belong to the same
@@ -208,7 +208,7 @@
*
* @see java.lang.ThreadGroup
* @see java.lang.Runnable
- *
+ *
* @since Android 1.0
*/
public Thread() {
@@ -219,14 +219,14 @@
* Constructs a new {@code Thread} with a {@code Runnable} object and a
* newly generated name. The new {@code Thread} will belong to the same
* {@code ThreadGroup} as the {@code Thread} calling this constructor.
- *
+ *
* @param runnable
* a {@code Runnable} whose method <code>run</code> will be
* executed by the new {@code Thread}
*
* @see java.lang.ThreadGroup
* @see java.lang.Runnable
- *
+ *
* @since Android 1.0
*/
public Thread(Runnable runnable) {
@@ -237,13 +237,13 @@
* Constructs a new {@code Thread} with a {@code Runnable} object and name
* provided. The new {@code Thread} will belong to the same {@code
* ThreadGroup} as the {@code Thread} calling this constructor.
- *
+ *
* @param runnable
* a {@code Runnable} whose method <code>run</code> will be
* executed by the new {@code Thread}
* @param threadName
* the name for the {@code Thread} being created
- *
+ *
* @see java.lang.ThreadGroup
* @see java.lang.Runnable
*
@@ -261,10 +261,10 @@
* Constructs a new {@code Thread} with no {@code Runnable} object and the
* name provided. The new {@code Thread} will belong to the same {@code
* ThreadGroup} as the {@code Thread} calling this constructor.
- *
+ *
* @param threadName
* the name for the {@code Thread} being created
- *
+ *
* @see java.lang.ThreadGroup
* @see java.lang.Runnable
*
@@ -282,7 +282,7 @@
* Constructs a new {@code Thread} with a {@code Runnable} object and a
* newly generated name. The new {@code Thread} will belong to the {@code
* ThreadGroup} passed as parameter.
- *
+ *
* @param group
* {@code ThreadGroup} to which the new {@code Thread} will
* belong
@@ -298,7 +298,7 @@
* @see java.lang.Runnable
* @see java.lang.SecurityException
* @see java.lang.SecurityManager
- *
+ *
* @since Android 1.0
*/
public Thread(ThreadGroup group, Runnable runnable) {
@@ -308,7 +308,7 @@
/**
* Constructs a new {@code Thread} with a {@code Runnable} object, the given
* name and belonging to the {@code ThreadGroup} passed as parameter.
- *
+ *
* @param group
* ThreadGroup to which the new {@code Thread} will belong
* @param runnable
@@ -325,7 +325,7 @@
* @see java.lang.Runnable
* @see java.lang.SecurityException
* @see java.lang.SecurityManager
- *
+ *
* @since Android 1.0
*/
public Thread(ThreadGroup group, Runnable runnable, String threadName) {
@@ -339,7 +339,7 @@
/**
* Constructs a new {@code Thread} with no {@code Runnable} object, the
* given name and belonging to the {@code ThreadGroup} passed as parameter.
- *
+ *
* @param group
* {@code ThreadGroup} to which the new {@code Thread} will belong
* @param threadName
@@ -353,7 +353,7 @@
* @see java.lang.Runnable
* @see java.lang.SecurityException
* @see java.lang.SecurityManager
- *
+ *
* @since Android 1.0
*/
public Thread(ThreadGroup group, String threadName) {
@@ -367,7 +367,7 @@
/**
* Constructs a new {@code Thread} with a {@code Runnable} object, the given
* name and belonging to the {@code ThreadGroup} passed as parameter.
- *
+ *
* @param group
* {@code ThreadGroup} to which the new {@code Thread} will
* belong
@@ -389,7 +389,7 @@
* @see java.lang.Runnable
* @see java.lang.SecurityException
* @see java.lang.SecurityManager
- *
+ *
* @since Android 1.0
*/
public Thread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
@@ -528,9 +528,9 @@
/**
* Returns the number of active {@code Thread}s in the running {@code
* Thread}'s group and its subgroups.
- *
+ *
* @return the number of {@code Thread}s
- *
+ *
* @since Android 1.0
*/
public static int activeCount() {
@@ -542,14 +542,14 @@
* there's none installed, this method is a no-op. If there's a
* SecurityManager installed, {@link SecurityManager#checkAccess(Thread)} is
* called for that SecurityManager.
- *
+ *
* @throws SecurityException
* if a SecurityManager is installed and it does not allow
* access to the Thread.
- *
+ *
* @see java.lang.SecurityException
* @see java.lang.SecurityManager
- *
+ *
* @since Android 1.0
*/
public final void checkAccess() {
@@ -564,12 +564,12 @@
/**
* Returns the number of stack frames in this thread.
- *
+ *
* @return Number of stack frames
* @deprecated The results of this call were never well defined. To make
* things worse, it would depend on whether the Thread was
* suspended or not, and suspend was deprecated too.
- *
+ *
* @since Android 1.0
*/
@Deprecated
@@ -581,7 +581,7 @@
* Returns the Thread of the caller, that is, the current Thread.
*
* @return the current Thread.
- *
+ *
* @since Android 1.0
*/
public static Thread currentThread() {
@@ -592,7 +592,7 @@
* Destroys the receiver without any monitor cleanup.
*
* @deprecated Not implemented.
- *
+ *
* @since Android 1.0
*/
@Deprecated
@@ -603,9 +603,9 @@
/**
* Prints to the standard error stream a text representation of the current
* stack for this Thread.
- *
+ *
* @see Throwable#printStackTrace()
- *
+ *
* @since Android 1.0
*/
public static void dumpStack() {
@@ -617,7 +617,7 @@
* receiver - and subgroups - into the array <code>threads</code> passed as
* parameter. If the array passed as parameter is too small no exception is
* thrown - the extra elements are simply not copied.
- *
+ *
* @param threads
* array into which the Threads will be copied
* @return How many Threads were copied over
@@ -626,7 +626,7 @@
* {@link SecurityManager#checkAccess(Thread)}
* @see java.lang.SecurityException
* @see java.lang.SecurityManager
- *
+ *
* @since Android 1.0
*/
public static int enumerate(Thread[] threads) {
@@ -640,13 +640,13 @@
* Returns the stack traces of all the currently live threads and puts them
* into the given map.
* </p>
- *
+ *
* @return A Map of current Threads to StackTraceElement arrays.
* @throws SecurityException
* if the current SecurityManager fails the
* {@link SecurityManager#checkPermission(java.security.Permission)}
* call.
- *
+ *
* @since Android 1.0
*/
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
@@ -684,14 +684,14 @@
* </ol>
* are satisfied, a security check for
* <code>RuntimePermission("getClassLoader")</code> is performed first.
- *
+ *
* @return ClassLoader The context ClassLoader
* @see java.lang.ClassLoader
* @see #getContextClassLoader()
- *
+ *
* @throws SecurityException
* if the aforementioned security check fails.
- *
+ *
* @since Android 1.0
*/
public ClassLoader getContextClassLoader() {
@@ -719,7 +719,7 @@
*
* @return an {@link UncaughtExceptionHandler} or <code>null</code> if
* none exists.
- *
+ *
* @since Android 1.0
*/
public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
@@ -731,9 +731,9 @@
* generated on thread creation, is unique to the thread, and doesn't change
* during the lifetime of the thread; the ID may be reused after the thread
* has been terminated.
- *
+ *
* @return the thread's ID.
- *
+ *
* @since Android 1.0
*/
public long getId() {
@@ -744,7 +744,7 @@
* Returns the name of the Thread.
*
* @return the Thread's name
- *
+ *
* @since Android 1.0
*/
public final String getName() {
@@ -756,7 +756,7 @@
*
* @return the Thread's priority
* @see Thread#setPriority
- *
+ *
* @since Android 1.0
*/
public final int getPriority() {
@@ -770,13 +770,13 @@
* The <code>RuntimePermission("getStackTrace")</code> is checked before
* returning a result.
* </p>
- *
+ *
* @return an array of StackTraceElements.
* @throws SecurityException
* if the current SecurityManager fails the
* {@link SecurityManager#checkPermission(java.security.Permission)}
* call.
- *
+ *
* @since Android 1.0
*/
public StackTraceElement[] getStackTrace() {
@@ -792,9 +792,9 @@
/**
* Returns the current state of the Thread. This method is useful for
* monitoring purposes.
- *
+ *
* @return a {@link State} value.
- *
+ *
* @since Android 1.0
*/
public State getState() {
@@ -805,7 +805,7 @@
// deletes the reference we won't run into a null reference later.
VMThread thread = vmThread;
if (thread != null) {
- // If the Thread Object became invalid or was not yet started,
+ // If the Thread Object became invalid or was not yet started,
// getStatus() will return -1.
int state = thread.getStatus();
if(state != -1) {
@@ -814,12 +814,12 @@
}
return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
}
-
+
/**
* Returns the ThreadGroup to which this Thread belongs.
- *
+ *
* @return the Thread's ThreadGroup
- *
+ *
* @since Android 1.0
*/
public final ThreadGroup getThreadGroup() {
@@ -835,9 +835,9 @@
* Returns the thread's uncaught exception handler. If not explicitly set,
* then the ThreadGroup's handler is returned. If the thread is terminated,
* then <code>null</code> is returned.
- *
+ *
* @return an {@link UncaughtExceptionHandler} instance or {@code null}.
- *
+ *
* @since Android 1.0
*/
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
@@ -870,14 +870,14 @@
* their interrupt status set and return immediately. They don't receive an
* exception in this case.
* <ul>
- *
+ *
* @throws SecurityException
* if <code>checkAccess()</code> fails with a SecurityException
* @see java.lang.SecurityException
* @see java.lang.SecurityManager
* @see Thread#interrupted
* @see Thread#isInterrupted
- *
+ *
* @since Android 1.0
*/
public void interrupt() {
@@ -898,12 +898,12 @@
* <code>currentThread()</code>) has a pending interrupt request (<code>
* true</code>) or not (<code>false</code>). It also has the side-effect of
* clearing the flag.
- *
+ *
* @return a <code>boolean</code> indicating the interrupt status
* @see Thread#currentThread
* @see Thread#interrupt
* @see Thread#isInterrupted
- *
+ *
* @since Android 1.0
*/
public static boolean interrupted() {
@@ -915,10 +915,10 @@
* still runs code (hasn't died yet). Returns <code>false</code> either if
* the receiver hasn't been started yet or if it has already started and run
* to completion and died.
- *
+ *
* @return a <code>boolean</code> indicating the lifeness of the Thread
* @see Thread#start
- *
+ *
* @since Android 1.0
*/
public final boolean isAlive() {
@@ -936,7 +936,7 @@
*
* @return a <code>boolean</code> indicating whether the Thread is a daemon
* @see Thread#setDaemon
- *
+ *
* @since Android 1.0
*/
public final boolean isDaemon() {
@@ -951,7 +951,7 @@
* @return a <code>boolean</code> indicating the interrupt status
* @see Thread#interrupt
* @see Thread#interrupted
- *
+ *
* @since Android 1.0
*/
public boolean isInterrupted() {
@@ -971,7 +971,7 @@
* the receiver while it was in the <code>join()</code> call
* @see Object#notifyAll
* @see java.lang.ThreadDeath
- *
+ *
* @since Android 1.0
*/
public final void join() throws InterruptedException {
@@ -997,7 +997,7 @@
* the receiver while it was in the <code>join()</code> call
* @see Object#notifyAll
* @see java.lang.ThreadDeath
- *
+ *
* @since Android 1.0
*/
public final void join(long millis) throws InterruptedException {
@@ -1015,7 +1015,7 @@
* the receiver while it was in the <code>join()</code> call
* @see Object#notifyAll
* @see java.lang.ThreadDeath
- *
+ *
* @since Android 1.0
*/
public final void join(long millis, int nanos) throws InterruptedException {
@@ -1067,12 +1067,12 @@
* suspended, or suspended and already resumed. If the receiver is
* suspended, however, makes it resume to the point where it was when it was
* suspended.
- *
+ *
* @throws SecurityException
* if <code>checkAccess()</code> fails with a SecurityException
* @see Thread#suspend()
* @deprecated Used with deprecated method {@link Thread#suspend}
- *
+ *
* @since Android 1.0
*/
@Deprecated
@@ -1090,7 +1090,7 @@
* holds. If no Runnable is set, does nothing.
*
* @see Thread#start
- *
+ *
* @since Android 1.0
*/
public void run() {
@@ -1111,7 +1111,7 @@
* checkPermission call.
* @see java.lang.ClassLoader
* @see #getContextClassLoader()
- *
+ *
* @since Android 1.0
*/
public void setContextClassLoader(ClassLoader cl) {
@@ -1126,13 +1126,13 @@
/**
* Set if the receiver is a daemon Thread or not. This can only be done
* before the Thread starts running.
- *
+ *
* @param isDaemon
* indicates whether the Thread should be daemon or not
* @throws SecurityException
* if <code>checkAccess()</code> fails with a SecurityException
* @see Thread#isDaemon
- *
+ *
* @since Android 1.0
*/
public final void setDaemon(boolean isDaemon) {
@@ -1156,13 +1156,13 @@
* The <code>RuntimePermission("setDefaultUncaughtExceptionHandler")</code>
* is checked prior to setting the handler.
* </p>
- *
+ *
* @param handler
* The handler to set or <code>null</code>.
* @throws SecurityException
* if the current SecurityManager fails the checkPermission
* call.
- *
+ *
* @since Android 1.0
*/
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
@@ -1197,7 +1197,7 @@
* @throws SecurityException if <code>checkAccess()</code> fails with a
* SecurityException
* @see Thread#getName
- *
+ *
* @since Android 1.0
*/
public final void setName(String threadName) {
@@ -1220,7 +1220,7 @@
* be the parameter that was passed - it will depend on the receiver's
* ThreadGroup. The priority cannot be set to be higher than the receiver's
* ThreadGroup's maxPriority().
- *
+ *
* @param priority
* new priority for the Thread
* @throws SecurityException
@@ -1229,7 +1229,7 @@
* if the new priority is greater than Thread.MAX_PRIORITY or
* less than Thread.MIN_PRIORITY
* @see Thread#getPriority
- *
+ *
* @since Android 1.0
*/
public final void setPriority(int priority) {
@@ -1256,12 +1256,12 @@
* Sets the uncaught exception handler. This handler is invoked in case this
* Thread dies due to an unhandled exception.
* </p>
- *
+ *
* @param handler
* The handler to set or <code>null</code>.
* @throws SecurityException
* if the current SecurityManager fails the checkAccess call.
- *
+ *
* @since Android 1.0
*/
public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
@@ -1274,14 +1274,14 @@
* Causes the thread which sent this message to sleep for the given interval
* of time (given in milliseconds). The precision is not guaranteed - the
* Thread may sleep more or less than requested.
- *
+ *
* @param time
* The time to sleep in milliseconds.
* @throws InterruptedException
* if <code>interrupt()</code> was called for this Thread while
* it was sleeping
* @see Thread#interrupt()
- *
+ *
* @since Android 1.0
*/
public static void sleep(long time) throws InterruptedException {
@@ -1292,7 +1292,7 @@
* Causes the thread which sent this message to sleep for the given interval
* of time (given in milliseconds and nanoseconds). The precision is not
* guaranteed - the Thread may sleep more or less than requested.
- *
+ *
* @param millis
* The time to sleep in milliseconds.
* @param nanos
@@ -1301,7 +1301,7 @@
* if <code>interrupt()</code> was called for this Thread while
* it was sleeping
* @see Thread#interrupt()
- *
+ *
* @since Android 1.0
*/
public static void sleep(long millis, int nanos) throws InterruptedException {
@@ -1314,9 +1314,9 @@
* Thread calling <code>start()</code>).
*
* @throws IllegalThreadStateException if the Thread has been started before
- *
+ *
* @see Thread#run
- *
+ *
* @since Android 1.0
*/
public synchronized void start() {
@@ -1338,7 +1338,7 @@
* SecurityException
* @deprecated because stopping a thread in this manner is unsafe and can
* leave your application and the VM in an unpredictable state.
- *
+ *
* @since Android 1.0
*/
@Deprecated
@@ -1359,7 +1359,7 @@
* <code>null</code>
* @deprecated because stopping a thread in this manner is unsafe and can
* leave your application and the VM in an unpredictable state.
- *
+ *
* @since Android 1.0
*/
@Deprecated
@@ -1388,12 +1388,12 @@
* resume()</code> is sent to it. Suspend requests are not queued, which
* means that N requests are equivalent to just one - only one resume
* request is needed in this case.
- *
+ *
* @throws SecurityException
* if <code>checkAccess()</code> fails with a SecurityException
* @see Thread#resume()
* @deprecated May cause deadlocks.
- *
+ *
* @since Android 1.0
*/
@Deprecated
@@ -1409,9 +1409,9 @@
/**
* Returns a string containing a concise, human-readable description of the
* Thread. It includes the Thread's name, priority, and group name.
- *
+ *
* @return a printable representation for the receiver.
- *
+ *
* @since Android 1.0
*/
@Override
@@ -1422,7 +1422,7 @@
/**
* Causes the calling Thread to yield execution time to another Thread that
* is ready to run. The actual scheduling is implementation-dependent.
- *
+ *
* @since Android 1.0
*/
public static void yield() {
@@ -1436,7 +1436,7 @@
* @param object the object to test for the monitor lock
* @return true if the current thread has a monitor lock on the specified
* object; false otherwise
- *
+ *
* @since Android 1.0
*/
public static boolean holdsLock(Object object) {
@@ -1448,7 +1448,7 @@
* terminated by an uncaught exception. Upon such termination, the handler
* is notified of the terminating thread and causal exception. If there is
* no explicit handler set then the thread's group is the default handler.
- *
+ *
* @since Android 1.0
*/
public static interface UncaughtExceptionHandler {
@@ -1459,7 +1459,7 @@
*
* @param thread the thread that has an uncaught exception
* @param ex the exception that was thrown
- *
+ *
* @since Android 1.0
*/
void uncaughtException(Thread thread, Throwable ex);
@@ -1482,7 +1482,7 @@
parkState = ParkState.PREEMPTIVELY_UNPARKED;
return;
}
-
+
synchronized (vmt) {
switch (parkState) {
case ParkState.PREEMPTIVELY_UNPARKED: {
@@ -1506,12 +1506,12 @@
}
}
}
-
+
/**
* Implementation of <code>parkFor()</code>. See {@link LangAccessImpl}.
* This method must only be called when <code>this</code> is the current
* thread.
- *
+ *
* @param nanos number of nanoseconds to park for
*/
/*package*/ void parkFor(long nanos) {
@@ -1521,7 +1521,7 @@
// Running threads should always have an associated vmThread.
throw new AssertionError();
}
-
+
synchronized (vmt) {
switch (parkState) {
case ParkState.PREEMPTIVELY_UNPARKED: {
@@ -1545,7 +1545,7 @@
*/
if (parkState == ParkState.PARKED) {
parkState = ParkState.UNPARKED;
- }
+ }
}
break;
}
@@ -1553,7 +1553,7 @@
throw new AssertionError(
"shouldn't happen: attempt to repark");
}
- }
+ }
}
}
@@ -1561,7 +1561,7 @@
* Implementation of <code>parkUntil()</code>. See {@link LangAccessImpl}.
* This method must only be called when <code>this</code> is the current
* thread.
- *
+ *
* @param time absolute milliseconds since the epoch to park until
*/
/*package*/ void parkUntil(long time) {
@@ -1571,7 +1571,7 @@
// Running threads should always have an associated vmThread.
throw new AssertionError();
}
-
+
synchronized (vmt) {
/*
* Note: This conflates the two time bases of "wall clock"
diff --git a/luni/src/main/java/java/io/BufferedInputStream.java b/luni/src/main/java/java/io/BufferedInputStream.java
index 0b9afc3..22379dd 100644
--- a/luni/src/main/java/java/io/BufferedInputStream.java
+++ b/luni/src/main/java/java/io/BufferedInputStream.java
@@ -30,68 +30,49 @@
* drawback is that some extra space is required to hold the buffer and that
* copying takes place when filling that buffer, but this is usually outweighed
* by the performance benefits.
- *
+ *
* <p/>A typical application pattern for the class looks like this:<p/>
- *
+ *
* <pre>
* BufferedInputStream buf = new BufferedInputStream(new FileInputStream("file.java"));
* </pre>
- *
+ *
* @see BufferedOutputStream
- *
- * @since Android 1.0
*/
public class BufferedInputStream extends FilterInputStream {
- // BEGIN android-changed
- // The address of the buffer should not be cached in a register.
- // This was changed to be more close to the RI.
/**
* The buffer containing the current bytes read from the target InputStream.
- *
- * @since Android 1.0
*/
protected volatile byte[] buf;
- // END android-changed
/**
* The total number of bytes inside the byte array {@code buf}.
- *
- * @since Android 1.0
*/
protected int count;
/**
* The current limit, which when passed, invalidates the current mark.
- *
- * @since Android 1.0
*/
protected int marklimit;
/**
* The currently marked position. -1 indicates no mark has been set or the
* mark has been invalidated.
- *
- * @since Android 1.0
*/
protected int markpos = -1;
/**
* The current position within the byte array {@code buf}.
- *
- * @since Android 1.0
*/
protected int pos;
- private boolean closed = false;
-
/**
* Constructs a new {@code BufferedInputStream} on the {@link InputStream}
* {@code in}. The default buffer size (8 KB) is allocated and all reads
* can now be filtered through this stream.
- *
+ *
* @param in
* the InputStream the buffer reads from.
- * @since Android 1.0
*/
public BufferedInputStream(InputStream in) {
super(in);
@@ -116,14 +97,13 @@
* Constructs a new {@code BufferedInputStream} on the {@link InputStream}
* {@code in}. The buffer size is specified by the parameter {@code size}
* and all reads are now filtered through this stream.
- *
+ *
* @param in
* the input stream the buffer reads from.
* @param size
* the size of buffer to allocate.
* @throws IllegalArgumentException
* if {@code size < 0}.
- * @since Android 1.0
*/
public BufferedInputStream(InputStream in, int size) {
super(in);
@@ -138,43 +118,43 @@
* Returns the number of bytes that are available before this stream will
* block. This method returns the number of bytes available in the buffer
* plus those available in the source stream.
- *
+ *
* @return the number of bytes available before blocking.
* @throws IOException
* if this stream is closed.
- * @since Android 1.0
*/
@Override
public synchronized int available() throws IOException {
- if (buf == null) {
+ InputStream localIn = in; // 'in' could be invalidated by close()
+ if (buf == null || localIn == null) {
// K0059=Stream is closed
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
- return count - pos + in.available();
+ return count - pos + localIn.available();
}
/**
* Closes this stream. The source stream is closed and any resources
* associated with it are released.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
- public synchronized void close() throws IOException {
- if (null != in) {
- super.close();
- in = null;
- }
+ public void close() throws IOException {
buf = null;
- closed = true;
+ InputStream localIn = in;
+ in = null;
+ if (localIn != null) {
+ localIn.close();
+ }
}
- private int fillbuf() throws IOException {
+ private int fillbuf(InputStream localIn, byte[] localBuf)
+ throws IOException {
if (markpos == -1 || (pos - markpos >= marklimit)) {
/* Mark position not set or exceeded readlimit */
- int result = in.read(buf);
+ int result = localIn.read(localBuf);
if (result > 0) {
markpos = -1;
pos = 0;
@@ -182,22 +162,25 @@
}
return result;
}
- if (markpos == 0 && marklimit > buf.length) {
- /* Increase buffer size to accomodate the readlimit */
- int newLength = buf.length * 2;
+ if (markpos == 0 && marklimit > localBuf.length) {
+ /* Increase buffer size to accommodate the readlimit */
+ int newLength = localBuf.length * 2;
if (newLength > marklimit) {
newLength = marklimit;
}
byte[] newbuf = new byte[newLength];
- System.arraycopy(buf, 0, newbuf, 0, buf.length);
- buf = newbuf;
+ System.arraycopy(localBuf, 0, newbuf, 0, localBuf.length);
+ // Reassign buf, which will invalidate any local references
+ // FIXME: what if buf was null?
+ localBuf = buf = newbuf;
} else if (markpos > 0) {
- System.arraycopy(buf, markpos, buf, 0, buf.length - markpos);
+ System.arraycopy(localBuf, markpos, localBuf, 0, localBuf.length
+ - markpos);
}
/* Set the new position and mark position */
pos -= markpos;
count = markpos = 0;
- int bytesread = in.read(buf, pos, buf.length - pos);
+ int bytesread = localIn.read(localBuf, pos, localBuf.length - pos);
count = bytesread <= 0 ? pos : pos + bytesread;
return bytesread;
}
@@ -209,12 +192,11 @@
* position if {@code readlimit} has not been surpassed. The underlying
* buffer may be increased in size to allow {@code readlimit} number of
* bytes to be supported.
- *
+ *
* @param readlimit
* the number of bytes that can be read before the mark is
* invalidated.
* @see #reset()
- * @since Android 1.0
*/
@Override
public synchronized void mark(int readlimit) {
@@ -225,11 +207,10 @@
/**
* Indicates whether {@code BufferedInputStream} supports the {@code mark()}
* and {@code reset()} methods.
- *
+ *
* @return {@code true} for BufferedInputStreams.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -241,28 +222,39 @@
* range from 0 to 255. Returns -1 if the end of the source string has been
* reached. If the internal buffer does not contain any available bytes then
* it is filled from the source stream and the first byte is returned.
- *
+ *
* @return the byte read or -1 if the end of the source stream has been
* reached.
* @throws IOException
* if this stream is closed or another IOException occurs.
- * @since Android 1.0
*/
@Override
public synchronized int read() throws IOException {
- if (in == null) {
+ // Use local refs since buf and in may be invalidated by an
+ // unsynchronized close()
+ byte[] localBuf = buf;
+ InputStream localIn = in;
+ if (localBuf == null || localIn == null) {
// K0059=Stream is closed
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
/* Are there buffered bytes available? */
- if (pos >= count && fillbuf() == -1) {
+ if (pos >= count && fillbuf(localIn, localBuf) == -1) {
return -1; /* no, fill buffer */
}
+ // localBuf may have been invalidated by fillbuf
+ if (localBuf != buf) {
+ localBuf = buf;
+ if (localBuf == null) {
+ // K0059=Stream is closed
+ throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
+ }
+ }
/* Did filling the buffer fail with -1 (EOF)? */
if (count - pos > 0) {
- return buf[pos++] & 0xFF;
+ return localBuf[pos++] & 0xFF;
}
return -1;
}
@@ -275,7 +267,7 @@
* mark has not been set and the requested number of bytes is larger than
* the receiver's buffer size, this implementation bypasses the buffer and
* simply places the results directly into {@code buffer}.
- *
+ *
* @param buffer
* the byte array in which to store the bytes read.
* @param offset
@@ -291,12 +283,14 @@
* @throws IOException
* if the stream is already closed or another IOException
* occurs.
- * @since Android 1.0
*/
@Override
public synchronized int read(byte[] buffer, int offset, int length)
throws IOException {
- if (closed) {
+ // Use local ref since buf may be invalidated by an unsynchronized
+ // close()
+ byte[] localBuf = buf;
+ if (localBuf == null) {
// K0059=Stream is closed
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
@@ -316,7 +310,9 @@
if (length == 0) {
return 0;
}
- if (null == buf) {
+ InputStream localIn = in;
+ if (localIn == null) {
+ // K0059=Stream is closed
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
@@ -324,9 +320,9 @@
if (pos < count) {
/* There are bytes available in the buffer. */
int copylength = count - pos >= length ? length : count - pos;
- System.arraycopy(buf, pos, buffer, offset, copylength);
+ System.arraycopy(localBuf, pos, buffer, offset, copylength);
pos += copylength;
- if (copylength == length || in.available() == 0) {
+ if (copylength == length || localIn.available() == 0) {
return copylength;
}
offset += copylength;
@@ -341,24 +337,33 @@
* If we're not marked and the required size is greater than the
* buffer, simply read the bytes directly bypassing the buffer.
*/
- if (markpos == -1 && required >= buf.length) {
- read = in.read(buffer, offset, required);
+ if (markpos == -1 && required >= localBuf.length) {
+ read = localIn.read(buffer, offset, required);
if (read == -1) {
return required == length ? -1 : length - required;
}
} else {
- if (fillbuf() == -1) {
+ if (fillbuf(localIn, localBuf) == -1) {
return required == length ? -1 : length - required;
}
+ // localBuf may have been invalidated by fillbuf
+ if (localBuf != buf) {
+ localBuf = buf;
+ if (localBuf == null) {
+ // K0059=Stream is closed
+ throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
+ }
+ }
+
read = count - pos >= required ? required : count - pos;
- System.arraycopy(buf, pos, buffer, offset, read);
+ System.arraycopy(localBuf, pos, buffer, offset, read);
pos += read;
}
required -= read;
if (required == 0) {
return length;
}
- if (in.available() == 0) {
+ if (localIn.available() == 0) {
return length - required;
}
offset += read;
@@ -367,13 +372,12 @@
/**
* Resets this stream to the last marked location.
- *
+ *
* @throws IOException
* if this stream is closed, no mark has been set or the mark is
* no longer valid because more than {@code readlimit} bytes
* have been read since setting the mark.
* @see #mark(int)
- * @since Android 1.0
*/
@Override
public synchronized void reset() throws IOException {
@@ -383,7 +387,7 @@
* so it is preferable to avoid loading up the whole big set of
* messages just for these cases.
*/
- if (closed) {
+ if (buf == null) {
throw new IOException("Stream is closed");
}
if (-1 == markpos) {
@@ -397,24 +401,31 @@
* Skips {@code amount} number of bytes in this stream. Subsequent
* {@code read()}'s will not return these bytes unless {@code reset()} is
* used.
- *
+ *
* @param amount
* the number of bytes to skip. {@code skip} does nothing and
* returns 0 if {@code amount} is less than zero.
* @return the number of bytes actually skipped.
* @throws IOException
* if this stream is closed or another IOException occurs.
- * @since Android 1.0
*/
@Override
public synchronized long skip(long amount) throws IOException {
- if (null == in) {
+ // Use local refs since buf and in may be invalidated by an
+ // unsynchronized close()
+ byte[] localBuf = buf;
+ InputStream localIn = in;
+ if (localBuf == null) {
// K0059=Stream is closed
throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
}
if (amount < 1) {
return 0;
}
+ if (localIn == null) {
+ // K0059=Stream is closed
+ throw new IOException(Msg.getString("K0059")); //$NON-NLS-1$
+ }
if (count - pos >= amount) {
pos += amount;
@@ -425,7 +436,7 @@
if (markpos != -1) {
if (amount <= marklimit) {
- if (fillbuf() == -1) {
+ if (fillbuf(localIn, localBuf) == -1) {
return read;
}
if (count - pos >= amount - read) {
@@ -437,9 +448,7 @@
pos = count;
return read;
}
- markpos = -1;
}
- return read + in.skip(amount - read);
+ return read + localIn.skip(amount - read);
}
}
-
diff --git a/luni/src/main/java/java/io/BufferedOutputStream.java b/luni/src/main/java/java/io/BufferedOutputStream.java
index 835d13f..6d52dee 100644
--- a/luni/src/main/java/java/io/BufferedOutputStream.java
+++ b/luni/src/main/java/java/io/BufferedOutputStream.java
@@ -30,40 +30,33 @@
* drawback is that some extra space is required to hold the buffer and that
* copying takes place when flushing that buffer, but this is usually outweighed
* by the performance benefits.
- *
+ *
* <p/>A typical application pattern for the class looks like this:<p/>
- *
+ *
* <pre>
* BufferedOutputStream buf = new BufferedOutputStream(new FileOutputStream("file.java"));
* </pre>
- *
+ *
* @see BufferedInputStream
- *
- * @since Android 1.0
*/
public class BufferedOutputStream extends FilterOutputStream {
/**
* The buffer containing the bytes to be written to the target stream.
- *
- * @since Android 1.0
*/
protected byte[] buf;
/**
* The total number of bytes inside the byte array {@code buf}.
- *
- * @since Android 1.0
*/
protected int count;
/**
* Constructs a new {@code BufferedOutputStream} on the {@link OutputStream}
* {@code out}. The buffer size is set to the default value of 8 KB.
- *
+ *
* @param out
* the {@code OutputStream} for which write operations are
* buffered.
- * @since Android 1.0
*/
public BufferedOutputStream(OutputStream out) {
super(out);
@@ -87,14 +80,13 @@
/**
* Constructs a new {@code BufferedOutputStream} on the {@link OutputStream}
* {@code out}. The buffer size is set to {@code size}.
- *
+ *
* @param out
* the output stream for which write operations are buffered.
* @param size
* the size of the buffer in bytes.
* @throws IllegalArgumentException
* if {@code size <= 0}.
- * @since Android 1.0
*/
public BufferedOutputStream(OutputStream out, int size) {
super(out);
@@ -108,17 +100,13 @@
/**
* Flushes this stream to ensure all pending data is written out to the
* target stream. In addition, the target stream is flushed.
- *
+ *
* @throws IOException
* if an error occurs attempting to flush this stream.
- * @since Android 1.0
*/
@Override
public synchronized void flush() throws IOException {
- if (count > 0) {
- out.write(buf, 0, count);
- }
- count = 0;
+ flushInternal();
out.flush();
}
@@ -128,7 +116,7 @@
* bytes, they are copied in. If not, the buffered bytes plus the bytes in
* {@code buffer} are written to the target stream, the target is flushed,
* and the buffer is cleared.
- *
+ *
* @param buffer
* the buffer to be written.
* @param offset
@@ -144,7 +132,8 @@
* if an error occurs attempting to write to this stream.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
+ * @throws ArrayIndexOutOfBoundsException
+ * If offset or count is outside of bounds.
*/
@Override
public synchronized void write(byte[] buffer, int offset, int length)
@@ -153,6 +142,13 @@
// K0047=buffer is null
throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
}
+
+ if (length >= buf.length) {
+ flushInternal();
+ out.write(buffer, offset, length);
+ return;
+ }
+
// BEGIN android-changed
// Exception priorities (in case of multiple errors) differ from
// RI, but are spec-compliant.
@@ -163,32 +159,15 @@
throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
}
// END android-changed
- if (count == 0 && length >= buf.length) {
- out.write(buffer, offset, length);
- return;
+
+ // flush the internal buffer first if we have not enough space left
+ if (length >= (buf.length - count)) {
+ flushInternal();
}
- int available = buf.length - count;
- if (length < available) {
- available = length;
- }
- if (available > 0) {
- System.arraycopy(buffer, offset, buf, count, available);
- count += available;
- }
- if (count == buf.length) {
- out.write(buf, 0, buf.length);
- count = 0;
- if (length > available) {
- offset += available;
- available = length - available;
- if (available >= buf.length) {
- out.write(buffer, offset, available);
- } else {
- System.arraycopy(buffer, offset, buf, count, available);
- count += available;
- }
- }
- }
+
+ // the length is always less than (buf.length - count) here so arraycopy is safe
+ System.arraycopy(buffer, offset, buf, count, length);
+ count += length;
}
/**
@@ -197,12 +176,11 @@
* copied into the buffer and the count incremented. Otherwise, the buffer
* plus {@code oneByte} are written to the target stream, the target is
* flushed, and the buffer is reset.
- *
+ *
* @param oneByte
* the byte to be written.
* @throws IOException
* if an error occurs attempting to write to this stream.
- * @since Android 1.0
*/
@Override
public synchronized void write(int oneByte) throws IOException {
@@ -212,4 +190,14 @@
}
buf[count++] = (byte) oneByte;
}
+
+ /**
+ * Flushes only internal buffer.
+ */
+ private void flushInternal() throws IOException {
+ if (count > 0) {
+ out.write(buf, 0, count);
+ }
+ count = 0;
+ }
}
diff --git a/luni/src/main/java/java/io/BufferedReader.java b/luni/src/main/java/java/io/BufferedReader.java
index e82e538..875840c 100644
--- a/luni/src/main/java/java/io/BufferedReader.java
+++ b/luni/src/main/java/java/io/BufferedReader.java
@@ -30,16 +30,15 @@
* some extra space is required to hold the buffer and that copying takes place
* when filling that buffer, but this is usually outweighed by the performance
* benefits.
- *
+ *
* <p/>A typical application pattern for the class looks like this:<p/>
- *
+ *
* <pre>
* BufferedReader buf = new BufferedReader(new FileReader("file.java"));
* </pre>
- *
+ *
* @see BufferedWriter
- *
- * @since Android 1.0
+ * @since 1.1
*/
public class BufferedReader extends Reader {
@@ -58,10 +57,9 @@
/**
* Constructs a new BufferedReader on the Reader {@code in}. The
* buffer gets the default size (8 KB).
- *
+ *
* @param in
* the Reader that is buffered.
- * @since Android 1.0
*/
public BufferedReader(Reader in) {
super(in);
@@ -87,14 +85,13 @@
/**
* Constructs a new BufferedReader on the Reader {@code in}. The buffer
* size is specified by the parameter {@code size}.
- *
+ *
* @param in
* the Reader that is buffered.
* @param size
* the size of the buffer to allocate.
* @throws IllegalArgumentException
* if {@code size <= 0}.
- * @since Android 1.0
*/
public BufferedReader(Reader in, int size) {
super(in);
@@ -109,10 +106,9 @@
* Closes this reader. This implementation closes the buffered source reader
* and releases the buffer. Nothing is done if this reader has already been
* closed.
- *
+ *
* @throws IOException
* if an error occurs while closing this reader.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -158,7 +154,7 @@
/**
* Indicates whether or not this reader is closed.
- *
+ *
* @return {@code true} if this reader is closed, {@code false}
* otherwise.
*/
@@ -171,7 +167,7 @@
* indicates how many characters can be read before the mark is invalidated.
* Calling {@code reset()} will reposition the reader back to the marked
* position if {@code readlimit} has not been surpassed.
- *
+ *
* @param readlimit
* the number of characters that can be read before the mark is
* invalidated.
@@ -181,7 +177,6 @@
* if an error occurs while setting a mark in this reader.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public void mark(int readlimit) throws IOException {
@@ -200,11 +195,10 @@
/**
* Indicates whether this reader supports the {@code mark()} and
* {@code reset()} methods. This implementation returns {@code true}.
- *
+ *
* @return {@code true} for {@code BufferedReader}.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -217,12 +211,11 @@
* character from the buffer. If there are no characters available in the
* buffer, it fills the buffer and then returns a character. It returns -1
* if there are no more characters in the source reader.
- *
+ *
* @return the character read or -1 if the end of the source reader has been
* reached.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -234,6 +227,7 @@
if (pos < count || fillbuf() != -1) {
return buf[pos++];
}
+ markpos = -1;
return -1;
}
}
@@ -246,7 +240,7 @@
* has not been set and the requested number of characters is larger than
* this readers buffer size, BufferedReader bypasses the buffer and simply
* places the results directly into {@code buffer}.
- *
+ *
* @param buffer
* the character array to store the characters read.
* @param offset
@@ -263,7 +257,6 @@
* {@code buffer}.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read(char[] buffer, int offset, int length) throws IOException {
@@ -336,13 +329,13 @@
* Returns the next line of text available from this reader. A line is
* represented by zero or more characters followed by {@code '\n'},
* {@code '\r'}, {@code "\r\n"} or the end of the reader. The string does
- * not include the newline sequence.
- *
+ * not include the newline sequence. In EBCDIC systems, a new line can also
+ * be represented by the {@code \u0085} (NEL) character.
+ *
* @return the contents of the line or {@code null} if no characters were
* read before the end of the reader has been reached.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
public String readLine() throws IOException {
synchronized (lock) {
@@ -355,7 +348,10 @@
}
for (int charPos = pos; charPos < count; charPos++) {
char ch = buf[charPos];
- if (ch > '\r') {
+ // BEGIN android-note
+ // a switch statement may be more efficient
+ // END android-note
+ if ((ch > '\r') && (ch != '\u0085')) {
continue;
}
if (ch == '\n') {
@@ -370,6 +366,11 @@
pos++;
}
return res;
+ } else if (ch == '\u0085') {
+ /* Also handle the EBCDIC NEL character */
+ String res = new String(buf, pos, charPos - pos);
+ pos = charPos + 1;
+ return res;
}
}
@@ -393,8 +394,11 @@
}
}
for (int charPos = pos; charPos < count; charPos++) {
+ // BEGIN android-note
+ // use a local variable for buf[charPos] and a switch statement
+ // END android-note
if (eol == '\0') {
- if ((buf[charPos] == '\n' || buf[charPos] == '\r')) {
+ if ((buf[charPos] == '\n' || buf[charPos] == '\r') || (buf[charPos] == '\u0085')) {
eol = buf[charPos];
}
} else if (eol == '\r' && (buf[charPos] == '\n')) {
@@ -424,7 +428,7 @@
/**
* Indicates whether this reader is ready to be read without blocking.
- *
+ *
* @return {@code true} if this reader will not block when {@code read} is
* called, {@code false} if unknown or blocking will occur.
* @throws IOException
@@ -432,7 +436,6 @@
* @see #read()
* @see #read(char[], int, int)
* @see #readLine()
- * @since Android 1.0
*/
@Override
public boolean ready() throws IOException {
@@ -448,12 +451,11 @@
* Resets this reader's position to the last {@code mark()} location.
* Invocations of {@code read()} and {@code skip()} will occur from this new
* location.
- *
+ *
* @throws IOException
* if this reader is closed or no mark has been set.
* @see #mark(int)
* @see #markSupported()
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
@@ -473,7 +475,7 @@
* {@code read()}s will not return these characters unless {@code reset()}
* is used. Skipping characters may invalidate a mark if {@code readlimit}
* is surpassed.
- *
+ *
* @param amount
* the maximum number of characters to skip.
* @return the number of characters actually skipped.
@@ -484,7 +486,6 @@
* @see #mark(int)
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public long skip(long amount) throws IOException {
diff --git a/luni/src/main/java/java/io/BufferedWriter.java b/luni/src/main/java/java/io/BufferedWriter.java
index 761b9c5..86949fa 100644
--- a/luni/src/main/java/java/io/BufferedWriter.java
+++ b/luni/src/main/java/java/io/BufferedWriter.java
@@ -33,16 +33,14 @@
* some extra space is required to hold the buffer and that copying takes place
* when filling that buffer, but this is usually outweighed by the performance
* benefits.
- *
+ *
* <p/>A typical application pattern for the class looks like this:<p/>
- *
+ *
* <pre>
* BufferedWriter buf = new BufferedWriter(new FileWriter("file.java"));
* </pre>
- *
+ *
* @see BufferedReader
- *
- * @since Android 1.0
*/
public class BufferedWriter extends Writer {
@@ -59,10 +57,9 @@
* Constructs a new {@code BufferedWriter} with {@code out} as the writer
* for which to buffer write operations. The buffer size is set to the
* default value of 8 KB.
- *
+ *
* @param out
* the writer for which character writing is buffered.
- * @since Android 1.0
*/
public BufferedWriter(Writer out) {
super(out);
@@ -88,14 +85,13 @@
* Constructs a new {@code BufferedWriter} with {@code out} as the writer
* for which to buffer write operations. The buffer size is set to {@code
* size}.
- *
+ *
* @param out
* the writer for which character writing is buffered.
* @param size
* the size of the buffer in bytes.
* @throws IllegalArgumentException
* if {@code size <= 0}.
- * @since Android 1.0
*/
public BufferedWriter(Writer out, int size) {
super(out);
@@ -110,16 +106,15 @@
* Closes this writer. The contents of the buffer are flushed, the target
* writer is closed, and the buffer is released. Only the first invocation
* of close has any effect.
- *
+ *
* @throws IOException
* if an error occurs while closing this writer.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
synchronized (lock) {
if (!isClosed()) {
- flush();
+ flushInternal();
out.close();
buf = null;
out = null;
@@ -130,10 +125,9 @@
/**
* Flushes this writer. The contents of the buffer are committed to the
* target writer and it is then flushed.
- *
+ *
* @throws IOException
* if an error occurs while flushing this writer.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -141,17 +135,24 @@
if (isClosed()) {
throw new IOException(Msg.getString("K005d")); //$NON-NLS-1$
}
- if (pos > 0) {
- out.write(buf, 0, pos);
- }
- pos = 0;
+ flushInternal();
out.flush();
}
}
/**
+ * Flushes the internal buffer.
+ */
+ private void flushInternal() throws IOException {
+ if (pos > 0) {
+ out.write(buf, 0, pos);
+ }
+ pos = 0;
+ }
+
+ /**
* Indicates whether this writer is closed.
- *
+ *
* @return {@code true} if this writer is closed, {@code false} otherwise.
*/
private boolean isClosed() {
@@ -162,10 +163,9 @@
* Writes a newline to this writer. A newline is determined by the System
* property "line.separator". The target writer may or may not be flushed
* when a newline is written.
- *
+ *
* @throws IOException
* if an error occurs attempting to write to this writer.
- * @since Android 1.0
*/
public void newLine() throws IOException {
write(lineSeparator, 0, lineSeparator.length());
@@ -176,7 +176,7 @@
* {@code cbuf} to this writer. If {@code count} is greater than this
* writer's buffer, then the buffer is flushed and the characters are
* written directly to the target writer.
- *
+ *
* @param cbuf
* the array containing characters to write.
* @param offset
@@ -189,7 +189,6 @@
* {@code cbuf}.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public void write(char[] cbuf, int offset, int count) throws IOException {
@@ -243,12 +242,11 @@
* Writes the character {@code oneChar} to this writer. If the buffer
* gets full by writing this character, this writer is flushed. Only the
* lower two bytes of the integer {@code oneChar} are written.
- *
+ *
* @param oneChar
* the character to write.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public void write(int oneChar) throws IOException {
@@ -270,7 +268,7 @@
* then this writer is flushed and the remaining characters are written
* directly to the target writer. If count is negative no characters are
* written to the buffer. This differs from the behavior of the superclass.
- *
+ *
* @param str
* the non-null String containing characters to write.
* @param offset
@@ -283,7 +281,6 @@
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code offset + count} is greater
* than the length of {@code str}.
- * @since Android 1.0
*/
@Override
public void write(String str, int offset, int count) throws IOException {
diff --git a/luni/src/main/java/java/io/ByteArrayInputStream.java b/luni/src/main/java/java/io/ByteArrayInputStream.java
index 1564ca5..f0b7219 100644
--- a/luni/src/main/java/java/io/ByteArrayInputStream.java
+++ b/luni/src/main/java/java/io/ByteArrayInputStream.java
@@ -23,48 +23,38 @@
/**
* A specialized {@link InputStream } for reading the contents of a byte array.
- *
+ *
* @see ByteArrayOutputStream
- *
- * @since Android 1.0
*/
public class ByteArrayInputStream extends InputStream {
/**
* The {@code byte} array containing the bytes to stream over.
- *
- * @since Android 1.0
*/
protected byte[] buf;
/**
* The current position within the byte array.
- *
- * @since Android 1.0
*/
protected int pos;
/**
- * The current mark position.
- *
- * @since Android 1.0
+ * The current mark position. Initially set to 0 or the <code>offset</code>
+ * parameter within the constructor.
*/
protected int mark;
/**
* The total number of bytes initially available in the byte array
* {@code buf}.
- *
- * @since Android 1.0
*/
protected int count;
/**
* Constructs a new {@code ByteArrayInputStream} on the byte array
* {@code buf}.
- *
+ *
* @param buf
* the byte array to stream over.
- * @since Android 1.0
*/
public ByteArrayInputStream(byte buf[]) {
this.mark = 0;
@@ -76,14 +66,13 @@
* Constructs a new {@code ByteArrayInputStream} on the byte array
* {@code buf} with the initial position set to {@code offset} and the
* number of bytes available set to {@code offset} + {@code length}.
- *
+ *
* @param buf
* the byte array to stream over.
* @param offset
* the initial position in {@code buf} to start streaming from.
* @param length
* the number of bytes available for streaming.
- * @since Android 1.0
*/
public ByteArrayInputStream(byte[] buf, int offset, int length) {
// BEGIN android-note
@@ -99,9 +88,8 @@
* Returns the number of bytes that are available before this stream will
* block. This method returns the number of bytes yet to be read from the
* source byte array.
- *
+ *
* @return the number of bytes available before blocking.
- * @since Android 1.0
*/
@Override
public synchronized int available() {
@@ -110,10 +98,9 @@
/**
* Closes this stream and frees resources associated with this stream.
- *
+ *
* @throws IOException
* if an I/O error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -124,12 +111,11 @@
* Sets a mark position in this ByteArrayInputStream. The parameter
* {@code readlimit} is ignored. Sending {@code reset()} will reposition the
* stream back to the marked position.
- *
+ *
* @param readlimit
* ignored.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public synchronized void mark(int readlimit) {
@@ -140,11 +126,10 @@
* Indicates whether this stream supports the {@code mark()} and
* {@code reset()} methods. Returns {@code true} since this class supports
* these methods.
- *
+ *
* @return always {@code true}.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -155,9 +140,8 @@
* Reads a single byte from the source byte array and returns it as an
* integer in the range from 0 to 255. Returns -1 if the end of the source
* array has been reached.
- *
+ *
* @return the byte read or -1 if the end of this stream has been reached.
- * @since Android 1.0
*/
@Override
public synchronized int read() {
@@ -168,7 +152,7 @@
* Reads at most {@code len} bytes from this stream and stores
* them in byte array {@code b} starting at {@code offset}. This
* implementation reads bytes from the source byte array.
- *
+ *
* @param b
* the byte array in which to store the bytes read.
* @param offset
@@ -183,8 +167,7 @@
* {@code offset + length} is greater than the size of
* {@code b}.
* @throws NullPointerException
- * if {@code b} is null.
- * @since Android 1.0
+ * if {@code b} is {@code null}.
*/
@Override
public synchronized int read(byte[] b, int offset, int length) {
@@ -222,9 +205,8 @@
* Resets this stream to the last marked location. This implementation
* resets the position to either the marked position, the start position
* supplied in the constructor or 0 if neither has been provided.
- *
+ *
* @see #mark(int)
- * @since Android 1.0
*/
@Override
public synchronized void reset() {
@@ -236,11 +218,10 @@
* {@code read()}s will not return these bytes unless {@code reset()} is
* used. This implementation skips {@code count} number of bytes in the
* target stream. It does nothing and returns 0 if {@code n} is negative.
- *
+ *
* @param n
* the number of bytes to skip.
* @return the number of bytes actually skipped.
- * @since Android 1.0
*/
@Override
public synchronized long skip(long n) {
diff --git a/luni/src/main/java/java/io/ByteArrayOutputStream.java b/luni/src/main/java/java/io/ByteArrayOutputStream.java
index 8c6fa05..4d5a738 100644
--- a/luni/src/main/java/java/io/ByteArrayOutputStream.java
+++ b/luni/src/main/java/java/io/ByteArrayOutputStream.java
@@ -24,23 +24,17 @@
* (internal) byte array. As bytes are written to this stream, the byte array
* may be expanded to hold more bytes. When the writing is considered to be
* finished, a copy of the byte array can be requested from the class.
- *
+ *
* @see ByteArrayInputStream
- *
- * @since Android 1.0
*/
public class ByteArrayOutputStream extends OutputStream {
/**
* The byte array containing the bytes written.
- *
- * @since Android 1.0
*/
protected byte[] buf;
/**
* The number of bytes written.
- *
- * @since Android 1.0
*/
protected int count;
@@ -48,8 +42,6 @@
* Constructs a new ByteArrayOutputStream with a default size of 32 bytes.
* If more than 32 bytes are written to this instance, the underlying byte
* array will expand.
- *
- * @since Android 1.0
*/
public ByteArrayOutputStream() {
super();
@@ -60,13 +52,12 @@
* Constructs a new {@code ByteArrayOutputStream} with a default size of
* {@code size} bytes. If more than {@code size} bytes are written to this
* instance, the underlying byte array will expand.
- *
+ *
* @param size
* initial size for the underlying byte array, must be
* non-negative.
* @throws IllegalArgumentException
* if {@code size} < 0.
- * @since Android 1.0
*/
public ByteArrayOutputStream(int size) {
super();
@@ -79,10 +70,9 @@
/**
* Closes this stream. This releases system resources used for this stream.
- *
+ *
* @throws IOException
* if an error occurs while attempting to close this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -109,8 +99,6 @@
* Resets this stream to the beginning of the underlying byte array. All
* subsequent writes will overwrite any bytes previously stored in this
* stream.
- *
- * @since Android 1.0
*/
public synchronized void reset() {
count = 0;
@@ -118,9 +106,8 @@
/**
* Returns the total number of bytes written to this stream so far.
- *
+ *
* @return the number of bytes written to this stream.
- * @since Android 1.0
*/
public int size() {
return count;
@@ -130,9 +117,8 @@
* Returns the contents of this ByteArrayOutputStream as a byte array. Any
* changes made to the receiver after returning will not be reflected in the
* byte array returned to the caller.
- *
+ *
* @return this stream's current contents as a byte array.
- * @since Android 1.0
*/
public synchronized byte[] toByteArray() {
byte[] newArray = new byte[count];
@@ -144,9 +130,8 @@
* Returns the contents of this ByteArrayOutputStream as a string. Any
* changes made to the receiver after returning will not be reflected in the
* string returned to the caller.
- *
+ *
* @return this stream's current contents as a string.
- * @since Android 1.0
*/
@Override
@@ -161,13 +146,12 @@
* {@code c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))}. This method is
* deprecated and either {@link #toString()} or {@link #toString(String)}
* should be used.
- *
+ *
* @param hibyte
* the high byte of each resulting Unicode character.
* @return this stream's current contents as a string with the high byte set
* to {@code hibyte}.
* @deprecated Use {@link #toString()}.
- * @since Android 1.0
*/
@Deprecated
public String toString(int hibyte) {
@@ -181,14 +165,13 @@
/**
* Returns the contents of this ByteArrayOutputStream as a string converted
* according to the encoding declared in {@code enc}.
- *
+ *
* @param enc
* a string representing the encoding to use when translating
* this stream to a string.
* @return this stream's current contents as an encoded string.
* @throws UnsupportedEncodingException
* if the provided encoding is not supported.
- * @since Android 1.0
*/
public String toString(String enc) throws UnsupportedEncodingException {
return new String(buf, 0, count, enc);
@@ -197,18 +180,19 @@
/**
* Writes {@code count} bytes from the byte array {@code buffer} starting at
* offset {@code index} to this stream.
- *
+ *
* @param buffer
* the buffer to be written.
* @param offset
* the initial position in {@code buffer} to retrieve bytes.
* @param len
* the number of bytes of {@code buffer} to write.
+ * @throws NullPointerException
+ * if {@code buffer} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code len < 0}, or if
* {@code offset + len} is greater than the length of
* {@code buffer}.
- * @since Android 1.0
*/
@Override
public synchronized void write(byte[] buffer, int offset, int len) {
@@ -239,28 +223,26 @@
/**
* Writes the specified byte {@code oneByte} to the OutputStream. Only the
* low order byte of {@code oneByte} is written.
- *
+ *
* @param oneByte
* the byte to be written.
- * @since Android 1.0
*/
@Override
public synchronized void write(int oneByte) {
if (count == buf.length) {
expand(1);
}
- buf[count++] = (byte)oneByte;
+ buf[count++] = (byte) oneByte;
}
/**
* Takes the contents of this stream and writes it to the output stream
* {@code out}.
- *
+ *
* @param out
* an OutputStream on which to write the contents of this stream.
* @throws IOException
* if an error occurs while writing to {@code out}.
- * @since Android 1.0
*/
public synchronized void writeTo(OutputStream out) throws IOException {
out.write(buf, 0, count);
diff --git a/luni/src/main/java/java/io/CharArrayReader.java b/luni/src/main/java/java/io/CharArrayReader.java
index 95a8826..d2757f6 100644
--- a/luni/src/main/java/java/io/CharArrayReader.java
+++ b/luni/src/main/java/java/io/CharArrayReader.java
@@ -21,37 +21,27 @@
/**
* A specialized {@link Reader} for reading the contents of a char array.
- *
+ *
* @see CharArrayWriter
- *
- * @since Android 1.0
*/
public class CharArrayReader extends Reader {
/**
* The buffer for characters.
- *
- * @since Android 1.0
*/
protected char buf[];
/**
* The current buffer position.
- *
- * @since Android 1.0
*/
protected int pos;
/**
* The current mark position.
- *
- * @since Android 1.0
*/
protected int markedPos = -1;
/**
* The ending index of the buffer.
- *
- * @since Android 1.0
*/
protected int count;
@@ -59,10 +49,9 @@
* Constructs a CharArrayReader on the char array {@code buf}. The size of
* the reader is set to the length of the buffer and the object to to read
* from is set to {@code buf}.
- *
+ *
* @param buf
* the char array from which to read.
- * @since Android 1.0
*/
public CharArrayReader(char[] buf) {
super(buf);
@@ -74,7 +63,7 @@
* Constructs a CharArrayReader on the char array {@code buf}. The size of
* the reader is set to {@code length} and the start position from which to
* read the buffer is set to {@code offset}.
- *
+ *
* @param buf
* the char array from which to read.
* @param offset
@@ -84,7 +73,6 @@
* @throws IllegalArgumentException
* if {@code offset < 0} or {@code length < 0}, or if
* {@code offset} is greater than the size of {@code buf} .
- * @since Android 1.0
*/
public CharArrayReader(char[] buf, int offset, int length) {
super(buf);
@@ -92,7 +80,7 @@
// Exception priorities (in case of multiple errors) differ from
// RI, but are spec-compliant.
// made implicit null check explicit,
- // removed redundant check, used (offset | length) < 0 instead of
+ // removed redundant check, used (offset | length) < 0 instead of
// (offset < 0) || (length < 0) to safe one operation
if (buf == null) {
throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
@@ -103,6 +91,7 @@
// END android-changed
this.buf = buf;
this.pos = offset;
+ this.markedPos = offset;
/* This is according to spec */
this.count = this.pos + length < buf.length ? length : buf.length;
@@ -112,8 +101,6 @@
* This method closes this CharArrayReader. Once it is closed, you can no
* longer read from it. Only the first invocation of this method has any
* effect.
- *
- * @since Android 1.0
*/
@Override
public void close() {
@@ -126,7 +113,7 @@
/**
* Indicates whether this reader is open.
- *
+ *
* @return {@code true} if the reader is open, {@code false} otherwise.
*/
private boolean isOpen() {
@@ -135,7 +122,7 @@
/**
* Indicates whether this reader is closed.
- *
+ *
* @return {@code true} if the reader is closed, {@code false} otherwise.
*/
private boolean isClosed() {
@@ -147,12 +134,11 @@
* ignored for CharArrayReaders. Calling {@code reset()} will reposition the
* reader back to the marked position provided the mark has not been
* invalidated.
- *
+ *
* @param readLimit
* ignored for CharArrayReaders.
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public void mark(int readLimit) throws IOException {
@@ -167,11 +153,10 @@
/**
* Indicates whether this reader supports the {@code mark()} and
* {@code reset()} methods.
- *
+ *
* @return {@code true} for CharArrayReader.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -182,12 +167,11 @@
* Reads a single character from this reader and returns it as an integer
* with the two higher-order bytes set to 0. Returns -1 if no more
* characters are available from this reader.
- *
+ *
* @return the character read as an int or -1 if the end of the reader has
* been reached.
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -207,7 +191,7 @@
* stores them at {@code offset} in the character array {@code buf}.
* Returns the number of characters actually read or -1 if the end of reader
* was encountered.
- *
+ *
* @param buffer
* the character array to store the characters read.
* @param offset
@@ -223,7 +207,6 @@
* {@code buffer}.
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public int read(char[] buffer, int offset, int len) throws IOException {
@@ -264,12 +247,11 @@
* {@code false} if this reader may or may not block when {@code read} is
* called. The implementation in CharArrayReader always returns {@code true}
* even when it has been closed.
- *
+ *
* @return {@code true} if this reader will not block when {@code read} is
* called, {@code false} if unknown or blocking will occur.
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public boolean ready() throws IOException {
@@ -286,10 +268,9 @@
* Invocations of {@code read()} and {@code skip()} will occur from this new
* location. If this reader has not been marked, it is reset to the
* beginning of the string.
- *
+ *
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
@@ -305,13 +286,12 @@
* Skips {@code count} number of characters in this reader. Subsequent
* {@code read()}s will not return these characters unless {@code reset()}
* is used. This method does nothing and returns 0 if {@code n} is negative.
- *
+ *
* @param n
* the number of characters to skip.
* @return the number of characters actually skipped.
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public long skip(long n) throws IOException {
diff --git a/luni/src/main/java/java/io/CharArrayWriter.java b/luni/src/main/java/java/io/CharArrayWriter.java
index 7e58b2b..6b3fa39 100644
--- a/luni/src/main/java/java/io/CharArrayWriter.java
+++ b/luni/src/main/java/java/io/CharArrayWriter.java
@@ -24,33 +24,25 @@
* char array. As bytes are written to this writer, the char array may be
* expanded to hold more characters. When the writing is considered to be
* finished, a copy of the char array can be requested from the class.
- *
+ *
* @see CharArrayReader
- *
- * @since Android 1.0
*/
public class CharArrayWriter extends Writer {
/**
* The buffer for characters.
- *
- * @since Android 1.0
*/
protected char[] buf;
/**
* The ending index of the buffer.
- *
- * @since Android 1.0
*/
protected int count;
/**
- * Constructs a new CharArrayWriter which has a buffer allocated with the
- * default size of 32 characters. This buffer is also used as the
+ * Constructs a new {@code CharArrayWriter} which has a buffer allocated
+ * with the default size of 32 characters. This buffer is also used as the
* {@code lock} to synchronize access to this writer.
- *
- * @since Android 1.0
*/
public CharArrayWriter() {
super();
@@ -59,15 +51,14 @@
}
/**
- * Constructs a new CharArrayWriter which has a buffer allocated with the
- * size of {@code initialSize} characters. The buffer is also used as the
- * {@code lock} to synchronize access to this writer.
- *
+ * Constructs a new {@code CharArrayWriter} which has a buffer allocated
+ * with the size of {@code initialSize} characters. The buffer is also used
+ * as the {@code lock} to synchronize access to this writer.
+ *
* @param initialSize
* the initial size of this CharArrayWriters buffer.
* @throws IllegalArgumentException
* if {@code initialSize < 0}.
- * @since Android 1.0
*/
public CharArrayWriter(int initialSize) {
super();
@@ -79,9 +70,7 @@
}
/**
- * Closes this writer. The implementation in CharArrayWriter does nothing.
- *
- * @since Android 1.0
+ * Closes this writer. The implementation in {@code CharArrayWriter} does nothing.
*/
@Override
public void close() {
@@ -94,15 +83,14 @@
return;
}
- char[] newbuf = new char[buf.length + (2 * i)];
+ int newLen = Math.max(2 * buf.length, count + i);
+ char[] newbuf = new char[newLen];
System.arraycopy(buf, 0, newbuf, 0, count);
buf = newbuf;
}
/**
- * Flushes this writer. The implementation in CharArrayWriter does nothing.
- *
- * @since Android 1.0
+ * Flushes this writer. The implementation in {@code CharArrayWriter} does nothing.
*/
@Override
public void flush() {
@@ -113,8 +101,6 @@
* Resets this writer. The current write position is reset to the beginning
* of the buffer. All written characters are lost and the size of this
* writer is set to 0.
- *
- * @since Android 1.0
*/
public void reset() {
synchronized (lock) {
@@ -126,9 +112,8 @@
* Returns the size of this writer, that is the number of characters it
* stores. This number changes if this writer is reset or when more
* characters are written to it.
- *
+ *
* @return this CharArrayWriter's current size in characters.
- * @since Android 1.0
*/
public int size() {
synchronized (lock) {
@@ -140,9 +125,8 @@
* Returns the contents of the receiver as a char array. The array returned
* is a copy and any modifications made to this writer after calling this
* method are not reflected in the result.
- *
+ *
* @return this CharArrayWriter's contents as a new char array.
- * @since Android 1.0
*/
public char[] toCharArray() {
synchronized (lock) {
@@ -153,12 +137,11 @@
}
/**
- * Returns the contents of this CharArrayWriter as a string. The string
- * returned is a copy and any modifications made to this writer after
+ * Returns the contents of this {@code CharArrayWriter} as a string. The
+ * string returned is a copy and any modifications made to this writer after
* calling this method are not reflected in the result.
- *
+ *
* @return this CharArrayWriters contents as a new string.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -170,7 +153,7 @@
/**
* Writes {@code count} characters starting at {@code offset} in {@code c}
* to this writer.
- *
+ *
* @param c
* the non-null array containing characters to write.
* @param offset
@@ -180,7 +163,6 @@
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code len < 0}, or if
* {@code offset + len} is bigger than the size of {@code c}.
- * @since Android 1.0
*/
@Override
public void write(char[] c, int offset, int len) {
@@ -210,10 +192,9 @@
* Writes the specified character {@code oneChar} to this writer.
* This implementation writes the two low order bytes of the integer
* {@code oneChar} to the buffer.
- *
+ *
* @param oneChar
* the character to write.
- * @since Android 1.0
*/
@Override
public void write(int oneChar) {
@@ -226,7 +207,7 @@
/**
* Writes {@code count} number of characters starting at {@code offset} from
* the string {@code str} to this CharArrayWriter.
- *
+ *
* @param str
* the non-null string containing the characters to write.
* @param offset
@@ -234,12 +215,11 @@
* @param len
* the number of characters to retrieve and write.
* @throws NullPointerException
- * if {@code str} is null.
+ * if {@code str} is {@code null}.
* @throws StringIndexOutOfBoundsException
* if {@code offset < 0} or {@code len < 0}, or if
* {@code offset + len} is bigger than the length of
* {@code str}.
- * @since Android 1.0
*/
@Override
public void write(String str, int offset, int len) {
@@ -264,17 +244,16 @@
}
/**
- * Writes the contents of this CharArrayWriter to another Writer. The output
- * is all the characters that have been written to the receiver since the
- * last reset or since it was created.
- *
+ * Writes the contents of this {@code CharArrayWriter} to another {@code
+ * Writer}. The output is all the characters that have been written to the
+ * receiver since the last reset or since it was created.
+ *
* @param out
- * the non-null Writer on which to write the contents.
+ * the non-null {@code Writer} on which to write the contents.
* @throws NullPointerException
- * if {@code out} is null.
+ * if {@code out} is {@code null}.
* @throws IOException
* if an error occurs attempting to write out the contents.
- * @since Android 1.0
*/
public void writeTo(Writer out) throws IOException {
synchronized (lock) {
@@ -283,13 +262,12 @@
}
/**
- * Appends a char {@code c} to the CharArrayWriter. The method works the
- * same way as {@code write(c)}.
- *
+ * Appends a char {@code c} to the {@code CharArrayWriter}. The method works
+ * the same way as {@code write(c)}.
+ *
* @param c
* the character appended to the CharArrayWriter.
* @return this CharArrayWriter.
- * @since Android 1.0
*/
@Override
public CharArrayWriter append(char c) {
@@ -298,14 +276,14 @@
}
/**
- * Appends a CharSequence {@code csq} to the CharArrayWriter. The method
+ * Appends a {@code CharSequence} to the {@code CharArrayWriter}. The method
* works the same way as {@code write(csq.toString())}. If {@code csq} is
- * null, then it will be substituted with the string "null".
- *
+ * {@code null}, then it will be substituted with the string {@code "null"}.
+ *
* @param csq
- * the CharSequence appended to the CharArrayWriter, may be null.
+ * the {@code CharSequence} appended to the {@code
+ * CharArrayWriter}, may be {@code null}.
* @return this CharArrayWriter.
- * @since Android 1.0
*/
@Override
public CharArrayWriter append(CharSequence csq) {
@@ -318,26 +296,27 @@
}
/**
- * Append a subsequence of a CharSequence {@code csq} to the
- * CharArrayWriter. The first and last characters of the subsequence are
- * specified by the parameters {@code start} and {@code end}. The
- * CharArrayWriter.append({@code csq}) works the same way as
- * {@code CharArrayWriter.write(csq.subSequence(start, end).toString)}. If
- * {@code csq} is null, then it will be substituted with the string "null".
- *
+ * Append a subsequence of a {@code CharSequence} to the {@code
+ * CharArrayWriter}. The first and last characters of the subsequence are
+ * specified by the parameters {@code start} and {@code end}. A call to
+ * {@code CharArrayWriter.append(csq)} works the same way as {@code
+ * CharArrayWriter.write(csq.subSequence(start, end).toString)}. If {@code
+ * csq} is {@code null}, then it will be substituted with the string {@code
+ * "null"}.
+ *
* @param csq
- * the CharSequence appended to the CharArrayWriter, may be null.
+ * the {@code CharSequence} appended to the {@code
+ * CharArrayWriter}, may be {@code null}.
* @param start
- * the index of the first character in the CharSequence appended
- * to the CharArrayWriter.
+ * the index of the first character in the {@code CharSequence}
+ * appended to the {@code CharArrayWriter}.
* @param end
- * the index of the character after the last one in the
- * CharSequence appended to the CharArrayWriter.
+ * the index of the character after the last one in the {@code
+ * CharSequence} appended to the {@code CharArrayWriter}.
* @return this CharArrayWriter.
* @throws IndexOutOfBoundsException
* if {@code start < 0}, {@code end < 0}, {@code start > end},
* or if {@code end} is greater than the length of {@code csq}.
- * @since Android 1.0
*/
@Override
public CharArrayWriter append(CharSequence csq, int start, int end) {
diff --git a/luni/src/main/java/java/io/CharConversionException.java b/luni/src/main/java/java/io/CharConversionException.java
index 2247527..97dc186 100644
--- a/luni/src/main/java/java/io/CharConversionException.java
+++ b/luni/src/main/java/java/io/CharConversionException.java
@@ -19,8 +19,6 @@
/**
* The top level class for character conversion exceptions.
- *
- * @since Android 1.0
*/
public class CharConversionException extends IOException {
@@ -29,8 +27,6 @@
/**
* Constructs a new {@code CharConversionException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
public CharConversionException() {
super();
@@ -39,10 +35,9 @@
/**
* Constructs a new {@code CharConversionException} with its stack trace and
* detail message filled in.
- *
+ *
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public CharConversionException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/Closeable.java b/luni/src/main/java/java/io/Closeable.java
index 015b39a..94b6bd8 100644
--- a/luni/src/main/java/java/io/Closeable.java
+++ b/luni/src/main/java/java/io/Closeable.java
@@ -21,18 +21,15 @@
* are not used any longer. This usually includes all sorts of
* {@link InputStream}s and {@link OutputStream}s. Calling the {@code close}
* method releases resources that the object holds.
- *
- * @since Android 1.0
*/
public interface Closeable {
/**
* Closes the object and release any system resources it holds. If the
* object has already been closed, then invoking this method has no effect.
- *
+ *
* @throws IOException
* if any error occurs when closing the object.
- * @since Android 1.0
*/
public void close() throws IOException;
}
\ No newline at end of file
diff --git a/luni/src/main/java/java/io/DataInput.java b/luni/src/main/java/java/io/DataInput.java
index a199d2f..02a28d9 100644
--- a/luni/src/main/java/java/io/DataInput.java
+++ b/luni/src/main/java/java/io/DataInput.java
@@ -23,13 +23,12 @@
* {@link DataOutput}. Types that can be read include byte, 16-bit short, 32-bit
* int, 32-bit float, 64-bit long, 64-bit double, byte strings, and MUTF-8
* strings.
- *
+ *
* <h3>MUTF-8 (Modified UTF-8) Encoding</h3>
* <p>
* When encoding strings as UTF, implementations of {@code DataInput} and
* {@code DataOutput} use a slightly modified form of UTF-8, hereafter referred
* to as MUTF-8. This form is identical to standard UTF-8, except:
- * </p>
* <ul>
* <li>Only the one-, two-, and three-byte encodings are used.</li>
* <li>Code points in the range <code>U+10000</code> …
@@ -42,12 +41,9 @@
* further information about character encoding. MUTF-8 is actually closer to
* the (relatively less well-known) encoding <a
* href="http://www.unicode.org/reports/tr26/">CESU-8</a> than to UTF-8 per se.
- * </p>
- *
+ *
* @see DataInputStream
* @see RandomAccessFile
- *
- * @since Android 1.0
*/
public interface DataInput {
/**
@@ -59,7 +55,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeBoolean(boolean)
- * @since Android 1.0
*/
public abstract boolean readBoolean() throws IOException;
@@ -72,7 +67,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeByte(int)
- * @since Android 1.0
*/
public abstract byte readByte() throws IOException;
@@ -85,7 +79,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeChar(int)
- * @since Android 1.0
*/
public abstract char readChar() throws IOException;
@@ -98,7 +91,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeDouble(double)
- * @since Android 1.0
*/
public abstract double readDouble() throws IOException;
@@ -111,7 +103,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeFloat(float)
- * @since Android 1.0
*/
public abstract float readFloat() throws IOException;
@@ -127,7 +118,6 @@
* if an I/O error occurs while reading.
* @see DataOutput#write(byte[])
* @see DataOutput#write(byte[], int, int)
- * @since Android 1.0
*/
public abstract void readFully(byte[] buffer) throws IOException;
@@ -149,7 +139,6 @@
* if an I/O error occurs while reading.
* @see DataOutput#write(byte[])
* @see DataOutput#write(byte[], int, int)
- * @since Android 1.0
*/
public abstract void readFully(byte[] buffer, int offset, int count)
throws IOException;
@@ -163,7 +152,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeInt(int)
- * @since Android 1.0
*/
public abstract int readInt() throws IOException;
@@ -179,7 +167,6 @@
* request can be satisfied.
* @throws IOException
* if an I/O error occurs while reading.
- * @since Android 1.0
*/
public abstract String readLine() throws IOException;
@@ -192,7 +179,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeLong(long)
- * @since Android 1.0
*/
public abstract long readLong() throws IOException;
@@ -205,7 +191,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeShort(int)
- * @since Android 1.0
*/
public abstract short readShort() throws IOException;
@@ -218,7 +203,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeByte(int)
- * @since Android 1.0
*/
public abstract int readUnsignedByte() throws IOException;
@@ -231,7 +215,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeShort(int)
- * @since Android 1.0
*/
public abstract int readUnsignedShort() throws IOException;
@@ -244,7 +227,6 @@
* @throws IOException
* if an I/O error occurs while reading.
* @see DataOutput#writeUTF(java.lang.String)
- * @since Android 1.0
*/
public abstract String readUTF() throws IOException;
@@ -258,7 +240,6 @@
* @return the number of bytes actually skipped.
* @throws IOException
* if a problem occurs during skipping.
- * @since Android 1.0
*/
public abstract int skipBytes(int count) throws IOException;
}
diff --git a/luni/src/main/java/java/io/DataInputStream.java b/luni/src/main/java/java/io/DataInputStream.java
index 88b10a5..42e38a2 100644
--- a/luni/src/main/java/java/io/DataInputStream.java
+++ b/luni/src/main/java/java/io/DataInputStream.java
@@ -21,38 +21,38 @@
import org.apache.harmony.luni.util.Util;
/**
- * Wraps an existing {@link InputStream} and reads typed data from it.
+ * Wraps an existing {@link InputStream} and reads typed data from it.
* Typically, this stream has been written by a DataOutputStream. Types that can
* be read include byte, 16-bit short, 32-bit int, 32-bit float, 64-bit long,
* 64-bit double, byte strings, and strings encoded in
* {@link DataInput modified UTF-8}.
- *
+ *
* @see DataOutputStream
- *
- * @since Android 1.0
*/
public class DataInputStream extends FilterInputStream implements DataInput {
+ byte[] buff;
+
/**
* Constructs a new DataInputStream on the InputStream {@code in}. All
* reads are then filtered through this stream. Note that data read by this
* stream is not in a human readable format and was most likely created by a
* DataOutputStream.
- *
+ *
* @param in
* the source InputStream the filter reads from.
* @see DataOutputStream
* @see RandomAccessFile
- * @since Android 1.0
*/
public DataInputStream(InputStream in) {
super(in);
+ buff = new byte[8];
}
/**
* Reads bytes from this stream into the byte array {@code buffer}. Returns
* the number of bytes that have been read.
- *
+ *
* @param buffer
* the buffer to read bytes into.
* @return the number of bytes that have been read or -1 if the end of the
@@ -61,7 +61,6 @@
* if a problem occurs while reading from this stream.
* @see DataOutput#write(byte[])
* @see DataOutput#write(byte[], int, int)
- * @since Android 1.0
*/
@Override
public final int read(byte[] buffer) throws IOException {
@@ -73,7 +72,7 @@
* the byte array {@code buffer} starting at {@code offset}. Returns the
* number of bytes that have been read or -1 if no bytes have been read and
* the end of the stream has been reached.
- *
+ *
* @param buffer
* the byte array in which to store the bytes read.
* @param offset
@@ -87,7 +86,6 @@
* if a problem occurs while reading from this stream.
* @see DataOutput#write(byte[])
* @see DataOutput#write(byte[], int, int)
- * @since Android 1.0
*/
@Override
public final int read(byte[] buffer, int offset, int length)
@@ -97,7 +95,7 @@
/**
* Reads a boolean from this stream.
- *
+ *
* @return the next boolean value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before one byte
@@ -105,7 +103,6 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeBoolean(boolean)
- * @since Android 1.0
*/
public final boolean readBoolean() throws IOException {
int temp = in.read();
@@ -117,7 +114,7 @@
/**
* Reads an 8-bit byte value from this stream.
- *
+ *
* @return the next byte value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before one byte
@@ -125,7 +122,6 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeByte(int)
- * @since Android 1.0
*/
public final byte readByte() throws IOException {
int temp = in.read();
@@ -137,7 +133,7 @@
/**
* Reads a 16-bit character value from this stream.
- *
+ *
* @return the next char value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before two bytes
@@ -145,20 +141,29 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeChar(int)
- * @since Android 1.0
*/
public final char readChar() throws IOException {
- int b1 = in.read();
- int b2 = in.read();
- if ((b1 | b2) < 0) {
+ if (readToBuff(2) < 0){
throw new EOFException();
}
- return (char) ((b1 << 8) + b2);
+ return (char) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
+
+ }
+
+ private int readToBuff(int count) throws IOException {
+ int offset = 0;
+
+ while(offset < count) {
+ int bytesRead = in.read(buff, offset, count - offset);
+ if(bytesRead == -1) return bytesRead;
+ offset += bytesRead;
+ }
+ return offset;
}
/**
* Reads a 64-bit double value from this stream.
- *
+ *
* @return the next double value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before eight
@@ -166,7 +171,6 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeDouble(double)
- * @since Android 1.0
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
@@ -174,7 +178,7 @@
/**
* Reads a 32-bit float value from this stream.
- *
+ *
* @return the next float value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before four
@@ -182,7 +186,6 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeFloat(float)
- * @since Android 1.0
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
@@ -192,7 +195,7 @@
* Reads bytes from this stream into the byte array {@code buffer}. This
* method will block until {@code buffer.length} number of bytes have been
* read.
- *
+ *
* @param buffer
* to read bytes into.
* @throws EOFException
@@ -202,7 +205,6 @@
* if a problem occurs while reading from this stream.
* @see DataOutput#write(byte[])
* @see DataOutput#write(byte[], int, int)
- * @since Android 1.0
*/
public final void readFully(byte[] buffer) throws IOException {
readFully(buffer, 0, buffer.length);
@@ -213,7 +215,7 @@
* buffer} starting at the position {@code offset}. This method blocks until
* {@code length} bytes have been read. If {@code length} is zero, then this
* method returns without reading any bytes.
- *
+ *
* @param buffer
* the byte array into which the data is read.
* @param offset
@@ -232,7 +234,6 @@
* @throws NullPointerException
* if {@code buffer} or the source stream are null.
* @see java.io.DataInput#readFully(byte[], int, int)
- * @since Android 1.0
*/
public final void readFully(byte[] buffer, int offset, int length)
throws IOException {
@@ -271,7 +272,7 @@
/**
* Reads a 32-bit integer value from this stream.
- *
+ *
* @return the next int value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before four
@@ -279,25 +280,13 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeInt(int)
- * @since Android 1.0
*/
public final int readInt() throws IOException {
- // BEGIN android-changed
- byte[] buf = new byte[4];
- int nread = 0;
- while (nread < 4) {
- int nbytes = in.read(buf, nread, 4 - nread);
- if (nbytes == -1) {
- throw new EOFException();
- }
- nread += nbytes;
+ if (readToBuff(4) < 0){
+ throw new EOFException();
}
- int b1 = buf[0] & 0xff;
- int b2 = buf[1] & 0xff;
- int b3 = buf[2] & 0xff;
- int b4 = buf[3] & 0xff;
- return ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
- // END android-changed
+ return ((buff[0] & 0xff) << 24) | ((buff[1] & 0xff) << 16) |
+ ((buff[2] & 0xff) << 8) | (buff[3] & 0xff);
}
/**
@@ -305,13 +294,12 @@
* source stream. A line is represented by zero or more characters followed
* by {@code '\n'}, {@code '\r'}, {@code "\r\n"} or the end of the stream.
* The string does not include the newline sequence.
- *
+ *
* @return the contents of the line or {@code null} if no characters were
* read before the end of the source stream has been reached.
* @throws IOException
* if a problem occurs while reading from this stream.
* @deprecated Use {@link BufferedReader}
- * @since Android 1.0
*/
@Deprecated
public final String readLine() throws IOException {
@@ -350,7 +338,7 @@
/**
* Reads a 64-bit long value from this stream.
- *
+ *
* @return the next long value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before eight
@@ -358,24 +346,22 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeLong(long)
- * @since Android 1.0
*/
public final long readLong() throws IOException {
- int i1 = readInt();
- int b1 = in.read();
- int b2 = in.read();
- int b3 = in.read();
- int b4 = in.read();
- if ((b1 | b2 | b3 | b4) < 0) {
+ if (readToBuff(8) < 0){
throw new EOFException();
}
- return (((long) i1) << 32) + ((long) b1 << 24) + (b2 << 16) + (b3 << 8)
- + b4;
+ int i1 = ((buff[0] & 0xff) << 24) | ((buff[1] & 0xff) << 16) |
+ ((buff[2] & 0xff) << 8) | (buff[3] & 0xff);
+ int i2 = ((buff[4] & 0xff) << 24) | ((buff[5] & 0xff) << 16) |
+ ((buff[6] & 0xff) << 8) | (buff[7] & 0xff);
+
+ return ((i1 & 0xffffffffL) << 32) | (i2 & 0xffffffffL);
}
/**
* Reads a 16-bit short value from this stream.
- *
+ *
* @return the next short value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before two bytes
@@ -383,29 +369,18 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeShort(int)
- * @since Android 1.0
*/
public final short readShort() throws IOException {
- // BEGIN android-changed
- byte[] buf = new byte[2];
- int nread = 0;
- while (nread < 2) {
- int nbytes = in.read(buf, nread, 2 - nread);
- if (nbytes == -1) {
- throw new EOFException();
- }
- nread += nbytes;
+ if (readToBuff(2) < 0){
+ throw new EOFException();
}
- int b1 = buf[0] & 0xff;
- int b2 = buf[1] & 0xff;
- return (short) ((b1 << 8) + b2);
- // END android-changed
+ return (short) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
}
/**
* Reads an unsigned 8-bit byte value from this stream and returns it as an
* int.
- *
+ *
* @return the next unsigned byte value from the source stream.
* @throws EOFException
* if the end of the filtered stream has been reached before one
@@ -413,7 +388,6 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeByte(int)
- * @since Android 1.0
*/
public final int readUnsignedByte() throws IOException {
int temp = in.read();
@@ -426,7 +400,7 @@
/**
* Reads a 16-bit unsigned short value from this stream and returns it as an
* int.
- *
+ *
* @return the next unsigned short value from the source stream.
* @throws EOFException
* if the end of the filtered stream is reached before two bytes
@@ -434,21 +408,18 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeShort(int)
- * @since Android 1.0
*/
public final int readUnsignedShort() throws IOException {
- int b1 = in.read();
- int b2 = in.read();
- if ((b1 | b2) < 0) {
+ if (readToBuff(2) < 0){
throw new EOFException();
}
- return ((b1 << 8) + b2);
+ return (char) (((buff[0] & 0xff) << 8) | (buff[1] & 0xff));
}
/**
* Reads an string encoded in {@link DataInput modified UTF-8} from this
* stream.
- *
+ *
* @return the next {@link DataInput MUTF-8} encoded string read from the
* source stream.
* @throws EOFException if the end of the input is reached before the read
@@ -456,90 +427,28 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutput#writeUTF(java.lang.String)
- * @since Android 1.0
*/
public final String readUTF() throws IOException {
- int utfSize = readUnsignedShort();
- return decodeUTF(utfSize);
+ return decodeUTF(readUnsignedShort());
}
- // BEGIN android-removed
- // static final int MAX_BUF_SIZE = 8192;
- //
- // private static class CacheLock {
- // }
- //
- // static final Object cacheLock = new CacheLock();
- //
- // static boolean useShared = true;
- //
- // static byte[] byteBuf = new byte[0];
- //
- // static char[] charBuf = new char[0];
- // END android-removed
String decodeUTF(int utfSize) throws IOException {
- // BEGIN android-removed
- // byte[] buf;
- // char[] out = null;
- // boolean makeBuf = true;
- //
- // /*
- // * Try to avoid the synchronization -- if we get a stale value for
- // * useShared then there is no foul below, but those that sync on the
- // * lock must see the right value.
- // */
- // if (utfSize <= MAX_BUF_SIZE && useShared) {
- // synchronized (cacheLock) {
- // if (useShared) {
- // useShared = false;
- // makeBuf = false;
- // }
- // }
- // }
- // if (makeBuf) {
- // buf = new byte[utfSize];
- // out = new char[utfSize];
- // } else {
- // /*
- // * Need to 'sample' byteBuf and charBuf before using them because
- // * they are not protected by the cacheLock. They may get out of sync
- // * with the static and one another, but that is ok because we
- // * explicitly check and fix their length after sampling.
- // */
- // buf = byteBuf;
- // if (buf.length < utfSize) {
- // buf = byteBuf = new byte[utfSize];
- // }
- // out = charBuf;
- // if (out.length < utfSize) {
- // out = charBuf = new char[utfSize];
- // }
- // }
- // END android-removed
- // BEGIN android-added
+ return decodeUTF(utfSize, this);
+ }
+
+ private static String decodeUTF(int utfSize, DataInput in) throws IOException {
byte[] buf = new byte[utfSize];
char[] out = new char[utfSize];
- // END android-added
- readFully(buf, 0, utfSize);
- String result;
- result = Util.convertUTF8WithBuf(buf, out, 0, utfSize);
- // BEGIN android-removed
- // if (!makeBuf) {
- // /*
- // * Do not synchronize useShared on cacheLock, it will make it back
- // * to main storage at some point, and no harm until it does.
- // */
- // useShared = true;
- // }
- //END android-removed
- return result;
+ in.readFully(buf, 0, utfSize);
+
+ return Util.convertUTF8WithBuf(buf, out, 0, utfSize);
}
/**
* Reads a string encoded in {@link DataInput modified UTF-8} from the
* {@code DataInput} stream {@code in}.
- *
+ *
* @param in
* the input stream to read from.
* @return the next {@link DataInput MUTF-8} encoded string from the source
@@ -547,19 +456,18 @@
* @throws IOException
* if a problem occurs while reading from this stream.
* @see DataOutputStream#writeUTF(java.lang.String)
- * @since Android 1.0
*/
public static final String readUTF(DataInput in) throws IOException {
- return in.readUTF();
+ return decodeUTF(in.readUnsignedShort(), in);
}
/**
* Skips {@code count} number of bytes in this stream. Subsequent {@code
* read()}s will not return these bytes unless {@code reset()} is used.
- *
+ *
* This method will not throw an {@link EOFException} if the end of the
* input is reached before {@code count} bytes where skipped.
- *
+ *
* @param count
* the number of bytes to skip.
* @return the number of bytes actually skipped.
@@ -567,7 +475,6 @@
* if a problem occurs during skipping.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
public final int skipBytes(int count) throws IOException {
int skipped = 0;
diff --git a/luni/src/main/java/java/io/DataOutput.java b/luni/src/main/java/java/io/DataOutput.java
index d028a18..8275958 100644
--- a/luni/src/main/java/java/io/DataOutput.java
+++ b/luni/src/main/java/java/io/DataOutput.java
@@ -23,35 +23,29 @@
* DataInput. Types that can be written include byte, 16-bit short, 32-bit int,
* 32-bit float, 64-bit long, 64-bit double, byte strings, and {@link DataInput
* MUTF-8} encoded strings.
- *
+ *
* @see DataOutputStream
* @see RandomAccessFile
- *
- * @since Android 1.0
*/
public interface DataOutput {
/**
* Writes the entire contents of the byte array {@code buffer} to this
* stream.
- *
+ *
* @param buffer
* the buffer to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readFully(byte[])
* @see DataInput#readFully(byte[], int, int)
- * @since Android 1.0
*/
public abstract void write(byte[] buffer) throws IOException;
- // BEGIN android-note
- // changed array notation to be consistent with the rest of harmony
- // END android-note
/**
* Writes {@code count} bytes from the byte array {@code buffer} starting at
* offset {@code index}.
- *
+ *
* @param buffer
* the buffer to write.
* @param offset
@@ -62,7 +56,6 @@
* if an I/O error occurs while writing.
* @see DataInput#readFully(byte[])
* @see DataInput#readFully(byte[], int, int)
- * @since Android 1.0
*/
public abstract void write(byte[] buffer, int offset, int count) throws IOException;
// BEGIN android-note
@@ -71,51 +64,47 @@
/**
* Writes the specified 8-bit byte.
- *
+ *
* @param oneByte
* the byte to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readByte()
- * @since Android 1.0
*/
public abstract void write(int oneByte) throws IOException;
/**
* Writes the specified boolean.
- *
+ *
* @param val
* the boolean value to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readBoolean()
- * @since Android 1.0
*/
public abstract void writeBoolean(boolean val) throws IOException;
/**
* Writes the specified 8-bit byte.
- *
+ *
* @param val
* the byte value to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readByte()
* @see DataInput#readUnsignedByte()
- * @since Android 1.0
*/
public abstract void writeByte(int val) throws IOException;
/**
* Writes the low order 8-bit bytes from the specified string.
- *
+ *
* @param str
* the string containing the bytes to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readFully(byte[])
* @see DataInput#readFully(byte[],int,int)
- * @since Android 1.0
*/
public abstract void writeBytes(String str) throws IOException;
@@ -123,106 +112,95 @@
* Writes the specified 16-bit character. Only the two least significant
* bytes of the integer {@code oneByte} are written, with the higher one
* written first. This represents the Unicode value of the char.
- *
+ *
* @param val
* the character to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readChar()
- * @since Android 1.0
*/
public abstract void writeChar(int val) throws IOException;
- // BEGIN android-note
- // renamed parameter because it was misleading
- // END android-note
/**
* Writes the 16-bit characters contained in {@code str}.
- *
+ *
* @param str
* the string that contains the characters to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readChar()
- * @since Android 1.0
*/
public abstract void writeChars(String str) throws IOException;
/**
* Writes the specified 64-bit double. The resulting output is the eight
* bytes returned by {@link Double#doubleToLongBits(double)}.
- *
+ *
* @param val
* the double to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readDouble()
- * @since Android 1.0
*/
public abstract void writeDouble(double val) throws IOException;
/**
* Writes the specified 32-bit float. The resulting output is the four bytes
* returned by {@link Float#floatToIntBits(float)}.
- *
+ *
* @param val
* the float to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readFloat()
- * @since Android 1.0
*/
public abstract void writeFloat(float val) throws IOException;
/**
* Writes the specified 32-bit int. The resulting output is the four bytes,
* highest order first, of {@code val}.
- *
+ *
* @param val
* the int to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readInt()
- * @since Android 1.0
*/
public abstract void writeInt(int val) throws IOException;
/**
* Writes the specified 64-bit long. The resulting output is the eight
* bytes, highest order first, of {@code val}.
- *
+ *
* @param val
* the long to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readLong()
- * @since Android 1.0
*/
public abstract void writeLong(long val) throws IOException;
/**
* Writes the specified 16-bit short. Only the lower two bytes of {@code
* val} are written with the higher one written first.
- *
+ *
* @param val
* the short to write.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readShort()
* @see DataInput#readUnsignedShort()
- * @since Android 1.0
*/
public abstract void writeShort(int val) throws IOException;
/**
* Writes the specified string encoded in {@link DataInput modified UTF-8}.
- *
+ *
* @param str
* the string to write encoded in {@link DataInput modified UTF-8}.
* @throws IOException
* if an I/O error occurs while writing.
* @see DataInput#readUTF()
- * @since Android 1.0
*/
public abstract void writeUTF(String str) throws IOException;
}
diff --git a/luni/src/main/java/java/io/DataOutputStream.java b/luni/src/main/java/java/io/DataOutputStream.java
index 7f45c58..18e04a5 100644
--- a/luni/src/main/java/java/io/DataOutputStream.java
+++ b/luni/src/main/java/java/io/DataOutputStream.java
@@ -24,41 +24,37 @@
* Typically, this stream can be read in by DataInputStream. Types that can be
* written include byte, 16-bit short, 32-bit int, 32-bit float, 64-bit long,
* 64-bit double, byte strings, and {@link DataInput MUTF-8} encoded strings.
- *
+ *
* @see DataInputStream
- *
- * @since Android 1.0
*/
public class DataOutputStream extends FilterOutputStream implements DataOutput {
/**
* The number of bytes written out so far.
- *
- * @since Android 1.0
*/
protected int written;
+ byte buff[];
/**
* Constructs a new {@code DataOutputStream} on the {@code OutputStream}
* {@code out}. Note that data written by this stream is not in a human
* readable form but can be reconstructed by using a {@link DataInputStream}
* on the resulting output.
- *
+ *
* @param out
* the target stream for writing.
- * @since Android 1.0
*/
public DataOutputStream(OutputStream out) {
super(out);
+ buff = new byte[8];
}
/**
* Flushes this stream to ensure all pending data is sent out to the target
* stream. This implementation then also flushes the target stream.
- *
+ *
* @throws IOException
* if an error occurs attempting to flush this stream.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -67,9 +63,8 @@
/**
* Returns the total number of bytes written to the target stream so far.
- *
+ *
* @return the number of bytes written to the target stream.
- * @since Android 1.0
*/
public final int size() {
if (written < 0) {
@@ -81,7 +76,7 @@
/**
* Writes {@code count} bytes from the byte array {@code buffer} starting at
* {@code offset} to the target stream.
- *
+ *
* @param buffer
* the buffer to write to the target stream.
* @param offset
@@ -94,7 +89,6 @@
* if {@code buffer} is {@code null}.
* @see DataInputStream#readFully(byte[])
* @see DataInputStream#readFully(byte[], int, int)
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
@@ -111,13 +105,12 @@
/**
* Writes a byte to the target stream. Only the least significant byte of
* the integer {@code oneByte} is written.
- *
+ *
* @param oneByte
* the byte to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readByte()
- * @since Android 1.0
*/
@Override
public void write(int oneByte) throws IOException {
@@ -127,13 +120,12 @@
/**
* Writes a boolean to the target stream.
- *
+ *
* @param val
* the boolean value to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readBoolean()
- * @since Android 1.0
*/
public final void writeBoolean(boolean val) throws IOException {
out.write(val ? 1 : 0);
@@ -143,14 +135,13 @@
/**
* Writes an 8-bit byte to the target stream. Only the least significant
* byte of the integer {@code val} is written.
- *
+ *
* @param val
* the byte value to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readByte()
* @see DataInputStream#readUnsignedByte()
- * @since Android 1.0
*/
public final void writeByte(int val) throws IOException {
out.write(val);
@@ -159,14 +150,13 @@
/**
* Writes the low order bytes from a string to the target stream.
- *
+ *
* @param str
* the string containing the bytes to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readFully(byte[])
* @see DataInputStream#readFully(byte[],int,int)
- * @since Android 1.0
*/
public final void writeBytes(String str) throws IOException {
if (str.length() == 0) {
@@ -184,31 +174,30 @@
* Writes a 16-bit character to the target stream. Only the two lower bytes
* of the integer {@code val} are written, with the higher one written
* first. This corresponds to the Unicode value of {@code val}.
- *
+ *
* @param val
* the character to write to the target stream
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readChar()
- * @since Android 1.0
*/
public final void writeChar(int val) throws IOException {
- out.write(val >> 8);
- out.write(val);
+ buff[0] = (byte) (val >> 8);
+ buff[1] = (byte) val;
+ out.write(buff, 0, 2);
written += 2;
}
/**
* Writes the 16-bit characters contained in {@code str} to the target
* stream.
- *
+ *
* @param str
* the string that contains the characters to write to this
* stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readChar()
- * @since Android 1.0
*/
public final void writeChars(String str) throws IOException {
byte newBytes[] = new byte[str.length() * 2];
@@ -224,13 +213,12 @@
/**
* Writes a 64-bit double to the target stream. The resulting output is the
* eight bytes resulting from calling Double.doubleToLongBits().
- *
+ *
* @param val
* the double to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readDouble()
- * @since Android 1.0
*/
public final void writeDouble(double val) throws IOException {
writeLong(Double.doubleToLongBits(val));
@@ -239,13 +227,12 @@
/**
* Writes a 32-bit float to the target stream. The resulting output is the
* four bytes resulting from calling Float.floatToIntBits().
- *
+ *
* @param val
* the float to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readFloat()
- * @since Android 1.0
*/
public final void writeFloat(float val) throws IOException {
writeInt(Float.floatToIntBits(val));
@@ -254,63 +241,68 @@
/**
* Writes a 32-bit int to the target stream. The resulting output is the
* four bytes, highest order first, of {@code val}.
- *
+ *
* @param val
* the int to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readInt()
- * @since Android 1.0
*/
public final void writeInt(int val) throws IOException {
- out.write(val >> 24);
- out.write(val >> 16);
- out.write(val >> 8);
- out.write(val);
+ buff[0] = (byte) (val >> 24);
+ buff[1] = (byte) (val >> 16);
+ buff[2] = (byte) (val >> 8);
+ buff[3] = (byte) val;
+ out.write(buff, 0, 4);
written += 4;
}
/**
* Writes a 64-bit long to the target stream. The resulting output is the
* eight bytes, highest order first, of {@code val}.
- *
+ *
* @param val
* the long to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readLong()
- * @since Android 1.0
*/
public final void writeLong(long val) throws IOException {
- writeInt((int) (val >> 32));
- writeInt((int) val);
+ buff[0] = (byte) (val >> 56);
+ buff[1] = (byte) (val >> 48);
+ buff[2] = (byte) (val >> 40);
+ buff[3] = (byte) (val >> 32);
+ buff[4] = (byte) (val >> 24);
+ buff[5] = (byte) (val >> 16);
+ buff[6] = (byte) (val >> 8);
+ buff[7] = (byte) val;
+ out.write(buff, 0, 8);
+ written += 8;
}
/**
* Writes the specified 16-bit short to the target stream. Only the lower
* two bytes of the integer {@code val} are written, with the higher one
* written first.
- *
+ *
* @param val
* the short to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see DataInputStream#readShort()
* @see DataInputStream#readUnsignedShort()
- * @since Android 1.0
*/
public final void writeShort(int val) throws IOException {
- writeChar(val);
+ buff[0] = (byte) (val >> 8);
+ buff[1] = (byte) val;
+ out.write(buff, 0, 2);
+ written += 2;
}
-
- // BEGIN android-added
- static final int MAX_BUF_SIZE = 8192;
- // END android-added
-
+
/**
* Writes the specified encoded in {@link DataInput modified UTF-8} to this
* stream.
- *
+ *
* @param str
* the string to write to the target stream encoded in
* {@link DataInput modified UTF-8}.
@@ -319,58 +311,14 @@
* @throws UTFDataFormatException
* if the encoded string is longer than 65535 bytes.
* @see DataInputStream#readUTF()
- * @since Android 1.0
*/
public final void writeUTF(String str) throws IOException {
- int length = str.length();
- // BEGIN android-changed
- if (length <= MAX_BUF_SIZE / 3) {
- int size = length * 3;
- byte[] utfBytes = new byte[size];
- // boolean makeBuf = true;
- // synchronized (DataInputStream.byteBuf) {
- // if (DataInputStream.useShared) {
- // DataInputStream.useShared = false;
- // makeBuf = false;
- // }
- // }
- // if (makeBuf) {
- // utfBytes = new byte[size];
- // } else {
- // if (DataInputStream.byteBuf.length < size) {
- // DataInputStream.byteBuf = new byte[size];
- // }
- // utfBytes = DataInputStream.byteBuf;
- // }
- int utfIndex = 0;
- for (int i = 0; i < length; i++) {
- int charValue = str.charAt(i);
- if (charValue > 0 && charValue <= 127) {
- utfBytes[utfIndex++] = (byte) charValue;
- } else if (charValue <= 2047) {
- utfBytes[utfIndex++] = (byte) (0xc0 | (0x1f & (charValue >> 6)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
- } else {
- utfBytes[utfIndex++] = (byte) (0xe0 | (0x0f & (charValue >> 12)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & (charValue >> 6)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
- }
- }
- writeShort(utfIndex);
- write(utfBytes, 0, utfIndex);
- // if (!makeBuf) {
- // DataInputStream.useShared = true;
- // }
- } else {
- long utfCount;
- if (length <= 65535 && (utfCount = countUTFBytes(str)) <= 65535) {
- writeShort((int) utfCount);
- writeUTFBytes(str, utfCount);
- } else {
- throw new UTFDataFormatException(Msg.getString("K0068")); //$NON-NLS-1$
- }
+ long utfCount = countUTFBytes(str);
+ if (utfCount > 65535) {
+ throw new UTFDataFormatException(Msg.getString("K0068")); //$NON-NLS-1$
}
- // END android-changed
+ writeShort((int) utfCount);
+ writeUTFBytes(str, utfCount);
}
long countUTFBytes(String str) {
@@ -389,76 +337,23 @@
}
void writeUTFBytes(String str, long count) throws IOException {
- boolean single = true;
int size = (int) count;
- // BEGIN android-changed
- if (count > MAX_BUF_SIZE) {
- single = false;
- size = MAX_BUF_SIZE;
- }
+ int length = str.length();
byte[] utfBytes = new byte[size];
- // END android-changed
- // BEGIN android-removed
- // boolean makeBuf = true;
- // if (DataInputStream.useShared) {
- // synchronized (DataInputStream.cacheLock) {
- // if (DataInputStream.useShared) {
- // DataInputStream.useShared = false;
- // makeBuf = false;
- // }
- // }
- // }
- // if (makeBuf) {
- // utfBytes = new byte[size];
- // } else {
- // // byteBuf is not protected by the cacheLock, so sample it first
- // utfBytes = DataInputStream.byteBuf;
- // if (utfBytes.length < size) {
- // utfBytes = DataInputStream.byteBuf = new byte[size];
- // }
- // }
- // END android-removed
-
- int utfIndex = 0, i = 0, length = str.length();
- int end = length;
- while (i < length) {
- if (!single) {
- end = i + ((utfBytes.length - utfIndex) / 3);
- if (end > length) {
- end = length;
- }
- }
- for (int j = i; j < end; j++) {
- int charValue = str.charAt(j);
- if (charValue > 0 && charValue <= 127) {
- utfBytes[utfIndex++] = (byte) charValue;
- } else if (charValue <= 2047) {
- utfBytes[utfIndex++] = (byte) (0xc0 | (0x1f & (charValue >> 6)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
- } else {
- utfBytes[utfIndex++] = (byte) (0xe0 | (0x0f & (charValue >> 12)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & (charValue >> 6)));
- utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
- }
- }
- if (single || utfIndex > utfBytes.length - 300) {
- write(utfBytes, 0, utfIndex);
- if (single) {
- return;
- }
- utfIndex = 0;
- }
- i = end;
+ int utfIndex = 0;
+ for (int i = 0; i < length; i++) {
+ int charValue = str.charAt(i);
+ if (charValue > 0 && charValue <= 127) {
+ utfBytes[utfIndex++] = (byte) charValue;
+ } else if (charValue <= 2047) {
+ utfBytes[utfIndex++] = (byte) (0xc0 | (0x1f & (charValue >> 6)));
+ utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
+ } else {
+ utfBytes[utfIndex++] = (byte) (0xe0 | (0x0f & (charValue >> 12)));
+ utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & (charValue >> 6)));
+ utfBytes[utfIndex++] = (byte) (0x80 | (0x3f & charValue));
+ }
}
- if (utfIndex > 0) {
- write(utfBytes, 0, utfIndex);
- }
- // BEGIN android-removed
- // if (!makeBuf) {
- // // Update the useShared flag optimistically (see DataInputStream
- // // equivalent)
- // DataInputStream.useShared = true;
- // }
- // END android-removed
+ write(utfBytes, 0, utfIndex);
}
}
diff --git a/luni/src/main/java/java/io/EOFException.java b/luni/src/main/java/java/io/EOFException.java
index 40beadd..7999f43 100644
--- a/luni/src/main/java/java/io/EOFException.java
+++ b/luni/src/main/java/java/io/EOFException.java
@@ -20,8 +20,6 @@
/**
* Thrown when a program encounters the end of a file or stream during an input
* operation.
- *
- * @since Android 1.0
*/
public class EOFException extends IOException {
@@ -29,8 +27,6 @@
/**
* Constructs a new {@code EOFException} with its stack trace filled in.
- *
- * @since Android 1.0
*/
public EOFException() {
super();
@@ -42,7 +38,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public EOFException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/EmulatedFields.java b/luni/src/main/java/java/io/EmulatedFields.java
index 4ef241d..a947a52 100644
--- a/luni/src/main/java/java/io/EmulatedFields.java
+++ b/luni/src/main/java/java/io/EmulatedFields.java
@@ -103,17 +103,18 @@
}
/**
- * Return a boolean indicating if the field named <code>name</code> has
- * been assigned a value explicitly (false) or if it still holds a default
- * value for the type (true) because it hasn't been assigned to yet.
+ * Returns {@code true} indicating the field called {@code name} has not had
+ * a value explicitly assigned and that it still holds a default value for
+ * its type, or {@code false} indicating that the field named has been
+ * assigned a value explicitly.
*
* @param name
- * a String, the name of the field to test
- * @return <code>true</code> if <code>name</code> still holds its
- * default value, <code>false</code> otherwise
+ * the name of the field to test.
+ * @return {@code true} if {@code name} still holds its default value,
+ * {@code false} otherwise
*
* @throws IllegalArgumentException
- * If <code>name</code> is null
+ * if {@code name} is {@code null}
*/
public boolean defaulted(String name) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, null);
@@ -124,23 +125,23 @@
}
/**
- * Find and return an ObjectSlot that corresponds to a field named
- * <code>fieldName</code> and type <code>fieldType</code>. If the field
- * type <code>fieldType</code> corresponds to a primitive type, the field
- * type has to match exactly or <code>null</code> is returned. If the
- * field type <code>fieldType</code> corresponds to an object type, the
- * field type has to be compatible in terms of assignment, or null is
- * returned. If <code>fieldType</code> is <code>null</code>, no such
- * compatibility checking is performed and the slot is returned.
+ * Finds and returns an ObjectSlot that corresponds to a field named {@code
+ * fieldName} and type {@code fieldType}. If the field type {@code
+ * fieldType} corresponds to a primitive type, the field type has to match
+ * exactly or {@code null} is returned. If the field type {@code fieldType}
+ * corresponds to an object type, the field type has to be compatible in
+ * terms of assignment, or null is returned. If {@code fieldType} is {@code
+ * null}, no such compatibility checking is performed and the slot is
+ * returned.
*
* @param fieldName
- * A String, the name of the field to find
+ * the name of the field to find
* @param fieldType
- * A Class, the type of the field. This will be used to test
- * compatibility. If null, no testing is done, the corresponding
- * slot is returned.
- * @return If there is no field with that name, or no compatible field
- * (relative to <code>fieldType</code>)
+ * the type of the field. This will be used to test
+ * compatibility. If {@code null}, no testing is done, the
+ * corresponding slot is returned.
+ * @return the object slot, or {@code null} if there is no field with that
+ * name, or no compatible field (relative to {@code fieldType})
*/
private ObjectSlot findSlot(String fieldName, Class<?> fieldType) {
boolean isPrimitive = fieldType != null && fieldType.isPrimitive();
@@ -187,19 +188,19 @@
}
/**
- * Find and return the byte value of a given field named <code>name</code>
+ * Finds and returns the byte value of a given field named {@code name}
* in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * default value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public byte get(String name, byte defaultValue)
throws IllegalArgumentException {
@@ -213,19 +214,19 @@
}
/**
- * Find and return the char value of a given field named <code>name</code>
- * in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * Finds and returns the char value of a given field named {@code name} in the
+ * receiver. If the field has not been assigned any value yet, the default
+ * value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public char get(String name, char defaultValue)
throws IllegalArgumentException {
@@ -239,19 +240,19 @@
}
/**
- * Find and return the double value of a given field named <code>name</code>
+ * Finds and returns the double value of a given field named {@code name}
* in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * default value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public double get(String name, double defaultValue)
throws IllegalArgumentException {
@@ -265,19 +266,19 @@
}
/**
- * Find and return the float value of a given field named <code>name</code>
- * in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * Finds and returns the float value of a given field named {@code name} in
+ * the receiver. If the field has not been assigned any value yet, the
+ * default value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public float get(String name, float defaultValue)
throws IllegalArgumentException {
@@ -291,19 +292,19 @@
}
/**
- * Find and return the int value of a given field named <code>name</code>
- * in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * Finds and returns the int value of a given field named {@code name} in the
+ * receiver. If the field has not been assigned any value yet, the default
+ * value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public int get(String name, int defaultValue)
throws IllegalArgumentException {
@@ -317,19 +318,19 @@
}
/**
- * Find and return the long value of a given field named <code>name</code>
- * in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * Finds and returns the long value of a given field named {@code name} in the
+ * receiver. If the field has not been assigned any value yet, the default
+ * value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public long get(String name, long defaultValue)
throws IllegalArgumentException {
@@ -343,19 +344,19 @@
}
/**
- * Find and return the Object value of a given field named <code>name</code>
- * in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * Finds and returns the Object value of a given field named {@code name} in
+ * the receiver. If the field has not been assigned any value yet, the
+ * default value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public Object get(String name, Object defaultValue)
throws IllegalArgumentException {
@@ -368,19 +369,19 @@
}
/**
- * Find and return the short value of a given field named <code>name</code>
- * in the receiver. If the field has not been assigned any value yet, the
- * default value <code>defaultValue</code> is returned instead.
+ * Finds and returns the short value of a given field named {@code name} in
+ * the receiver. If the field has not been assigned any value yet, the
+ * default value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public short get(String name, short defaultValue)
throws IllegalArgumentException {
@@ -394,20 +395,19 @@
}
/**
- * Find and return the boolean value of a given field named
- * <code>name</code> in the receiver. If the field has not been assigned
- * any value yet, the default value <code>defaultValue</code> is returned
- * instead.
+ * Finds and returns the boolean value of a given field named {@code name} in
+ * the receiver. If the field has not been assigned any value yet, the
+ * default value {@code defaultValue} is returned instead.
*
* @param name
- * A String, the name of the field to find
+ * the name of the field to find.
* @param defaultValue
- * Return value in case the field has not been assigned to yet.
+ * return value in case the field has not been assigned to yet.
* @return the value of the given field if it has been assigned, the default
- * value otherwise
+ * value otherwise.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public boolean get(String name, boolean defaultValue)
throws IllegalArgumentException {
@@ -421,16 +421,16 @@
}
/**
- * Find and set the byte value of a given field named <code>name</code> in
- * the receiver.
+ * Find and set the byte value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, byte value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Byte.TYPE);
@@ -442,16 +442,16 @@
}
/**
- * Find and set the char value of a given field named <code>name</code> in
- * the receiver.
+ * Find and set the char value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, char value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Character.TYPE);
@@ -463,16 +463,16 @@
}
/**
- * Find and set the double value of a given field named <code>name</code>
- * in the receiver.
+ * Find and set the double value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, double value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Double.TYPE);
@@ -484,16 +484,16 @@
}
/**
- * Find and set the float value of a given field named <code>name</code>
- * in the receiver.
+ * Find and set the float value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, float value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Float.TYPE);
@@ -505,16 +505,16 @@
}
/**
- * Find and set the int value of a given field named <code>name</code> in
- * the receiver.
+ * Find and set the int value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, int value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Integer.TYPE);
@@ -526,16 +526,16 @@
}
/**
- * Find and set the long value of a given field named <code>name</code> in
- * the receiver.
+ * Find and set the long value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, long value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Long.TYPE);
@@ -547,16 +547,16 @@
}
/**
- * Find and set the Object value of a given field named <code>name</code>
- * in the receiver.
+ * Find and set the Object value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, Object value) throws IllegalArgumentException {
Class<?> valueClass = null;
@@ -572,16 +572,16 @@
}
/**
- * Find and set the short value of a given field named <code>name</code>
- * in the receiver.
+ * Find and set the short value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, short value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Short.TYPE);
@@ -593,16 +593,16 @@
}
/**
- * Find and set the boolean value of a given field named <code>name</code>
- * in the receiver.
+ * Find and set the boolean value of a given field named {@code name} in the
+ * receiver.
*
* @param name
- * A String, the name of the field to set
+ * the name of the field to set.
* @param value
- * New value for the field.
+ * new value for the field.
*
* @throws IllegalArgumentException
- * If the corresponding field can not be found.
+ * if the corresponding field can not be found.
*/
public void put(String name, boolean value) throws IllegalArgumentException {
ObjectSlot slot = findSlot(name, Boolean.TYPE);
diff --git a/luni/src/main/java/java/io/Externalizable.java b/luni/src/main/java/java/io/Externalizable.java
index 03049eb..d07f0b7 100644
--- a/luni/src/main/java/java/io/Externalizable.java
+++ b/luni/src/main/java/java/io/Externalizable.java
@@ -20,8 +20,6 @@
/**
* Defines an interface for classes that want to be serializable, but have their
* own binary representation.
- *
- * @since Android 1.0
*/
public interface Externalizable extends Serializable {
/**
@@ -33,7 +31,6 @@
* if an error occurs attempting to read from {@code input}.
* @throws ClassNotFoundException
* if the class of the instance being loaded cannot be found.
- * @since Android 1.0
*/
public void readExternal(ObjectInput input) throws IOException,
ClassNotFoundException;
@@ -45,7 +42,6 @@
* the ObjectOutput to write the object to.
* @throws IOException
* if an error occurs attempting to write to {@code output}.
- * @since Android 1.0
*/
public void writeExternal(ObjectOutput output) throws IOException;
}
diff --git a/luni/src/main/java/java/io/File.java b/luni/src/main/java/java/io/File.java
index f4e8623..e34ab18 100644
--- a/luni/src/main/java/java/io/File.java
+++ b/luni/src/main/java/java/io/File.java
@@ -21,15 +21,11 @@
import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
+import java.security.SecureRandom;
import java.util.ArrayList;
-// BEGIN android-added
-import java.util.Collections;
-// END android-added
import java.util.List;
-// BEGIN android-removed
-// import org.apache.harmony.luni.util.DeleteOnExit;
-// END android-removed
+import org.apache.harmony.luni.util.DeleteOnExit;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
import org.apache.harmony.luni.util.Util;
@@ -45,50 +41,39 @@
* <p>
* When manipulating file paths, the static fields of this class may be used to
* determine the platform specific separators.
- *
+ *
* @see java.io.Serializable
* @see java.lang.Comparable
- *
- * @since Android 1.0
*/
public class File implements Serializable, Comparable<File> {
+
private static final long serialVersionUID = 301077366599181567L;
+ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
private String path;
transient byte[] properPath;
/**
- * The system dependent file separator character. Since Android is a Unix-
- * based system, this defaults to '/'.
- *
- * @since Android 1.0
+ * The system dependent file separator character.
*/
public static final char separatorChar;
/**
* The system dependent file separator string. The initial value of this
- * field is the system property "file.separator". Since Android is a Unix-
- * based system, this defaults to "/".
- *
- * @since Android 1.0
+ * field is the system property "file.separator".
*/
public static final String separator;
/**
- * The system dependent path separator character. Since Android is a Unix-
- * based system, this defaults to ':'.
- *
- * @since Android 1.0
+ * The system dependent path separator character.
*/
public static final char pathSeparatorChar;
/**
* The system dependent path separator string. The initial value of this
- * field is the system property "path.separator". Since Android is a Unix-
- * based system, this defaults to ':'.
- *
- * @since Android 1.0
+ * field is the system property "path.separator".
*/
public static final String pathSeparator;
@@ -115,14 +100,13 @@
/**
* Constructs a new file using the specified directory and name.
- *
+ *
* @param dir
* the directory where the file is stored.
* @param name
* the file's name.
* @throws NullPointerException
- * if {@code name} is null.
- * @since Android 1.0
+ * if {@code name} is {@code null}.
*/
public File(File dir, String name) {
if (name == null) {
@@ -137,10 +121,9 @@
/**
* Constructs a new file using the specified path.
- *
+ *
* @param path
* the path to be used for the file.
- * @since Android 1.0
*/
public File(String path) {
// path == null check & NullPointerException thrown by fixSlashes
@@ -150,14 +133,13 @@
/**
* Constructs a new File using the specified directory path and file name,
* placing a path separator between the two.
- *
+ *
* @param dirPath
* the path to the directory where the file is stored.
* @param name
* the file's name.
* @throws NullPointerException
- * if {@code name} is null.
- * @since Android 1.0
+ * if {@code name} is {@code null}.
*/
public File(String dirPath, String name) {
if (name == null) {
@@ -175,7 +157,7 @@
* needs to be an absolute and hierarchical Unified Resource Identifier with
* file scheme and non-empty path component, but with undefined authority,
* query or fragment components.
- *
+ *
* @param uri
* the Unified Resource Identifier that is used to construct this
* file.
@@ -183,7 +165,6 @@
* if {@code uri} does not comply with the conditions above.
* @see #toURI
* @see java.net.URI
- * @since Android 1.0
*/
public File(URI uri) {
// check pre-conditions
@@ -193,7 +174,7 @@
private String calculatePath(String dirPath, String name) {
dirPath = fixSlashes(dirPath);
- if (!name.equals("")) { //$NON-NLS-1$
+ if (!name.equals(EMPTY_STRING) || dirPath.equals(EMPTY_STRING)) {
// Remove all the proceeding separator chars from name
name = fixSlashes(name);
@@ -217,36 +198,37 @@
return dirPath;
}
+ @SuppressWarnings("nls")
private void checkURI(URI uri) {
if (!uri.isAbsolute()) {
- throw new IllegalArgumentException(Msg.getString("K031a", uri)); //$NON-NLS-1$
- } else if (!uri.getRawSchemeSpecificPart().startsWith("/")) { //$NON-NLS-1$
- throw new IllegalArgumentException(Msg.getString("K031b", uri)); //$NON-NLS-1$
+ throw new IllegalArgumentException(Msg.getString("K031a", uri));
+ } else if (!uri.getRawSchemeSpecificPart().startsWith("/")) {
+ throw new IllegalArgumentException(Msg.getString("K031b", uri));
}
String temp = uri.getScheme();
- if (temp == null || !temp.equals("file")) { //$NON-NLS-1$
- throw new IllegalArgumentException(Msg.getString("K031c", uri)); //$NON-NLS-1$
+ if (temp == null || !temp.equals("file")) {
+ throw new IllegalArgumentException(Msg.getString("K031c", uri));
}
temp = uri.getRawPath();
if (temp == null || temp.length() == 0) {
- throw new IllegalArgumentException(Msg.getString("K031d", uri)); //$NON-NLS-1$
+ throw new IllegalArgumentException(Msg.getString("K031d", uri));
}
if (uri.getRawAuthority() != null) {
- throw new IllegalArgumentException(Msg.getString(
- "K031e", new String[] { "authority", uri.toString() })); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new IllegalArgumentException(Msg.getString("K031e",
+ new String[] { "authority", uri.toString() }));
}
if (uri.getRawQuery() != null) {
- throw new IllegalArgumentException(Msg.getString(
- "K031e", new String[] { "query", uri.toString() })); //$NON-NLS-1$//$NON-NLS-2$
+ throw new IllegalArgumentException(Msg.getString("K031e",
+ new String[] { "query", uri.toString() }));
}
if (uri.getRawFragment() != null) {
- throw new IllegalArgumentException(Msg.getString(
- "K031e", new String[] { "fragment", uri.toString() })); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new IllegalArgumentException(Msg.getString("K031e",
+ new String[] { "fragment", uri.toString() }));
}
}
@@ -259,9 +241,8 @@
* file systems, each with its own platform-dependent root. Further, the
* canonical pathname of any file on the system will always begin with one
* of the returned file system roots.
- *
+ *
* @return the array of file system roots.
- * @since Android 1.0
*/
public static File[] listRoots() {
byte[][] rootsList = rootsImpl();
@@ -293,7 +274,8 @@
char newPath[] = origPath.toCharArray();
for (int i = 0; i < length; i++) {
char pathChar = newPath[i];
- if (pathChar == '\\' || pathChar == '/') {
+ if ((separatorChar == '\\' && pathChar == '\\')
+ || pathChar == '/') {
/* UNC Name requires 2 leading slashes */
if ((foundSlash && i == uncIndex) || !foundSlash) {
newPath[newLength++] = separatorChar;
@@ -319,42 +301,40 @@
&& (newLength > (uncIndex + 1) || (newLength == 2 && newPath[0] != separatorChar))) {
newLength--;
}
- String tempPath = new String(newPath, 0, newLength);
- // If it's the same keep it identical for SecurityManager purposes
- if (!tempPath.equals(origPath)) {
- return tempPath;
- }
- return origPath;
+
+ return new String(newPath, 0, newLength);
}
/**
* Indicates whether the current context is allowed to read from this file.
- *
+ *
* @return {@code true} if this file can be read, {@code false} otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* read request.
- * @since Android 1.0
*/
public boolean canRead() {
+ if (path.length() == 0) {
+ return false;
+ }
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
+ byte[] pp = properPath(true);
// BEGIN android-changed
- return exists() && isReadableImpl(properPath(true));
+ return exists() && isReadableImpl(pp);
// END android-changed
}
/**
* Indicates whether the current context is allowed to write to this file.
- *
+ *
* @return {@code true} if this file can be written, {@code false}
* otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* write request.
- * @since Android 1.0
*/
public boolean canWrite() {
SecurityManager security = System.getSecurityManager();
@@ -375,13 +355,12 @@
/**
* Returns the relative sort ordering of the paths for this file and the
* file {@code another}. The ordering is platform dependent.
- *
+ *
* @param another
* a file to compare this file to
* @return an int determined by comparing the two paths. Possible values are
* described in the Comparable interface.
* @see Comparable
- * @since Android 1.0
*/
public int compareTo(File another) {
if (caseSensitive) {
@@ -392,13 +371,12 @@
/**
* Deletes this file. Directories must be empty before they will be deleted.
- *
+ *
* @return {@code true} if this file was deleted, {@code false} otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* request.
* @see java.lang.SecurityManager#checkDelete
- * @since Android 1.0
*/
public boolean delete() {
SecurityManager security = System.getSecurityManager();
@@ -418,13 +396,12 @@
/**
* Schedules this file to be automatically deleted once the virtual machine
- * terminates. This will only happen when the virtual machine terminates
+ * terminates. This will only happen when the virtual machine terminates
* normally as described by the Java Language Specification section 12.9.
- *
+ *
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* request.
- * @since Android 1.0
*/
public void deleteOnExit() {
SecurityManager security = System.getSecurityManager();
@@ -439,12 +416,11 @@
/**
* Compares {@code obj} to this file and returns {@code true} if they
* represent the <em>same</em> object using a path specific comparison.
- *
+ *
* @param obj
* the object to compare this file with.
* @return {@code true} if {@code obj} is the same as this object,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object obj) {
@@ -460,13 +436,13 @@
/**
* Returns a boolean indicating whether this file can be found on the
* underlying file system.
- *
+ *
* @return {@code true} if this file exists, {@code false} otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
* @see #getPath
- * @since Android 1.0
+ * @see java.lang.SecurityManager#checkRead(FileDescriptor)
*/
public boolean exists() {
if (path.length() == 0) {
@@ -483,22 +459,20 @@
/**
* Returns the absolute path of this file.
- *
+ *
* @return the absolute file path.
* @see java.lang.SecurityManager#checkPropertyAccess
- * @since Android 1.0
*/
public String getAbsolutePath() {
byte[] absolute = properPath(false);
- return Util.toString(absolute);
+ return Util.toUTF8String(absolute);
}
/**
* Returns a new file constructed using the absolute path of this file.
- *
+ *
* @return a new file from this file's absolute path.
* @see java.lang.SecurityManager#checkPropertyAccess
- * @since Android 1.0
*/
public File getAbsoluteFile() {
return new File(this.getAbsolutePath());
@@ -513,42 +487,20 @@
* with a direct directory reference. If the file does not exist,
* getCanonicalPath() may not resolve any references and simply returns an
* absolute path name or throws an IOException.
- *
+ *
* @return the canonical path of this file.
* @throws IOException
* if an I/O error occurs.
* @see java.lang.SecurityManager#checkPropertyAccess
- * @since Android 1.0
*/
public String getCanonicalPath() throws IOException {
byte[] result = properPath(false);
-
- boolean exists = false;
- byte[] pathBytes = result;
- do {
- byte[] linkBytes = getLinkImpl(pathBytes);
- if (linkBytes == pathBytes) {
- break;
- }
- if (linkBytes[0] == separatorChar) {
- pathBytes = linkBytes;
- } else {
- int index = pathBytes.length - 1;
- while (pathBytes[index] != separatorChar) {
- index--;
- }
- byte[] temp = new byte[index + 1 + linkBytes.length];
- System.arraycopy(pathBytes, 0, temp, 0, index + 1);
- System.arraycopy(linkBytes, 0, temp, index + 1,
- linkBytes.length);
- pathBytes = temp;
- }
- exists = existsImpl(pathBytes);
- } while (exists);
- if (exists) {
- result = pathBytes;
+ if(separatorChar == '/') {
+ // resolve the full path first
+ result = resolveLink(result, result.length, false);
+ // resolve the parent directories
+ result = resolve(result);
}
-
int numSeparators = 1;
for (int i = 0; i < result.length; i++) {
if (result[i] == separatorChar) {
@@ -614,18 +566,104 @@
newResult[newLength] = 0;
newResult = getCanonImpl(newResult);
newLength = newResult.length;
- return Util.toString(newResult, 0, newLength);
+ return Util.toUTF8String(newResult, 0, newLength);
+ }
+
+ /*
+ * Resolve symbolic links in the parent directories.
+ */
+ private byte[] resolve(byte[] newResult) throws IOException {
+ int last = 1, nextSize, linkSize;
+ byte[] linkPath = newResult, bytes;
+ boolean done, inPlace;
+ for (int i = 1; i <= newResult.length; i++) {
+ if (i == newResult.length || newResult[i] == separatorChar) {
+ done = i >= newResult.length - 1;
+ // if there is only one segment, do nothing
+ if (done && linkPath.length == 1) {
+ return newResult;
+ }
+ inPlace = false;
+ if (linkPath == newResult) {
+ bytes = newResult;
+ // if there are no symbolic links, terminate the C string
+ // instead of copying
+ if (!done) {
+ inPlace = true;
+ newResult[i] = '\0';
+ }
+ } else {
+ nextSize = i - last + 1;
+ linkSize = linkPath.length;
+ if (linkPath[linkSize - 1] == separatorChar) {
+ linkSize--;
+ }
+ bytes = new byte[linkSize + nextSize];
+ System.arraycopy(linkPath, 0, bytes, 0, linkSize);
+ System.arraycopy(newResult, last - 1, bytes, linkSize,
+ nextSize);
+ // the full path has already been resolved
+ }
+ if (done) {
+ return bytes;
+ }
+ linkPath = resolveLink(bytes, inPlace ? i : bytes.length, true);
+ if (inPlace) {
+ newResult[i] = '/';
+ }
+ last = i + 1;
+ }
+ }
+ throw new InternalError();
+ }
+
+ /*
+ * Resolve a symbolic link. While the path resolves to an existing path,
+ * keep resolving. If an absolute link is found, resolve the parent
+ * directories if resolveAbsolute is true.
+ */
+ private byte[] resolveLink(byte[] pathBytes, int length,
+ boolean resolveAbsolute) throws IOException {
+ boolean restart = false;
+ byte[] linkBytes, temp;
+ do {
+ linkBytes = getLinkImpl(pathBytes);
+ if (linkBytes == pathBytes) {
+ break;
+ }
+ if (linkBytes[0] == separatorChar) {
+ // link to an absolute path, if resolving absolute paths,
+ // resolve the parent dirs again
+ restart = resolveAbsolute;
+ pathBytes = linkBytes;
+ } else {
+ int last = length - 1;
+ while (pathBytes[last] != separatorChar) {
+ last--;
+ }
+ last++;
+ temp = new byte[last + linkBytes.length];
+ System.arraycopy(pathBytes, 0, temp, 0, last);
+ System.arraycopy(linkBytes, 0, temp, last, linkBytes.length);
+ pathBytes = temp;
+ }
+ length = pathBytes.length;
+ } while (existsImpl(pathBytes));
+ // resolve the parent directories
+ if (restart) {
+ return resolve(pathBytes);
+ }
+ return pathBytes;
}
/**
* Returns a new file created using the canonical path of this file.
* Equivalent to {@code new File(this.getCanonicalPath())}.
- *
+ *
* @return the new file constructed from this file's canonical path.
* @throws IOException
* if an I/O error occurs.
* @see java.lang.SecurityManager#checkPropertyAccess
- * @since Android 1.0
*/
public File getCanonicalFile() throws IOException {
return new File(getCanonicalPath());
@@ -635,10 +673,9 @@
/**
* Returns the name of the file or directory represented by this file.
- *
+ *
* @return this file's name or an empty string if there is no name part in
* the file's path.
- * @since Android 1.0
*/
public String getName() {
int separatorIndex = path.lastIndexOf(separator);
@@ -650,9 +687,8 @@
* Returns the pathname of the parent of this file. This is the path up to
* but not including the last name. {@code null} is returned if there is no
* parent.
- *
+ *
* @return this file's parent pathname or {@code null}.
- * @since Android 1.0
*/
public String getParent() {
int length = path.length(), firstInPath = 0;
@@ -677,9 +713,8 @@
* Returns a new file made from the pathname of the parent of this file.
* This is the path up to but not including the last name. {@code null} is
* returned when there is no parent.
- *
+ *
* @return a new file representing this file's parent or {@code null}.
- * @since Android 1.0
*/
public File getParentFile() {
String tempParent = getParent();
@@ -691,9 +726,8 @@
/**
* Returns the path of this file.
- *
+ *
* @return this file's path.
- * @since Android 1.0
*/
public String getPath() {
return path;
@@ -702,10 +736,9 @@
/**
* Returns an integer hash code for the receiver. Any two objects for which
* {@code equals} returns {@code true} must return the same hash code.
- *
+ *
* @return this files's hash value.
* @see #equals
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -721,11 +754,10 @@
* the character '/'; on Windows it is absolute if either it starts with
* '\', '/', '\\' (to represent a file server), or a letter followed by a
* colon.
- *
+ *
* @return {@code true} if this file's pathname is absolute, {@code false}
* otherwise.
* @see #getPath
- * @since Android 1.0
*/
public boolean isAbsolute() {
// BEGIN android-changed
@@ -741,13 +773,12 @@
/**
* Indicates if this file represents a <em>directory</em> on the
* underlying file system.
- *
+ *
* @return {@code true} if this file is a directory, {@code false}
* otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
- * @since Android 1.0
*/
public boolean isDirectory() {
if (path.length() == 0) {
@@ -765,12 +796,11 @@
/**
* Indicates if this file represents a <em>file</em> on the underlying
* file system.
- *
+ *
* @return {@code true} if this file is a file, {@code false} otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
- * @since Android 1.0
*/
public boolean isFile() {
if (path.length() == 0) {
@@ -787,16 +817,15 @@
/**
* Returns whether or not this file is a hidden file as defined by the
- * operating system. The notion of "hidden" is system-dependent. For
- * Unix systems (like Android) a file is considered hidden if its name
- * starts with a ".". For Windows systems there is an explicit flag in the
- * file system for this purpose.
- *
+ * operating system. The notion of "hidden" is system-dependent. For Unix
+ * systems a file is considered hidden if its name starts with a ".". For
+ * Windows systems there is an explicit flag in the file system for this
+ * purpose.
+ *
* @return {@code true} if the file is hidden, {@code false} otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
- * @since Android 1.0
*/
public boolean isHidden() {
if (path.length() == 0) {
@@ -822,12 +851,11 @@
/**
* Returns the time when this file was last modified, measured in
* milliseconds since January 1st, 1970, midnight.
- *
+ *
* @return the time when this file was last modified.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
- * @since Android 1.0
*/
public long lastModified() {
SecurityManager security = System.getSecurityManager();
@@ -847,7 +875,7 @@
/**
* Sets the time this file was last modified, measured in milliseconds since
* January 1st, 1970, midnight.
- *
+ *
* @param time
* the last modification time for this file.
* @return {@code true} if the operation is successful, {@code false}
@@ -857,7 +885,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies write
* access to this file.
- * @since Android 1.0
*/
public boolean setLastModified(long time) {
if (time < 0) {
@@ -875,13 +902,12 @@
/**
* Marks this file or directory to be read-only as defined by the operating
* system.
- *
+ *
* @return {@code true} if the operation is successful, {@code false}
* otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies write
* access to this file.
- * @since Android 1.0
*/
public boolean setReadOnly() {
SecurityManager security = System.getSecurityManager();
@@ -895,12 +921,11 @@
/**
* Returns the length of this file in bytes.
- *
+ *
* @return the number of bytes in this file.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
- * @since Android 1.0
*/
public long length() {
SecurityManager security = System.getSecurityManager();
@@ -914,35 +939,42 @@
/**
* Returns an array of strings with the file names in the directory
- * represented by this file. The result is {@ null} if this file is not a
- * directory.
+ * represented by this file. The result is {@code null} if this file is not
+ * a directory.
* <p>
* The entries {@code .} and {@code ..} representing the current and parent
* directory are not returned as part of the list.
- * </p>
- *
+ *
* @return an array of strings with file names or {@code null}.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
* @see #isDirectory
- * @since Android 1.0
+ * @see java.lang.SecurityManager#checkRead(FileDescriptor)
*/
public java.lang.String[] list() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
- if (!isDirectory()) {
+
+ if (path.length() == 0) {
return null;
}
- byte[][] implList = listImpl(properPath(true));
+
+ byte[] bs = properPath(true);
+ if (!isDirectoryImpl(bs) || !existsImpl(bs) || !isReadableImpl(bs)) {
+ return null;
+ }
+
+ byte[][] implList = listImpl(bs);
if (implList == null) {
+ // empty list
return new String[0];
}
String result[] = new String[implList.length];
for (int index = 0; index < implList.length; index++) {
- result[index] = Util.toString(implList[index]);
+ result[index] = Util.toUTF8String(implList[index]);
}
return result;
}
@@ -952,13 +984,13 @@
* file. The result is {@code null} if this file is not a directory. The
* paths of the files in the array are absolute if the path of this file is
* absolute, they are relative otherwise.
- *
+ *
* @return an array of files or {@code null}.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
* @see #list
- * @since Android 1.0
+ * @see #isDirectory
*/
public File[] listFiles() {
String[] tempNames = list();
@@ -982,8 +1014,7 @@
* <p>
* The entries {@code .} and {@code ..} representing the current and parent
* directories are not returned as part of the list.
- * </p>
- *
+ *
* @param filter
* the filter to match names against, may be {@code null}.
* @return an array of files or {@code null}.
@@ -991,7 +1022,9 @@
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
* @see #list(FilenameFilter filter)
- * @since Android 1.0
+ * @see #getPath
+ * @see #isDirectory
+ * @see java.lang.SecurityManager#checkRead(FileDescriptor)
*/
public File[] listFiles(FilenameFilter filter) {
String[] tempNames = list(filter);
@@ -1014,25 +1047,33 @@
* <p>
* The entries {@code .} and {@code ..} representing the current and parent
* directories are not returned as part of the list.
- * </p>
- *
+ *
* @param filter
* the filter to match names against, may be {@code null}.
* @return an array of files or {@code null}.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
- * @since Android 1.0
+ * @see #getPath
+ * @see #isDirectory
+ * @see java.lang.SecurityManager#checkRead(FileDescriptor)
*/
public File[] listFiles(FileFilter filter) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
- if (!isDirectory()) {
+
+ if (path.length() == 0) {
return null;
}
- byte[][] implList = listImpl(properPath(true));
+
+ byte[] bs = properPath(true);
+ if (!isDirectoryImpl(bs) || !existsImpl(bs) || !isReadableImpl(bs)) {
+ return null;
+ }
+
+ byte[][] implList = listImpl(bs);
if (implList == null) {
return new File[0];
}
@@ -1056,38 +1097,46 @@
* <p>
* The entries {@code .} and {@code ..} representing the current and parent
* directories are not returned as part of the list.
- * </p>
- *
+ *
* @param filter
* the filter to match names against, may be {@code null}.
* @return an array of files or {@code null}.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies read
* access to this file.
- * @since Android 1.0
+ * @see #getPath
+ * @see #isDirectory
+ * @see java.lang.SecurityManager#checkRead(FileDescriptor)
*/
public java.lang.String[] list(FilenameFilter filter) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
- if (!isDirectory()) {
+
+ if (path.length() == 0) {
return null;
}
- byte[][] implList = listImpl(properPath(true));
+
+ byte[] bs = properPath(true);
+ if (!isDirectoryImpl(bs) || !existsImpl(bs) || !isReadableImpl(bs)) {
+ return null;
+ }
+
+ byte[][] implList = listImpl(bs);
if (implList == null) {
+ // empty list
return new String[0];
}
- java.util.Vector<String> tempResult = new java.util.Vector<String>();
+ List<String> tempResult = new ArrayList<String>();
for (int index = 0; index < implList.length; index++) {
String aName = Util.toString(implList[index]);
if (filter == null || filter.accept(this, aName)) {
- tempResult.addElement(aName);
+ tempResult.add(aName);
}
}
- String[] result = new String[tempResult.size()];
- tempResult.copyInto(result);
- return result;
+
+ return tempResult.toArray(new String[tempResult.size()]);
}
private synchronized static native byte[][] listImpl(byte[] path);
@@ -1095,14 +1144,13 @@
/**
* Creates the directory named by the trailing filename of this file. Does
* not create the complete path required to create this directory.
- *
+ *
* @return {@code true} if the directory has been created, {@code false}
* otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies write
* access for this file.
* @see #mkdirs
- * @since Android 1.0
*/
public boolean mkdir() {
SecurityManager security = System.getSecurityManager();
@@ -1117,7 +1165,7 @@
/**
* Creates the directory named by the trailing filename of this file,
* including the complete directory path required to create this directory.
- *
+ *
* @return {@code true} if the necessary directories have been created,
* {@code false} if the target directory already exists or one of
* the directories can not be created.
@@ -1125,7 +1173,6 @@
* if a {@code SecurityManager} is installed and it denies write
* access for this file.
* @see #mkdir
- * @since Android 1.0
*/
public boolean mkdirs() {
/* If the terminal directory already exists, answer false */
@@ -1151,7 +1198,7 @@
/**
* Creates a new, empty file on the file system according to the path
* information stored in this file.
- *
+ *
* @return {@code true} if the file has been created, {@code false} if it
* already exists.
* @throws IOException
@@ -1160,7 +1207,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies write
* access for this file.
- * @since Android 1.0
*/
public boolean createNewFile() throws IOException {
SecurityManager security = System.getSecurityManager();
@@ -1215,10 +1261,11 @@
/**
* Creates an empty temporary file using the given prefix and suffix as part
- * of the file name. If suffix is null, {@code .tmp} is used. This method
- * is a convenience method that calls {@link #createTempFile(String, String,
- * File)} with the third argument being {@code null}.
- *
+ * of the file name. If suffix is {@code null}, {@code .tmp} is used. This
+ * method is a convenience method that calls
+ * {@link #createTempFile(String, String, File)} with the third argument
+ * being {@code null}.
+ *
* @param prefix
* the prefix to the temp file name.
* @param suffix
@@ -1226,7 +1273,6 @@
* @return the temporary file.
* @throws IOException
* if an error occurs when writing the file.
- * @since Android 1.0
*/
public static File createTempFile(String prefix, String suffix)
throws IOException {
@@ -1236,7 +1282,7 @@
/**
* Creates an empty temporary file in the given directory using the given
* prefix and suffix as part of the file name.
- *
+ *
* @param prefix
* the prefix to the temp file name.
* @param suffix
@@ -1246,26 +1292,30 @@
* {@code null} for the default location for temporary files,
* which is taken from the "java.io.tmpdir" system property. It
* may be necessary to set this property to an existing, writable
- * directory for this method to work properly.
+ * directory for this method to work properly.
* @return the temporary file.
* @throws IllegalArgumentException
* if the length of {@code prefix} is less than 3.
* @throws IOException
* if an error occurs when writing the file.
- * @since Android 1.0
*/
+ @SuppressWarnings("nls")
public static File createTempFile(String prefix, String suffix,
File directory) throws IOException {
// Force a prefix null check first
if (prefix.length() < 3) {
- throw new IllegalArgumentException(Msg.getString("K006b")); //$NON-NLS-1$
+ throw new IllegalArgumentException(Msg.getString("K006b"));
}
- String newSuffix = suffix == null ? ".tmp" : suffix; //$NON-NLS-1$
- String tmpDir = "."; //$NON-NLS-1$
- tmpDir = AccessController.doPrivileged(new PriviAction<String>(
- "java.io.tmpdir", ".")); //$NON-NLS-1$//$NON-NLS-2$
- File result, tmpDirFile = directory == null ? new File(tmpDir)
- : directory;
+ String newSuffix = suffix == null ? ".tmp" : suffix;
+ File tmpDirFile;
+ if (directory == null) {
+ String tmpDir = AccessController.doPrivileged(
+ new PriviAction<String>("java.io.tmpdir", "."));
+ tmpDirFile = new File(tmpDir);
+ } else {
+ tmpDirFile = directory;
+ }
+ File result;
do {
result = genTempFile(prefix, newSuffix, tmpDirFile);
} while (!result.createNewFile());
@@ -1274,7 +1324,7 @@
private static File genTempFile(String prefix, String suffix, File directory) {
if (counter == 0) {
- int newInt = new java.util.Random().nextInt();
+ int newInt = new SecureRandom().nextInt();
counter = ((newInt / 65535) & 0xFFFF) + 0x2710;
}
StringBuilder newName = new StringBuilder();
@@ -1290,7 +1340,7 @@
* Returns a string representing the proper path for this file. If this file
* path is absolute, the user.dir property is not prepended, otherwise it
* is.
- *
+ *
* @param internal
* is user.dir internal.
* @return the proper path.
@@ -1311,7 +1361,7 @@
userdir = System.getProperty("user.dir"); //$NON-NLS-1$
}
if (path.length() == 0) {
- return properPath = Util.getBytes(userdir);
+ return properPath = Util.getUTF8Bytes(userdir);
}
int length = userdir.length();
if (length > 0 && userdir.charAt(length - 1) == separatorChar) {
@@ -1328,14 +1378,13 @@
/**
* Renames this file to the name represented by the {@code dest} file. This
* works for both normal files and directories.
- *
+ *
* @param dest
* the file containing the new name.
* @return {@code true} if the File was renamed, {@code false} otherwise.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies write
* access for this file or the {@code dest} file.
- * @since Android 1.0
*/
public boolean renameTo(java.io.File dest) {
SecurityManager security = System.getSecurityManager();
@@ -1351,9 +1400,8 @@
/**
* Returns a string containing a concise, human-readable description of this
* file.
- *
+ *
* @return a printable representation of this file.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -1364,22 +1412,22 @@
* Returns a Uniform Resource Identifier for this file. The URI is system
* dependent and may not be transferable between different operating / file
* systems.
- *
+ *
* @return an URI for this file.
- * @since Android 1.0
*/
+ @SuppressWarnings("nls")
public URI toURI() {
String name = getAbsoluteName();
try {
- if (!name.startsWith("/")) { //$NON-NLS-1$
+ if (!name.startsWith("/")) {
// start with sep.
- return new URI("file", null, //$NON-NLS-1$
- new StringBuilder(name.length() + 1).append('/')
- .append(name).toString(), null, null);
- } else if (name.startsWith("//")) { //$NON-NLS-1$
- return new URI("file", name, null); // UNC path //$NON-NLS-1$
+ return new URI("file", null, new StringBuilder(
+ name.length() + 1).append('/').append(name).toString(),
+ null, null);
+ } else if (name.startsWith("//")) {
+ return new URI("file", "", name, null); // UNC path
}
- return new URI("file", null, name, null, null); //$NON-NLS-1$
+ return new URI("file", null, name, null, null);
} catch (URISyntaxException e) {
// this should never happen
return null;
@@ -1390,22 +1438,23 @@
* Returns a Uniform Resource Locator for this file. The URL is system
* dependent and may not be transferable between different operating / file
* systems.
- *
- * @return an URL for this file.
+ *
+ * @return a URL for this file.
* @throws java.net.MalformedURLException
- * if the path cannot be transformed into an URL.
- * @since Android 1.0
+ * if the path cannot be transformed into a URL.
*/
+ @SuppressWarnings("nls")
public URL toURL() throws java.net.MalformedURLException {
String name = getAbsoluteName();
- if (!name.startsWith("/")) { //$NON-NLS-1$
+ if (!name.startsWith("/")) {
// start with sep.
- return new URL("file", "", -1, new StringBuilder(name.length() + 1) //$NON-NLS-1$ //$NON-NLS-2$
- .append('/').append(name).toString(), null);
- } else if (name.startsWith("//")) { //$NON-NLS-1$
- return new URL("file:" + name); // UNC path //$NON-NLS-1$
+ return new URL(
+ "file", EMPTY_STRING, -1, new StringBuilder(name.length() + 1) //$NON-NLS-1$
+ .append('/').append(name).toString(), null);
+ } else if (name.startsWith("//")) {
+ return new URL("file:" + name); // UNC path
}
- return new URL("file", "", -1, name, null); //$NON-NLS-1$ //$NON-NLS-2$
+ return new URL("file", EMPTY_STRING, -1, name, null);
}
private String getAbsoluteName() {
@@ -1436,60 +1485,3 @@
path = path.replace(inSeparator, separatorChar);
}
}
-
-// BEGIN android-added
-/**
- * Implements the actual DeleteOnExit mechanism. Is registered as a shutdown
- * hook in the Runtime, once it is actually being used.
- */
-class DeleteOnExit extends Thread {
-
- /**
- * Our singleton instance.
- */
- private static DeleteOnExit instance;
-
- /**
- * Our list of files scheduled for deletion.
- */
- private ArrayList<String> files = new ArrayList<String>();
-
- /**
- * Returns our singleton instance, creating it if necessary.
- */
- public static synchronized DeleteOnExit getInstance() {
- if (instance == null) {
- instance = new DeleteOnExit();
- Runtime.getRuntime().addShutdownHook(instance);
- }
-
- return instance;
- }
-
- /**
- * Schedules a file for deletion.
- *
- * @param filename The file to delete.
- */
- public void addFile(String filename) {
- synchronized(files) {
- if (!files.contains(filename)) {
- files.add(filename);
- }
- }
- }
-
- /**
- * Does the actual work. Note we (a) first sort the files lexicographically
- * and then (b) delete them in reverse order. This is to make sure files
- * get deleted before their parent directories.
- */
- @Override
- public void run() {
- Collections.sort(files);
- for (int i = files.size() - 1; i >= 0; i--) {
- new File(files.get(i)).delete();
- }
- }
-}
-// END android-added
diff --git a/luni/src/main/java/java/io/FileDescriptor.java b/luni/src/main/java/java/io/FileDescriptor.java
index e131c88..15eb983 100644
--- a/luni/src/main/java/java/io/FileDescriptor.java
+++ b/luni/src/main/java/java/io/FileDescriptor.java
@@ -30,33 +30,25 @@
* System.err streams respectively.
* <p>
* Applications should not create new FileDescriptors.
- *
+ *
* @see FileInputStream#getFD()
* @see FileOutputStream#getFD()
* @see RandomAccessFile#getFD()
- *
- * @since Android 1.0
*/
public final class FileDescriptor {
/**
* The FileDescriptor representing standard input.
- *
- * @since Android 1.0
*/
public static final FileDescriptor in = new FileDescriptor();
/**
* FileDescriptor representing standard out.
- *
- * @since Android 1.0
*/
public static final FileDescriptor out = new FileDescriptor();
/**
* FileDescriptor representing standard error.
- *
- * @since Android 1.0
*/
public static final FileDescriptor err = new FileDescriptor();
@@ -68,8 +60,8 @@
*/
int descriptor = -1;
// END android-changed
-
- boolean readOnly = false;
+
+ boolean readOnly = false;
private static native void oneTimeInitialization();
@@ -84,8 +76,6 @@
/**
* Constructs a new FileDescriptor containing an invalid handle. The
* contained handle is usually modified by native code at a later point.
- *
- * @since Android 1.0
*/
public FileDescriptor() {
super();
@@ -94,10 +84,9 @@
/**
* Ensures that data which is buffered within the underlying implementation
* is written out to the appropriate device before returning.
- *
+ *
* @throws SyncFailedException
* when the operation fails.
- * @since Android 1.0
*/
public void sync() throws SyncFailedException {
// if the descriptor is a read-only one, do nothing
@@ -105,15 +94,16 @@
syncImpl();
}
}
-
+
private native void syncImpl() throws SyncFailedException;
/**
* Indicates whether this FileDescriptor is valid.
- *
+ *
* @return {@code true} if this FileDescriptor is valid, {@code false}
* otherwise.
- * @since Android 1.0
*/
- public native boolean valid();
+ public boolean valid() {
+ return descriptor != -1;
+ }
}
diff --git a/luni/src/main/java/java/io/FileFilter.java b/luni/src/main/java/java/io/FileFilter.java
index 674ce13..5638dd9 100644
--- a/luni/src/main/java/java/io/FileFilter.java
+++ b/luni/src/main/java/java/io/FileFilter.java
@@ -24,21 +24,18 @@
/**
* An interface for filtering {@link File} objects based on their names
* or other information.
- *
+ *
* @see File#listFiles(FileFilter)
- *
- * @since Android 1.0
*/
public interface FileFilter {
/**
* Indicating whether a specific file should be included in a pathname list.
- *
+ *
* @param pathname
* the abstract file to check.
* @return {@code true} if the file should be included, {@code false}
* otherwise.
- * @since Android 1.0
*/
public abstract boolean accept(File pathname);
}
diff --git a/luni/src/main/java/java/io/FileInputStream.java b/luni/src/main/java/java/io/FileInputStream.java
index c39d1e7..1243262 100644
--- a/luni/src/main/java/java/io/FileInputStream.java
+++ b/luni/src/main/java/java/io/FileInputStream.java
@@ -31,11 +31,9 @@
* Since this may induce some performance penalty, in particular if many small
* read requests are made, a FileInputStream is often wrapped by a
* BufferedInputStream.
- *
+ *
* @see BufferedInputStream
* @see FileOutputStream
- *
- * @since Android 1.0
*/
public class FileInputStream extends InputStream implements Closeable {
/**
@@ -58,7 +56,7 @@
/**
* Constructs a new {@code FileInputStream} based on {@code file}.
- *
+ *
* @param file
* the file from which this stream reads.
* @throws FileNotFoundException
@@ -66,7 +64,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* read request.
- * @since Android 1.0
*/
public FileInputStream(File file) throws FileNotFoundException {
super();
@@ -90,7 +87,7 @@
* Constructs a new {@code FileInputStream} on the {@link FileDescriptor}
* {@code fd}. The file must already be open, therefore no
* {@code FileNotFoundException} will be thrown.
- *
+ *
* @param fd
* the FileDescriptor from which this stream reads.
* @throws NullPointerException
@@ -98,7 +95,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* read request.
- * @since Android 1.0
*/
public FileInputStream(FileDescriptor fd) {
super();
@@ -121,7 +117,7 @@
* Constructs a new {@code FileInputStream} on the file named
* {@code fileName}. The path of {@code fileName} may be absolute or
* relative to the system property {@code "user.dir"}.
- *
+ *
* @param fileName
* the path and name of the file from which this stream reads.
* @throws FileNotFoundException
@@ -129,7 +125,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* read request.
- * @since Android 1.0
*/
public FileInputStream(String fileName) throws FileNotFoundException {
this(null == fileName ? (File) null : new File(fileName));
@@ -139,11 +134,10 @@
* Returns the number of bytes that are available before this stream will
* block. This method always returns the size of the file minus the current
* position.
- *
+ *
* @return the number of bytes available before blocking.
* @throws IOException
* if an error occurs in this stream.
- * @since Android 1.0
*/
@Override
public int available() throws IOException {
@@ -157,7 +151,7 @@
// use.
return fileSystem.ioctlAvailable(fd.descriptor);
- // END android-added
+ // END android-added
// BEGIN android-deleted
// synchronized (repositioningLock) {
@@ -179,10 +173,9 @@
/**
* Closes this stream.
- *
+ *
* @throws IOException
* if an error occurs attempting to close this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -203,10 +196,9 @@
/**
* Ensures that all resources for this stream are released when it is about
* to be garbage collected.
- *
+ *
* @throws IOException
* if an error occurs attempting to finalize this stream.
- * @since Android 1.0
*/
@Override
protected void finalize() throws IOException {
@@ -220,10 +212,8 @@
* that is the same as the current position of this stream within the file.
* All changes made to the underlying file descriptor state via the channel
* are visible by the input stream and vice versa.
- * </p>
- *
+ *
* @return the file channel for this stream.
- * @since Android 1.0
*/
public FileChannel getChannel() {
// BEGIN android-changed
@@ -240,12 +230,11 @@
/**
* Returns the {@link FileDescriptor} representing the operating system
* resource for this stream.
- *
+ *
* @return the {@code FileDescriptor} for this stream.
* @throws IOException
* if an error occurs while getting this stream's
* {@code FileDescriptor}.
- * @since Android 1.0
*/
public final FileDescriptor getFD() throws IOException {
return fd;
@@ -255,11 +244,10 @@
* Reads a single byte from this stream and returns it as an integer in the
* range from 0 to 255. Returns -1 if the end of this stream has been
* reached.
- *
+ *
* @return the byte read or -1 if the end of this stream has been reached.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -271,14 +259,13 @@
/**
* Reads bytes from this stream and stores them in the byte array
* {@code buffer}.
- *
+ *
* @param buffer
* the byte array in which to store the bytes read.
* @return the number of bytes actually read or -1 if the end of the stream
* has been reached.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer) throws IOException {
@@ -288,7 +275,7 @@
/**
* Reads at most {@code count} bytes from this stream and stores them in the
* byte array {@code buffer} starting at {@code offset}.
- *
+ *
* @param buffer
* the byte array in which to store the bytes read.
* @param offset
@@ -304,7 +291,6 @@
* {@code buffer}.
* @throws IOException
* if the stream is closed or another IOException occurs.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
@@ -338,14 +324,13 @@
* Skips {@code count} number of bytes in this stream. Subsequent
* {@code read()}'s will not return these bytes unless {@code reset()} is
* used. This method may perform multiple reads to read {@code count} bytes.
- *
+ *
* @param count
* the number of bytes to skip.
* @return the number of bytes actually skipped.
* @throws IOException
* if {@code count < 0}, this stream is closed or another
* IOException occurs.
- * @since Android 1.0
*/
@Override
public long skip(long count) throws IOException {
diff --git a/luni/src/main/java/java/io/FileNotFoundException.java b/luni/src/main/java/java/io/FileNotFoundException.java
index a0f5bc6..2ab9e89 100644
--- a/luni/src/main/java/java/io/FileNotFoundException.java
+++ b/luni/src/main/java/java/io/FileNotFoundException.java
@@ -19,8 +19,6 @@
/**
* Thrown when a file specified by a program cannot be found.
- *
- * @since Android 1.0
*/
public class FileNotFoundException extends IOException {
@@ -29,8 +27,6 @@
/**
* Constructs a new {@code FileNotFoundException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
public FileNotFoundException() {
super();
@@ -42,7 +38,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public FileNotFoundException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/FileOutputStream.java b/luni/src/main/java/java/io/FileOutputStream.java
index 00ae5d8..f0b25c9 100644
--- a/luni/src/main/java/java/io/FileOutputStream.java
+++ b/luni/src/main/java/java/io/FileOutputStream.java
@@ -31,10 +31,10 @@
* Since this may induce some performance penalty, in particular if many small
* write requests are made, a FileOutputStream is often wrapped by a
* BufferedOutputStream.
- *
+ *
* @see BufferedOutputStream
* @see FileInputStream
- *
+ *
* @since Android 1.0
*/
public class FileOutputStream extends OutputStream implements Closeable {
@@ -55,7 +55,7 @@
/**
* Constructs a new FileOutputStream on the File {@code file}. If the file
* exists, it is overwritten.
- *
+ *
* @param file
* the file to which this stream writes.
* @throws FileNotFoundException
@@ -63,7 +63,7 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* write request.
- * @since Android 1.0
+ * @see java.lang.SecurityManager#checkWrite(FileDescriptor)
*/
public FileOutputStream(File file) throws FileNotFoundException {
this(file, false);
@@ -73,7 +73,7 @@
* Constructs a new FileOutputStream on the File {@code file}. The
* parameter {@code append} determines whether or not the file is opened and
* appended to or just opened and overwritten.
- *
+ *
* @param file
* the file to which this stream writes.
* @param append
@@ -83,7 +83,8 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* write request.
- * @since Android 1.0
+ * @see java.lang.SecurityManager#checkWrite(FileDescriptor)
+ * @see java.lang.SecurityManager#checkWrite(String)
*/
public FileOutputStream(File file, boolean append)
throws FileNotFoundException {
@@ -104,7 +105,7 @@
* Constructs a new FileOutputStream on the FileDescriptor {@code fd}. The
* file must already be open, therefore no {@code FileNotFoundException}
* will be thrown.
- *
+ *
* @param fd
* the FileDescriptor to which this stream writes.
* @throws NullPointerException
@@ -112,7 +113,7 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* write request.
- * @since Android 1.0
+ * @see java.lang.SecurityManager#checkWrite(FileDescriptor)
*/
public FileOutputStream(FileDescriptor fd) {
super();
@@ -133,7 +134,7 @@
* Constructs a new FileOutputStream on the file named {@code filename}. If
* the file exists, it is overwritten. The {@code filename} may be absolute
* or relative to the system property {@code "user.dir"}.
- *
+ *
* @param filename
* the name of the file to which this stream writes.
* @throws FileNotFoundException
@@ -141,7 +142,6 @@
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* write request.
- * @since Android 1.0
*/
public FileOutputStream(String filename) throws FileNotFoundException {
this(filename, false);
@@ -152,17 +152,16 @@
* The parameter {@code append} determines whether or not the file is opened
* and appended to or just opened and overwritten. The {@code filename} may
* be absolute or relative to the system property {@code "user.dir"}.
- *
- * @param append
- * indicates whether or not to append to an existing file.
+ *
* @param filename
* the name of the file to which this stream writes.
+ * @param append
+ * indicates whether or not to append to an existing file.
* @throws FileNotFoundException
* if the file cannot be opened for writing.
* @throws SecurityException
* if a {@code SecurityManager} is installed and it denies the
* write request.
- * @since Android 1.0
*/
public FileOutputStream(String filename, boolean append)
throws FileNotFoundException {
@@ -172,10 +171,9 @@
/**
* Closes this stream. This implementation closes the underlying operating
* system resources allocated to represent this stream.
- *
+ *
* @throws IOException
* if an error occurs attempting to close this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -204,10 +202,9 @@
/**
* Frees any resources allocated for this stream before it is garbage
* collected. This method is called from the Java Virtual Machine.
- *
+ *
* @throws IOException
* if an error occurs attempting to finalize this stream.
- * @since Android 1.0
*/
@Override
protected void finalize() throws IOException {
@@ -221,10 +218,8 @@
* file that is the same as the current position of this stream within the
* file. All changes made to the underlying file descriptor state via the
* channel are visible by the output stream and vice versa.
- * </p>
- *
+ *
* @return the file channel representation for this stream.
- * @since Android 1.0
*/
public FileChannel getChannel() {
return channel;
@@ -233,12 +228,11 @@
/**
* Returns a FileDescriptor which represents the lowest level representation
* of an operating system stream resource.
- *
+ *
* @return a FileDescriptor representing this stream.
* @throws IOException
* if an error occurs attempting to get the FileDescriptor of
* this stream.
- * @since Android 1.0
*/
public final FileDescriptor getFD() throws IOException {
return fd;
@@ -247,13 +241,12 @@
/**
* Writes the entire contents of the byte array {@code buffer} to this
* stream.
- *
+ *
* @param buffer
* the buffer to be written to the file.
* @throws IOException
* if this stream is closed or an error occurs attempting to
* write to this stream.
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer) throws IOException {
@@ -263,7 +256,7 @@
/**
* Writes {@code count} bytes from the byte array {@code buffer} starting at
* {@code offset} to this stream.
- *
+ *
* @param buffer
* the buffer to write to this stream.
* @param offset
@@ -279,7 +272,6 @@
* write to this stream.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
@@ -308,13 +300,12 @@
/**
* Writes the specified byte {@code oneByte} to this stream. Only the low
* order byte of the integer {@code oneByte} is written.
- *
+ *
* @param oneByte
* the byte to be written.
* @throws IOException
* if this stream is closed an error occurs attempting to write
* to this stream.
- * @since Android 1.0
*/
@Override
public void write(int oneByte) throws IOException {
diff --git a/luni/src/main/java/java/io/FilePermission.java b/luni/src/main/java/java/io/FilePermission.java
index 3702ac7..610adee 100644
--- a/luni/src/main/java/java/io/FilePermission.java
+++ b/luni/src/main/java/java/io/FilePermission.java
@@ -34,7 +34,6 @@
* and directories contained in that directory. If the pathname
* ends in {@code /-}, it includes all the files and directories in that
* directory <i>recursively</i>. The following pathnames have a special meaning:
- * </p>
* <ul>
* <li>
* "*": all files in the current directory;
@@ -46,8 +45,6 @@
* "<<ALL FILES>>": any file and directory in the file system.
* </li>
* </ul>
- *
- * @since Android 1.0
*/
public final class FilePermission extends Permission implements Serializable {
@@ -87,8 +84,7 @@
* it contains a string other than "read", "write", "execute"
* and "delete".
* @throws NullPointerException
- * if {@code path} is null.
- * @since Android 1.0
+ * if {@code path} is {@code null}.
*/
public FilePermission(String path, String actions) {
super(path);
@@ -197,7 +193,6 @@
* Returns the actions associated with this file permission.
*
* @return the actions associated with this file permission.
- * @since Android 1.0
*/
@Override
public String getActions() {
@@ -213,7 +208,6 @@
* the object to check equality with.
* @return {@code true} if this file permission is equal to {@code obj},
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object obj) {
@@ -245,7 +239,6 @@
* the permission to check.
* @return {@code true} if the argument permission is implied by the
* receiver, and {@code false} if it is not.
- * @since Android 1.0
*/
@Override
public boolean implies(Permission p) {
@@ -361,7 +354,6 @@
*
* @return A new PermissionCollection object suitable for storing
* FilePermission objects.
- * @since Android 1.0
*/
@Override
public PermissionCollection newPermissionCollection() {
@@ -372,7 +364,6 @@
* Calculates the hash code value for this file permission.
*
* @return the hash code value for this file permission.
- * @since Android 1.0
*/
@Override
public int hashCode() {
diff --git a/luni/src/main/java/java/io/FilePermissionCollection.java b/luni/src/main/java/java/io/FilePermissionCollection.java
index 9d49b79..3049442 100644
--- a/luni/src/main/java/java/io/FilePermissionCollection.java
+++ b/luni/src/main/java/java/io/FilePermissionCollection.java
@@ -25,8 +25,6 @@
/**
* Collects {@link FilePermission} objects and allows to query whether a
* particular permission is implied by it.
- *
- * @since Android 1.0
*/
final class FilePermissionCollection extends PermissionCollection implements
Serializable {
diff --git a/luni/src/main/java/java/io/FileReader.java b/luni/src/main/java/java/io/FileReader.java
index 90cd454..c62fdeb 100644
--- a/luni/src/main/java/java/io/FileReader.java
+++ b/luni/src/main/java/java/io/FileReader.java
@@ -27,8 +27,6 @@
*
* @see BufferedReader
* @see FileWriter
- *
- * @since Android 1.0
*/
public class FileReader extends InputStreamReader {
@@ -39,7 +37,6 @@
* a File to be opened for reading characters from.
* @throws FileNotFoundException
* if {@code file} does not exist.
- * @since Android 1.0
*/
public FileReader(File file) throws FileNotFoundException {
super(new FileInputStream(file));
@@ -52,7 +49,6 @@
*
* @param fd
* the previously opened file descriptor.
- * @since Android 1.0
*/
public FileReader(FileDescriptor fd) {
super(new FileInputStream(fd));
@@ -65,7 +61,6 @@
* an absolute or relative path specifying the file to open.
* @throws FileNotFoundException
* if there is no file named {@code filename}.
- * @since Android 1.0
*/
public FileReader(String filename) throws FileNotFoundException {
super(new FileInputStream(filename));
diff --git a/luni/src/main/java/java/io/FileWriter.java b/luni/src/main/java/java/io/FileWriter.java
index 63aee88..86a9af8 100644
--- a/luni/src/main/java/java/io/FileWriter.java
+++ b/luni/src/main/java/java/io/FileWriter.java
@@ -27,8 +27,6 @@
*
* @see BufferedWriter
* @see FileReader
- *
- * @since Android 1.0
*/
public class FileWriter extends OutputStreamWriter {
@@ -39,7 +37,6 @@
* the non-null File to write bytes to.
* @throws IOException
* if {@code file} cannot be opened for writing.
- * @since Android 1.0
*/
public FileWriter(File file) throws IOException {
super(new FileOutputStream(file));
@@ -56,7 +53,6 @@
* indicates whether or not to append to an existing file.
* @throws IOException
* if the {@code file} cannot be opened for writing.
- * @since Android 1.0
*/
public FileWriter(File file, boolean append) throws IOException {
super(new FileOutputStream(file, append));
@@ -67,7 +63,6 @@
*
* @param fd
* the non-null FileDescriptor to write bytes to.
- * @since Android 1.0
*/
public FileWriter(FileDescriptor fd) {
super(new FileOutputStream(fd));
@@ -80,7 +75,6 @@
* the non-null name of the file to write bytes to.
* @throws IOException
* if the file cannot be opened for writing.
- * @since Android 1.0
*/
public FileWriter(String filename) throws IOException {
super(new FileOutputStream(new File(filename)));
@@ -97,7 +91,6 @@
* indicates whether or not to append to an existing file.
* @throws IOException
* if the {@code file} cannot be opened for writing.
- * @since Android 1.0
*/
public FileWriter(String filename, boolean append) throws IOException {
super(new FileOutputStream(filename, append));
diff --git a/luni/src/main/java/java/io/FilenameFilter.java b/luni/src/main/java/java/io/FilenameFilter.java
index 40a6cca..a51bcc6 100644
--- a/luni/src/main/java/java/io/FilenameFilter.java
+++ b/luni/src/main/java/java/io/FilenameFilter.java
@@ -21,9 +21,8 @@
* An interface for filtering {@link File} objects based on their names
* or the directory they reside in.
*
+ * @see File
* @see File#list(FilenameFilter)
- *
- * @since Android 1.0
*/
public interface FilenameFilter {
@@ -34,10 +33,9 @@
* the directory in which the {@code filename} was found.
* @param filename
* the name of the file in {@code dir} to test.
- * @return {@code true} if the filename matches the filter
- * and can be included in the list, {@code false}
+ * @return {@code true} if the filename matches the filter
+ * and can be included in the list, {@code false}
* otherwise.
- * @since Android 1.0
*/
public abstract boolean accept(File dir, String filename);
}
diff --git a/luni/src/main/java/java/io/FilterInputStream.java b/luni/src/main/java/java/io/FilterInputStream.java
index 5110060..0baa409 100644
--- a/luni/src/main/java/java/io/FilterInputStream.java
+++ b/luni/src/main/java/java/io/FilterInputStream.java
@@ -26,21 +26,13 @@
* from this class.
*
* @see FilterOutputStream
- *
- * @since Android 1.0
*/
public class FilterInputStream extends InputStream {
- // BEGIN android-changed
- // The underlying input stream address should not be cached in a register.
- // This was changed to be more close to the RI.
/**
* The source input stream that is filtered.
- *
- * @since Android 1.0
*/
protected volatile InputStream in;
- // END android-changed
/**
* Constructs a new {@code FilterInputStream} with the specified input
@@ -48,7 +40,6 @@
*
* @param in
* the non-null InputStream to filter reads on.
- * @since Android 1.0
*/
protected FilterInputStream(InputStream in) {
super();
@@ -57,12 +48,11 @@
/**
* Returns the number of bytes that are available before this stream will
- * block.
- *
+ * block.
+ *
* @return the number of bytes available before blocking.
* @throws IOException
* if an error occurs in this stream.
- * @since Android 1.0
*/
@Override
public int available() throws IOException {
@@ -74,7 +64,6 @@
*
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -88,14 +77,12 @@
* position, provided that {@code readlimit} has not been surpassed.
* <p>
* This implementation sets a mark in the filtered stream.
- * </p>
- *
+ *
* @param readlimit
* the number of bytes that can be read from this stream before
* the mark is invalidated.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public synchronized void mark(int readlimit) {
@@ -112,7 +99,6 @@
* @see #mark(int)
* @see #reset()
* @see #skip(long)
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -128,7 +114,6 @@
* reached.
* @throws IOException
* if the stream is closed or another IOException occurs.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -147,7 +132,6 @@
* filtered stream has been reached while reading.
* @throws IOException
* if this stream is closed or another IOException occurs.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer) throws IOException {
@@ -172,7 +156,6 @@
* filtered stream has been reached while reading.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
@@ -189,7 +172,6 @@
* bytes have been read since setting the mark.
* @see #mark(int)
* @see #markSupported()
- * @since Android 1.0
*/
@Override
public synchronized void reset() throws IOException {
@@ -208,12 +190,10 @@
* @throws IOException
* if this stream is closed or another IOException occurs.
* @see #mark(int)
- * @see #reset()
- * @since Android 1.0
+ * @see #reset()
*/
@Override
public long skip(long count) throws IOException {
return in.skip(count);
}
}
-
diff --git a/luni/src/main/java/java/io/FilterOutputStream.java b/luni/src/main/java/java/io/FilterOutputStream.java
index 212b22e..66765f9 100644
--- a/luni/src/main/java/java/io/FilterOutputStream.java
+++ b/luni/src/main/java/java/io/FilterOutputStream.java
@@ -26,27 +26,22 @@
* decompression of the underlying stream. Output streams that wrap another
* output stream and provide some additional functionality on top of it usually
* inherit from this class.
- *
+ *
* @see FilterOutputStream
- *
- * @since Android 1.0
*/
public class FilterOutputStream extends OutputStream {
/**
* The target output stream for this filter stream.
- *
- * @since Android 1.0
*/
protected OutputStream out;
/**
* Constructs a new {@code FilterOutputStream} with {@code out} as its
* target stream.
- *
+ *
* @param out
* the target stream that this stream writes to.
- * @since Android 1.0
*/
public FilterOutputStream(OutputStream out) {
this.out = out;
@@ -54,10 +49,9 @@
/**
* Closes this stream. This implementation closes the target stream.
- *
+ *
* @throws IOException
* if an error occurs attempting to close this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -73,10 +67,9 @@
/**
* Ensures that all pending data is sent out to the target stream. This
* implementation flushes the target stream.
- *
+ *
* @throws IOException
* if an error occurs attempting to flush this stream.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -87,12 +80,11 @@
* Writes the entire contents of the byte array {@code buffer} to this
* stream. This implementation writes the {@code buffer} to the target
* stream.
- *
+ *
* @param buffer
* the buffer to be written.
* @throws IOException
* if an I/O error occurs while writing to this stream.
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer) throws IOException {
@@ -105,7 +97,7 @@
/**
* Writes {@code count} bytes from the byte array {@code buffer} starting at
* {@code offset} to the target stream.
- *
+ *
* @param buffer
* the buffer to write.
* @param offset
@@ -118,7 +110,6 @@
* {@code buffer}.
* @throws IOException
* if an I/O error occurs while writing to this stream.
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
@@ -149,12 +140,11 @@
/**
* Writes one byte to the target stream. Only the low order byte of the
* integer {@code oneByte} is written.
- *
+ *
* @param oneByte
* the byte to be written.
* @throws IOException
* if an I/O error occurs while writing to this stream.
- * @since Android 1.0
*/
@Override
public void write(int oneByte) throws IOException {
diff --git a/luni/src/main/java/java/io/FilterReader.java b/luni/src/main/java/java/io/FilterReader.java
index 7fa96b5..e8e06dd 100644
--- a/luni/src/main/java/java/io/FilterReader.java
+++ b/luni/src/main/java/java/io/FilterReader.java
@@ -26,15 +26,11 @@
* class.
*
* @see FilterWriter
- *
- * @since Android 1.0
*/
public abstract class FilterReader extends Reader {
/**
* The target Reader which is being filtered.
- *
- * @since Android 1.0
*/
protected Reader in;
@@ -43,7 +39,6 @@
*
* @param in
* The non-null Reader to filter reads on.
- * @since Android 1.0
*/
protected FilterReader(Reader in) {
super(in);
@@ -55,7 +50,6 @@
*
* @throws IOException
* if an error occurs while closing this reader.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -71,7 +65,6 @@
* position, provided that {@code readlimit} has not been surpassed.
* <p>
* This implementation sets a mark in the filtered reader.
- * </p>
*
* @param readlimit
* the number of bytes that can be read from this reader before
@@ -80,7 +73,6 @@
* if an error occurs while marking this reader.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public synchronized void mark(int readlimit) throws IOException {
@@ -98,7 +90,6 @@
* @see #mark(int)
* @see #reset()
* @see #skip(long)
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -116,7 +107,6 @@
* been reached.
* @throws IOException
* if an error occurs while reading from this reader.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -142,7 +132,6 @@
* filtered reader has been reached while reading.
* @throws IOException
* if an error occurs while reading from this reader.
- * @since Android 1.0
*/
@Override
public int read(char[] buffer, int offset, int count) throws IOException {
@@ -161,7 +150,6 @@
* is called, {@code false} if unknown or blocking will occur.
* @throws IOException
* if the reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
@Override
public boolean ready() throws IOException {
@@ -182,7 +170,6 @@
* {@code mark()} and {@code reset()}.
* @see #mark(int)
* @see #markSupported()
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
@@ -205,7 +192,6 @@
* @see #mark(int)
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public long skip(long count) throws IOException {
diff --git a/luni/src/main/java/java/io/FilterWriter.java b/luni/src/main/java/java/io/FilterWriter.java
index 66c1d34..cd48f64 100644
--- a/luni/src/main/java/java/io/FilterWriter.java
+++ b/luni/src/main/java/java/io/FilterWriter.java
@@ -24,26 +24,22 @@
* decompression of the underlying writer. Writers that wrap another writer and
* provide some additional functionality on top of it usually inherit from this
* class.
- *
+ *
* @see FilterReader
- *
- * @since Android 1.0
*/
public abstract class FilterWriter extends Writer {
/**
* The Writer being filtered.
- * @since Android 1.0
*/
protected Writer out;
/**
* Constructs a new FilterWriter on the Writer {@code out}. All writes are
* now filtered through this writer.
- *
+ *
* @param out
* the target Writer to filter writes on.
- * @since Android 1.0
*/
protected FilterWriter(Writer out) {
super(out);
@@ -52,10 +48,9 @@
/**
* Closes this writer. This implementation closes the target writer.
- *
+ *
* @throws IOException
* if an error occurs attempting to close this writer.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -67,10 +62,9 @@
/**
* Flushes this writer to ensure all pending data is sent out to the target
* writer. This implementation flushes the target writer.
- *
+ *
* @throws IOException
* if an error occurs attempting to flush this writer.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -82,7 +76,7 @@
/**
* Writes {@code count} characters from the char array {@code buffer}
* starting at position {@code offset} to the target writer.
- *
+ *
* @param buffer
* the buffer to write.
* @param offset
@@ -91,7 +85,6 @@
* the number of characters in {@code buffer} to write.
* @throws IOException
* if an error occurs while writing to this writer.
- * @since Android 1.0
*/
@Override
public void write(char[] buffer, int offset, int count) throws IOException {
@@ -106,12 +99,11 @@
/**
* Writes the specified character {@code oneChar} to the target writer. Only the
* two least significant bytes of the integer {@code oneChar} are written.
- *
+ *
* @param oneChar
* the char to write to the target writer.
* @throws IOException
* if an error occurs while writing to this writer.
- * @since Android 1.0
*/
@Override
public void write(int oneChar) throws IOException {
@@ -124,7 +116,7 @@
* Writes {@code count} characters from the string {@code str} starting at
* position {@code index} to this writer. This implementation writes
* {@code str} to the target writer.
- *
+ *
* @param str
* the string to be written.
* @param offset
@@ -133,7 +125,6 @@
* the number of chars in {@code str} to write.
* @throws IOException
* if an error occurs while writing to this writer.
- * @since Android 1.0
*/
@Override
public void write(String str, int offset, int count) throws IOException {
diff --git a/luni/src/main/java/java/io/Flushable.java b/luni/src/main/java/java/io/Flushable.java
index 55fcc92..c36de30 100644
--- a/luni/src/main/java/java/io/Flushable.java
+++ b/luni/src/main/java/java/io/Flushable.java
@@ -20,17 +20,14 @@
* Defines an interface for classes that can (or need to) be flushed, typically
* before some output processing is considered to be finished and the object
* gets closed.
- *
- * @since Android 1.0
*/
public interface Flushable {
/**
* Flushes the object by writing out any buffered data to the underlying
* output.
- *
+ *
* @throws IOException
* if there are any issues writing the data.
- * @since Android 1.0
*/
void flush() throws IOException;
}
diff --git a/luni/src/main/java/java/io/IOException.java b/luni/src/main/java/java/io/IOException.java
index 869a6d0..24cea9f 100644
--- a/luni/src/main/java/java/io/IOException.java
+++ b/luni/src/main/java/java/io/IOException.java
@@ -22,8 +22,6 @@
* calling the constructor, as usual. Note there are also several subclasses of
* this class for more specific error situations, such as
* {@link FileNotFoundException} or {@link EOFException}.
- *
- * @since Android 1.0
*/
public class IOException extends Exception {
@@ -31,8 +29,6 @@
/**
* Constructs a new {@code IOException} with its stack trace filled in.
- *
- * @since Android 1.0
*/
public IOException() {
super();
@@ -44,7 +40,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public IOException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/InputStream.java b/luni/src/main/java/java/io/InputStream.java
index 23fd89c..f20ce7d 100644
--- a/luni/src/main/java/java/io/InputStream.java
+++ b/luni/src/main/java/java/io/InputStream.java
@@ -34,10 +34,8 @@
* <p>
* Many specialized input streams for purposes like reading from a file already
* exist in this package.
- *
+ *
* @see OutputStream
- *
- * @since Android 1.0
*/
public abstract class InputStream extends Object implements Closeable {
@@ -46,8 +44,6 @@
/**
* This constructor does nothing. It is provided for signature
* compatibility.
- *
- * @since Android 1.0
*/
public InputStream() {
/* empty */
@@ -57,11 +53,10 @@
* Returns the number of bytes that are available before this stream will
* block. This implementation always returns 0. Subclasses should override
* and indicate the correct number of bytes available.
- *
+ *
* @return the number of bytes available before blocking.
* @throws IOException
* if an error occurs in this stream.
- * @since Android 1.0
*/
public int available() throws IOException {
return 0;
@@ -70,10 +65,9 @@
/**
* Closes this stream. Concrete implementations of this class should free
* any resources during close. This implementation does nothing.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
public void close() throws IOException {
/* empty */
@@ -87,14 +81,12 @@
* <p>
* This default implementation does nothing and concrete subclasses must
* provide their own implementation.
- * </p>
- *
+ *
* @param readlimit
* the number of bytes that can be read from this stream before
* the mark is invalidated.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
public void mark(int readlimit) {
/* empty */
@@ -103,11 +95,10 @@
/**
* Indicates whether this stream supports the {@code mark()} and
* {@code reset()} methods. The default implementation returns {@code false}.
- *
+ *
* @return always {@code false}.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
public boolean markSupported() {
return false;
@@ -118,24 +109,22 @@
* range from 0 to 255. Returns -1 if the end of the stream has been
* reached. Blocks until one byte has been read, the end of the source
* stream is detected or an exception is thrown.
- *
+ *
* @return the byte read or -1 if the end of stream has been reached.
* @throws IOException
* if the stream is closed or another IOException occurs.
- * @since Android 1.0
*/
public abstract int read() throws IOException;
/**
* Reads bytes from this stream and stores them in the byte array {@code b}.
- *
+ *
* @param b
* the byte array in which to store the bytes read.
* @return the number of bytes actually read or -1 if the end of the stream
* has been reached.
* @throws IOException
* if this stream is closed or another IOException occurs.
- * @since Android 1.0
*/
public int read(byte[] b) throws IOException {
// BEGIN android-note
@@ -147,7 +136,7 @@
/**
* Reads at most {@code length} bytes from this stream and stores them in
* the byte array {@code b} starting at {@code offset}.
- *
+ *
* @param b
* the byte array in which to store the bytes read.
* @param offset
@@ -163,7 +152,6 @@
* {@code b}.
* @throws IOException
* if the stream is closed or another IOException occurs.
- * @since Android 1.0
*/
public int read(byte[] b, int offset, int length) throws IOException {
// BEGIN android-note
@@ -195,7 +183,7 @@
}
throw e;
}
- b[offset + i] = (byte)c;
+ b[offset + i] = (byte) c;
}
return length;
}
@@ -208,11 +196,9 @@
* <p>
* This implementation always throws an {@code IOException} and concrete
* subclasses should provide the proper implementation.
- * </p>
- *
+ *
* @throws IOException
* if this stream is closed or another IOException occurs.
- * @since Android 1.0
*/
public synchronized void reset() throws IOException {
throw new IOException();
@@ -225,14 +211,12 @@
* <p>
* This default implementation reads {@code n} bytes into a temporary
* buffer. Concrete subclasses should provide their own implementation.
- * </p>
- *
+ *
* @param n
* the number of bytes to skip.
* @return the number of bytes actually skipped.
* @throws IOException
* if this stream is closed or another IOException occurs.
- * @since Android 1.0
*/
public long skip(long n) throws IOException {
if (n <= 0) {
diff --git a/luni/src/main/java/java/io/InputStreamReader.java b/luni/src/main/java/java/io/InputStreamReader.java
index 0f74b14..0fdcb9a 100644
--- a/luni/src/main/java/java/io/InputStreamReader.java
+++ b/luni/src/main/java/java/io/InputStreamReader.java
@@ -26,15 +26,11 @@
import java.nio.charset.MalformedInputException;
import java.nio.charset.UnmappableCharacterException;
import java.security.AccessController;
-import java.util.HashMap;
+import org.apache.harmony.luni.util.HistoricalNamesUtil;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
-// BEGIN android-note
-// Later changes from Harmony have been integrated into this version.
-// END android-note
-
/**
* A class for turning a byte stream into a character stream. Data read from the
* source input stream is converted into characters by either a default or a
@@ -42,10 +38,8 @@
* "file.encoding" system property. {@code InputStreamReader} contains a buffer
* of bytes read from the source stream and converts these into characters as
* needed. The buffer size is 8K.
- *
+ *
* @see OutputStreamWriter
- *
- * @since Android 1.0
*/
public class InputStreamReader extends Reader {
private InputStream in;
@@ -63,10 +57,9 @@
* {@code in}. This constructor sets the character converter to the encoding
* specified in the "file.encoding" property and falls back to ISO 8859_1
* (ISO-Latin-1) if the property doesn't exist.
- *
+ *
* @param in
* the input stream from which to read characters.
- * @since Android 1.0
*/
public InputStreamReader(InputStream in) {
super(in);
@@ -85,7 +78,7 @@
* character converter that is used to decode bytes into characters is
* identified by name by {@code enc}. If the encoding cannot be found, an
* UnsupportedEncodingException error is thrown.
- *
+ *
* @param in
* the InputStream from which to read characters.
* @param enc
@@ -94,7 +87,6 @@
* if {@code enc} is {@code null}.
* @throws UnsupportedEncodingException
* if the encoding specified by {@code enc} cannot be found.
- * @since Android 1.0
*/
public InputStreamReader(InputStream in, final String enc)
throws UnsupportedEncodingException {
@@ -117,12 +109,11 @@
/**
* Constructs a new InputStreamReader on the InputStream {@code in} and
* CharsetDecoder {@code dec}.
- *
+ *
* @param in
* the source InputStream from which to read characters.
* @param dec
* the CharsetDecoder used by the character conversion.
- * @since Android 1.0
*/
public InputStreamReader(InputStream in, CharsetDecoder dec) {
super(in);
@@ -135,12 +126,11 @@
/**
* Constructs a new InputStreamReader on the InputStream {@code in} and
* Charset {@code charset}.
- *
+ *
* @param in
* the source InputStream from which to read characters.
* @param charset
* the Charset that defines the character converter
- * @since Android 1.0
*/
public InputStreamReader(InputStream in, Charset charset) {
super(in);
@@ -154,10 +144,9 @@
/**
* Closes this reader. This implementation closes the source InputStream and
* releases all local storage.
- *
+ *
* @throws IOException
* if an error occurs attempting to close this reader.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -178,10 +167,9 @@
/**
* Returns the name of the encoding used to convert bytes into characters.
* The value {@code null} is returned if this reader has been closed.
- *
+ *
* @return the name of the character converter or {@code null} if this
* reader is closed.
- * @since Android 1.0
*/
public String getEncoding() {
if (!isOpen()) {
@@ -190,172 +178,17 @@
return HistoricalNamesUtil.getHistoricalName(decoder.charset().name());
}
- /*
- * helper for getEncoding()
- */
- @SuppressWarnings("nls")
- static class HistoricalNamesUtil {
- private static HashMap<String, String> historicalNames = new HashMap<String, String>();
- static {
- historicalNames.put("Big5-HKSCS", "Big5_HKSCS");
- historicalNames.put("EUC-JP", "EUC_JP");
- historicalNames.put("EUC-KR", "EUC_KR");
- historicalNames.put("GB2312", "EUC_CN");
- historicalNames.put("IBM-Thai", "Cp838");
- historicalNames.put("IBM00858", "Cp858");
- historicalNames.put("IBM01140", "Cp1140");
- historicalNames.put("IBM01141", "Cp1141");
- historicalNames.put("IBM01142", "Cp1142");
- historicalNames.put("IBM01143", "Cp1143");
- historicalNames.put("IBM01144", "Cp1144");
- historicalNames.put("IBM01145", "Cp1145");
- historicalNames.put("IBM01146", "Cp1146");
- historicalNames.put("IBM01147", "Cp1147");
- historicalNames.put("IBM01148", "Cp1148");
- historicalNames.put("IBM01149", "Cp1149");
- historicalNames.put("IBM037", "Cp037");
- historicalNames.put("IBM1026", "Cp1026");
- historicalNames.put("IBM1047", "Cp1047");
- historicalNames.put("IBM273", "Cp273");
- historicalNames.put("IBM277", "Cp277");
- historicalNames.put("IBM278", "Cp278");
- historicalNames.put("IBM280", "Cp280");
- historicalNames.put("IBM284", "Cp284");
- historicalNames.put("IBM285", "Cp285");
- historicalNames.put("IBM297", "Cp297");
- historicalNames.put("IBM420", "Cp420");
- historicalNames.put("IBM424", "Cp424");
- historicalNames.put("IBM437", "Cp437");
- historicalNames.put("IBM500", "Cp500");
- historicalNames.put("IBM775", "Cp775");
- historicalNames.put("IBM850", "Cp850");
- historicalNames.put("IBM852", "Cp852");
- historicalNames.put("IBM855", "Cp855");
- historicalNames.put("IBM857", "Cp857");
- historicalNames.put("IBM860", "Cp860");
- historicalNames.put("IBM861", "Cp861");
- historicalNames.put("IBM862", "Cp862");
- historicalNames.put("IBM863", "Cp863");
- historicalNames.put("IBM864", "Cp864");
- historicalNames.put("IBM865", "Cp865");
- historicalNames.put("IBM866", "Cp866");
- historicalNames.put("IBM868", "Cp868");
- historicalNames.put("IBM869", "Cp869");
- historicalNames.put("IBM870", "Cp870");
- historicalNames.put("IBM871", "Cp871");
- historicalNames.put("IBM918", "Cp918");
- historicalNames.put("ISO-2022-CN", "ISO2022CN");
- historicalNames.put("ISO-2022-JP", "ISO2022JP");
- historicalNames.put("ISO-2022-KR", "ISO2022KR");
- historicalNames.put("ISO-8859-1", "ISO8859_1");
- historicalNames.put("ISO-8859-13", "ISO8859_13");
- historicalNames.put("ISO-8859-15", "ISO8859_15");
- historicalNames.put("ISO-8859-2", "ISO8859_2");
- historicalNames.put("ISO-8859-3", "ISO8859_3");
- historicalNames.put("ISO-8859-4", "ISO8859_4");
- historicalNames.put("ISO-8859-5", "ISO8859_5");
- historicalNames.put("ISO-8859-6", "ISO8859_6");
- historicalNames.put("ISO-8859-7", "ISO8859_7");
- historicalNames.put("ISO-8859-8", "ISO8859_8");
- historicalNames.put("ISO-8859-9", "ISO8859_9");
- historicalNames.put("KOI8-R", "KOI8_R");
- historicalNames.put("Shift_JIS", "SJIS");
- historicalNames.put("TIS-620", "TIS620");
- historicalNames.put("US-ASCII", "ASCII");
- historicalNames.put("UTF-16BE", "UnicodeBigUnmarked");
- historicalNames.put("UTF-16LE", "UnicodeLittleUnmarked");
- historicalNames.put("UTF-8", "UTF8");
- historicalNames.put("windows-1250", "Cp1250");
- historicalNames.put("windows-1251", "Cp1251");
- historicalNames.put("windows-1252", "Cp1252");
- historicalNames.put("windows-1253", "Cp1253");
- historicalNames.put("windows-1254", "Cp1254");
- historicalNames.put("windows-1255", "Cp1255");
- historicalNames.put("windows-1256", "Cp1256");
- historicalNames.put("windows-1257", "Cp1257");
- historicalNames.put("windows-1258", "Cp1258");
- historicalNames.put("windows-31j", "MS932");
- historicalNames.put("x-Big5-Solaris", "Big5_Solaris");
- historicalNames.put("x-euc-jp-linux", "EUC_JP_LINUX");
- historicalNames.put("x-EUC-TW", "EUC_TW");
- historicalNames.put("x-eucJP-Open", "EUC_JP_Solaris");
- historicalNames.put("x-IBM1006", "Cp1006");
- historicalNames.put("x-IBM1025", "Cp1025");
- historicalNames.put("x-IBM1046", "Cp1046");
- historicalNames.put("x-IBM1097", "Cp1097");
- historicalNames.put("x-IBM1098", "Cp1098");
- historicalNames.put("x-IBM1112", "Cp1112");
- historicalNames.put("x-IBM1122", "Cp1122");
- historicalNames.put("x-IBM1123", "Cp1123");
- historicalNames.put("x-IBM1124", "Cp1124");
- historicalNames.put("x-IBM1381", "Cp1381");
- historicalNames.put("x-IBM1383", "Cp1383");
- historicalNames.put("x-IBM33722", "Cp33722");
- historicalNames.put("x-IBM737", "Cp737");
- historicalNames.put("x-IBM856", "Cp856");
- historicalNames.put("x-IBM874", "Cp874");
- historicalNames.put("x-IBM875", "Cp875");
- historicalNames.put("x-IBM921", "Cp921");
- historicalNames.put("x-IBM922", "Cp922");
- historicalNames.put("x-IBM930", "Cp930");
- historicalNames.put("x-IBM933", "Cp933");
- historicalNames.put("x-IBM935", "Cp935");
- historicalNames.put("x-IBM937", "Cp937");
- historicalNames.put("x-IBM939", "Cp939");
- historicalNames.put("x-IBM942", "Cp942");
- historicalNames.put("x-IBM942C", "Cp942C");
- historicalNames.put("x-IBM943", "Cp943");
- historicalNames.put("x-IBM943C", "Cp943C");
- historicalNames.put("x-IBM948", "Cp948");
- historicalNames.put("x-IBM949", "Cp949");
- historicalNames.put("x-IBM949C", "Cp949C");
- historicalNames.put("x-IBM950", "Cp950");
- historicalNames.put("x-IBM964", "Cp964");
- historicalNames.put("x-IBM970", "Cp970");
- historicalNames.put("x-ISCII91", "ISCII91");
- historicalNames.put("x-ISO-2022-CN-CNS", "ISO2022CN");
- historicalNames.put("x-ISO-2022-CN-GB", "ISO2022CN");
- historicalNames.put("x-JISAutoDetect", "JISAutoDetect");
- historicalNames.put("x-MacArabic", "MacArabic");
- historicalNames.put("x-MacCentralEurope", "MacCentralEurope");
- historicalNames.put("x-MacCroatian", "MacCroatian");
- historicalNames.put("x-MacCyrillic", "MacCyrillic");
- historicalNames.put("x-MacDingbat", "MacDingbat");
- historicalNames.put("x-MacGreek", "MacGreek");
- historicalNames.put("x-MacHebrew", "MacHebrew");
- historicalNames.put("x-MacIceland", "MacIceland");
- historicalNames.put("x-MacRoman", "MacRoman");
- historicalNames.put("x-MacRomania", "MacRomania");
- historicalNames.put("x-MacSymbol", "MacSymbol");
- historicalNames.put("x-MacThai", "MacThai");
- historicalNames.put("x-MacTurkish", "MacTurkish");
- historicalNames.put("x-MacUkraine", "MacUkraine");
- historicalNames.put("x-MS950-HKSCS", "MS950_HKSCS");
- historicalNames.put("x-mswin-936", "MS936");
- historicalNames.put("x-PCK", "PCK");
- historicalNames.put("x-windows-874", "MS874");
- historicalNames.put("x-windows-949", "MS949");
- historicalNames.put("x-windows-950", "MS950");
- }
-
- public static String getHistoricalName(String name) {
- return (!historicalNames.containsKey(name) ? name : historicalNames
- .get(name));
- }
- }
-
/**
* Reads a single character from this reader and returns it as an integer
* with the two higher-order bytes set to 0. Returns -1 if the end of the
* reader has been reached. The byte value is either obtained from
* converting bytes in this reader's buffer or by first filling the buffer
* from the source InputStream and then reading from the buffer.
- *
+ *
* @return the character read or -1 if the end of the reader has been
* reached.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -377,7 +210,7 @@
* been reached. The bytes are either obtained from converting bytes in this
* reader's buffer or by first filling the buffer from the source
* InputStream and then reading from the buffer.
- *
+ *
* @param buf
* the array to store the characters read.
* @param offset
@@ -393,7 +226,6 @@
* {@code buf}.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read(char[] buf, int offset, int length) throws IOException {
@@ -465,10 +297,7 @@
if (result == CoderResult.UNDERFLOW && endOfInput) {
result = decoder.decode(bytes, out, true);
- // FIXME: should flush at first, but seems ICU has a bug that it
- // will throw IAE if some malform/unmappable bytes found during
- // decoding
- // result = decoder.flush(out);
+ decoder.flush(out);
decoder.reset();
}
if (result.isMalformed()) {
@@ -496,12 +325,11 @@
* {@code read()} is called. This implementation returns {@code true} if
* there are bytes available in the buffer or the source stream has bytes
* available.
- *
+ *
* @return {@code true} if the receiver will not block when {@code read()}
* is called, {@code false} if unknown or blocking will occur.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
@Override
public boolean ready() throws IOException {
diff --git a/luni/src/main/java/java/io/InterruptedIOException.java b/luni/src/main/java/java/io/InterruptedIOException.java
index de11d28..4d537fc 100644
--- a/luni/src/main/java/java/io/InterruptedIOException.java
+++ b/luni/src/main/java/java/io/InterruptedIOException.java
@@ -21,8 +21,6 @@
* Signals that a blocking I/O operation has been interrupted. The number of
* bytes that were transferred successfully before the interruption took place
* is stored in a field of the exception.
- *
- * @since Android 1.0
*/
public class InterruptedIOException extends IOException {
@@ -30,16 +28,12 @@
/**
* The number of bytes transferred before the I/O interrupt occurred.
- *
- * @since Android 1.0
*/
public int bytesTransferred;
/**
* Constructs a new {@code InterruptedIOException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
public InterruptedIOException() {
super();
@@ -51,7 +45,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public InterruptedIOException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/InvalidClassException.java b/luni/src/main/java/java/io/InvalidClassException.java
index 10764b5..4712bb6 100644
--- a/luni/src/main/java/java/io/InvalidClassException.java
+++ b/luni/src/main/java/java/io/InvalidClassException.java
@@ -30,8 +30,6 @@
*
* @see ObjectInputStream #readObject()
* @see ObjectInputValidation#validateObject()
- *
- * @since Android 1.0
*/
public class InvalidClassException extends ObjectStreamException {
@@ -39,8 +37,6 @@
/**
* The fully qualified name of the class that caused the problem.
- *
- * @since Android 1.0
*/
public String classname;
@@ -50,7 +46,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public InvalidClassException(String detailMessage) {
super(detailMessage);
@@ -65,7 +60,6 @@
* the name of the class that caused the exception.
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public InvalidClassException(String className, String detailMessage) {
super(detailMessage);
@@ -80,7 +74,6 @@
*
* @return the detail message, possibly concatenated with the name of the
* class that caused the problem.
- * @since Android 1.0
*/
@Override
public String getMessage() {
diff --git a/luni/src/main/java/java/io/InvalidObjectException.java b/luni/src/main/java/java/io/InvalidObjectException.java
index a2bb5df..365209d 100644
--- a/luni/src/main/java/java/io/InvalidObjectException.java
+++ b/luni/src/main/java/java/io/InvalidObjectException.java
@@ -22,8 +22,6 @@
*
* @see ObjectInputStream#registerValidation(ObjectInputValidation, int)
* @see ObjectInputValidation#validateObject()
- *
- * @since Android 1.0
*/
public class InvalidObjectException extends ObjectStreamException {
@@ -35,7 +33,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public InvalidObjectException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/LineNumberInputStream.java b/luni/src/main/java/java/io/LineNumberInputStream.java
index 3bb3997..1a40177 100644
--- a/luni/src/main/java/java/io/LineNumberInputStream.java
+++ b/luni/src/main/java/java/io/LineNumberInputStream.java
@@ -27,10 +27,8 @@
* line terminator sequences are {@code '\r'}, {@code '\n'} and {@code "\r\n"}.
* When using {@code read}, line terminator sequences are always translated into
* {@code '\n'}.
- *
+ *
* @deprecated Use {@link LineNumberReader}
- *
- * @since Android 1.0
*/
@Deprecated
public class LineNumberInputStream extends FilterInputStream {
@@ -46,10 +44,9 @@
/**
* Constructs a new {@code LineNumberInputStream} on the {@link InputStream}
* {@code in}. Line numbers are counted for all data read from this stream.
- *
+ *
* @param in
* The non-null input stream to count line numbers.
- * @since Android 1.0
*/
public LineNumberInputStream(InputStream in) {
super(in);
@@ -63,12 +60,10 @@
* which are converted into {@code '\n'} by this stream. Therefore,
* {@code available} returns only {@code in.available() / 2} bytes as
* result.
- * </p>
- *
+ *
* @return the guaranteed number of bytes available before blocking.
* @throws IOException
* if an error occurs in this stream.
- * @since Android 1.0
*/
@Override
public int available() throws IOException {
@@ -77,9 +72,8 @@
/**
* Returns the current line number for this stream. Numbering starts at 0.
- *
+ *
* @return the current line number.
- * @since Android 1.0
*/
public int getLineNumber() {
return lineNumber;
@@ -94,14 +88,12 @@
* line number count.
* <p>
* This implementation sets a mark in the filtered stream.
- * </p>
- *
+ *
* @param readlimit
* the number of bytes that can be read from this stream before
* the mark is invalidated.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public void mark(int readlimit) {
@@ -119,14 +111,13 @@
* Recognized line terminator sequences are {@code '\r'}, {@code '\n'} and
* {@code "\r\n"}. Line terminator sequences are always translated into
* {@code '\n'}.
- * </p>
- *
+ *
* @return the byte read or -1 if the end of the filtered stream has been
* reached.
* @throws IOException
* if the stream is closed or another IOException occurs.
- * @since Android 1.0
*/
+ @SuppressWarnings("fallthrough")
@Override
public int read() throws IOException {
int currentChar = lastChar;
@@ -159,8 +150,7 @@
* Recognized line terminator sequences are {@code '\r'}, {@code '\n'} and
* {@code "\r\n"}. Line terminator sequences are always translated into
* {@code '\n'}.
- * </p>
- *
+ *
* @param buffer
* the array in which to store the bytes read.
* @param offset
@@ -178,7 +168,6 @@
* if this stream is closed or another IOException occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
@@ -217,14 +206,13 @@
/**
* Resets this stream to the last marked location. It also resets the line
* count to what is was when this stream was marked.
- *
+ *
* @throws IOException
* if this stream is already closed, no mark has been set or the
* mark is no longer valid because more than {@code readlimit}
* bytes have been read since setting the mark.
* @see #mark(int)
* @see #markSupported()
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
@@ -237,12 +225,11 @@
* Sets the line number of this stream to the specified
* {@code lineNumber}. Note that this may have side effects on the
* line number associated with the last marked position.
- *
+ *
* @param lineNumber
* the new lineNumber value.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
@@ -254,7 +241,7 @@
* used. This implementation skips {@code count} number of bytes in the
* filtered stream and increments the line number count whenever line
* terminator sequences are skipped.
- *
+ *
* @param count
* the number of bytes to skip.
* @return the number of bytes actually skipped.
@@ -263,7 +250,6 @@
* @see #mark(int)
* @see #read()
* @see #reset()
- * @since Android 1.0
*/
@Override
public long skip(long count) throws IOException {
diff --git a/luni/src/main/java/java/io/LineNumberReader.java b/luni/src/main/java/java/io/LineNumberReader.java
index 8110426..8ecdd95 100644
--- a/luni/src/main/java/java/io/LineNumberReader.java
+++ b/luni/src/main/java/java/io/LineNumberReader.java
@@ -22,8 +22,6 @@
* while reading the data. The line number starts at 0 and is incremented any
* time {@code '\r'}, {@code '\n'} or {@code "\r\n"} is read. The class has an
* internal buffer for its data. The size of the buffer defaults to 8 KB.
- *
- * @since Android 1.0
*/
public class LineNumberReader extends BufferedReader {
@@ -38,10 +36,9 @@
/**
* Constructs a new LineNumberReader on the Reader {@code in}. The internal
* buffer gets the default size (8 KB).
- *
+ *
* @param in
* the Reader that is buffered.
- * @since Android 1.0
*/
public LineNumberReader(Reader in) {
super(in);
@@ -50,14 +47,13 @@
/**
* Constructs a new LineNumberReader on the Reader {@code in}. The size of
* the internal buffer is specified by the parameter {@code size}.
- *
+ *
* @param in
* the Reader that is buffered.
* @param size
* the size of the buffer to allocate.
* @throws IllegalArgumentException
* if {@code size <= 0}.
- * @since Android 1.0
*/
public LineNumberReader(Reader in, int size) {
super(in, size);
@@ -65,9 +61,8 @@
/**
* Returns the current line number for this reader. Numbering starts at 0.
- *
+ *
* @return the current line number.
- * @since Android 1.0
*/
public int getLineNumber() {
synchronized (lock) {
@@ -82,7 +77,7 @@
* position, provided that {@code readlimit} has not been surpassed. The
* line number associated with this marked position is also stored so that
* it can be restored when {@code reset()} is called.
- *
+ *
* @param readlimit
* the number of characters that can be read from this stream
* before the mark is invalidated.
@@ -90,7 +85,6 @@
* if an error occurs while setting the mark in this reader.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public void mark(int readlimit) throws IOException {
@@ -110,14 +104,13 @@
* Recognized line terminator sequences are {@code '\r'}, {@code '\n'} and
* {@code "\r\n"}. Line terminator sequences are always translated into
* {@code '\n'}.
- * </p>
- *
+ *
* @return the character read or -1 if the end of the source reader has been
* reached.
* @throws IOException
* if the reader is closed or another IOException occurs.
- * @since Android 1.0
*/
+ @SuppressWarnings("fallthrough")
@Override
public int read() throws IOException {
synchronized (lock) {
@@ -148,8 +141,7 @@
* Recognized line terminator sequences are {@code '\r'}, {@code '\n'} and
* {@code "\r\n"}. Line terminator sequences are always translated into
* {@code '\n'}.
- * </p>
- *
+ *
* @param buffer
* the array in which to store the characters read.
* @param offset
@@ -161,7 +153,6 @@
* source reader has been reached while reading.
* @throws IOException
* if this reader is closed or another IOException occurs.
- * @since Android 1.0
*/
@Override
public int read(char[] buffer, int offset, int count) throws IOException {
@@ -193,28 +184,17 @@
* represented by 0 or more characters followed by {@code '\r'},
* {@code '\n'}, {@code "\r\n"} or the end of the stream. The returned
* string does not include the newline sequence.
- *
+ *
* @return the contents of the line or {@code null} if no characters have
* been read before the end of the stream has been reached.
* @throws IOException
* if this reader is closed or another IOException occurs.
- * @since Android 1.0
*/
@Override
public String readLine() throws IOException {
synchronized (lock) {
- /* Typical Line Length */
- StringBuilder result = new StringBuilder(80);
- while (true) {
- int character = read();
- if (character == -1) {
- return result.length() != 0 ? result.toString() : null;
- }
- if (character == '\n') {
- return result.toString();
- }
- result.append((char) character);
- }
+ lineNumber++;
+ return super.readLine();
}
}
@@ -222,14 +202,13 @@
* Resets this reader to the last marked location. It also resets the line
* count to what is was when this reader was marked. This implementation
* resets the source reader.
- *
+ *
* @throws IOException
* if this reader is already closed, no mark has been set or the
* mark is no longer valid because more than {@code readlimit}
* bytes have been read since setting the mark.
* @see #mark(int)
* @see #markSupported()
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
@@ -244,12 +223,11 @@
* Sets the line number of this reader to the specified {@code lineNumber}.
* Note that this may have side effects on the line number associated with
* the last marked position.
- *
+ *
* @param lineNumber
* the new line number value.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
public void setLineNumber(int lineNumber) {
synchronized (lock) {
@@ -263,7 +241,7 @@
* is used. This implementation skips {@code count} number of characters in
* the source reader and increments the line number count whenever line
* terminator sequences are skipped.
- *
+ *
* @param count
* the number of characters to skip.
* @return the number of characters actually skipped.
@@ -274,7 +252,6 @@
* @see #mark(int)
* @see #read()
* @see #reset()
- * @since Android 1.0
*/
@Override
public long skip(long count) throws IOException {
diff --git a/luni/src/main/java/java/io/NotActiveException.java b/luni/src/main/java/java/io/NotActiveException.java
index 402eabe..51f4d3f 100644
--- a/luni/src/main/java/java/io/NotActiveException.java
+++ b/luni/src/main/java/java/io/NotActiveException.java
@@ -29,8 +29,6 @@
* <li>{@link ObjectInputStream#registerValidation(ObjectInputValidation, int)}</li>
* <li>{@link ObjectOutputStream#defaultWriteObject()}</li>
* </ul>
- *
- * @since Android 1.0
*/
public class NotActiveException extends ObjectStreamException {
@@ -39,8 +37,6 @@
/**
* Constructs a new {@code NotActiveException} with its stack trace filled
* in.
- *
- * @since Android 1.0
*/
public NotActiveException() {
super();
@@ -52,7 +48,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NotActiveException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/NotSerializableException.java b/luni/src/main/java/java/io/NotSerializableException.java
index ac57a76..f6e93a7 100644
--- a/luni/src/main/java/java/io/NotSerializableException.java
+++ b/luni/src/main/java/java/io/NotSerializableException.java
@@ -26,8 +26,6 @@
*
* @see ObjectOutput#writeObject(Object)
* @see ObjectOutputStream#writeObject(Object)
- *
- * @since Android 1.0
*/
public class NotSerializableException extends ObjectStreamException {
@@ -36,8 +34,6 @@
/**
* Constructs a new {@code NotSerializableException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
public NotSerializableException() {
super();
@@ -49,7 +45,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NotSerializableException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/ObjectInput.java b/luni/src/main/java/java/io/ObjectInput.java
index 7ca3cbe..3b32553 100644
--- a/luni/src/main/java/java/io/ObjectInput.java
+++ b/luni/src/main/java/java/io/ObjectInput.java
@@ -22,8 +22,6 @@
*
* @see ObjectInputStream
* @see ObjectOutput
- *
- * @since Android 1.0
*/
public interface ObjectInput extends DataInput {
/**
@@ -33,7 +31,6 @@
* @return the number of bytes available.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
public int available() throws IOException;
@@ -43,7 +40,6 @@
*
* @throws IOException
* if an I/O error occurs while closing the input stream.
- * @since Android 1.0
*/
public void close() throws IOException;
@@ -55,7 +51,6 @@
* @return the byte read or -1 if the end of this stream has been reached.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
public int read() throws IOException;
@@ -69,7 +64,6 @@
* reached.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
public int read(byte[] buffer) throws IOException;
@@ -89,7 +83,6 @@
* reached.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
public int read(byte[] buffer, int offset, int count) throws IOException;
@@ -102,7 +95,6 @@
* if the object's class cannot be found.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
public Object readObject() throws ClassNotFoundException, IOException;
@@ -117,7 +109,6 @@
*
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
public long skip(long toSkip) throws IOException;
}
diff --git a/luni/src/main/java/java/io/ObjectInputStream.java b/luni/src/main/java/java/io/ObjectInputStream.java
index 9483ab0..7dc87ff 100644
--- a/luni/src/main/java/java/io/ObjectInputStream.java
+++ b/luni/src/main/java/java/io/ObjectInputStream.java
@@ -17,6 +17,11 @@
package java.io;
+// BEGIN android-note
+// Harmony uses ObjectAccessors to access fields through JNI. Android has not
+// yet migrated that API. As a consequence, there's a lot of changes here...
+// END android-note
+
import java.io.EmulatedFields.ObjectSlot;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
@@ -27,14 +32,20 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.IdentityHashMap;
+import java.util.HashMap;
import java.util.Iterator;
// BEGIN android-added
import dalvik.system.VMStack;
// END android-added
+// BEGIN android-removed
+// import org.apache.harmony.misc.accessors.ObjectAccessor;
+// import org.apache.harmony.misc.accessors.AccessorFactory;
+// END android-removed
+
+import org.apache.harmony.kernel.vm.VM;
+import org.apache.harmony.luni.internal.nls.Messages;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
@@ -42,18 +53,19 @@
* A specialized {@link InputStream} that is able to read (deserialize) Java
* objects as well as primitive data types (int, byte, char etc.). The data has
* typically been saved using an ObjectOutputStream.
- *
+ *
* @see ObjectOutputStream
* @see ObjectInput
* @see Serializable
* @see Externalizable
- *
- * @since Android 1.0
*/
public class ObjectInputStream extends InputStream implements ObjectInput,
ObjectStreamConstants {
- private static InputStream emptyStream = new ByteArrayInputStream(
+ // BEGIN android-note
+ // this is non-static to avoid sync contention. Would static be faster?
+ // END android-note
+ private InputStream emptyStream = new ByteArrayInputStream(
new byte[0]);
// To put into objectsRead when reading unsharedObject
@@ -85,7 +97,7 @@
private boolean enableResolve;
// Table mapping Integer (handle) -> Object
- private Hashtable<Integer, Object> objectsRead;
+ private HashMap<Integer, Object> objectsRead;
// Used by defaultReadObject
private Object currentObject;
@@ -109,10 +121,8 @@
// Handle for the current class descriptor
private Integer descriptorHandle;
- // cache for readResolve methods
- private IdentityHashMap<Class<?>, Object> readResolveCache;
-
- private static final Hashtable<String, Class<?>> PRIMITIVE_CLASSES = new Hashtable<String, Class<?>>();
+ private static final HashMap<String, Class<?>> PRIMITIVE_CLASSES =
+ new HashMap<String, Class<?>>();
static {
PRIMITIVE_CLASSES.put("byte", byte.class); //$NON-NLS-1$
@@ -125,6 +135,10 @@
PRIMITIVE_CLASSES.put("double", double.class); //$NON-NLS-1$
}
+ // BEGIN android-removed
+ // private ObjectAccessor accessor = AccessorFactory.getObjectAccessor();
+ // END android-removed
+
// Internal type used to keep track of validators & corresponding priority
static class InputValidationDesc {
ObjectInputValidation validator;
@@ -135,22 +149,19 @@
/**
* GetField is an inner class that provides access to the persistent fields
* read from the source stream.
- *
- * @since Android 1.0
*/
public abstract static class GetField {
/**
* Gets the ObjectStreamClass that describes a field.
- *
+ *
* @return the descriptor class for a serialized field.
- * @since Android 1.0
*/
public abstract ObjectStreamClass getObjectStreamClass();
/**
* Indicates if the field identified by {@code name} is defaulted. This
* means that it has no value in this stream.
- *
+ *
* @param name
* the name of the field to check.
* @return {@code true} if the field is defaulted, {@code false}
@@ -160,7 +171,6 @@
* @throws IOException
* if an error occurs while reading from the source input
* stream.
- * @since Android 1.0
*/
public abstract boolean defaulted(String name) throws IOException,
IllegalArgumentException;
@@ -168,7 +178,7 @@
/**
* Gets the value of the boolean field identified by {@code name} from
* the persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -181,7 +191,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code boolean}.
- * @since Android 1.0
*/
public abstract boolean get(String name, boolean defaultValue)
throws IOException, IllegalArgumentException;
@@ -189,7 +198,7 @@
/**
* Gets the value of the character field identified by {@code name} from
* the persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -202,7 +211,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code char}.
- * @since Android 1.0
*/
public abstract char get(String name, char defaultValue)
throws IOException, IllegalArgumentException;
@@ -210,7 +218,7 @@
/**
* Gets the value of the byte field identified by {@code name} from the
* persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -223,7 +231,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code byte}.
- * @since Android 1.0
*/
public abstract byte get(String name, byte defaultValue)
throws IOException, IllegalArgumentException;
@@ -231,7 +238,7 @@
/**
* Gets the value of the short field identified by {@code name} from the
* persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -244,7 +251,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code short}.
- * @since Android 1.0
*/
public abstract short get(String name, short defaultValue)
throws IOException, IllegalArgumentException;
@@ -252,7 +258,7 @@
/**
* Gets the value of the integer field identified by {@code name} from
* the persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -265,15 +271,14 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code int}.
- * @since Android 1.0
*/
public abstract int get(String name, int defaultValue)
throws IOException, IllegalArgumentException;
- /**
+ /**
* Gets the value of the long field identified by {@code name} from the
* persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -286,7 +291,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code long}.
- * @since Android 1.0
*/
public abstract long get(String name, long defaultValue)
throws IOException, IllegalArgumentException;
@@ -294,7 +298,7 @@
/**
* Gets the value of the float field identified by {@code name} from the
* persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -307,7 +311,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code float} is
* not {@code char}.
- * @since Android 1.0
*/
public abstract float get(String name, float defaultValue)
throws IOException, IllegalArgumentException;
@@ -315,7 +318,7 @@
/**
* Gets the value of the double field identified by {@code name} from
* the persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -328,7 +331,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code double}.
- * @since Android 1.0
*/
public abstract double get(String name, double defaultValue)
throws IOException, IllegalArgumentException;
@@ -336,7 +338,7 @@
/**
* Gets the value of the object field identified by {@code name} from
* the persistent field.
- *
+ *
* @param name
* the name of the field to get.
* @param defaultValue
@@ -349,7 +351,6 @@
* @throws IllegalArgumentException
* if the type of the field identified by {@code name} is
* not {@code Object}.
- * @since Android 1.0
*/
public abstract Object get(String name, Object defaultValue)
throws IOException, IllegalArgumentException;
@@ -359,14 +360,13 @@
* Constructs a new ObjectInputStream. This default constructor can be used
* by subclasses that do not want to use the public constructor if it
* allocates unneeded data.
- *
+ *
* @throws IOException
* if an error occurs when creating this stream.
* @throws SecurityException
* if a security manager is installed and it denies subclassing
* this class.
* @see SecurityManager#checkPermission(java.security.Permission)
- * @since Android 1.0
*/
protected ObjectInputStream() throws IOException, SecurityException {
super();
@@ -382,7 +382,7 @@
/**
* Constructs a new ObjectInputStream that reads from the InputStream
* {@code input}.
- *
+ *
* @param input
* the non-null source InputStream to filter reads on.
* @throws IOException
@@ -393,7 +393,6 @@
* @throws SecurityException
* if a security manager is installed and it denies subclassing
* this class.
- * @since Android 1.0
*/
public ObjectInputStream(InputStream input)
throws StreamCorruptedException, IOException {
@@ -437,7 +436,6 @@
primitiveTypes = new DataInputStream(this);
enableResolve = false;
this.subclassOverridingImplementation = false;
- this.readResolveCache = new IdentityHashMap<Class<?>, Object>();
resetState();
nestedLevels = 0;
// So read...() methods can be used by
@@ -452,12 +450,11 @@
* Returns the number of bytes of primitive data that can be read from this
* stream without blocking. This method should not be used at any arbitrary
* position; just when reading primitive data types (int, char etc).
- *
+ *
* @return the number of available primitive data bytes.
* @throws IOException
* if any I/O problem occurs while computing the available
* bytes.
- * @since Android 1.0
*/
@Override
public int available() throws IOException {
@@ -470,7 +467,7 @@
* Checks to if it is ok to read primitive types from this stream at
* this point. One is not supposed to read primitive types when about to
* read an object, for example, so an exception has to be thrown.
- *
+ *
* @throws IOException
* If any IO problem occurred when trying to read primitive type
* or if it is illegal to read primitive types
@@ -514,10 +511,9 @@
/**
* Closes this stream. This implementation closes the source stream.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -528,7 +524,7 @@
* Default method to read objects from this stream. Serializable fields
* defined in the object's class and superclasses are read from the source
* stream.
- *
+ *
* @throws ClassNotFoundException
* if the object's class cannot be found.
* @throws IOException
@@ -536,7 +532,6 @@
* @throws NotActiveException
* if this method is not called from {@code readObject()}.
* @see ObjectOutputStream#defaultWriteObject
- * @since Android 1.0
*/
public void defaultReadObject() throws IOException, ClassNotFoundException,
NotActiveException {
@@ -552,7 +547,7 @@
* Enables object replacement for this stream. By default this is not
* enabled. Only trusted subclasses (loaded with system class loader) are
* allowed to change this status.
- *
+ *
* @param enable
* {@code true} to enable object replacement; {@code false} to
* disable it.
@@ -562,7 +557,6 @@
* object replacement for this stream.
* @see #resolveObject
* @see ObjectOutputStream#enableReplaceObject
- * @since Android 1.0
*/
protected boolean enableResolveObject(boolean enable)
throws SecurityException {
@@ -581,7 +575,7 @@
/**
* Checks if two classes belong to the same package.
- *
+ *
* @param c1
* one of the classes to test.
* @param c2
@@ -594,12 +588,9 @@
String nameC2 = c2.getName();
int indexDotC1 = nameC1.lastIndexOf('.');
int indexDotC2 = nameC2.lastIndexOf('.');
- // BEGIN android-changed
- // copied from newer version of harmony
if (indexDotC1 != indexDotC2) {
return false; // cannot be in the same package if indices are not
}
- // END android-changed
// the same
if (indexDotC1 < 0) {
return true; // both of them are in default package
@@ -608,16 +599,17 @@
nameC2.substring(0, indexDotC2));
}
+ // BEGIN android-added
/**
* Create and return a new instance of class {@code instantiationClass}
* but running the constructor defined in class
* {@code constructorClass} (same as {@code instantiationClass}
* or a superclass).
- *
+ *
* Has to be native to avoid visibility rules and to be able to have
* {@code instantiationClass} not the same as
* {@code constructorClass} (no such API in java.lang.reflect).
- *
+ *
* @param instantiationClass
* The new object will be an instance of this class
* @param constructorClass
@@ -626,26 +618,27 @@
*/
private static native Object newInstance(Class<?> instantiationClass,
Class<?> constructorClass);
+ // END android-added
/**
* Return the next {@code int} handle to be used to indicate cyclic
* references being loaded from the stream.
- *
+ *
* @return the next handle to represent the next cyclic reference
*/
- private int nextHandle() {
- return this.currentHandle++;
+ private Integer nextHandle() {
+ return Integer.valueOf(this.currentHandle++);
}
/**
* Return the next token code (TC) from the receiver, which indicates what
* kind of object follows
- *
+ *
* @return the next TC from the receiver
- *
+ *
* @throws IOException
* If an IO error occurs
- *
+ *
* @see ObjectStreamConstants
*/
private byte nextTC() throws IOException {
@@ -670,12 +663,11 @@
* Reads a single byte from the source stream and returns it as an integer
* in the range from 0 to 255. Returns -1 if the end of the source stream
* has been reached. Blocks if no input is available.
- *
+ *
* @return the byte read or -1 if the end of the source stream has been
* reached.
* @throws IOException
* if an error occurs while reading from this stream.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -688,7 +680,7 @@
* in byte array {@code buffer} starting at offset {@code count}. Blocks
* until {@code count} bytes have been read, the end of the source stream is
* detected or an exception is thrown.
- *
+ *
* @param buffer
* the array in which to store the bytes read.
* @param offset
@@ -706,7 +698,6 @@
* if an error occurs while reading from this stream.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
@@ -734,9 +725,9 @@
* Reads and returns an array of raw bytes with primitive data. The array
* will have up to 255 bytes. The primitive data will be in the format
* described by {@code DataOutputStream}.
- *
+ *
* @return The primitive data read, as raw bytes
- *
+ *
* @throws IOException
* If an IO exception happened when reading the primitive data.
*/
@@ -750,9 +741,9 @@
* Reads and returns an array of raw bytes with primitive data. The array
* will have more than 255 bytes. The primitive data will be in the format
* described by {@code DataOutputStream}.
- *
+ *
* @return The primitive data read, as raw bytes
- *
+ *
* @throws IOException
* If an IO exception happened when reading the primitive data.
*/
@@ -764,14 +755,13 @@
/**
* Reads a boolean from the source stream.
- *
+ *
* @return the boolean value read from the source stream.
* @throws EOFException
* if the end of the input is reached before the read
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public boolean readBoolean() throws IOException {
return primitiveTypes.readBoolean();
@@ -779,14 +769,13 @@
/**
* Reads a byte (8 bit) from the source stream.
- *
+ *
* @return the byte value read from the source stream.
* @throws EOFException
* if the end of the input is reached before the read
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public byte readByte() throws IOException {
return primitiveTypes.readByte();
@@ -794,14 +783,13 @@
/**
* Reads a character (16 bit) from the source stream.
- *
+ *
* @return the char value read from the source stream.
* @throws EOFException
* if the end of the input is reached before the read
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public char readChar() throws IOException {
return primitiveTypes.readChar();
@@ -809,7 +797,7 @@
/**
* Reads and discards block data and objects until TC_ENDBLOCKDATA is found.
- *
+ *
* @throws IOException
* If an IO exception happened when reading the optional class
* annotation.
@@ -834,9 +822,9 @@
/**
* Reads a class descriptor (an {@code ObjectStreamClass}) from the
* stream.
- *
+ *
* @return the class descriptor read from the stream
- *
+ *
* @throws IOException
* If an IO exception happened when reading the class
* descriptor.
@@ -855,8 +843,7 @@
ObjectStreamClass streamClass = ObjectStreamClass
.lookup(proxyClass);
streamClass.setLoadFields(new ObjectStreamField[0]);
- registerObjectRead(streamClass, Integer.valueOf(nextHandle()),
- false);
+ registerObjectRead(streamClass, nextHandle(), false);
checkedSetSuperClassDesc(streamClass, readClassDesc());
return streamClass;
case TC_REFERENCE:
@@ -872,11 +859,11 @@
/**
* Reads the content of the receiver based on the previously read token
* {@code tc}.
- *
+ *
* @param tc
* The token code for the next item in the stream
* @return the object read from the stream
- *
+ *
* @throws IOException
* If an IO exception happened when reading the class
* descriptor.
@@ -922,11 +909,11 @@
/**
* Reads the content of the receiver based on the previously read token
* {@code tc}. Primitive data content is considered an error.
- *
+ *
* @param unshared
* read the object unshared
* @return the object read from the stream
- *
+ *
* @throws IOException
* If an IO exception happened when reading the class
* descriptor.
@@ -990,9 +977,9 @@
/**
* Reads the next item from the stream assuming it is a cyclic reference to
* an object previously read. Return the actual object previously read.
- *
+ *
* @return the object previously read from the stream
- *
+ *
* @throws IOException
* If an IO exception happened when reading the class
* descriptor.
@@ -1006,14 +993,13 @@
/**
* Reads a double (64 bit) from the source stream.
- *
+ *
* @return the double value read from the source stream.
* @throws EOFException
* if the end of the input is reached before the read
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public double readDouble() throws IOException {
return primitiveTypes.readDouble();
@@ -1029,9 +1015,9 @@
* When exceptions are found normally in the object graph, they are loaded
* as a regular object, and not by this method. In that case, the set of
* "known objects" is not reset.
- *
+ *
* @return the exception read
- *
+ *
* @throws IOException
* If an IO exception happened when reading the exception
* object.
@@ -1064,17 +1050,17 @@
/**
* Reads a collection of field descriptors (name, type name, etc) for the
* class descriptor {@code cDesc} (an {@code ObjectStreamClass})
- *
+ *
* @param cDesc
* The class descriptor (an {@code ObjectStreamClass})
* for which to write field information
- *
+ *
* @throws IOException
* If an IO exception happened when reading the field
* descriptors.
* @throws ClassNotFoundException
* If a class for one of the field types could not be found
- *
+ *
* @see #readObject()
*/
private void readFieldDescriptors(ObjectStreamClass cDesc)
@@ -1109,17 +1095,45 @@
enableResolve = old;
}
}
+
+ classSig = formatClassSig(classSig);
ObjectStreamField f = new ObjectStreamField(classSig, fieldName);
fields[i] = f;
}
}
+ /*
+ * Format the class signature for ObjectStreamField, for example,
+ * "[L[Ljava.lang.String;;" is converted to "[Ljava.lang.String;"
+ */
+ private static String formatClassSig(String classSig) {
+ int start = 0;
+ int end = classSig.length();
+
+ if (end <= 0) {
+ return classSig;
+ }
+
+ while (classSig.startsWith("[L", start) //$NON-NLS-1$
+ && classSig.charAt(end - 1) == ';') {
+ start += 2;
+ end--;
+ }
+
+ if (start > 0) {
+ start -= 2;
+ end++;
+ return classSig.substring(start, end);
+ }
+ return classSig;
+ }
+
/**
* Reads the persistent fields of the object that is currently being read
* from the source stream. The values read are stored in a GetField object
* that provides access to the persistent fields. This GetField object is
* then returned.
- *
+ *
* @return the GetField object from which persistent fields can be accessed
* by name.
* @throws ClassNotFoundException
@@ -1129,7 +1143,6 @@
* if an error occurs while reading from this stream.
* @throws NotActiveException
* if this stream is currently not reading an object.
- * @since Android 1.0
*/
public GetField readFields() throws IOException, ClassNotFoundException,
NotActiveException {
@@ -1146,11 +1159,11 @@
/**
* Reads a collection of field values for the emulated fields
* {@code emulatedFields}
- *
+ *
* @param emulatedFields
* an {@code EmulatedFieldsForLoading}, concrete subclass
* of {@code GetField}
- *
+ *
* @throws IOException
* If an IO exception happened when reading the field values.
* @throws InvalidClassException
@@ -1159,7 +1172,7 @@
* @throws OptionalDataException
* If optional data could not be found when reading the
* exception graph
- *
+ *
* @see #readFields
* @see #readObject()
*/
@@ -1206,13 +1219,13 @@
* This is the default mechanism, when emulated fields (an
* {@code GetField}) are not used. Actual values to load are stored
* directly into the object {@code obj}.
- *
+ *
* @param obj
* Instance in which the fields will be set.
* @param classDesc
* A class descriptor (an {@code ObjectStreamClass})
* defining which fields should be loaded.
- *
+ *
* @throws IOException
* If an IO exception happened when reading the field values.
* @throws InvalidClassException
@@ -1223,7 +1236,7 @@
* exception graph
* @throws ClassNotFoundException
* If a class of an object being de-serialized can not be found
- *
+ *
* @see #readFields
* @see #readObject()
*/
@@ -1238,9 +1251,16 @@
}
for (ObjectStreamField fieldDesc : fields) {
+
+ // BEGIN android-removed
+ // // get associated Field
+ // long fieldID = fieldDesc.getFieldID(accessor, declaringClass);
+ // END android-removed
+
// Code duplication starts, just because Java is typed
if (fieldDesc.isPrimitive()) {
try {
+ // BEGIN android-changed
switch (fieldDesc.getTypeCode()) {
case 'B':
setField(obj, declaringClass, fieldDesc.getName(),
@@ -1278,19 +1298,22 @@
throw new StreamCorruptedException(Msg.getString(
"K00d5", fieldDesc.getTypeCode())); //$NON-NLS-1$
}
+ // END android-changed
} catch (NoSuchFieldError err) {
}
} else {
// Object type (array included).
String fieldName = fieldDesc.getName();
boolean setBack = false;
+ // BEGIN android-added
ObjectStreamField field = classDesc.getField(fieldName);
- if (mustResolve && field == null) {
+ // END android-added
+ if (mustResolve && fieldDesc == null) {
setBack = true;
mustResolve = false;
}
Object toSet;
- if (field != null && field.isUnshared()) {
+ if (fieldDesc != null && fieldDesc.isUnshared()) {
toSet = readUnshared();
} else {
toSet = readObject();
@@ -1298,18 +1321,9 @@
if (setBack) {
mustResolve = true;
}
- if (field != null) {
+ if (fieldDesc != null) {
if (toSet != null) {
- // BEGIN android-removed
- // Class<?> fieldType = field.getType();
- // END android-removed
- // BEGIN android-added
- // Originally getTypeInternal() was called getType().
- // After the semantics of getType() changed inside
- // Harmony, the check below wasn't adjusted and didn't
- // work anymore.
- Class<?> fieldType = field.getTypeInternal();
- // END android-added
+ Class<?> fieldType = fieldDesc.getType();
Class<?> valueType = toSet.getClass();
if (!fieldType.isAssignableFrom(valueType)) {
throw new ClassCastException(Msg.getString(
@@ -1319,8 +1333,10 @@
+ fieldName }));
}
try {
+ // BEGIN android-changed
objSetField(obj, declaringClass, fieldName, field
.getTypeString(), toSet);
+ // END android-changed
} catch (NoSuchFieldError e) {
// Ignored
}
@@ -1332,14 +1348,13 @@
/**
* Reads a float (32 bit) from the source stream.
- *
+ *
* @return the float value read from the source stream.
* @throws EOFException
* if the end of the input is reached before the read
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public float readFloat() throws IOException {
return primitiveTypes.readFloat();
@@ -1348,7 +1363,7 @@
/**
* Reads bytes from the source stream into the byte array {@code buffer}.
* This method will block until {@code buffer.length} bytes have been read.
- *
+ *
* @param buffer
* the array in which to store the bytes read.
* @throws EOFException
@@ -1356,7 +1371,6 @@
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public void readFully(byte[] buffer) throws IOException {
primitiveTypes.readFully(buffer);
@@ -1366,7 +1380,7 @@
* Reads bytes from the source stream into the byte array {@code buffer}.
* This method will block until {@code length} number of bytes have been
* read.
- *
+ *
* @param buffer
* the byte array in which to store the bytes read.
* @param offset
@@ -1379,7 +1393,6 @@
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public void readFully(byte[] buffer, int offset, int length)
throws IOException {
@@ -1394,13 +1407,13 @@
* (corresponding to class descriptor {@code classDesc}) defines
* private instance method {@code readObject} it will be used to load
* field values.
- *
+ *
* @param object
* Instance into which stored field values loaded.
* @param classDesc
* A class descriptor (an {@code ObjectStreamClass})
* defining which fields should be loaded.
- *
+ *
* @throws IOException
* If an IO exception happened when reading the field values in
* the hierarchy.
@@ -1409,7 +1422,7 @@
* @throws NotActiveException
* If {@code defaultReadObject} is called from the wrong
* context.
- *
+ *
* @see #defaultReadObject
* @see #readObject()
*/
@@ -1449,7 +1462,7 @@
int index = findStreamSuperclass(superclass, streamClassList,
lastIndex);
if (index == -1) {
- readObjectNoData(object, superclass);
+ readObjectNoData(object, superclass, ObjectStreamClass.lookupStreamClass(superclass));
} else {
for (int j = lastIndex; j <= index; j++) {
readObjectForClass(object, streamClassList.get(j));
@@ -1483,16 +1496,13 @@
return -1;
}
- private void readObjectNoData(Object object, Class<?> cl)
+ private void readObjectNoData(Object object, Class<?> cl, ObjectStreamClass classDesc)
throws ObjectStreamException {
- if (!ObjectStreamClass.isSerializable(cl)) {
+ if (!classDesc.isSerializable()) {
return;
}
-
- final Method readMethod = ObjectStreamClass
- .getPrivateReadObjectNoDataMethod(cl);
- if (readMethod != null) {
- AccessController.doPrivileged(new PriviAction<Object>(readMethod));
+ if (classDesc.hasMethodReadObjectNoData()){
+ final Method readMethod = classDesc.getMethodReadObjectNoData();
try {
readMethod.invoke(object, new Object[0]);
} catch (InvocationTargetException e) {
@@ -1507,6 +1517,7 @@
throw new RuntimeException(e.toString());
}
}
+
}
private void readObjectForClass(Object object, ObjectStreamClass classDesc)
@@ -1518,12 +1529,12 @@
boolean hadWriteMethod = (classDesc.getFlags() & SC_WRITE_METHOD) > 0;
Class<?> targetClass = classDesc.forClass();
+
final Method readMethod;
if (targetClass == null || !mustResolve) {
readMethod = null;
} else {
- readMethod = ObjectStreamClass
- .getPrivateReadObjectMethod(targetClass);
+ readMethod = classDesc.getMethodReadObject();
}
try {
if (readMethod != null) {
@@ -1562,30 +1573,27 @@
/**
* Reads an integer (32 bit) from the source stream.
- *
+ *
* @return the integer value read from the source stream.
* @throws EOFException
* if the end of the input is reached before the read
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public int readInt() throws IOException {
return primitiveTypes.readInt();
}
/**
- * Reads the next line from the source stream. Lines are terminated by
+ * Reads the next line from the source stream. Lines are terminated by
* {@code '\r'}, {@code '\n'}, {@code "\r\n"} or an {@code EOF}.
- *
+ *
* @return the string read from the source stream.
* @throws IOException
* if an error occurs while reading from the source stream.
* @deprecated Use {@link BufferedReader}
- * @since Android 1.0
*/
- @SuppressWarnings("deprecation")
@Deprecated
public String readLine() throws IOException {
return primitiveTypes.readLine();
@@ -1593,14 +1601,13 @@
/**
* Reads a long (64 bit) from the source stream.
- *
+ *
* @return the long value read from the source stream.
* @throws EOFException
* if the end of the input is reached before the read
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public long readLong() throws IOException {
return primitiveTypes.readLong();
@@ -1609,11 +1616,11 @@
/**
* Read a new array from the receiver. It is assumed the array has not been
* read yet (not a cyclic reference). Return the array read.
- *
+ *
* @param unshared
* read the object unshared
* @return the array read
- *
+ *
* @throws IOException
* If an IO exception happened when reading the array.
* @throws ClassNotFoundException
@@ -1629,7 +1636,7 @@
throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
}
- Integer newHandle = Integer.valueOf(nextHandle());
+ Integer newHandle = nextHandle();
// Array size
int size = input.readInt();
@@ -1690,6 +1697,10 @@
// Array of Objects
Object[] objectArray = (Object[]) result;
for (int i = 0; i < size; i++) {
+ // TODO: This place is the opportunity for enhancement
+ // We can implement writing elements through fast-path,
+ // without setting up the context (see readObject()) for
+ // each element with public API
objectArray[i] = readObject();
}
}
@@ -1703,11 +1714,11 @@
/**
* Reads a new class from the receiver. It is assumed the class has not been
* read yet (not a cyclic reference). Return the class read.
- *
+ *
* @param unshared
* read the object unshared
* @return The {@code java.lang.Class} read from the stream.
- *
+ *
* @throws IOException
* If an IO exception happened when reading the class.
* @throws ClassNotFoundException
@@ -1718,10 +1729,9 @@
ObjectStreamClass classDesc = readClassDesc();
if (classDesc != null) {
- Integer newHandle = Integer.valueOf(nextHandle());
Class<?> localClass = classDesc.forClass();
if (localClass != null) {
- registerObjectRead(localClass, newHandle, unshared);
+ registerObjectRead(localClass, nextHandle(), unshared);
}
return localClass;
}
@@ -1753,11 +1763,9 @@
ObjectStreamClass classDesc;
primitiveData = input;
Integer oldHandle = descriptorHandle;
- descriptorHandle = Integer.valueOf(nextHandle());
+ descriptorHandle = nextHandle();
classDesc = readClassDescriptor();
- if (descriptorHandle != null) {
- registerObjectRead(classDesc, descriptorHandle, false);
- }
+ registerObjectRead(classDesc, descriptorHandle, false);
descriptorHandle = oldHandle;
primitiveData = emptyStream;
classDesc.setClass(resolveClass(classDesc));
@@ -1789,7 +1797,7 @@
ClassNotFoundException, IOException {
// read classdesc for Enum first
ObjectStreamClass classDesc = readEnumDesc();
- Integer newHandle = Integer.valueOf(nextHandle());
+ Integer newHandle = nextHandle();
// read name after class desc
String name;
byte tc = nextTC();
@@ -1818,11 +1826,11 @@
* Reads a new class descriptor from the receiver. It is assumed the class
* descriptor has not been read yet (not a cyclic reference). Return the
* class descriptor read.
- *
+ *
* @param unshared
* read the object unshared
* @return The {@code ObjectStreamClass} read from the stream.
- *
+ *
* @throws IOException
* If an IO exception happened when reading the class
* descriptor.
@@ -1835,21 +1843,17 @@
// subclasses during readClassDescriptor()
primitiveData = input;
Integer oldHandle = descriptorHandle;
- descriptorHandle = Integer.valueOf(nextHandle());
+ descriptorHandle = nextHandle();
ObjectStreamClass newClassDesc = readClassDescriptor();
- if (descriptorHandle != null) {
- registerObjectRead(newClassDesc, descriptorHandle, unshared);
- }
+ registerObjectRead(newClassDesc, descriptorHandle, unshared);
descriptorHandle = oldHandle;
primitiveData = emptyStream;
// We need to map classDesc to class.
try {
newClassDesc.setClass(resolveClass(newClassDesc));
- // Check SUIDs
- verifySUID(newClassDesc);
- // Check base name of the class
- verifyBaseName(newClassDesc);
+ // Check SUIDs & base name of the class
+ verifyAndInit(newClassDesc);
} catch (ClassNotFoundException e) {
if (mustResolve) {
throw e;
@@ -1877,9 +1881,9 @@
* Reads a new proxy class descriptor from the receiver. It is assumed the
* proxy class descriptor has not been read yet (not a cyclic reference).
* Return the proxy class descriptor read.
- *
+ *
* @return The {@code Class} read from the stream.
- *
+ *
* @throws IOException
* If an IO exception happened when reading the class
* descriptor.
@@ -1901,33 +1905,33 @@
/**
* Reads a class descriptor from the source stream.
- *
+ *
* @return the class descriptor read from the source stream.
* @throws ClassNotFoundException
* if a class for one of the objects cannot be found.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
protected ObjectStreamClass readClassDescriptor() throws IOException,
ClassNotFoundException {
ObjectStreamClass newClassDesc = new ObjectStreamClass();
String name = input.readUTF();
- if ("".equals(name)) {
- throw new IOException("The stream is corrupted.");
+ if (name.length() == 0) {
+ // luni.07 = The stream is corrupted
+ throw new IOException(Messages.getString("luni.07")); //$NON-NLS-1$
}
newClassDesc.setName(name);
newClassDesc.setSerialVersionUID(input.readLong());
newClassDesc.setFlags(input.readByte());
- // We must register the class descriptor before reading field
- // descriptors.
- // if called outside of readObject, the descriptorHandle might be null
- descriptorHandle = (null == descriptorHandle ? Integer
- .valueOf(nextHandle()) : descriptorHandle);
+ /*
+ * We must register the class descriptor before reading field
+ * descriptors. If called outside of readObject, the descriptorHandle
+ * might be null.
+ */
+ descriptorHandle = (null == descriptorHandle ? nextHandle() : descriptorHandle);
registerObjectRead(newClassDesc, descriptorHandle, false);
- descriptorHandle = null;
readFieldDescriptors(newClassDesc);
return newClassDesc;
@@ -1936,7 +1940,7 @@
/**
* Creates the proxy class that implements the interfaces specified in
* {@code interfaceNames}.
- *
+ *
* @param interfaceNames
* the interfaces used to create the proxy class.
* @return the proxy class.
@@ -1946,16 +1950,15 @@
* @throws IOException
* if an error occurs while reading from the source stream.
* @see ObjectOutputStream#annotateProxyClass(Class)
- * @since Android 1.0
*/
protected Class<?> resolveProxyClass(String[] interfaceNames)
throws IOException, ClassNotFoundException {
- // BEGIN android-removed
+ // TODO: This method is opportunity for performance enhancement
+ // We can cache the classloader and recently used interfaces.
+ // BEGIN android-changed
// ClassLoader loader = VM.getNonBootstrapClassLoader();
- // END android-removed
- // BEGIN android-added
ClassLoader loader = ClassLoader.getSystemClassLoader();
- // END android-added
+ // END android-changed
Class<?>[] interfaces = new Class<?>[interfaceNames.length];
for (int i = 0; i < interfaceNames.length; i++) {
interfaces[i] = Class.forName(interfaceNames[i], false, loader);
@@ -1969,61 +1972,19 @@
/**
* Write a new handle describing a cyclic reference from the stream.
- *
+ *
* @return the handle read
- *
+ *
* @throws IOException
* If an IO exception happened when reading the handle
*/
- private Integer readNewHandle() throws IOException {
- return Integer.valueOf(input.readInt());
+ private int readNewHandle() throws IOException {
+ return input.readInt();
}
- /**
- * Read a new object from the stream. It is assumed the object has not been
- * loaded yet (not a cyclic reference). Return the object read.
- *
- * If the object implements {@code Externalizable} its
- * {@code readExternal} is called. Otherwise, all fields described by
- * the class hierarchy are loaded. Each class can define how its declared
- * instance fields are loaded by defining a private method
- * {@code readObject}
- *
- * @param unshared
- * read the object unshared
- * @return the object read
- *
- * @throws IOException
- * If an IO exception happened when reading the object.
- * @throws OptionalDataException
- * If optional data could not be found when reading the object
- * graph
- * @throws ClassNotFoundException
- * If a class for one of the objects could not be found
- */
- private Object readNewObject(boolean unshared)
- throws OptionalDataException, ClassNotFoundException, IOException {
- ObjectStreamClass classDesc = readClassDesc();
+ private Class<?> resolveConstructorClass(Class<?> objectClass, boolean wasSerializable, boolean wasExternalizable)
+ throws OptionalDataException, ClassNotFoundException, IOException {
- if (classDesc == null) {
- throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
- }
-
- Integer newHandle = Integer.valueOf(nextHandle());
-
- // Note that these values come from the Stream, and in fact it could be
- // that the classes have been changed so that the info below now
- // conflicts with the newer class
- boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0;
- boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0;
-
- // Maybe we should cache the values above in classDesc ? It may be the
- // case that when reading classDesc we may need to read more stuff
- // depending on the values above
- Class<?> objectClass = classDesc.forClass();
-
- Object result, registeredResult = null;
- if (objectClass != null) {
// The class of the instance may not be the same as the class of the
// constructor to run
// This is the constructor to run if Externalizable
@@ -2083,9 +2044,71 @@
}
}
+ return constructorClass;
+ }
+
+ /**
+ * Read a new object from the stream. It is assumed the object has not been
+ * loaded yet (not a cyclic reference). Return the object read.
+ *
+ * If the object implements <code>Externalizable</code> its
+ * <code>readExternal</code> is called. Otherwise, all fields described by
+ * the class hierarchy are loaded. Each class can define how its declared
+ * instance fields are loaded by defining a private method
+ * <code>readObject</code>
+ *
+ * @param unshared
+ * read the object unshared
+ * @return the object read
+ *
+ * @throws IOException
+ * If an IO exception happened when reading the object.
+ * @throws OptionalDataException
+ * If optional data could not be found when reading the object
+ * graph
+ * @throws ClassNotFoundException
+ * If a class for one of the objects could not be found
+ */
+ private Object readNewObject(boolean unshared)
+ throws OptionalDataException, ClassNotFoundException, IOException {
+ ObjectStreamClass classDesc = readClassDesc();
+
+ if (classDesc == null) {
+ throw new InvalidClassException(Msg.getString("K00d1")); //$NON-NLS-1$
+ }
+
+ Integer newHandle = nextHandle();
+
+ // Note that these values come from the Stream, and in fact it could be
+ // that the classes have been changed so that the info below now
+ // conflicts with the newer class
+ boolean wasExternalizable = (classDesc.getFlags() & SC_EXTERNALIZABLE) > 0;
+ boolean wasSerializable = (classDesc.getFlags() & SC_SERIALIZABLE) > 0;
+
+
+ // Maybe we should cache the values above in classDesc ? It may be the
+ // case that when reading classDesc we may need to read more stuff
+ // depending on the values above
+ Class<?> objectClass = classDesc.forClass();
+
+ Object result, registeredResult = null;
+ if (objectClass != null) {
+
+ // BEGIN android-changed
+ // long constructor = classDesc.getConstructor();
+ // if (constructor == ObjectStreamClass.CONSTRUCTOR_IS_NOT_RESOLVED) {
+ // constructor = accessor.getMethodID(resolveConstructorClass(objectClass, wasSerializable, wasExternalizable), null, new Class[0]);
+ // classDesc.setConstructor(constructor);
+ // }
+ Class constructorClass = resolveConstructorClass(objectClass, wasSerializable, wasExternalizable);
+ // END android-changed
+
// Now we know which class to instantiate and which constructor to
// run. We are allowed to run the constructor.
+ // BEGIN android-changed
+ // result = accessor.newInstance(objectClass, constructor, null);
result = newInstance(objectClass, constructorClass);
+ // END android-changed
registerObjectRead(result, newHandle, unshared);
registeredResult = result;
@@ -2131,38 +2154,23 @@
}
if (objectClass != null) {
- Object readResolveMethod = readResolveCache.get(objectClass);
- if (readResolveMethod != this) {
- if (readResolveMethod == null) {
- final Method readResolve = ObjectStreamClass
- .methodReadResolve(objectClass);
- if (readResolve == null) {
- readResolveCache.put(objectClass, this);
- readResolveMethod = null;
+
+ if (classDesc.hasMethodReadResolve()){
+ Method methodReadResolve = classDesc.getMethodReadResolve();
+ try {
+ result = methodReadResolve.invoke(result, (Object[]) null);
+ } catch (IllegalAccessException iae) {
+ } catch (InvocationTargetException ite) {
+ Throwable target = ite.getTargetException();
+ if (target instanceof ObjectStreamException) {
+ throw (ObjectStreamException) target;
+ } else if (target instanceof Error) {
+ throw (Error) target;
} else {
- // Has replacement method
- AccessController.doPrivileged(new PriviAction<Object>(
- readResolve));
- readResolveCache.put(objectClass, readResolve);
- readResolveMethod = readResolve;
+ throw (RuntimeException) target;
}
}
- if (readResolveMethod != null) {
- try {
- result = ((Method) readResolveMethod).invoke(result,
- (Object[]) null);
- } catch (IllegalAccessException iae) {
- } catch (InvocationTargetException ite) {
- Throwable target = ite.getTargetException();
- if (target instanceof ObjectStreamException) {
- throw (ObjectStreamException) target;
- } else if (target instanceof Error) {
- throw (Error) target;
- } else {
- throw (RuntimeException) target;
- }
- }
- }
+
}
}
// We get here either if class-based replacement was not needed or if it
@@ -2183,7 +2191,7 @@
/**
* Read a string encoded in {@link DataInput modified UTF-8} from the
* receiver. Return the string read.
- *
+ *
* @param unshared
* read the object unshared
* @return the string just read.
@@ -2195,8 +2203,7 @@
if (enableResolve) {
result = resolveObject(result);
}
- int newHandle = nextHandle();
- registerObjectRead(result, Integer.valueOf(newHandle), unshared);
+ registerObjectRead(result, nextHandle(), unshared);
return result;
}
@@ -2204,11 +2211,11 @@
/**
* Read a new String in UTF format from the receiver. Return the string
* read.
- *
+ *
* @param unshared
* read the object unshared
* @return the string just read.
- *
+ *
* @throws IOException
* If an IO exception happened when reading the String.
*/
@@ -2218,15 +2225,14 @@
if (enableResolve) {
result = resolveObject(result);
}
- int newHandle = nextHandle();
- registerObjectRead(result, Integer.valueOf(newHandle), unshared);
+ registerObjectRead(result, nextHandle(), unshared);
return result;
}
/**
* Reads the next object from the source stream.
- *
+ *
* @return the object read from the source stream.
* @throws ClassNotFoundException
* if the class of one of the objects in the object graph cannot
@@ -2236,7 +2242,6 @@
* @throws OptionalDataException
* if primitive data types were found instead of an object.
* @see ObjectOutputStream#writeObject(Object)
- * @since Android 1.0
*/
public final Object readObject() throws OptionalDataException,
ClassNotFoundException, IOException {
@@ -2245,7 +2250,7 @@
/**
* Reads the next unshared object from the source stream.
- *
+ *
* @return the new object read.
* @throws ClassNotFoundException
* if the class of one of the objects in the object graph cannot
@@ -2253,7 +2258,6 @@
* @throws IOException
* if an error occurs while reading from the source stream.
* @see ObjectOutputStream#writeUnshared
- * @since Android 1.0
*/
public Object readUnshared() throws IOException, ClassNotFoundException {
return readObject(true);
@@ -2347,7 +2351,7 @@
/**
* Method to be overriden by subclasses to read the next object from the
* source stream.
- *
+ *
* @return the object read from the source stream.
* @throws ClassNotFoundException
* if the class of one of the objects in the object graph cannot
@@ -2357,7 +2361,6 @@
* @throws OptionalDataException
* if primitive data types were found instead of an object.
* @see ObjectOutputStream#writeObjectOverride
- * @since Android 1.0
*/
protected Object readObjectOverride() throws OptionalDataException,
ClassNotFoundException, IOException {
@@ -2370,11 +2373,10 @@
/**
* Reads a short (16 bit) from the source stream.
- *
+ *
* @return the short value read from the source stream.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public short readShort() throws IOException {
return primitiveTypes.readShort();
@@ -2382,13 +2384,12 @@
/**
* Reads and validates the ObjectInputStream header from the source stream.
- *
+ *
* @throws IOException
* if an error occurs while reading from the source stream.
* @throws StreamCorruptedException
* if the source stream does not contain readable serialized
* objects.
- * @since Android 1.0
*/
protected void readStreamHeader() throws IOException,
StreamCorruptedException {
@@ -2401,7 +2402,7 @@
/**
* Reads an unsigned byte (8 bit) from the source stream.
- *
+ *
* @return the unsigned byte value read from the source stream packaged in
* an integer.
* @throws EOFException
@@ -2409,7 +2410,6 @@
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public int readUnsignedByte() throws IOException {
return primitiveTypes.readUnsignedByte();
@@ -2417,7 +2417,7 @@
/**
* Reads an unsigned short (16 bit) from the source stream.
- *
+ *
* @return the unsigned short value read from the source stream packaged in
* an integer.
* @throws EOFException
@@ -2425,7 +2425,6 @@
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public int readUnsignedShort() throws IOException {
return primitiveTypes.readUnsignedShort();
@@ -2434,7 +2433,7 @@
/**
* Reads a string encoded in {@link DataInput modified UTF-8} from the
* source stream.
- *
+ *
* @return the string encoded in {@link DataInput modified UTF-8} read from
* the source stream.
* @throws EOFException
@@ -2442,7 +2441,6 @@
* request can be satisfied.
* @throws IOException
* if an error occurs while reading from the source stream.
- * @since Android 1.0
*/
public String readUTF() throws IOException {
return primitiveTypes.readUTF();
@@ -2450,11 +2448,11 @@
/**
* Return the object previously read tagged with handle {@code handle}.
- *
+ *
* @param handle
* The handle that this object was assigned when it was read.
* @return the object previously read.
- *
+ *
* @throws InvalidObjectException
* If there is no previously read object with this handle
*/
@@ -2472,14 +2470,14 @@
/**
* Assume object {@code obj} has been read, and assign a handle to
* it, {@code handle}.
- *
+ *
* @param obj
* Non-null object being loaded.
* @param handle
* An Integer, the handle to this object
* @param unshared
* Boolean, indicates that caller is reading in unshared mode
- *
+ *
* @see #nextHandle
*/
private void registerObjectRead(Object obj, Integer handle, boolean unshared) {
@@ -2494,7 +2492,7 @@
* a class that implements "special" deserialization rules. It can be called
* multiple times. Validation callbacks are then done in order of decreasing
* priority, defined by {@code priority}.
- *
+ *
* @param object
* an object that can validate itself by receiving a callback.
* @param priority
@@ -2512,7 +2510,7 @@
Object instanceBeingRead = this.currentObject;
// We can't be called from just anywhere. There are rules.
- if (instanceBeingRead == null) {
+ if (instanceBeingRead == null && nestedLevels == 0) {
throw new NotActiveException();
}
if (object == null) {
@@ -2552,7 +2550,7 @@
* Reset the collection of objects already loaded by the receiver.
*/
private void resetSeenObjects() {
- objectsRead = new Hashtable<Integer, Object>();
+ objectsRead = new HashMap<Integer, Object>();
currentHandle = baseWireHandle;
primitiveData = emptyStream;
}
@@ -2572,7 +2570,7 @@
/**
* Loads the Java class corresponding to the class descriptor {@code
* osClass} that has just been read from the source stream.
- *
+ *
* @param osClass
* an ObjectStreamClass read from the source stream.
* @return a Class corresponding to the descriptor {@code osClass}.
@@ -2581,18 +2579,24 @@
* @throws IOException
* if an I/O error occurs while creating the class.
* @see ObjectOutputStream#annotateClass(Class)
- * @since Android 1.0
*/
protected Class<?> resolveClass(ObjectStreamClass osClass)
throws IOException, ClassNotFoundException {
- String className = osClass.getName();
- // if it is primitive class, for example, long.class
- Class<?> cls = PRIMITIVE_CLASSES.get(className);
+ // fastpath: obtain cached value
+ Class<?> cls = osClass.forClass();
if (null == cls) {
- // not primitive class
- // Use the first non-null ClassLoader on the stack. If null, use the
- // system class loader
- return Class.forName(className, true, callerClassLoader);
+ // slowpath: resolve the class
+ String className = osClass.getName();
+
+ // if it is primitive class, for example, long.class
+ cls = PRIMITIVE_CLASSES.get(className);
+
+ if (null == cls) {
+ // not primitive class
+ // Use the first non-null ClassLoader on the stack. If null, use
+ // the system class loader
+ cls = Class.forName(className, true, callerClassLoader);
+ }
}
return cls;
}
@@ -2602,7 +2606,7 @@
* object} with a new object. Object substitution has to be activated first
* with calling {@code enableResolveObject(true)}. This implementation just
* returns {@code object}.
- *
+ *
* @param object
* the original object for which a replacement may be defined.
* @return the replacement object for {@code object}.
@@ -2612,262 +2616,71 @@
* @see #enableResolveObject
* @see ObjectOutputStream#enableReplaceObject
* @see ObjectOutputStream#replaceObject
- * @since Android 1.0
*/
protected Object resolveObject(Object object) throws IOException {
// By default no object replacement. Subclasses can override
return object;
}
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code byte} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
+ // BEGIN android-added
+
+ /*
+ * These methods set the value of a field named fieldName of instance. The
+ * field is declared by declaringClass. The field is the same type as the
+ * value parameter.
+ *
+ * these methods could be implemented non-natively on top of
+ * java.lang.reflect at the expense of extra object creation
+ * (java.lang.reflect.Field). Otherwise Serialization could not fetch
+ * private fields, except by the use of a native method like this one.
+ *
+ * @throws NoSuchFieldError If the field does not exist.
*/
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, byte value)
throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code char} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
+
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, char value)
throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code double} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
+
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, double value)
throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code float} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, float value)
throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code int} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, int value)
throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code long} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, long value)
throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new value {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * Class which declares the field
- * @param fieldName
- * Name of the field to set
- * @param fieldTypeName
- * Name of the class defining the type of the field
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
private static native void objSetField(Object instance,
Class<?> declaringClass, String fieldName, String fieldTypeName,
Object value) throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code short} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, short value)
throws NoSuchFieldError;
- /**
- * Set a given declared field named {@code fieldName} of
- * {@code instance} to the new {@code boolean} value
- * {@code value}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect
- * implementations that support the {@code setAccessible} API, at the
- * expense of extra object creation (java.lang.reflect.Field). Otherwise
- * Serialization could not set private fields, except by the use of a native
- * method like this one.
- *
- * @param instance
- * Object whose field to set
- * @param declaringClass
- * {@code instance}'s declaring class
- * @param fieldName
- * Name of the field to set
- * @param value
- * New value for the field
- *
- * @throws NoSuchFieldError
- * If the field does not exist.
- */
private static native void setField(Object instance,
Class<?> declaringClass, String fieldName, boolean value)
throws NoSuchFieldError;
+ // END android-added
+
/**
* Skips {@code length} bytes on the source stream. This method should not
* be used to skip bytes at any arbitrary position, just when reading
* primitive data types (int, char etc).
- *
+ *
* @param length
* the number of bytes to skip.
* @return the number of bytes actually skipped.
@@ -2875,7 +2688,6 @@
* if an error occurs while skipping bytes on the source stream.
* @throws NullPointerException
* if the source stream is {@code null}.
- * @since Android 1.0
*/
public int skipBytes(int length) throws IOException {
// To be used with available. Ok to call if reading primitive buffer
@@ -2896,50 +2708,31 @@
}
/**
- * Verify if the SUID for descriptor {@code loadedStreamClass}matches
- * the SUID of the corresponding loaded class.
- *
+ * Verify if the SUID & the base name for descriptor
+ * <code>loadedStreamClass</code>matches
+ * the SUID & the base name of the corresponding loaded class and
+ * init private fields.
+ *
* @param loadedStreamClass
* An ObjectStreamClass that was loaded from the stream.
- *
+ *
* @throws InvalidClassException
* If the SUID of the stream class does not match the VM class
*/
- private void verifySUID(ObjectStreamClass loadedStreamClass)
+ private void verifyAndInit(ObjectStreamClass loadedStreamClass)
throws InvalidClassException {
+
Class<?> localClass = loadedStreamClass.forClass();
- // Instances of java.lang.Class are always Serializable, even if their
- // instances aren't (e.g. java.lang.Object.class). We cannot call lookup
- // because it returns null if the parameter represents instances that
- // cannot be serialized, and that is not what we want. If we are loading
- // an instance of java.lang.Class, we better have the corresponding
- // ObjectStreamClass.
ObjectStreamClass localStreamClass = ObjectStreamClass
.lookupStreamClass(localClass);
+
if (loadedStreamClass.getSerialVersionUID() != localStreamClass
.getSerialVersionUID()) {
throw new InvalidClassException(loadedStreamClass.getName(), Msg
.getString("K00da", loadedStreamClass, //$NON-NLS-1$
localStreamClass));
}
- }
- /**
- * Verify if the base name for descriptor {@code loadedStreamClass}
- * matches the base name of the corresponding loaded class.
- *
- * @param loadedStreamClass
- * An ObjectStreamClass that was loaded from the stream.
- *
- * @throws InvalidClassException
- * If the base name of the stream class does not match the VM
- * class
- */
- private void verifyBaseName(ObjectStreamClass loadedStreamClass)
- throws InvalidClassException {
- Class<?> localClass = loadedStreamClass.forClass();
- ObjectStreamClass localStreamClass = ObjectStreamClass
- .lookupStreamClass(localClass);
String loadedClassBaseName = getBaseName(loadedStreamClass.getName());
String localClassBaseName = getBaseName(localStreamClass.getName());
@@ -2948,10 +2741,12 @@
.getString("KA015", loadedClassBaseName, //$NON-NLS-1$
localClassBaseName));
}
+
+ loadedStreamClass.initPrivateFields(localStreamClass);
}
private static String getBaseName(String fullName) {
- int k = fullName.lastIndexOf("."); //$NON-NLS-1$
+ int k = fullName.lastIndexOf('.');
if (k == -1 || k == (fullName.length() - 1)) {
return fullName;
diff --git a/luni/src/main/java/java/io/ObjectInputValidation.java b/luni/src/main/java/java/io/ObjectInputValidation.java
index f1cae74..3dce15e 100644
--- a/luni/src/main/java/java/io/ObjectInputValidation.java
+++ b/luni/src/main/java/java/io/ObjectInputValidation.java
@@ -22,10 +22,7 @@
* example, the validation of a whole graph of objects after all of them have
* been loaded.
*
- * @see ObjectInputStream
* @see ObjectInputStream#registerValidation(ObjectInputValidation, int)
- *
- * @since Android 1.0
*/
public interface ObjectInputValidation {
/**
@@ -33,7 +30,6 @@
*
* @throws InvalidObjectException
* if this object fails to validate itself.
- * @since Android 1.0
*/
public void validateObject() throws InvalidObjectException;
}
diff --git a/luni/src/main/java/java/io/ObjectOutput.java b/luni/src/main/java/java/io/ObjectOutput.java
index cd68439..6680457 100644
--- a/luni/src/main/java/java/io/ObjectOutput.java
+++ b/luni/src/main/java/java/io/ObjectOutput.java
@@ -22,8 +22,6 @@
*
* @see ObjectOutputStream
* @see ObjectInput
- *
- * @since Android 1.0
*/
public interface ObjectOutput extends DataOutput {
/**
@@ -32,7 +30,6 @@
*
* @throws IOException
* if an error occurs while closing the target stream.
- * @since Android 1.0
*/
public void close() throws IOException;
@@ -42,7 +39,6 @@
*
* @throws IOException
* if an error occurs while flushing the target stream.
- * @since Android 1.0
*/
public void flush() throws IOException;
@@ -54,7 +50,6 @@
* the buffer to write.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void write(byte[] buffer) throws IOException;
@@ -72,7 +67,6 @@
* stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void write(byte[] buffer, int offset, int count) throws IOException;
@@ -85,7 +79,6 @@
* the byte to write.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void write(int value) throws IOException;
@@ -96,7 +89,6 @@
* the object to write.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeObject(Object obj) throws IOException;
}
diff --git a/luni/src/main/java/java/io/ObjectOutputStream.java b/luni/src/main/java/java/io/ObjectOutputStream.java
index 5da4950..e3c1471 100644
--- a/luni/src/main/java/java/io/ObjectOutputStream.java
+++ b/luni/src/main/java/java/io/ObjectOutputStream.java
@@ -20,27 +20,40 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.security.AccessController;
import java.util.IdentityHashMap;
-import org.apache.harmony.luni.util.PriviAction;
+
+// BEGIN android-note
+// Harmony uses ObjectAccessors to access fields through JNI. Android has not
+// yet migrated that API. As a consequence, there's a lot of changes here...
+// END android-note
+
+// BEGIN android-removed
+// import org.apache.harmony.misc.accessors.ObjectAccessor;
+// import org.apache.harmony.misc.accessors.AccessorFactory;
+// END android-removed
+
+import org.apache.harmony.luni.util.Msg;
/**
* A specialized {@link OutputStream} that is able to write (serialize) Java
* objects as well as primitive data types (int, byte, char etc.). The data can
* later be loaded using an ObjectInputStream.
- *
+ *
* @see ObjectInputStream
* @see ObjectOutput
* @see Serializable
* @see Externalizable
- *
- * @since Android 1.0
*/
public class ObjectOutputStream extends OutputStream implements ObjectOutput,
ObjectStreamConstants {
/*
+ * Mask to zero SC_BLOC_DATA bit.
+ */
+ private static final byte NOT_SC_BLOCK_DATA = (byte) (SC_BLOCK_DATA ^ 0xFF);
+
+ /*
* How many nested levels to writeObject. We may not need this.
*/
private int nestedLevels;
@@ -107,136 +120,129 @@
*/
private boolean subclassOverridingImplementation;
+
+ // BEGIN android-removed
+ // private ObjectAccessor accessor = AccessorFactory.getObjectAccessor();
+ // END android-removed
+
/*
- * cache for writeReplace methods
+ * Descriptor for java.lang.reflect.Proxy
*/
- private IdentityHashMap<Class<?>, Object> writeReplaceCache;
+ private final ObjectStreamClass proxyClassDesc = ObjectStreamClass.lookup(Proxy.class);
/**
* PutField is an inner class to provide access to the persistent fields
* that are written to the target stream.
- *
- * @since Android 1.0
*/
public static abstract class PutField {
/**
* Puts the value of the boolean field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, boolean value);
/**
* Puts the value of the character field identified by {@code name} to
* the persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, char value);
/**
* Puts the value of the byte field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, byte value);
/**
* Puts the value of the short field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, short value);
/**
* Puts the value of the integer field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, int value);
/**
* Puts the value of the long field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, long value);
/**
* Puts the value of the float field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, float value);
/**
* Puts the value of the double field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, double value);
/**
* Puts the value of the Object field identified by {@code name} to the
* persistent field.
- *
+ *
* @param name
* the name of the field to serialize.
* @param value
* the value that is put to the persistent field.
- * @since Android 1.0
*/
public abstract void put(String name, Object value);
/**
* Writes the fields to the target stream {@code out}.
- *
+ *
* @param out
* the target stream
* @throws IOException
* if an error occurs while writing to the target stream.
* @deprecated This method is unsafe and may corrupt the target stream.
* Use ObjectOutputStream#writeFields() instead.
- * @since Android 1.0
*/
@Deprecated
public abstract void write(ObjectOutput out) throws IOException;
@@ -246,14 +252,13 @@
* Constructs a new {@code ObjectOutputStream}. This default constructor can
* be used by subclasses that do not want to use the public constructor if
* it allocates unneeded data.
- *
+ *
* @throws IOException
* if an error occurs when creating this stream.
* @throws SecurityException
* if a security manager is installed and it denies subclassing
* this class.
* @see SecurityManager#checkPermission(java.security.Permission)
- * @since Android 1.0
*/
protected ObjectOutputStream() throws IOException, SecurityException {
super();
@@ -271,17 +276,16 @@
/**
* Constructs a new ObjectOutputStream that writes to the OutputStream
* {@code output}.
- *
+ *
* @param output
* the non-null OutputStream to filter writes on.
- *
+ *
* @throws IOException
* if an error occurs while writing the object stream
* header
* @throws SecurityException
* if a security manager is installed and it denies subclassing
* this class.
- * @since Android 1.0
*/
public ObjectOutputStream(OutputStream output) throws IOException {
Class<?> implementationClass = getClass();
@@ -316,7 +320,6 @@
this.enableReplace = false;
this.protocolVersion = PROTOCOL_VERSION_2;
this.subclassOverridingImplementation = false;
- this.writeReplaceCache = new IdentityHashMap<Class<?>, Object>();
resetState();
this.nestedException = new StreamCorruptedException();
@@ -333,13 +336,12 @@
* stream. This optional data can be read when deserializing the class
* descriptor (ObjectStreamClass) for this class from an input stream. By
* default, no extra data is saved.
- *
+ *
* @param aClass
* the class to annotate.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see ObjectInputStream#resolveClass(ObjectStreamClass)
- * @since Android 1.0
*/
protected void annotateClass(Class<?> aClass) throws IOException {
// By default no extra info is saved. Subclasses can override
@@ -349,13 +351,12 @@
* Writes optional information for a proxy class to the target stream. This
* optional data can be read when deserializing the proxy class from an
* input stream. By default, no extra data is saved.
- *
+ *
* @param aClass
* the proxy class to annotate.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see ObjectInputStream#resolveProxyClass(String[])
- * @since Android 1.0
*/
protected void annotateProxyClass(Class<?> aClass) throws IOException {
// By default no extra info is saved. Subclasses can override
@@ -377,10 +378,9 @@
/**
* Closes this stream. Any buffered data is flushed. This implementation
* closes the target stream.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -393,7 +393,7 @@
* Computes the collection of emulated fields that users can manipulate to
* store a representation different than the one declared by the class of
* the object being dumped.
- *
+ *
* @see #writeFields
* @see #writeFieldValues(EmulatedFieldsForDumping)
*/
@@ -405,13 +405,12 @@
* Default method to write objects to this stream. Serializable fields
* defined in the object's class and superclasses are written to the output
* stream.
- *
+ *
* @throws IOException
* if an error occurs while writing to the target stream.
* @throws NotActiveException
* if this method is not called from {@code writeObject()}.
* @see ObjectInputStream#defaultReadObject
- * @since Android 1.0
*/
public void defaultWriteObject() throws IOException {
// We can't be called from just anywhere. There are rules.
@@ -424,13 +423,12 @@
/**
* Writes buffered data to the target stream. This is similar to {@code
* flush} but the flush is not propagated to the target stream.
- *
+ *
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
protected void drain() throws IOException {
- if (primitiveTypes == null) {
+ if (primitiveTypes == null || primitiveTypesBuffer == null) {
return;
}
@@ -462,7 +460,7 @@
/**
* Dumps the parameter {@code obj} only if it is {@code null}
* or an object that has already been dumped previously.
- *
+ *
* @param obj
* Object to check if an instance previously dumped by this
* stream.
@@ -470,14 +468,14 @@
* method does nothing). Integer, if {@code obj} is an
* instance which has been dumped already. In this case this method
* saves the cyclic reference.
- *
+ *
* @throws IOException
* If an error occurs attempting to save {@code null} or
* a cyclic reference.
*/
private Integer dumpCycle(Object obj) throws IOException {
// If the object has been saved already, save its handle only
- Integer handle = registeredObjectHandleFor(obj);
+ Integer handle = objectsWritten.get(obj);
if (handle != null) {
writeCyclicReference(handle);
return handle;
@@ -489,7 +487,7 @@
* Enables object replacement for this stream. By default this is not
* enabled. Only trusted subclasses (loaded with system class loader) are
* allowed to change this status.
- *
+ *
* @param enable
* {@code true} to enable object replacement; {@code false} to
* disable it.
@@ -499,7 +497,6 @@
* object replacement for this stream.
* @see #replaceObject
* @see ObjectInputStream#enableResolveObject
- * @since Android 1.0
*/
protected boolean enableReplaceObject(boolean enable)
throws SecurityException {
@@ -519,11 +516,10 @@
/**
* Writes buffered data to the target stream and calls the {@code flush}
* method of the target stream.
- *
+ *
* @throws IOException
* if an error occurs while writing to or flushing the output
* stream.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -531,212 +527,64 @@
output.flush();
}
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * a boolean.
+ // BEGIN android-added
+ /*
+ * These methods get the value of a field named fieldName of object
+ * instance. The field is declared by declaringClass. The field is the same
+ * type as the method return value.
*
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
+ * these methods could be implemented non-natively on top of
+ * java.lang.reflect at the expense of extra object creation
+ * (java.lang.reflect.Field). Otherwise Serialization could not fetch
+ * private fields, except by the use of a native method like this one.
*
* @throws NoSuchFieldError If the field does not exist.
*/
+
private static native boolean getFieldBool(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * a byte
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native byte getFieldByte(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * a char.
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native char getFieldChar(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * a double.
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native double getFieldDouble(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * a float.
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native float getFieldFloat(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * an int.
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native int getFieldInt(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * a long.
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native long getFieldLong(Object instance,
Class<?> declaringClass, String fieldName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * an Object type whose name is {@code fieldTypeName}.
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @param fieldTypeName Name of the class that defines the type of this field
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native Object getFieldObj(Object instance,
Class<?> declaringClass, String fieldName, String fieldTypeName);
- /**
- * Get the value of field named
- * {@code fieldName<code> of object <code>instance}. The
- * field is declared by class {@code declaringClass}. The field is supposed to be
- * a short.
- *
- * This method could be implemented non-natively on top of java.lang.reflect implementations
- * that support the {@code setAccessible} API, at the expense of extra object creation
- * (java.lang.reflect.Field). Otherwise Serialization could not fetch private fields, except
- * by the use of a native method like this one.
- *
- * @param instance Object whose field value we want to fetch
- * @param declaringClass The class that declares the field
- * @param fieldName Name of the field we want to fetch
- * @return the value of the field
- *
- * @throws NoSuchFieldError If the field does not exist.
- */
private static native short getFieldShort(Object instance,
Class<?> declaringClass, String fieldName);
+ // END android-added
/**
- * Return the next {@code int} handle to be used to indicate cyclic
+ * Return the next <code>Integer</code> handle to be used to indicate cyclic
* references being saved to the stream.
- *
- * @return int, the next handle to represent the next cyclic reference
+ *
+ * @return the next handle to represent the next cyclic reference
*/
- private int nextHandle() {
- return this.currentHandle++;
+ private Integer nextHandle() {
+ return Integer.valueOf(this.currentHandle++);
}
/**
* Gets this stream's {@code PutField} object. This object provides access
* to the persistent fields that are eventually written to the output
* stream. It is used to transfer the values from the fields of the object
- * that is currently being written to the persistent fields.
- *
+ * that is currently being written to the persistent fields.
+ *
* @return the PutField object from which persistent fields can be accessed
* by name.
* @throws IOException
@@ -744,7 +592,6 @@
* @throws NotActiveException
* if this method is not called from {@code writeObject()}.
* @see ObjectInputStream#defaultReadObject
- * @since Android 1.0
*/
public PutField putFields() throws IOException {
// We can't be called from just anywhere. There are rules.
@@ -758,39 +605,25 @@
}
/**
- * Return the {@code Integer} handle used to tag object
- * {@code obj} as an instance that has been dumped already. Return
- * {@code null} if object {@code obj} has not been saved yet.
- *
- * @param obj
- * the object
- * @return null if object {@code obj} has not been saved yet. Integer
- * The handle that this object was assigned when it was saved.
- */
- private Integer registeredObjectHandleFor(Object obj) {
- return objectsWritten.get(obj);
- }
-
- /**
* Assume object {@code obj} has not been dumped yet, and assign a
* handle to it
- *
+ *
* @param obj
* Non-null object being dumped.
* @return the handle that this object is being assigned.
- *
+ *
* @see #nextHandle
*/
private Integer registerObjectWritten(Object obj) {
- Integer handle = Integer.valueOf(nextHandle());
- registerObjectWritten(obj, handle);
+ Integer handle = nextHandle();
+ objectsWritten.put(obj, handle);
return handle;
}
/**
* Remove the unshared object from the table, and restore any previous
* handle.
- *
+ *
* @param obj
* Non-null object being dumped.
* @param previousHandle
@@ -798,33 +631,18 @@
*/
private void removeUnsharedReference(Object obj, Integer previousHandle) {
if (previousHandle != null) {
- registerObjectWritten(obj, previousHandle);
+ objectsWritten.put(obj, previousHandle);
} else {
objectsWritten.remove(obj);
}
}
/**
- * Assume object {@code obj} has not been dumped yet, and assign a
- * handle to it, {@code handle}.
- *
- * @param obj
- * Non-null object being dumped.
- * @param handle
- * An Integer, the handle to this object
- *
- * @see #nextHandle
- */
- private void registerObjectWritten(Object obj, Integer handle) {
- objectsWritten.put(obj, handle);
- }
-
- /**
* Allows trusted subclasses to substitute the specified original {@code
* object} with a new object. Object substitution has to be activated first
* with calling {@code enableReplaceObject(true)}. This implementation just
* returns {@code object}.
- *
+ *
* @param object
* the original object for which a replacement may be defined.
* @return the replacement object for {@code object}.
@@ -834,7 +652,6 @@
* @see #enableReplaceObject
* @see ObjectInputStream#enableResolveObject
* @see ObjectInputStream#resolveObject
- * @since Android 1.0
*/
protected Object replaceObject(Object object) throws IOException {
// By default no object replacement. Subclasses can override
@@ -847,11 +664,10 @@
* point. Objects previously written are no longer remembered, so they will
* be written again (instead of a cyclical reference) if found in the object
* graph.
- *
+ *
* @throws IOException
* if {@code reset()} is called during the serialization of an
* object.
- * @since Android 1.0
*/
public void reset() throws IOException {
// First we flush what we have
@@ -869,7 +685,7 @@
* Reset the collection of objects already dumped by the receiver. If the
* objects are found again in the object graph, the receiver will dump them
* again, instead of a handle (cyclic reference).
- *
+ *
*/
private void resetSeenObjects() {
objectsWritten = new IdentityHashMap<Object, Integer>();
@@ -880,7 +696,7 @@
* Reset the receiver. The collection of objects already dumped by the
* receiver is reset, and internal structures are also reset so that the
* receiver knows it is in a fresh clean state.
- *
+ *
*/
private void resetState() {
resetSeenObjects();
@@ -889,7 +705,7 @@
/**
* Sets the specified protocol version to be used by this stream.
- *
+ *
* @param version
* the protocol version to be used. Use a {@code
* PROTOCOL_VERSION_x} constant from {@code
@@ -900,13 +716,16 @@
* if an I/O error occurs.
* @see ObjectStreamConstants#PROTOCOL_VERSION_1
* @see ObjectStreamConstants#PROTOCOL_VERSION_2
- * @since Android 1.0
*/
public void useProtocolVersion(int version) throws IOException {
+ if (!objectsWritten.isEmpty()) {
+ // KA028=Cannot set protocol version when stream in use
+ throw new IllegalStateException(Msg.getString("KA028")); //$NON-NLS-1$
+ }
if (version != ObjectStreamConstants.PROTOCOL_VERSION_1
&& version != ObjectStreamConstants.PROTOCOL_VERSION_2) {
- throw new IllegalArgumentException(org.apache.harmony.luni.util.Msg
- .getString("K00b3", version)); //$NON-NLS-1$
+ // K00b3=Unknown protocol\: {0}
+ throw new IllegalArgumentException(Msg.getString("K00b3", version)); //$NON-NLS-1$
}
protocolVersion = version;
}
@@ -914,12 +733,11 @@
/**
* Writes the entire contents of the byte array {@code buffer} to the output
* stream. Blocks until all bytes are written.
- *
+ *
* @param buffer
* the buffer to write.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer) throws IOException {
@@ -931,7 +749,7 @@
* Writes {@code count} bytes from the byte array {@code buffer} starting at
* offset {@code index} to the target stream. Blocks until all bytes are
* written.
- *
+ *
* @param buffer
* the buffer to write.
* @param offset
@@ -941,7 +759,6 @@
* stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer, int offset, int length) throws IOException {
@@ -953,12 +770,11 @@
* Writes a single byte to the target stream. Only the least significant
* byte of the integer {@code value} is written to the stream. Blocks until
* the byte is actually written.
- *
+ *
* @param value
* the byte to write.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
@Override
public void write(int value) throws IOException {
@@ -968,12 +784,11 @@
/**
* Writes a boolean to the target stream.
- *
+ *
* @param value
* the boolean value to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeBoolean(boolean value) throws IOException {
checkWritePrimitiveTypes();
@@ -982,12 +797,11 @@
/**
* Writes a byte (8 bit) to the target stream.
- *
+ *
* @param value
* the byte to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeByte(int value) throws IOException {
checkWritePrimitiveTypes();
@@ -998,12 +812,11 @@
* Writes the string {@code value} as a sequence of bytes to the target
* stream. Only the least significant byte of each character in the string
* is written.
- *
+ *
* @param value
* the string to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeBytes(String value) throws IOException {
checkWritePrimitiveTypes();
@@ -1012,12 +825,11 @@
/**
* Writes a character (16 bit) to the target stream.
- *
+ *
* @param value
* the character to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeChar(int value) throws IOException {
checkWritePrimitiveTypes();
@@ -1027,12 +839,11 @@
/**
* Writes the string {@code value} as a sequence of characters to the target
* stream.
- *
+ *
* @param value
* the string to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeChars(String value) throws IOException {
checkWritePrimitiveTypes();
@@ -1042,14 +853,14 @@
/**
* Write a class descriptor {@code classDesc} (an
* {@code ObjectStreamClass}) to the stream.
- *
+ *
* @param classDesc
* The class descriptor (an {@code ObjectStreamClass}) to
* be dumped
* @param unshared
* Write the object unshared
* @return the handle assigned to the class descriptor
- *
+ *
* @throws IOException
* If an IO exception happened when writing the class
* descriptor.
@@ -1066,12 +877,16 @@
}
if (handle == null) {
Class<?> classToWrite = classDesc.forClass();
- Integer previousHandle = objectsWritten.get(classDesc);
+ Integer previousHandle = null;
+ if (unshared) {
+ previousHandle = objectsWritten.get(classDesc);
+ }
// If we got here, it is a new (non-null) classDesc that will have
// to be registered as well
- handle = registerObjectWritten(classDesc);
+ handle = nextHandle();
+ objectsWritten.put(classDesc, handle);
- if (Proxy.isProxyClass(classToWrite)) {
+ if (classDesc.isProxy()) {
output.writeByte(TC_PROXYCLASSDESC);
Class<?>[] interfaces = classToWrite.getInterfaces();
output.writeInt(interfaces.length);
@@ -1080,7 +895,7 @@
}
annotateProxyClass(classToWrite);
output.writeByte(TC_ENDBLOCKDATA);
- writeClassDescForClass(Proxy.class);
+ writeClassDesc(proxyClassDesc, false);
if (unshared) {
// remove reference to unshared object
removeUnsharedReference(classDesc, previousHandle);
@@ -1112,31 +927,12 @@
}
/**
- * Writes a class descriptor (an {@code ObjectStreamClass}) that
- * corresponds to the {@code java.lang.Class objClass} to the stream.
- *
- * @param objClass
- * The class for which a class descriptor (an
- * {@code ObjectStreamClass}) will be dumped.
- * @return the handle assigned to the class descriptor
- *
- * @throws IOException
- * If an IO exception happened when writing the class
- * descriptor.
- *
- */
- private Integer writeClassDescForClass(Class<?> objClass)
- throws IOException {
- return writeClassDesc(ObjectStreamClass.lookup(objClass), false);
- }
-
- /**
* Writes a handle representing a cyclic reference (object previously
* dumped).
- *
+ *
* @param handle
* The Integer handle that represents an object previously seen
- *
+ *
* @throws IOException
* If an IO exception happened when writing the cyclic
* reference.
@@ -1148,12 +944,11 @@
/**
* Writes a double (64 bit) to the target stream.
- *
+ *
* @param value
* the double to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeDouble(double value) throws IOException {
checkWritePrimitiveTypes();
@@ -1164,17 +959,17 @@
* Writes a collection of field descriptors (name, type name, etc) for the
* class descriptor {@code classDesc} (an
* {@code ObjectStreamClass})
- *
+ *
* @param classDesc
* The class descriptor (an {@code ObjectStreamClass})
* for which to write field information
* @param externalizable
* true if the descriptors are externalizable
- *
+ *
* @throws IOException
* If an IO exception happened when writing the field
* descriptors.
- *
+ *
* @see #writeObject(Object)
*/
private void writeFieldDescriptors(ObjectStreamClass classDesc,
@@ -1207,13 +1002,12 @@
* Writes the fields of the object currently being written to the target
* stream. The field values are buffered in the currently active {@code
* PutField} object, which can be accessed by calling {@code putFields()}.
- *
+ *
* @throws IOException
* if an error occurs while writing to the target stream.
* @throws NotActiveException
* if there are no fields to write to the target stream.
* @see #putFields
- * @since Android 1.0
*/
public void writeFields() throws IOException {
// Has to have fields to write
@@ -1226,14 +1020,14 @@
/**
* Writes a collection of field values for the emulated fields
* {@code emulatedFields}
- *
+ *
* @param emulatedFields
* an {@code EmulatedFieldsForDumping}, concrete subclass
* of {@code PutField}
- *
+ *
* @throws IOException
* If an IO exception happened when writing the field values.
- *
+ *
* @see #writeFields
* @see #writeObject(Object)
*/
@@ -1279,32 +1073,37 @@
}
}
+
/**
* Writes a collection of field values for the fields described by class
* descriptor {@code classDesc} (an {@code ObjectStreamClass}).
* This is the default mechanism, when emulated fields (an
* {@code PutField}) are not used. Actual values to dump are fetched
* directly from object {@code obj}.
- *
+ *
* @param obj
* Instance from which to fetch field values to dump.
* @param classDesc
* A class descriptor (an {@code ObjectStreamClass})
* defining which fields should be dumped.
- *
+ *
* @throws IOException
* If an IO exception happened when writing the field values.
- *
+ *
* @see #writeObject(Object)
*/
private void writeFieldValues(Object obj, ObjectStreamClass classDesc)
throws IOException {
ObjectStreamField[] fields = classDesc.fields();
Class<?> declaringClass = classDesc.forClass();
- for (int i = 0; i < fields.length; i++) {
+ for(ObjectStreamField fieldDesc : fields) {
try {
+
+ // BEGIN android-changed
+ // // get associated Field
+ // long fieldID = fieldDesc.getFieldID(accessor, declaringClass);
+
// Code duplication starts, just because Java is typed
- ObjectStreamField fieldDesc = fields[i];
if (fieldDesc.isPrimitive()) {
switch (fieldDesc.getTypeCode()) {
case 'B':
@@ -1346,14 +1145,15 @@
}
} else {
// Object type (array included).
- Object field = getFieldObj(obj, declaringClass, fieldDesc
+ Object objField = getFieldObj(obj, declaringClass, fieldDesc
.getName(), fieldDesc.getTypeString());
if (fieldDesc.isUnshared()) {
- writeUnshared(field);
+ writeUnshared(objField);
} else {
- writeObject(field);
+ writeObject(objField);
}
}
+ // END android-changed
} catch (NoSuchFieldError nsf) {
// The user defined serialPersistentFields but did not provide
// the glue to transfer values,
@@ -1366,12 +1166,11 @@
/**
* Writes a float (32 bit) to the target stream.
- *
+ *
* @param value
* the float to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeFloat(float value) throws IOException {
checkWritePrimitiveTypes();
@@ -1386,19 +1185,19 @@
* (corresponding to class descriptor {@code classDesc}) defines
* private instance method {@code writeObject} it will be used to
* dump field values.
- *
+ *
* @param object
* Instance from which to fetch field values to dump.
* @param classDesc
* A class descriptor (an {@code ObjectStreamClass})
* defining which fields should be dumped.
- *
+ *
* @throws IOException
* If an IO exception happened when writing the field values in
* the hierarchy.
* @throws NotActiveException
* If the given object is not active
- *
+ *
* @see #defaultWriteObject
* @see #writeObject(Object)
*/
@@ -1423,14 +1222,9 @@
// See if the object has a writeObject method. If so, run it
boolean executed = false;
- Class<?> targetClass = classDesc.forClass();
try {
- final Method method = ObjectStreamClass
- .getPrivateWriteObjectMethod(targetClass);
- if (method != null) {
- // We have to be able to fetch its value, even if it is
- // private
- AccessController.doPrivileged(new PriviAction<Object>(method));
+ if (classDesc.hasMethodWriteObject()){
+ final Method method = classDesc.getMethodWriteObject();
try {
method.invoke(object, new Object[] { this });
executed = true;
@@ -1447,6 +1241,7 @@
}
}
+
if (executed) {
drain();
output.writeByte(TC_ENDBLOCKDATA);
@@ -1466,12 +1261,11 @@
/**
* Writes an integer (32 bit) to the target stream.
- *
+ *
* @param value
* the integer to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeInt(int value) throws IOException {
checkWritePrimitiveTypes();
@@ -1480,12 +1274,11 @@
/**
* Writes a long (64 bit) to the target stream.
- *
+ *
* @param value
* the long to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeLong(long value) throws IOException {
checkWritePrimitiveTypes();
@@ -1497,7 +1290,7 @@
* component type {@code componentType} into the receiver. It is
* assumed the array has not been dumped yet. Return an {@code Integer}
* that represents the handle for this object (array) which is dumped here.
- *
+ *
* @param array
* The array object to dump
* @param arrayClass
@@ -1507,20 +1300,19 @@
* A {@code java.lang.Class} representing the array
* component type
* @return the handle assigned to the array
- *
+ *
* @throws IOException
* If an IO exception happened when writing the array.
*/
- private Integer writeNewArray(Object array, Class<?> arrayClass,
+ private Integer writeNewArray(Object array, Class<?> arrayClass, ObjectStreamClass arrayClDesc,
Class<?> componentType, boolean unshared) throws IOException {
output.writeByte(TC_ARRAY);
- writeClassDescForClass(arrayClass);
+ writeClassDesc(arrayClDesc, false);
- Integer previousHandle = objectsWritten.get(array);
- Integer handle = registerObjectWritten(array);
- if (unshared) {
- // remove reference to unshared object
- removeUnsharedReference(array, previousHandle);
+ Integer handle = nextHandle();
+
+ if (!unshared) {
+ objectsWritten.put(array, handle);
}
// Now we have code duplication just because Java is typed. We have to
@@ -1585,6 +1377,10 @@
Object[] objectArray = (Object[]) array;
output.writeInt(objectArray.length);
for (int i = 0; i < objectArray.length; i++) {
+ // TODO: This place is the opportunity for enhancement
+ // We can implement writing elements through fast-path,
+ // without setting up the context (see writeObject()) for
+ // each element with public API
writeObject(objectArray[i]);
}
}
@@ -1597,11 +1393,11 @@
* descriptor ({@code ObjectStreamClass}) that corresponds to them.
* Return an {@code Integer} that represents the handle for this
* object (class) which is dumped here.
- *
+ *
* @param object
* The {@code java.lang.Class} object to dump
* @return the handle assigned to the class being dumped
- *
+ *
* @throws IOException
* If an IO exception happened when writing the class.
*/
@@ -1614,21 +1410,20 @@
// We cannot call lookup because it returns null if the parameter
// represents instances that cannot be serialized, and that is not what
// we want.
+ ObjectStreamClass clDesc = ObjectStreamClass.lookupStreamClass(object);
// The handle for the classDesc is NOT the handle for the class object
// being dumped. We must allocate a new handle and return it.
- if (object.isEnum()) {
- writeEnumDesc(object, unshared);
+ if (clDesc.isEnum()) {
+ writeEnumDesc(object, clDesc, unshared);
} else {
- writeClassDesc(ObjectStreamClass.lookupStreamClass(object),
- unshared);
+ writeClassDesc(clDesc, unshared);
}
- Integer previousHandle = objectsWritten.get(object);
- Integer handle = registerObjectWritten(object);
- if (unshared) {
- // remove reference to unshared object
- removeUnsharedReference(object, previousHandle);
+ Integer handle = nextHandle();
+
+ if (!unshared) {
+ objectsWritten.put(object, handle);
}
return handle;
@@ -1640,10 +1435,10 @@
* descriptors for the superclass chain will be dumped as well. Return an
* {@code Integer} that represents the handle for this object (class
* descriptor) which is dumped here.
- *
+ *
* @param classDesc
* The {@code ObjectStreamClass} object to dump
- *
+ *
* @throws IOException
* If an IO exception happened when writing the class
* descriptor.
@@ -1653,15 +1448,15 @@
output.writeUTF(classDesc.getName());
output.writeLong(classDesc.getSerialVersionUID());
byte flags = classDesc.getFlags();
- boolean externalizable = false;
- externalizable = ObjectStreamClass.isExternalizable(classDesc
- .forClass());
- if (protocolVersion != PROTOCOL_VERSION_1) {
- // Change for 1.2. Objects can be saved in old format
- // (PROTOCOL_VERSION_1) or in the 1.2 format (PROTOCOL_VERSION_2).
- // Nested "if" check to optimize checking. Second check is more
- // expensive.
- if (externalizable) {
+
+ boolean externalizable = classDesc.isExternalizable();
+
+ if (externalizable) {
+ if (protocolVersion == PROTOCOL_VERSION_1) {
+ flags &= NOT_SC_BLOCK_DATA;
+ } else {
+ // Change for 1.2. Objects can be saved in old format
+ // (PROTOCOL_VERSION_1) or in the 1.2 format (PROTOCOL_VERSION_2).
flags |= SC_BLOCK_DATA;
}
}
@@ -1676,12 +1471,11 @@
/**
* Writes a class descriptor to the target stream.
- *
+ *
* @param classDesc
* the class descriptor to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
protected void writeClassDescriptor(ObjectStreamClass classDesc)
throws IOException {
@@ -1695,14 +1489,14 @@
* This is used to dump the exception instance that happened (if any) when
* dumping the original object graph. The set of seen objects will be reset
* just before and just after dumping this exception object.
- *
+ *
* When exceptions are found normally in the object graph, they are dumped
* as a regular object, and not by this method. In that case, the set of
* "known objects" is not reset.
- *
+ *
* @param ex
* Exception object to dump
- *
+ *
* @throws IOException
* If an IO exception happened when writing the exception
* object.
@@ -1719,13 +1513,13 @@
* the receiver. It is assumed the object has not been dumped yet. Return an
* {@code Integer} that represents the handle for this object which
* is dumped here.
- *
+ *
* If the object implements {@code Externalizable} its
* {@code writeExternal} is called. Otherwise, all fields described
* by the class hierarchy is dumped. Each class can define how its declared
* instance fields are dumped by defining a private method
* {@code writeObject}
- *
+ *
* @param object
* The object to dump
* @param theClass
@@ -1734,11 +1528,11 @@
* @param unshared
* Write the object unshared
* @return the handle assigned to the object
- *
+ *
* @throws IOException
* If an IO exception happened when writing the object.
*/
- private Integer writeNewObject(Object object, Class<?> theClass,
+ private Integer writeNewObject(Object object, Class<?> theClass, ObjectStreamClass clDesc,
boolean unshared) throws IOException {
// Not String, not null, not array, not cyclic reference
@@ -1746,8 +1540,8 @@
currentPutField = null; // null it, to make sure one will be computed if
// needed
- boolean externalizable = ObjectStreamClass.isExternalizable(theClass);
- boolean serializable = ObjectStreamClass.isSerializable(theClass);
+ boolean externalizable = clDesc.isExternalizable();
+ boolean serializable = clDesc.isSerializable();
if (!externalizable && !serializable) {
// Object is neither externalizable nor serializable. Error
throw new NotSerializableException(theClass.getName());
@@ -1755,16 +1549,20 @@
// Either serializable or externalizable, now we can save info
output.writeByte(TC_OBJECT);
- writeClassDescForClass(theClass);
- Integer previousHandle = objectsWritten.get(object);
- Integer handle = registerObjectWritten(object);
+ writeClassDesc(clDesc, false);
+ Integer previousHandle = null;
+ if (unshared) {
+ previousHandle = objectsWritten.get(object);
+ }
+ Integer handle = nextHandle();
+ objectsWritten.put(object, handle);
// This is how we know what to do in defaultWriteObject. And it is also
// used by defaultWriteObject to check if it was called from an invalid
// place.
// It allows writeExternal to call defaultWriteObject and have it work.
currentObject = object;
- currentClass = ObjectStreamClass.lookup(theClass);
+ currentClass = clDesc;
try {
if (externalizable) {
boolean noBlockData = protocolVersion == PROTOCOL_VERSION_1;
@@ -1808,11 +1606,11 @@
* String has not been dumped yet. Return an {@code Integer} that
* represents the handle for this object (String) which is dumped here.
* Strings are saved encoded with {@link DataInput modified UTF-8}.
- *
+ *
* @param object
* the string to dump.
* @return the handle assigned to the String being dumped
- *
+ *
* @throws IOException
* If an IO exception happened when writing the String.
*/
@@ -1828,19 +1626,19 @@
}
output.writeUTFBytes(object, count);
- Integer previousHandle = objectsWritten.get(object);
- Integer handle = registerObjectWritten(object);
- if (unshared) {
- // remove reference to unshared object
- removeUnsharedReference(object, previousHandle);
+ Integer handle = nextHandle();
+
+ if (!unshared) {
+ objectsWritten.put(object, handle);
}
+
return handle;
}
/**
* Write a special tag that indicates the value {@code null} into the
* receiver.
- *
+ *
* @throws IOException
* If an IO exception happened when writing the tag for
* {@code null}.
@@ -1851,13 +1649,12 @@
/**
* Writes an object to the target stream.
- *
+ *
* @param object
* the object to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see ObjectInputStream#readObject()
- * @since Android 1.0
*/
public final void writeObject(Object object) throws IOException {
writeObject(object, false);
@@ -1868,13 +1665,12 @@
* to {@code writeObject}, except that it always writes a new object to the
* stream versus the use of back-referencing for identical objects by
* {@code writeObject}.
- *
+ *
* @param object
* the object to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
* @see ObjectInputStream#readUnshared()
- * @since Android 1.0
*/
public void writeUnshared(Object object) throws IOException {
writeObject(object, true);
@@ -1919,7 +1715,7 @@
/**
* Write object {@code object} into the receiver's underlying stream.
- *
+ *
* @param object
* The object to write
* @param unshared
@@ -1931,10 +1727,10 @@
* A boolean indicating if stream-based replacement should be
* computed (if supported) for the object.
* @return the handle assigned to the final object being dumped
- *
+ *
* @throws IOException
* If an IO exception happened when writing the object
- *
+ *
* @see ObjectInputStream#readObject()
*/
private Integer writeObjectInternal(Object object, boolean unshared,
@@ -1955,6 +1751,8 @@
// Non-null object, first time seen...
Class<?> objClass = object.getClass();
+ ObjectStreamClass clDesc = ObjectStreamClass.lookupStreamClass(objClass);
+
nestedLevels++;
try {
@@ -1969,58 +1767,41 @@
}
}
- if (ObjectStreamClass.isSerializable(object.getClass())
+ if (clDesc.isSerializable()
&& computeClassBasedReplacement) {
- Object writeReplaceMethod = writeReplaceCache.get(objClass);
- if (writeReplaceMethod != this) {
- if (writeReplaceMethod == null) {
- final Method writeReplace = ObjectStreamClass
- .methodWriteReplace(objClass);
- if (writeReplace == null) {
- writeReplaceCache.put(objClass, this);
- writeReplaceMethod = null;
+ if(clDesc.hasMethodWriteReplace()){
+ Method methodWriteReplace = clDesc.getMethodWriteReplace();
+ Object replObj = null;
+ try {
+ replObj = methodWriteReplace.invoke(object, (Object[]) null);
+ } catch (IllegalAccessException iae) {
+ replObj = object;
+ } catch (InvocationTargetException ite) {
+ // WARNING - Not sure this is the right thing to do
+ // if we can't run the method
+ Throwable target = ite.getTargetException();
+ if (target instanceof ObjectStreamException) {
+ throw (ObjectStreamException) target;
+ } else if (target instanceof Error) {
+ throw (Error) target;
} else {
- // Has replacement method
- AccessController
- .doPrivileged(new PriviAction<Object>(
- writeReplace));
- writeReplaceCache.put(objClass, writeReplace);
- writeReplaceMethod = writeReplace;
+ throw (RuntimeException) target;
}
}
- if (writeReplaceMethod != null) {
- Object classBasedReplacement;
- try {
- classBasedReplacement = ((Method) writeReplaceMethod)
- .invoke(object, (Object[]) null);
- } catch (IllegalAccessException iae) {
- classBasedReplacement = object;
- } catch (InvocationTargetException ite) {
- // WARNING - Not sure this is the right thing to do
- // if we can't run the method
- Throwable target = ite.getTargetException();
- if (target instanceof ObjectStreamException) {
- throw (ObjectStreamException) target;
- } else if (target instanceof Error) {
- throw (Error) target;
- } else {
- throw (RuntimeException) target;
- }
+ if (replObj != object) {
+ // All over, class-based replacement off this time.
+ Integer replacementHandle = writeObjectInternal(
+ replObj, false, false,
+ computeStreamReplacement);
+ // Make the original object also map to the same
+ // handle.
+ if (replacementHandle != null) {
+ objectsWritten.put(object, replacementHandle);
}
- if (classBasedReplacement != object) {
- // All over, class-based replacement off this time.
- Integer replacementHandle = writeObjectInternal(
- classBasedReplacement, false, false,
- computeStreamReplacement);
- // Make the original object also map to the same
- // handle.
- if (replacementHandle != null) {
- registerObjectWritten(object, replacementHandle);
- }
- return replacementHandle;
- }
+ return replacementHandle;
}
}
+
}
// We get here either if class-based replacement was not needed or
@@ -2036,7 +1817,7 @@
computeClassBasedReplacement, false);
// Make the original object also map to the same handle.
if (replacementHandle != null) {
- registerObjectWritten(object, replacementHandle);
+ objectsWritten.put(object, replacementHandle);
}
return replacementHandle;
}
@@ -2061,7 +1842,7 @@
// Is it an Array ?
if (objClass.isArray()) {
- return writeNewArray(object, objClass, objClass
+ return writeNewArray(object, objClass, clDesc, objClass
.getComponentType(), unshared);
}
@@ -2070,20 +1851,23 @@
}
// Not a String or Class or Array. Default procedure.
- return writeNewObject(object, objClass, unshared);
+ return writeNewObject(object, objClass, clDesc, unshared);
} finally {
nestedLevels--;
}
}
// write for Enum Class Desc only, which is different from other classes
- private ObjectStreamClass writeEnumDesc(Class<?> theClass, boolean unshared)
+ private ObjectStreamClass writeEnumDesc(Class<?> theClass, ObjectStreamClass classDesc, boolean unshared)
throws IOException {
// write classDesc, classDesc for enum is different
- ObjectStreamClass classDesc = ObjectStreamClass.lookup(theClass);
+
// set flag for enum, the flag is (SC_SERIALIZABLE | SC_ENUM)
classDesc.setFlags((byte) (SC_SERIALIZABLE | SC_ENUM));
- Integer previousHandle = objectsWritten.get(classDesc);
+ Integer previousHandle = null;
+ if (unshared) {
+ previousHandle = objectsWritten.get(classDesc);
+ }
Integer handle = null;
if (!unshared) {
handle = dumpCycle(classDesc);
@@ -2092,7 +1876,7 @@
Class<?> classToWrite = classDesc.forClass();
// If we got here, it is a new (non-null) classDesc that will have
// to be registered as well
- registerObjectWritten(classDesc);
+ objectsWritten.put(classDesc, nextHandle());
output.writeByte(TC_CLASSDESC);
if (protocolVersion == PROTOCOL_VERSION_1) {
@@ -2109,11 +1893,11 @@
drain(); // flush primitive types in the annotation
output.writeByte(TC_ENDBLOCKDATA);
// write super class
- ObjectStreamClass superClass = classDesc.getSuperclass();
- if (null != superClass) {
+ ObjectStreamClass superClassDesc = classDesc.getSuperclass();
+ if (null != superClassDesc) {
// super class is also enum
- superClass.setFlags((byte) (SC_SERIALIZABLE | SC_ENUM));
- writeEnumDesc(superClass.forClass(), unshared);
+ superClassDesc.setFlags((byte) (SC_SERIALIZABLE | SC_ENUM));
+ writeEnumDesc(superClassDesc.forClass(), superClassDesc, unshared);
} else {
output.writeByte(TC_NULL);
}
@@ -2137,18 +1921,26 @@
// write enum only
theClass = theClass.getSuperclass();
}
- ObjectStreamClass classDesc = writeEnumDesc(theClass, unshared);
+ ObjectStreamClass classDesc = ObjectStreamClass.lookup(theClass);
+ writeEnumDesc(theClass, classDesc, unshared);
- Integer previousHandle = objectsWritten.get(object);
- Integer handle = registerObjectWritten(object);
+ Integer previousHandle = null;
+ if (unshared) {
+ previousHandle = objectsWritten.get(object);
+ }
+ Integer handle = nextHandle();
+ objectsWritten.put(object, handle);
ObjectStreamField[] fields = classDesc.getSuperclass().fields();
Class<?> declaringClass = classDesc.getSuperclass().forClass();
// Only write field "name" for enum class, which is the second field of
// enum, that is fields[1]. Ignore all non-fields and fields.length < 2
if (null != fields && fields.length > 1) {
+ // BEGIN android-changed
String str = (String) getFieldObj(object, declaringClass, fields[1]
.getName(), fields[1].getTypeString());
+ // END android-changed
+
Integer strhandle = null;
if (!unshared) {
strhandle = dumpCycle(str);
@@ -2169,31 +1961,26 @@
/**
* Method to be overridden by subclasses to write {@code object} to the
* target stream.
- *
+ *
* @param object
* the object to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
protected void writeObjectOverride(Object object) throws IOException {
- // BEGIN android-changed
- // copied from newer version of harmony
if (!subclassOverridingImplementation) {
// Subclasses must override.
throw new IOException();
}
- // END android-changed
}
/**
* Writes a short (16 bit) to the target stream.
- *
+ *
* @param value
* the short to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeShort(int value) throws IOException {
checkWritePrimitiveTypes();
@@ -2202,10 +1989,9 @@
/**
* Writes the {@link ObjectOutputStream} header to the target stream.
- *
+ *
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
protected void writeStreamHeader() throws IOException {
output.writeShort(STREAM_MAGIC);
@@ -2215,12 +2001,11 @@
/**
* Writes a string encoded with {@link DataInput modified UTF-8} to the
* target stream.
- *
+ *
* @param value
* the string to write to the target stream.
* @throws IOException
* if an error occurs while writing to the target stream.
- * @since Android 1.0
*/
public void writeUTF(String value) throws IOException {
checkWritePrimitiveTypes();
diff --git a/luni/src/main/java/java/io/ObjectStreamClass.java b/luni/src/main/java/java/io/ObjectStreamClass.java
index 37b1f17..ac356ea 100644
--- a/luni/src/main/java/java/io/ObjectStreamClass.java
+++ b/luni/src/main/java/java/io/ObjectStreamClass.java
@@ -22,6 +22,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -33,18 +34,17 @@
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
+import org.apache.harmony.luni.util.ThreadLocalCache;
/**
* Represents a descriptor for identifying a class during serialization and
* deserialization. Information contained in the descriptor includes the name
* and SUID of the class as well as field names and types. Information inherited
* from the superclasses is also taken into account.
- *
+ *
* @see ObjectOutputStream
* @see ObjectInputStream
* @see java.lang.Class
- *
- * @since Android 1.0
*/
public class ObjectStreamClass implements Serializable {
@@ -55,6 +55,8 @@
// Name of the field that contains the SUID value (if present)
private static final String UID_FIELD_NAME = "serialVersionUID"; //$NON-NLS-1$
+ static final long CONSTRUCTOR_IS_NOT_RESOLVED = -1;
+
private static final int CLASS_MODIFIERS_MASK;
private static final int FIELD_MODIFIERS_MASK;
@@ -98,8 +100,6 @@
/**
* Constant indicating that the class has no Serializable fields.
- *
- * @since Android 1.0
*/
public static final ObjectStreamField[] NO_FIELDS = new ObjectStreamField[0];
@@ -135,9 +135,36 @@
static final Class<ObjectStreamClass> OBJECTSTREAMCLASSCLASS = ObjectStreamClass.class;
- // Table mapping instances of java.lang.Class to to corresponding instances
- // of ObjectStreamClass
- private static final WeakHashMap<Class<?>, ObjectStreamClass> classesAndDescriptors = new WeakHashMap<Class<?>, ObjectStreamClass>();
+ private transient Method methodWriteReplace;
+
+ private transient Method methodReadResolve;
+
+ private transient Method methodWriteObject;
+
+ private transient Method methodReadObject;
+
+ private transient Method methodReadObjectNoData;
+
+ /**
+ * Indicates whether the class properties resolved
+ *
+ * @see #resolveProperties()
+ */
+ private transient boolean arePropertiesResolved;
+
+ /**
+ * Cached class properties
+ *
+ * @see #resolveProperties()
+ * @see #isSerializable()
+ * @see #isExternalizable()
+ * @see #isProxy()
+ * @see #isEnum()
+ */
+ private transient boolean isSerializable;
+ private transient boolean isExternalizable;
+ private transient boolean isProxy;
+ private transient boolean isEnum;
// ClassDesc //
@@ -167,6 +194,17 @@
// Array of ObjectStreamField describing the serialized fields of this class
private transient ObjectStreamField[] loadFields;
+ // MethodID for deserialization constructor
+ private transient long constructor = CONSTRUCTOR_IS_NOT_RESOLVED;
+
+ void setConstructor(long newConstructor) {
+ constructor = newConstructor;
+ }
+
+ long getConstructor() {
+ return constructor;
+ }
+
/*
* If an ObjectStreamClass describes an Externalizable class, it (the
* descriptor) should not have field descriptors (ObjectStreamField) at all.
@@ -183,22 +221,24 @@
}
/**
- * Adds an extra entry mapping a given class {@code cl} to its class
- * descriptor, which will be computed (an ObjectStreamClass). If
- * {@code computeSUID} is true, this method will compute the SUID for
- * this class.
- *
+ * Compute class descriptor for a given class <code>cl</code>.
+ *
* @param cl
* a java.langClass for which to compute the corresponding
* descriptor
- * @param computeSUID
- * a boolean indicating if SUID should be computed or not.
* @return the computer class descriptor
*/
- private static ObjectStreamClass addToCache(Class<?> cl, boolean computeSUID) {
+ private static ObjectStreamClass createClassDesc(Class<?> cl) {
ObjectStreamClass result = new ObjectStreamClass();
+ boolean isArray = cl.isArray();
+ boolean serializable = isSerializable(cl);
+ boolean externalizable = isExternalizable(cl);
+
+ result.isSerializable = serializable;
+ result.isExternalizable = externalizable;
+
// Now we fill in the values
result.setName(cl.getName());
result.setClass(cl);
@@ -208,45 +248,73 @@
}
Field[] declaredFields = null;
- if (computeSUID) {
- // Lazy computation, to save speed & space
- declaredFields = cl.getDeclaredFields();
- result.setSerialVersionUID((cl.isEnum() || (cl == Enum.class)) ? 0
- : computeSerialVersionUID(cl, declaredFields));
+
+ // Compute the SUID
+ if(serializable || externalizable) {
+ if (result.isEnum() || result.isProxy()) {
+ result.setSerialVersionUID(0L);
+ } else {
+ declaredFields = cl.getDeclaredFields();
+ result.setSerialVersionUID(computeSerialVersionUID(cl,
+ declaredFields));
+ }
}
- boolean serializable = isSerializable(cl);
// Serializables need field descriptors
- if (serializable && !cl.isArray()) {
+ if (serializable && !isArray) {
if (declaredFields == null) {
-
declaredFields = cl.getDeclaredFields();
}
result.buildFieldDescriptors(declaredFields);
} else {
// Externalizables or arrays do not need FieldDesc info
- result.setFields(new ObjectStreamField[0]);
+ result.setFields(NO_FIELDS);
+ }
+
+ // Copy all fields to loadFields - they should be read by default in
+ // ObjectInputStream.defaultReadObject() method
+ ObjectStreamField[] fields = result.getFields();
+
+ if (fields != null) {
+ ObjectStreamField[] loadFields = new ObjectStreamField[fields.length];
+
+ for (int i = 0; i < fields.length; ++i) {
+ loadFields[i] = new ObjectStreamField(fields[i].getName(),
+ fields[i].getType(), fields[i].isUnshared());
+
+ // resolve type string to init typeString field in
+ // ObjectStreamField
+ loadFields[i].getTypeString();
+ }
+ result.setLoadFields(loadFields);
}
byte flags = 0;
- boolean externalizable = isExternalizable(cl);
if (externalizable) {
flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
+ flags |= ObjectStreamConstants.SC_BLOCK_DATA; // use protocol version 2 by default
} else if (serializable) {
flags |= ObjectStreamConstants.SC_SERIALIZABLE;
}
- if (getPrivateWriteObjectMethod(cl) != null) {
+ result.methodWriteReplace = findMethod(cl, "writeReplace"); //$NON-NLS-1$
+ result.methodReadResolve = findMethod(cl, "readResolve"); //$NON-NLS-1$
+ result.methodWriteObject = findPrivateMethod(cl, "writeObject", //$NON-NLS-1$
+ WRITE_PARAM_TYPES);
+ result.methodReadObject = findPrivateMethod(cl, "readObject", //$NON-NLS-1$
+ READ_PARAM_TYPES);
+ result.methodReadObjectNoData = findPrivateMethod(cl,
+ "readObjectNoData", EMPTY_CONSTRUCTOR_PARAM_TYPES); //$NON-NLS-1$
+ if (result.hasMethodWriteObject()) {
flags |= ObjectStreamConstants.SC_WRITE_METHOD;
}
result.setFlags(flags);
- classesAndDescriptors.put(cl, result);
return result;
}
/**
* Builds the collection of field descriptors for the receiver
- *
+ *
* @param declaredFields
* collection of java.lang.reflect.Field for which to compute
* field descriptors
@@ -315,12 +383,12 @@
}
fields = _fields;
}
-
+
/**
* Compute and return the Serial Version UID of the class {@code cl}.
* The value is computed based on the class name, superclass chain, field
* names, method names, modifiers, etc.
- *
+ *
* @param cl
* a java.lang.Class for which to compute the SUID
* @param fields
@@ -477,7 +545,7 @@
/*
* write name, modifier & "descriptor" of all but private
* ones
- *
+ *
* constructor.getName() returns the constructor name as
* typed, not the VM name
*/
@@ -534,7 +602,7 @@
/**
* Returns what the serializaton specification calls "descriptor" given a
* field signature.
- *
+ *
* @param signature
* a field signature
* @return containing the descriptor
@@ -546,7 +614,7 @@
/**
* Return what the serializaton specification calls "descriptor" given a
* method/constructor signature.
- *
+ *
* @param signature
* a method or constructor signature
* @return containing the descriptor
@@ -558,7 +626,7 @@
/**
* Return the java.lang.reflect.Field {@code serialPersistentFields}
* if class {@code cl} implements it. Return null otherwise.
- *
+ *
* @param cl
* a java.lang.Class which to test
* @return {@code java.lang.reflect.Field} if the class has
@@ -583,10 +651,9 @@
/**
* Returns the class (java.lang.Class) for this descriptor.
- *
+ *
* @return the class in the local VM that this descriptor represents;
* {@code null} if there is no corresponding class.
- * @since Android 1.0
*/
public Class<?> forClass() {
if (resolvedClass != null) {
@@ -597,7 +664,7 @@
/**
* Return a String representing the signature for a Constructor {@code c}.
- *
+ *
* @param c
* a java.lang.reflect.Constructor for which to compute the
* signature
@@ -608,12 +675,11 @@
/**
* Gets a field descriptor of the class represented by this class
* descriptor.
- *
+ *
* @param name
* the name of the desired field.
* @return the field identified by {@code name} or {@code null} if there is
* no such field.
- * @since Android 1.0
*/
public ObjectStreamField getField(String name) {
ObjectStreamField[] allFields = getFields();
@@ -629,20 +695,18 @@
/**
* Returns the collection of field descriptors for the fields of the
* corresponding class
- *
+ *
* @return the receiver's collection of declared fields for the class it
* represents
*/
ObjectStreamField[] fields() {
if (fields == null) {
- synchronized(this){
- Class<?> forCl = forClass();
- if (forCl != null && isSerializable(forCl) && !forCl.isArray()) {
- buildFieldDescriptors(forCl.getDeclaredFields());
- } else {
- // Externalizables or arrays do not need FieldDesc info
- setFields(new ObjectStreamField[0]);
- }
+ Class<?> forCl = forClass();
+ if (forCl != null && isSerializable() && !forCl.isArray()) {
+ buildFieldDescriptors(forCl.getDeclaredFields());
+ } else {
+ // Externalizables or arrays do not need FieldDesc info
+ setFields(NO_FIELDS);
}
}
return fields;
@@ -651,10 +715,9 @@
/**
* Returns a collection of field descriptors for the serialized fields of
* the class represented by this class descriptor.
- *
+ *
* @return an array of field descriptors or an array of length zero if there
* are no fields in this descriptor's class.
- * @since Android 1.0
*/
public ObjectStreamField[] getFields() {
copyFieldAttributes();
@@ -662,9 +725,9 @@
}
/**
- * If a Class uses "serialPersistentFields" to define the serialized fields,
+ * If a Class uses "serialPersistentFields" to define the serialized fields,
* this.loadFields cannot get the "unshared" information when deserializing
- * fields using current implementation of ObjectInputStream. This method
+ * fields using current implementation of ObjectInputStream. This method
* provides a way to copy the "unshared" attribute from this.fields.
*
*/
@@ -672,7 +735,7 @@
if ((loadFields == null) || fields == null) {
return;
}
-
+
for (int i = 0; i < loadFields.length; i++) {
ObjectStreamField loadField = loadFields[i];
String name = loadField.getName();
@@ -690,7 +753,7 @@
/**
* Returns the collection of field descriptors for the input fields of the
* corresponding class
- *
+ *
* @return the receiver's collection of input fields for the class it
* represents
*/
@@ -700,7 +763,7 @@
/**
* Return a String representing the signature for a field {@code f}.
- *
+ *
* @param f
* a java.lang.reflect.Field for which to compute the signature
* @return the field's signature
@@ -709,11 +772,11 @@
/**
* Returns the flags for this descriptor, where possible combined values are
- *
+ *
* ObjectStreamConstants.SC_WRITE_METHOD
* ObjectStreamConstants.SC_SERIALIZABLE
* ObjectStreamConstants.SC_EXTERNALIZABLE
- *
+ *
* @return byte the receiver's flags for the class it represents
*/
byte getFlags() {
@@ -722,7 +785,7 @@
/**
* Return a String representing the signature for a method {@code m}.
- *
+ *
* @param m
* a java.lang.reflect.Method for which to compute the signature
* @return the method's signature
@@ -731,9 +794,8 @@
/**
* Returns the name of the class represented by this descriptor.
- *
+ *
* @return the fully qualified name of the class this descriptor represents.
- * @since Android 1.0
*/
public String getName() {
return className;
@@ -742,9 +804,8 @@
/**
* Returns the Serial Version User ID of the class represented by this
* descriptor.
- *
+ *
* @return the SUID for the class represented by this descriptor.
- * @since Android 1.0
*/
public long getSerialVersionUID() {
return svUID;
@@ -753,7 +814,7 @@
/**
* Returns the descriptor (ObjectStreamClass) of the superclass of the class
* represented by the receiver.
- *
+ *
* @return an ObjectStreamClass representing the superclass of the class
* represented by the receiver.
*/
@@ -767,7 +828,7 @@
* compiler-generated, it is used by the serialization code to compute SUID.
* This is unfortunate, since it may depend on compiler optimizations in
* some cases.
- *
+ *
* @param cl
* a java.lang.Class which to test
* @return {@code true} if the class has <clinit> {@code false}
@@ -776,84 +837,15 @@
private static native boolean hasClinit(Class<?> cl);
/**
- * Return true if the given class {@code cl} implements private
- * method {@code readObject()}.
- *
- * @param cl
- * a java.lang.Class which to test
- * @return {@code true} if the class implements readObject
- * {@code false} if the class does not implement readObject
- */
- static Method getPrivateReadObjectMethod(Class<?> cl) {
- try {
- Method method = cl
- .getDeclaredMethod("readObject", READ_PARAM_TYPES); //$NON-NLS-1$
- if (Modifier.isPrivate(method.getModifiers())
- && method.getReturnType() == VOID_CLASS) {
- return method;
- }
- } catch (NoSuchMethodException nsm) {
- // Ignored
- }
- return null;
- }
-
- /**
- * Return true if the given class {@code cl} implements private
- * method {@code readObject()}.
- *
- * @param cl
- * a java.lang.Class which to test
- * @return {@code true} if the class implements readObject
- * {@code false} if the class does not implement readObject
- */
- static Method getPrivateReadObjectNoDataMethod(Class<?> cl) {
- try {
- Method method = cl.getDeclaredMethod("readObjectNoData", //$NON-NLS-1$
- EMPTY_CONSTRUCTOR_PARAM_TYPES);
- if (Modifier.isPrivate(method.getModifiers())
- && method.getReturnType() == VOID_CLASS) {
- return method;
- }
- } catch (NoSuchMethodException nsm) {
- // Ignored
- }
- return null;
- }
-
- /**
- * Return true if the given class {@code cl} implements private
- * method {@code writeObject()}.
- *
- * @param cl
- * a java.lang.Class which to test
- * @return {@code true} if the class implements writeObject
- * {@code false} if the class does not implement writeObject
- */
- static Method getPrivateWriteObjectMethod(Class<?> cl) {
- try {
- Method method = cl.getDeclaredMethod("writeObject", //$NON-NLS-1$
- WRITE_PARAM_TYPES);
- if (Modifier.isPrivate(method.getModifiers())
- && method.getReturnType() == VOID_CLASS) {
- return method;
- }
- } catch (NoSuchMethodException nsm) {
- // Ignored
- }
- return null;
- }
-
- /**
* Return true if instances of class {@code cl} are Externalizable,
* false otherwise.
- *
+ *
* @param cl
* a java.lang.Class which to test
* @return {@code true} if instances of the class are Externalizable
* {@code false} if instances of the class are not
* Externalizable
- *
+ *
* @see Object#hashCode
*/
static boolean isExternalizable(Class<?> cl) {
@@ -865,7 +857,7 @@
* <code>typecode<code> describes a primitive type
*
* @param typecode a char describing the typecode
- * @return {@code true} if the typecode represents a primitive type
+ * @return {@code true} if the typecode represents a primitive type
* {@code false} if the typecode represents an Object type (including arrays)
*
* @see Object#hashCode
@@ -877,13 +869,13 @@
/**
* Return true if instances of class {@code cl} are Serializable,
* false otherwise.
- *
+ *
* @param cl
* a java.lang.Class which to test
* @return {@code true} if instances of the class are Serializable
* {@code false} if instances of the class are not
* Serializable
- *
+ *
* @see Object#hashCode
*/
static boolean isSerializable(Class<?> cl) {
@@ -891,8 +883,65 @@
}
/**
+ * Resolves the class properties, if they weren't already
+ */
+ private void resolveProperties() {
+ if (arePropertiesResolved) {
+ return;
+ }
+
+ Class<?> cl = forClass();
+ isProxy = Proxy.isProxyClass(cl);
+ isEnum = Enum.class.isAssignableFrom(cl);
+ isSerializable = isSerializable(cl);
+ isExternalizable = isExternalizable(cl);
+
+ arePropertiesResolved = true;
+ }
+
+ /**
+ * Answers whether the class for this descriptor is serializable
+ *
+ * @return true if class implements Serializable
+ */
+ boolean isSerializable() {
+ resolveProperties();
+ return isSerializable;
+ }
+
+ /**
+ * Answers whether the class for this descriptor is serializable
+ *
+ * @return true if class implements Serializable
+ */
+ boolean isExternalizable() {
+ resolveProperties();
+ return isExternalizable;
+ }
+
+ /**
+ * Answers whether the class for this descriptor is proxied class
+ *
+ * @return true if class is proxied
+ */
+ boolean isProxy() {
+ resolveProperties();
+ return isProxy;
+ }
+
+ /**
+ * Answers whether the class for this descriptor is subclass of Enum
+ *
+ * @return true if class is subclass of Enum
+ */
+ boolean isEnum() {
+ resolveProperties();
+ return isEnum;
+ }
+
+ /**
* Return a little endian long stored in a given position of the buffer
- *
+ *
* @param buffer
* a byte array with the byte representation of the number
* @param position
@@ -911,83 +960,67 @@
* Returns the descriptor corresponding to the class {@code cl}. If the
* class is not serializable or externalizable then {@code null} is
* returned.
- *
+ *
* @param cl
* a java.langClass for which to obtain the corresponding
* descriptor
* @return the corresponding descriptor if the {@code cl} is serializable or
* externalizable; {@code null} otherwise.
- * @since Android 1.0
*/
public static ObjectStreamClass lookup(Class<?> cl) {
- boolean serializable = isSerializable(cl);
- boolean externalizable = isExternalizable(cl);
+ ObjectStreamClass osc = lookupStreamClass(cl);
- // Has to be either Serializable or Externalizable
- if (!serializable && !externalizable) {
- return null;
+ if (osc.isSerializable() || osc.isExternalizable()) {
+ return osc;
}
- return lookupStreamClass(cl, true);
+ return null;
}
/**
* Return the descriptor (ObjectStreamClass) corresponding to the class
* {@code cl}. Returns an ObjectStreamClass even if instances of the
* class cannot be serialized
- *
+ *
* @param cl
* a java.langClass for which to obtain the corresponding
* descriptor
* @return the corresponding descriptor
*/
static ObjectStreamClass lookupStreamClass(Class<?> cl) {
- return lookupStreamClass(cl, isSerializable(cl) || isExternalizable(cl));
- }
- /**
- * Return the descriptor (ObjectStreamClass) corresponding to the class
- * {@code cl}. Returns an ObjectStreamClass even if instances of the
- * class cannot be serialized
- *
- * @param cl
- * a {@code java.langClass} for which to obtain the
- * corresponding descriptor
- * @param computeSUID
- * a boolean indicating if SUID should be computed or not.
- * @return the corresponding descriptor
- */
- private static synchronized ObjectStreamClass lookupStreamClass(
- Class<?> cl, boolean computeSUID) {
- // Synchronized because of the lookup table 'classesAndDescriptors'
- ObjectStreamClass cachedValue = classesAndDescriptors.get(cl);
- if (cachedValue != null) {
- return cachedValue;
+ WeakHashMap<Class<?>,ObjectStreamClass> tlc = OSCThreadLocalCache.oscWeakHashMap.get();
+
+ ObjectStreamClass cachedValue = tlc.get(cl);
+ if (cachedValue == null) {
+ cachedValue = createClassDesc(cl);
+ tlc.put(cl, cachedValue);
}
- return addToCache(cl, computeSUID);
+ return cachedValue;
+
}
/**
- * Return the java.lang.reflect.Method {@code readResolve} if class
- * {@code cl} implements it. Return null otherwise.
- *
+ * Return the java.lang.reflect.Method if class <code>cl</code> implements
+ * <code>methodName</code> . Return null otherwise.
+ *
* @param cl
* a java.lang.Class which to test
- * @return {@code java.lang.reflect.Method} if the class implements
- * readResolve {@code null} if the class does not implement
- * readResolve
+ * @return <code>java.lang.reflect.Method</code> if the class implements
+ * writeReplace <code>null</code> if the class does not implement
+ * writeReplace
*/
- static Method methodReadResolve(Class<?> cl) {
+ static Method findMethod(Class<?> cl, String methodName) {
Class<?> search = cl;
+ Method method = null;
while (search != null) {
try {
- Method method = search.getDeclaredMethod(
- "readResolve", (Class[]) null); //$NON-NLS-1$
+ method = search.getDeclaredMethod(methodName, (Class[]) null);
if (search == cl
|| (method.getModifiers() & Modifier.PRIVATE) == 0) {
+ method.setAccessible(true);
return method;
}
- return null;
} catch (NoSuchMethodException nsm) {
}
search = search.getSuperclass();
@@ -996,37 +1029,81 @@
}
/**
- * Return the java.lang.reflect.Method {@code writeReplace} if class
- * {@code cl} implements it. Return null otherwise.
- *
+ * Return the java.lang.reflect.Method if class <code>cl</code> implements
+ * private <code>methodName</code> . Return null otherwise.
+ *
* @param cl
* a java.lang.Class which to test
* @return {@code java.lang.reflect.Method} if the class implements
* writeReplace {@code null} if the class does not implement
* writeReplace
*/
- static Method methodWriteReplace(Class<?> cl) {
- Class<?> search = cl;
- while (search != null) {
- try {
- Method method = search.getDeclaredMethod(
- "writeReplace", (Class[]) null); //$NON-NLS-1$
- if (search == cl
- || (method.getModifiers() & Modifier.PRIVATE) == 0) {
- return method;
- }
- return null;
- } catch (NoSuchMethodException nsm) {
- // Ignored
+ static Method findPrivateMethod(Class<?> cl, String methodName,
+ Class<?>[] param) {
+ try {
+ Method method = cl.getDeclaredMethod(methodName, param);
+ if (Modifier.isPrivate(method.getModifiers())
+ && method.getReturnType() == VOID_CLASS) {
+ method.setAccessible(true);
+ return method;
}
- search = search.getSuperclass();
+ } catch (NoSuchMethodException nsm) {
+ // Ignored
}
return null;
}
+ boolean hasMethodWriteReplace() {
+ return (methodWriteReplace != null);
+ }
+
+ Method getMethodWriteReplace() {
+ return methodWriteReplace;
+ }
+
+ boolean hasMethodReadResolve() {
+ return (methodReadResolve != null);
+ }
+
+ Method getMethodReadResolve() {
+ return methodReadResolve;
+ }
+
+ boolean hasMethodWriteObject() {
+ return (methodWriteObject != null);
+ }
+
+ Method getMethodWriteObject() {
+ return methodWriteObject;
+ }
+
+ boolean hasMethodReadObject() {
+ return (methodReadObject != null);
+ }
+
+ Method getMethodReadObject() {
+ return methodReadObject;
+ }
+
+ boolean hasMethodReadObjectNoData() {
+ return (methodReadObjectNoData != null);
+ }
+
+ Method getMethodReadObjectNoData() {
+ return methodReadObjectNoData;
+ }
+
+ void initPrivateFields(ObjectStreamClass desc) {
+ methodWriteReplace = desc.methodWriteReplace;
+ methodReadResolve = desc.methodReadResolve;
+ methodWriteObject = desc.methodWriteObject;
+ methodReadObject = desc.methodReadObject;
+ methodReadObjectNoData = desc.methodReadObjectNoData;
+ }
+
/**
* Set the class (java.lang.Class) that the receiver represents
- *
+ *
* @param c
* aClass, the new class that the receiver describes
*/
@@ -1037,7 +1114,7 @@
/**
* Set the collection of field descriptors for the fields of the
* corresponding class
- *
+ *
* @param f
* ObjectStreamField[], the receiver's new collection of declared
* fields for the class it represents
@@ -1049,7 +1126,7 @@
/**
* Set the collection of field descriptors for the input fields of the
* corresponding class
- *
+ *
* @param f
* ObjectStreamField[], the receiver's new collection of input
* fields for the class it represents
@@ -1060,11 +1137,11 @@
/**
* Set the flags for this descriptor, where possible combined values are
- *
+ *
* ObjectStreamConstants.SC_WRITE_METHOD
* ObjectStreamConstants.SC_SERIALIZABLE
* ObjectStreamConstants.SC_EXTERNALIZABLE
- *
+ *
* @param b
* byte, the receiver's new flags for the class it represents
*/
@@ -1074,7 +1151,7 @@
/**
* Set the name of the class represented by the receiver
- *
+ *
* @param newName
* a String, the new fully qualified name of the class the
* receiver represents
@@ -1085,7 +1162,7 @@
/**
* Set the Serial Version User ID of the class represented by the receiver
- *
+ *
* @param l
* a long, the new SUID for the class represented by the receiver
*/
@@ -1096,7 +1173,7 @@
/**
* Set the descriptor for the superclass of the class described by the
* receiver
- *
+ *
* @param c
* an ObjectStreamClass, the new ObjectStreamClass for the
* superclass of the class represented by the receiver
@@ -1124,13 +1201,24 @@
/**
* Returns a string containing a concise, human-readable description of this
* descriptor.
- *
+ *
* @return a printable representation of this descriptor.
- * @since Android 1.0
*/
@Override
public String toString() {
return getName() + ": static final long serialVersionUID =" //$NON-NLS-1$
+ getSerialVersionUID() + "L;"; //$NON-NLS-1$
}
+
+ static class OSCThreadLocalCache extends ThreadLocalCache {
+
+ // thread-local cache for ObjectStreamClass.lookup
+ public static ThreadLocalCache<WeakHashMap<Class<?>,ObjectStreamClass>> oscWeakHashMap = new ThreadLocalCache<WeakHashMap<Class<?>,ObjectStreamClass>>() {
+ protected WeakHashMap<Class<?>,ObjectStreamClass> initialValue() {
+ return new WeakHashMap<Class<?>,ObjectStreamClass>();
+ }
+ };
+
+ }
+
}
diff --git a/luni/src/main/java/java/io/ObjectStreamConstants.java b/luni/src/main/java/java/io/ObjectStreamConstants.java
index 8f7ad66..01b0109 100644
--- a/luni/src/main/java/java/io/ObjectStreamConstants.java
+++ b/luni/src/main/java/java/io/ObjectStreamConstants.java
@@ -19,168 +19,122 @@
/**
* A helper interface with constants used by the serialization implementation.
- *
- * @since Android 1.0
*/
public abstract interface ObjectStreamConstants {
/**
* The stream header's magic number.
- *
- * @since Android 1.0
*/
public static final short STREAM_MAGIC = (short) 0xaced;
/**
* The stream header's version number.
- *
- * @since Android 1.0
*/
public static final short STREAM_VERSION = 5;
// These are tags to indicate the stream contents
-
+
/**
* The minimum tag value.
- *
- * @since Android 1.0
*/
public static final byte TC_BASE = 0x70;
/**
* Tag to mark a {@code null} object reference.
- *
- * @since Android 1.0
*/
public static final byte TC_NULL = (byte) 0x70;
/**
* Tag to mark a reference to an object that has already been written to the
* stream.
- *
- * @since Android 1.0
*/
public static final byte TC_REFERENCE = (byte) 0x71;
/**
* Tag to mark a new class descriptor.
- *
- * @since Android 1.0
*/
public static final byte TC_CLASSDESC = (byte) 0x72;
/**
* Tag to mark a new object.
- *
- * @since Android 1.0
*/
public static final byte TC_OBJECT = (byte) 0x73;
/**
* Tag to mark a new string.
- *
- * @since Android 1.0
*/
public static final byte TC_STRING = (byte) 0x74;
/**
* Tag to mark a new array.
- *
- * @since Android 1.0
*/
public static final byte TC_ARRAY = (byte) 0x75;
/**
* Tag to mark a reference to a class.
- *
- * @since Android 1.0
*/
public static final byte TC_CLASS = (byte) 0x76;
/**
* Tag to mark a block of optional data. The byte following this tag
* indicates the size of the block.
- *
- * @since Android 1.0
*/
public static final byte TC_BLOCKDATA = (byte) 0x77;
/**
* Tag to mark the end of block data blocks for an object.
- *
- * @since Android 1.0
*/
public static final byte TC_ENDBLOCKDATA = (byte) 0x78;
/**
* Tag to mark a stream reset.
- *
- * @since Android 1.0
*/
public static final byte TC_RESET = (byte) 0x79;
/**
* Tag to mark a long block of data. The long following this tag
* indicates the size of the block.
- *
- * @since Android 1.0
*/
public static final byte TC_BLOCKDATALONG = (byte) 0x7A;
/**
* Tag to mark an exception.
- *
- * @since Android 1.0
*/
public static final byte TC_EXCEPTION = (byte) 0x7B;
/**
* Tag to mark a long string.
- *
- * @since Android 1.0
*/
public static final byte TC_LONGSTRING = (byte) 0x7C;
/**
* Tag to mark a new proxy class descriptor.
- *
- * @since Android 1.0
*/
public static final byte TC_PROXYCLASSDESC = (byte) 0x7D;
/**
* The maximum tag value.
- *
- * @since Android 1.0
*/
public static final byte TC_MAX = 0x7E;
/**
* Handle for the first object that gets serialized.
- *
- * @since Android 1.0
*/
public static final int baseWireHandle = 0x007e0000;
/**
* Stream protocol version 1.
- *
- * @since Android 1.0
*/
public static final int PROTOCOL_VERSION_1 = 1;
/**
* Stream protocol version 2.
- *
- * @since Android 1.0
*/
public static final int PROTOCOL_VERSION_2 = 2;
/**
* Permission constant to enable subclassing of ObjectInputStream and
* ObjectOutputStream.
- *
- * @since Android 1.0
*/
public static final SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION = new SerializablePermission(
"enableSubclassImplementation"); //$NON-NLS-1$
@@ -188,8 +142,6 @@
/**
* Permission constant to enable object substitution during serialization
* and deserialization.
- *
- * @since Android 1.0
*/
public static final SerializablePermission SUBSTITUTION_PERMISSION = new SerializablePermission(
"enableSubstitution"); //$NON-NLS-1$
@@ -199,47 +151,35 @@
/**
* Bit mask for the {@code flag} field in ObjectStreamClass. Indicates
* that a serializable class has its own {@code writeObject} method.
- *
- * @since Android 1.0
*/
public static final byte SC_WRITE_METHOD = 0x01; // If SC_SERIALIZABLE
/**
* Bit mask for the {@code flag} field in ObjectStreamClass. Indicates
* that a class is serializable.
- *
- * @since Android 1.0
*/
public static final byte SC_SERIALIZABLE = 0x02;
/**
* Bit mask for the {@code flag} field in ObjectStreamClass. Indicates
* that a class is externalizable.
- *
- * @since Android 1.0
*/
public static final byte SC_EXTERNALIZABLE = 0x04;
/**
* Bit mask for the {@code flag} field in ObjectStreamClass. Indicates
* that an externalizable class is written in block data mode.
- *
- * @since Android 1.0
*/
public static final byte SC_BLOCK_DATA = 0x08; // If SC_EXTERNALIZABLE
/**
* Tag to mark a new enum.
- *
- * @since Android 1.0
*/
public static final byte TC_ENUM = 0x7E;
/**
* Bit mask for the {@code flag} field in ObjectStreamClass. Indicates
* that a class is an enum type.
- *
- * @since Android 1.0
*/
public static final byte SC_ENUM = 0x10;
}
diff --git a/luni/src/main/java/java/io/ObjectStreamException.java b/luni/src/main/java/java/io/ObjectStreamException.java
index a06b102..c3ad7dc 100644
--- a/luni/src/main/java/java/io/ObjectStreamException.java
+++ b/luni/src/main/java/java/io/ObjectStreamException.java
@@ -28,8 +28,6 @@
* @see OptionalDataException
* @see StreamCorruptedException
* @see WriteAbortedException
- *
- * @since Android 1.0
*/
public abstract class ObjectStreamException extends IOException {
@@ -38,8 +36,6 @@
/**
* Constructs a new {@code ObjectStreamException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
protected ObjectStreamException() {
super();
@@ -51,7 +47,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
protected ObjectStreamException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/ObjectStreamField.java b/luni/src/main/java/java/io/ObjectStreamField.java
index 95deb7b..3baebf7 100644
--- a/luni/src/main/java/java/io/ObjectStreamField.java
+++ b/luni/src/main/java/java/io/ObjectStreamField.java
@@ -17,22 +17,32 @@
package java.io;
+// BEGIN android-note
+// Harmony uses ObjectAccessors to access fields through JNI. Android has not
+// yet migrated that API.
+// END android-note
+
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Comparator;
+// BEGIN android-removed
+// import org.apache.harmony.misc.accessors.ObjectAccessor;
+// END android-removed
+
/**
* Describes a field for the purpose of serialization. Classes can define the
* collection of fields that are serialized, which may be different from the set
* of all declared fields.
- *
+ *
* @see ObjectOutputStream#writeFields()
* @see ObjectInputStream#readFields()
- *
- * @since Android 1.0
*/
public class ObjectStreamField implements Comparable<Object> {
+ static final int FIELD_IS_NOT_RESOLVED = -1;
+ static final int FIELD_IS_ABSENT = -2;
+
// Declared name of the field
private String name;
@@ -49,16 +59,32 @@
private boolean isDeserialized;
+ private long assocFieldID = FIELD_IS_NOT_RESOLVED;
+
+ // BEGIN android-removed
+ // long getFieldID(ObjectAccessor accessor, Class<?> declaringClass) {
+ // if (assocFieldID != FIELD_IS_NOT_RESOLVED) {
+ // return assocFieldID;
+ // } else {
+ // try {
+ // assocFieldID = accessor.getFieldID(declaringClass, name);
+ // } catch(NoSuchFieldError e) {
+ // assocFieldID = FIELD_IS_ABSENT;
+ // }
+ // return assocFieldID;
+ // }
+ // }
+ // END android-removed
+
/**
* Constructs an ObjectStreamField with the specified name and type.
- *
+ *
* @param name
* the name of the field.
* @param cl
* the type of the field.
* @throws NullPointerException
* if {@code name} or {@code cl} is {@code null}.
- * @since Android 1.0
*/
public ObjectStreamField(String name, Class<?> cl) {
if (name == null || cl == null) {
@@ -71,7 +97,7 @@
/**
* Constructs an ObjectStreamField with the specified name, type and the
* indication if it is unshared.
- *
+ *
* @param name
* the name of the field.
* @param cl
@@ -82,7 +108,6 @@
* @throws NullPointerException
* if {@code name} or {@code cl} is {@code null}.
* @see ObjectOutputStream#writeUnshared(Object)
- * @since Android 1.0
*/
public ObjectStreamField(String name, Class<?> cl, boolean unshared) {
if (name == null || cl == null) {
@@ -97,7 +122,7 @@
/**
* Constructs an ObjectStreamField with the given name and the given type.
* The type may be null.
- *
+ *
* @param signature
* A String representing the type of the field
* @param name
@@ -117,13 +142,12 @@
* of the compared fields has a primitive type and the other one not. If so,
* the field with the primitive type is considered to be "smaller". If both
* fields are equal, their names are compared.
- *
+ *
* @param o
* the object to compare with.
* @return -1 if this field is "smaller" than field {@code o}, 0 if both
* fields are equal; 1 if this field is "greater" than field {@code
* o}.
- * @since Android 1.0
*/
public int compareTo(Object o) {
ObjectStreamField f = (ObjectStreamField) o;
@@ -139,34 +163,14 @@
// Either both primitives or both not primitives. Compare based on name.
return this.getName().compareTo(f.getName());
}
-
+
// BEGIN android-removed
// There shouldn't be an implementation of these methods.
- // /**
- // * Indicates if this field descriptor is equal to {@code arg0}. Field
- // * descriptors are equal if their name is equal.
- // *
- // * @param arg0
- // * the object to check equality with.
- // * @return {@code true} if the name of this field descriptor is equal to the
- // * name of {@code arg0}, {@code false} otherwise.
- // * @since Android 1.0
- // */
// @Override
// public boolean equals(Object arg0) {
- // // BEGIN android-changed
- // // copied from newer harmony version
- // return (arg0 instanceof ObjectStreamField) && compareTo(arg0) == 0;
- // // END android-changed
+ // return (arg0 instanceof ObjectStreamField) && (compareTo(arg0) == 0);
// }
- //
- // /**
- // * Returns a hash code for this field descriptor. The hash code of this
- // * field's name is returned.
- // *
- // * @return the field's hash code.
- // * @since Android 1.0
- // */
+ //
// @Override
// public int hashCode() {
// return getName().hashCode();
@@ -175,9 +179,8 @@
/**
* Gets the name of this field.
- *
+ *
* @return the field's name.
- * @since Android 1.0
*/
public String getName() {
return name;
@@ -185,9 +188,8 @@
/**
* Gets the offset of this field in the object.
- *
+ *
* @return this field's offset.
- * @since Android 1.0
*/
public int getOffset() {
return offset;
@@ -196,7 +198,7 @@
/**
* Return the type of the field the receiver represents, this is an internal
* method
- *
+ *
* @return A Class object representing the type of the field
*/
// BEGIN android-note
@@ -211,9 +213,8 @@
/**
* Gets the type of this field.
- *
+ *
* @return a {@code Class} object representing the type of the field.
- * @since Android 1.0
*/
public Class<?> getType() {
Class<?> cl = getTypeInternal();
@@ -226,7 +227,7 @@
/**
* Gets a character code for the type of this field. The following codes are
* used:
- *
+ *
* <pre>
* B byte
* C char
@@ -239,9 +240,8 @@
* Z boolean
* [ array
* </pre>
- *
+ *
* @return the field's type code.
- * @since Android 1.0
*/
public char getTypeCode() {
Class<?> t = getTypeInternal();
@@ -278,10 +278,9 @@
/**
* Gets the type signature used by the VM to represent the type of this
* field.
- *
+ *
* @return the signature of this field's class or {@code null} if this
* field's type is primitive.
- * @since Android 1.0
*/
public String getTypeString() {
if (isPrimitive()) {
@@ -298,10 +297,9 @@
/**
* Indicates whether this field's type is a primitive type.
- *
+ *
* @return {@code true} if this field's type is primitive; {@code false} if
* the type of this field is a regular class.
- * @since Android 1.0
*/
public boolean isPrimitive() {
Class<?> t = getTypeInternal();
@@ -310,10 +308,9 @@
/**
* Sets this field's offset in the object.
- *
+ *
* @param newValue
* the field's new offset.
- * @since Android 1.0
*/
protected void setOffset(int newValue) {
this.offset = newValue;
@@ -322,9 +319,8 @@
/**
* Returns a string containing a concise, human-readable description of this
* field descriptor.
- *
+ *
* @return a printable representation of this descriptor.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -335,7 +331,7 @@
/**
* Sorts the fields for dumping. Primitive types come first, then regular
* types.
- *
+ *
* @param fields
* ObjectStreamField[] fields to be sorted
*/
@@ -396,9 +392,8 @@
/**
* Indicats whether this field is unshared.
- *
+ *
* @return {@code true} if this field is unshared, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isUnshared() {
return unshared;
diff --git a/luni/src/main/java/java/io/OptionalDataException.java b/luni/src/main/java/java/io/OptionalDataException.java
index 891bfdd..39d3d5d 100644
--- a/luni/src/main/java/java/io/OptionalDataException.java
+++ b/luni/src/main/java/java/io/OptionalDataException.java
@@ -25,8 +25,6 @@
* @see ObjectInputStream#available()
* @see ObjectInputStream#readObject()
* @see ObjectInputStream#skipBytes(int)
- *
- * @since Android 1.0
*/
public class OptionalDataException extends ObjectStreamException {
@@ -34,24 +32,18 @@
/**
* {@code true} indicates that there is no more primitive data available.
- *
- * @since Android 1.0
*/
public boolean eof;
/**
* The number of bytes of primitive data (int, char, long etc.) that are
* available.
- *
- * @since Android 1.0
*/
public int length;
/**
* Constructs a new {@code OptionalDataException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
OptionalDataException() {
super();
@@ -63,7 +55,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
OptionalDataException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/OutputStream.java b/luni/src/main/java/java/io/OutputStream.java
index 5531ab5..2172411 100644
--- a/luni/src/main/java/java/io/OutputStream.java
+++ b/luni/src/main/java/java/io/OutputStream.java
@@ -32,17 +32,13 @@
* <p>
* Many specialized output streams for purposes like writing to a file already
* exist in this package.
- *
+ *
* @see InputStream
- *
- * @since Android 1.0
*/
public abstract class OutputStream implements Closeable, Flushable {
/**
* Default constructor.
- *
- * @since Android 1.0
*/
public OutputStream() {
super();
@@ -51,10 +47,9 @@
/**
* Closes this stream. Implementations of this method should free any
* resources used by the stream. This implementation does nothing.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
public void close() throws IOException {
/* empty */
@@ -63,10 +58,9 @@
/**
* Flushes this stream. Implementations of this method should ensure that
* any buffered data is written out. This implementation does nothing.
- *
+ *
* @throws IOException
* if an error occurs while flushing this stream.
- * @since Android 1.0
*/
public void flush() throws IOException {
/* empty */
@@ -75,12 +69,11 @@
/**
* Writes the entire contents of the byte array {@code buffer} to this
* stream.
- *
+ *
* @param buffer
* the buffer to be written.
* @throws IOException
* if an error occurs while writing to this stream.
- * @since Android 1.0
*/
public void write(byte[] buffer) throws IOException {
// BEGIN android-note
@@ -92,7 +85,7 @@
/**
* Writes {@code count} bytes from the byte array {@code buffer} starting at
* position {@code offset} to this stream.
- *
+ *
* @param buffer
* the buffer to be written.
* @param offset
@@ -106,7 +99,6 @@
* if {@code offset < 0} or {@code count < 0}, or if
* {@code offset + count} is bigger than the length of
* {@code buffer}.
- * @since Android 1.0
*/
public void write(byte[] buffer, int offset, int count) throws IOException {
// BEGIN android-note
@@ -134,12 +126,11 @@
/**
* Writes a single byte to this stream. Only the least significant byte of
* the integer {@code oneByte} is written to the stream.
- *
+ *
* @param oneByte
* the byte to be written.
* @throws IOException
* if an error occurs while writing to this stream.
- * @since Android 1.0
*/
public abstract void write(int oneByte) throws IOException;
}
diff --git a/luni/src/main/java/java/io/OutputStreamWriter.java b/luni/src/main/java/java/io/OutputStreamWriter.java
index d6cc91e..6e6cc50 100644
--- a/luni/src/main/java/java/io/OutputStreamWriter.java
+++ b/luni/src/main/java/java/io/OutputStreamWriter.java
@@ -25,6 +25,7 @@
import java.nio.charset.CodingErrorAction;
import java.security.AccessController;
+import org.apache.harmony.luni.util.HistoricalNamesUtil;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
@@ -35,10 +36,8 @@
* "file.encoding" system property. {@code OutputStreamWriter} contains a buffer
* of bytes to be written to target stream and converts these into characters as
* needed. The buffer size is 8K.
- *
+ *
* @see InputStreamReader
- *
- * @since Android 1.0
*/
public class OutputStreamWriter extends Writer {
@@ -52,10 +51,9 @@
* Constructs a new OutputStreamWriter using {@code out} as the target
* stream to write converted characters to. The default character encoding
* is used.
- *
+ *
* @param out
* the non-null target stream to write converted bytes to.
- * @since Android 1.0
*/
public OutputStreamWriter(OutputStream out) {
super(out);
@@ -73,7 +71,7 @@
* stream to write converted characters to and {@code enc} as the character
* encoding. If the encoding cannot be found, an
* UnsupportedEncodingException error is thrown.
- *
+ *
* @param out
* the target stream to write converted bytes to.
* @param enc
@@ -82,7 +80,6 @@
* if {@code enc} is {@code null}.
* @throws UnsupportedEncodingException
* if the encoding specified by {@code enc} cannot be found.
- * @since Android 1.0
*/
public OutputStreamWriter(OutputStream out, final String enc)
throws UnsupportedEncodingException {
@@ -104,12 +101,11 @@
* Constructs a new OutputStreamWriter using {@code out} as the target
* stream to write converted characters to and {@code cs} as the character
* encoding.
- *
+ *
* @param out
* the target stream to write converted bytes to.
* @param cs
* the {@code Charset} that specifies the character encoding.
- * @since Android 1.0
*/
public OutputStreamWriter(OutputStream out, Charset cs) {
super(out);
@@ -123,12 +119,11 @@
* Constructs a new OutputStreamWriter using {@code out} as the target
* stream to write converted characters to and {@code enc} as the character
* encoder.
- *
+ *
* @param out
* the target stream to write converted bytes to.
* @param enc
* the character encoder used for character conversion.
- * @since Android 1.0
*/
public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
super(out);
@@ -144,11 +139,9 @@
* <p>
* Only the first invocation of this method has any effect. Subsequent calls
* do nothing.
- * </p>
- *
+ *
* @throws IOException
* if an error occurs while closing this writer.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -168,10 +161,9 @@
* Flushes this writer. This implementation ensures that all buffered bytes
* are written to the target stream. After writing the bytes, the target
* stream is flushed as well.
- *
+ *
* @throws IOException
* if an error occurs while flushing this writer.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -197,17 +189,15 @@
/**
* Gets the name of the encoding that is used to convert characters to
* bytes.
- *
+ *
* @return the string describing the converter or {@code null} if this
* writer is closed.
- * @since Android 1.0
*/
public String getEncoding() {
if (encoder == null) {
return null;
}
- return InputStreamReader.HistoricalNamesUtil.getHistoricalName(encoder
- .charset().name());
+ return HistoricalNamesUtil.getHistoricalName(encoder.charset().name());
}
/**
@@ -215,7 +205,7 @@
* to this writer. The characters are immediately converted to bytes by the
* character converter and stored in a local buffer. If the buffer gets full
* as a result of the conversion, this writer is flushed.
- *
+ *
* @param buf
* the array containing characters to write.
* @param offset
@@ -229,7 +219,6 @@
* @throws IOException
* if this writer has already been closed or another I/O error
* occurs.
- * @since Android 1.0
*/
@Override
public void write(char[] buf, int offset, int count) throws IOException {
@@ -273,12 +262,11 @@
* of the integer {@code oneChar} are immediately converted to bytes by the
* character converter and stored in a local buffer. If the buffer gets full
* by converting this character, this writer is flushed.
- *
+ *
* @param oneChar
* the character to write.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public void write(int oneChar) throws IOException {
@@ -294,7 +282,7 @@
* to this writer. The characters are immediately converted to bytes by the
* character converter and stored in a local buffer. If the buffer gets full
* as a result of the conversion, this writer is flushed.
- *
+ *
* @param str
* the string containing characters to write.
* @param offset
@@ -308,7 +296,6 @@
* if {@code offset < 0} or {@code count < 0}, or if
* {@code offset + count} is bigger than the length of
* {@code str}.
- * @since Android 1.0
*/
@Override
public void write(String str, int offset, int count) throws IOException {
diff --git a/luni/src/main/java/java/io/PipedInputStream.java b/luni/src/main/java/java/io/PipedInputStream.java
index 5562c58..d06143d 100644
--- a/luni/src/main/java/java/io/PipedInputStream.java
+++ b/luni/src/main/java/java/io/PipedInputStream.java
@@ -23,10 +23,8 @@
* Receives information from a communications pipe. When two threads want to
* pass data back and forth, one creates a piped output stream and the other one
* creates a piped input stream.
- *
+ *
* @see PipedOutputStream
- *
- * @since Android 1.0
*/
public class PipedInputStream extends InputStream {
@@ -36,29 +34,21 @@
/**
* The circular buffer through which data is passed.
- *
- * @since Android 1.0
*/
protected byte buffer[];
/**
* The index in {@code buffer} where the next byte will be written.
- *
- * @since Android 1.0
*/
protected int in = -1;
/**
* The index in {@code buffer} where the next byte will be read.
- *
- * @since Android 1.0
*/
protected int out = 0;
/**
* The size of the default pipe in bytes.
- *
- * @since Android 1.0
*/
protected static final int PIPE_SIZE = 1024;
@@ -71,8 +61,6 @@
* Constructs a new unconnected {@code PipedInputStream}. The resulting
* stream must be connected to a {@link PipedOutputStream} before data may
* be read from it.
- *
- * @since Android 1.0
*/
public PipedInputStream() {
/* empty */
@@ -82,12 +70,11 @@
* Constructs a new {@code PipedInputStream} connected to the
* {@link PipedOutputStream} {@code out}. Any data written to the output
* stream can be read from the this input stream.
- *
+ *
* @param out
* the piped output stream to connect to.
* @throws IOException
* if this stream or {@code out} are already connected.
- * @since Android 1.0
*/
public PipedInputStream(PipedOutputStream out) throws IOException {
connect(out);
@@ -97,11 +84,10 @@
* Returns the number of bytes that are available before this stream will
* block. This implementation returns the number of bytes written to this
* pipe that have not been read yet.
- *
+ *
* @return the number of bytes available before blocking.
* @throws IOException
* if an error occurs in this stream.
- * @since Android 1.0
*/
@Override
public synchronized int available() throws IOException {
@@ -114,10 +100,9 @@
/**
* Closes this stream. This implementation releases the buffer used for the
* pipe and notifies all threads waiting to read or write.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -134,12 +119,11 @@
* Connects this {@code PipedInputStream} to a {@link PipedOutputStream}.
* Any data written to the output stream becomes readable in this input
* stream.
- *
+ *
* @param src
* the source output stream.
* @throws IOException
* if either stream is already connected.
- * @since Android 1.0
*/
public void connect(PipedOutputStream src) throws IOException {
src.connect(this);
@@ -155,15 +139,13 @@
* Separate threads should be used to read from a {@code PipedInputStream}
* and to write to the connected {@link PipedOutputStream}. If the same
* thread is used, a deadlock may occur.
- * </p>
- *
+ *
* @return the byte read or -1 if the end of the source stream has been
* reached.
* @throws IOException
* if this stream is closed or not connected to an output
* stream, or if the thread writing to the connected output
* stream is no longer alive.
- * @since Android 1.0
*/
@Override
public synchronized int read() throws IOException {
@@ -180,16 +162,15 @@
*/
lastReader = Thread.currentThread();
try {
- boolean first = true;
+ int attempts = 3;
while (in == -1) {
// Are we at end of stream?
if (isClosed) {
return -1;
}
- if (!first && lastWriter != null && !lastWriter.isAlive()) {
+ if ((attempts-- <= 0) && lastWriter != null && !lastWriter.isAlive()) {
throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
}
- first = false;
// Notify callers of receive()
notifyAll();
wait(1000);
@@ -219,8 +200,7 @@
* Separate threads should be used to read from a {@code PipedInputStream}
* and to write to the connected {@link PipedOutputStream}. If the same
* thread is used, a deadlock may occur.
- * </p>
- *
+ *
* @param bytes
* the array in which to store the bytes read.
* @param offset
@@ -278,16 +258,15 @@
*/
lastReader = Thread.currentThread();
try {
- boolean first = true;
+ int attempts = 3;
while (in == -1) {
// Are we at end of stream?
if (isClosed) {
return -1;
}
- if (!first && lastWriter != null && !lastWriter.isAlive()) {
+ if ((attempts-- <= 0) && lastWriter != null && !lastWriter.isAlive()) {
throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
}
- first = false;
// Notify callers of receive()
notifyAll();
wait(1000);
@@ -342,8 +321,7 @@
* {@code in} in the {@code buffer}.
* <p>
* This method blocks as long as {@code buffer} is full.
- * </p>
- *
+ *
* @param oneByte
* the byte to store in this pipe.
* @throws InterruptedIOException
diff --git a/luni/src/main/java/java/io/PipedOutputStream.java b/luni/src/main/java/java/io/PipedOutputStream.java
index 3041f70..15ee930 100644
--- a/luni/src/main/java/java/io/PipedOutputStream.java
+++ b/luni/src/main/java/java/io/PipedOutputStream.java
@@ -23,10 +23,8 @@
* Places information on a communications pipe. When two threads want to pass
* data back and forth, one creates a piped output stream and the other one
* creates a piped input stream.
- *
+ *
* @see PipedInputStream
- *
- * @since Android 1.0
*/
public class PipedOutputStream extends OutputStream {
@@ -39,8 +37,6 @@
* Constructs a new unconnected {@code PipedOutputStream}. The resulting
* stream must be connected to a {@link PipedInputStream} before data can be
* written to it.
- *
- * @since Android 1.0
*/
public PipedOutputStream() {
super();
@@ -50,12 +46,11 @@
* Constructs a new {@code PipedOutputStream} connected to the
* {@link PipedInputStream} {@code dest}. Any data written to this stream
* can be read from the target stream.
- *
+ *
* @param dest
* the piped input stream to connect to.
* @throws IOException
* if this stream or {@code dest} are already connected.
- * @since Android 1.0
*/
public PipedOutputStream(PipedInputStream dest) throws IOException {
super();
@@ -65,10 +60,9 @@
/**
* Closes this stream. If this stream is connected to an input stream, the
* input stream is closed and the pipe is disconnected.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -82,12 +76,11 @@
/**
* Connects this stream to a {@link PipedInputStream}. Any data written to
* this output stream becomes readable in the input stream.
- *
+ *
* @param stream
* the destination input stream.
* @throws IOException
* if either stream is already connected.
- * @since Android 1.0
*/
public void connect(PipedInputStream stream) throws IOException {
if (null == stream) {
@@ -109,10 +102,9 @@
/**
* Notifies the readers of this {@link PipedInputStream} that bytes can be
* read. This method does nothing if this stream is not connected.
- *
+ *
* @throws IOException
* if an I/O error occurs while flushing this stream.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -131,8 +123,7 @@
* Separate threads should be used to write to a {@code PipedOutputStream}
* and to read from the connected {@link PipedInputStream}. If the same
* thread is used, a deadlock may occur.
- * </p>
- *
+ *
* @param buffer
* the buffer to write.
* @param offset
@@ -151,7 +142,6 @@
* if this stream is not connected, if the target stream is
* closed or if the thread reading from the target stream is no
* longer alive. This case is currently not handled correctly.
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
@@ -173,8 +163,7 @@
* Separate threads should be used to write to a {@code PipedOutputStream}
* and to read from the connected {@link PipedInputStream}. If the same
* thread is used, a deadlock may occur.
- * </p>
- *
+ *
* @param oneByte
* the byte to write.
* @throws InterruptedIOException
@@ -185,7 +174,6 @@
* if this stream is not connected, if the target stream is
* closed or if the thread reading from the target stream is no
* longer alive. This case is currently not handled correctly.
- * @since Android 1.0
*/
@Override
public void write(int oneByte) throws IOException {
diff --git a/luni/src/main/java/java/io/PipedReader.java b/luni/src/main/java/java/io/PipedReader.java
index a0af9a5..251ac90 100644
--- a/luni/src/main/java/java/io/PipedReader.java
+++ b/luni/src/main/java/java/io/PipedReader.java
@@ -23,10 +23,8 @@
* Receives information on a communications pipe. When two threads want to pass
* data back and forth, one creates a piped writer and the other creates a piped
* reader.
- *
+ *
* @see PipedWriter
- *
- * @since Android 1.0
*/
public class PipedReader extends Reader {
@@ -66,9 +64,8 @@
* Constructs a new unconnected {@code PipedReader}. The resulting reader
* must be connected to a {@code PipedWriter} before data may be read from
* it.
- *
+ *
* @see PipedWriter
- * @since Android 1.0
*/
public PipedReader() {
data = new char[PIPE_SIZE];
@@ -78,12 +75,11 @@
* Constructs a new {@code PipedReader} connected to the {@link PipedWriter}
* {@code out}. Any data written to the writer can be read from the this
* reader.
- *
+ *
* @param out
* the {@code PipedWriter} to connect to.
* @throws IOException
* if {@code out} is already connected.
- * @since Android 1.0
*/
public PipedReader(PipedWriter out) throws IOException {
this();
@@ -93,10 +89,9 @@
/**
* Closes this reader. This implementation releases the buffer used for
* the pipe and notifies all threads waiting to read or write.
- *
+ *
* @throws IOException
* if an error occurs while closing this reader.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -112,13 +107,12 @@
/**
* Connects this {@code PipedReader} to a {@link PipedWriter}. Any data
* written to the writer becomes readable in this reader.
- *
+ *
* @param src
* the writer to connect to.
* @throws IOException
* if this reader is closed or already connected, or if {@code
* src} is already connected.
- * @since Android 1.0
*/
public void connect(PipedWriter src) throws IOException {
synchronized (lock) {
@@ -128,7 +122,7 @@
/**
* Establishes the connection to the PipedWriter.
- *
+ *
* @throws IOException
* If this Reader is already connected.
*/
@@ -154,13 +148,11 @@
* Separate threads should be used to read from a {@code PipedReader} and to
* write to the connected {@link PipedWriter}. If the same thread is used,
* a deadlock may occur.
- * </p>
- *
+ *
* @return the character read or -1 if the end of the reader has been
* reached.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -179,8 +171,7 @@
* Separate threads should be used to read from a {@code PipedReader} and to
* write to the connected {@link PipedWriter}. If the same thread is used, a
* deadlock may occur.
- * </p>
- *
+ *
* @param buffer
* the character array in which to store the characters read.
* @param offset
@@ -298,14 +289,13 @@
* called, {@code false} if unknown or blocking will occur. This
* implementation returns {@code true} if the internal buffer contains
* characters that can be read.
- *
+ *
* @return always {@code false}.
* @throws IOException
* if this reader is closed or not connected, or if some other
* I/O error occurs.
* @see #read()
* @see #read(char[], int, int)
- * @since Android 1.0
*/
@Override
public boolean ready() throws IOException {
@@ -326,10 +316,10 @@
* <P>
* If the buffer is full and the thread sending #receive is interrupted, the
* InterruptedIOException will be thrown.
- *
+ *
* @param oneChar
* the char to store into the pipe.
- *
+ *
* @throws IOException
* If the stream is already closed or another IOException
* occurs.
@@ -380,14 +370,14 @@
* <P>
* If the buffer is full and the thread sending #receive is interrupted, the
* InterruptedIOException will be thrown.
- *
+ *
* @param chars
* the char array to store into the pipe.
* @param offset
* offset to start reading from
* @param count
* total characters to read
- *
+ *
* @throws IOException
* If the stream is already closed or another IOException
* occurs.
diff --git a/luni/src/main/java/java/io/PipedWriter.java b/luni/src/main/java/java/io/PipedWriter.java
index 98a73c9..5fc968d 100644
--- a/luni/src/main/java/java/io/PipedWriter.java
+++ b/luni/src/main/java/java/io/PipedWriter.java
@@ -23,10 +23,8 @@
* Places information on a communications pipe. When two threads want to pass
* data back and forth, one creates a piped writer and the other creates a piped
* reader.
- *
+ *
* @see PipedReader
- *
- * @since Android 1.0
*/
public class PipedWriter extends Writer {
/**
@@ -40,9 +38,8 @@
* Constructs a new unconnected {@code PipedWriter}. The resulting writer
* must be connected to a {@code PipedReader} before data may be written to
* it.
- *
+ *
* @see PipedReader
- * @since Android 1.0
*/
public PipedWriter() {
super();
@@ -52,12 +49,11 @@
* Constructs a new {@code PipedWriter} connected to the {@link PipedReader}
* {@code dest}. Any data written to this writer can be read from {@code
* dest}.
- *
+ *
* @param dest
* the {@code PipedReader} to connect to.
* @throws IOException
* if {@code dest} is already connected.
- * @since Android 1.0
*/
public PipedWriter(PipedReader dest) throws IOException {
super(dest);
@@ -68,10 +64,9 @@
* Closes this writer. If a {@link PipedReader} is connected to this writer,
* it is closed as well and the pipe is disconnected. Any data buffered in
* the reader can still be read.
- *
+ *
* @throws IOException
* if an error occurs while closing this writer.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -88,13 +83,12 @@
/**
* Connects this {@code PipedWriter} to a {@link PipedReader}. Any data
* written to this writer becomes readable in the reader.
- *
+ *
* @param stream
* the reader to connect to.
* @throws IOException
* if this writer is closed or already connected, or if {@code
* stream} is already connected.
- * @since Android 1.0
*/
public void connect(PipedReader stream) throws IOException {
synchronized (lock) {
@@ -112,10 +106,9 @@
/**
* Notifies the readers of this {@code PipedReader} that characters can be read. This
* method does nothing if this Writer is not connected.
- *
+ *
* @throws IOException
* if an I/O error occurs while flushing this writer.
- * @since Android 1.0
*/
@Override
public void flush() throws IOException {
@@ -132,8 +125,7 @@
* Separate threads should be used to write to a {@code PipedWriter} and to
* read from the connected {@code PipedReader}. If the same thread is used,
* a deadlock may occur.
- * </p>
- *
+ *
* @param buffer
* the buffer to write.
* @param offset
@@ -155,7 +147,6 @@
* correctly.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
@Override
public void write(char[] buffer, int offset, int count) throws IOException {
@@ -194,8 +185,7 @@
* Separate threads should be used to write to a {@code PipedWriter} and to
* read from the connected {@code PipedReader}. If the same thread is used,
* a deadlock may occur.
- * </p>
- *
+ *
* @param c
* the character to write.
* @throws InterruptedIOException
@@ -207,7 +197,6 @@
* reader is closed or if the thread reading from the target
* reader is no longer alive. This case is currently not handled
* correctly.
- * @since Android 1.0
*/
@Override
public void write(int c) throws IOException {
diff --git a/luni/src/main/java/java/io/PrintStream.java b/luni/src/main/java/java/io/PrintStream.java
index 0aae645..29d460e 100644
--- a/luni/src/main/java/java/io/PrintStream.java
+++ b/luni/src/main/java/java/io/PrintStream.java
@@ -18,6 +18,7 @@
package java.io;
import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
import java.security.AccessController;
import java.util.Formatter;
import java.util.IllegalFormatException;
@@ -33,8 +34,6 @@
* so that they can be read back in. No {@code IOException} is thrown by this
* class. Instead, callers should use {@link #checkError()} to see if a problem
* has occurred in this stream.
- *
- * @since Android 1.0
*/
public class PrintStream extends FilterOutputStream implements Appendable,
Closeable {
@@ -63,12 +62,11 @@
* Constructs a new {@code PrintStream} with {@code out} as its target
* stream. By default, the new print stream does not automatically flush its
* contents to the target stream when a newline is encountered.
- *
+ *
* @param out
* the target output stream.
* @throws NullPointerException
* if {@code out} is {@code null}.
- * @since Android 1.0
*/
public PrintStream(OutputStream out) {
super(out);
@@ -82,7 +80,7 @@
* stream. The parameter {@code autoflush} determines if the print stream
* automatically flushes its contents to the target stream when a newline is
* encountered.
- *
+ *
* @param out
* the target output stream.
* @param autoflush
@@ -90,7 +88,6 @@
* newline sequence.
* @throws NullPointerException
* if {@code out} is {@code null}.
- * @since Android 1.0
*/
public PrintStream(OutputStream out, boolean autoflush) {
super(out);
@@ -105,7 +102,7 @@
* stream and using the character encoding {@code enc} while writing. The
* parameter {@code autoflush} determines if the print stream automatically
* flushes its contents to the target stream when a newline is encountered.
- *
+ *
* @param out
* the target output stream.
* @param autoflush
@@ -117,7 +114,6 @@
* if {@code out} or {@code enc} are {@code null}.
* @throws UnsupportedEncodingException
* if the encoding specified by {@code enc} is not supported.
- * @since Android 1.0
*/
public PrintStream(OutputStream out, boolean autoflush, String enc)
throws UnsupportedEncodingException {
@@ -126,7 +122,11 @@
throw new NullPointerException();
}
this.autoflush = autoflush;
- if (!Charset.isSupported(enc)) {
+ try {
+ if (!Charset.isSupported(enc)) {
+ throw new UnsupportedEncodingException(enc);
+ }
+ } catch (IllegalCharsetNameException e) {
throw new UnsupportedEncodingException(enc);
}
encoding = enc;
@@ -135,7 +135,7 @@
/**
* Constructs a new {@code PrintStream} with {@code file} as its target. The
* virtual machine's default character set is used for character encoding.
- *
+ *
* @param file
* the target file. If the file already exists, its contents are
* removed, otherwise a new file is created.
@@ -144,7 +144,6 @@
* @throws SecurityException
* if a security manager exists and it denies writing to the
* target file.
- * @since Android 1.0
*/
public PrintStream(File file) throws FileNotFoundException {
super(new FileOutputStream(file));
@@ -153,7 +152,7 @@
/**
* Constructs a new {@code PrintStream} with {@code file} as its target. The
* character set named {@code csn} is used for character encoding.
- *
+ *
* @param file
* the target file. If the file already exists, its contents are
* removed, otherwise a new file is created.
@@ -168,7 +167,6 @@
* target file.
* @throws UnsupportedEncodingException
* if the encoding specified by {@code csn} is not supported.
- * @since Android 1.0
*/
public PrintStream(File file, String csn) throws FileNotFoundException,
UnsupportedEncodingException {
@@ -186,7 +184,7 @@
* Constructs a new {@code PrintStream} with the file identified by
* {@code fileName} as its target. The virtual machine's default character
* set is used for character encoding.
- *
+ *
* @param fileName
* the target file's name. If the file already exists, its
* contents are removed, otherwise a new file is created.
@@ -195,7 +193,6 @@
* @throws SecurityException
* if a security manager exists and it denies writing to the
* target file.
- * @since Android 1.0
*/
public PrintStream(String fileName) throws FileNotFoundException {
this(new File(fileName));
@@ -205,7 +202,7 @@
* Constructs a new {@code PrintStream} with the file identified by
* {@code fileName} as its target. The character set named {@code csn} is
* used for character encoding.
- *
+ *
* @param fileName
* the target file's name. If the file already exists, its
* contents are removed, otherwise a new file is created.
@@ -220,7 +217,6 @@
* target file.
* @throws UnsupportedEncodingException
* if the encoding specified by {@code csn} is not supported.
- * @since Android 1.0
*/
public PrintStream(String fileName, String csn)
throws FileNotFoundException, UnsupportedEncodingException {
@@ -229,12 +225,11 @@
/**
* Flushes this stream and returns the value of the error flag.
- *
+ *
* @return {@code true} if either an {@code IOException} has been thrown
* previously or if {@code setError()} has been called;
* {@code false} otherwise.
- * @see #setError()
- * @since Android 1.0
+ * @see #setError()
*/
public boolean checkError() {
if (out != null) {
@@ -247,8 +242,6 @@
* Closes this print stream. Flushes this stream and then closes the target
* stream. If an I/O error occurs, this stream's error state is set to
* {@code true}.
- *
- * @since Android 1.0
*/
@Override
public synchronized void close() {
@@ -267,8 +260,6 @@
* Ensures that all pending data is sent out to the target stream. It also
* flushes the target stream. If an I/O error occurs, this stream's error
* state is set to {@code true}.
- *
- * @since Android 1.0
*/
@Override
public synchronized void flush() {
@@ -288,7 +279,7 @@
* target stream using the specified format string and arguments. For the
* locale, the default value of the current virtual machine instance is
* used.
- *
+ *
* @param format
* the format string used for {@link java.util.Formatter#format}.
* @param args
@@ -302,7 +293,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintStream format(String format, Object... args) {
return format(Locale.getDefault(), format, args);
@@ -311,7 +301,7 @@
/**
* Writes a string formatted by an intermediate {@link Formatter} to this
* stream using the specified locale, format string and arguments.
- *
+ *
* @param l
* the locale used in the method. No localization will be applied
* if {@code l} is {@code null}.
@@ -328,7 +318,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintStream format(Locale l, String format, Object... args) {
if (format == null) {
@@ -342,7 +331,7 @@
* Prints a formatted string. The behavior of this method is the same as
* this stream's {@code #format(String, Object...)} method. For the locale,
* the default value of the current virtual machine instance is used.
- *
+ *
* @param format
* the format string used for
* {@link java.util.Formatter#format}.
@@ -357,7 +346,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintStream printf(String format, Object... args) {
return format(format, args);
@@ -366,7 +354,7 @@
/**
* Prints a formatted string. The behavior of this method is the same as
* this stream's {@code #format(Locale, String, Object...)} method.
- *
+ *
* @param l
* the locale used in the method. No localization will be applied
* if {@code l} is {@code null}.
@@ -383,7 +371,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintStream printf(Locale l, String format, Object... args) {
return format(l, format, args);
@@ -399,11 +386,10 @@
/**
* Prints the string representation of the specified character array
* to the target stream.
- *
+ *
* @param charArray
* the character array to print to the target stream.
* @see #print(String)
- * @since Android 1.0
*/
public void print(char[] charArray) {
print(new String(charArray, 0, charArray.length));
@@ -412,11 +398,10 @@
/**
* Prints the string representation of the specified character to the target
* stream.
- *
+ *
* @param ch
* the character to print to the target stream.
* @see #print(String)
- * @since Android 1.0
*/
public void print(char ch) {
print(String.valueOf(ch));
@@ -425,11 +410,10 @@
/**
* Prints the string representation of the specified double to the target
* stream.
- *
+ *
* @param dnum
* the double value to print to the target stream.
* @see #print(String)
- * @since Android 1.0
*/
public void print(double dnum) {
print(String.valueOf(dnum));
@@ -438,12 +422,11 @@
/**
* Prints the string representation of the specified float to the target
* stream.
- *
+ *
* @param fnum
* the float value to print to the target stream.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(float fnum) {
print(String.valueOf(fnum));
}
@@ -451,12 +434,11 @@
/**
* Prints the string representation of the specified integer to the target
* stream.
- *
+ *
* @param inum
* the integer value to print to the target stream.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(int inum) {
print(String.valueOf(inum));
}
@@ -464,12 +446,11 @@
/**
* Prints the string representation of the specified long to the target
* stream.
- *
+ *
* @param lnum
* the long value to print to the target stream.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(long lnum) {
print(String.valueOf(lnum));
}
@@ -477,12 +458,11 @@
/**
* Prints the string representation of the specified object to the target
* stream.
- *
+ *
* @param obj
* the object to print to the target stream.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(Object obj) {
print(String.valueOf(obj));
}
@@ -494,12 +474,10 @@
* {@code write(int)}.
* <p>
* If an I/O error occurs, this stream's error state is set to {@code true}.
- * </p>
- *
+ *
* @param str
* the string to print to the target stream.
* @see #write(int)
- * @since Android 1.0
*/
public synchronized void print(String str) {
if (out == null) {
@@ -525,12 +503,11 @@
/**
* Prints the string representation of the specified boolean to the target
* stream.
- *
+ *
* @param bool
* the boolean value to print the target stream.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(boolean bool) {
print(String.valueOf(bool));
}
@@ -538,8 +515,6 @@
/**
* Prints the string representation of the system property
* {@code "line.separator"} to the target stream.
- *
- * @since Android 1.0
*/
public void println() {
newline();
@@ -549,11 +524,10 @@
* Prints the string representation of the specified character array
* followed by the system property {@code "line.separator"} to the target
* stream.
- *
+ *
* @param charArray
* the character array to print to the target stream.
* @see #print(String)
- * @since Android 1.0
*/
public void println(char[] charArray) {
println(new String(charArray, 0, charArray.length));
@@ -562,11 +536,10 @@
/**
* Prints the string representation of the specified character followed by
* the system property {@code "line.separator"} to the target stream.
- *
+ *
* @param ch
* the character to print to the target stream.
* @see #print(String)
- * @since Android 1.0
*/
public void println(char ch) {
println(String.valueOf(ch));
@@ -575,11 +548,10 @@
/**
* Prints the string representation of the specified double followed by the
* system property {@code "line.separator"} to the target stream.
- *
+ *
* @param dnum
* the double value to print to the target stream.
* @see #print(String)
- * @since Android 1.0
*/
public void println(double dnum) {
println(String.valueOf(dnum));
@@ -588,12 +560,11 @@
/**
* Prints the string representation of the specified float followed by the
* system property {@code "line.separator"} to the target stream.
- *
+ *
* @param fnum
* the float value to print to the target stream.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void println(float fnum) {
println(String.valueOf(fnum));
}
@@ -601,12 +572,12 @@
/**
* Prints the string representation of the specified integer followed by the
* system property {@code "line.separator"} to the target stream.
- *
+ *
* @param inum
* the integer value to print to the target stream.
* @see #print(String)
* @since Android 1.0
- */
+ */
public void println(int inum) {
println(String.valueOf(inum));
}
@@ -614,12 +585,12 @@
/**
* Prints the string representation of the specified long followed by the
* system property {@code "line.separator"} to the target stream.
- *
+ *
* @param lnum
* the long value to print to the target stream.
* @see #print(String)
* @since Android 1.0
- */
+ */
public void println(long lnum) {
println(String.valueOf(lnum));
}
@@ -627,12 +598,12 @@
/**
* Prints the string representation of the specified object followed by the
* system property {@code "line.separator"} to the target stream.
- *
+ *
* @param obj
* the object to print to the target stream.
* @see #print(String)
* @since Android 1.0
- */
+ */
public void println(Object obj) {
println(String.valueOf(obj));
}
@@ -645,7 +616,7 @@
* <p>
* If an I/O error occurs, this stream's error state is set to {@code true}.
* </p>
- *
+ *
* @param str
* the string to print to the target stream.
* @see #write(int)
@@ -659,20 +630,17 @@
/**
* Prints the string representation of the specified boolean followed by the
* system property {@code "line.separator"} to the target stream.
- *
+ *
* @param bool
* the boolean value to print to the target stream.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void println(boolean bool) {
println(String.valueOf(bool));
}
/**
* Sets the error flag of this print stream to {@code true}.
- *
- * @since Android 1.0
*/
protected void setError() {
ioError = true;
@@ -685,8 +653,7 @@
* <p>
* This stream's error flag is set to {@code true} if this stream is closed
* or an I/O error occurs.
- * </p>
- *
+ *
* @param buffer
* the buffer to be written.
* @param offset
@@ -697,7 +664,6 @@
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is bigger than the length of {@code buffer}.
* @see #flush()
- * @since Android 1.0
*/
@Override
public void write(byte[] buffer, int offset, int count) {
@@ -738,11 +704,9 @@
* <p>
* This stream's error flag is set to {@code true} if it is closed or an I/O
* error occurs.
- * </p>
- *
+ *
* @param oneByte
* the byte to be written
- * @since Android 1.0
*/
@Override
public synchronized void write(int oneByte) {
@@ -763,11 +727,10 @@
/**
* Appends the character {@code c} to the target stream. This method works
* the same way as {@link #print(char)}.
- *
+ *
* @param c
* the character to append to the target stream.
* @return this stream.
- * @since Android 1.0
*/
public PrintStream append(char c) {
print(c);
@@ -779,11 +742,10 @@
* method works the same way as {@code PrintStream.print(csq.toString())}.
* If {@code csq} is {@code null}, then the string "null" is written to the
* target stream.
- *
+ *
* @param csq
* the character sequence appended to the target stream.
* @return this stream.
- * @since Android 1.0
*/
public PrintStream append(CharSequence csq) {
if (null == csq) {
@@ -800,7 +762,7 @@
* PrintStream.print(csq.subsequence(start, end).toString())}. If {@code
* csq} is {@code null}, then the specified subsequence of the string "null"
* will be written to the target stream.
- *
+ *
* @param csq
* the character sequence appended to the target stream.
* @param start
@@ -814,7 +776,6 @@
* if {@code start > end}, {@code start < 0}, {@code end < 0} or
* either {@code start} or {@code end} are greater or equal than
* the length of {@code csq}.
- * @since Android 1.0
*/
public PrintStream append(CharSequence csq, int start, int end) {
if (null == csq) {
diff --git a/luni/src/main/java/java/io/PrintWriter.java b/luni/src/main/java/java/io/PrintWriter.java
index 0c5189d..f87707d 100644
--- a/luni/src/main/java/java/io/PrintWriter.java
+++ b/luni/src/main/java/java/io/PrintWriter.java
@@ -25,24 +25,16 @@
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
-// BEGIN android-note
-// added @return comment to #printf(Locale l, String format, Object... args)
-// END android-note
-
/**
* Wraps either an existing {@link OutputStream} or an existing {@link Writer}
* and provides convenience methods for printing common data types in a human
* readable format. No {@code IOException} is thrown by this class. Instead,
* callers should use {@link #checkError()} to see if a problem has occurred in
* this writer.
- *
- * @since Android 1.0
*/
public class PrintWriter extends Writer {
/**
* The writer to print data to.
- *
- * @since Android 1.0
*/
protected Writer out;
@@ -64,12 +56,11 @@
* Constructs a new {@code PrintWriter} with {@code out} as its target
* stream. By default, the new print writer does not automatically flush its
* contents to the target stream when a newline is encountered.
- *
+ *
* @param out
* the target output stream.
* @throws NullPointerException
* if {@code out} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter(OutputStream out) {
this(new OutputStreamWriter(out), false);
@@ -80,7 +71,7 @@
* stream. The parameter {@code autoflush} determines if the print writer
* automatically flushes its contents to the target stream when a newline is
* encountered.
- *
+ *
* @param out
* the target output stream.
* @param autoflush
@@ -88,7 +79,6 @@
* newline sequence.
* @throws NullPointerException
* if {@code out} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter(OutputStream out, boolean autoflush) {
this(new OutputStreamWriter(out), autoflush);
@@ -98,12 +88,11 @@
* Constructs a new {@code PrintWriter} with {@code wr} as its target
* writer. By default, the new print writer does not automatically flush its
* contents to the target writer when a newline is encountered.
- *
+ *
* @param wr
* the target writer.
* @throws NullPointerException
* if {@code wr} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter(Writer wr) {
this(wr, false);
@@ -114,7 +103,7 @@
* writer. The parameter {@code autoflush} determines if the print writer
* automatically flushes its contents to the target writer when a newline is
* encountered.
- *
+ *
* @param wr
* the target writer.
* @param autoflush
@@ -122,7 +111,6 @@
* newline sequence.
* @throws NullPointerException
* if {@code out} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter(Writer wr, boolean autoflush) {
super(wr);
@@ -135,7 +123,7 @@
* virtual machine's default character set is used for character encoding.
* The print writer does not automatically flush its contents to the target
* file when a newline is encountered. The output to the file is buffered.
- *
+ *
* @param file
* the target file. If the file already exists, its contents are
* removed, otherwise a new file is created.
@@ -144,7 +132,6 @@
* @throws SecurityException
* if a security manager exists and it denies writing to the
* target file.
- * @since Android 1.0
*/
public PrintWriter(File file) throws FileNotFoundException {
// BEGIN android-modified
@@ -160,7 +147,7 @@
* character set named {@code csn} is used for character encoding.
* The print writer does not automatically flush its contents to the target
* file when a newline is encountered. The output to the file is buffered.
- *
+ *
* @param file
* the target file. If the file already exists, its contents are
* removed, otherwise a new file is created.
@@ -175,7 +162,6 @@
* target file.
* @throws UnsupportedEncodingException
* if the encoding specified by {@code csn} is not supported.
- * @since Android 1.0
*/
public PrintWriter(File file, String csn) throws FileNotFoundException,
UnsupportedEncodingException {
@@ -193,7 +179,7 @@
* used for character encoding. The print writer does not automatically
* flush its contents to the target file when a newline is encountered. The
* output to the file is buffered.
- *
+ *
* @param fileName
* the target file's name. If the file already exists, its
* contents are removed, otherwise a new file is created.
@@ -202,7 +188,6 @@
* @throws SecurityException
* if a security manager exists and it denies writing to the
* target file.
- * @since Android 1.0
*/
public PrintWriter(String fileName) throws FileNotFoundException {
// BEGIN android-modified
@@ -219,7 +204,7 @@
* character encoding. The print writer does not automatically flush its
* contents to the target file when a newline is encountered. The output to
* the file is buffered.
- *
+ *
* @param fileName
* the target file's name. If the file already exists, its
* contents are removed, otherwise a new file is created.
@@ -234,7 +219,6 @@
* target file.
* @throws UnsupportedEncodingException
* if the encoding specified by {@code csn} is not supported.
- * @since Android 1.0
*/
public PrintWriter(String fileName, String csn)
throws FileNotFoundException, UnsupportedEncodingException {
@@ -248,12 +232,11 @@
/**
* Flushes this writer and returns the value of the error flag.
- *
+ *
* @return {@code true} if either an {@code IOException} has been thrown
* previously or if {@code setError()} has been called;
* {@code false} otherwise.
- * @see #setError()
- * @since Android 1.0
+ * @see #setError()
*/
public boolean checkError() {
if (out != null) {
@@ -265,8 +248,6 @@
/**
* Closes this print writer. Flushes this writer and then closes the target.
* If an I/O error occurs, this writer's error flag is set to {@code true}.
- *
- * @since Android 1.0
*/
@Override
public void close() {
@@ -286,8 +267,6 @@
* Ensures that all pending data is sent out to the target. It also
* flushes the target. If an I/O error occurs, this writer's error
* state is set to {@code true}.
- *
- * @since Android 1.0
*/
@Override
public void flush() {
@@ -309,7 +288,7 @@
* target using the specified format string and arguments. For the locale,
* the default value of the current virtual machine instance is used. If
* automatic flushing is enabled then the buffer is flushed as well.
- *
+ *
* @param format
* the format string used for {@link java.util.Formatter#format}.
* @param args
@@ -323,7 +302,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter format(String format, Object... args) {
return format(Locale.getDefault(), format, args);
@@ -333,7 +311,7 @@
* Writes a string formatted by an intermediate {@code Formatter} to the
* target using the specified locale, format string and arguments. If
* automatic flushing is enabled then this writer is flushed.
- *
+ *
* @param l
* the locale used in the method. No localization will be applied
* if {@code l} is {@code null}.
@@ -350,7 +328,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter format(Locale l, String format, Object... args) {
if (format == null) {
@@ -367,7 +344,7 @@
* Prints a formatted string. The behavior of this method is the same as
* this writer's {@code #format(String, Object...)} method. For the locale,
* the default value of the current virtual machine instance is used.
- *
+ *
* @param format
* the format string used for {@link java.util.Formatter#format}.
* @param args
@@ -381,7 +358,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter printf(String format, Object... args) {
return format(format, args);
@@ -390,7 +366,7 @@
/**
* Prints a formatted string. The behavior of this method is the same as
* this writer's {@code #format(Locale, String, Object...)} method.
- *
+ *
* @param l
* the locale used in the method. No localization will be applied
* if {@code l} is {@code null}.
@@ -407,7 +383,6 @@
* error regarding the format string or arguments is detected.
* @throws NullPointerException
* if {@code format} is {@code null}.
- * @since Android 1.0
*/
public PrintWriter printf(Locale l, String format, Object... args) {
return format(l, format, args);
@@ -426,11 +401,10 @@
/**
* Prints the string representation of the specified character array
* to the target.
- *
+ *
* @param charArray
* the character array to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void print(char[] charArray) {
print(new String(charArray, 0, charArray.length));
@@ -439,11 +413,10 @@
/**
* Prints the string representation of the specified character to the
* target.
- *
+ *
* @param ch
* the character to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void print(char ch) {
print(String.valueOf(ch));
@@ -451,23 +424,21 @@
/**
* Prints the string representation of the specified double to the target.
- *
+ *
* @param dnum
* the double value to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void print(double dnum) {
print(String.valueOf(dnum));
}
- /**
+ /**
* Prints the string representation of the specified float to the target.
- *
+ *
* @param fnum
* the float value to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void print(float fnum) {
print(String.valueOf(fnum));
@@ -475,23 +446,21 @@
/**
* Prints the string representation of the specified integer to the target.
- *
+ *
* @param inum
* the integer value to print to the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(int inum) {
print(String.valueOf(inum));
}
/**
* Prints the string representation of the specified long to the target.
- *
+ *
* @param lnum
* the long value to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void print(long lnum) {
print(String.valueOf(lnum));
@@ -499,12 +468,11 @@
/**
* Prints the string representation of the specified object to the target.
- *
+ *
* @param obj
* the object to print to the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(Object obj) {
print(String.valueOf(obj));
}
@@ -515,12 +483,10 @@
* The bytes are then written to the target with {@code write(int)}.
* <p>
* If an I/O error occurs, this writer's error flag is set to {@code true}.
- * </p>
- *
+ *
* @param str
* the string to print to the target.
* @see #write(int)
- * @since Android 1.0
*/
public void print(String str) {
write(str != null ? str : String.valueOf((Object) null));
@@ -528,12 +494,11 @@
/**
* Prints the string representation of the specified boolean to the target.
- *
+ *
* @param bool
* the boolean value to print the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void print(boolean bool) {
print(String.valueOf(bool));
}
@@ -542,8 +507,6 @@
* Prints the string representation of the system property {@code
* "line.separator"} to the target. Flushes this writer if the autoflush
* flag is set to {@code true}.
- *
- * @since Android 1.0
*/
public void println() {
synchronized (lock) {
@@ -555,11 +518,10 @@
* Prints the string representation of the specified character array
* followed by the system property {@code "line.separator"} to the target.
* Flushes this writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param charArray
* the character array to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void println(char[] charArray) {
println(new String(charArray, 0, charArray.length));
@@ -569,11 +531,10 @@
* Prints the string representation of the specified character followed by
* the system property {@code "line.separator"} to the target. Flushes this
* writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param ch
* the character to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void println(char ch) {
println(String.valueOf(ch));
@@ -583,11 +544,10 @@
* Prints the string representation of the specified double followed by the
* system property {@code "line.separator"} to the target. Flushes this
* writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param dnum
* the double value to print to the target.
* @see #print(String)
- * @since Android 1.0
*/
public void println(double dnum) {
println(String.valueOf(dnum));
@@ -597,12 +557,11 @@
* Prints the string representation of the specified float followed by the
* system property {@code "line.separator"} to the target. Flushes this
* writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param fnum
* the float value to print to the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void println(float fnum) {
println(String.valueOf(fnum));
}
@@ -611,12 +570,11 @@
* Prints the string representation of the specified integer followed by the
* system property {@code "line.separator"} to the target. Flushes this
* writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param inum
* the integer value to print to the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void println(int inum) {
println(String.valueOf(inum));
}
@@ -625,12 +583,11 @@
* Prints the string representation of the specified long followed by the
* system property {@code "line.separator"} to the target. Flushes this
* writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param lnum
* the long value to print to the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void println(long lnum) {
println(String.valueOf(lnum));
}
@@ -639,12 +596,11 @@
* Prints the string representation of the specified object followed by the
* system property {@code "line.separator"} to the target. Flushes this
* writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param obj
* the object to print to the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void println(Object obj) {
println(String.valueOf(obj));
}
@@ -657,12 +613,10 @@
* is flushed if the autoflush flag is set to {@code true}.
* <p>
* If an I/O error occurs, this writer's error flag is set to {@code true}.
- * </p>
- *
+ *
* @param str
* the string to print to the target.
* @see #write(int)
- * @since Android 1.0
*/
public void println(String str) {
synchronized (lock) {
@@ -675,20 +629,17 @@
* Prints the string representation of the specified boolean followed by the
* system property {@code "line.separator"} to the target. Flushes this
* writer if the autoflush flag is set to {@code true}.
- *
+ *
* @param bool
* the boolean value to print to the target.
* @see #print(String)
- * @since Android 1.0
- */
+ */
public void println(boolean bool) {
println(String.valueOf(bool));
}
/**
* Sets the error flag of this writer to {@code true}.
- *
- * @since Android 1.0
*/
protected void setError() {
synchronized (lock) {
@@ -698,10 +649,9 @@
/**
* Writes the character buffer {@code buf} to the target.
- *
+ *
* @param buf
* the non-null array containing characters to write.
- * @since Android 1.0
*/
@Override
public void write(char[] buf) {
@@ -717,8 +667,7 @@
* <p>
* This writer's error flag is set to {@code true} if this writer is closed
* or an I/O error occurs.
- * </p>
- *
+ *
* @param buf
* the buffer to write to the target.
* @param offset
@@ -728,7 +677,6 @@
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is greater than the length of {@code buf}.
- * @since Android 1.0
*/
@Override
public void write(char[] buf, int offset, int count) {
@@ -744,11 +692,9 @@
* <p>
* This writer's error flag is set to {@code true} if this writer is closed
* or an I/O error occurs.
- * </p>
- *
+ *
* @param oneChar
* the character to write to the target.
- * @since Android 1.0
*/
@Override
public void write(int oneChar) {
@@ -774,10 +720,9 @@
/**
* Writes the characters from the specified string to the target.
- *
+ *
* @param str
* the non-null string containing the characters to write.
- * @since Android 1.0
*/
@Override
public void write(String str) {
@@ -787,7 +732,7 @@
/**
* Writes {@code count} characters from {@code str} starting at {@code
* offset} to the target.
- *
+ *
* @param str
* the non-null string containing the characters to write.
* @param offset
@@ -797,7 +742,6 @@
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is greater than the length of {@code str}.
- * @since Android 1.0
*/
@Override
public void write(String str, int offset, int count) {
@@ -805,12 +749,11 @@
}
/**
- * Appends the character {@code c} to the target.
- *
+ * Appends the character {@code c} to the target.
+ *
* @param c
* the character to append to the target.
* @return this writer.
- * @since Android 1.0
*/
@Override
public PrintWriter append(char c) {
@@ -823,11 +766,10 @@
* method works the same way as {@code PrintWriter.print(csq.toString())}.
* If {@code csq} is {@code null}, then the string "null" is written
* to the target.
- *
+ *
* @param csq
* the character sequence appended to the target.
* @return this writer.
- * @since Android 1.0
*/
@Override
public PrintWriter append(CharSequence csq) {
@@ -845,7 +787,7 @@
* PrintWriter.print(csq.subsequence(start, end).toString())}. If {@code
* csq} is {@code null}, then the specified subsequence of the string "null"
* will be written to the target.
- *
+ *
* @param csq
* the character sequence appended to the target.
* @param start
@@ -859,7 +801,6 @@
* if {@code start > end}, {@code start < 0}, {@code end < 0} or
* either {@code start} or {@code end} are greater or equal than
* the length of {@code csq}.
- * @since Android 1.0
*/
@Override
public PrintWriter append(CharSequence csq, int start, int end) {
diff --git a/luni/src/main/java/java/io/PushbackInputStream.java b/luni/src/main/java/java/io/PushbackInputStream.java
index c397c86..1784012 100644
--- a/luni/src/main/java/java/io/PushbackInputStream.java
+++ b/luni/src/main/java/java/io/PushbackInputStream.java
@@ -25,14 +25,10 @@
* this useful. The number of bytes which may be pushed back can be specified
* during construction. If the buffer of pushed back bytes is empty, bytes are
* read from the underlying input stream.
- *
- * @since Android 1.0
*/
public class PushbackInputStream extends FilterInputStream {
/**
* The buffer that contains pushed-back bytes.
- *
- * @since Android 1.0
*/
protected byte[] buf;
@@ -40,8 +36,6 @@
* The current position within {@code buf}. A value equal to
* {@code buf.length} indicates that no bytes are available. A value of 0
* indicates that the buffer is full.
- *
- * @since Android 1.0
*/
protected int pos;
@@ -49,10 +43,9 @@
* Constructs a new {@code PushbackInputStream} with the specified input
* stream as source. The size of the pushback buffer is set to the default
* value of 1 byte.
- *
+ *
* @param in
* the source input stream.
- * @since Android 1.0
*/
public PushbackInputStream(InputStream in) {
super(in);
@@ -63,14 +56,13 @@
/**
* Constructs a new {@code PushbackInputStream} with {@code in} as source
* input stream. The size of the pushback buffer is set to {@code size}.
- *
+ *
* @param in
* the source input stream.
* @param size
* the size of the pushback buffer.
* @throws IllegalArgumentException
* if {@code size} is negative.
- * @since Android 1.0
*/
public PushbackInputStream(InputStream in, int size) {
super(in);
@@ -85,12 +77,11 @@
* Returns the number of bytes that are available before this stream will
* block. This is the sum of the bytes available in the pushback buffer and
* those available from the source stream.
- *
+ *
* @return the number of bytes available before blocking.
* @throws IOException
* if this stream is closed or an I/O error occurs in the source
* stream.
- * @since Android 1.0
*/
@Override
public int available() throws IOException {
@@ -103,10 +94,9 @@
/**
* Closes this stream. This implementation closes the source stream
* and releases the pushback buffer.
- *
+ *
* @throws IOException
* if an error occurs while closing this stream.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -121,11 +111,10 @@
* Indicates whether this stream supports the {@code mark(int)} and
* {@code reset()} methods. {@code PushbackInputStream} does not support
* them, so it returns {@code false}.
- *
+ *
* @return always {@code false}.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -138,13 +127,12 @@
* available bytes then a byte from the source input stream is returned.
* Blocks until one byte has been read, the end of the source stream is
* detected or an exception is thrown.
- *
+ *
* @return the byte read or -1 if the end of the source stream has been
* reached.
* @throws IOException
* if this stream is closed or an I/O error occurs while reading
* from this stream.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -166,7 +154,7 @@
* from the pushback buffer first, then from the source stream if more bytes
* are required. Blocks until {@code count} bytes have been read, the end of
* the source stream is detected or an exception is thrown.
- *
+ *
* @param buffer
* the array in which to store the bytes read from this stream.
* @param offset
@@ -185,7 +173,6 @@
* reading from this stream.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer, int offset, int length) throws IOException {
@@ -234,13 +221,12 @@
/**
* Skips {@code count} bytes in this stream. This implementation skips bytes
* in the pushback buffer first and then in the source stream if necessary.
- *
+ *
* @param count
* the number of bytes to skip.
* @return the number of bytes actually skipped.
* @throws IOException
* if this stream is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public long skip(long count) throws IOException {
@@ -270,14 +256,12 @@
* contents of {@code buffer}, an {@code IOException} is thrown. Parts of
* {@code buffer} may have already been copied to the pushback buffer when
* the exception is thrown.
- * </p>
- *
+ *
* @param buffer
* the buffer containing the bytes to push back to this stream.
* @throws IOException
* if the free space in the internal pushback buffer is not
* sufficient to store the contents of {@code buffer}.
- * @since Android 1.0
*/
public void unread(byte[] buffer) throws IOException {
unread(buffer, 0, buffer.length);
@@ -294,8 +278,7 @@
* subset of {@code buffer}, an {@code IOException} is thrown. Parts of
* {@code buffer} may have already been copied to the pushback buffer when
* the exception is thrown.
- * </p>
- *
+ *
* @param buffer
* the buffer containing the bytes to push back to this stream.
* @param offset
@@ -309,7 +292,6 @@
* @throws IOException
* if the free space in the internal pushback buffer is not
* sufficient to store the selected contents of {@code buffer}.
- * @since Android 1.0
*/
public void unread(byte[] buffer, int offset, int length)
throws IOException {
@@ -345,14 +327,12 @@
* <p>
* If this stream's internal pushback buffer cannot store the byte, an
* {@code IOException} is thrown.
- * </p>
- *
+ *
* @param oneByte
* the byte to push back to this stream.
* @throws IOException
* if this stream is closed or the internal pushback buffer is
* full.
- * @since Android 1.0
*/
public void unread(int oneByte) throws IOException {
if (buf == null) {
@@ -367,11 +347,10 @@
/**
* Marks the current position in this stream. Setting a mark is not
* supported in this class; this implementation does nothing.
- *
+ *
* @param readlimit
* the number of bytes that can be read from this stream before
* the mark is invalidated; this parameter is ignored.
- * @since Android 1.0
*/
@Override
public void mark(int readlimit) {
@@ -382,10 +361,9 @@
* Resets this stream to the last marked position. Resetting the stream is
* not supported in this class; this implementation always throws an
* {@code IOException}.
- *
+ *
* @throws IOException
* if this method is called.
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
diff --git a/luni/src/main/java/java/io/PushbackReader.java b/luni/src/main/java/java/io/PushbackReader.java
index 484caf3..606ecb4 100644
--- a/luni/src/main/java/java/io/PushbackReader.java
+++ b/luni/src/main/java/java/io/PushbackReader.java
@@ -25,8 +25,6 @@
* find this useful. The number of characters which may be pushed back can be
* specified during construction. If the buffer of pushed back bytes is empty,
* characters are read from the underlying reader.
- *
- * @since Android 1.0
*/
public class PushbackReader extends FilterReader {
/**
@@ -45,10 +43,9 @@
* Constructs a new {@code PushbackReader} with the specified reader as
* source. The size of the pushback buffer is set to the default value of 1
* character.
- *
+ *
* @param in
* the source reader.
- * @since Android 1.0
*/
public PushbackReader(Reader in) {
super(in);
@@ -59,14 +56,13 @@
/**
* Constructs a new {@code PushbackReader} with {@code in} as source reader.
* The size of the pushback buffer is set to {@code size}.
- *
+ *
* @param in
* the source reader.
* @param size
* the size of the pushback buffer.
* @throws IllegalArgumentException
* if {@code size} is negative.
- * @since Android 1.0
*/
public PushbackReader(Reader in, int size) {
super(in);
@@ -80,10 +76,9 @@
/**
* Closes this reader. This implementation closes the source reader
* and releases the pushback buffer.
- *
+ *
* @throws IOException
* if an error occurs while closing this reader.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -97,13 +92,12 @@
* Marks the current position in this stream. Setting a mark is not
* supported in this class; this implementation always throws an
* {@code IOException}.
- *
+ *
* @param readAheadLimit
* the number of character that can be read from this reader
* before the mark is invalidated; this parameter is ignored.
* @throws IOException
* if this method is called.
- * @since Android 1.0
*/
@Override
public void mark(int readAheadLimit) throws IOException {
@@ -114,11 +108,10 @@
* Indicates whether this reader supports the {@code mark(int)} and
* {@code reset()} methods. {@code PushbackReader} does not support them, so
* it returns {@code false}.
- *
+ *
* @return always {@code false}.
* @see #mark(int)
* @see #reset()
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -132,13 +125,12 @@
* available characters then a character from the source reader is returned.
* Blocks until one character has been read, the end of the source reader is
* detected or an exception is thrown.
- *
+ *
* @return the character read or -1 if the end of the source reader has been
* reached.
* @throws IOException
* if this reader is closed or an I/O error occurs while reading
* from this reader.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -164,7 +156,7 @@
* read from the pushback buffer first, then from the source reader if more
* bytes are required. Blocks until {@code count} characters have been read,
* the end of the source reader is detected or an exception is thrown.
- *
+ *
* @param buffer
* the array in which to store the characters read from this
* reader.
@@ -182,7 +174,6 @@
* @throws IOException
* if this reader is closed or another I/O error occurs while
* reading from this reader.
- * @since Android 1.0
*/
@Override
public int read(char[] buffer, int offset, int count) throws IOException {
@@ -236,7 +227,7 @@
* Indicates whether this reader is ready to be read without blocking.
* Returns {@code true} if this reader will not block when {@code read} is
* called, {@code false} if unknown or blocking will occur.
- *
+ *
* @return {@code true} if the receiver will not block when
* {@code read()} is called, {@code false} if unknown
* or blocking will occur.
@@ -244,7 +235,6 @@
* if this reader is closed or some other I/O error occurs.
* @see #read()
* @see #read(char[], int, int)
- * @since Android 1.0
*/
@Override
public boolean ready() throws IOException {
@@ -260,10 +250,9 @@
* Resets this reader to the last marked position. Resetting the reader is
* not supported in this class; this implementation always throws an
* {@code IOException}.
- *
+ *
* @throws IOException
* if this method is called.
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
@@ -279,8 +268,7 @@
* contents of {@code buffer}, an {@code IOException} is thrown. Parts of
* {@code buffer} may have already been copied to the pushback buffer when
* the exception is thrown.
- * </p>
- *
+ *
* @param buffer
* the buffer containing the characters to push back to this
* reader.
@@ -288,7 +276,6 @@
* if this reader is closed or the free space in the internal
* pushback buffer is not sufficient to store the contents of
* {@code buffer}.
- * @since Android 1.0
*/
public void unread(char[] buffer) throws IOException {
unread(buffer, 0, buffer.length);
@@ -305,8 +292,7 @@
* subset of {@code buffer}, an {@code IOException} is thrown. Parts of
* {@code buffer} may have already been copied to the pushback buffer when
* the exception is thrown.
- * </p>
- *
+ *
* @param buffer
* the buffer containing the characters to push back to this
* reader.
@@ -324,7 +310,6 @@
* contents of {@code buffer}.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
public void unread(char[] buffer, int offset, int count) throws IOException {
synchronized (lock) {
@@ -361,14 +346,12 @@
* <p>
* If this reader's internal pushback buffer cannot store the character, an
* {@code IOException} is thrown.
- * </p>
- *
+ *
* @param oneChar
* the character to push back to this stream.
* @throws IOException
* if this reader is closed or the internal pushback buffer is
* full.
- * @since Android 1.0
*/
public void unread(int oneChar) throws IOException {
synchronized (lock) {
@@ -386,14 +369,13 @@
* Skips {@code count} characters in this reader. This implementation skips
* characters in the pushback buffer first and then in the source reader if
* necessary.
- *
+ *
* @param count
* the number of characters to skip.
* @return the number of characters actually skipped.
* @throws IllegalArgumentException if {@code count < 0}.
* @throws IOException
* if this reader is closed or another I/O error occurs.
- * @since Android 1.0
*/
@Override
public long skip(long count) throws IOException {
diff --git a/luni/src/main/java/java/io/RandomAccessFile.java b/luni/src/main/java/java/io/RandomAccessFile.java
index 7152116..37d77f5 100644
--- a/luni/src/main/java/java/io/RandomAccessFile.java
+++ b/luni/src/main/java/java/io/RandomAccessFile.java
@@ -33,8 +33,6 @@
* opened in read/write mode, write operations are available as well. The
* position of the next read or write operation can be moved forwards and
* backwards after every operation.
- *
- * @since Android 1.0
*/
public class RandomAccessFile implements DataInput, DataOutput, Closeable {
/**
@@ -51,7 +49,7 @@
private IFileSystem fileSystem = Platform.getFileSystem();
private boolean isReadOnly;
-
+
// BEGIN android-added
private int options;
// END android-added
@@ -61,12 +59,11 @@
private Object repositionLock = new RepositionLock();
- // BEGIN android-changed
/**
* Constructs a new {@code RandomAccessFile} based on {@code file} and opens
- * it according to the access string in {@code mode}.
+ * it according to the access string in {@code mode}.
* <p><a id="accessmode"/>
- * {@code mode} may have one of following values:
+ * {@code mode} may have one of following values:
* <table border="0">
* <tr>
* <td>{@code "r"}</td>
@@ -90,7 +87,7 @@
* file's content must be written synchronously to the target device.</td>
* </tr>
* </table>
- * </p>
+ *
* @param file
* the file to open.
* @param mode
@@ -107,16 +104,17 @@
* access request according to {@code mode}.
* @see java.lang.SecurityManager#checkRead(FileDescriptor)
* @see java.lang.SecurityManager#checkWrite(FileDescriptor)
- * @since Android 1.0
*/
public RandomAccessFile(File file, String mode)
throws FileNotFoundException {
super();
+ // BEGIN android-changed
options = 0;
-
+ // END android-changed
+
fd = new FileDescriptor();
-
+
if (mode.equals("r")) { //$NON-NLS-1$
isReadOnly = true;
fd.readOnly = true;
@@ -143,8 +141,12 @@
security.checkWrite(file.getPath());
}
}
-
+
fd.descriptor = fileSystem.open(file.properPath(true), options);
+ // BEGIN android-removed
+ // channel = FileChannelFactory.getFileChannel(this, fd.descriptor,
+ // options);
+ // END android-removed
// if we are in "rws" mode, attempt to sync file+metadata
if (syncMetadata) {
@@ -155,14 +157,13 @@
}
}
}
- // END android-changed
/**
* Constructs a new {@code RandomAccessFile} based on the file named {@code
* fileName} and opens it according to the access string in {@code mode}.
* The file path may be specified absolutely or relative to the system
* property {@code "user.dir"}.
- *
+ *
* @param fileName
* the name of the file to open.
* @param mode
@@ -179,7 +180,6 @@
* access request according to {@code mode}.
* @see java.lang.SecurityManager#checkRead(FileDescriptor)
* @see java.lang.SecurityManager#checkWrite(FileDescriptor)
- * @since Android 1.0
*/
public RandomAccessFile(String fileName, String mode)
throws FileNotFoundException {
@@ -188,10 +188,9 @@
/**
* Closes this file.
- *
+ *
* @throws IOException
* if an error occurs while closing this file.
- * @since Android 1.0
*/
public void close() throws IOException {
// BEGIN android-changed
@@ -208,39 +207,34 @@
// END android-changed
}
- // BEGIN android-changed
/**
* Gets this file's {@link FileChannel} object.
* <p>
- * The file channel's {@link FileChannel.#position() position} is the same
+ * The file channel's {@link FileChannel#position() position} is the same
* as this file's file pointer offset (see {@link #getFilePointer()}). Any
* changes made to this file's file pointer offset are also visible in the
* file channel's position and vice versa.
- * </p>
- *
+ *
* @return this file's file channel instance.
- * @since Android 1.0
*/
- public final FileChannel getChannel() {
- synchronized(this) {
- if(channel == null) {
- channel = FileChannelFactory.getFileChannel(this, fd.descriptor,
- options);
- }
- return channel;
+ public final synchronized FileChannel getChannel() {
+ // BEGIN android-added
+ if(channel == null) {
+ channel = FileChannelFactory.getFileChannel(this, fd.descriptor,
+ options);
}
+ // END android-added
+ return channel;
}
- // END android-changed
/**
* Gets this file's {@link FileDescriptor}. This represents the operating
* system resource for this random access file.
- *
+ *
* @return this file's file descriptor object.
* @throws IOException
* if an error occurs while getting the file descriptor of this
* file.
- * @since Android 1.0
*/
public final FileDescriptor getFD() throws IOException {
return fd;
@@ -249,13 +243,12 @@
/**
* Gets the current position within this file. All reads and
* writes take place at the current file pointer position.
- *
+ *
* @return the current offset in bytes from the beginning of the file.
- *
+ *
* @throws IOException
* if an error occurs while getting the file pointer of this
* file.
- * @since Android 1.0
*/
public long getFilePointer() throws IOException {
openCheck();
@@ -265,7 +258,7 @@
/**
* Checks to see if the file is currently open. Returns silently if it is,
* and throws an exception if it is not.
- *
+ *
* @throws IOException
* the receiver is closed.
*/
@@ -277,11 +270,10 @@
/**
* Returns the length of this file in bytes.
- *
+ *
* @return the file's length in bytes.
* @throws IOException
* if this file is closed or some other I/O error occurs.
- * @since Android 1.0
*/
public long length() throws IOException {
openCheck();
@@ -301,11 +293,10 @@
* as an integer in the range from 0 to 255. Returns -1 if the end of the
* file has been reached. Blocks until one byte has been read, the end of
* the file is detected or an exception is thrown.
- *
+ *
* @return the byte read or -1 if the end of the file has been reached.
* @throws IOException
* if this file is closed or another I/O error occurs.
- * @since Android 1.0
*/
public int read() throws IOException {
openCheck();
@@ -321,14 +312,13 @@
* byte array {@code buffer}. The maximum number of bytes read corresponds
* to the size of {@code buffer}. Blocks until at least one byte has been
* read.
- *
+ *
* @param buffer
* the byte array in which to store the bytes read.
* @return the number of bytes actually read or -1 if the end of the file
* has been reached.
* @throws IOException
* if this file is closed or another I/O error occurs.
- * @since Android 1.0
*/
public int read(byte[] buffer) throws IOException {
return read(buffer, 0, buffer.length);
@@ -339,7 +329,7 @@
* and stores them in the byte array {@code buffer} starting at {@code
* offset}. Blocks until {@code count} bytes have been read, the end of the
* file is reached or an exception is thrown.
- *
+ *
* @param buffer
* the array in which to store the bytes read from this file.
* @param offset
@@ -354,7 +344,6 @@
* offset + count} is greater than the size of {@code buffer}.
* @throws IOException
* if this file is closed or another I/O error occurs.
- * @since Android 1.0
*/
public int read(byte[] buffer, int offset, int count) throws IOException {
// have to have four comparisions to not miss integer overflow cases
@@ -383,14 +372,13 @@
* Reads a boolean from the current position in this file. Blocks until one
* byte has been read, the end of the file is reached or an exception is
* thrown.
- *
+ *
* @return the next boolean value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeBoolean(boolean)
- * @since Android 1.0
*/
public final boolean readBoolean() throws IOException {
int temp = this.read();
@@ -404,14 +392,13 @@
* Reads an 8-bit byte from the current position in this file. Blocks until
* one byte has been read, the end of the file is reached or an exception is
* thrown.
- *
+ *
* @return the next signed 8-bit byte value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeBoolean(boolean)
- * @since Android 1.0
*/
public final byte readByte() throws IOException {
int temp = this.read();
@@ -425,15 +412,14 @@
* Reads a 16-bit character from the current position in this file. Blocks until
* two bytes have been read, the end of the file is reached or an exception is
* thrown.
- *
+ *
* @return the next char value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeChar(int)
- * @since Android 1.0
- */
+ */
public final char readChar() throws IOException {
byte[] buffer = new byte[2];
if (read(buffer, 0, buffer.length) != buffer.length) {
@@ -446,14 +432,13 @@
* Reads a 64-bit double from the current position in this file. Blocks
* until eight bytes have been read, the end of the file is reached or an
* exception is thrown.
- *
+ *
* @return the next double value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeDouble(double)
- * @since Android 1.0
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
@@ -463,14 +448,13 @@
* Reads a 32-bit float from the current position in this file. Blocks
* until four bytes have been read, the end of the file is reached or an
* exception is thrown.
- *
+ *
* @return the next float value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeFloat(float)
- * @since Android 1.0
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
@@ -480,7 +464,7 @@
* Reads bytes from this file into {@code buffer}. Blocks until {@code
* buffer.length} number of bytes have been read, the end of the file is
* reached or an exception is thrown.
- *
+ *
* @param buffer
* the buffer to read bytes into.
* @throws EOFException
@@ -489,7 +473,6 @@
* if this file is closed or another I/O error occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
public final void readFully(byte[] buffer) throws IOException {
readFully(buffer, 0, buffer.length);
@@ -499,7 +482,7 @@
* Read bytes from this file into {@code buffer} starting at offset {@code
* offset}. This method blocks until {@code count} number of bytes have been
* read.
- *
+ *
* @param buffer
* the buffer to read bytes into.
* @param offset
@@ -516,7 +499,6 @@
* if this file is closed or another I/O error occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
public final void readFully(byte[] buffer, int offset, int count)
throws IOException {
@@ -547,14 +529,13 @@
* Reads a 32-bit integer from the current position in this file. Blocks
* until four bytes have been read, the end of the file is reached or an
* exception is thrown.
- *
+ *
* @return the next int value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeInt(int)
- * @since Android 1.0
*/
public final int readInt() throws IOException {
byte[] buffer = new byte[4];
@@ -573,13 +554,11 @@
* <p>
* Blocks until a line terminating sequence has been read, the end of the
* file is reached or an exception is thrown.
- * </p>
- *
+ *
* @return the contents of the line or {@code null} if no characters have
* been read before the end of the file has been reached.
* @throws IOException
* if this file is closed or another I/O error occurs.
- * @since Android 1.0
*/
public final String readLine() throws IOException {
StringBuilder line = new StringBuilder(80); // Typical line length
@@ -615,14 +594,13 @@
* Reads a 64-bit long from the current position in this file. Blocks until
* eight bytes have been read, the end of the file is reached or an
* exception is thrown.
- *
+ *
* @return the next long value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeLong(long)
- * @since Android 1.0
*/
public final long readLong() throws IOException {
byte[] buffer = new byte[8];
@@ -641,14 +619,13 @@
* Reads a 16-bit short from the current position in this file. Blocks until
* two bytes have been read, the end of the file is reached or an exception
* is thrown.
- *
+ *
* @return the next short value from this file.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeShort(int)
- * @since Android 1.0
*/
public final short readShort() throws IOException {
byte[] buffer = new byte[2];
@@ -662,14 +639,13 @@
* Reads an unsigned 8-bit byte from the current position in this file and
* returns it as an integer. Blocks until one byte has been read, the end of
* the file is reached or an exception is thrown.
- *
+ *
* @return the next unsigned byte value from this file as an int.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeByte(int)
- * @since Android 1.0
*/
public final int readUnsignedByte() throws IOException {
int temp = this.read();
@@ -683,14 +659,13 @@
* Reads an unsigned 16-bit short from the current position in this file and
* returns it as an integer. Blocks until two bytes have been read, the end of
* the file is reached or an exception is thrown.
- *
+ *
* @return the next unsigned short value from this file as an int.
* @throws EOFException
* if the end of this file is detected.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #writeShort(int)
- * @since Android 1.0
*/
public final int readUnsignedShort() throws IOException {
byte[] buffer = new byte[2];
@@ -706,7 +681,7 @@
* is determined by the first two bytes read from the file. Blocks until all
* required bytes have been read, the end of the file is reached or an
* exception is thrown.
- *
+ *
* @return the next string encoded in {@link DataInput modified UTF-8} from
* this file.
* @throws EOFException
@@ -716,7 +691,6 @@
* @throws UTFDataFormatException
* if the bytes read cannot be decoded into a character string.
* @see #writeUTF(String)
- * @since Android 1.0
*/
public final String readUTF() throws IOException {
int utfSize = readUnsignedShort();
@@ -736,13 +710,12 @@
* position may be greater than the current length of the file, but the
* file's length will only change if the moving of the pointer is followed
* by a {@code write} operation.
- *
+ *
* @param pos
* the new file pointer position.
* @throws IOException
* if this file is closed, {@code pos < 0} or another I/O error
* occurs.
- * @since Android 1.0
*/
public void seek(long pos) throws IOException {
if (pos < 0) {
@@ -761,14 +734,13 @@
* file to the new end are undefined. The file is truncated if its current
* size is bigger than {@code newLength}. If the current file pointer
* position is in the truncated part, it is set to the end of the file.
- *
+ *
* @param newLength
* the new file length in bytes.
* @throws IllegalArgumentException
* if {@code newLength < 0}.
* @throws IOException
* if this file is closed or another I/O error occurs.
- * @since Android 1.0
*/
public void setLength(long newLength) throws IOException {
openCheck();
@@ -793,13 +765,12 @@
* bytes are skipped if the end of the file is reached or an exception is
* thrown during the operation. Nothing is done if {@code count} is
* negative.
- *
+ *
* @param count
* the number of bytes to skip.
* @return the number of bytes actually skipped.
* @throws IOException
* if this file is closed or another I/O error occurs.
- * @since Android 1.0
*/
public int skipBytes(int count) throws IOException {
if (count > 0) {
@@ -815,7 +786,7 @@
/**
* Writes the entire contents of the byte array {@code buffer} to this file,
* starting at the current file pointer.
- *
+ *
* @param buffer
* the buffer to write.
* @throws IOException
@@ -824,7 +795,6 @@
* @see #read(byte[],int,int)
* @see #readFully(byte[])
* @see #readFully(byte[],int,int)
- * @since Android 1.0
*/
public void write(byte[] buffer) throws IOException {
write(buffer, 0, buffer.length);
@@ -834,7 +804,7 @@
* Writes {@code count} bytes from the byte array {@code buffer} to this
* file, starting at the current file pointer and using {@code offset} as
* the first position within {@code buffer} to get bytes.
- *
+ *
* @param buffer
* the buffer to write to this file.
* @param offset
@@ -848,7 +818,6 @@
* if an I/O error occurs while writing to this file.
* @see #read(byte[], int, int)
* @see #readFully(byte[], int, int)
- * @since Android 1.0
*/
public void write(byte[] buffer, int offset, int count) throws IOException {
// BEGIN android-changed
@@ -883,13 +852,12 @@
/**
* Writes a byte to this file, starting at the current file pointer. Only
* the least significant byte of the integer {@code oneByte} is written.
- *
+ *
* @param oneByte
* the byte to write to this file.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #read()
- * @since Android 1.0
*/
public void write(int oneByte) throws IOException {
openCheck();
@@ -907,13 +875,12 @@
/**
* Writes a boolean to this file, starting at the current file pointer.
- *
+ *
* @param val
* the boolean to write to this file.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #readBoolean()
- * @since Android 1.0
*/
public final void writeBoolean(boolean val) throws IOException {
write(val ? 1 : 0);
@@ -922,14 +889,13 @@
/**
* Writes an 8-bit byte to this file, starting at the current file pointer.
* Only the least significant byte of the integer {@code val} is written.
- *
+ *
* @param val
* the byte to write to this file.
* @throws IOException
* if this file is closed or another I/O error occurs.
* @see #readByte()
* @see #readUnsignedByte()
- * @since Android 1.0
*/
public final void writeByte(int val) throws IOException {
write(val & 0xFF);
@@ -938,7 +904,7 @@
/**
* Writes the low order 8-bit bytes from a string to this file, starting at
* the current file pointer.
- *
+ *
* @param str
* the string containing the bytes to write to this file
* @throws IOException
@@ -947,7 +913,6 @@
* @see #read(byte[],int,int)
* @see #readFully(byte[])
* @see #readFully(byte[],int,int)
- * @since Android 1.0
*/
public final void writeBytes(String str) throws IOException {
byte bytes[] = new byte[str.length()];
@@ -957,18 +922,16 @@
write(bytes);
}
-
/**
* Writes a 16-bit character to this file, starting at the current file
* pointer. Only the two least significant bytes of the integer {@code val}
* are written, with the high byte first.
- *
+ *
* @param val
* the char to write to this file.
* @throws IOException
* if an I/O error occurs while writing to this file.
* @see #readChar()
- * @since Android 1.0
*/
public final void writeChar(int val) throws IOException {
byte[] buffer = new byte[2];
@@ -981,13 +944,12 @@
* Writes the 16-bit characters from a string to this file, starting at the
* current file pointer. Each character is written in the same way as with
* {@link #writeChar(int)}, with its high byte first.
- *
+ *
* @param str
* the string to write to this file.
* @throws IOException
* if an I/O error occurs while writing to this file.
* @see #readChar()
- * @since Android 1.0
*/
public final void writeChars(String str) throws IOException {
byte newBytes[] = new byte[str.length() * 2];
@@ -1003,13 +965,12 @@
* Writes a 64-bit double to this file, starting at the current file
* pointer. The eight bytes returned by
* {@link Double#doubleToLongBits(double)} are written to this file.
- *
+ *
* @param val
* the double to write to this file.
* @throws IOException
* if an I/O error occurs while writing to this file.
* @see #readDouble()
- * @since Android 1.0
*/
public final void writeDouble(double val) throws IOException {
writeLong(Double.doubleToLongBits(val));
@@ -1019,13 +980,12 @@
* Writes a 32-bit float to this file, starting at the current file pointer.
* The four bytes returned by {@link Float#floatToIntBits(float)} are
* written to this file.
- *
+ *
* @param val
* the float to write to this file.
* @throws IOException
* if an I/O error occurs while writing to this file.
* @see #readFloat()
- * @since Android 1.0
*/
public final void writeFloat(float val) throws IOException {
writeInt(Float.floatToIntBits(val));
@@ -1035,13 +995,12 @@
* Writes a 32-bit integer to this file, starting at the current file
* pointer. The four bytes of the integer are written with the highest byte
* first.
- *
+ *
* @param val
* the int to write to this file.
* @throws IOException
* if an I/O error occurs while writing to this file.
* @see #readInt()
- * @since Android 1.0
*/
public final void writeInt(int val) throws IOException {
byte[] buffer = new byte[4];
@@ -1056,13 +1015,12 @@
* Writes a 64-bit long to this file, starting at the current file
* pointer. The eight bytes of the long are written with the highest byte
* first.
- *
+ *
* @param val
* the long to write to this file.
* @throws IOException
* if an I/O error occurs while writing to this file.
* @see #readLong()
- * @since Android 1.0
*/
public final void writeLong(long val) throws IOException {
byte[] buffer = new byte[8];
@@ -1082,13 +1040,13 @@
* Writes a 16-bit short to this file, starting at the current file
* pointer. Only the two least significant bytes of the integer {@code val}
* are written, with the high byte first.
- *
+ *
* @param val
* the short to write to this file.
* @throws IOException
* if an I/O error occurs while writing to this file.
* @see #readShort()
- * @since Android 1.0
+ * @see DataInput#readUnsignedShort()
*/
public final void writeShort(int val) throws IOException {
writeChar(val);
@@ -1097,7 +1055,7 @@
/**
* Writes a string encoded with {@link DataInput modified UTF-8} to this
* file, starting at the current file pointer.
- *
+ *
* @param str
* the string to write in {@link DataInput modified UTF-8}
* format.
@@ -1106,7 +1064,6 @@
* @throws UTFDataFormatException
* if the encoded string is longer than 65535 bytes.
* @see #readUTF()
- * @since Android 1.0
*/
public final void writeUTF(String str) throws IOException {
int utfCount = 0, length = str.length();
diff --git a/luni/src/main/java/java/io/Reader.java b/luni/src/main/java/java/io/Reader.java
index 42fb9ee..1f78f5a 100644
--- a/luni/src/main/java/java/io/Reader.java
+++ b/luni/src/main/java/java/io/Reader.java
@@ -33,24 +33,18 @@
* <p>
* Many specialized readers for purposes like reading from a file already exist
* in this package.
- *
+ *
* @see Writer
- *
- * @since Android 1.0
*/
public abstract class Reader implements Readable, Closeable {
/**
* The object used to synchronize access to the reader.
- *
- * @since Android 1.0
*/
protected Object lock;
/**
* Constructs a new {@code Reader} with {@code this} as the object used to
* synchronize critical sections.
- *
- * @since Android 1.0
*/
protected Reader() {
super();
@@ -60,12 +54,11 @@
/**
* Constructs a new {@code Reader} with {@code lock} used to synchronize
* critical sections.
- *
+ *
* @param lock
* the {@code Object} used to synchronize critical sections.
* @throws NullPointerException
* if {@code lock} is {@code null}.
- * @since Android 1.0
*/
protected Reader(Object lock) {
if (lock == null) {
@@ -77,10 +70,9 @@
/**
* Closes this reader. Implementations of this method should free any
* resources associated with the reader.
- *
+ *
* @throws IOException
* if an error occurs while closing this reader.
- * @since Android 1.0
*/
public abstract void close() throws IOException;
@@ -92,8 +84,7 @@
* <p>
* This default implementation simply throws an {@code IOException};
* subclasses must provide their own implementation.
- * </p>
- *
+ *
* @param readLimit
* the number of characters that can be read before the mark is
* invalidated.
@@ -103,7 +94,6 @@
* if an error occurs while setting a mark in this reader.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
public void mark(int readLimit) throws IOException {
throw new IOException();
@@ -113,9 +103,8 @@
* Indicates whether this reader supports the {@code mark()} and
* {@code reset()} methods. This default implementation returns
* {@code false}.
- *
+ *
* @return always {@code false}.
- * @since Android 1.0
*/
public boolean markSupported() {
return false;
@@ -125,12 +114,11 @@
* Reads a single character from this reader and returns it as an integer
* with the two higher-order bytes set to 0. Returns -1 if the end of the
* reader has been reached.
- *
+ *
* @return the character read or -1 if the end of the reader has been
* reached.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
public int read() throws IOException {
synchronized (lock) {
@@ -146,14 +134,13 @@
* Reads characters from this reader and stores them in the character array
* {@code buf} starting at offset 0. Returns the number of characters
* actually read or -1 if the end of the reader has been reached.
- *
+ *
* @param buf
* character array to store the characters read.
* @return the number of characters read or -1 if the end of the reader has
* been reached.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
public int read(char[] buf) throws IOException {
// BEGIN android-note
@@ -167,7 +154,7 @@
* at {@code offset} in the character array {@code buf}. Returns the number
* of characters actually read or -1 if the end of the reader has been
* reached.
- *
+ *
* @param buf
* the character array to store the characters read.
* @param offset
@@ -179,7 +166,6 @@
* been reached.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
- * @since Android 1.0
*/
public abstract int read(char[] buf, int offset, int count)
throws IOException;
@@ -192,14 +178,13 @@
* Returns {@code true} if this reader will not block when {@code read} is
* called, {@code false} if unknown or blocking will occur. This default
* implementation always returns {@code false}.
- *
+ *
* @return always {@code false}.
* @throws IOException
* if this reader is closed or some other I/O error occurs.
* @see #read()
* @see #read(char[])
* @see #read(char[], int, int)
- * @since Android 1.0
*/
public boolean ready() throws IOException {
return false;
@@ -211,12 +196,11 @@
* location. If this reader has not been marked, the behavior of
* {@code reset()} is implementation specific. This default
* implementation throws an {@code IOException}.
- *
+ *
* @throws IOException
* always thrown in this default implementation.
* @see #mark(int)
* @see #markSupported()
- * @since Android 1.0
*/
public void reset() throws IOException {
throw new IOException();
@@ -227,7 +211,7 @@
* {@code read} methods will not return these characters unless {@code
* reset()} is used. This method may perform multiple reads to read {@code
* count} characters.
- *
+ *
* @param count
* the maximum number of characters to skip.
* @return the number of characters actually skipped.
@@ -238,7 +222,6 @@
* @see #mark(int)
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
public long skip(long count) throws IOException {
if (count < 0) {
@@ -267,7 +250,7 @@
/**
* Reads characters and puts them into the {@code target} character buffer.
- *
+ *
* @param target
* the destination character buffer.
* @return the number of characters put into {@code target} or -1 if the end
@@ -278,7 +261,6 @@
* if {@code target} is {@code null}.
* @throws ReadOnlyBufferException
* if {@code target} is read-only.
- * @since Android 1.0
*/
public int read(CharBuffer target) throws IOException {
if (null == target) {
diff --git a/luni/src/main/java/java/io/SequenceInputStream.java b/luni/src/main/java/java/io/SequenceInputStream.java
index 1b946b5..3719021 100644
--- a/luni/src/main/java/java/io/SequenceInputStream.java
+++ b/luni/src/main/java/java/io/SequenceInputStream.java
@@ -28,8 +28,6 @@
* Concatenates two or more existing {@link InputStream}s. Reads are taken from
* the first stream until it ends, then the next stream is used, until the last
* stream returns end of file.
- *
- * @since Android 1.0
*/
public class SequenceInputStream extends InputStream {
/**
@@ -45,14 +43,13 @@
/**
* Constructs a new {@code SequenceInputStream} using the two streams
* {@code s1} and {@code s2} as the sequence of streams to read from.
- *
+ *
* @param s1
* the first stream to get bytes from.
* @param s2
* the second stream to get bytes from.
* @throws NullPointerException
* if {@code s1} is {@code null}.
- * @since Android 1.0
*/
public SequenceInputStream(InputStream s1, InputStream s2) {
if (s1 == null) {
@@ -68,12 +65,11 @@
* Constructs a new SequenceInputStream using the elements returned from
* Enumeration {@code e} as the stream sequence. The instances returned by
* {@code e.nextElement()} must be of type {@link InputStream}.
- *
+ *
* @param e
* the enumeration of {@code InputStreams} to get bytes from.
* @throws NullPointerException
* if any of the elements in {@code e} is {@code null}.
- * @since Android 1.0
*/
public SequenceInputStream(Enumeration<? extends InputStream> e) {
this.e = e;
@@ -87,12 +83,11 @@
/**
* Returns the number of bytes that are available before the current input stream will
- * block.
- *
+ * block.
+ *
* @return the number of bytes available in the current input stream before blocking.
* @throws IOException
* if an I/O error occurs in the current input stream.
- * @since Android 1.0
*/
@Override
public int available() throws IOException {
@@ -103,11 +98,10 @@
}
/**
- * Closes all streams in this sequence of input stream.
- *
+ * Closes all streams in this sequence of input stream.
+ *
* @throws IOException
* if an error occurs while closing any of the input streams.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -119,7 +113,7 @@
/**
* Sets up the next InputStream or leaves it alone if there are none left.
- *
+ *
* @throws IOException
*/
private void nextStream() throws IOException {
@@ -142,14 +136,13 @@
* stream first; if the end of this stream has been reached, it reads from
* the next one. Blocks until one byte has been read, the end of the last
* input stream in the sequence has been reached, or an exception is thrown.
- *
+ *
* @return the byte read or -1 if either the end of the last stream in the
* sequence has been reached or this input stream sequence is
* closed.
* @throws IOException
* if an error occurs while reading the current source input
* stream.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -179,7 +172,7 @@
* If a substream has already reached the end when this call is made, it
* will close that substream and start with the next one. If there are no
* more substreams it will return -1.
- *
+ *
* @param buffer
* the array in which to store the bytes read.
* @param offset
@@ -197,7 +190,6 @@
* if an I/O error occurs.
* @throws NullPointerException
* if {@code buffer} is {@code null}.
- * @since Android 1.0
*/
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
diff --git a/luni/src/main/java/java/io/Serializable.java b/luni/src/main/java/java/io/Serializable.java
index 17690e3..9cd7816 100644
--- a/luni/src/main/java/java/io/Serializable.java
+++ b/luni/src/main/java/java/io/Serializable.java
@@ -28,13 +28,9 @@
* <p>
* {@code private void writeObject(java.io.ObjectOutputStream out) throws
* IOException}
- * </p>
* <p>
* {@code private void readObject(java.io.ObjectInputStream in) throws
* IOException, ClassNotFoundException}
- * </p>
- *
- * @since Android 1.0
*/
public interface Serializable {
/* empty */
diff --git a/luni/src/main/java/java/io/StreamCorruptedException.java b/luni/src/main/java/java/io/StreamCorruptedException.java
index 1181507..9d25727 100644
--- a/luni/src/main/java/java/io/StreamCorruptedException.java
+++ b/luni/src/main/java/java/io/StreamCorruptedException.java
@@ -25,8 +25,6 @@
*
* @see ObjectInputStream
* @see OptionalDataException
- *
- * @since Android 1.0
*/
public class StreamCorruptedException extends ObjectStreamException {
@@ -35,8 +33,6 @@
/**
* Constructs a new {@code StreamCorruptedException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
public StreamCorruptedException() {
super();
@@ -48,7 +44,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public StreamCorruptedException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/StreamTokenizer.java b/luni/src/main/java/java/io/StreamTokenizer.java
index 391fca8..d39e5a8 100644
--- a/luni/src/main/java/java/io/StreamTokenizer.java
+++ b/luni/src/main/java/java/io/StreamTokenizer.java
@@ -23,51 +23,37 @@
* and different comment styles. The class can be used for limited processing
* of source code of programming languages like Java, although it is nowhere
* near a full parser.
- *
- * @since Android 1.0
*/
public class StreamTokenizer {
/**
* Contains a number if the current token is a number ({@code ttype} ==
* {@code TT_NUMBER}).
- *
- * @since Android 1.0
*/
public double nval;
/**
* Contains a string if the current token is a word ({@code ttype} ==
* {@code TT_WORD}).
- *
- * @since Android 1.0
*/
public String sval;
/**
* The constant representing the end of the stream.
- *
- * @since Android 1.0
*/
public static final int TT_EOF = -1;
/**
* The constant representing the end of the line.
- *
- * @since Android 1.0
*/
public static final int TT_EOL = '\n';
/**
* The constant representing a number token.
- *
- * @since Android 1.0
*/
public static final int TT_NUMBER = -2;
/**
* The constant representing a word token.
- *
- * @since Android 1.0
*/
public static final int TT_WORD = -3;
@@ -89,8 +75,6 @@
* whether {@code eolIsSignificant} is {@code true}.</li>
* <li> {@code TT_EOF} - the end of the stream has been reached.</li>
* </ul>
- *
- * @since Android 1.0
*/
public int ttype = TT_UNKNOWN;
@@ -135,7 +119,7 @@
* specification.
*/
private StreamTokenizer() {
- /**
+ /*
* Initialize the default state per specification. All byte values 'A'
* through 'Z', 'a' through 'z', and '\u00A0' through '\u00FF' are
* considered to be alphabetic.
@@ -176,7 +160,6 @@
* @throws NullPointerException
* if {@code is} is {@code null}.
* @deprecated Use {@link #StreamTokenizer(Reader)}
- * @since Android 1.0
*/
@Deprecated
public StreamTokenizer(InputStream is) {
@@ -205,7 +188,6 @@
*
* @param r
* the source reader from which to parse tokens.
- * @since Android 1.0
*/
public StreamTokenizer(Reader r) {
this();
@@ -221,7 +203,6 @@
*
* @param ch
* the character to be considered a comment character.
- * @since Android 1.0
*/
public void commentChar(int ch) {
if (0 <= ch && ch < tokenTypes.length) {
@@ -235,7 +216,6 @@
*
* @param flag
* {@code true} if EOL is significant, {@code false} otherwise.
- * @since Android 1.0
*/
public void eolIsSignificant(boolean flag) {
isEOLSignificant = flag;
@@ -245,7 +225,6 @@
* Returns the current line number.
*
* @return this tokenizer's current line number.
- * @since Android 1.0
*/
public int lineno() {
return lineNumber;
@@ -258,7 +237,6 @@
* @param flag
* {@code true} if {@code sval} should be converted to lower
* case, {@code false} otherwise.
- * @since Android 1.0
*/
public void lowerCaseMode(boolean flag) {
forceLowercase = flag;
@@ -272,7 +250,6 @@
* @return the value of {@code ttype}.
* @throws IOException
* if an I/O error occurs while parsing the next token.
- * @since Android 1.0
*/
public int nextToken() throws IOException {
if (pushBackToken) {
@@ -507,7 +484,6 @@
*
* @param ch
* the character to be considered an ordinary character.
- * @since Android 1.0
*/
public void ordinaryChar(int ch) {
if (0 <= ch && ch < tokenTypes.length) {
@@ -525,7 +501,6 @@
* the first character in the range of ordinary characters.
* @param hi
* the last character in the range of ordinary characters.
- * @since Android 1.0
*/
public void ordinaryChars(int low, int hi) {
if (low < 0) {
@@ -541,8 +516,6 @@
/**
* Specifies that this tokenizer shall parse numbers.
- *
- * @since Android 1.0
*/
public void parseNumbers() {
for (int i = '0'; i <= '9'; i++) {
@@ -555,8 +528,6 @@
/**
* Indicates that the current token should be pushed back and returned again
* the next time {@code nextToken()} is called.
- *
- * @since Android 1.0
*/
public void pushBack() {
pushBackToken = true;
@@ -568,7 +539,6 @@
*
* @param ch
* the character to be considered a quote character.
- * @since Android 1.0
*/
public void quoteChar(int ch) {
if (0 <= ch && ch < tokenTypes.length) {
@@ -586,8 +556,6 @@
/**
* Specifies that all characters shall be treated as ordinary characters.
- *
- * @since Android 1.0
*/
public void resetSyntax() {
for (int i = 0; i < 256; i++) {
@@ -602,7 +570,6 @@
* @param flag
* {@code true} if {@code //} should be recognized as the start
* of a comment, {@code false} otherwise.
- * @since Android 1.0
*/
public void slashSlashComments(boolean flag) {
slashSlashComments = flag;
@@ -616,7 +583,6 @@
* @param flag
* {@code true} if {@code /*} should be recognized as the start
* of a comment, {@code false} otherwise.
- * @since Android 1.0
*/
public void slashStarComments(boolean flag) {
slashStarComments = flag;
@@ -626,7 +592,6 @@
* Returns the state of this tokenizer in a readable format.
*
* @return the current state of this tokenizer.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -648,8 +613,6 @@
result.append(sval);
break;
default:
- // BEGIN android-changed
- // copied from a newer version of harmony
if (ttype == TT_UNKNOWN || tokenTypes[ttype] == TOKEN_QUOTE) {
result.append(sval);
} else {
@@ -657,7 +620,6 @@
result.append((char) ttype);
result.append('\'');
}
- // END android-changed
}
result.append("], line "); //$NON-NLS-1$
result.append(lineNumber);
@@ -672,7 +634,6 @@
* the first character in the range of whitespace characters.
* @param hi
* the last character in the range of whitespace characters.
- * @since Android 1.0
*/
public void whitespaceChars(int low, int hi) {
if (low < 0) {
@@ -695,7 +656,6 @@
* the first character in the range of word characters.
* @param hi
* the last character in the range of word characters.
- * @since Android 1.0
*/
public void wordChars(int low, int hi) {
if (low < 0) {
diff --git a/luni/src/main/java/java/io/StringBufferInputStream.java b/luni/src/main/java/java/io/StringBufferInputStream.java
index 6e20ab6..cc4ab81 100644
--- a/luni/src/main/java/java/io/StringBufferInputStream.java
+++ b/luni/src/main/java/java/io/StringBufferInputStream.java
@@ -22,31 +22,23 @@
/**
* A specialized {@link InputStream} that reads bytes from a {@code String} in
* a sequential manner.
- *
+ *
* @deprecated Use {@link StringReader}
- *
- * @since Android 1.0
*/
@Deprecated
public class StringBufferInputStream extends InputStream {
/**
* The source string containing the data to read.
- *
- * @since Android 1.0
*/
protected String buffer;
/**
* The total number of characters in the source string.
- *
- * @since Android 1.0
*/
protected int count;
/**
* The current position within the source string.
- *
- * @since Android 1.0
*/
protected int pos;
@@ -54,12 +46,11 @@
* Construct a new {@code StringBufferInputStream} with {@code str} as
* source. The size of the stream is set to the {@code length()} of the
* string.
- *
+ *
* @param str
* the source string for this stream.
* @throws NullPointerException
* if {@code str} is {@code null}.
- * @since Android 1.0
*/
public StringBufferInputStream(String str) {
if (str == null) {
@@ -72,9 +63,8 @@
/**
* Returns the number of bytes that are available before this stream will
* block.
- *
+ *
* @return the number of bytes available before blocking.
- * @since Android 1.0
*/
@Override
public synchronized int available() {
@@ -85,10 +75,9 @@
* Reads a single byte from the source string and returns it as an integer
* in the range from 0 to 255. Returns -1 if the end of the source string
* has been reached.
- *
+ *
* @return the byte read or -1 if the end of the source string has been
* reached.
- * @since Android 1.0
*/
@Override
public synchronized int read() {
@@ -98,7 +87,7 @@
/**
* Reads at most {@code length} bytes from the source string and stores them
* in the byte array {@code b} starting at {@code offset}.
- *
+ *
* @param b
* the byte array in which to store the bytes read.
* @param offset
@@ -114,7 +103,6 @@
* {@code b}.
* @throws NullPointerException
* if {@code b} is {@code null}.
- * @since Android 1.0
*/
@Override
public synchronized int read(byte[] b, int offset, int length) {
@@ -153,8 +141,6 @@
/**
* Resets this stream to the beginning of the source string.
- *
- * @since Android 1.0
*/
@Override
public synchronized void reset() {
@@ -166,11 +152,10 @@
* returns 0 if {@code n} is negative. Less than {@code n} characters are
* skipped if the end of the source string is reached before the operation
* completes.
- *
+ *
* @param n
* the number of characters to skip.
* @return the number of characters actually skipped.
- * @since Android 1.0
*/
@Override
public synchronized long skip(long n) {
diff --git a/luni/src/main/java/java/io/StringReader.java b/luni/src/main/java/java/io/StringReader.java
index 3a19429..0a9e9bb 100644
--- a/luni/src/main/java/java/io/StringReader.java
+++ b/luni/src/main/java/java/io/StringReader.java
@@ -22,10 +22,8 @@
/**
* A specialized {@link Reader} that reads characters from a {@code String} in
* a sequential manner.
- *
+ *
* @see StringWriter
- *
- * @since Android 1.0
*/
public class StringReader extends Reader {
private String str;
@@ -40,13 +38,12 @@
* Construct a new {@code StringReader} with {@code str} as source. The size
* of the reader is set to the {@code length()} of the string and the Object
* to synchronize access through is set to {@code str}.
- *
+ *
* @param str
* the source string for this reader.
- * @since Android 1.0
*/
public StringReader(String str) {
- super(str);
+ super();
this.str = str;
this.count = str.length();
}
@@ -55,22 +52,15 @@
* Closes this reader. Once it is closed, read operations on this reader
* will throw an {@code IOException}. Only the first invocation of this
* method has any effect.
- *
- * @since Android 1.0
*/
@Override
public void close() {
- synchronized (lock) {
- if (isClosed()) {
- return;
- }
- str = null;
- }
+ str = null;
}
/**
* Returns a boolean indicating whether this reader is closed.
- *
+ *
* @return {@code true} if closed, otherwise {@code false}.
*/
private boolean isClosed() {
@@ -81,7 +71,7 @@
* Sets a mark position in this reader. The parameter {@code readLimit} is
* ignored for this class. Calling {@code reset()} will reposition the
* reader back to the marked position.
- *
+ *
* @param readLimit
* ignored for {@code StringReader} instances.
* @throws IllegalArgumentException
@@ -90,7 +80,6 @@
* if this reader is closed.
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public void mark(int readLimit) throws IOException {
@@ -109,9 +98,8 @@
/**
* Indicates whether this reader supports the {@code mark()} and {@code
* reset()} methods. This implementation returns {@code true}.
- *
+ *
* @return always {@code true}.
- * @since Android 1.0
*/
@Override
public boolean markSupported() {
@@ -122,12 +110,11 @@
* Reads a single character from the source string and returns it as an
* integer with the two higher-order bytes set to 0. Returns -1 if the end
* of the source string has been reached.
- *
+ *
* @return the character read or -1 if the end of the source string has been
* reached.
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public int read() throws IOException {
@@ -147,7 +134,7 @@
* them at {@code offset} in the character array {@code buf}. Returns the
* number of characters actually read or -1 if the end of the source string
* has been reached.
- *
+ *
* @param buf
* the character array to store the characters read.
* @param offset
@@ -162,14 +149,12 @@
* {@code offset + len} is greater than the size of {@code buf}.
* @throws IOException
* if this reader is closed.
- * @since Android 1.0
*/
@Override
public int read(char[] buf, int offset, int len) throws IOException {
// BEGIN android-note
// changed array notation to be consistent with the rest of harmony
// END android-note
- // avoid int overflow
// BEGIN android-changed
// Exception priorities (in case of multiple errors) differ from
// RI, but are spec-compliant.
@@ -178,14 +163,18 @@
if (buf == null) {
throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
}
- if ((offset | len) < 0 || len > buf.length - offset) {
- throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
- }
- // END android-changed
synchronized (lock) {
+ // avoid int overflow
+ if ((offset | len) < 0 || len > buf.length - offset) {
+ throw new ArrayIndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
+ }
+ // END android-changed
if (isClosed()) {
throw new IOException(Msg.getString("K0083")); //$NON-NLS-1$
}
+ if (len == 0) {
+ return 0;
+ }
if (pos == this.count) {
return -1;
}
@@ -200,13 +189,12 @@
/**
* Indicates whether this reader is ready to be read without blocking. This
* implementation always returns {@code true}.
- *
+ *
* @return always {@code true}.
* @throws IOException
* if this reader is closed.
* @see #read()
* @see #read(char[], int, int)
- * @since Android 1.0
*/
@Override
public boolean ready() throws IOException {
@@ -223,12 +211,11 @@
* Invocations of {@code read()} and {@code skip()} will occur from this new
* location. If this reader has not been marked, it is reset to the
* beginning of the source string.
- *
+ *
* @throws IOException
* if this reader is closed.
* @see #mark(int)
* @see #markSupported()
- * @since Android 1.0
*/
@Override
public void reset() throws IOException {
@@ -244,7 +231,7 @@
* Skips {@code amount} characters in the source string. Subsequent calls of
* {@code read} methods will not return these characters unless {@code
* reset()} is used.
- *
+ *
* @param ns
* the maximum number of characters to skip.
* @return the number of characters actually skipped or 0 if {@code ns < 0}.
@@ -253,7 +240,6 @@
* @see #mark(int)
* @see #markSupported()
* @see #reset()
- * @since Android 1.0
*/
@Override
public long skip(long ns) throws IOException {
diff --git a/luni/src/main/java/java/io/StringWriter.java b/luni/src/main/java/java/io/StringWriter.java
index 01a6db8..45f6c16 100644
--- a/luni/src/main/java/java/io/StringWriter.java
+++ b/luni/src/main/java/java/io/StringWriter.java
@@ -26,10 +26,8 @@
* in a sequential manner, appending them in the process. The result can later
* be queried using the {@link #StringWriter(int)} or {@link #toString()}
* methods.
- *
+ *
* @see StringReader
- *
- * @since Android 1.0
*/
public class StringWriter extends Writer {
@@ -40,8 +38,6 @@
* allocated with the default size of 16 characters. The {@code
* StringBuffer} is also the {@code lock} used to synchronize access to this
* writer.
- *
- * @since Android 1.0
*/
public StringWriter() {
super();
@@ -54,10 +50,9 @@
* allocated with a size of {@code initialSize} characters. The {@code
* StringBuffer} is also the {@code lock} used to synchronize access to this
* writer.
- *
+ *
* @param initialSize
* the intial size of the target string buffer.
- * @since Android 1.0
*/
public StringWriter(int initialSize) {
if (initialSize < 0) {
@@ -71,10 +66,9 @@
* Calling this method has no effect. In contrast to most {@code Writer} subclasses,
* the other methods in {@code StringWriter} do not throw an {@code IOException} if
* {@code close()} has been called.
- *
+ *
* @throws IOException
* if an error occurs while closing this writer.
- * @since Android 1.0
*/
@Override
public void close() throws IOException {
@@ -83,8 +77,6 @@
/**
* Calling this method has no effect.
- *
- * @since Android 1.0
*/
@Override
public void flush() {
@@ -94,33 +86,27 @@
/**
* Gets a reference to this writer's internal {@link StringBuffer}. Any
* changes made to the returned buffer are reflected in this writer.
- *
+ *
* @return a reference to this writer's internal {@code StringBuffer}.
- * @since Android 1.0
*/
public StringBuffer getBuffer() {
- synchronized (lock) {
- return buf;
- }
+ return buf;
}
/**
* Gets a copy of the contents of this writer as a string.
- *
+ *
* @return this writer's contents as a string.
- * @since Android 1.0
*/
@Override
public String toString() {
- synchronized (lock) {
- return buf.toString();
- }
+ return buf.toString();
}
/**
* Writes {@code count} characters starting at {@code offset} in {@code buf}
* to this writer's {@code StringBuffer}.
- *
+ *
* @param cbuf
* the non-null character array to write.
* @param offset
@@ -130,7 +116,6 @@
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is greater than the size of {@code buf}.
- * @since Android 1.0
*/
@Override
public void write(char[] cbuf, int offset, int count) {
@@ -147,45 +132,40 @@
throw new IndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
}
// END android-changed
- synchronized (lock) {
- this.buf.append(cbuf, offset, count);
+ if (count == 0) {
+ return;
}
+ buf.append(cbuf, offset, count);
}
/**
* Writes one character to this writer's {@code StringBuffer}. Only the two
* least significant bytes of the integer {@code oneChar} are written.
- *
+ *
* @param oneChar
* the character to write to this writer's {@code StringBuffer}.
- * @since Android 1.0
*/
@Override
public void write(int oneChar) {
- synchronized (lock) {
- buf.append((char) oneChar);
- }
+ buf.append((char) oneChar);
}
/**
* Writes the characters from the specified string to this writer's {@code
* StringBuffer}.
- *
+ *
* @param str
* the non-null string containing the characters to write.
- * @since Android 1.0
*/
@Override
public void write(String str) {
- synchronized (lock) {
- buf.append(str);
- }
+ buf.append(str);
}
/**
* Writes {@code count} characters from {@code str} starting at {@code
* offset} to this writer's {@code StringBuffer}.
- *
+ *
* @param str
* the non-null string containing the characters to write.
* @param offset
@@ -195,24 +175,20 @@
* @throws StringIndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is greater than the length of {@code str}.
- * @since Android 1.0
*/
@Override
public void write(String str, int offset, int count) {
String sub = str.substring(offset, offset + count);
- synchronized (lock) {
- buf.append(sub);
- }
+ buf.append(sub);
}
/**
* Appends the character {@code c} to this writer's {@code StringBuffer}.
* This method works the same way as {@link #write(int)}.
- *
+ *
* @param c
* the character to append to the target stream.
* @return this writer.
- * @since Android 1.0
*/
@Override
public StringWriter append(char c) {
@@ -225,18 +201,17 @@
* StringBuffer}. This method works the same way as {@code
* StringWriter.write(csq.toString())}. If {@code csq} is {@code null}, then
* the string "null" is written to the target stream.
- *
+ *
* @param csq
* the character sequence appended to the target.
* @return this writer.
- * @since Android 1.0
*/
@Override
public StringWriter append(CharSequence csq) {
if (null == csq) {
- append(TOKEN_NULL, 0, TOKEN_NULL.length());
+ write(TOKEN_NULL);
} else {
- append(csq, 0, csq.length());
+ write(csq.toString());
}
return this;
}
@@ -247,7 +222,7 @@
* StringWriter.writer(csq.subsequence(start, end).toString())}. If {@code
* csq} is {@code null}, then the specified subsequence of the string "null"
* will be written to the target.
- *
+ *
* @param csq
* the character sequence appended to the target.
* @param start
@@ -261,7 +236,6 @@
* if {@code start > end}, {@code start < 0}, {@code end < 0} or
* either {@code start} or {@code end} are greater or equal than
* the length of {@code csq}.
- * @since Android 1.0
*/
@Override
public StringWriter append(CharSequence csq, int start, int end) {
diff --git a/luni/src/main/java/java/io/SyncFailedException.java b/luni/src/main/java/java/io/SyncFailedException.java
index 2f8d9c7..c4f7340 100644
--- a/luni/src/main/java/java/io/SyncFailedException.java
+++ b/luni/src/main/java/java/io/SyncFailedException.java
@@ -20,8 +20,6 @@
/**
* Signals that the {@link FileDescriptor#sync()} method has failed to
* complete.
- *
- * @since Android 1.0
*/
public class SyncFailedException extends IOException {
@@ -33,7 +31,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public SyncFailedException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/UTFDataFormatException.java b/luni/src/main/java/java/io/UTFDataFormatException.java
index 20a7abe..215e3e2 100644
--- a/luni/src/main/java/java/io/UTFDataFormatException.java
+++ b/luni/src/main/java/java/io/UTFDataFormatException.java
@@ -22,9 +22,7 @@
* likely while reading some {@link DataInputStream}.
*
* @see DataInputStream#readUTF()
- *
- * @since Android 1.0
-*/
+ */
public class UTFDataFormatException extends IOException {
private static final long serialVersionUID = 420743449228280612L;
@@ -32,8 +30,6 @@
/**
* Constructs a new {@code UTFDataFormatException} with its stack trace
* filled in.
- *
- * @since Android 1.0
*/
public UTFDataFormatException() {
super();
@@ -45,7 +41,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UTFDataFormatException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/UnsupportedEncodingException.java b/luni/src/main/java/java/io/UnsupportedEncodingException.java
index deeab29..eca6c81 100644
--- a/luni/src/main/java/java/io/UnsupportedEncodingException.java
+++ b/luni/src/main/java/java/io/UnsupportedEncodingException.java
@@ -18,11 +18,8 @@
package java.io;
/**
- * Signals that a requested character encoding is not available, either because
- * it is not included a specific Android system, or because the encoding name
- * is simply incorrect.
- *
- * @since Android 1.0
+ * Thrown when a program asks for a particular character converter that is
+ * unavailable.
*/
public class UnsupportedEncodingException extends IOException {
@@ -31,8 +28,6 @@
/**
* Constructs a new {@code UnsupportedEncodingException} with its stack
* trace filled in.
- *
- * @since Android 1.0
*/
public UnsupportedEncodingException() {
super();
@@ -44,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UnsupportedEncodingException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/io/WriteAbortedException.java b/luni/src/main/java/java/io/WriteAbortedException.java
index 02c2f70..11ee1fe 100644
--- a/luni/src/main/java/java/io/WriteAbortedException.java
+++ b/luni/src/main/java/java/io/WriteAbortedException.java
@@ -26,8 +26,6 @@
* object.
*
* @see ObjectInputStream#readObject()
- *
- * @since Android 1.0
*/
public class WriteAbortedException extends ObjectStreamException {
@@ -36,8 +34,6 @@
/**
* The exception that occured when writeObject() was attempting to serialize
* the object.
- *
- * @since Android 1.0
*/
public Exception detail;
@@ -50,7 +46,6 @@
* the detail message for this exception.
* @param rootCause
* the exception that was thrown when serializing the object.
- * @since Android 1.0
*/
public WriteAbortedException(String detailMessage, Exception rootCause) {
super(detailMessage);
@@ -64,7 +59,6 @@
* time.
*
* @return the exception message.
- * @since Android 1.0
*/
@Override
public String getMessage() {
@@ -79,7 +73,6 @@
* Gets the cause of this exception or {@code null} if there is no cause.
*
* @return the exception cause.
- * @since Android 1.0
*/
@Override
public Throwable getCause() {
diff --git a/luni/src/main/java/java/io/Writer.java b/luni/src/main/java/java/io/Writer.java
index 5505e80..dfb37c5 100644
--- a/luni/src/main/java/java/io/Writer.java
+++ b/luni/src/main/java/java/io/Writer.java
@@ -31,10 +31,8 @@
* <p>
* Many specialized readers for purposes like reading from a file already exist
* in this package.
- *
+ *
* @see Reader
- *
- * @since Android 1.0
*/
public abstract class Writer implements Appendable, Closeable, Flushable {
@@ -42,16 +40,12 @@
/**
* The object used to synchronize access to the writer.
- *
- * @since Android 1.0
*/
protected Object lock;
/**
* Constructs a new {@code Writer} with {@code this} as the object used to
* synchronize critical sections.
- *
- * @since Android 1.0
*/
protected Writer() {
super();
@@ -61,12 +55,11 @@
/**
* Constructs a new {@code Writer} with {@code lock} used to synchronize
* critical sections.
- *
+ *
* @param lock
* the {@code Object} used to synchronize critical sections.
* @throws NullPointerException
* if {@code lock} is {@code null}.
- * @since Android 1.0
*/
protected Writer(Object lock) {
if (lock == null) {
@@ -78,31 +71,28 @@
/**
* Closes this writer. Implementations of this method should free any
* resources associated with the writer.
- *
+ *
* @throws IOException
* if an error occurs while closing this writer.
- * @since Android 1.0
*/
public abstract void close() throws IOException;
/**
* Flushes this writer. Implementations of this method should ensure that
* all buffered characters are written to the target.
- *
+ *
* @throws IOException
* if an error occurs while flushing this writer.
- * @since Android 1.0
*/
public abstract void flush() throws IOException;
/**
* Writes the entire character buffer {@code buf} to the target.
- *
+ *
* @param buf
* the non-null array containing characters to write.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
public void write(char[] buf) throws IOException {
// BEGIN android-note
@@ -114,7 +104,7 @@
/**
* Writes {@code count} characters starting at {@code offset} in {@code buf}
* to the target.
- *
+ *
* @param buf
* the non-null character array to write.
* @param offset
@@ -126,7 +116,6 @@
* offset + count} is greater than the size of {@code buf}.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
public abstract void write(char[] buf, int offset, int count)
throws IOException;
@@ -137,12 +126,11 @@
/**
* Writes one character to the target. Only the two least significant bytes
* of the integer {@code oneChar} are written.
- *
+ *
* @param oneChar
* the character to write to the target.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
public void write(int oneChar) throws IOException {
synchronized (lock) {
@@ -154,12 +142,11 @@
/**
* Writes the characters from the specified string to the target.
- *
+ *
* @param str
* the non-null string containing the characters to write.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
public void write(String str) throws IOException {
char buf[] = new char[str.length()];
@@ -172,7 +159,7 @@
/**
* Writes {@code count} characters from {@code str} starting at {@code
* offset} to the target.
- *
+ *
* @param str
* the non-null string containing the characters to write.
* @param offset
@@ -184,7 +171,6 @@
* @throws IndexOutOfBoundsException
* if {@code offset < 0} or {@code count < 0}, or if {@code
* offset + count} is greater than the length of {@code str}.
- * @since Android 1.0
*/
public void write(String str, int offset, int count) throws IOException {
if (count < 0) { // other cases tested by getChars()
@@ -201,13 +187,12 @@
/**
* Appends the character {@code c} to the target. This method works the same
* way as {@link #write(int)}.
- *
+ *
* @param c
* the character to append to the target stream.
* @return this writer.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
public Writer append(char c) throws IOException {
write(c);
@@ -219,13 +204,12 @@
* works the same way as {@code Writer.write(csq.toString())}. If {@code
* csq} is {@code null}, then the string "null" is written to the target
* stream.
- *
+ *
* @param csq
* the character sequence appended to the target.
* @return this writer.
* @throws IOException
* if this writer is closed or another I/O error occurs.
- * @since Android 1.0
*/
public Writer append(CharSequence csq) throws IOException {
if (null == csq) {
@@ -242,7 +226,7 @@
* Writer.writer(csq.subsequence(start, end).toString())}. If {@code
* csq} is {@code null}, then the specified subsequence of the string "null"
* will be written to the target.
- *
+ *
* @param csq
* the character sequence appended to the target.
* @param start
@@ -258,7 +242,6 @@
* if {@code start > end}, {@code start < 0}, {@code end < 0} or
* either {@code start} or {@code end} are greater or equal than
* the length of {@code csq}.
- * @since Android 1.0
*/
public Writer append(CharSequence csq, int start, int end)
throws IOException {
diff --git a/luni/src/main/java/java/lang/AbstractMethodError.java b/luni/src/main/java/java/lang/AbstractMethodError.java
index cdfa0ec..4d5238a 100644
--- a/luni/src/main/java/java/lang/AbstractMethodError.java
+++ b/luni/src/main/java/java/lang/AbstractMethodError.java
@@ -22,8 +22,6 @@
* <p>
* Note that this can only occur when inconsistent class files have been loaded,
* since invoking an abstract method is a compile time error.
- * </p>
- * @since Android 1.0
*/
public class AbstractMethodError extends IncompatibleClassChangeError {
@@ -32,8 +30,6 @@
/**
* Constructs a new {@code AbstractMethodError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public AbstractMethodError() {
super();
@@ -42,10 +38,9 @@
/**
* Constructs a new {@code AbstractMethodError} with the current stack trace
* and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public AbstractMethodError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/AbstractStringBuilder.java b/luni/src/main/java/java/lang/AbstractStringBuilder.java
index 39459a0..06f8c50 100644
--- a/luni/src/main/java/java/lang/AbstractStringBuilder.java
+++ b/luni/src/main/java/java/lang/AbstractStringBuilder.java
@@ -23,15 +23,13 @@
import org.apache.harmony.luni.util.Msg;
/**
- * <p>
* A modifiable {@link CharSequence sequence of characters} for use in creating
* and modifying Strings. This class is intended as a base class for
* {@link StringBuffer} and {@link StringBuilder}.
- * </p>
*
* @see StringBuffer
* @see StringBuilder
- * @since Android 1.0
+ * @since 1.5
*/
abstract class AbstractStringBuilder {
@@ -95,8 +93,8 @@
}
private void enlargeBuffer(int min) {
- int twice = (value.length << 1) + 2;
- char[] newData = new char[min > twice ? min : twice];
+ int newSize = ((value.length >> 1) + value.length) + 2;
+ char[] newData = new char[min > newSize ? min : newSize];
System.arraycopy(value, 0, newData, 0, count);
value = newData;
shared = false;
@@ -106,9 +104,6 @@
int newSize = count + 4;
if (newSize > value.length) {
enlargeBuffer(newSize);
- } else if (shared) {
- value = value.clone();
- shared = false;
}
value[count++] = 'n';
value[count++] = 'u';
@@ -120,9 +115,6 @@
int newSize = count + chars.length;
if (newSize > value.length) {
enlargeBuffer(newSize);
- } else if (shared) {
- value = value.clone();
- shared = false;
}
System.arraycopy(chars, 0, value, count, chars.length);
count = newSize;
@@ -137,9 +129,6 @@
int newSize = count + length;
if (newSize > value.length) {
enlargeBuffer(newSize);
- } else if (shared) {
- value = value.clone();
- shared = false;
}
System.arraycopy(chars, start, value, count, length);
count = newSize;
@@ -152,10 +141,6 @@
if (count == value.length) {
enlargeBuffer(count + 1);
}
- if (shared) {
- value = value.clone();
- shared = false;
- }
value[count++] = ch;
}
@@ -168,9 +153,6 @@
int newSize = count + adding;
if (newSize > value.length) {
enlargeBuffer(newSize);
- } else if (shared) {
- value = value.clone();
- shared = false;
}
// BEGIN android-changed
string._getChars(0, adding, value, count);
@@ -213,7 +195,7 @@
/**
* Returns the number of characters that can be held without growing.
- *
+ *
* @return the capacity
* @see #ensureCapacity
* @see #length
@@ -224,7 +206,7 @@
/**
* Retrieves the character at the {@code index}.
- *
+ *
* @param index
* the index of the character to retrieve.
* @return the char value.
@@ -296,20 +278,21 @@
* value of either the {@code minimumCapacity} or the current capacity
* multiplied by two plus two. Although this is the general policy, there is
* no guarantee that the capacity will change.
- *
+ *
* @param min
* the new minimum capacity to set.
*/
public void ensureCapacity(int min) {
if (min > value.length) {
- enlargeBuffer(min);
+ int twice = (value.length << 1) + 2;
+ enlargeBuffer(twice > min ? twice : min);
}
}
/**
* Copies the requested sequence of characters to the {@code char[]} passed
* starting at {@code destStart}.
- *
+ *
* @param start
* the inclusive start index of the characters to copy.
* @param end
@@ -343,7 +326,7 @@
}
}
- final void insert0(int index, char chars[], int start, int length) {
+ final void insert0(int index, char[] chars, int start, int length) {
if (0 <= index && index <= count) {
// start + length could overflow, start/length maybe MaxInt
if (start >= 0 && 0 <= length && length <= chars.length - start) {
@@ -354,8 +337,9 @@
}
return;
}
- throw new StringIndexOutOfBoundsException("offset " + start
- + ", len " + length + ", array.length " + chars.length);
+ throw new StringIndexOutOfBoundsException("offset " + start //$NON-NLS-1$
+ + ", length " + length //$NON-NLS-1$
+ + ", char[].length " + chars.length); //$NON-NLS-1$
}
throw new StringIndexOutOfBoundsException(index);
}
@@ -401,7 +385,7 @@
/**
* The current length.
- *
+ *
* @return the number of characters contained in this instance.
*/
public int length() {
@@ -481,15 +465,72 @@
return;
}
if (!shared) {
- for (int i = 0, end = count, mid = count / 2; i < mid; i++) {
- char temp = value[--end];
- value[end] = value[i];
- value[i] = temp;
+ int end = count - 1;
+ char frontHigh = value[0];
+ char endLow = value[end];
+ boolean allowFrontSur = true, allowEndSur = true;
+ for (int i = 0, mid = count / 2; i < mid; i++, --end) {
+ char frontLow = value[i + 1];
+ char endHigh = value[end - 1];
+ boolean surAtFront = allowFrontSur && frontLow >= 0xdc00
+ && frontLow <= 0xdfff && frontHigh >= 0xd800
+ && frontHigh <= 0xdbff;
+ if (surAtFront && (count < 3)) {
+ return;
+ }
+ boolean surAtEnd = allowEndSur && endHigh >= 0xd800
+ && endHigh <= 0xdbff && endLow >= 0xdc00
+ && endLow <= 0xdfff;
+ allowFrontSur = allowEndSur = true;
+ if (surAtFront == surAtEnd) {
+ if (surAtFront) {
+ // both surrogates
+ value[end] = frontLow;
+ value[end - 1] = frontHigh;
+ value[i] = endHigh;
+ value[i + 1] = endLow;
+ frontHigh = value[i + 2];
+ endLow = value[end - 2];
+ i++;
+ end--;
+ } else {
+ // neither surrogates
+ value[end] = frontHigh;
+ value[i] = endLow;
+ frontHigh = frontLow;
+ endLow = endHigh;
+ }
+ } else {
+ if (surAtFront) {
+ // surrogate only at the front
+ value[end] = frontLow;
+ value[i] = endLow;
+ endLow = endHigh;
+ allowFrontSur = false;
+ } else {
+ // surrogate only at the end
+ value[end] = frontHigh;
+ value[i] = endHigh;
+ frontHigh = frontLow;
+ allowEndSur = false;
+ }
+ }
+ }
+ if ((count & 1) == 1 && (!allowFrontSur || !allowEndSur)) {
+ value[end] = allowFrontSur ? endLow : frontHigh;
}
} else {
char[] newData = new char[value.length];
for (int i = 0, end = count; i < count; i++) {
- newData[--end] = value[i];
+ char high = value[i];
+ if ((i + 1) < count && high >= 0xd800 && high <= 0xdbff) {
+ char low = value[i + 1];
+ if (low >= 0xdc00 && low <= 0xdfff) {
+ newData[--end] = low;
+ i++;
+ }
+ }
+ newData[--end] = high;
}
value = newData;
shared = false;
@@ -498,7 +539,7 @@
/**
* Sets the character at the {@code index}.
- *
+ *
* @param index
* the zero-based index of the character to replace.
* @param ch
@@ -522,7 +563,7 @@
* Sets the current length to a new value. If the new length is larger than
* the current length, then the new characters at the end of this object
* will contain the {@code char} value of {@code \u0000}.
- *
+ *
* @param length
* the new length of this StringBuffer.
* @exception IndexOutOfBoundsException
@@ -533,16 +574,16 @@
if (length < 0) {
throw new StringIndexOutOfBoundsException(length);
}
- if (count < length) {
- if (length > value.length) {
- enlargeBuffer(length);
+ if (length > value.length) {
+ enlargeBuffer(length);
+ } else {
+ if (shared) {
+ char[] newData = new char[value.length];
+ System.arraycopy(value, 0, newData, 0, count);
+ value = newData;
+ shared = false;
} else {
- if (shared) {
- char[] newData = new char[value.length];
- System.arraycopy(value, 0, newData, 0, count);
- value = newData;
- shared = false;
- } else {
+ if (count < length) {
Arrays.fill(value, count, length, (char) 0);
}
}
@@ -553,7 +594,7 @@
/**
* Returns the String value of the subsequence from the {@code start} index
* to the current end.
- *
+ *
* @param start
* the inclusive start index to begin the subsequence.
* @return a String containing the subsequence.
@@ -567,8 +608,8 @@
return ""; //$NON-NLS-1$
}
- shared = true;
- return new String(start, count - start, value);
+ // Remove String sharing for more performance
+ return new String(value, start, count - start);
}
throw new StringIndexOutOfBoundsException(start);
}
@@ -576,7 +617,7 @@
/**
* Returns the String value of the subsequence from the {@code start} index
* to the {@code end} index.
- *
+ *
* @param start
* the inclusive start index to begin the subsequence.
* @param end
@@ -592,7 +633,7 @@
return ""; //$NON-NLS-1$
}
- shared = true;
+ // Remove String sharing for more performance
return new String(value, start, end - start);
}
throw new StringIndexOutOfBoundsException();
@@ -600,7 +641,7 @@
/**
* Returns the current String representation.
- *
+ *
* @return a String containing the characters in this instance.
*/
@Override
@@ -608,8 +649,10 @@
if (count == 0) {
return ""; //$NON-NLS-1$
}
-
- if (count >= 256 && count <= (value.length >> 1)) {
+ // Optimize String sharing for more performance
+ int wasted = value.length - count;
+ if (wasted >= 256
+ || (wasted >= INITIAL_CAPACITY && wasted >= (count >> 1))) {
return new String(value, 0, count);
}
shared = true;
@@ -619,7 +662,7 @@
/**
* Returns a {@code CharSequence} of the subsequence from the {@code start}
* index to the {@code end} index.
- *
+ *
* @param start
* the inclusive start index to begin the subsequence.
* @param end
@@ -628,6 +671,7 @@
* @throws IndexOutOfBoundsException
* if {@code start} is negative, greater than {@code end} or if
* {@code end} is greater than the current {@link #length()}.
+ * @since 1.4
*/
public CharSequence subSequence(int start, int end) {
return substring(start, end);
@@ -636,12 +680,13 @@
/**
* Searches for the first index of the specified character. The search for
* the character starts at the beginning and moves towards the end.
- *
+ *
* @param string
* the string to find.
* @return the index of the specified character, -1 if the character isn't
* found.
* @see #lastIndexOf(String)
+ * @since 1.4
*/
public int indexOf(String string) {
return indexOf(string, 0);
@@ -650,7 +695,7 @@
/**
* Searches for the index of the specified character. The search for the
* character starts at the specified offset and moves towards the end.
- *
+ *
* @param subString
* the string to find.
* @param start
@@ -658,6 +703,7 @@
* @return the index of the specified character, -1 if the character isn't
* found
* @see #lastIndexOf(String,int)
+ * @since 1.4
*/
public int indexOf(String subString, int start) {
if (start < 0) {
@@ -698,12 +744,15 @@
/**
* Searches for the last index of the specified character. The search for
* the character starts at the end and moves towards the beginning.
- *
+ *
* @param string
* the string to find.
* @return the index of the specified character, -1 if the character isn't
* found.
- * @see String#lastIndexOf(String)
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
+ * @see String#lastIndexOf(java.lang.String)
+ * @since 1.4
*/
public int lastIndexOf(String string) {
return lastIndexOf(string, count);
@@ -712,14 +761,17 @@
/**
* Searches for the index of the specified character. The search for the
* character starts at the specified offset and moves towards the beginning.
- *
+ *
* @param subString
* the string to find.
* @param start
* the starting offset.
* @return the index of the specified character, -1 if the character isn't
* found.
+ * @throws NullPointerException
+ * if {@code subString} is {@code null}.
* @see String#lastIndexOf(String,int)
+ * @since 1.4
*/
public int lastIndexOf(String subString, int start) {
int subCount = subString.length();
@@ -762,6 +814,8 @@
/**
* Trims off any extra capacity beyond the current length. Note, this method
* is NOT guaranteed to change the capacity of this object.
+ *
+ * @since 1.5
*/
public void trimToSize() {
if (count < value.length) {
@@ -774,7 +828,7 @@
/**
* Retrieves the Unicode code point value at the {@code index}.
- *
+ *
* @param index
* the index to the {@code char} code unit.
* @return the Unicode code point value.
@@ -783,6 +837,7 @@
* {@link #length()}.
* @see Character
* @see Character#codePointAt(char[], int, int)
+ * @since 1.5
*/
public int codePointAt(int index) {
if (index < 0 || index >= count) {
@@ -793,7 +848,7 @@
/**
* Retrieves the Unicode code point value that precedes the {@code index}.
- *
+ *
* @param index
* the index to the {@code char} code unit within this object.
* @return the Unicode code point value.
@@ -801,7 +856,8 @@
* if {@code index} is less than 1 or greater than
* {@link #length()}.
* @see Character
- * @see Character#codePointBefore(char[], int)
+ * @see Character#codePointBefore(char[], int, int)
+ * @since 1.5
*/
public int codePointBefore(int index) {
if (index < 1 || index > count) {
@@ -811,11 +867,9 @@
}
/**
- * <p>
* Calculates the number of Unicode code points between {@code beginIndex}
* and {@code endIndex}.
- * </p>
- *
+ *
* @param beginIndex
* the inclusive beginning index of the subsequence.
* @param endIndex
@@ -827,6 +881,7 @@
* {@link #length()}.
* @see Character
* @see Character#codePointCount(char[], int, int)
+ * @since 1.5
*/
public int codePointCount(int beginIndex, int endIndex) {
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
@@ -837,11 +892,9 @@
}
/**
- * <p>
* Returns the index that is offset {@code codePointOffset} code points from
* {@code index}.
- * </p>
- *
+ *
* @param index
* the index to calculate the offset from.
* @param codePointOffset
@@ -855,6 +908,7 @@
* {@code codePointOffset}.
* @see Character
* @see Character#offsetByCodePoints(char[], int, int, int, int)
+ * @since 1.5
*/
public int offsetByCodePoints(int index, int codePointOffset) {
return Character.offsetByCodePoints(value, 0, count, index,
diff --git a/luni/src/main/java/java/lang/Appendable.java b/luni/src/main/java/java/lang/Appendable.java
index 1b4e702..ca4b532 100644
--- a/luni/src/main/java/java/lang/Appendable.java
+++ b/luni/src/main/java/java/lang/Appendable.java
@@ -27,16 +27,13 @@
* <p>
* {@code Appendable} itself does not guarantee thread safety. This
* responsibility is up to the implementing class.
- * </p>
* <p>
* Implementing classes can choose different exception handling mechanism. They
* can choose to throw exceptions other than {@code IOException} or they do not
* throw any exceptions at all and use error codes instead.
- * </p>
- * @since Android 1.0
*/
public interface Appendable {
-
+
/**
* Appends the specified character.
*
@@ -45,7 +42,6 @@
* @return this {@code Appendable}.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
Appendable append(char c) throws IOException;
@@ -55,14 +51,12 @@
* limited size.
* <p>
* If {@code csq} is {@code null}, the characters "null" are appended.
- * </p>
- *
+ *
* @param csq
* the character sequence to append.
* @return this {@code Appendable}.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
Appendable append(CharSequence csq) throws IOException;
@@ -73,7 +67,6 @@
* to calling {@code append(csq.subSequence(start, end))}.
* <p>
* If {@code csq} is {@code null}, the characters "null" are appended.
- * </p>
*
* @param csq
* the character sequence to append.
@@ -89,7 +82,6 @@
* or {@code end} is greater than the length of {@code csq}.
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
Appendable append(CharSequence csq, int start, int end) throws IOException;
}
diff --git a/luni/src/main/java/java/lang/ArithmeticException.java b/luni/src/main/java/java/lang/ArithmeticException.java
index 74671fc..a6ab2a0 100644
--- a/luni/src/main/java/java/lang/ArithmeticException.java
+++ b/luni/src/main/java/java/lang/ArithmeticException.java
@@ -19,8 +19,6 @@
/**
* Thrown when the an invalid arithmetic operation is attempted.
- *
- * @since Android 1.0
*/
public class ArithmeticException extends RuntimeException {
@@ -29,8 +27,6 @@
/**
* Constructs a new {@code ArithmeticException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public ArithmeticException() {
super();
@@ -39,10 +35,9 @@
/**
* Constructs a new {@code ArithmeticException} with the current stack trace
* and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public ArithmeticException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java b/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
index 0f231d3..d43a7e6 100644
--- a/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
+++ b/luni/src/main/java/java/lang/ArrayIndexOutOfBoundsException.java
@@ -22,8 +22,6 @@
/**
* Thrown when the an array is indexed with a value less than zero, or greater
* than or equal to the size of the array.
- *
- * @since Android 1.0
*/
public class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException {
@@ -32,8 +30,6 @@
/**
* Constructs a new {@code ArrayIndexOutOfBoundsException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public ArrayIndexOutOfBoundsException() {
super();
@@ -46,7 +42,6 @@
*
* @param index
* the invalid index.
- * @since Android 1.0
*/
public ArrayIndexOutOfBoundsException(int index) {
super(Msg.getString("K0052", index)); //$NON-NLS-1$
@@ -55,10 +50,9 @@
/**
* Constructs a new {@code ArrayIndexOutOfBoundsException} with the current
* stack trace and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public ArrayIndexOutOfBoundsException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/ArrayStoreException.java b/luni/src/main/java/java/lang/ArrayStoreException.java
index b69697a..6cb9c8f 100644
--- a/luni/src/main/java/java/lang/ArrayStoreException.java
+++ b/luni/src/main/java/java/lang/ArrayStoreException.java
@@ -20,8 +20,6 @@
/**
* Thrown when a program attempts to store an element of an incompatible type in
* an array.
- *
- * @since Android 1.0
*/
public class ArrayStoreException extends RuntimeException {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code ArrayStoreException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public ArrayStoreException() {
super();
@@ -40,10 +36,9 @@
/**
* Constructs a new {@code ArrayStoreException} with the current stack trace
* and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public ArrayStoreException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/AssertionError.java b/luni/src/main/java/java/lang/AssertionError.java
index 8d3368b..e4d4ed0 100644
--- a/luni/src/main/java/java/lang/AssertionError.java
+++ b/luni/src/main/java/java/lang/AssertionError.java
@@ -19,8 +19,8 @@
/**
* Thrown when an assertion has failed.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public class AssertionError extends Error {
@@ -28,8 +28,6 @@
/**
* Constructs a new {@code AssertionError} with no message.
- *
- * @since Android 1.0
*/
public AssertionError() {
super();
@@ -44,7 +42,6 @@
* @param detailMessage
* the object to be converted into the detail message and
* optionally the cause.
- * @since Android 1.0
*/
public AssertionError(Object detailMessage) {
super(String.valueOf(detailMessage),
@@ -58,7 +55,6 @@
*
* @param detailMessage
* the value to be converted into the message.
- * @since Android 1.0
*/
public AssertionError(boolean detailMessage) {
this(String.valueOf(detailMessage));
@@ -70,7 +66,6 @@
*
* @param detailMessage
* the value to be converted into the message.
- * @since Android 1.0
*/
public AssertionError(char detailMessage) {
this(String.valueOf(detailMessage));
@@ -82,7 +77,6 @@
*
* @param detailMessage
* the value to be converted into the message.
- * @since Android 1.0
*/
public AssertionError(int detailMessage) {
this(Integer.toString(detailMessage));
@@ -94,7 +88,6 @@
*
* @param detailMessage
* the value to be converted into the message.
- * @since Android 1.0
*/
public AssertionError(long detailMessage) {
this(Long.toString(detailMessage));
@@ -106,7 +99,6 @@
*
* @param detailMessage
* the value to be converted into the message.
- * @since Android 1.0
*/
public AssertionError(float detailMessage) {
this(Float.toString(detailMessage));
@@ -118,7 +110,6 @@
*
* @param detailMessage
* the value to be converted into the message.
- * @since Android 1.0
*/
public AssertionError(double detailMessage) {
this(Double.toString(detailMessage));
diff --git a/luni/src/main/java/java/lang/Boolean.java b/luni/src/main/java/java/lang/Boolean.java
index c49c384..9c476a4 100644
--- a/luni/src/main/java/java/lang/Boolean.java
+++ b/luni/src/main/java/java/lang/Boolean.java
@@ -21,8 +21,8 @@
/**
* The wrapper for the primitive type {@code boolean}.
- *
- * @since Android 1.0
+ *
+ * @since 1.0
*/
public final class Boolean implements Serializable, Comparable<Boolean> {
@@ -36,8 +36,6 @@
/**
* The {@link Class} object that represents the primitive type {@code
* boolean}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Class<Boolean> TYPE = (Class<Boolean>) new boolean[0]
@@ -49,16 +47,12 @@
/**
* The {@code Boolean} object that represents the primitive value
* {@code true}.
- *
- * @since Android 1.0
*/
public static final Boolean TRUE = new Boolean(true);
/**
* The {@code Boolean} object that represents the primitive value
* {@code false}.
- *
- * @since Android 1.0
*/
public static final Boolean FALSE = new Boolean(false);
@@ -68,10 +62,9 @@
* "true" using a non-case sensitive comparison, the result will be a
* Boolean representing the primitive value {@code true}, otherwise it will
* be a Boolean representing the primitive value {@code false}.
- *
+ *
* @param string
* the string representing a boolean value.
- * @since Android 1.0
*/
public Boolean(String string) {
this(parseBoolean(string));
@@ -80,10 +73,9 @@
/**
* Constructs a new {@code Boolean} with the specified primitive boolean
* value.
- *
+ *
* @param value
* the primitive boolean value, {@code true} or {@code false}.
- * @since Android 1.0
*/
public Boolean(boolean value) {
this.value = value;
@@ -92,9 +84,8 @@
/**
* Gets the primitive value of this boolean, either {@code true} or
* {@code false}.
- *
+ *
* @return this object's primitive value, {@code true} or {@code false}.
- * @since Android 1.0
*/
public boolean booleanValue() {
return value;
@@ -104,12 +95,11 @@
* Compares this instance with the specified object and indicates if they
* are equal. In order to be equal, {@code o} must be an instance of
* {@code Boolean} and have the same boolean value as this object.
- *
+ *
* @param o
* the object to compare this boolean with.
* @return {@code true} if the specified object is equal to this
* {@code Boolean}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object o) {
@@ -120,7 +110,7 @@
/**
* Compares this object to the specified boolean object to determine their
* relative order.
- *
+ *
* @param that
* the boolean object to compare this object to.
* @return 0 if the value of this boolean and the value of {@code that} are
@@ -129,7 +119,7 @@
* negative value if the value if this boolean is {@code false} and
* the value of {@code that} is {@code true}.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.5
*/
public int compareTo(Boolean that) {
if (that == null) {
@@ -145,10 +135,9 @@
/**
* Returns an integer hash code for this boolean.
- *
+ *
* @return this boolean's hash code, which is {@code 1231} for {@code true}
* values and {@code 1237} for {@code false} values.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -158,10 +147,9 @@
/**
* Returns a string containing a concise, human-readable description of this
* boolean.
- *
+ *
* @return "true" if the value of this boolean is {@code true}, "false"
* otherwise.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -171,14 +159,13 @@
/**
* Returns the {@code boolean} value of the system property identified by
* {@code string}.
- *
+ *
* @param string
* the name of the requested system property.
* @return {@code true} if the system property named by {@code string}
* exists and it is equal to "true" using case insensitive
* comparison, {@code false} otherwise.
* @see System#getProperty(String)
- * @since Android 1.0
*/
public static boolean getBoolean(String string) {
if (string == null || string.length() == 0) {
@@ -189,25 +176,24 @@
/**
* Parses the specified string as a {@code boolean}.
- *
+ *
* @param s
* the string representation of a boolean value.
* @return {@code true} if {@code s} is not {@code null} and is equal to
* {@code "true"} using case insensitive comparison, {@code false}
* otherwise.
- * @since Android 1.0
+ * @since 1.5
*/
public static boolean parseBoolean(String s) {
return "true".equalsIgnoreCase(s); //$NON-NLS-1$
}
/**
- * Converts the specified boolean to its string representation.
- *
+ * Converts the specified boolean to its string representation.
+ *
* @param value
* the boolean to convert.
* @return "true" if {@code value} is {@code true}, "false" otherwise.
- * @since Android 1.0
*/
public static String toString(boolean value) {
return String.valueOf(value);
@@ -215,13 +201,12 @@
/**
* Parses the specified string as a boolean value.
- *
+ *
* @param string
* the string representation of a boolean value.
* @return {@code Boolean.TRUE} if {@code string} is equal to "true" using
* case insensitive comparison, {@code Boolean.FALSE} otherwise.
* @see #parseBoolean(String)
- * @since Android 1.0
*/
public static Boolean valueOf(String string) {
return parseBoolean(string) ? Boolean.TRUE : Boolean.FALSE;
@@ -233,13 +218,11 @@
* If it is not necessary to get a new {@code Boolean} instance, it is
* recommended to use this method instead of the constructor, since it
* returns its static instances, which results in better performance.
- * </p>
- *
+ *
* @param b
* the boolean to convert to a {@code Boolean}.
* @return {@code Boolean.TRUE} if {@code b} is equal to {@code true},
* {@code Boolean.FALSE} otherwise.
- * @since Android 1.0
*/
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
diff --git a/luni/src/main/java/java/lang/Byte.java b/luni/src/main/java/java/lang/Byte.java
index a74b539..7e20493 100644
--- a/luni/src/main/java/java/lang/Byte.java
+++ b/luni/src/main/java/java/lang/Byte.java
@@ -19,10 +19,11 @@
/**
* The wrapper for the primitive type {@code byte}.
- *
- * @since Android 1.0
+ *
+ * @since 1.1
*/
-public final class Byte extends Number implements Comparable<Byte> {
+public final class Byte extends Number implements Comparable<Byte> {
+
private static final long serialVersionUID = -7183698231559129828L;
/**
@@ -32,30 +33,24 @@
/**
* The maximum {@code Byte} value, 2<sup>7</sup>-1.
- *
- * @since Android 1.0
*/
public static final byte MAX_VALUE = (byte) 0x7F;
/**
* The minimum {@code Byte} value, -2<sup>7</sup>.
- *
- * @since Android 1.0
*/
public static final byte MIN_VALUE = (byte) 0x80;
-
+
/**
* The number of bits needed to represent a {@code Byte} value in two's
* complement form.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int SIZE = 8;
/**
* The {@link Class} object that represents the primitive type {@code byte}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Class<Byte> TYPE = (Class<Byte>) new byte[0].getClass()
@@ -63,7 +58,7 @@
// Note: This can't be set to "byte.class", since *that* is
// defined to be "java.lang.Byte.TYPE";
-
+
/**
* A cache of instances used by {@link #valueOf(byte)} and auto-boxing.
*/
@@ -71,10 +66,9 @@
/**
* Constructs a new {@code Byte} with the specified primitive byte value.
- *
+ *
* @param value
* the primitive byte value to store in the new instance.
- * @since Android 1.0
*/
public Byte(byte value) {
this.value = value;
@@ -82,13 +76,12 @@
/**
* Constructs a new {@code Byte} from the specified string.
- *
+ *
* @param string
* the string representation of a single byte value.
* @throws NumberFormatException
* if {@code string} can not be decoded into a byte value.
* @see #parseByte(String)
- * @since Android 1.0
*/
public Byte(String string) throws NumberFormatException {
this(parseByte(string));
@@ -96,9 +89,8 @@
/**
* Gets the primitive value of this byte.
- *
+ *
* @return this object's primitive value.
- * @since Android 1.0
*/
@Override
public byte byteValue() {
@@ -108,7 +100,7 @@
/**
* Compares this object to the specified byte object to determine their
* relative order.
- *
+ *
* @param object
* the byte object to compare this object to.
* @return a negative value if the value of this byte is less than the value
@@ -116,7 +108,7 @@
* {@code object} are equal; a positive value if the value of this
* byte is greater than the value of {@code object}.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.2
*/
public int compareTo(Byte object) {
return value > object.value ? 1 : (value < object.value ? -1 : 0);
@@ -127,13 +119,12 @@
* string can be decoded into a single byte value. The string may be an
* optional minus sign "-" followed by a hexadecimal ("0x..." or "#..."),
* octal ("0..."), or decimal ("...") representation of a byte.
- *
+ *
* @param string
* a string representation of a single byte value.
* @return a {@code Byte} containing the value represented by {@code string}.
* @throws NumberFormatException
* if {@code string} can not be parsed as a byte value.
- * @since Android 1.0
*/
public static Byte decode(String string) throws NumberFormatException {
int intValue = Integer.decode(string).intValue();
@@ -153,12 +144,11 @@
* Compares this object with the specified object and indicates if they are
* equal. In order to be equal, {@code object} must be an instance of
* {@code Byte} and have the same byte value as this object.
- *
+ *
* @param object
* the object to compare this byte with.
* @return {@code true} if the specified object is equal to this
* {@code Byte}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -189,14 +179,13 @@
/**
* Parses the specified string as a signed decimal byte value. The ASCII
* character \u002d ('-') is recognized as the minus sign.
- *
+ *
* @param string
* the string representation of a single byte value.
* @return the primitive byte value represented by {@code string}.
* @throws NumberFormatException
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a byte value.
- * @since Android 1.0
*/
public static byte parseByte(String string) throws NumberFormatException {
int intValue = Integer.parseInt(string);
@@ -210,7 +199,7 @@
/**
* Parses the specified string as a signed byte value using the specified
* radix. The ASCII character \u002d ('-') is recognized as the minus sign.
- *
+ *
* @param string
* the string representation of a single byte value.
* @param radix
@@ -222,7 +211,6 @@
* {@code radix < Character.MIN_RADIX},
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as a byte value.
- * @since Android 1.0
*/
public static byte parseByte(String string, int radix)
throws NumberFormatException {
@@ -247,11 +235,10 @@
/**
* Returns a string containing a concise, human-readable description of the
* specified byte value.
- *
+ *
* @param value
* the byte to convert to a string.
* @return a printable representation of {@code value}.
- * @since Android 1.0
*/
public static String toString(byte value) {
return Integer.toString(value);
@@ -259,7 +246,7 @@
/**
* Parses the specified string as a signed decimal byte value.
- *
+ *
* @param string
* the string representation of a single byte value.
* @return a {@code Byte} instance containing the byte value represented by
@@ -268,7 +255,6 @@
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a byte value.
* @see #parseByte(String)
- * @since Android 1.0
*/
public static Byte valueOf(String string) throws NumberFormatException {
return valueOf(parseByte(string));
@@ -277,7 +263,7 @@
/**
* Parses the specified string as a signed byte value using the specified
* radix.
- *
+ *
* @param string
* the string representation of a single byte value.
* @param radix
@@ -290,25 +276,23 @@
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as a byte value.
* @see #parseByte(String, int)
- * @since Android 1.0
*/
public static Byte valueOf(String string, int radix)
throws NumberFormatException {
return valueOf(parseByte(string, radix));
}
-
+
/**
* Returns a {@code Byte} instance for the specified byte value.
* <p>
* If it is not necessary to get a new {@code Byte} instance, it is
* recommended to use this method instead of the constructor, since it
* maintains a cache of instances which may result in better performance.
- * </p>
- *
+ *
* @param b
* the byte value to store in the instance.
* @return a {@code Byte} instance containing {@code b}.
- * @since Android 1.0
+ * @since 1.5
*/
public static Byte valueOf(byte b) {
synchronized (CACHE) {
diff --git a/luni/src/main/java/java/lang/CharSequence.java b/luni/src/main/java/java/lang/CharSequence.java
index 1901192..fc1ecd3 100644
--- a/luni/src/main/java/java/lang/CharSequence.java
+++ b/luni/src/main/java/java/lang/CharSequence.java
@@ -21,37 +21,33 @@
/**
* This interface represents an ordered set of characters and defines the
* methods to probe them.
- *
- * @since Android 1.0
*/
public interface CharSequence {
/**
* Returns the number of characters in this sequence.
- *
+ *
* @return the number of characters.
- * @since Android 1.0
*/
public int length();
/**
* Returns the character at the specified index, with the first character
* having index zero.
- *
+ *
* @param index
* the index of the character to return.
* @return the requested character.
* @throws IndexOutOfBoundsException
* if {@code index < 0} or {@code index} is greater than the
* length of this sequence.
- * @since Android 1.0
*/
public char charAt(int index);
/**
* Returns a {@code CharSequence} from the {@code start} index (inclusive)
* to the {@code end} index (exclusive) of this sequence.
- *
+ *
* @param start
* the start offset of the sub-sequence. It is inclusive, that
* is, the index of the first character that is included in the
@@ -65,16 +61,14 @@
* if {@code start < 0}, {@code end < 0}, {@code start > end},
* or if {@code start} or {@code end} are greater than the
* length of this sequence.
- * @since Android 1.0
*/
public CharSequence subSequence(int start, int end);
/**
* Returns a string with the same characters in the same order as in this
* sequence.
- *
+ *
* @return a string based on this sequence.
- * @since Android 1.0
*/
public String toString();
}
diff --git a/luni/src/main/java/java/lang/Character.java b/luni/src/main/java/java/lang/Character.java
index 564e37a..8e83b48 100644
--- a/luni/src/main/java/java/lang/Character.java
+++ b/luni/src/main/java/java/lang/Character.java
@@ -21,7 +21,7 @@
// BEGIN android-removed
// import java.util.SortedMap;
// import java.util.TreeMap;
-//
+//
// import org.apache.harmony.luni.util.BinarySearch;
// END android-removed
@@ -36,7 +36,6 @@
* Character data is based upon the Unicode Standard, 4.0. The Unicode
* specification, character tables and other information are available at <a
* href="http://www.unicode.org/">http://www.unicode.org/</a>.
- * </p>
* <p>
* Unicode characters are referred to as <i>code points</i>. The range of valid
* code points is U+0000 to U+10FFFF. The <i>Basic Multilingual Plane (BMP)</i>
@@ -47,14 +46,12 @@
* supplementary character are made up of a <i>high surrogate</i> with a value
* range of 0xD800 to 0xDBFF and a <i>low surrogate</i> with a value range of
* 0xDC00 to 0xDFFF.
- * </p>
* <p>
* On the Java platform a {@code char} value represents either a single BMP code
* point or a UTF-16 unit that's part of a surrogate pair. The {@code int} type
* is used to represent all Unicode code points.
- * </p>
- *
- * @since Android 1.0
+ *
+ * @since 1.0
*/
public final class Character implements Serializable, Comparable<Character> {
private static final long serialVersionUID = 3786198910865385080L;
@@ -63,36 +60,26 @@
/**
* The minimum {@code Character} value.
- *
- * @since Android 1.0
*/
public static final char MIN_VALUE = '\u0000';
/**
* The maximum {@code Character} value.
- *
- * @since Android 1.0
*/
public static final char MAX_VALUE = '\uffff';
/**
* The minimum radix used for conversions between characters and integers.
- *
- * @since Android 1.0
*/
public static final int MIN_RADIX = 2;
/**
* The maximum radix used for conversions between characters and integers.
- *
- * @since Android 1.0
*/
public static final int MAX_RADIX = 36;
/**
* The {@link Class} object that represents the primitive type {@code char}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Class<Character> TYPE = (Class<Character>) new char[0]
@@ -103,437 +90,415 @@
/**
* Unicode category constant Cn.
- *
- * @since Android 1.0
*/
public static final byte UNASSIGNED = 0;
/**
* Unicode category constant Lu.
- *
- * @since Android 1.0
*/
public static final byte UPPERCASE_LETTER = 1;
/**
* Unicode category constant Ll.
- *
- * @since Android 1.0
*/
public static final byte LOWERCASE_LETTER = 2;
/**
* Unicode category constant Lt.
- *
- * @since Android 1.0
*/
public static final byte TITLECASE_LETTER = 3;
/**
* Unicode category constant Lm.
- *
- * @since Android 1.0
*/
public static final byte MODIFIER_LETTER = 4;
/**
* Unicode category constant Lo.
- *
- * @since Android 1.0
*/
public static final byte OTHER_LETTER = 5;
/**
* Unicode category constant Mn.
- *
- * @since Android 1.0
*/
public static final byte NON_SPACING_MARK = 6;
/**
* Unicode category constant Me.
- *
- * @since Android 1.0
*/
public static final byte ENCLOSING_MARK = 7;
/**
* Unicode category constant Mc.
- *
- * @since Android 1.0
*/
public static final byte COMBINING_SPACING_MARK = 8;
/**
* Unicode category constant Nd.
- *
- * @since Android 1.0
*/
public static final byte DECIMAL_DIGIT_NUMBER = 9;
/**
* Unicode category constant Nl.
- *
- * @since Android 1.0
*/
public static final byte LETTER_NUMBER = 10;
/**
* Unicode category constant No.
- *
- * @since Android 1.0
*/
public static final byte OTHER_NUMBER = 11;
/**
* Unicode category constant Zs.
- *
- * @since Android 1.0
*/
public static final byte SPACE_SEPARATOR = 12;
/**
* Unicode category constant Zl.
- *
- * @since Android 1.0
*/
public static final byte LINE_SEPARATOR = 13;
/**
* Unicode category constant Zp.
- *
- * @since Android 1.0
*/
public static final byte PARAGRAPH_SEPARATOR = 14;
/**
* Unicode category constant Cc.
- *
- * @since Android 1.0
*/
public static final byte CONTROL = 15;
/**
* Unicode category constant Cf.
- *
- * @since Android 1.0
*/
public static final byte FORMAT = 16;
/**
* Unicode category constant Co.
- *
- * @since Android 1.0
*/
public static final byte PRIVATE_USE = 18;
/**
* Unicode category constant Cs.
- *
- * @since Android 1.0
*/
public static final byte SURROGATE = 19;
/**
* Unicode category constant Pd.
- *
- * @since Android 1.0
*/
public static final byte DASH_PUNCTUATION = 20;
/**
* Unicode category constant Ps.
- *
- * @since Android 1.0
*/
public static final byte START_PUNCTUATION = 21;
/**
* Unicode category constant Pe.
- *
- * @since Android 1.0
*/
public static final byte END_PUNCTUATION = 22;
/**
* Unicode category constant Pc.
- *
- * @since Android 1.0
*/
public static final byte CONNECTOR_PUNCTUATION = 23;
/**
* Unicode category constant Po.
- *
- * @since Android 1.0
*/
public static final byte OTHER_PUNCTUATION = 24;
/**
* Unicode category constant Sm.
- *
- * @since Android 1.0
*/
public static final byte MATH_SYMBOL = 25;
/**
* Unicode category constant Sc.
- *
- * @since Android 1.0
*/
public static final byte CURRENCY_SYMBOL = 26;
/**
* Unicode category constant Sk.
- *
- * @since Android 1.0
*/
public static final byte MODIFIER_SYMBOL = 27;
/**
* Unicode category constant So.
- *
- * @since Android 1.0
*/
public static final byte OTHER_SYMBOL = 28;
/**
* Unicode category constant Pi.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte INITIAL_QUOTE_PUNCTUATION = 29;
/**
* Unicode category constant Pf.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte FINAL_QUOTE_PUNCTUATION = 30;
/**
* Unicode bidirectional constant.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_UNDEFINED = -1;
/**
* Unicode bidirectional constant L.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0;
/**
* Unicode bidirectional constant R.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1;
/**
* Unicode bidirectional constant AL.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2;
/**
* Unicode bidirectional constant EN.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3;
/**
* Unicode bidirectional constant ES.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4;
/**
* Unicode bidirectional constant ET.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5;
/**
* Unicode bidirectional constant AN.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6;
/**
* Unicode bidirectional constant CS.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7;
/**
* Unicode bidirectional constant NSM.
*
- * @since Android 1.0
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_NONSPACING_MARK = 8;
/**
* Unicode bidirectional constant BN.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9;
/**
* Unicode bidirectional constant B.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10;
/**
* Unicode bidirectional constant S.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11;
/**
* Unicode bidirectional constant WS.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_WHITESPACE = 12;
/**
* Unicode bidirectional constant ON.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13;
/**
* Unicode bidirectional constant LRE.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14;
/**
* Unicode bidirectional constant LRO.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15;
/**
* Unicode bidirectional constant RLE.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16;
/**
* Unicode bidirectional constant RLO.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17;
/**
* Unicode bidirectional constant PDF.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
-
+
/**
* The minimum value of a high surrogate or leading surrogate unit in UTF-16
* encoding, {@code '\uD800'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final char MIN_HIGH_SURROGATE = '\uD800';
/**
* The maximum value of a high surrogate or leading surrogate unit in UTF-16
* encoding, {@code '\uDBFF'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final char MAX_HIGH_SURROGATE = '\uDBFF';
/**
* The minimum value of a low surrogate or trailing surrogate unit in UTF-16
* encoding, {@code '\uDC00'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final char MIN_LOW_SURROGATE = '\uDC00';
/**
* The maximum value of a low surrogate or trailing surrogate unit in UTF-16
* encoding, {@code '\uDFFF'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final char MAX_LOW_SURROGATE = '\uDFFF';
/**
* The minimum value of a surrogate unit in UTF-16 encoding, {@code '\uD800'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final char MIN_SURROGATE = '\uD800';
/**
* The maximum value of a surrogate unit in UTF-16 encoding, {@code '\uDFFF'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final char MAX_SURROGATE = '\uDFFF';
/**
* The minimum value of a supplementary code point, {@code U+010000}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int MIN_SUPPLEMENTARY_CODE_POINT = 0x10000;
/**
* The minimum code point value, {@code U+0000}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int MIN_CODE_POINT = 0x000000;
/**
* The maximum code point value, {@code U+10FFFF}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int MAX_CODE_POINT = 0x10FFFF;
/**
- * The number of bits required to represent a {@code Character} value in
- * two's compliment form.
- *
- * @since Android 1.0
+ * The number of bits required to represent a {@code Character} value
+ * unsigned form.
+ *
+ * @since 1.5
*/
public static final int SIZE = 16;
// BEGIN android-removed
- // removed strings containing information about chars that now are read from
- // icu data.
+ // Unicode 3.0.1 (same as Unicode 3.0.0)
+ // private static final String bidiKeys = ...
+
+ // private static final char[] bidiValues = ...
+
+ // private static final char[] mirrored = ...
+
+ // Unicode 3.0.1 (same as Unicode 3.0.0)
+ // private static final String typeKeys = ...
+
+ // private static final char[] typeValues = ...
+
+ // private static final int[] typeValuesCache = ...
+
+ // Unicode 3.0.1 (same as Unicode 3.0.0)
+ // private static final String uppercaseKeys = ...
+
+ // private static final char[] uppercaseValues = ...
+
+ // private static final int[] uppercaseValuesCache = ...
+
+ // private static final String lowercaseKeys = ...
+
+ // private static final char[] lowercaseValues = ...
+
+ // private static final int[] lowercaseValuesCache = ...
+
+ // private static final String digitKeys = ...
+
+ // private static final char[] digitValues = ...
// END android-removed
-
+
+ // BEGIN android-note
+ // put this in a helper class so that it's only initialized on demand?
+ // END android-note
private static final char[] typeTags = "\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0000\u0000\u0000\u0000\u0000\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0003\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0002\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0000\u0000\u0000\u0000\u0003\u0000\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0003\u0000\u0000\u0000\u0000\u0002"
.getValue();
-
+
+ // BEGIN android-note
+ // put this in a helper class so that it's only initialized on demand?
+ // END android-note
private static final byte[] DIRECTIONALITY = new byte[] {
DIRECTIONALITY_LEFT_TO_RIGHT, DIRECTIONALITY_RIGHT_TO_LEFT,
DIRECTIONALITY_EUROPEAN_NUMBER,
@@ -557,24 +522,28 @@
private static final int ISJAVAPART = 2;
// BEGIN android-removed
- // removed strings containing information about chars that now are read from
- // icu data.
+ // Unicode 3.0.1 (same as Unicode 3.0.0)
+ // private static final String titlecaseKeys = ...
+
+ // private static final char[] titlecaseValues = ...
+
+ // Unicode 3.0.0 (NOT the same as Unicode 3.0.1)
+ // private static final String numericKeys = ...
+
+ // private static final char[] numericValues = ...
// END android-removed
-
- /**
+
+ /*
* Represents a subset of the Unicode character set.
- *
- * @since Android 1.0
*/
public static class Subset {
String name;
/**
* Constructs a new {@code Subset}.
- *
+ *
* @param string
* this subset's name.
- * @since Android 1.0
*/
protected Subset(String string) {
if (string == null) {
@@ -586,12 +555,11 @@
/**
* Compares this character subset with the specified object. Uses
* {@link java.lang.Object#equals(Object)} to do the comparison.
- *
+ *
* @param object
* the object to compare this character subset with.
* @return {@code true} if {@code object} is this subset, that is, if
* {@code object == this}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public final boolean equals(Object object) {
@@ -600,10 +568,9 @@
/**
* Returns the integer hash code for this character subset.
- *
+ *
* @return this subset's hash code, which is the hash code computed by
* {@link java.lang.Object#hashCode()}.
- * @since Android 1.0
*/
@Override
public final int hashCode() {
@@ -612,9 +579,8 @@
/**
* Returns the string representation of this subset.
- *
+ *
* @return this subset's name.
- * @since Android 1.0
*/
@Override
public final String toString() {
@@ -622,799 +588,796 @@
}
}
- // BEGIN android-changed
-
/**
* Represents a block of Unicode characters, as defined by the Unicode 4.0.1
* specification.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public static final class UnicodeBlock extends Subset {
/**
* The "Surrogates Area" Unicode Block.
- *
+ *
* @deprecated As of Java 5, this block has been replaced by
* {@link #HIGH_SURROGATES},
* {@link #HIGH_PRIVATE_USE_SURROGATES} and
* {@link #LOW_SURROGATES}.
- * @since Android 1.0
*/
@Deprecated
- public static final UnicodeBlock SURROGATES_AREA = new UnicodeBlock("SURROGATES_AREA");
+ public static final UnicodeBlock SURROGATES_AREA = new UnicodeBlock("SURROGATES_AREA", 0x0, 0x0);
/**
- * The "Basic Latin" Unicode Block.
+ * The "Basic Latin" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock BASIC_LATIN = new UnicodeBlock("BASIC_LATIN");
+ public static final UnicodeBlock BASIC_LATIN = new UnicodeBlock("BASIC_LATIN", 0x0, 0x7f);
/**
- * The "Latin-1 Supplement" Unicode Block.
+ * The "Latin-1 Supplement" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock LATIN_1_SUPPLEMENT = new UnicodeBlock("LATIN_1_SUPPLEMENT");
+ public static final UnicodeBlock LATIN_1_SUPPLEMENT = new UnicodeBlock("LATIN_1_SUPPLEMENT", 0x80, 0xff);
/**
- * The "Latin Extended-A" Unicode Block.
+ * The "Latin Extended-A" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock LATIN_EXTENDED_A = new UnicodeBlock("LATIN_EXTENDED_A");
+ public static final UnicodeBlock LATIN_EXTENDED_A = new UnicodeBlock("LATIN_EXTENDED_A", 0x100, 0x17f);
/**
- * The "Latin Extended-B" Unicode Block.
+ * The "Latin Extended-B" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock LATIN_EXTENDED_B = new UnicodeBlock("LATIN_EXTENDED_B");
+ public static final UnicodeBlock LATIN_EXTENDED_B = new UnicodeBlock("LATIN_EXTENDED_B", 0x180, 0x24f);
/**
- * The "IPA Extensions" Unicode Block.
+ * The "IPA Extensions" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock IPA_EXTENSIONS = new UnicodeBlock("IPA_EXTENSIONS");
+ public static final UnicodeBlock IPA_EXTENSIONS = new UnicodeBlock("IPA_EXTENSIONS", 0x250, 0x2af);
/**
- * The "Spacing Modifier Letters" Unicode Block.
+ * The "Spacing Modifier Letters" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock SPACING_MODIFIER_LETTERS = new UnicodeBlock("SPACING_MODIFIER_LETTERS");
+ public static final UnicodeBlock SPACING_MODIFIER_LETTERS = new UnicodeBlock("SPACING_MODIFIER_LETTERS", 0x2b0, 0x2ff);
/**
- * The "Combining Diacritical Marks" Unicode Block.
+ * The "Combining Diacritical Marks" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS = new UnicodeBlock("COMBINING_DIACRITICAL_MARKS");
+ public static final UnicodeBlock COMBINING_DIACRITICAL_MARKS = new UnicodeBlock("COMBINING_DIACRITICAL_MARKS", 0x300, 0x36f);
/**
* The "Greek and Coptic" Unicode Block. Previously referred
* to as "Greek".
- *
- * @since Android 1.0
- */
- public static final UnicodeBlock GREEK = new UnicodeBlock("GREEK");
- /**
- * The "Cyrillic" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CYRILLIC = new UnicodeBlock("CYRILLIC");
+ public static final UnicodeBlock GREEK = new UnicodeBlock("GREEK", 0x370, 0x3ff);
+ /**
+ * The "Cyrillic" Unicode Block.
+ *
+ * @since 1.2
+ */
+ public static final UnicodeBlock CYRILLIC = new UnicodeBlock("CYRILLIC", 0x400, 0x4ff);
/**
* The "Cyrillic Supplement" Unicode Block. Previously
* referred to as "Cyrillic Supplementary".
- *
- * @since Android 1.0
- */
- public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY = new UnicodeBlock("CYRILLIC_SUPPLEMENTARY");
- /**
- * The "Armenian" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock ARMENIAN = new UnicodeBlock("ARMENIAN");
+ public static final UnicodeBlock CYRILLIC_SUPPLEMENTARY = new UnicodeBlock("CYRILLIC_SUPPLEMENTARY", 0x500, 0x52f);
/**
- * The "Hebrew" Unicode Block.
+ * The "Armenian" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock HEBREW = new UnicodeBlock("HEBREW");
+ public static final UnicodeBlock ARMENIAN = new UnicodeBlock("ARMENIAN", 0x530, 0x58f);
/**
- * The "Arabic" Unicode Block.
+ * The "Hebrew" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ARABIC = new UnicodeBlock("ARABIC");
+ public static final UnicodeBlock HEBREW = new UnicodeBlock("HEBREW", 0x590, 0x5ff);
/**
- * The "Syriac" Unicode Block.
+ * The "Arabic" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock SYRIAC = new UnicodeBlock("SYRIAC");
+ public static final UnicodeBlock ARABIC = new UnicodeBlock("ARABIC", 0x600, 0x6ff);
/**
- * The "Thaana" Unicode Block.
+ * The "Syriac" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock THAANA = new UnicodeBlock("THAANA");
+ public static final UnicodeBlock SYRIAC = new UnicodeBlock("SYRIAC", 0x700, 0x74f);
/**
- * The "Devanagari" Unicode Block.
+ * The "Thaana" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock DEVANAGARI = new UnicodeBlock("DEVANAGARI");
+ public static final UnicodeBlock THAANA = new UnicodeBlock("THAANA", 0x780, 0x7bf);
/**
- * The "Bengali" Unicode Block.
+ * The "Devanagari" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock BENGALI = new UnicodeBlock("BENGALI");
+ public static final UnicodeBlock DEVANAGARI = new UnicodeBlock("DEVANAGARI", 0x900, 0x97f);
/**
- * The "Gurmukhi" Unicode Block.
+ * The "Bengali" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock GURMUKHI = new UnicodeBlock("GURMUKHI");
+ public static final UnicodeBlock BENGALI = new UnicodeBlock("BENGALI", 0x980, 0x9ff);
/**
- * The "Gujarati" Unicode Block.
+ * The "Gurmukhi" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock GUJARATI = new UnicodeBlock("GUJARATI");
+ public static final UnicodeBlock GURMUKHI = new UnicodeBlock("GURMUKHI", 0xa00, 0xa7f);
/**
- * The "Oriya" Unicode Block.
+ * The "Gujarati" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ORIYA = new UnicodeBlock("ORIYA");
+ public static final UnicodeBlock GUJARATI = new UnicodeBlock("GUJARATI", 0xa80, 0xaff);
/**
- * The "Tamil" Unicode Block.
+ * The "Oriya" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock TAMIL = new UnicodeBlock("TAMIL");
+ public static final UnicodeBlock ORIYA = new UnicodeBlock("ORIYA", 0xb00, 0xb7f);
/**
- * The "Telugu" Unicode Block.
+ * The "Tamil" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock TELUGU = new UnicodeBlock("TELUGU");
+ public static final UnicodeBlock TAMIL = new UnicodeBlock("TAMIL", 0xb80, 0xbff);
/**
- * The "Kannada" Unicode Block.
+ * The "Telugu" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock KANNADA = new UnicodeBlock("KANNADA");
+ public static final UnicodeBlock TELUGU = new UnicodeBlock("TELUGU", 0xc00, 0xc7f);
/**
- * The "Malayalam" Unicode Block.
+ * The "Kannada" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock MALAYALAM = new UnicodeBlock("MALAYALAM");
+ public static final UnicodeBlock KANNADA = new UnicodeBlock("KANNADA", 0xc80, 0xcff);
/**
- * The "Sinhala" Unicode Block.
+ * The "Malayalam" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock SINHALA = new UnicodeBlock("SINHALA");
+ public static final UnicodeBlock MALAYALAM = new UnicodeBlock("MALAYALAM", 0xd00, 0xd7f);
/**
- * The "Thai" Unicode Block.
+ * The "Sinhala" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock THAI = new UnicodeBlock("THAI");
+ public static final UnicodeBlock SINHALA = new UnicodeBlock("SINHALA", 0xd80, 0xdff);
/**
- * The "Lao" Unicode Block.
+ * The "Thai" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock LAO = new UnicodeBlock("LAO");
+ public static final UnicodeBlock THAI = new UnicodeBlock("THAI", 0xe00, 0xe7f);
/**
- * The "Tibetan" Unicode Block.
+ * The "Lao" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock TIBETAN = new UnicodeBlock("TIBETAN");
+ public static final UnicodeBlock LAO = new UnicodeBlock("LAO", 0xe80, 0xeff);
/**
- * The "Myanmar" Unicode Block.
+ * The "Tibetan" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock MYANMAR = new UnicodeBlock("MYANMAR");
+ public static final UnicodeBlock TIBETAN = new UnicodeBlock("TIBETAN", 0xf00, 0xfff);
/**
- * The "Georgian" Unicode Block.
+ * The "Myanmar" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock GEORGIAN = new UnicodeBlock("GEORGIAN");
+ public static final UnicodeBlock MYANMAR = new UnicodeBlock("MYANMAR", 0x1000, 0x109f);
/**
- * The "Hangul Jamo" Unicode Block.
+ * The "Georgian" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock HANGUL_JAMO = new UnicodeBlock("HANGUL_JAMO");
+ public static final UnicodeBlock GEORGIAN = new UnicodeBlock("GEORGIAN", 0x10a0, 0x10ff);
/**
- * The "Ethiopic" Unicode Block.
+ * The "Hangul Jamo" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ETHIOPIC = new UnicodeBlock("ETHIOPIC");
+ public static final UnicodeBlock HANGUL_JAMO = new UnicodeBlock("HANGUL_JAMO", 0x1100, 0x11ff);
/**
- * The "Cherokee" Unicode Block.
+ * The "Ethiopic" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock CHEROKEE = new UnicodeBlock("CHEROKEE");
+ public static final UnicodeBlock ETHIOPIC = new UnicodeBlock("ETHIOPIC", 0x1200, 0x137f);
/**
- * The "Unified Canadian Aboriginal Syllabics" Unicode Block.
+ * The "Cherokee" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS");
+ public static final UnicodeBlock CHEROKEE = new UnicodeBlock("CHEROKEE", 0x13a0, 0x13ff);
/**
- * The "Ogham" Unicode Block.
+ * The "Unified Canadian Aboriginal Syllabics" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock OGHAM = new UnicodeBlock("OGHAM");
+ public static final UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS = new UnicodeBlock("UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS", 0x1400, 0x167f);
/**
- * The "Runic" Unicode Block.
+ * The "Ogham" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock RUNIC = new UnicodeBlock("RUNIC");
+ public static final UnicodeBlock OGHAM = new UnicodeBlock("OGHAM", 0x1680, 0x169f);
/**
- * The "Tagalog" Unicode Block.
+ * The "Runic" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock TAGALOG = new UnicodeBlock("TAGALOG");
+ public static final UnicodeBlock RUNIC = new UnicodeBlock("RUNIC", 0x16a0, 0x16ff);
/**
- * The "Hanunoo" Unicode Block.
+ * The "Tagalog" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock HANUNOO = new UnicodeBlock("HANUNOO");
+ public static final UnicodeBlock TAGALOG = new UnicodeBlock("TAGALOG", 0x1700, 0x171f);
/**
- * The "Buhid" Unicode Block.
+ * The "Hanunoo" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock BUHID = new UnicodeBlock("BUHID");
+ public static final UnicodeBlock HANUNOO = new UnicodeBlock("HANUNOO", 0x1720, 0x173f);
/**
- * The "Tagbanwa" Unicode Block.
+ * The "Buhid" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock TAGBANWA = new UnicodeBlock("TAGBANWA");
+ public static final UnicodeBlock BUHID = new UnicodeBlock("BUHID", 0x1740, 0x175f);
/**
- * The "Khmer" Unicode Block.
+ * The "Tagbanwa" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock KHMER = new UnicodeBlock("KHMER");
+ public static final UnicodeBlock TAGBANWA = new UnicodeBlock("TAGBANWA", 0x1760, 0x177f);
/**
- * The "Mongolian" Unicode Block.
+ * The "Khmer" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock MONGOLIAN = new UnicodeBlock("MONGOLIAN");
+ public static final UnicodeBlock KHMER = new UnicodeBlock("KHMER", 0x1780, 0x17ff);
/**
- * The "Limbu" Unicode Block.
+ * The "Mongolian" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock LIMBU = new UnicodeBlock("LIMBU");
+ public static final UnicodeBlock MONGOLIAN = new UnicodeBlock("MONGOLIAN", 0x1800, 0x18af);
/**
- * The "Tai Le" Unicode Block.
+ * The "Limbu" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock TAI_LE = new UnicodeBlock("TAI_LE");
+ public static final UnicodeBlock LIMBU = new UnicodeBlock("LIMBU", 0x1900, 0x194f);
/**
- * The "Khmer Symbols" Unicode Block.
+ * The "Tai Le" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock KHMER_SYMBOLS = new UnicodeBlock("KHMER_SYMBOLS");
+ public static final UnicodeBlock TAI_LE = new UnicodeBlock("TAI_LE", 0x1950, 0x197f);
/**
- * The "Phonetic Extensions" Unicode Block.
+ * The "Khmer Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock PHONETIC_EXTENSIONS = new UnicodeBlock("PHONETIC_EXTENSIONS");
+ public static final UnicodeBlock KHMER_SYMBOLS = new UnicodeBlock("KHMER_SYMBOLS", 0x19e0, 0x19ff);
/**
- * The "Latin Extended Additional" Unicode Block.
+ * The "Phonetic Extensions" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL = new UnicodeBlock("LATIN_EXTENDED_ADDITIONAL");
+ public static final UnicodeBlock PHONETIC_EXTENSIONS = new UnicodeBlock("PHONETIC_EXTENSIONS", 0x1d00, 0x1d7f);
/**
- * The "Greek Extended" Unicode Block.
+ * The "Latin Extended Additional" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock GREEK_EXTENDED = new UnicodeBlock("GREEK_EXTENDED");
+ public static final UnicodeBlock LATIN_EXTENDED_ADDITIONAL = new UnicodeBlock("LATIN_EXTENDED_ADDITIONAL", 0x1e00, 0x1eff);
/**
- * The "General Punctuation" Unicode Block.
+ * The "Greek Extended" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock GENERAL_PUNCTUATION = new UnicodeBlock("GENERAL_PUNCTUATION");
+ public static final UnicodeBlock GREEK_EXTENDED = new UnicodeBlock("GREEK_EXTENDED", 0x1f00, 0x1fff);
/**
- * The "Superscripts and Subscripts" Unicode Block.
+ * The "General Punctuation" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS = new UnicodeBlock("SUPERSCRIPTS_AND_SUBSCRIPTS");
+ public static final UnicodeBlock GENERAL_PUNCTUATION = new UnicodeBlock("GENERAL_PUNCTUATION", 0x2000, 0x206f);
/**
- * The "Currency Symbols" Unicode Block.
+ * The "Superscripts and Subscripts" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CURRENCY_SYMBOLS = new UnicodeBlock("CURRENCY_SYMBOLS");
+ public static final UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS = new UnicodeBlock("SUPERSCRIPTS_AND_SUBSCRIPTS", 0x2070, 0x209f);
+ /**
+ * The "Currency Symbols" Unicode Block.
+ *
+ * @since 1.2
+ */
+ public static final UnicodeBlock CURRENCY_SYMBOLS = new UnicodeBlock("CURRENCY_SYMBOLS", 0x20a0, 0x20cf);
/**
* The "Combining Diacritical Marks for Symbols" Unicode
* Block. Previously referred to as "Combining Marks for
* Symbols".
- *
- * @since Android 1.0
- */
- public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS = new UnicodeBlock("COMBINING_MARKS_FOR_SYMBOLS");
- /**
- * The "Letterlike Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock LETTERLIKE_SYMBOLS = new UnicodeBlock("LETTERLIKE_SYMBOLS");
+ public static final UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS = new UnicodeBlock("COMBINING_MARKS_FOR_SYMBOLS", 0x20d0, 0x20ff);
/**
- * The "Number Forms" Unicode Block.
+ * The "Letterlike Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock NUMBER_FORMS = new UnicodeBlock("NUMBER_FORMS");
+ public static final UnicodeBlock LETTERLIKE_SYMBOLS = new UnicodeBlock("LETTERLIKE_SYMBOLS", 0x2100, 0x214f);
/**
- * The "Arrows" Unicode Block.
+ * The "Number Forms" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ARROWS = new UnicodeBlock("ARROWS");
+ public static final UnicodeBlock NUMBER_FORMS = new UnicodeBlock("NUMBER_FORMS", 0x2150, 0x218f);
/**
- * The "Mathematical Operators" Unicode Block.
+ * The "Arrows" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock MATHEMATICAL_OPERATORS = new UnicodeBlock("MATHEMATICAL_OPERATORS");
+ public static final UnicodeBlock ARROWS = new UnicodeBlock("ARROWS", 0x2190, 0x21ff);
/**
- * The "Miscellaneous Technical" Unicode Block.
+ * The "Mathematical Operators" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock MISCELLANEOUS_TECHNICAL = new UnicodeBlock("MISCELLANEOUS_TECHNICAL");
+ public static final UnicodeBlock MATHEMATICAL_OPERATORS = new UnicodeBlock("MATHEMATICAL_OPERATORS", 0x2200, 0x22ff);
/**
- * The "Control Pictures" Unicode Block.
+ * The "Miscellaneous Technical" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CONTROL_PICTURES = new UnicodeBlock("CONTROL_PICTURES");
+ public static final UnicodeBlock MISCELLANEOUS_TECHNICAL = new UnicodeBlock("MISCELLANEOUS_TECHNICAL", 0x2300, 0x23ff);
/**
- * The "Optical Character Recognition" Unicode Block.
+ * The "Control Pictures" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION = new UnicodeBlock("OPTICAL_CHARACTER_RECOGNITION");
+ public static final UnicodeBlock CONTROL_PICTURES = new UnicodeBlock("CONTROL_PICTURES", 0x2400, 0x243f);
/**
- * The "Enclosed Alphanumerics" Unicode Block.
+ * The "Optical Character Recognition" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ENCLOSED_ALPHANUMERICS = new UnicodeBlock("ENCLOSED_ALPHANUMERICS");
+ public static final UnicodeBlock OPTICAL_CHARACTER_RECOGNITION = new UnicodeBlock("OPTICAL_CHARACTER_RECOGNITION", 0x2440, 0x245f);
/**
- * The "Box Drawing" Unicode Block.
+ * The "Enclosed Alphanumerics" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock BOX_DRAWING = new UnicodeBlock("BOX_DRAWING");
+ public static final UnicodeBlock ENCLOSED_ALPHANUMERICS = new UnicodeBlock("ENCLOSED_ALPHANUMERICS", 0x2460, 0x24ff);
/**
- * The "Block Elements" Unicode Block.
+ * The "Box Drawing" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock BLOCK_ELEMENTS = new UnicodeBlock("BLOCK_ELEMENTS");
+ public static final UnicodeBlock BOX_DRAWING = new UnicodeBlock("BOX_DRAWING", 0x2500, 0x257f);
/**
- * The "Geometric Shapes" Unicode Block.
+ * The "Block Elements" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock GEOMETRIC_SHAPES = new UnicodeBlock("GEOMETRIC_SHAPES");
+ public static final UnicodeBlock BLOCK_ELEMENTS = new UnicodeBlock("BLOCK_ELEMENTS", 0x2580, 0x259f);
/**
- * The "Miscellaneous Symbols" Unicode Block.
+ * The "Geometric Shapes" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock MISCELLANEOUS_SYMBOLS = new UnicodeBlock("MISCELLANEOUS_SYMBOLS");
+ public static final UnicodeBlock GEOMETRIC_SHAPES = new UnicodeBlock("GEOMETRIC_SHAPES", 0x25a0, 0x25ff);
/**
- * The "Dingbats" Unicode Block.
+ * The "Miscellaneous Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock DINGBATS = new UnicodeBlock("DINGBATS");
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS = new UnicodeBlock("MISCELLANEOUS_SYMBOLS", 0x2600, 0x26ff);
/**
- * The "Miscellaneous Mathematical Symbols-A" Unicode Block.
+ * The "Dingbats" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A");
+ public static final UnicodeBlock DINGBATS = new UnicodeBlock("DINGBATS", 0x2700, 0x27bf);
/**
- * The "Supplemental Arrows-A" Unicode Block.
+ * The "Miscellaneous Mathematical Symbols-A" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A = new UnicodeBlock("SUPPLEMENTAL_ARROWS_A");
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A = new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A", 0x27c0, 0x27ef);
/**
- * The "Braille Patterns" Unicode Block.
+ * The "Supplemental Arrows-A" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock BRAILLE_PATTERNS = new UnicodeBlock("BRAILLE_PATTERNS");
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_A = new UnicodeBlock("SUPPLEMENTAL_ARROWS_A", 0x27f0, 0x27ff);
/**
- * The "Supplemental Arrows-B" Unicode Block.
+ * The "Braille Patterns" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B = new UnicodeBlock("SUPPLEMENTAL_ARROWS_B");
+ public static final UnicodeBlock BRAILLE_PATTERNS = new UnicodeBlock("BRAILLE_PATTERNS", 0x2800, 0x28ff);
/**
- * The "Miscellaneous Mathematical Symbols-B" Unicode Block.
+ * The "Supplemental Arrows-B" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B");
+ public static final UnicodeBlock SUPPLEMENTAL_ARROWS_B = new UnicodeBlock("SUPPLEMENTAL_ARROWS_B", 0x2900, 0x297f);
/**
- * The "Supplemental Mathematical Operators" Unicode Block.
+ * The "Miscellaneous Mathematical Symbols-B" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS = new UnicodeBlock("SUPPLEMENTAL_MATHEMATICAL_OPERATORS");
+ public static final UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B = new UnicodeBlock("MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B", 0x2980, 0x29ff);
/**
- * The "Miscellaneous Symbols and Arrows" Unicode Block.
+ * The "Supplemental Mathematical Operators" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS = new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_ARROWS");
+ public static final UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS = new UnicodeBlock("SUPPLEMENTAL_MATHEMATICAL_OPERATORS", 0x2a00, 0x2aff);
/**
- * The "CJK Radicals Supplement" Unicode Block.
+ * The "Miscellaneous Symbols and Arrows" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT = new UnicodeBlock("CJK_RADICALS_SUPPLEMENT");
+ public static final UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS = new UnicodeBlock("MISCELLANEOUS_SYMBOLS_AND_ARROWS", 0x2b00, 0x2bff);
/**
- * The "Kangxi Radicals" Unicode Block.
+ * The "CJK Radicals Supplement" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock KANGXI_RADICALS = new UnicodeBlock("KANGXI_RADICALS");
+ public static final UnicodeBlock CJK_RADICALS_SUPPLEMENT = new UnicodeBlock("CJK_RADICALS_SUPPLEMENT", 0x2e80, 0x2eff);
/**
- * The "Ideographic Description Characters" Unicode Block.
+ * The "Kangxi Radicals" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS = new UnicodeBlock("IDEOGRAPHIC_DESCRIPTION_CHARACTERS");
+ public static final UnicodeBlock KANGXI_RADICALS = new UnicodeBlock("KANGXI_RADICALS", 0x2f00, 0x2fdf);
/**
- * The "CJK Symbols and Punctuation" Unicode Block.
+ * The "Ideographic Description Characters" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION = new UnicodeBlock("CJK_SYMBOLS_AND_PUNCTUATION");
+ public static final UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS = new UnicodeBlock("IDEOGRAPHIC_DESCRIPTION_CHARACTERS", 0x2ff0, 0x2fff);
/**
- * The "Hiragana" Unicode Block.
+ * The "CJK Symbols and Punctuation" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock HIRAGANA = new UnicodeBlock("HIRAGANA");
+ public static final UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION = new UnicodeBlock("CJK_SYMBOLS_AND_PUNCTUATION", 0x3000, 0x303f);
/**
- * The "Katakana" Unicode Block.
+ * The "Hiragana" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock KATAKANA = new UnicodeBlock("KATAKANA");
+ public static final UnicodeBlock HIRAGANA = new UnicodeBlock("HIRAGANA", 0x3040, 0x309f);
/**
- * The "Bopomofo" Unicode Block.
+ * The "Katakana" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock BOPOMOFO = new UnicodeBlock("BOPOMOFO");
+ public static final UnicodeBlock KATAKANA = new UnicodeBlock("KATAKANA", 0x30a0, 0x30ff);
/**
- * The "Hangul Compatibility Jamo" Unicode Block.
+ * The "Bopomofo" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO = new UnicodeBlock("HANGUL_COMPATIBILITY_JAMO");
+ public static final UnicodeBlock BOPOMOFO = new UnicodeBlock("BOPOMOFO", 0x3100, 0x312f);
/**
- * The "Kanbun" Unicode Block.
+ * The "Hangul Compatibility Jamo" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock KANBUN = new UnicodeBlock("KANBUN");
+ public static final UnicodeBlock HANGUL_COMPATIBILITY_JAMO = new UnicodeBlock("HANGUL_COMPATIBILITY_JAMO", 0x3130, 0x318f);
/**
- * The "Bopomofo Extended" Unicode Block.
+ * The "Kanbun" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock BOPOMOFO_EXTENDED = new UnicodeBlock("BOPOMOFO_EXTENDED");
+ public static final UnicodeBlock KANBUN = new UnicodeBlock("KANBUN", 0x3190, 0x319f);
/**
- * The "Katakana Phonetic Extensions" Unicode Block.
+ * The "Bopomofo Extended" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS = new UnicodeBlock("KATAKANA_PHONETIC_EXTENSIONS");
+ public static final UnicodeBlock BOPOMOFO_EXTENDED = new UnicodeBlock("BOPOMOFO_EXTENDED", 0x31a0, 0x31bf);
/**
- * The "Enclosed CJK Letters and Months" Unicode Block.
+ * The "Katakana Phonetic Extensions" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS = new UnicodeBlock("ENCLOSED_CJK_LETTERS_AND_MONTHS");
+ public static final UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS = new UnicodeBlock("KATAKANA_PHONETIC_EXTENSIONS", 0x31f0, 0x31ff);
/**
- * The "CJK Compatibility" Unicode Block.
+ * The "Enclosed CJK Letters and Months" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CJK_COMPATIBILITY = new UnicodeBlock("CJK_COMPATIBILITY");
+ public static final UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS = new UnicodeBlock("ENCLOSED_CJK_LETTERS_AND_MONTHS", 0x3200, 0x32ff);
/**
- * The "CJK Unified Ideographs Extension A" Unicode Block.
+ * The "CJK Compatibility" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A");
+ public static final UnicodeBlock CJK_COMPATIBILITY = new UnicodeBlock("CJK_COMPATIBILITY", 0x3300, 0x33ff);
/**
- * The "Yijing Hexagram Symbols" Unicode Block.
+ * The "CJK Unified Ideographs Extension A" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS = new UnicodeBlock("YIJING_HEXAGRAM_SYMBOLS");
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A = new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A", 0x3400, 0x4dbf);
/**
- * The "CJK Unified Ideographs" Unicode Block.
+ * The "Yijing Hexagram Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS = new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS");
+ public static final UnicodeBlock YIJING_HEXAGRAM_SYMBOLS = new UnicodeBlock("YIJING_HEXAGRAM_SYMBOLS", 0x4dc0, 0x4dff);
/**
- * The "Yi Syllables" Unicode Block.
+ * The "CJK Unified Ideographs" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock YI_SYLLABLES = new UnicodeBlock("YI_SYLLABLES");
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS = new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS", 0x4e00, 0x9fff);
/**
- * The "Yi Radicals" Unicode Block.
+ * The "Yi Syllables" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock YI_RADICALS = new UnicodeBlock("YI_RADICALS");
+ public static final UnicodeBlock YI_SYLLABLES = new UnicodeBlock("YI_SYLLABLES", 0xa000, 0xa48f);
/**
- * The "Hangul Syllables" Unicode Block.
+ * The "Yi Radicals" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.4
*/
- public static final UnicodeBlock HANGUL_SYLLABLES = new UnicodeBlock("HANGUL_SYLLABLES");
+ public static final UnicodeBlock YI_RADICALS = new UnicodeBlock("YI_RADICALS", 0xa490, 0xa4cf);
+ /**
+ * The "Hangul Syllables" Unicode Block.
+ *
+ * @since 1.2
+ */
+ public static final UnicodeBlock HANGUL_SYLLABLES = new UnicodeBlock("HANGUL_SYLLABLES", 0xac00, 0xd7af);
/**
* The "High Surrogates" Unicode Block. This block represents
* code point values in the high surrogate range 0xD800 to 0xDB7F
- *
- * @since Android 1.0
*/
- public static final UnicodeBlock HIGH_SURROGATES = new UnicodeBlock("HIGH_SURROGATES");
+ public static final UnicodeBlock HIGH_SURROGATES = new UnicodeBlock("HIGH_SURROGATES", 0xd800, 0xdb7f);
/**
* The "High Private Use Surrogates" Unicode Block. This block
* represents code point values in the high surrogate range 0xDB80 to
* 0xDBFF
- *
- * @since Android 1.0
*/
- public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES = new UnicodeBlock("HIGH_PRIVATE_USE_SURROGATES");
+ public static final UnicodeBlock HIGH_PRIVATE_USE_SURROGATES = new UnicodeBlock("HIGH_PRIVATE_USE_SURROGATES", 0xdb80, 0xdbff);
/**
* The "Low Surrogates" Unicode Block. This block represents
* code point values in the low surrogate range 0xDC00 to 0xDFFF
- *
- * @since Android 1.0
*/
- public static final UnicodeBlock LOW_SURROGATES = new UnicodeBlock("LOW_SURROGATES");
+ public static final UnicodeBlock LOW_SURROGATES = new UnicodeBlock("LOW_SURROGATES", 0xdc00, 0xdfff);
/**
- * The "Private Use Area" Unicode Block.
+ * The "Private Use Area" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock PRIVATE_USE_AREA = new UnicodeBlock("PRIVATE_USE_AREA");
+ public static final UnicodeBlock PRIVATE_USE_AREA = new UnicodeBlock("PRIVATE_USE_AREA", 0xe000, 0xf8ff);
/**
- * The "CJK Compatibility Ideographs" Unicode Block.
+ * The "CJK Compatibility Ideographs" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS = new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS");
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS = new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS", 0xf900, 0xfaff);
/**
- * The "Alphabetic Presentation Forms" Unicode Block.
+ * The "Alphabetic Presentation Forms" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS = new UnicodeBlock("ALPHABETIC_PRESENTATION_FORMS");
+ public static final UnicodeBlock ALPHABETIC_PRESENTATION_FORMS = new UnicodeBlock("ALPHABETIC_PRESENTATION_FORMS", 0xfb00, 0xfb4f);
/**
- * The "Arabic Presentation Forms-A" Unicode Block.
+ * The "Arabic Presentation Forms-A" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A = new UnicodeBlock("ARABIC_PRESENTATION_FORMS_A");
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_A = new UnicodeBlock("ARABIC_PRESENTATION_FORMS_A", 0xfb50, 0xfdff);
/**
- * The "Variation Selectors" Unicode Block.
+ * The "Variation Selectors" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock VARIATION_SELECTORS = new UnicodeBlock("VARIATION_SELECTORS");
+ public static final UnicodeBlock VARIATION_SELECTORS = new UnicodeBlock("VARIATION_SELECTORS", 0xfe00, 0xfe0f);
/**
- * The "Combining Half Marks" Unicode Block.
+ * The "Combining Half Marks" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock COMBINING_HALF_MARKS = new UnicodeBlock("COMBINING_HALF_MARKS");
+ public static final UnicodeBlock COMBINING_HALF_MARKS = new UnicodeBlock("COMBINING_HALF_MARKS", 0xfe20, 0xfe2f);
/**
- * The "CJK Compatibility Forms" Unicode Block.
+ * The "CJK Compatibility Forms" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock CJK_COMPATIBILITY_FORMS = new UnicodeBlock("CJK_COMPATIBILITY_FORMS");
+ public static final UnicodeBlock CJK_COMPATIBILITY_FORMS = new UnicodeBlock("CJK_COMPATIBILITY_FORMS", 0xfe30, 0xfe4f);
/**
- * The "Small Form Variants" Unicode Block.
+ * The "Small Form Variants" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock SMALL_FORM_VARIANTS = new UnicodeBlock("SMALL_FORM_VARIANTS");
+ public static final UnicodeBlock SMALL_FORM_VARIANTS = new UnicodeBlock("SMALL_FORM_VARIANTS", 0xfe50, 0xfe6f);
/**
- * The "Arabic Presentation Forms-B" Unicode Block.
+ * The "Arabic Presentation Forms-B" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B = new UnicodeBlock("ARABIC_PRESENTATION_FORMS_B");
+ public static final UnicodeBlock ARABIC_PRESENTATION_FORMS_B = new UnicodeBlock("ARABIC_PRESENTATION_FORMS_B", 0xfe70, 0xfeff);
/**
- * The "Halfwidth and Fullwidth Forms" Unicode Block.
+ * The "Halfwidth and Fullwidth Forms" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS = new UnicodeBlock("HALFWIDTH_AND_FULLWIDTH_FORMS");
+ public static final UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS = new UnicodeBlock("HALFWIDTH_AND_FULLWIDTH_FORMS", 0xff00, 0xffef);
/**
- * The "Specials" Unicode Block.
+ * The "Specials" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock SPECIALS = new UnicodeBlock("SPECIALS");
+ public static final UnicodeBlock SPECIALS = new UnicodeBlock("SPECIALS", 0xfff0, 0xffff);
/**
- * The "Linear B Syllabary" Unicode Block.
+ * The "Linear B Syllabary" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.2
*/
- public static final UnicodeBlock LINEAR_B_SYLLABARY = new UnicodeBlock("LINEAR_B_SYLLABARY");
+ public static final UnicodeBlock LINEAR_B_SYLLABARY = new UnicodeBlock("LINEAR_B_SYLLABARY", 0x10000, 0x1007f);
/**
- * The "Linear B Ideograms" Unicode Block.
+ * The "Linear B Ideograms" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock LINEAR_B_IDEOGRAMS = new UnicodeBlock("LINEAR_B_IDEOGRAMS");
+ public static final UnicodeBlock LINEAR_B_IDEOGRAMS = new UnicodeBlock("LINEAR_B_IDEOGRAMS", 0x10080, 0x100ff);
/**
- * The "Aegean Numbers" Unicode Block.
+ * The "Aegean Numbers" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock AEGEAN_NUMBERS = new UnicodeBlock("AEGEAN_NUMBERS");
+ public static final UnicodeBlock AEGEAN_NUMBERS = new UnicodeBlock("AEGEAN_NUMBERS", 0x10100, 0x1013f);
/**
- * The "Old Italic" Unicode Block.
+ * The "Old Italic" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock OLD_ITALIC = new UnicodeBlock("OLD_ITALIC");
+ public static final UnicodeBlock OLD_ITALIC = new UnicodeBlock("OLD_ITALIC", 0x10300, 0x1032f);
/**
- * The "Gothic" Unicode Block.
+ * The "Gothic" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock GOTHIC = new UnicodeBlock("GOTHIC");
+ public static final UnicodeBlock GOTHIC = new UnicodeBlock("GOTHIC", 0x10330, 0x1034f);
/**
- * The "Ugaritic" Unicode Block.
+ * The "Ugaritic" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock UGARITIC = new UnicodeBlock("UGARITIC");
+ public static final UnicodeBlock UGARITIC = new UnicodeBlock("UGARITIC", 0x10380, 0x1039f);
/**
- * The "Deseret" Unicode Block.
+ * The "Deseret" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock DESERET = new UnicodeBlock("DESERET");
+ public static final UnicodeBlock DESERET = new UnicodeBlock("DESERET", 0x10400, 0x1044f);
/**
- * The "Shavian" Unicode Block.
+ * The "Shavian" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock SHAVIAN = new UnicodeBlock("SHAVIAN");
+ public static final UnicodeBlock SHAVIAN = new UnicodeBlock("SHAVIAN", 0x10450, 0x1047f);
/**
- * The "Osmanya" Unicode Block.
+ * The "Osmanya" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock OSMANYA = new UnicodeBlock("OSMANYA");
+ public static final UnicodeBlock OSMANYA = new UnicodeBlock("OSMANYA", 0x10480, 0x104af);
/**
- * The "Cypriot Syllabary" Unicode Block.
+ * The "Cypriot Syllabary" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock CYPRIOT_SYLLABARY = new UnicodeBlock("CYPRIOT_SYLLABARY");
+ public static final UnicodeBlock CYPRIOT_SYLLABARY = new UnicodeBlock("CYPRIOT_SYLLABARY", 0x10800, 0x1083f);
/**
- * The "Byzantine Musical Symbols" Unicode Block.
+ * The "Byzantine Musical Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS = new UnicodeBlock("BYZANTINE_MUSICAL_SYMBOLS");
+ public static final UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS = new UnicodeBlock("BYZANTINE_MUSICAL_SYMBOLS", 0x1d000, 0x1d0ff);
/**
- * The "Musical Symbols" Unicode Block.
+ * The "Musical Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock MUSICAL_SYMBOLS = new UnicodeBlock("MUSICAL_SYMBOLS");
+ public static final UnicodeBlock MUSICAL_SYMBOLS = new UnicodeBlock("MUSICAL_SYMBOLS", 0x1d100, 0x1d1ff);
/**
- * The "Tai Xuan Jing Symbols" Unicode Block.
+ * The "Tai Xuan Jing Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS = new UnicodeBlock("TAI_XUAN_JING_SYMBOLS");
+ public static final UnicodeBlock TAI_XUAN_JING_SYMBOLS = new UnicodeBlock("TAI_XUAN_JING_SYMBOLS", 0x1d300, 0x1d35f);
/**
- * The "Mathematical Alphanumeric Symbols" Unicode Block.
+ * The "Mathematical Alphanumeric Symbols" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS = new UnicodeBlock("MATHEMATICAL_ALPHANUMERIC_SYMBOLS");
+ public static final UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS = new UnicodeBlock("MATHEMATICAL_ALPHANUMERIC_SYMBOLS", 0x1d400, 0x1d7ff);
/**
- * The "CJK Unified Ideographs Extension B" Unicode Block.
+ * The "CJK Unified Ideographs Extension B" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B");
+ public static final UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B = new UnicodeBlock("CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B", 0x20000, 0x2a6df);
/**
- * The "CJK Compatibility Ideographs Supplement" Unicode Block.
+ * The "CJK Compatibility Ideographs Supplement" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT");
+ public static final UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT = new UnicodeBlock("CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT", 0x2f800, 0x2fa1f);
/**
- * The "Tags" Unicode Block.
+ * The "Tags" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock TAGS = new UnicodeBlock("TAGS");
+ public static final UnicodeBlock TAGS = new UnicodeBlock("TAGS", 0xe0000, 0xe007f);
/**
- * The "Variation Selectors Supplement" Unicode Block.
+ * The "Variation Selectors Supplement" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT = new UnicodeBlock("VARIATION_SELECTORS_SUPPLEMENT");
+ public static final UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT = new UnicodeBlock("VARIATION_SELECTORS_SUPPLEMENT", 0xe0100, 0xe01ef);
/**
- * The "Supplementary Private Use Area-A" Unicode Block.
+ * The "Supplementary Private Use Area-A" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A = new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_A");
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A = new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_A", 0xf0000, 0xfffff);
/**
- * The "Supplementary Private Use Area-B" Unicode Block.
+ * The "Supplementary Private Use Area-B" Unicode Block.
*
- * @since Android 1.0
+ * @since 1.5
*/
- public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B = new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_B");
+ public static final UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B = new UnicodeBlock("SUPPLEMENTARY_PRIVATE_USE_AREA_B", 0x100000, 0x10ffff);
/*
* All of the UnicodeBlocks with valid ranges in ascending order.
*/
private static UnicodeBlock[] BLOCKS;
+ // BEGIN android-changed
+ // /*
+ // * A SortedMap (String.CASE_INSENSITIVE_ORDER) with keys that represents
+ // * valid block names and values of the UnicodeBlock constant they map
+ // * to.
+ // */
+ // private static final SortedMap<String, UnicodeBlock> BLOCKS_BY_NAME = ...;
// END android-changed
-
+
/**
* Retrieves the constant that corresponds to the specified block name.
* The block names are defined by the Unicode 4.0.1 specification in the
* {@code Blocks-4.0.1.txt} file.
* <p>
* Block names may be one of the following:
- * </p>
* <ul>
* <li>Canonical block name, as defined by the Unicode specification;
* case-insensitive.</li>
@@ -1424,13 +1387,15 @@
* uppercasing the canonical name and replacing all spaces and hyphens
* with underscores.</li>
* </ul>
- *
+ *
* @param blockName
* the name of the block to retrieve.
* @return the UnicodeBlock constant corresponding to {@code blockName}.
+ * @throws NullPointerException
+ * if {@code blockName} is {@code null}.
* @throws IllegalArgumentException
* if {@code blockName} is not a valid block name.
- * @since Android 1.0
+ * @since 1.5
*/
public static final UnicodeBlock forName(String blockName) {
// BEGIN android-note
@@ -1449,7 +1414,7 @@
return SURROGATES_AREA;
} else if(blockName.equalsIgnoreCase("greek")) {
return GREEK;
- } else if(blockName.equals("COMBINING_MARKS_FOR_SYMBOLS") ||
+ } else if(blockName.equals("COMBINING_MARKS_FOR_SYMBOLS") ||
blockName.equals("Combining Marks for Symbols") ||
blockName.equals("CombiningMarksforSymbols")) {
return COMBINING_MARKS_FOR_SYMBOLS;
@@ -1459,27 +1424,26 @@
return BLOCKS[block];
// END android-changed
}
-
+
/**
* Gets the constant for the Unicode block that contains the specified
* character.
- *
+ *
* @param c
* the character for which to get the {@code UnicodeBlock}
* constant.
* @return the {@code UnicodeBlock} constant for the block that contains
* {@code c}, or {@code null} if {@code c} does not belong to
* any defined block.
- * @since Android 1.0
*/
public static UnicodeBlock of(char c) {
return of((int) c);
}
-
+
/**
* Gets the constant for the Unicode block that contains the specified
* Unicode code point.
- *
+ *
* @param codePoint
* the Unicode code point for which to get the
* {@code UnicodeBlock} constant.
@@ -1488,7 +1452,7 @@
* not belong to any defined block.
* @throws IllegalArgumentException
* if {@code codePoint} is not a valid Unicode code point.
- * @since Android 1.0
+ * @since 1.5
*/
public static UnicodeBlock of(int codePoint) {
if (!isValidCodePoint(codePoint)) {
@@ -1505,9 +1469,9 @@
return BLOCKS[block];
// END android-changed
}
-
+
// BEGIN android-changed
- private UnicodeBlock(String blockName) {
+ private UnicodeBlock(String blockName, int start, int end) {
super(blockName);
}
// END android-changed
@@ -1516,10 +1480,9 @@
/**
* Constructs a new {@code Character} with the specified primitive char
* value.
- *
+ *
* @param value
* the primitive char value to store in the new instance.
- * @since Android 1.0
*/
public Character(char value) {
this.value = value;
@@ -1527,9 +1490,8 @@
/**
* Gets the primitive value of this character.
- *
+ *
* @return this object's primitive value.
- * @since Android 1.0
*/
public char charValue() {
return value;
@@ -1538,7 +1500,7 @@
/**
* Compares this object to the specified character object to determine their
* relative order.
- *
+ *
* @param c
* the character object to compare this object to.
* @return {@code 0} if the value of this character and the value of
@@ -1547,22 +1509,22 @@
* value if the value of this character is less than the value of
* {@code c}.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.2
*/
public int compareTo(Character c) {
return value - c.value;
}
-
+
/**
* Returns a {@code Character} instance for the {@code char} value passed.
* For ASCII/Latin-1 characters (and generally all characters with a Unicode
* value up to 512), this method should be used instead of the constructor,
* as it maintains a cache of corresponding {@code Character} instances.
- *
+ *
* @param c
* the char value for which to get a {@code Character} instance.
* @return the {@code Character} instance for {@code c}.
- * @since Android 1.0
+ * @since 1.5
*/
public static Character valueOf(char c) {
if (c >= CACHE_LEN ) {
@@ -1589,12 +1551,12 @@
}
/**
* Indicates whether {@code codePoint} is a valid Unicode code point.
- *
+ *
* @param codePoint
* the code point to test.
* @return {@code true} if {@code codePoint} is a valid Unicode code point;
* {@code false} otherwise.
- * @since Android 1.0
+ * @since 1.5
*/
public static boolean isValidCodePoint(int codePoint) {
return (MIN_CODE_POINT <= codePoint && MAX_CODE_POINT >= codePoint);
@@ -1603,12 +1565,12 @@
/**
* Indicates whether {@code codePoint} is within the supplementary code
* point range.
- *
+ *
* @param codePoint
* the code point to test.
* @return {@code true} if {@code codePoint} is within the supplementary
* code point range; {@code false} otherwise.
- * @since Android 1.0
+ * @since 1.5
*/
public static boolean isSupplementaryCodePoint(int codePoint) {
return (MIN_SUPPLEMENTARY_CODE_POINT <= codePoint && MAX_CODE_POINT >= codePoint);
@@ -1618,13 +1580,13 @@
* Indicates whether {@code ch} is a high- (or leading-) surrogate code unit
* that is used for representing supplementary characters in UTF-16
* encoding.
- *
+ *
* @param ch
* the character to test.
* @return {@code true} if {@code ch} is a high-surrogate code unit;
* {@code false} otherwise.
* @see #isLowSurrogate(char)
- * @since Android 1.0
+ * @since 1.5
*/
public static boolean isHighSurrogate(char ch) {
return (MIN_HIGH_SURROGATE <= ch && MAX_HIGH_SURROGATE >= ch);
@@ -1634,21 +1596,21 @@
* Indicates whether {@code ch} is a low- (or trailing-) surrogate code unit
* that is used for representing supplementary characters in UTF-16
* encoding.
- *
+ *
* @param ch
* the character to test.
* @return {@code true} if {@code ch} is a low-surrogate code unit;
* {@code false} otherwise.
* @see #isHighSurrogate(char)
- * @since Android 1.0
- */
+ * @since 1.5
+ */
public static boolean isLowSurrogate(char ch) {
return (MIN_LOW_SURROGATE <= ch && MAX_LOW_SURROGATE >= ch);
}
/**
* Indicates whether the specified character pair is a valid surrogate pair.
- *
+ *
* @param high
* the high surrogate unit to test.
* @param low
@@ -1658,7 +1620,7 @@
* otherwise.
* @see #isHighSurrogate(char)
* @see #isLowSurrogate(char)
- * @since Android 1.0
+ * @since 1.5
*/
public static boolean isSurrogatePair(char high, char low) {
return (isHighSurrogate(high) && isLowSurrogate(low));
@@ -1670,12 +1632,14 @@
* is greater than or equal to {@code 0x10000}, in which case {@code 2} is
* returned, otherwise {@code 1}. To test if the code point is valid, use
* the {@link #isValidCodePoint(int)} method.
- *
+ *
* @param codePoint
* the code point for which to calculate the number of required
* chars.
* @return {@code 2} if {@code codePoint >= 0x10000}; {@code 1} otherwise.
- * @since Android 1.0
+ * @see #isValidCodePoint(int)
+ * @see #isSupplementaryCodePoint(int)
+ * @since 1.5
*/
public static int charCount(int codePoint) {
return (codePoint >= 0x10000 ? 2 : 1);
@@ -1687,14 +1651,14 @@
* surrogates, then the result is indeterminate. The
* {@link #isSurrogatePair(char, char)} method should be used prior to this
* method to validate the pair.
- *
+ *
* @param high
* the high surrogate unit.
* @param low
* the low surrogate unit.
* @return the Unicode code point corresponding to the surrogate unit pair.
* @see #isSurrogatePair(char, char)
- * @since Android 1.0
+ * @since 1.5
*/
public static int toCodePoint(char high, char low) {
// See RFC 2781, Section 2.2
@@ -1711,7 +1675,7 @@
* {@code index + 1} is a low-surrogate unit, then the supplementary code
* point represented by the pair is returned; otherwise the {@code char}
* value at {@code index} is returned.
- *
+ *
* @param seq
* the source sequence of {@code char} units.
* @param index
@@ -1719,10 +1683,12 @@
* point.
* @return the Unicode code point or {@code char} value at {@code index} in
* {@code seq}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if the {@code index} is negative or greater than or equal to
* the length of {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointAt(CharSequence seq, int index) {
if (seq == null) {
@@ -1751,7 +1717,7 @@
* {@code index + 1} is a low-surrogate unit, then the supplementary code
* point represented by the pair is returned; otherwise the {@code char}
* value at {@code index} is returned.
- *
+ *
* @param seq
* the source array of {@code char} units.
* @param index
@@ -1759,10 +1725,12 @@
* point.
* @return the Unicode code point or {@code char} value at {@code index} in
* {@code seq}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if the {@code index} is negative or greater than or equal to
* the length of {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointAt(char[] seq, int index) {
if (seq == null) {
@@ -1792,7 +1760,7 @@
* low-surrogate unit, then the supplementary code point represented by the
* pair is returned; otherwise the {@code char} value at {@code index} is
* returned.
- *
+ *
* @param seq
* the source array of {@code char} units.
* @param index
@@ -1801,16 +1769,18 @@
* the index after the last unit in {@code seq} that can be used.
* @return the Unicode code point or {@code char} value at {@code index} in
* {@code seq}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code index < 0}, {@code index >= limit},
* {@code limit < 0} or if {@code limit} is greater than the
* length of {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointAt(char[] seq, int index, int limit) {
if (index < 0 || index >= limit || limit < 0 || limit > seq.length) {
throw new IndexOutOfBoundsException();
- }
+ }
char high = seq[index++];
if (index >= limit) {
@@ -1830,7 +1800,7 @@
* {@code index - 2} is a high-surrogate unit, then the supplementary code
* point represented by the pair is returned; otherwise the {@code char}
* value at {@code index - 1} is returned.
- *
+ *
* @param seq
* the source sequence of {@code char} units.
* @param index
@@ -1838,10 +1808,12 @@
* point that should be returned.
* @return the Unicode code point or {@code char} value before {@code index}
* in {@code seq}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if the {@code index} is less than 1 or greater than the
* length of {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointBefore(CharSequence seq, int index) {
if (seq == null) {
@@ -1870,7 +1842,7 @@
* {@code index - 2} is a high-surrogate unit, then the supplementary code
* point represented by the pair is returned; otherwise the {@code char}
* value at {@code index - 1} is returned.
- *
+ *
* @param seq
* the source array of {@code char} units.
* @param index
@@ -1878,10 +1850,12 @@
* point that should be returned.
* @return the Unicode code point or {@code char} value before {@code index}
* in {@code seq}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if the {@code index} is less than 1 or greater than the
* length of {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointBefore(char[] seq, int index) {
if (seq == null) {
@@ -1911,7 +1885,7 @@
* high-surrogate unit, then the supplementary code point represented by the
* pair is returned; otherwise the {@code char} value at {@code index - 1}
* is returned.
- *
+ *
* @param seq
* the source array of {@code char} units.
* @param index
@@ -1921,12 +1895,14 @@
* the index of the first element in {@code seq}.
* @return the Unicode code point or {@code char} value before {@code index}
* in {@code seq}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if the {@code index <= start}, {@code start < 0},
* {@code index} is greater than the length of {@code seq}, or
* if {@code start} is equal or greater than the length of
* {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointBefore(char[] seq, int index, int start) {
if (seq == null) {
@@ -1952,7 +1928,7 @@
* Converts the specified Unicode code point into a UTF-16 encoded sequence
* and copies the value(s) into the char array {@code dst}, starting at
* index {@code dstIndex}.
- *
+ *
* @param codePoint
* the Unicode code point to encode.
* @param dst
@@ -1962,12 +1938,14 @@
* @return the number of {@code char} value units copied into {@code dst}.
* @throws IllegalArgumentException
* if {@code codePoint} is not a valid Unicode code point.
+ * @throws NullPointerException
+ * if {@code dst} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code dstIndex} is negative, greater than or equal to
* {@code dst.length} or equals {@code dst.length - 1} when
* {@code codePoint} is a
* {@link #isSupplementaryCodePoint(int) supplementary code point}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int toChars(int codePoint, char[] dst, int dstIndex) {
if (!isValidCodePoint(codePoint)) {
@@ -2001,7 +1979,7 @@
/**
* Converts the specified Unicode code point into a UTF-16 encoded sequence
* and returns it as a char array.
- *
+ *
* @param codePoint
* the Unicode code point to encode.
* @return the UTF-16 encoded char sequence. If {@code codePoint} is a
@@ -2010,7 +1988,7 @@
* contains just one character.
* @throws IllegalArgumentException
* if {@code codePoint} is not a valid Unicode code point.
- * @since Android 1.0
+ * @since 1.5
*/
public static char[] toChars(int codePoint) {
if (!isValidCodePoint(codePoint)) {
@@ -2031,7 +2009,7 @@
* specified character sequence, as delineated by {@code beginIndex} and
* {@code endIndex}. Any surrogate values with missing pair values will be
* counted as one code point.
- *
+ *
* @param seq
* the {@code CharSequence} to look through.
* @param beginIndex
@@ -2039,10 +2017,12 @@
* @param endIndex
* the exclusive index to stop counting at.
* @return the number of Unicode code points.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code beginIndex < 0}, {@code beginIndex > endIndex} or
* if {@code endIndex} is greater than the length of {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointCount(CharSequence seq, int beginIndex,
int endIndex) {
@@ -2075,7 +2055,7 @@
* specified char array, as delineated by {@code offset} and {@code count}.
* Any surrogate values with missing pair values will be counted as one code
* point.
- *
+ *
* @param seq
* the char array to look through
* @param offset
@@ -2084,11 +2064,13 @@
* the number of {@code char} values to look through in
* {@code seq}.
* @return the number of Unicode code points.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code offset < 0}, {@code count < 0} or if
* {@code offset + count} is greater than the length of
* {@code seq}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int codePointCount(char[] seq, int offset, int count) {
if (seq == null) {
@@ -2119,7 +2101,7 @@
/**
* Determines the index in the specified character sequence that is offset
* {@code codePointOffset} code points from {@code index}.
- *
+ *
* @param seq
* the character sequence to find the index in.
* @param index
@@ -2129,13 +2111,15 @@
* be a negative or positive value.
* @return the index in {@code seq} that is {@code codePointOffset} code
* points away from {@code index}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code index < 0}, {@code index} is greater than the
* length of {@code seq}, or if there are not enough values in
* {@code seq} to skip {@code codePointOffset} code points
* forwards or backwards (if {@code codePointOffset} is
* negative) from {@code index}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int offsetByCodePoints(CharSequence seq, int index,
int codePointOffset) {
@@ -2193,7 +2177,7 @@
* Determines the index in a subsequence of the specified character array
* that is offset {@code codePointOffset} code points from {@code index}.
* The subsequence is delineated by {@code start} and {@code count}.
- *
+ *
* @param seq
* the character array to find the index in.
* @param start
@@ -2209,6 +2193,8 @@
* be a negative or positive value.
* @return the index in {@code seq} that is {@code codePointOffset} code
* points away from {@code index}.
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code start < 0}, {@code count < 0},
* {@code index < start}, {@code index > start + count},
@@ -2217,7 +2203,7 @@
* {@code seq} to skip {@code codePointOffset} code points
* forward or backward (if {@code codePointOffset} is
* negative) from {@code index}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int offsetByCodePoints(char[] seq, int start, int count,
int index, int codePointOffset) {
@@ -2276,14 +2262,13 @@
* Convenience method to determine the value of the specified character
* {@code c} in the supplied radix. The value of {@code radix} must be
* between MIN_RADIX and MAX_RADIX.
- *
+ *
* @param c
* the character to determine the value of.
* @param radix
* the radix.
* @return the value of {@code c} in {@code radix} if {@code radix} lies
* between {@link #MIN_RADIX} and {@link #MAX_RADIX}; -1 otherwise.
- * @since Android 1.0
*/
public static int digit(char c, int radix) {
// BEGIN android-changed
@@ -2313,12 +2298,12 @@
return UCharacter.digit(c, radix);
// ENd android-changed
}
-
+
/**
* Convenience method to determine the value of the character
* {@code codePoint} in the supplied radix. The value of {@code radix} must
* be between MIN_RADIX and MAX_RADIX.
- *
+ *
* @param codePoint
* the character, including supplementary characters.
* @param radix
@@ -2326,7 +2311,6 @@
* @return if {@code radix} lies between {@link #MIN_RADIX} and
* {@link #MAX_RADIX} then the value of the character in the radix;
* -1 otherwise.
- * @since Android 1.0
*/
public static int digit(int codePoint, int radix) {
return UCharacter.digit(codePoint, radix);
@@ -2336,12 +2320,11 @@
* Compares this object with the specified object and indicates if they are
* equal. In order to be equal, {@code object} must be an instance of
* {@code Character} and have the same char value as this object.
- *
+ *
* @param object
* the object to compare this double with.
* @return {@code true} if the specified object is equal to this
* {@code Character}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -2355,14 +2338,13 @@
* {@code MAX_RADIX} inclusive; {@code digit} must not be negative and
* smaller than {@code radix}. If any of these conditions does not hold, 0
* is returned.
- *
+ *
* @param digit
* the integer value.
* @param radix
* the radix.
* @return the character which represents the {@code digit} in the
* {@code radix}.
- * @since Android 1.0
*/
public static char forDigit(int digit, int radix) {
if (MIN_RADIX <= radix && radix <= MAX_RADIX) {
@@ -2375,13 +2357,12 @@
/**
* Gets the numeric value of the specified Unicode character.
- *
+ *
* @param c
* the Unicode character to get the numeric value of.
* @return a non-negative numeric integer value if a numeric value for
* {@code c} exists, -1 if there is no numeric value for {@code c},
* -2 if the numeric value can not be represented with an integer.
- * @since Android 1.0
*/
public static int getNumericValue(char c) {
// BEGIN android-changed
@@ -2414,19 +2395,18 @@
return UCharacter.getNumericValue(c);
// END android-changed
}
-
+
/**
* Gets the numeric value of the specified Unicode code point. For example,
* the code point '\u216B' stands for the Roman number XII, which has the
* numeric value 12.
- *
+ *
* @param codePoint
* the Unicode code point to get the numeric value of.
* @return a non-negative numeric integer value if a numeric value for
* {@code codePoint} exists, -1 if there is no numeric value for
* {@code codePoint}, -2 if the numeric value can not be
* represented with an integer.
- * @since Android 1.0
*/
public static int getNumericValue(int codePoint) {
return UCharacter.getNumericValue(codePoint);
@@ -2434,14 +2414,16 @@
/**
* Gets the general Unicode category of the specified character.
- *
+ *
* @param c
* the character to get the category of.
* @return the Unicode category of {@code c}.
- * @since Android 1.0
*/
public static int getType(char c) {
// BEGIN android-changed
+ // if(c < 1000) {
+ // return typeValuesCache[(int)c];
+ // }
// int result = BinarySearch.binarySearchRange(typeKeys, c);
// int high = typeValues[result * 2];
// if (c <= high) {
@@ -2452,19 +2434,23 @@
// return (c & 1) == 1 ? code >> 8 : code & 0xff;
// }
// return UNASSIGNED;
- return getType((int)c);
+ return getType((int) c);
// END android-changed
}
-
+
/**
* Gets the general Unicode category of the specified code point.
- *
+ *
* @param codePoint
* the Unicode code point to get the category of.
* @return the Unicode category of {@code codePoint}.
- * @since Android 1.0
*/
public static int getType(int codePoint) {
+ // BEGIN android-changed
+ // if (codePoint < 1000 && codePoint > 0) {
+ // return typeValuesCache[codePoint];
+ // }
+ // END android-changed
int type = UCharacter.getType(codePoint);
// the type values returned by UCharacter are not compatible with what
@@ -2477,11 +2463,10 @@
/**
* Gets the Unicode directionality of the specified character.
- *
+ *
* @param c
* the character to get the directionality of.
* @return the Unicode directionality of {@code c}.
- * @since Android 1.0
*/
public static byte getDirectionality(char c) {
// BEGIN android-changed
@@ -2498,21 +2483,20 @@
return getDirectionality((int)c);
// END android-changed
}
-
+
/**
* Gets the Unicode directionality of the specified character.
- *
+ *
* @param codePoint
* the Unicode code point to get the directionality of.
* @return the Unicode directionality of {@code codePoint}.
- * @since Android 1.0
*/
public static byte getDirectionality(int codePoint) {
if (getType(codePoint) == Character.UNASSIGNED) {
return Character.DIRECTIONALITY_UNDEFINED;
}
-
- byte UCDirectionality = UCharacter.getDirectionality(codePoint);
+
+ byte UCDirectionality = UCharacter.getDirectionality(codePoint);
if (UCDirectionality == -1) {
return -1;
}
@@ -2521,12 +2505,11 @@
/**
* Indicates whether the specified character is mirrored.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is mirrored; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isMirrored(char c) {
// BEGIN android-changed
@@ -2539,15 +2522,14 @@
return isMirrored((int)c);
// ENd android-changed
}
-
+
/**
* Indicates whether the specified code point is mirrored.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is mirrored, {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isMirrored(int codePoint) {
return UCharacter.isMirrored(codePoint);
@@ -2561,12 +2543,11 @@
/**
* Indicates whether the specified character is defined in the Unicode
* specification.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if the general Unicode category of the character is
* not {@code UNASSIGNED}; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isDefined(char c) {
// BEGIN android-changed
@@ -2574,16 +2555,15 @@
return UCharacter.isDefined(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is defined in the Unicode
* specification.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if the general Unicode category of the code point is
* not {@code UNASSIGNED}; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isDefined(int codePoint) {
return UCharacter.isDefined(codePoint);
@@ -2591,12 +2571,11 @@
/**
* Indicates whether the specified character is a digit.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a digit; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isDigit(char c) {
// BEGIN android-changed
@@ -2611,15 +2590,14 @@
return UCharacter.isDigit(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is a digit.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a digit; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isDigit(int codePoint) {
return UCharacter.isDigit(codePoint);
@@ -2628,11 +2606,10 @@
/**
* Indicates whether the specified character is ignorable in a Java or
* Unicode identifier.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is ignorable; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isIdentifierIgnorable(char c) {
// BEGIN android-changed
@@ -2641,16 +2618,15 @@
return UCharacter.isIdentifierIgnorable(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is ignorable in a Java or
* Unicode identifier.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is ignorable; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isIdentifierIgnorable(int codePoint) {
return UCharacter.isIdentifierIgnorable(codePoint);
@@ -2658,12 +2634,11 @@
/**
* Indicates whether the specified character is an ISO control character.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is an ISO control character;
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isISOControl(char c) {
return isISOControl((int)c);
@@ -2671,12 +2646,11 @@
/**
* Indicates whether the specified code point is an ISO control character.
- *
+ *
* @param c
* the code point to check.
* @return {@code true} if {@code c} is an ISO control character;
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isISOControl(int c) {
return (c >= 0 && c <= 0x1f) || (c >= 0x7f && c <= 0x9f);
@@ -2685,12 +2659,11 @@
/**
* Indicates whether the specified character is a valid part of a Java
* identifier other than the first character.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is valid as part of a Java identifier;
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isJavaIdentifierPart(char c) {
// Optimized case for ASCII
@@ -2709,31 +2682,29 @@
/**
* Indicates whether the specified code point is a valid part of a Java
* identifier other than the first character.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code c} is valid as part of a Java identifier;
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isJavaIdentifierPart(int codePoint) {
int type = getType(codePoint);
return (type >= UPPERCASE_LETTER && type <= OTHER_LETTER)
|| type == CURRENCY_SYMBOL || type == CONNECTOR_PUNCTUATION
|| (type >= DECIMAL_DIGIT_NUMBER && type <= LETTER_NUMBER)
- || type == COMBINING_SPACING_MARK || type == NON_SPACING_MARK
+ || type == COMBINING_SPACING_MARK || type == NON_SPACING_MARK
|| isIdentifierIgnorable(codePoint);
}
/**
* Indicates whether the specified character is a valid first character for
* a Java identifier.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a valid first character of a Java
* identifier; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isJavaIdentifierStart(char c) {
// Optimized case for ASCII
@@ -2746,16 +2717,15 @@
|| type == CURRENCY_SYMBOL || type == CONNECTOR_PUNCTUATION
|| type == LETTER_NUMBER;
}
-
+
/**
* Indicates whether the specified code point is a valid start for a Java
* identifier.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a valid start of a Java
* identifier; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isJavaIdentifierStart(int codePoint) {
int type = getType(codePoint);
@@ -2765,13 +2735,12 @@
/**
* Indicates whether the specified character is a Java letter.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a Java letter; {@code false}
* otherwise.
* @deprecated Use {@link #isJavaIdentifierStart(char)}
- * @since Android 1.0
*/
@Deprecated
public static boolean isJavaLetter(char c) {
@@ -2781,13 +2750,12 @@
/**
* Indicates whether the specified character is a Java letter or digit
* character.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a Java letter or digit;
* {@code false} otherwise.
* @deprecated Use {@link #isJavaIdentifierPart(char)}
- * @since Android 1.0
*/
@Deprecated
public static boolean isJavaLetterOrDigit(char c) {
@@ -2796,11 +2764,10 @@
/**
* Indicates whether the specified character is a letter.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a letter; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isLetter(char c) {
// BEGIN android-changed
@@ -2815,15 +2782,14 @@
return UCharacter.isLetter(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is a letter.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a letter; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isLetter(int codePoint) {
return UCharacter.isLetter(codePoint);
@@ -2831,12 +2797,11 @@
/**
* Indicates whether the specified character is a letter or a digit.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a letter or a digit; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isLetterOrDigit(char c) {
// BEGIN android-changed
@@ -2846,15 +2811,14 @@
return UCharacter.isLetterOrDigit(c);
// END andorid-changed
}
-
+
/**
* Indicates whether the specified code point is a letter or a digit.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a letter or a digit;
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isLetterOrDigit(int codePoint) {
return UCharacter.isLetterOrDigit(codePoint);
@@ -2862,12 +2826,11 @@
/**
* Indicates whether the specified character is a lower case letter.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a lower case letter; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isLowerCase(char c) {
// BEGIN android-changed
@@ -2878,20 +2841,19 @@
// if (c < 128) {
// return false;
// }
- //
+ //
// return getType(c) == LOWERCASE_LETTER;
return UCharacter.isLowerCase(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is a lower case letter.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a lower case letter;
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isLowerCase(int codePoint) {
return UCharacter.isLowerCase(codePoint);
@@ -2899,13 +2861,12 @@
/**
* Indicates whether the specified character is a Java space.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a Java space; {@code false}
* otherwise.
* @deprecated Use {@link #isWhitespace(char)}
- * @since Android 1.0
*/
@Deprecated
public static boolean isSpace(char c) {
@@ -2916,12 +2877,11 @@
* Indicates whether the specified character is a Unicode space character.
* That is, if it is a member of one of the Unicode categories Space
* Separator, Line Separator, or Paragraph Separator.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a Unicode space character,
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isSpaceChar(char c) {
// BEGIN android-changed
@@ -2936,17 +2896,16 @@
return UCharacter.isSpaceChar(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is a Unicode space character.
* That is, if it is a member of one of the Unicode categories Space
* Separator, Line Separator, or Paragraph Separator.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a Unicode space character,
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isSpaceChar(int codePoint) {
return UCharacter.isSpaceChar(codePoint);
@@ -2954,12 +2913,11 @@
/**
* Indicates whether the specified character is a titlecase character.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a titlecase character, {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isTitleCase(char c) {
// BEGIN android-changed
@@ -2978,15 +2936,14 @@
return UCharacter.isTitleCase(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is a titlecase character.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a titlecase character,
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isTitleCase(int codePoint) {
return UCharacter.isTitleCase(codePoint);
@@ -2995,12 +2952,11 @@
/**
* Indicates whether the specified character is valid as part of a Unicode
* identifier other than the first character.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is valid as part of a Unicode
* identifier; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isUnicodeIdentifierPart(char c) {
// BEGIN android-changed
@@ -3013,16 +2969,15 @@
return UCharacter.isUnicodeIdentifierPart(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is valid as part of a Unicode
* identifier other than the first character.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is valid as part of a Unicode
* identifier; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isUnicodeIdentifierPart(int codePoint) {
return UCharacter.isUnicodeIdentifierPart(codePoint);
@@ -3031,12 +2986,11 @@
/**
* Indicates whether the specified character is a valid initial character
* for a Unicode identifier.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a valid first character for a
* Unicode identifier; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isUnicodeIdentifierStart(char c) {
// BEGIN android-changed
@@ -3046,16 +3000,15 @@
return UCharacter.isUnicodeIdentifierStart(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is a valid initial character
* for a Unicode identifier.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a valid first character for
* a Unicode identifier; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isUnicodeIdentifierStart(int codePoint) {
return UCharacter.isUnicodeIdentifierStart(codePoint);
@@ -3063,12 +3016,11 @@
/**
* Indicates whether the specified character is an upper case letter.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if {@code c} is a upper case letter; {@code false}
* otherwise.
- * @since Android 1.0
*/
public static boolean isUpperCase(char c) {
// BEGIN android-changed
@@ -3079,20 +3031,19 @@
// if (c < 128) {
// return false;
// }
- //
+ //
// return getType(c) == UPPERCASE_LETTER;
return UCharacter.isUpperCase(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is an upper case letter.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if {@code codePoint} is a upper case letter;
* {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isUpperCase(int codePoint) {
return UCharacter.isUpperCase(codePoint);
@@ -3101,12 +3052,11 @@
/**
* Indicates whether the specified character is a whitespace character in
* Java.
- *
+ *
* @param c
* the character to check.
* @return {@code true} if the supplied {@code c} is a whitespace character
* in Java; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isWhitespace(char c) {
// BEGIN android-changed
@@ -3124,30 +3074,29 @@
return UCharacter.isWhitespace(c);
// END android-changed
}
-
+
/**
* Indicates whether the specified code point is a whitespace character in
* Java.
- *
+ *
* @param codePoint
* the code point to check.
* @return {@code true} if the supplied {@code c} is a whitespace character
* in Java; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isWhitespace(int codePoint) {
//FIXME depends on ICU when the codePoint is '\u2007'
return UCharacter.isWhitespace(codePoint);
+
}
/**
* Reverses the order of the first and second byte in the specified
* character.
- *
+ *
* @param c
* the character to reverse.
* @return the character with reordered bytes.
- * @since Android 1.0
*/
public static char reverseBytes(char c) {
return (char)((c<<8) | (c>>8));
@@ -3157,12 +3106,11 @@
* Returns the lower case equivalent for the specified character if the
* character is an upper case letter. Otherwise, the specified character is
* returned unchanged.
- *
+ *
* @param c
* the character
* @return if {@code c} is an upper case character then its lower case
* counterpart, otherwise just {@code c}.
- * @since Android 1.0
*/
public static char toLowerCase(char c) {
// BEGIN android-changed
@@ -3170,10 +3118,13 @@
// if ('A' <= c && c <= 'Z') {
// return (char) (c + ('a' - 'A'));
// }
- // if (c < 128) {
+ // if (c < 192) {// || c == 215 || (c > 222 && c < 256)) {
// return c;
// }
- //
+ // if (c<1000) {
+ // return (char)lowercaseValuesCache[c-192];
+ // }
+ //
// int result = BinarySearch.binarySearchRange(lowercaseKeys, c);
// if (result >= 0) {
// boolean by2 = false;
@@ -3195,17 +3146,16 @@
return (char)UCharacter.toLowerCase(c);
// END android-changed
}
-
+
/**
* Returns the lower case equivalent for the specified code point if it is
* an upper case letter. Otherwise, the specified code point is returned
* unchanged.
- *
+ *
* @param codePoint
* the code point to check.
* @return if {@code codePoint} is an upper case character then its lower
* case counterpart, otherwise just {@code codePoint}.
- * @since Android 1.0
*/
public static int toLowerCase(int codePoint) {
return UCharacter.toLowerCase(codePoint);
@@ -3218,11 +3168,10 @@
/**
* Converts the specified character to its string representation.
- *
+ *
* @param value
* the character to convert.
* @return the character converted to a string.
- * @since Android 1.0
*/
public static String toString(char value) {
return String.valueOf(value);
@@ -3231,12 +3180,11 @@
/**
* Returns the title case equivalent for the specified character if it
* exists. Otherwise, the specified character is returned unchanged.
- *
+ *
* @param c
* the character to convert.
* @return the title case equivalent of {@code c} if it exists, otherwise
* {@code c}.
- * @since Android 1.0
*/
public static char toTitleCase(char c) {
// BEGIN android-changed
@@ -3251,16 +3199,15 @@
return (char)UCharacter.toTitleCase(c);
// ENd android-changed
}
-
+
/**
* Returns the title case equivalent for the specified code point if it
* exists. Otherwise, the specified code point is returned unchanged.
- *
+ *
* @param codePoint
* the code point to convert.
* @return the title case equivalent of {@code codePoint} if it exists,
* otherwise {@code codePoint}.
- * @since Android 1.0
*/
public static int toTitleCase(int codePoint) {
return UCharacter.toTitleCase(codePoint);
@@ -3270,12 +3217,11 @@
* Returns the upper case equivalent for the specified character if the
* character is a lower case letter. Otherwise, the specified character is
* returned unchanged.
- *
+ *
* @param c
* the character to convert.
* @return if {@code c} is a lower case character then its upper case
* counterpart, otherwise just {@code c}.
- * @since Android 1.0
*/
public static char toUpperCase(char c) {
// BEGIN android-changed
@@ -3283,10 +3229,12 @@
// if ('a' <= c && c <= 'z') {
// return (char) (c - ('a' - 'A'));
// }
- // if (c < 128) {
+ // if (c < 181) {
// return c;
// }
- //
+ // if (c<1000) {
+ // return (char)uppercaseValuesCache[(int)c-181];
+ // }
// int result = BinarySearch.binarySearchRange(uppercaseKeys, c);
// if (result >= 0) {
// boolean by2 = false;
@@ -3308,17 +3256,16 @@
return (char)UCharacter.toUpperCase(c);
// END android-changed
}
-
+
/**
* Returns the upper case equivalent for the specified code point if the
* code point is a lower case letter. Otherwise, the specified code point is
* returned unchanged.
- *
+ *
* @param codePoint
* the code point to convert.
* @return if {@code codePoint} is a lower case character then its upper
* case counterpart, otherwise just {@code codePoint}.
- * @since Android 1.0
*/
public static int toUpperCase(int codePoint) {
return UCharacter.toUpperCase(codePoint);
diff --git a/luni/src/main/java/java/lang/ClassCastException.java b/luni/src/main/java/java/lang/ClassCastException.java
index 1482b21..b33efcf 100644
--- a/luni/src/main/java/java/lang/ClassCastException.java
+++ b/luni/src/main/java/java/lang/ClassCastException.java
@@ -22,8 +22,6 @@
/**
* Thrown when a program attempts to cast a an object to a type with which it is
* not compatible.
- *
- * @since Android 1.0
*/
public class ClassCastException extends RuntimeException {
private static final long serialVersionUID = -9223365651070458532L;
@@ -31,8 +29,6 @@
/**
* Constructs a new {@code ClassCastException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public ClassCastException() {
super();
@@ -41,10 +37,9 @@
/**
* Constructs a new {@code ClassCastException} with the current stack trace
* and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public ClassCastException(String detailMessage) {
super(detailMessage);
@@ -53,12 +48,11 @@
/**
* Constructs a new {@code ClassCastException} with the current stack trace
* and a detail message based on the source and target class.
- *
+ *
* @param instanceClass
* the class being cast from.
* @param castClass
* the class being cast to.
- * @since Android 1.0
*/
ClassCastException(Class<?> instanceClass, Class<?> castClass) {
super(Msg.getString("K0340", instanceClass.getName(), castClass //$NON-NLS-1$
diff --git a/luni/src/main/java/java/lang/ClassCircularityError.java b/luni/src/main/java/java/lang/ClassCircularityError.java
index 6dd1c8e..07bf339 100644
--- a/luni/src/main/java/java/lang/ClassCircularityError.java
+++ b/luni/src/main/java/java/lang/ClassCircularityError.java
@@ -24,9 +24,6 @@
* <p>
* Note that this error can only occur when inconsistent class files are loaded,
* since it would normally be detected at compile time.
- * </p>
- *
- * @since Android 1.0
*/
public class ClassCircularityError extends LinkageError {
@@ -35,8 +32,6 @@
/**
* Constructs a new {@code ClassCircularityError} that include the current
* stack trace.
- *
- * @since Android 1.0
*/
public ClassCircularityError() {
super();
@@ -45,10 +40,9 @@
/**
* Constructs a new {@code ClassCircularityError} with the current stack
* trace and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public ClassCircularityError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/ClassFormatError.java b/luni/src/main/java/java/lang/ClassFormatError.java
index 282ed70..009f44a 100644
--- a/luni/src/main/java/java/lang/ClassFormatError.java
+++ b/luni/src/main/java/java/lang/ClassFormatError.java
@@ -20,8 +20,6 @@
/**
* Thrown by a class loader when a class file has an illegal format or if the
* data that it contains can not be interpreted as a class.
- *
- * @since Android 1.0
*/
public class ClassFormatError extends LinkageError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code ClassFormatError} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public ClassFormatError() {
super();
@@ -40,10 +36,9 @@
/**
* Constructs a new {@code ClassFormatError} with the current stack trace
* and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public ClassFormatError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/ClassNotFoundException.java b/luni/src/main/java/java/lang/ClassNotFoundException.java
index 26bdbf7..2ac3b49 100644
--- a/luni/src/main/java/java/lang/ClassNotFoundException.java
+++ b/luni/src/main/java/java/lang/ClassNotFoundException.java
@@ -19,8 +19,6 @@
/**
* Thrown when a class loader is unable to find a class.
- *
- * @since Android 1.0
*/
public class ClassNotFoundException extends Exception {
@@ -31,8 +29,6 @@
/**
* Constructs a new {@code ClassNotFoundException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public ClassNotFoundException() {
super((Throwable) null);
@@ -41,10 +37,9 @@
/**
* Constructs a new {@code ClassNotFoundException} with the current stack
* trace and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public ClassNotFoundException(String detailMessage) {
super(detailMessage, null);
@@ -54,12 +49,11 @@
* Constructs a new {@code ClassNotFoundException} with the current stack
* trace, the specified detail message and the exception that occurred when
* loading the class.
- *
+ *
* @param detailMessage
* the detail message for this exception.
* @param exception
* the exception which occurred while loading the class.
- * @since Android 1.0
*/
public ClassNotFoundException(String detailMessage, Throwable exception) {
super(detailMessage);
@@ -68,7 +62,7 @@
/**
* Returns the exception which occurred when loading the class.
- *
+ *
* @return Throwable the exception which occurred while loading the class.
*/
public Throwable getException() {
@@ -78,7 +72,7 @@
/**
* Returns the cause of this Throwable, or {@code null} if there is no
* cause.
- *
+ *
* @return Throwable the receiver's cause.
*/
@Override
diff --git a/luni/src/main/java/java/lang/CloneNotSupportedException.java b/luni/src/main/java/java/lang/CloneNotSupportedException.java
index b484e08..2f4f11c 100644
--- a/luni/src/main/java/java/lang/CloneNotSupportedException.java
+++ b/luni/src/main/java/java/lang/CloneNotSupportedException.java
@@ -20,9 +20,8 @@
/**
* Thrown when a program attempts to clone an object which does not support the
* {@link Cloneable} interface.
- *
+ *
* @see Cloneable
- * @since Android 1.0
*/
public class CloneNotSupportedException extends Exception {
@@ -31,8 +30,6 @@
/**
* Constructs a new {@code CloneNotSupportedException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public CloneNotSupportedException() {
super();
@@ -41,10 +38,9 @@
/**
* Constructs a new {@code CloneNotSupportedException} with the current
* stack trace and the specified detail message.
- *
+ *
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public CloneNotSupportedException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/Comparable.java b/luni/src/main/java/java/lang/Comparable.java
index c50f112..df10416 100644
--- a/luni/src/main/java/java/lang/Comparable.java
+++ b/luni/src/main/java/java/lang/Comparable.java
@@ -28,21 +28,17 @@
* invertible (the sign of the result of x.compareTo(y) must be equal to the
* negation of the sign of the result of y.compareTo(x) for all combinations of
* x and y).
- * </p>
* <p>
* In addition, it is recommended (but not required) that if and only if the
* result of x.compareTo(y) is zero, then the result of x.equals(y) should be
* {@code true}.
- * </p>
- *
- * @since Android 1.0
*/
public interface Comparable<T> {
-
+
/**
* Compares this object to the specified object to determine their relative
* order.
- *
+ *
* @param another
* the object to compare to this instance.
* @return a negative integer if this instance is less than {@code another};
@@ -52,7 +48,6 @@
* @throws ClassCastException
* if {@code another} cannot be converted into something
* comparable to {@code this} instance.
- * @since Android 1.0
*/
int compareTo(T another);
}
diff --git a/luni/src/main/java/java/lang/Deprecated.java b/luni/src/main/java/java/lang/Deprecated.java
index eb356c2..047a6be 100644
--- a/luni/src/main/java/java/lang/Deprecated.java
+++ b/luni/src/main/java/java/lang/Deprecated.java
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,17 +18,16 @@
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* Annotation type used to mark program elements that should no longer be used
* by programmers. Compilers produce a warning if a deprecated program element
* is used.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
@Documented
-@Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)
-public @interface Deprecated
-{
-
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Deprecated {
}
diff --git a/luni/src/main/java/java/lang/Double.java b/luni/src/main/java/java/lang/Double.java
index c50b27d..bc0c380 100644
--- a/luni/src/main/java/java/lang/Double.java
+++ b/luni/src/main/java/java/lang/Double.java
@@ -19,9 +19,9 @@
/**
* The wrapper for the primitive type {@code double}.
- *
+ *
* @see java.lang.Number
- * @since Android 1.0
+ * @since 1.0
*/
public final class Double extends Number implements Comparable<Double> {
@@ -35,15 +35,11 @@
/**
* Constant for the maximum {@code double} value, (2 - 2<sup>-52</sup>) *
* 2<sup>1023</sup>.
- *
- * @since Android 1.0
*/
public static final double MAX_VALUE = 1.79769313486231570e+308;
/**
* Constant for the minimum {@code double} value, 2<sup>-1074</sup>.
- *
- * @since Android 1.0
*/
public static final double MIN_VALUE = 5e-324;
@@ -51,30 +47,24 @@
/**
* Constant for the Not-a-Number (NaN) value of the {@code double} type.
- *
- * @since Android 1.0
*/
public static final double NaN = 0.0 / 0.0;
/**
* Constant for the Positive Infinity value of the {@code double} type.
- *
- * @since Android 1.0
*/
public static final double POSITIVE_INFINITY = 1.0 / 0.0;
/**
* Constant for the Negative Infinity value of the {@code double} type.
- *
- * @since Android 1.0
*/
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
/**
* The {@link Class} object that represents the primitive type {@code
* double}.
- *
- * @since Android 1.0
+ *
+ * @since 1.1
*/
@SuppressWarnings("unchecked")
public static final Class<Double> TYPE = (Class<Double>) new double[0]
@@ -86,18 +76,17 @@
/**
* Constant for the number of bits needed to represent a {@code double} in
* two's complement form.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int SIZE = 64;
/**
* Constructs a new {@code Double} with the specified primitive double
* value.
- *
+ *
* @param value
* the primitive double value to store in the new instance.
- * @since Android 1.0
*/
public Double(double value) {
this.value = value;
@@ -105,13 +94,12 @@
/**
* Constructs a new {@code Double} from the specified string.
- *
+ *
* @param string
* the string representation of a double value.
* @throws NumberFormatException
* if {@code string} can not be decoded into a double value.
* @see #parseDouble(String)
- * @since Android 1.0
*/
public Double(String string) throws NumberFormatException {
this(parseDouble(string));
@@ -125,36 +113,20 @@
* than any other double value, including {@code Double.POSITIVE_INFINITY};</li>
* <li>+0.0d is greater than -0.0d</li>
* </ul>
- *
+ *
* @param object
* the double object to compare this object to.
* @return a negative value if the value of this double is less than the
* value of {@code object}; 0 if the value of this double and the
* value of {@code object} are equal; a positive value if the value
* of this double is greater than the value of {@code object}.
+ * @throws NullPointerException
+ * if {@code object} is {@code null}.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.2
*/
public int compareTo(Double object) {
- long d1, d2;
- long NaNbits = Double.doubleToLongBits(Double.NaN);
- if ((d1 = Double.doubleToLongBits(value)) == NaNbits) {
- if (Double.doubleToLongBits(object.value) == NaNbits) {
- return 0;
- }
- return 1;
- }
- if ((d2 = Double.doubleToLongBits(object.value)) == NaNbits) {
- return -1;
- }
- if (value == object.value) {
- if (d1 == d2) {
- return 0;
- }
- // check for -0
- return d1 > d2 ? 1 : -1;
- }
- return value > object.value ? 1 : -1;
+ return compare(value, object.value);
}
@Override
@@ -167,14 +139,13 @@
* to the IEEE 754 floating-point double precision bit layout. All
* <em>Not-a-Number (NaN)</em> values are converted to a single NaN
* representation ({@code 0x7ff8000000000000L}).
- *
+ *
* @param value
* the double value to convert.
* @return the IEEE 754 floating-point double precision representation of
* {@code value}.
* @see #doubleToRawLongBits(double)
* @see #longBitsToDouble(long)
- * @since Android 1.0
*/
public static native long doubleToLongBits(double value);
@@ -182,22 +153,20 @@
* Converts the specified double value to a binary representation conforming
* to the IEEE 754 floating-point double precision bit layout.
* <em>Not-a-Number (NaN)</em> values are preserved.
- *
+ *
* @param value
* the double value to convert.
* @return the IEEE 754 floating-point double precision representation of
* {@code value}.
* @see #doubleToLongBits(double)
* @see #longBitsToDouble(long)
- * @since Android 1.0
*/
public static native long doubleToRawLongBits(double value);
/**
* Gets the primitive value of this double.
- *
+ *
* @return this object's primitive value.
- * @since Android 1.0
*/
@Override
public double doubleValue() {
@@ -209,12 +178,11 @@
* equal. In order to be equal, {@code object} must be an instance of
* {@code Double} and the bit pattern of its double value is the same as
* this object's.
- *
+ *
* @param object
* the object to compare this double with.
* @return {@code true} if the specified object is equal to this
* {@code Double}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -241,10 +209,9 @@
/**
* Indicates whether this object represents an infinite value.
- *
+ *
* @return {@code true} if the value of this double is positive or negative
* infinity; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isInfinite() {
return isInfinite(value);
@@ -252,12 +219,11 @@
/**
* Indicates whether the specified double represents an infinite value.
- *
+ *
* @param d
* the double to check.
* @return {@code true} if the value of {@code d} is positive or negative
* infinity; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isInfinite(double d) {
return (d == POSITIVE_INFINITY) || (d == NEGATIVE_INFINITY);
@@ -265,10 +231,9 @@
/**
* Indicates whether this object is a <em>Not-a-Number (NaN)</em> value.
- *
+ *
* @return {@code true} if this double is <em>Not-a-Number</em>;
* {@code false} if it is a (potentially infinite) double number.
- * @since Android 1.0
*/
public boolean isNaN() {
return isNaN(value);
@@ -277,12 +242,11 @@
/**
* Indicates whether the specified double is a <em>Not-a-Number (NaN)</em>
* value.
- *
+ *
* @param d
* the double value to check.
* @return {@code true} if {@code d} is <em>Not-a-Number</em>;
* {@code false} if it is a (potentially infinite) double number.
- * @since Android 1.0
*/
public static boolean isNaN(double d) {
return d != d;
@@ -291,14 +255,13 @@
/**
* Converts the specified IEEE 754 floating-point double precision bit
* pattern to a Java double value.
- *
+ *
* @param bits
* the IEEE 754 floating-point double precision representation of
* a double value.
* @return the double value converted from {@code bits}.
* @see #doubleToLongBits(double)
* @see #doubleToRawLongBits(double)
- * @since Android 1.0
*/
public static native double longBitsToDouble(long bits);
@@ -309,14 +272,13 @@
/**
* Parses the specified string as a double value.
- *
+ *
* @param string
* the string representation of a double value.
* @return the primitive double value represented by {@code string}.
* @throws NumberFormatException
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a double value.
- * @since Android 1.0
*/
public static double parseDouble(String string)
throws NumberFormatException {
@@ -337,11 +299,10 @@
/**
* Returns a string containing a concise, human-readable description of the
* specified double value.
- *
+ *
* @param d
* the double to convert to a string.
* @return a printable representation of {@code d}.
- * @since Android 1.0
*/
public static String toString(double d) {
return org.apache.harmony.luni.util.NumberConverter.convert(d);
@@ -349,7 +310,7 @@
/**
* Parses the specified string as a double value.
- *
+ *
* @param string
* the string representation of a double value.
* @return a {@code Double} instance containing the double value represented
@@ -358,7 +319,6 @@
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a double value.
* @see #parseDouble(String)
- * @since Android 1.0
*/
public static Double valueOf(String string) throws NumberFormatException {
return new Double(parseDouble(string));
@@ -371,7 +331,7 @@
* than any other double value, including {@code Double.POSITIVE_INFINITY};</li>
* <li>+0.0d is greater than -0.0d</li>
* </ul>
- *
+ *
* @param double1
* the first value to compare.
* @param double2
@@ -379,37 +339,44 @@
* @return a negative value if {@code double1} is less than {@code double2};
* 0 if {@code double1} and {@code double2} are equal; a positive
* value if {@code double1} is greater than {@code double2}.
- * @since Android 1.0
*/
public static int compare(double double1, double double2) {
- long d1, d2;
- long NaNbits = Double.doubleToLongBits(Double.NaN);
- if ((d1 = Double.doubleToLongBits(double1)) == NaNbits) {
- if (Double.doubleToLongBits(double2) == NaNbits) {
+ // Non-zero, non-NaN checking.
+ if (double1 > double2) {
+ return 1;
+ }
+ if (double2 > double1) {
+ return -1;
+ }
+ if (double1 == double2 && 0.0d != double1) {
+ return 0;
+ }
+
+ // NaNs are equal to other NaNs and larger than any other double
+ if (isNaN(double1)) {
+ if (isNaN(double2)) {
return 0;
}
return 1;
- }
- if ((d2 = Double.doubleToLongBits(double2)) == NaNbits) {
+ } else if (isNaN(double2)) {
return -1;
}
- if (double1 == double2) {
- if (d1 == d2) {
- return 0;
- }
- // check for -0
- return d1 > d2 ? 1 : -1;
- }
- return double1 > double2 ? 1 : -1;
+
+ // Deal with +0.0 and -0.0
+ long d1 = doubleToRawLongBits(double1);
+ long d2 = doubleToRawLongBits(double2);
+ // The below expression is equivalent to:
+ // (d1 == d2) ? 0 : (d1 < d2) ? -1 : 1
+ return (int) ((d1 >> 63) - (d2 >> 63));
}
/**
* Returns a {@code Double} instance for the specified double value.
- *
+ *
* @param d
* the double value to store in the instance.
* @return a {@code Double} instance containing {@code d}.
- * @since Android 1.0
+ * @since 1.5
*/
public static Double valueOf(double d) {
return new Double(d);
@@ -417,11 +384,11 @@
/**
* Converts the specified double into its hexadecimal string representation.
- *
+ *
* @param d
* the double to convert.
* @return the hexadecimal string representation of {@code d}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toHexString(double d) {
/*
diff --git a/luni/src/main/java/java/lang/Enum.java b/luni/src/main/java/java/lang/Enum.java
index 0aa15dd..395c825 100644
--- a/luni/src/main/java/java/lang/Enum.java
+++ b/luni/src/main/java/java/lang/Enum.java
@@ -27,8 +27,6 @@
* The superclass of all enumerated types. Actual enumeration types inherit from
* this class, but extending this class does not make a class an enumration
* type, since the compiler needs to generate special information for it.
- *
- * @since Android 1.0
*/
public abstract class Enum<E extends Enum<E>> implements Serializable,
Comparable<E> {
@@ -41,13 +39,12 @@
/**
* Constructor for constants of enum subtypes.
- *
+ *
* @param name
* the enum constant's declared name.
* @param ordinal
* the enum constant's ordinal, which corresponds to its position
* in the enum declaration, starting at zero.
- * @since Android 1.0
*/
protected Enum(String name, int ordinal) {
this.name = name;
@@ -57,10 +54,9 @@
/**
* Returns the name of this enum constant. The name is the field as it
* appears in the {@code enum} declaration.
- *
+ *
* @return the name of this enum constant.
* @see #toString()
- * @since Android 1.0
*/
public final String name() {
return name;
@@ -69,9 +65,8 @@
/**
* Returns the position of the enum constant in the declaration. The first
* constant has an ordinal value of zero.
- *
+ *
* @return the ordinal value of this enum constant.
- * @since Android 1.0
*/
public final int ordinal() {
return ordinal;
@@ -80,9 +75,8 @@
/**
* Returns a string containing a concise, human-readable description of this
* object. In this case, the enum constant's name is returned.
- *
+ *
* @return a printable representation of this object.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -93,12 +87,11 @@
* Compares this object with the specified object and indicates if they are
* equal. In order to be equal, {@code object} must be identical to this
* enum constant.
- *
+ *
* @param other
* the object to compare this enum constant with.
* @return {@code true} if the specified object is equal to this
* {@code Enum}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public final boolean equals(Object other) {
@@ -113,11 +106,10 @@
/**
* {@code Enum} objects are singletons, they may not be cloned. This method
* always throws a {@code CloneNotSupportedException}.
- *
+ *
* @return does not return.
* @throws CloneNotSupportedException
* is always thrown.
- * @since Android 1.0
*/
@Override
protected final Object clone() throws CloneNotSupportedException {
@@ -129,7 +121,7 @@
* Compares this object to the specified enum object to determine their
* relative order. This method compares the object's ordinal values, that
* is, their position in the enum declaration.
- *
+ *
* @param o
* the enum object to compare this object to.
* @return a negative value if the ordinal value of this enum constant is
@@ -138,7 +130,6 @@
* value if the ordinal value of this enum constant is greater than
* the ordinal value of {@code o}.
* @see java.lang.Comparable
- * @since Android 1.0
*/
public final int compareTo(E o) {
return ordinal - o.ordinal;
@@ -146,9 +137,8 @@
/**
* Returns the enum constant's declaring class.
- *
+ *
* @return the class object representing the constant's enum type.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
@@ -162,7 +152,7 @@
/**
* Returns the constant with the specified name of the specified enum type.
- *
+ *
* @param enumType
* the class of the enumerated type to search for the constant
* value.
@@ -174,7 +164,6 @@
* @throws IllegalArgumentException
* if {@code enumType} is not an enumerated type or does not
* have a constant value called {@code name}.
- * @since Android 1.0
*/
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
if ((enumType == null) || (name == null)) {
diff --git a/luni/src/main/java/java/lang/EnumConstantNotPresentException.java b/luni/src/main/java/java/lang/EnumConstantNotPresentException.java
index 0416703..aec32d0 100644
--- a/luni/src/main/java/java/lang/EnumConstantNotPresentException.java
+++ b/luni/src/main/java/java/lang/EnumConstantNotPresentException.java
@@ -20,8 +20,8 @@
/**
* Thrown if an {@code enum} constant does not exist for a particular name.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public class EnumConstantNotPresentException extends RuntimeException {
@@ -36,12 +36,11 @@
* Constructs a new {@code EnumConstantNotPresentException} with the current
* stack trace and a detail message based on the specified enum type and
* missing constant name.
- *
+ *
* @param enumType
* the enum type.
* @param constantName
* the missing constant name.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public EnumConstantNotPresentException(Class<? extends Enum> enumType,
@@ -54,9 +53,8 @@
/**
* Gets the enum type for which the constant name is missing.
- *
+ *
* @return the enum type for which a constant name has not been found.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public Class<? extends Enum> enumType() {
@@ -68,7 +66,6 @@
*
* @return the name of the constant that has not been found in the enum
* type.
- * @since Android 1.0
*/
public String constantName() {
return constantName;
diff --git a/luni/src/main/java/java/lang/Error.java b/luni/src/main/java/java/lang/Error.java
index 3bce72c..dd284ae 100644
--- a/luni/src/main/java/java/lang/Error.java
+++ b/luni/src/main/java/java/lang/Error.java
@@ -26,7 +26,6 @@
* @see Throwable
* @see Exception
* @see RuntimeException
- * @since Android 1.0
*/
public class Error extends Throwable {
@@ -34,8 +33,6 @@
/**
* Constructs a new {@code Error} that includes the current stack trace.
- *
- * @since Android 1.0
*/
public Error() {
super();
@@ -47,7 +44,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public Error(String detailMessage) {
super(detailMessage);
@@ -61,7 +57,6 @@
* the detail message for this error.
* @param throwable
* the cause of this error.
- * @since Android 1.0
*/
public Error(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
@@ -73,7 +68,6 @@
*
* @param throwable
* the cause of this error.
- * @since Android 1.0
*/
public Error(Throwable throwable) {
super(throwable);
diff --git a/luni/src/main/java/java/lang/Exception.java b/luni/src/main/java/java/lang/Exception.java
index 010cea4..7921edd 100644
--- a/luni/src/main/java/java/lang/Exception.java
+++ b/luni/src/main/java/java/lang/Exception.java
@@ -26,15 +26,12 @@
* @see Throwable
* @see Error
* @see RuntimeException
- * @since Android 1.0
*/
public class Exception extends Throwable {
private static final long serialVersionUID = -3387516993124229948L;
/**
* Constructs a new {@code Exception} that includes the current stack trace.
- *
- * @since Android 1.0
*/
public Exception() {
super();
@@ -46,7 +43,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public Exception(String detailMessage) {
super(detailMessage);
@@ -60,7 +56,6 @@
* the detail message for this exception.
* @param throwable
* the cause of this exception.
- * @since Android 1.0
*/
public Exception(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
@@ -72,7 +67,6 @@
*
* @param throwable
* the cause of this exception.
- * @since Android 1.0
*/
public Exception(Throwable throwable) {
super(throwable);
diff --git a/luni/src/main/java/java/lang/ExceptionInInitializerError.java b/luni/src/main/java/java/lang/ExceptionInInitializerError.java
index 6096f08..3767488 100644
--- a/luni/src/main/java/java/lang/ExceptionInInitializerError.java
+++ b/luni/src/main/java/java/lang/ExceptionInInitializerError.java
@@ -19,8 +19,6 @@
/**
* Thrown when an exception occurs during class initialization.
- *
- * @since Android 1.0
*/
public class ExceptionInInitializerError extends LinkageError {
@@ -31,8 +29,6 @@
/**
* Constructs a new {@code ExceptionInInitializerError} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public ExceptionInInitializerError() {
super();
@@ -45,7 +41,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public ExceptionInInitializerError(String detailMessage) {
super(detailMessage);
@@ -70,7 +65,6 @@
* Returns the exception that is the cause of this error.
*
* @return the exception that caused this error.
- * @since Android 1.0
*/
public Throwable getException() {
return exception;
@@ -80,7 +74,6 @@
* Returns the cause of this error, or {@code null} if there is no cause.
*
* @return the exception that caused this error.
- * @since Android 1.0
*/
@Override
public Throwable getCause() {
diff --git a/luni/src/main/java/java/lang/Float.java b/luni/src/main/java/java/lang/Float.java
index 69f91c5..067149d 100644
--- a/luni/src/main/java/java/lang/Float.java
+++ b/luni/src/main/java/java/lang/Float.java
@@ -19,9 +19,9 @@
/**
* The wrapper for the primitive type {@code float}.
- *
+ *
* @see java.lang.Number
- * @since Android 1.0
+ * @since 1.0
*/
public final class Float extends Number implements Comparable<Float> {
@@ -34,44 +34,34 @@
/**
* Constant for the maximum {@code float} value, (2 - 2<sup>-23</sup>) * 2<sup>127</sup>.
- *
- * @since Android 1.0
*/
public static final float MAX_VALUE = 3.40282346638528860e+38f;
/**
* Constant for the minimum {@code float} value, 2<sup>-149</sup>.
- *
- * @since Android 1.0
*/
public static final float MIN_VALUE = 1.40129846432481707e-45f;
/**
* Constant for the Not-a-Number (NaN) value of the {@code float} type.
- *
- * @since Android 1.0
*/
public static final float NaN = 0.0f / 0.0f;
/**
* Constant for the Positive Infinity value of the {@code float} type.
- *
- * @since Android 1.0
*/
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
/**
* Constant for the Negative Infinity value of the {@code float} type.
- *
- * @since Android 1.0
*/
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
/**
- * The {@link Class} object that represents the primitive type {@code
+ * The {@link Class} object that represents the primitive type {@code
* float}.
- *
- * @since Android 1.0
+ *
+ * @since 1.1
*/
@SuppressWarnings("unchecked")
public static final Class<Float> TYPE = (Class<Float>) new float[0]
@@ -83,17 +73,16 @@
/**
* Constant for the number of bits needed to represent a {@code float} in
* two's complement form.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int SIZE = 32;
/**
* Constructs a new {@code Float} with the specified primitive float value.
- *
+ *
* @param value
* the primitive float value to store in the new instance.
- * @since Android 1.0
*/
public Float(float value) {
this.value = value;
@@ -101,10 +90,9 @@
/**
* Constructs a new {@code Float} with the specified primitive double value.
- *
+ *
* @param value
* the primitive double value to store in the new instance.
- * @since Android 1.0
*/
public Float(double value) {
this.value = (float) value;
@@ -112,13 +100,12 @@
/**
* Constructs a new {@code Float} from the specified string.
- *
+ *
* @param string
* the string representation of a float value.
* @throws NumberFormatException
* if {@code string} can not be decoded into a float value.
* @see #parseFloat(String)
- * @since Android 1.0
*/
public Float(String string) throws NumberFormatException {
this(parseFloat(string));
@@ -132,7 +119,7 @@
* than any other float value, including {@code Float.POSITIVE_INFINITY};</li>
* <li>+0.0f is greater than -0.0f</li>
* </ul>
- *
+ *
* @param object
* the float object to compare this object to.
* @return a negative value if the value of this float is less than the
@@ -140,28 +127,10 @@
* value of {@code object} are equal; a positive value if the value
* of this float is greater than the value of {@code object}.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.2
*/
public int compareTo(Float object) {
- int f1, f2;
- int NaNbits = Float.floatToIntBits(Float.NaN);
- if ((f1 = Float.floatToIntBits(value)) == NaNbits) {
- if (Float.floatToIntBits(object.value) == NaNbits) {
- return 0;
- }
- return 1;
- }
- if ((f2 = Float.floatToIntBits(object.value)) == NaNbits) {
- return -1;
- }
- if (value == object.value) {
- if (f1 == f2) {
- return 0;
- }
- // check for -0
- return f1 > f2 ? 1 : -1;
- }
- return value > object.value ? 1 : -1;
+ return compare(value, object.value);
}
@Override
@@ -178,12 +147,11 @@
* Compares this instance with the specified object and indicates if they
* are equal. In order to be equal, {@code object} must be an instance of
* {@code Float} and have the same float value as this object.
- *
+ *
* @param object
* the object to compare this float with.
* @return {@code true} if the specified object is equal to this
* {@code Float}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -197,14 +165,13 @@
* to the IEEE 754 floating-point single precision bit layout. All
* <em>Not-a-Number (NaN)</em> values are converted to a single NaN
* representation ({@code 0x7ff8000000000000L}).
- *
+ *
* @param value
* the float value to convert.
* @return the IEEE 754 floating-point single precision representation of
* {@code value}.
* @see #floatToRawIntBits(float)
* @see #intBitsToFloat(int)
- * @since Android 1.0
*/
public static native int floatToIntBits(float value);
@@ -212,22 +179,20 @@
* Converts the specified float value to a binary representation conforming
* to the IEEE 754 floating-point single precision bit layout.
* <em>Not-a-Number (NaN)</em> values are preserved.
- *
+ *
* @param value
* the float value to convert.
* @return the IEEE 754 floating-point single precision representation of
* {@code value}.
* @see #floatToIntBits(float)
* @see #intBitsToFloat(int)
- * @since Android 1.0
*/
public static native int floatToRawIntBits(float value);
/**
* Gets the primitive value of this float.
- *
+ *
* @return this object's primitive value.
- * @since Android 1.0
*/
@Override
public float floatValue() {
@@ -242,14 +207,13 @@
/**
* Converts the specified IEEE 754 floating-point single precision bit
* pattern to a Java float value.
- *
+ *
* @param bits
* the IEEE 754 floating-point single precision representation of
* a float value.
* @return the float value converted from {@code bits}.
* @see #floatToIntBits(float)
* @see #floatToRawIntBits(float)
- * @since Android 1.0
*/
public static native float intBitsToFloat(int bits);
@@ -260,10 +224,9 @@
/**
* Indicates whether this object represents an infinite value.
- *
+ *
* @return {@code true} if the value of this float is positive or negative
* infinity; {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isInfinite() {
return isInfinite(value);
@@ -271,12 +234,11 @@
/**
* Indicates whether the specified float represents an infinite value.
- *
+ *
* @param f
* the float to check.
* @return {@code true} if the value of {@code f} is positive or negative
* infinity; {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean isInfinite(float f) {
return (f == POSITIVE_INFINITY) || (f == NEGATIVE_INFINITY);
@@ -284,10 +246,9 @@
/**
* Indicates whether this object is a <em>Not-a-Number (NaN)</em> value.
- *
+ *
* @return {@code true} if this float is <em>Not-a-Number</em>;
* {@code false} if it is a (potentially infinite) float number.
- * @since Android 1.0
*/
public boolean isNaN() {
return isNaN(value);
@@ -296,12 +257,11 @@
/**
* Indicates whether the specified float is a <em>Not-a-Number (NaN)</em>
* value.
- *
+ *
* @param f
* the float value to check.
* @return {@code true} if {@code f} is <em>Not-a-Number</em>;
* {@code false} if it is a (potentially infinite) float number.
- * @since Android 1.0
*/
public static boolean isNaN(float f) {
return f != f;
@@ -314,14 +274,15 @@
/**
* Parses the specified string as a float value.
- *
+ *
* @param string
* the string representation of a float value.
* @return the primitive float value represented by {@code string}.
* @throws NumberFormatException
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a float value.
- * @since Android 1.0
+ * @see #valueOf(String)
+ * @since 1.2
*/
public static float parseFloat(String string) throws NumberFormatException {
return org.apache.harmony.luni.util.FloatingPointParser
@@ -341,11 +302,10 @@
/**
* Returns a string containing a concise, human-readable description of the
* specified float value.
- *
+ *
* @param f
* the float to convert to a string.
* @return a printable representation of {@code f}.
- * @since Android 1.0
*/
public static String toString(float f) {
return org.apache.harmony.luni.util.NumberConverter.convert(f);
@@ -353,7 +313,7 @@
/**
* Parses the specified string as a float value.
- *
+ *
* @param string
* the string representation of a float value.
* @return a {@code Float} instance containing the float value represented
@@ -362,7 +322,6 @@
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a float value.
* @see #parseFloat(String)
- * @since Android 1.0
*/
public static Float valueOf(String string) throws NumberFormatException {
return valueOf(parseFloat(string));
@@ -375,7 +334,7 @@
* than any other float value, including {@code Float.POSITIVE_INFINITY};</li>
* <li>+0.0f is greater than -0.0f</li>
* </ul>
- *
+ *
* @param float1
* the first value to compare.
* @param float2
@@ -383,37 +342,46 @@
* @return a negative value if {@code float1} is less than {@code float2};
* 0 if {@code float1} and {@code float2} are equal; a positive
* value if {@code float1} is greater than {@code float2}.
- * @since Android 1.0
+ * @since 1.4
*/
public static int compare(float float1, float float2) {
- int f1, f2;
- int NaNbits = Float.floatToIntBits(Float.NaN);
- if ((f1 = Float.floatToIntBits(float1)) == NaNbits) {
- if (Float.floatToIntBits(float2) == NaNbits) {
+ // Non-zero, non-NaN checking.
+ if (float1 > float2) {
+ return 1;
+ }
+ if (float2 > float1) {
+ return -1;
+ }
+ if (float1 == float2 && 0.0f != float1) {
+ return 0;
+ }
+
+ // NaNs are equal to other NaNs and larger than any other float
+ if (isNaN(float1)) {
+ if (isNaN(float2)) {
return 0;
}
return 1;
- }
- if ((f2 = Float.floatToIntBits(float2)) == NaNbits) {
+ } else if (isNaN(float2)) {
return -1;
}
- if (float1 == float2) {
- if (f1 == f2) {
- return 0;
- }
- // check for -0
- return f1 > f2 ? 1 : -1;
- }
- return float1 > float2 ? 1 : -1;
+
+ // Deal with +0.0 and -0.0
+ int f1 = floatToRawIntBits(float1);
+ int f2 = floatToRawIntBits(float2);
+ // The below expression is equivalent to:
+ // (f1 == f2) ? 0 : (f1 < f2) ? -1 : 1
+ // because f1 and f2 are either 0 or Integer.MIN_VALUE
+ return (f1 >> 31) - (f2 >> 31);
}
/**
* Returns a {@code Float} instance for the specified float value.
- *
+ *
* @param f
* the float value to store in the instance.
* @return a {@code Float} instance containing {@code f}.
- * @since Android 1.0
+ * @since 1.5
*/
public static Float valueOf(float f) {
return new Float(f);
@@ -421,11 +389,11 @@
/**
* Converts the specified float into its hexadecimal string representation.
- *
+ *
* @param f
* the float to convert.
* @return the hexadecimal string representation of {@code f}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toHexString(float f) {
/*
diff --git a/luni/src/main/java/java/lang/IllegalAccessError.java b/luni/src/main/java/java/lang/IllegalAccessError.java
index 7f87afd..7fcef85 100644
--- a/luni/src/main/java/java/lang/IllegalAccessError.java
+++ b/luni/src/main/java/java/lang/IllegalAccessError.java
@@ -22,9 +22,6 @@
* which is not accessible from where it is referenced.
* <p>
* Note that this can only occur when inconsistent class files have been loaded.
- * </p>
- *
- * @since Android 1.0
*/
public class IllegalAccessError extends IncompatibleClassChangeError {
@@ -33,8 +30,6 @@
/**
* Constructs a new {@code IllegalAccessError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public IllegalAccessError() {
super();
@@ -46,7 +41,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public IllegalAccessError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/IllegalAccessException.java b/luni/src/main/java/java/lang/IllegalAccessException.java
index b9d2d69..d96fd56 100644
--- a/luni/src/main/java/java/lang/IllegalAccessException.java
+++ b/luni/src/main/java/java/lang/IllegalAccessException.java
@@ -20,8 +20,6 @@
/**
* Thrown when a program attempts to access a field or method which is not
* accessible from the location where the reference is made.
- *
- * @since Android 1.0
*/
public class IllegalAccessException extends Exception {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code IllegalAccessException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public IllegalAccessException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public IllegalAccessException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/IllegalArgumentException.java b/luni/src/main/java/java/lang/IllegalArgumentException.java
index 6f8dcf6..eb2ad91 100644
--- a/luni/src/main/java/java/lang/IllegalArgumentException.java
+++ b/luni/src/main/java/java/lang/IllegalArgumentException.java
@@ -20,8 +20,6 @@
/**
* Thrown when a method is invoked with an argument which it can not reasonably
* deal with.
- *
- * @since Android 1.0
*/
public class IllegalArgumentException extends RuntimeException {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code IllegalArgumentException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public IllegalArgumentException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public IllegalArgumentException(String detailMessage) {
super(detailMessage);
@@ -57,7 +52,7 @@
* the detail message for this exception.
* @param cause
* the cause of this exception, may be {@code null}.
- * @since Android 1.0
+ * @since 1.5
*/
public IllegalArgumentException(String message, Throwable cause) {
super(message, cause);
@@ -69,8 +64,8 @@
*
* @param cause
* the cause of this exception, may be {@code null}.
- * @since Android 1.0
- */
+ * @since 1.5
+ */
public IllegalArgumentException(Throwable cause) {
super((cause == null ? null : cause.toString()), cause);
}
diff --git a/luni/src/main/java/java/lang/IllegalMonitorStateException.java b/luni/src/main/java/java/lang/IllegalMonitorStateException.java
index e570bfd..a0b8a75 100644
--- a/luni/src/main/java/java/lang/IllegalMonitorStateException.java
+++ b/luni/src/main/java/java/lang/IllegalMonitorStateException.java
@@ -21,8 +21,6 @@
* Thrown when a monitor operation is attempted when the monitor is not in the
* correct state, for example when a thread attempts to exit a monitor which it
* does not own.
- *
- * @since Android 1.0
*/
public class IllegalMonitorStateException extends RuntimeException {
@@ -31,8 +29,6 @@
/**
* Constructs a new {@code IllegalMonitorStateException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public IllegalMonitorStateException() {
super();
@@ -44,7 +40,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public IllegalMonitorStateException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/IllegalStateException.java b/luni/src/main/java/java/lang/IllegalStateException.java
index 427aaf4..28db2de 100644
--- a/luni/src/main/java/java/lang/IllegalStateException.java
+++ b/luni/src/main/java/java/lang/IllegalStateException.java
@@ -20,8 +20,6 @@
/**
* Thrown when an action is attempted at a time when the virtual machine is not
* in the correct state.
- *
- * @since Android 1.0
*/
public class IllegalStateException extends RuntimeException {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code IllegalStateException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public IllegalStateException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public IllegalStateException(String detailMessage) {
super(detailMessage);
@@ -57,7 +52,7 @@
* the detail message for this exception.
* @param cause
* the cause of this exception.
- * @since Android 1.0
+ * @since 1.5
*/
public IllegalStateException(String message, Throwable cause) {
super(message, cause);
@@ -69,7 +64,7 @@
*
* @param cause
* the cause of this exception, may be {@code null}.
- * @since Android 1.0
+ * @since 1.5
*/
public IllegalStateException(Throwable cause) {
super((cause == null ? null : cause.toString()), cause);
diff --git a/luni/src/main/java/java/lang/IllegalThreadStateException.java b/luni/src/main/java/java/lang/IllegalThreadStateException.java
index 82eccbb..f1e99a8 100644
--- a/luni/src/main/java/java/lang/IllegalThreadStateException.java
+++ b/luni/src/main/java/java/lang/IllegalThreadStateException.java
@@ -20,8 +20,6 @@
/**
* Thrown when an operation is attempted which is not possible given the state
* that the executing thread is in.
- *
- * @since Android 1.0
*/
public class IllegalThreadStateException extends IllegalArgumentException {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code IllegalThreadStateException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public IllegalThreadStateException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public IllegalThreadStateException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/IncompatibleClassChangeError.java b/luni/src/main/java/java/lang/IncompatibleClassChangeError.java
index 83950fd..2155a28 100644
--- a/luni/src/main/java/java/lang/IncompatibleClassChangeError.java
+++ b/luni/src/main/java/java/lang/IncompatibleClassChangeError.java
@@ -24,7 +24,6 @@
* the same running image.
*
* @see Error
- * @since Android 1.0
*/
public class IncompatibleClassChangeError extends LinkageError {
@@ -33,8 +32,6 @@
/**
* Constructs a new {@code IncompatibleClassChangeError} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public IncompatibleClassChangeError() {
super();
@@ -46,7 +43,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public IncompatibleClassChangeError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/IndexOutOfBoundsException.java b/luni/src/main/java/java/lang/IndexOutOfBoundsException.java
index a4dc282..f26fcbf 100644
--- a/luni/src/main/java/java/lang/IndexOutOfBoundsException.java
+++ b/luni/src/main/java/java/lang/IndexOutOfBoundsException.java
@@ -20,8 +20,6 @@
/**
* Thrown when a program attempts to access a value in an indexable collection
* using a value which is outside of the range of valid indices.
- *
- * @since Android 1.0
*/
public class IndexOutOfBoundsException extends RuntimeException {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code IndexOutOfBoundsException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public IndexOutOfBoundsException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public IndexOutOfBoundsException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/InheritableThreadLocal.java b/luni/src/main/java/java/lang/InheritableThreadLocal.java
index 41e0d82..7e12ac2 100644
--- a/luni/src/main/java/java/lang/InheritableThreadLocal.java
+++ b/luni/src/main/java/java/lang/InheritableThreadLocal.java
@@ -1,17 +1,18 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package java.lang;
@@ -24,36 +25,33 @@
* creation time. However, subclasses may override {code #childValue(Object)}
* to provide an arbitrary function for passing the value of a parent's
* thread-local variable to the child's thread-local variable.
- *
+ *
* @see java.lang.Thread
* @see java.lang.ThreadLocal
- *
- * @since Android 1.0
*/
public class InheritableThreadLocal<T> extends ThreadLocal<T> {
/**
* Creates a new inheritable thread-local variable.
- *
- * @since Android 1.0
*/
- public InheritableThreadLocal() {}
+ public InheritableThreadLocal() {
+ super();
+ }
/**
* Computes the initial value of this thread-local variable for the child
- * thread given the parent thread's value. Called from the parent thread
- * when creating a child thread. The default implementation returns the
- * parent thread's value.
- *
- * @param parentValue
- * the value of the variable in the parent thread.
+ * thread given the parent thread's value. Called from the parent thread when
+ * creating a child thread. The default implementation returns the parent
+ * thread's value.
+ *
+ * @param parentValue the value of the variable in the parent thread.
* @return the initial value of the variable for the child thread.
- * @since Android 1.0
*/
protected T childValue(T parentValue) {
return parentValue;
}
+ // BEGIN android-added
@Override
Values values(Thread current) {
return current.inheritableValues;
@@ -63,4 +61,5 @@
Values initializeValues(Thread current) {
return current.inheritableValues = new Values();
}
+ // END android-added
}
diff --git a/luni/src/main/java/java/lang/InstantiationError.java b/luni/src/main/java/java/lang/InstantiationError.java
index 0d387c6..9ad1ed6 100644
--- a/luni/src/main/java/java/lang/InstantiationError.java
+++ b/luni/src/main/java/java/lang/InstantiationError.java
@@ -23,9 +23,6 @@
* {@code new} is invoked.
* <p>
* Note that this can only occur when inconsistent class files are being loaded.
- * </p>
- *
- * @since Android 1.0
*/
public class InstantiationError extends IncompatibleClassChangeError {
private static final long serialVersionUID = -4885810657349421204L;
@@ -33,8 +30,6 @@
/**
* Constructs a new {@code InstantiationError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public InstantiationError() {
super();
@@ -46,7 +41,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public InstantiationError(String detailMessage) {
super(detailMessage);
@@ -58,7 +52,6 @@
*
* @param clazz
* the class that can not be instantiated.
- * @since Android 1.0
*/
InstantiationError(Class<?> clazz) {
super(clazz.getName());
diff --git a/luni/src/main/java/java/lang/InstantiationException.java b/luni/src/main/java/java/lang/InstantiationException.java
index cc8b556..fe68345 100644
--- a/luni/src/main/java/java/lang/InstantiationException.java
+++ b/luni/src/main/java/java/lang/InstantiationException.java
@@ -20,8 +20,6 @@
/**
* Thrown when a program attempts to access a constructor which is not
* accessible from the location where the reference is made.
- *
- * @since Android 1.0
*/
public class InstantiationException extends Exception {
private static final long serialVersionUID = -8441929162975509110L;
@@ -29,8 +27,6 @@
/**
* Constructs a new {@code InstantiationException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public InstantiationException() {
super();
@@ -42,7 +38,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public InstantiationException(String detailMessage) {
super(detailMessage);
@@ -54,7 +49,6 @@
*
* @param clazz
* the class that can not be instantiated.
- * @since Android 1.0
*/
InstantiationException(Class<?> clazz) {
super(clazz.getName());
diff --git a/luni/src/main/java/java/lang/Integer.java b/luni/src/main/java/java/lang/Integer.java
index 3a98872..570120b 100644
--- a/luni/src/main/java/java/lang/Integer.java
+++ b/luni/src/main/java/java/lang/Integer.java
@@ -24,10 +24,9 @@
* href="http://www.hackersdelight.org/">Henry S. Warren, Jr.'s Hacker's
* Delight, (Addison Wesley, 2002)</a> as well as <a
* href="http://aggregate.org/MAGIC/">The Aggregate's Magic Algorithms</a>.
- * </p>
- *
+ *
* @see java.lang.Number
- * @since Android 1.0
+ * @since 1.1
*/
public final class Integer extends Number implements Comparable<Integer> {
@@ -40,30 +39,32 @@
/**
* Constant for the maximum {@code int} value, 2<sup>31</sup>-1.
- *
- * @since Android 1.0
*/
public static final int MAX_VALUE = 0x7FFFFFFF;
/**
* Constant for the minimum {@code int} value, -2<sup>31</sup>.
- *
- * @since Android 1.0
*/
public static final int MIN_VALUE = 0x80000000;
/**
* Constant for the number of bits needed to represent an {@code int} in
* two's complement form.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int SIZE = 32;
+ /*
+ * Progressively smaller decimal order of magnitude that can be represented
+ * by an instance of Integer. Used to help compute the String
+ * representation.
+ */
+ private static final int[] decimalScale = new int[] { 1000000000, 100000000,
+ 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 };
+
/**
* The {@link Class} object that represents the primitive type {@code int}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Class<Integer> TYPE = (Class<Integer>) new int[0]
@@ -75,10 +76,9 @@
/**
* Constructs a new {@code Integer} with the specified primitive integer
* value.
- *
+ *
* @param value
* the primitive integer value to store in the new instance.
- * @since Android 1.0
*/
public Integer(int value) {
this.value = value;
@@ -86,13 +86,12 @@
/**
* Constructs a new {@code Integer} from the specified string.
- *
+ *
* @param string
* the string representation of an integer value.
* @throws NumberFormatException
* if {@code string} can not be decoded into an integer value.
* @see #parseInt(String)
- * @since Android 1.0
*/
public Integer(String string) throws NumberFormatException {
this(parseInt(string));
@@ -106,7 +105,7 @@
/**
* Compares this object to the specified integer object to determine their
* relative order.
- *
+ *
* @param object
* the integer object to compare this object to.
* @return a negative value if the value of this integer is less than the
@@ -114,7 +113,7 @@
* value of {@code object} are equal; a positive value if the value
* of this integer is greater than the value of {@code object}.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.2
*/
public int compareTo(Integer object) {
return value > object.value ? 1 : (value < object.value ? -1 : 0);
@@ -125,14 +124,13 @@
* string can be decoded into an integer value. The string may be an
* optional minus sign "-" followed by a hexadecimal ("0x..." or "#..."),
* octal ("0..."), or decimal ("...") representation of an integer.
- *
+ *
* @param string
* a string representation of an integer value.
* @return an {@code Integer} containing the value represented by
* {@code string}.
* @throws NumberFormatException
* if {@code string} can not be parsed as an integer value.
- * @since Android 1.0
*/
public static Integer decode(String string) throws NumberFormatException {
int length = string.length(), i = 0;
@@ -158,23 +156,21 @@
return valueOf(0);
}
if ((firstDigit = string.charAt(i)) == 'x' || firstDigit == 'X') {
- if (i == length) {
+ if (++i == length) {
// BEGIN android-changed
throw new NumberFormatException("unable to parse '"+string+"' as integer");
// END android-changed
}
- i++;
base = 16;
} else {
base = 8;
}
} else if (firstDigit == '#') {
- if (i == length) {
+ if (++i == length) {
// BEGIN android-changed
throw new NumberFormatException("unable to parse '"+string+"' as integer");
// END android-changed
}
- i++;
base = 16;
}
@@ -191,12 +187,11 @@
* Compares this instance with the specified object and indicates if they
* are equal. In order to be equal, {@code o} must be an instance of
* {@code Integer} and have the same integer value as this object.
- *
+ *
* @param o
* the object to compare this integer with.
* @return {@code true} if the specified object is equal to this
* {@code Integer}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object o) {
@@ -214,12 +209,11 @@
* {@code string}. Returns {@code null} if {@code string} is {@code null}
* or empty, if the property can not be found or if its value can not be
* parsed as an integer.
- *
+ *
* @param string
* the name of the requested system property.
* @return the requested property's value as an {@code Integer} or
* {@code null}.
- * @since Android 1.0
*/
public static Integer getInteger(String string) {
if (string == null || string.length() == 0) {
@@ -241,7 +235,7 @@
* {@code string}. Returns the specified default value if {@code string} is
* {@code null} or empty, if the property can not be found or if its value
* can not be parsed as an integer.
- *
+ *
* @param string
* the name of the requested system property.
* @param defaultValue
@@ -249,7 +243,6 @@
* system property with the requested name.
* @return the requested property's value as an {@code Integer} or the
* default value.
- * @since Android 1.0
*/
public static Integer getInteger(String string, int defaultValue) {
if (string == null || string.length() == 0) {
@@ -271,7 +264,7 @@
* {@code string}. Returns the specified default value if {@code string} is
* {@code null} or empty, if the property can not be found or if its value
* can not be parsed as an integer.
- *
+ *
* @param string
* the name of the requested system property.
* @param defaultValue
@@ -279,7 +272,6 @@
* system property with the requested name.
* @return the requested property's value as an {@code Integer} or the
* default value.
- * @since Android 1.0
*/
public static Integer getInteger(String string, Integer defaultValue) {
if (string == null || string.length() == 0) {
@@ -303,9 +295,8 @@
/**
* Gets the primitive value of this int.
- *
+ *
* @return this object's primitive value.
- * @since Android 1.0
*/
@Override
public int intValue() {
@@ -320,14 +311,13 @@
/**
* Parses the specified string as a signed decimal integer value. The ASCII
* character \u002d ('-') is recognized as the minus sign.
- *
+ *
* @param string
* the string representation of an integer value.
* @return the primitive integer value represented by {@code string}.
* @throws NumberFormatException
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as an integer value.
- * @since Android 1.0
*/
public static int parseInt(String string) throws NumberFormatException {
return parseInt(string, 10);
@@ -336,7 +326,7 @@
/**
* Parses the specified string as a signed integer value using the specified
* radix. The ASCII character \u002d ('-') is recognized as the minus sign.
- *
+ *
* @param string
* the string representation of an integer value.
* @param radix
@@ -348,7 +338,6 @@
* {@code radix < Character.MIN_RADIX},
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as an integer value.
- * @since Android 1.0
*/
public static int parseInt(String string, int radix)
throws NumberFormatException {
@@ -417,11 +406,10 @@
/**
* Converts the specified integer into its binary string representation. The
* returned string is a concatenation of '0' and '1' characters.
- *
+ *
* @param i
* the integer to convert.
* @return the binary string representation of {@code i}.
- * @since Android 1.0
*/
public static String toBinaryString(int i) {
int count = 1, j = i;
@@ -446,12 +434,11 @@
* Converts the specified integer into its hexadecimal string
* representation. The returned string is a concatenation of characters from
* '0' to '9' and 'a' to 'f'.
- *
+ *
* @param i
* the integer to convert.
* @return the hexadecimal string representation of {@code i}.
- * @since Android 1.0
- */
+ */
public static String toHexString(int i) {
int count = 1, j = i;
@@ -480,12 +467,11 @@
/**
* Converts the specified integer into its octal string representation. The
* returned string is a concatenation of characters from '0' to '7'.
- *
+ *
* @param i
* the integer to convert.
* @return the octal string representation of {@code i}.
- * @since Android 1.0
- */
+ */
public static String toOctalString(int i) {
int count = 1, j = i;
@@ -514,14 +500,102 @@
* Converts the specified integer into its decimal string representation.
* The returned string is a concatenation of a minus sign if the number is
* negative and characters from '0' to '9'.
- *
- * @param i
+ *
+ * @param value
* the integer to convert.
- * @return the decimal string representation of {@code i}.
- * @since Android 1.0
- */
- public static String toString(int i) {
- return toString(i, 10);
+ * @return the decimal string representation of {@code value}.
+ */
+ public static String toString(int value) {
+ // BEGIN android-note
+ // cache the strings in the range 0..99 to save allocations?
+ // END android-note
+ if (value == 0) {
+ return "0"; //$NON-NLS-1$
+ }
+
+ // Faster algorithm for smaller Integers
+ if (value < 1000 && value > -1000) {
+ char[] buffer = new char[4];
+ int positive_value = value < 0 ? -value : value;
+ int first_digit = 0;
+ if (value < 0) {
+ buffer[0] = '-';
+ first_digit++;
+ }
+ int last_digit = first_digit;
+ int quot = positive_value;
+ do {
+ int res = quot / 10;
+ int digit_value = quot - (res * 10);
+ digit_value += '0';
+ buffer[last_digit++] = (char) digit_value;
+ quot = res;
+ } while (quot != 0);
+
+ int count = last_digit--;
+ do {
+ char tmp = buffer[last_digit];
+ buffer[last_digit--] = buffer[first_digit];
+ buffer[first_digit++] = tmp;
+ } while (first_digit < last_digit);
+ return new String(0, count, buffer);
+ }
+ if (value == MIN_VALUE) {
+ return "-2147483648";//$NON-NLS-1$
+ }
+
+ char[] buffer = new char[11];
+ int positive_value = value < 0 ? -value : value;
+ byte first_digit = 0;
+ if (value < 0) {
+ buffer[0] = '-';
+ first_digit++;
+ }
+ byte last_digit = first_digit;
+ byte count;
+ int number;
+ boolean start = false;
+ for (int i = 0; i < 9; i++) {
+ count = 0;
+ if (positive_value < (number = decimalScale[i])) {
+ if (start) {
+ buffer[last_digit++] = '0';
+ }
+ continue;
+ }
+
+ if (i > 0) {
+ number = (decimalScale[i] << 3);
+ if (positive_value >= number) {
+ positive_value -= number;
+ count += 8;
+ }
+ number = (decimalScale[i] << 2);
+ if (positive_value >= number) {
+ positive_value -= number;
+ count += 4;
+ }
+ }
+ number = (decimalScale[i] << 1);
+ if (positive_value >= number) {
+ positive_value -= number;
+ count += 2;
+ }
+ if (positive_value >= decimalScale[i]) {
+ positive_value -= decimalScale[i];
+ count++;
+ }
+ if (count > 0 && !start) {
+ start = true;
+ }
+ if (start) {
+ buffer[last_digit++] = (char) (count + '0');
+ }
+ }
+
+ buffer[last_digit++] = (char) (positive_value + '0');
+ count = last_digit--;
+ return new String(0, count, buffer);
}
/**
@@ -531,15 +605,18 @@
* depending on the radix. If {@code radix} is not in the interval defined
* by {@code Character.MIN_RADIX} and {@code Character.MAX_RADIX} then 10 is
* used as the base for the conversion.
- *
+ *
* @param i
* the integer to convert.
* @param radix
* the base to use for the conversion.
* @return the string representation of {@code i}.
- * @since Android 1.0
- */
+ */
public static String toString(int i, int radix) {
+ // BEGIN android-note
+ // if radix==10, call thru to faster Integer.toString(int) ?
+ // only worthwhile if 10 is a popular parameter
+ // END android-note
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
radix = 10;
}
@@ -575,7 +652,7 @@
/**
* Parses the specified string as a signed decimal integer value.
- *
+ *
* @param string
* the string representation of an integer value.
* @return an {@code Integer} instance containing the integer value
@@ -584,7 +661,6 @@
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as an integer value.
* @see #parseInt(String)
- * @since Android 1.0
*/
public static Integer valueOf(String string) throws NumberFormatException {
return valueOf(parseInt(string));
@@ -593,7 +669,7 @@
/**
* Parses the specified string as a signed integer value using the specified
* radix.
- *
+ *
* @param string
* the string representation of an integer value.
* @param radix
@@ -606,7 +682,6 @@
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as an integer value.
* @see #parseInt(String, int)
- * @since Android 1.0
*/
public static Integer valueOf(String string, int radix)
throws NumberFormatException {
@@ -618,11 +693,11 @@
* and returns the bit mask value for that bit. This is also referred to as
* the Most Significant 1 Bit. Returns zero if the specified integer is
* zero.
- *
+ *
* @param i
* the integer to examine.
* @return the bit mask indicating the highest 1 bit in {@code i}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int highestOneBit(int i) {
i |= (i >> 1);
@@ -638,11 +713,11 @@
* and returns the bit mask value for that bit. This is also referred
* to as the Least Significant 1 Bit. Returns zero if the specified integer
* is zero.
- *
+ *
* @param i
* the integer to examine.
* @return the bit mask indicating the lowest 1 bit in {@code i}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int lowestOneBit(int i) {
return (i & (-i));
@@ -651,11 +726,11 @@
/**
* Determines the number of leading zeros in the specified integer prior to
* the {@link #highestOneBit(int) highest one bit}.
- *
+ *
* @param i
* the integer to examine.
* @return the number of leading zeros in {@code i}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int numberOfLeadingZeros(int i) {
i |= i >> 1;
@@ -669,11 +744,11 @@
/**
* Determines the number of trailing zeros in the specified integer after
* the {@link #lowestOneBit(int) lowest one bit}.
- *
+ *
* @param i
* the integer to examine.
* @return the number of trailing zeros in {@code i}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int numberOfTrailingZeros(int i) {
return bitCount((i & -i) - 1);
@@ -682,11 +757,11 @@
/**
* Counts the number of 1 bits in the specified integer; this is also
* referred to as population count.
- *
+ *
* @param i
* the integer to examine.
* @return the number of 1 bits in {@code i}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int bitCount(int i) {
i -= ((i >> 1) & 0x55555555);
@@ -700,13 +775,13 @@
/**
* Rotates the bits of the specified integer to the left by the specified
* number of bits.
- *
+ *
* @param i
* the integer value to rotate left.
* @param distance
* the number of bits to rotate.
* @return the rotated value.
- * @since Android 1.0
+ * @since 1.5
*/
public static int rotateLeft(int i, int distance) {
if (distance == 0) {
@@ -723,13 +798,13 @@
/**
* Rotates the bits of the specified integer to the right by the specified
* number of bits.
- *
+ *
* @param i
* the integer value to rotate right.
* @param distance
* the number of bits to rotate.
* @return the rotated value.
- * @since Android 1.0
+ * @since 1.5
*/
public static int rotateRight(int i, int distance) {
if (distance == 0) {
@@ -745,11 +820,11 @@
/**
* Reverses the order of the bytes of the specified integer.
- *
+ *
* @param i
* the integer value for which to reverse the byte order.
* @return the reversed value.
- * @since Android 1.0
+ * @since 1.5
*/
public static int reverseBytes(int i) {
int b3 = i >>> 24;
@@ -761,11 +836,11 @@
/**
* Reverses the order of the bits of the specified integer.
- *
+ *
* @param i
* the integer value for which to reverse the bit order.
* @return the reversed value.
- * @since Android 1.0
+ * @since 1.5
*/
public static int reverse(int i) {
// From Hacker's Delight, 7-1, Figure 7-1
@@ -778,12 +853,12 @@
/**
* Returns the value of the {@code signum} function for the specified
* integer.
- *
+ *
* @param i
* the integer value to check.
* @return -1 if {@code i} is negative, 1 if {@code i} is positive, 0 if
* {@code i} is zero.
- * @since Android 1.0
+ * @since 1.5
*/
public static int signum(int i) {
return (i == 0 ? 0 : (i < 0 ? -1 : 1));
@@ -795,12 +870,11 @@
* If it is not necessary to get a new {@code Integer} instance, it is
* recommended to use this method instead of the constructor, since it
* maintains a cache of instances which may result in better performance.
- * </p>
- *
+ *
* @param i
* the integer value to store in the instance.
* @return a {@code Integer} instance containing {@code i}.
- * @since Android 1.0
+ * @since 1.5
*/
public static Integer valueOf(int i) {
if (i < -128 || i > 127) {
@@ -814,7 +888,6 @@
/**
* <p>
* A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing.
- * </p>
*/
static final Integer[] CACHE = new Integer[256];
diff --git a/luni/src/main/java/java/lang/InternalError.java b/luni/src/main/java/java/lang/InternalError.java
index 9082cd8..d4748af 100644
--- a/luni/src/main/java/java/lang/InternalError.java
+++ b/luni/src/main/java/java/lang/InternalError.java
@@ -20,8 +20,6 @@
/**
* Thrown when the virtual machine notices that it has gotten into an undefined
* state.
- *
- * @since Android 1.0
*/
public class InternalError extends VirtualMachineError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code InternalError} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public InternalError() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public InternalError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/InterruptedException.java b/luni/src/main/java/java/lang/InterruptedException.java
index b014559..0e099c3 100644
--- a/luni/src/main/java/java/lang/InterruptedException.java
+++ b/luni/src/main/java/java/lang/InterruptedException.java
@@ -20,8 +20,6 @@
/**
* Thrown when a waiting thread is activated before the condition it was waiting
* for has been satisfied.
- *
- * @since Android 1.0
*/
public class InterruptedException extends Exception {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code InterruptedException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public InterruptedException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public InterruptedException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/Iterable.java b/luni/src/main/java/java/lang/Iterable.java
index d12f0a6..31883fb 100644
--- a/luni/src/main/java/java/lang/Iterable.java
+++ b/luni/src/main/java/java/lang/Iterable.java
@@ -21,8 +21,8 @@
/**
* Objects of classes that implement this interface can be used within a
* {@code foreach} statement.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public interface Iterable<T> {
@@ -30,7 +30,6 @@
* Returns an {@link Iterator} for the elements in this object.
*
* @return An {@code Iterator} instance.
- * @since Android 1.0
*/
Iterator<T> iterator();
}
diff --git a/luni/src/main/java/java/lang/LinkageError.java b/luni/src/main/java/java/lang/LinkageError.java
index 9bba54b..061f3dc 100644
--- a/luni/src/main/java/java/lang/LinkageError.java
+++ b/luni/src/main/java/java/lang/LinkageError.java
@@ -23,7 +23,6 @@
* loading and linking class files.
*
* @see Error
- * @since Android 1.0
*/
public class LinkageError extends Error {
@@ -32,8 +31,6 @@
/**
* Constructs a new {@code LinkageError} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public LinkageError() {
super();
@@ -45,7 +42,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public LinkageError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/Long.java b/luni/src/main/java/java/lang/Long.java
index 00b56ae..2746424 100644
--- a/luni/src/main/java/java/lang/Long.java
+++ b/luni/src/main/java/java/lang/Long.java
@@ -24,10 +24,9 @@
* href="http://www.hackersdelight.org/">Henry S. Warren, Jr.'s Hacker's
* Delight, (Addison Wesley, 2002)</a> as well as <a
* href="http://aggregate.org/MAGIC/">The Aggregate's Magic Algorithms</a>.
- * </p>
- *
+ *
* @see java.lang.Number
- * @since Android 1.0
+ * @since 1.0
*/
public final class Long extends Number implements Comparable<Long> {
@@ -40,22 +39,16 @@
/**
* Constant for the maximum {@code long} value, 2<sup>63</sup>-1.
- *
- * @since Android 1.0
*/
public static final long MAX_VALUE = 0x7FFFFFFFFFFFFFFFL;
/**
* Constant for the minimum {@code long} value, -2<sup>63</sup>.
- *
- * @since Android 1.0
*/
public static final long MIN_VALUE = 0x8000000000000000L;
/**
* The {@link Class} object that represents the primitive type {@code long}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Class<Long> TYPE = (Class<Long>) new long[0].getClass()
@@ -67,8 +60,8 @@
/**
* Constant for the number of bits needed to represent a {@code long} in
* two's complement form.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int SIZE = 64;
@@ -78,7 +71,6 @@
*
* @param value
* the primitive long value to store in the new instance.
- * @since Android 1.0
*/
public Long(long value) {
this.value = value;
@@ -92,7 +84,6 @@
* @throws NumberFormatException
* if {@code string} can not be decoded into a long value.
* @see #parseLong(String)
- * @since Android 1.0
*/
public Long(String string) throws NumberFormatException {
this(parseLong(string));
@@ -114,7 +105,7 @@
* {@code object} are equal; a positive value if the value of this
* long is greater than the value of {@code object}.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.2
*/
public int compareTo(Long object) {
return value > object.value ? 1 : (value < object.value ? -1 : 0);
@@ -131,7 +122,6 @@
* @return a {@code Long} containing the value represented by {@code string}.
* @throws NumberFormatException
* if {@code string} can not be parsed as a long value.
- * @since Android 1.0
*/
public static Long decode(String string) throws NumberFormatException {
int length = string.length(), i = 0;
@@ -187,7 +177,6 @@
* the object to compare this long with.
* @return {@code true} if the specified object is equal to this
* {@code Long}; {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object o) {
@@ -209,7 +198,6 @@
* @param string
* the name of the requested system property.
* @return the requested property's value as a {@code Long} or {@code null}.
- * @since Android 1.0
*/
public static Long getLong(String string) {
if (string == null || string.length() == 0) {
@@ -239,7 +227,6 @@
* property with the requested name.
* @return the requested property's value as a {@code Long} or the default
* value.
- * @since Android 1.0
*/
public static Long getLong(String string, long defaultValue) {
if (string == null || string.length() == 0) {
@@ -269,7 +256,6 @@
* property with the requested name.
* @return the requested property's value as a {@code Long} or the default
* value.
- * @since Android 1.0
*/
public static Long getLong(String string, Long defaultValue) {
if (string == null || string.length() == 0) {
@@ -300,7 +286,6 @@
* Gets the primitive value of this long.
*
* @return this object's primitive value.
- * @since Android 1.0
*/
@Override
public long longValue() {
@@ -317,7 +302,6 @@
* @throws NumberFormatException
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a long value.
- * @since Android 1.0
*/
public static long parseLong(String string) throws NumberFormatException {
return parseLong(string, 10);
@@ -338,7 +322,6 @@
* {@code radix < Character.MIN_RADIX},
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as a long value.
- * @since Android 1.0
*/
public static long parseLong(String string, int radix)
throws NumberFormatException {
@@ -397,7 +380,6 @@
* @param l
* the long value to convert.
* @return the binary string representation of {@code l}.
- * @since Android 1.0
*/
public static String toBinaryString(long l) {
int count = 1;
@@ -427,7 +409,6 @@
* @param l
* the long value to convert.
* @return the hexadecimal string representation of {@code l}.
- * @since Android 1.0
*/
public static String toHexString(long l) {
int count = 1;
@@ -462,7 +443,6 @@
* @param l
* the long value to convert.
* @return the octal string representation of {@code l}.
- * @since Android 1.0
*/
public static String toOctalString(long l) {
int count = 1;
@@ -497,8 +477,7 @@
* @param l
* the long to convert.
* @return the decimal string representation of {@code l}.
- * @since Android 1.0
- */
+ */
public static String toString(long l) {
return toString(l, 10);
}
@@ -516,7 +495,6 @@
* @param radix
* the base to use for the conversion.
* @return the string representation of {@code l}.
- * @since Android 1.0
*/
public static String toString(long l, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
@@ -564,7 +542,6 @@
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a long value.
* @see #parseLong(String)
- * @since Android 1.0
*/
public static Long valueOf(String string) throws NumberFormatException {
return valueOf(parseLong(string));
@@ -586,7 +563,6 @@
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as a long value.
* @see #parseLong(String, int)
- * @since Android 1.0
*/
public static Long valueOf(String string, int radix)
throws NumberFormatException {
@@ -602,7 +578,7 @@
* @param lng
* the long to examine.
* @return the bit mask indicating the highest 1 bit in {@code lng}.
- * @since Android 1.0
+ * @since 1.5
*/
public static long highestOneBit(long lng) {
lng |= (lng >> 1);
@@ -623,7 +599,7 @@
* @param lng
* the long to examine.
* @return the bit mask indicating the lowest 1 bit in {@code lng}.
- * @since Android 1.0
+ * @since 1.5
*/
public static long lowestOneBit(long lng) {
return (lng & (-lng));
@@ -632,11 +608,11 @@
/**
* Determines the number of leading zeros in the specified long value prior
* to the {@link #highestOneBit(long) highest one bit}.
- *
+ *
* @param lng
* the long to examine.
* @return the number of leading zeros in {@code lng}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int numberOfLeadingZeros(long lng) {
lng |= lng >> 1;
@@ -651,11 +627,11 @@
/**
* Determines the number of trailing zeros in the specified long value after
* the {@link #lowestOneBit(long) lowest one bit}.
- *
+ *
* @param lng
* the long to examine.
* @return the number of trailing zeros in {@code lng}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int numberOfTrailingZeros(long lng) {
return bitCount((lng & -lng) - 1);
@@ -664,11 +640,11 @@
/**
* Counts the number of 1 bits in the specified long value; this is also
* referred to as population count.
- *
+ *
* @param lng
* the long to examine.
* @return the number of 1 bits in {@code lng}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int bitCount(long lng) {
lng = (lng & 0x5555555555555555L) + ((lng >> 1) & 0x5555555555555555L);
@@ -684,13 +660,13 @@
/**
* Rotates the bits of the specified long value to the left by the specified
* number of bits.
- *
+ *
* @param lng
* the long value to rotate left.
* @param distance
* the number of bits to rotate.
* @return the rotated value.
- * @since Android 1.0
+ * @since 1.5
*/
public static long rotateLeft(long lng, int distance) {
if (distance == 0) {
@@ -705,15 +681,16 @@
}
/**
+ * <p>
* Rotates the bits of the specified long value to the right by the
* specified number of bits.
- *
+ *
* @param lng
* the long value to rotate right.
* @param distance
* the number of bits to rotate.
* @return the rotated value.
- * @since Android 1.0
+ * @since 1.5
*/
public static long rotateRight(long lng, int distance) {
if (distance == 0) {
@@ -733,7 +710,7 @@
* @param lng
* the long value for which to reverse the byte order.
* @return the reversed value.
- * @since Android 1.0
+ * @since 1.5
*/
public static long reverseBytes(long lng) {
long b7 = lng >>> 56;
@@ -753,7 +730,7 @@
* @param lng
* the long value for which to reverse the bit order.
* @return the reversed value.
- * @since Android 1.0
+ * @since 1.5
*/
public static long reverse(long lng) {
// From Hacker's Delight, 7-1, Figure 7-1
@@ -774,7 +751,7 @@
* the long value to check.
* @return -1 if {@code lng} is negative, 1 if {@code lng} is positive, 0 if
* {@code lng} is zero.
- * @since Android 1.0
+ * @since 1.5
*/
public static int signum(long lng) {
return (lng == 0 ? 0 : (lng < 0 ? -1 : 1));
@@ -786,12 +763,11 @@
* If it is not necessary to get a new {@code Long} instance, it is
* recommended to use this method instead of the constructor, since it
* maintains a cache of instances which may result in better performance.
- * </p>
- *
+ *
* @param lng
* the long value to store in the instance.
* @return a {@code Long} instance containing {@code lng}.
- * @since Android 1.0
+ * @since 1.5
*/
public static Long valueOf(long lng) {
if (lng < -128 || lng > 127) {
@@ -804,7 +780,6 @@
/**
* <p>
* A cache of instances used by {@link Long#valueOf(long)} and auto-boxing.
- * </p>
*/
static final Long[] CACHE = new Long[256];
diff --git a/luni/src/main/java/java/lang/Math.java b/luni/src/main/java/java/lang/Math.java
index f18f40f..998856a 100644
--- a/luni/src/main/java/java/lang/Math.java
+++ b/luni/src/main/java/java/lang/Math.java
@@ -17,26 +17,21 @@
package java.lang;
+
/**
* Class Math provides basic math constants and operations such as trigonometric
* functions, hyperbolic functions, exponential, logarithms, etc.
- *
- * @since Android 1.0
*/
public final class Math {
/**
* The double value closest to e, the base of the natural logarithm.
- *
- * @since Android 1.0
*/
public static final double E = 2.718281828459045;
/**
* The double value closest to pi, the ratio of a circle's circumference to
* its diameter.
- *
- * @since Android 1.0
*/
public static final double PI = 3.141592653589793;
@@ -58,18 +53,16 @@
* <li>{@code abs(-infinity) = +infinity}</li>
* <li>{@code abs(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose absolute value has to be computed.
* @return the absolute value of the argument.
- * @since Android 1.0
*/
- public static double abs(double d) {
- long bits = Double.doubleToLongBits(d);
- bits &= 0x7fffffffffffffffL;
- return Double.longBitsToDouble(bits);
- }
+ public static double abs(double d) {
+ long bits = Double.doubleToLongBits(d);
+ bits &= 0x7fffffffffffffffL;
+ return Double.longBitsToDouble(bits);
+ }
/**
* Returns the absolute value of the argument.
@@ -81,50 +74,45 @@
* <li>{@code abs(-infinity) = +infinity}</li>
* <li>{@code abs(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param f
* the value whose absolute value has to be computed.
* @return the argument if it is positive, otherwise the negation of the
* argument.
- * @since Android 1.0
*/
- public static float abs(float f) {
- int bits = Float.floatToIntBits(f);
- bits &= 0x7fffffff;
- return Float.intBitsToFloat(bits);
- }
+ public static float abs(float f) {
+ int bits = Float.floatToIntBits(f);
+ bits &= 0x7fffffff;
+ return Float.intBitsToFloat(bits);
+ }
/**
* Returns the absolute value of the argument.
* <p>
* If the argument is {@code Integer.MIN_VALUE}, {@code Integer.MIN_VALUE}
* is returned.
- * </p>
- *
+ *
* @param i
* the value whose absolute value has to be computed.
* @return the argument if it is positive, otherwise the negation of the
* argument.
- * @since Android 1.0
*/
- public static int abs(int i) {
- return i >= 0 ? i : -i;
- }
+ public static int abs(int i) {
+ return i >= 0 ? i : -i;
+ }
/**
* Returns the absolute value of the argument. If the argument is {@code
* Long.MIN_VALUE}, {@code Long.MIN_VALUE} is returned.
- *
+ *
* @param l
* the value whose absolute value has to be computed.
* @return the argument if it is positive, otherwise the negation of the
* argument.
- * @since Android 1.0
*/
- public static long abs(long l) {
- return l >= 0 ? l : -l;
- }
+ public static long abs(long l) {
+ return l >= 0 ? l : -l;
+ }
/**
* Returns the closest double approximation of the arc cosine of the
@@ -137,14 +125,12 @@
* <li>{@code acos((anything < -1) = NaN}</li>
* <li>{@code acos(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to compute arc cosine of.
* @return the arc cosine of the argument.
- * @since Android 1.0
*/
- public static native double acos(double d);
+ public static native double acos(double d);
/**
* Returns the closest double approximation of the arc sine of the argument
@@ -157,14 +143,12 @@
* <li>{@code asin((anything < -1)) = NaN}</li>
* <li>{@code asin(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose arc sine has to be computed.
* @return the arc sine of the argument.
- * @since Android 1.0
*/
- public static native double asin(double d);
+ public static native double asin(double d);
/**
* Returns the closest double approximation of the arc tangent of the
@@ -179,12 +163,10 @@
* <li>{@code atan(-infinity) = -pi/2}</li>
* <li>{@code atan(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose arc tangent has to be computed.
* @return the arc tangent of the argument.
- * @since Android 1.0
*/
public static native double atan(double d);
@@ -219,19 +201,14 @@
* <li>{@code atan2(-infinity, (anything but,0, NaN, and infinity))}
* {@code =} {@code -pi/2}</li>
* </ul>
- * </p>
- *
+ *
* @param y
* the numerator of the value whose atan has to be computed.
* @param x
* the denominator of the value whose atan has to be computed.
* @return the arc tangent of {@code y/x}.
- * @since Android 1.0
*/
- public static native double atan2(double y, double x);
- // BEGIN android-note
- // parameter names changed from d1 / d2 to x / y
- // END android-note
+ public static native double atan2(double x, double y);
/**
* Returns the closest double approximation of the cube root of the
@@ -245,12 +222,10 @@
* <li>{@code cbrt(-infinity) = -infinity}</li>
* <li>{@code cbrt(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose cube root has to be computed.
* @return the cube root of the argument.
- * @since Android 1.0
*/
public static native double cbrt(double d);
@@ -267,16 +242,14 @@
* <li>{@code ceil(-infinity) = -infinity}</li>
* <li>{@code ceil(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose closest integer value has to be computed.
* @return the ceiling of the argument.
- * @since Android 1.0
*/
public static native double ceil(double d);
- /**
+ /**
* Returns the closest double approximation of the cosine of the argument.
* The returned result is within 1 ulp (unit in the last place) of the real
* result.
@@ -287,15 +260,13 @@
* <li>{@code cos(-infinity) = NaN}</li>
* <li>{@code cos(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the angle whose cosine has to be computed, in radians.
* @return the cosine of the argument.
- * @since Android 1.0
*/
public static native double cos(double d);
-
+
/**
* Returns the closest double approximation of the hyperbolic cosine of the
* argument. The returned result is within 2.5 ulps (units in the last
@@ -307,12 +278,10 @@
* <li>{@code cosh(-infinity) = +infinity}</li>
* <li>{@code cosh(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose hyperbolic cosine has to be computed.
* @return the hyperbolic cosine of the argument.
- * @since Android 1.0
*/
public static native double cosh(double d);
@@ -327,15 +296,13 @@
* <li>{@code exp(-infinity) = +0.0}</li>
* <li>{@code exp(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose exponential has to be computed.
* @return the exponential of the argument.
- * @since Android 1.0
*/
public static native double exp(double d);
-
+
/**
* Returns the closest double approximation of <i>{@code e}</i><sup>
* {@code d}</sup>{@code - 1}. If the argument is very close to 0, it is
@@ -354,14 +321,12 @@
* <li>{@code expm1(-infinity) = -1.0}</li>
* <li>{@code expm1(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to compute the <i>{@code e}</i><sup>{@code d}
* </sup>{@code - 1} of.
* @return the <i>{@code e}</i><sup>{@code d}</sup>{@code - 1} value
* of the argument.
- * @since Android 1.0
*/
public static native double expm1(double d);
@@ -377,20 +342,19 @@
* <li>{@code floor(-infinity) = -infinity}</li>
* <li>{@code floor(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose closest integer value has to be computed.
* @return the floor of the argument.
- * @since Android 1.0
*/
public static native double floor(double d);
-
+
/**
* Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +}
* <i> {@code y}</i><sup>{@code 2}</sup>{@code )}. The final result is
* without medium underflow or overflow. The returned result is within 1 ulp
- * (unit in the last place) of the real result.
+ * (unit in the last place) of the real result. If one parameter remains
+ * constant, the result should be semi-monotonic.
* <p>
* Special cases:
* <ul>
@@ -400,8 +364,7 @@
* <li>{@code hypot((anything including NaN), -infinity) = +infinity}</li>
* <li>{@code hypot(NaN, NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param x
* a double number.
* @param y
@@ -409,7 +372,6 @@
* @return the {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +}
* <i> {@code y}</i><sup>{@code 2}</sup>{@code )} value of the
* arguments.
- * @since Android 1.0
*/
public static native double hypot(double x, double y);
@@ -431,19 +393,14 @@
* <li>{@code IEEEremainder(x, -infinity) = x } where x is anything but
* +/-infinity</li>
* </ul>
- * </p>
- *
+ *
* @param x
* the numerator of the operation.
* @param y
* the denominator of the operation.
* @return the IEEE754 floating point reminder of of {@code x/y}.
- * @since Android 1.0
*/
public static native double IEEEremainder(double x, double y);
- // BEGIN android-note
- // parameter names changed from d1 / d2 to x / y
- // END android-note
/**
* Returns the closest double approximation of the natural logarithm of the
@@ -459,12 +416,10 @@
* <li>{@code log(-infinity) = NaN}</li>
* <li>{@code log(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose log has to be computed.
* @return the natural logarithm of the argument.
- * @since Android 1.0
*/
public static native double log(double d);
@@ -482,21 +437,19 @@
* <li>{@code log10(-infinity) = NaN}</li>
* <li>{@code log10(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose base 10 log has to be computed.
* @return the natural logarithm of the argument.
- * @since Android 1.0
*/
public static native double log10(double d);
-
+
/**
* Returns the closest double approximation of the natural logarithm of the
* sum of the argument and 1. If the argument is very close to 0, it is much
* more accurate to use {@code log1p(d)} than {@code log(1.0+d)} (due to
* numerical cancellation). The returned result is within 1 ulp (unit in the
- * last place) of the real result.
+ * last place) of the real result and is semi-monotonic.
* <p>
* Special cases:
* <ul>
@@ -508,12 +461,10 @@
* <li>{@code log1p(-infinity) = NaN}</li>
* <li>{@code log1p(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to compute the {@code ln(1+d)} of.
* @return the natural logarithm of the sum of the argument and 1.
- * @since Android 1.0
*/
public static native double log1p(double d);
@@ -528,29 +479,34 @@
* <li>{@code max(+0.0, -0.0) = +0.0}</li>
* <li>{@code max(-0.0, +0.0) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param d1
* the first argument.
* @param d2
* the second argument.
* @return the larger of {@code d1} and {@code d2}.
- * @since Android 1.0
*/
- public static double max(double d1, double d2) {
- if (d1 > d2)
+ public static double max(double d1, double d2) {
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ if (d1 > d2) {
return d1;
- if (d1 < d2)
+ }
+ if (d1 < d2) {
return d2;
+ }
/* if either arg is NaN, return NaN */
- if (d1 != d2)
+ if (d1 != d2) {
return Double.NaN;
- /* max( +0.0,-0.0) == +0.0 */
- if (d1 == 0.0
- && ((Double.doubleToLongBits(d1) & Double.doubleToLongBits(d2)) & 0x8000000000000000L) == 0)
- return 0.0;
- return d1;
- }
+ }
+ /* max(+0.0,-0.0) == +0.0 */
+ /* 0 == Double.doubleToRawLongBits(0.0d) */
+ if (Double.doubleToRawLongBits(d1) != 0) {
+ return d2;
+ }
+ return 0.0d;
+ // END android-changed
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
@@ -563,59 +519,62 @@
* <li>{@code max(+0.0, -0.0) = +0.0}</li>
* <li>{@code max(-0.0, +0.0) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param f1
* the first argument.
* @param f2
* the second argument.
* @return the larger of {@code f1} and {@code f2}.
- * @since Android 1.0
*/
- public static float max(float f1, float f2) {
- if (f1 > f2)
+ public static float max(float f1, float f2) {
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ if (f1 > f2) {
return f1;
- if (f1 < f2)
+ }
+ if (f1 < f2) {
return f2;
+ }
/* if either arg is NaN, return NaN */
- if (f1 != f2)
+ if (f1 != f2) {
return Float.NaN;
- /* max( +0.0,-0.0) == +0.0 */
- if (f1 == 0.0f
- && ((Float.floatToIntBits(f1) & Float.floatToIntBits(f2)) & 0x80000000) == 0)
- return 0.0f;
- return f1;
- }
+ }
+ /* max(+0.0,-0.0) == +0.0 */
+ /* 0 == Float.floatToRawIntBits(0.0f) */
+ if (Float.floatToRawIntBits(f1) != 0) {
+ return f2;
+ }
+ return 0.0f;
+ // END android-changed
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
* arguments.
- *
+ *
* @param i1
* the first argument.
* @param i2
* the second argument.
* @return the larger of {@code i1} and {@code i2}.
- * @since Android 1.0
*/
- public static int max(int i1, int i2) {
- return i1 > i2 ? i1 : i2;
- }
+ public static int max(int i1, int i2) {
+ return i1 > i2 ? i1 : i2;
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
* arguments.
- *
+ *
* @param l1
* the first argument.
* @param l2
* the second argument.
* @return the larger of {@code l1} and {@code l2}.
- * @since Android 1.0
*/
- public static long max(long l1, long l2) {
- return l1 > l2 ? l1 : l2;
- }
+ public static long max(long l1, long l2) {
+ return l1 > l2 ? l1 : l2;
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
@@ -628,29 +587,34 @@
* <li>{@code min(+0.0, -0.0) = -0.0}</li>
* <li>{@code min(-0.0, +0.0) = -0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param d1
* the first argument.
* @param d2
* the second argument.
* @return the smaller of {@code d1} and {@code d2}.
- * @since Android 1.0
*/
- public static double min(double d1, double d2) {
- if (d1 > d2)
+ public static double min(double d1, double d2) {
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ if (d1 > d2) {
return d2;
- if (d1 < d2)
+ }
+ if (d1 < d2) {
return d1;
+ }
/* if either arg is NaN, return NaN */
- if (d1 != d2)
+ if (d1 != d2) {
return Double.NaN;
- /* min( +0.0,-0.0) == -0.0 */
- if (d1 == 0.0
- && ((Double.doubleToLongBits(d1) | Double.doubleToLongBits(d2)) & 0x8000000000000000l) != 0)
- return 0.0 * (-1.0);
- return d1;
- }
+ }
+ /* min(+0.0,-0.0) == -0.0 */
+ /* 0x8000000000000000L == Double.doubleToRawLongBits(-0.0d) */
+ if (Double.doubleToRawLongBits(d1) == 0x8000000000000000L) {
+ return -0.0d;
+ }
+ return d2;
+ // END android-changed
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
@@ -663,59 +627,62 @@
* <li>{@code min(+0.0, -0.0) = -0.0}</li>
* <li>{@code min(-0.0, +0.0) = -0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param f1
* the first argument.
* @param f2
* the second argument.
* @return the smaller of {@code f1} and {@code f2}.
- * @since Android 1.0
*/
- public static float min(float f1, float f2) {
- if (f1 > f2)
+ public static float min(float f1, float f2) {
+ // BEGIN android-changed
+ // copied from a newer version of Harmony
+ if (f1 > f2) {
return f2;
- if (f1 < f2)
+ }
+ if (f1 < f2) {
return f1;
+ }
/* if either arg is NaN, return NaN */
- if (f1 != f2)
+ if (f1 != f2) {
return Float.NaN;
- /* min( +0.0,-0.0) == -0.0 */
- if (f1 == 0.0f
- && ((Float.floatToIntBits(f1) | Float.floatToIntBits(f2)) & 0x80000000) != 0)
- return 0.0f * (-1.0f);
- return f1;
- }
+ }
+ /* min(+0.0,-0.0) == -0.0 */
+ /* 0x80000000 == Float.floatToRawIntBits(-0.0f) */
+ if (Float.floatToRawIntBits(f1) == 0x80000000) {
+ return -0.0f;
+ }
+ return f2;
+ // END android-changed
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
* arguments.
- *
+ *
* @param i1
* the first argument.
* @param i2
* the second argument.
* @return the smaller of {@code i1} and {@code i2}.
- * @since Android 1.0
*/
- public static int min(int i1, int i2) {
- return i1 < i2 ? i1 : i2;
- }
+ public static int min(int i1, int i2) {
+ return i1 < i2 ? i1 : i2;
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
* arguments.
- *
+ *
* @param l1
* the first argument.
* @param l2
* the second argument.
* @return the smaller of {@code l1} and {@code l2}.
- * @since Android 1.0
*/
- public static long min(long l1, long l2) {
- return l1 < l2 ? l1 : l2;
- }
+ public static long min(long l1, long l2) {
+ return l1 < l2 ? l1 : l2;
+ }
/**
* Returns the closest double approximation of the result of raising
@@ -747,19 +714,14 @@
* {@code pow(-1,(integer))*pow(+anything,integer) }</li>
* <li>{@code pow((-anything except 0 and inf), (non-integer)) = NAN}</li>
* </ul>
- * </p>
- *
+ *
* @param x
* the base of the operation.
* @param y
* the exponent of the operation.
* @return {@code x} to the power of {@code y}.
- * @since Android 1.0
*/
public static native double pow(double x, double y);
- // BEGIN android-note
- // parameter names changed from d1 / d2 to x / y
- // END android-note
/**
* Returns the double conversion of the result of rounding the argument to
@@ -773,16 +735,14 @@
* <li>{@code rint(-infinity) = -infinity}</li>
* <li>{@code rint(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to be rounded.
* @return the closest integer to the argument (as a double).
- * @since Android 1.0
*/
public static native double rint(double d);
- /**
+ /**
* Returns the result of rounding the argument to an integer. The result is
* equivalent to {@code (long) Math.floor(d+0.5)}.
* <p>
@@ -796,19 +756,17 @@
* <li>{@code round(-infintiy) = Long.MIN_VALUE}</li>
* <li>{@code round(NaN) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to be rounded.
* @return the closest integer to the argument.
- * @since Android 1.0
*/
- public static long round(double d) {
- // check for NaN
- if (d != d)
- return 0L;
- return (long) floor(d + 0.5d);
- }
+ public static long round(double d) {
+ // check for NaN
+ if (d != d)
+ return 0L;
+ return (long) floor(d + 0.5d);
+ }
/**
* Returns the result of rounding the argument to an integer. The result is
@@ -824,18 +782,39 @@
* <li>{@code round(-infintiy) = Integer.MIN_VALUE}</li>
* <li>{@code round(NaN) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param f
* the value to be rounded.
* @return the closest integer to the argument.
- * @since Android 1.0
*/
- public static int round(float f) {
- // check for NaN
- if (f != f)
- return 0;
- return (int) floor(f + 0.5f);
+ public static int round(float f) {
+ // check for NaN
+ if (f != f)
+ return 0;
+ return (int) floor(f + 0.5f);
+ }
+
+ /**
+ * Returns the signum function of the argument. If the argument is less than
+ * zero, it returns -1.0. If the argument is greater than zero, 1.0 is
+ * returned. If the argument is either positive or negative zero, the
+ * argument is returned as result.
+ * <p>
+ * Special cases:
+ * <ul>
+ * <li>{@code signum(+0.0) = +0.0}</li>
+ * <li>{@code signum(-0.0) = -0.0}</li>
+ * <li>{@code signum(+infinity) = +1.0}</li>
+ * <li>{@code signum(-infinity) = -1.0}</li>
+ * <li>{@code signum(NaN) = NaN}</li>
+ * </ul>
+ *
+ * @param d
+ * the value whose signum has to be computed.
+ * @return the value of the signum function.
+ */
+ public static double signum(double d) {
+ return StrictMath.signum(d);
}
/**
@@ -852,37 +831,10 @@
* <li>{@code signum(-infinity) = -1.0}</li>
* <li>{@code signum(NaN) = NaN}</li>
* </ul>
- * </p>
- *
- * @param d
- * the value whose signum has to be computed.
- * @return the value of the signum function.
- * @since Android 1.0
- */
- public static double signum(double d) {
- return StrictMath.signum(d);
- }
-
- /**
- * Returns the signum function of the argument. If the argument is less than
- * zero, it returns -1.0. If the argument is greater than zero, 1.0 is
- * returned. If the argument is either positive or negative zero, the
- * argument is returned as result.
- * <p>
- * Special cases:
- * <ul>
- * <li>{@code signum(+0.0) = +0.0}</li>
- * <li>{@code signum(-0.0) = -0.0}</li>
- * <li>{@code signum(+infinity) = +1.0}</li>
- * <li>{@code signum(-infinity) = -1.0}</li>
- * <li>{@code signum(NaN) = NaN}</li>
- * </ul>
- * </p>
- *
+ *
* @param f
* the value whose signum has to be computed.
* @return the value of the signum function.
- * @since Android 1.0
*/
public static float signum(float f) {
return StrictMath.signum(f);
@@ -901,15 +853,13 @@
* <li>{@code sin(-infinity) = NaN}</li>
* <li>{@code sin(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the angle whose sin has to be computed, in radians.
* @return the sine of the argument.
- * @since Android 1.0
*/
public static native double sin(double d);
-
+
/**
* Returns the closest double approximation of the hyperbolic sine of the
* argument. The returned result is within 2.5 ulps (units in the last
@@ -923,12 +873,10 @@
* <li>{@code sinh(-infinity) = -infinity}</li>
* <li>{@code sinh(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose hyperbolic sine has to be computed.
* @return the hyperbolic sine of the argument.
- * @since Android 1.0
*/
public static native double sinh(double d);
@@ -944,12 +892,10 @@
* <li>{@code sqrt(+infinity) = +infinity}</li>
* <li>{@code sqrt(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose square root has to be computed.
* @return the square root of the argument.
- * @since Android 1.0
*/
public static native double sqrt(double d);
@@ -966,15 +912,13 @@
* <li>{@code tan(-infinity) = NaN}</li>
* <li>{@code tan(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the angle whose tangens has to be computed, in radians.
* @return the tangent of the argument.
- * @since Android 1.0
*/
public static native double tan(double d);
-
+
/**
* Returns the closest double approximation of the hyperbolic tangent of the
* argument. The absolute value is always less than 1. The returned result
@@ -990,28 +934,25 @@
* <li>{@code tanh(-infinity) = -1.0}</li>
* <li>{@code tanh(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose hyperbolic tangent has to be computed.
* @return the hyperbolic tangent of the argument.
- * @since Android 1.0
*/
public static native double tanh(double d);
/**
* Returns a pseudo-random number between 0.0 (inclusive) and 1.0
* (exclusive).
- *
+ *
* @return a pseudo-random number.
- * @since Android 1.0
*/
- public static double random() {
- if (random == null) {
- random = new java.util.Random();
- }
- return random.nextDouble();
- }
+ public static double random() {
+ if (random == null) {
+ random = new java.util.Random();
+ }
+ return random.nextDouble();
+ }
/**
* Returns the measure in radians of the supplied degree angle. The result
@@ -1025,16 +966,14 @@
* <li>{@code toRadians(-infinity) = -infinity}</li>
* <li>{@code toRadians(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param angdeg
* an angle in degrees.
* @return the radian measure of the angle.
- * @since Android 1.0
*/
- public static double toRadians(double angdeg) {
- return angdeg / 180d * PI;
- }
+ public static double toRadians(double angdeg) {
+ return angdeg / 180d * PI;
+ }
/**
* Returns the measure in degrees of the supplied radian angle. The result
@@ -1048,18 +987,16 @@
* <li>{@code toDegrees(-infinity) = -infinity}</li>
* <li>{@code toDegrees(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param angrad
* an angle in radians.
* @return the degree measure of the angle.
- * @since Android 1.0
*/
- public static double toDegrees(double angrad) {
- return angrad * 180d / PI;
- }
-
- /**
+ public static double toDegrees(double angrad) {
+ return angrad * 180d / PI;
+ }
+
+ /**
* Returns the argument's ulp (unit in the last place). The size of a ulp of
* a double value is the positive distance between this value and the double
* value next larger in magnitude. For non-NaN {@code x},
@@ -1073,12 +1010,10 @@
* <li>{@code ulp(-infintiy) = infinity}</li>
* <li>{@code ulp(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the floating-point value to compute ulp of.
* @return the size of a ulp of the argument.
- * @since Android 1.0
*/
public static double ulp(double d) {
// special cases
@@ -1105,12 +1040,10 @@
* <li>{@code ulp(-infintiy) = infinity}</li>
* <li>{@code ulp(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param f
* the floating-point value to compute ulp of.
* @return the size of a ulp of the argument.
- * @since Android 1.0
*/
public static float ulp(float f) {
// special cases
diff --git a/luni/src/main/java/java/lang/NegativeArraySizeException.java b/luni/src/main/java/java/lang/NegativeArraySizeException.java
index 1ca7855..50b6929 100644
--- a/luni/src/main/java/java/lang/NegativeArraySizeException.java
+++ b/luni/src/main/java/java/lang/NegativeArraySizeException.java
@@ -20,8 +20,6 @@
/**
* Thrown when an attempt is made to create an array with a size of less than
* zero.
- *
- * @since Android 1.0
*/
public class NegativeArraySizeException extends RuntimeException {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code NegativeArraySizeException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public NegativeArraySizeException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NegativeArraySizeException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/NoClassDefFoundError.java b/luni/src/main/java/java/lang/NoClassDefFoundError.java
index e23ecc6..9fae360 100644
--- a/luni/src/main/java/java/lang/NoClassDefFoundError.java
+++ b/luni/src/main/java/java/lang/NoClassDefFoundError.java
@@ -20,8 +20,6 @@
/**
* Thrown when the virtual machine is unable to locate a class which it has been
* asked to load.
- *
- * @since Android 1.0
*/
public class NoClassDefFoundError extends LinkageError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code NoClassDefFoundError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public NoClassDefFoundError() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public NoClassDefFoundError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/NoSuchFieldError.java b/luni/src/main/java/java/lang/NoSuchFieldError.java
index 667d6a5..9b479f6 100644
--- a/luni/src/main/java/java/lang/NoSuchFieldError.java
+++ b/luni/src/main/java/java/lang/NoSuchFieldError.java
@@ -22,9 +22,6 @@
* on a class or object, a field that does not exist.
* <p>
* Note that this can only occur when inconsistent class files are being loaded.
- * </p>
- *
- * @since Android 1.0
*/
public class NoSuchFieldError extends IncompatibleClassChangeError {
@@ -33,8 +30,6 @@
/**
* Constructs a new {@code NoSuchFieldError} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public NoSuchFieldError() {
super();
@@ -46,7 +41,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public NoSuchFieldError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/NoSuchFieldException.java b/luni/src/main/java/java/lang/NoSuchFieldException.java
index 31a566d..283bfab 100644
--- a/luni/src/main/java/java/lang/NoSuchFieldException.java
+++ b/luni/src/main/java/java/lang/NoSuchFieldException.java
@@ -20,8 +20,6 @@
/**
* Thrown when the virtual machine notices that a program tries to reference,
* on a class or object, a field that does not exist.
- *
- * @since Android 1.0
*/
public class NoSuchFieldException extends java.lang.Exception {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code NoSuchFieldException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public NoSuchFieldException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NoSuchFieldException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/NoSuchMethodError.java b/luni/src/main/java/java/lang/NoSuchMethodError.java
index a72f76b..91ed06c 100644
--- a/luni/src/main/java/java/lang/NoSuchMethodError.java
+++ b/luni/src/main/java/java/lang/NoSuchMethodError.java
@@ -20,8 +20,6 @@
/**
* Thrown when the virtual machine notices that a program tries to reference,
* on a class or object, a method that does not exist.
- *
- * @since Android 1.0
*/
public class NoSuchMethodError extends IncompatibleClassChangeError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code NoSuchMethodError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public NoSuchMethodError() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NoSuchMethodError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/NoSuchMethodException.java b/luni/src/main/java/java/lang/NoSuchMethodException.java
index bd3cf01..cf4dbe0 100644
--- a/luni/src/main/java/java/lang/NoSuchMethodException.java
+++ b/luni/src/main/java/java/lang/NoSuchMethodException.java
@@ -20,8 +20,6 @@
/**
* Thrown when the virtual machine notices that a program tries to reference,
* on a class or object, a method that does not exist.
- *
- * @since Android 1.0
*/
public class NoSuchMethodException extends java.lang.Exception {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code NoSuchMethodException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public NoSuchMethodException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NoSuchMethodException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/NullPointerException.java b/luni/src/main/java/java/lang/NullPointerException.java
index d11b282..90e9e50 100644
--- a/luni/src/main/java/java/lang/NullPointerException.java
+++ b/luni/src/main/java/java/lang/NullPointerException.java
@@ -23,8 +23,6 @@
* object or array points to {@code null}. It also occurs in some other, less
* obvious circumstances, like a {@code throw e} statement where the {@link
* Throwable} reference is {@code null}.
- *
- * @since Android 1.0
*/
public class NullPointerException extends RuntimeException {
@@ -33,8 +31,6 @@
/**
* Constructs a new {@code NullPointerException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public NullPointerException() {
super();
@@ -46,7 +42,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NullPointerException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/Number.java b/luni/src/main/java/java/lang/Number.java
index dc868cb..4fb5596 100644
--- a/luni/src/main/java/java/lang/Number.java
+++ b/luni/src/main/java/java/lang/Number.java
@@ -22,8 +22,6 @@
* The abstract superclass of the classes which represent numeric base types
* (that is {@link Byte}, {@link Short}, {@link Integer}, {@link Long},
* {@link Float}, and {@link Double}.
- *
- * @since Android 1.0
*/
public abstract class Number implements java.io.Serializable {
@@ -31,8 +29,6 @@
/**
* Empty default constructor.
- *
- * @since Android 1.0
*/
public Number() {
}
@@ -42,7 +38,6 @@
* truncating the value, so it fits into a byte.
*
* @return the primitive byte value of this object.
- * @since Android 1.0
*/
public byte byteValue() {
return (byte) intValue();
@@ -52,7 +47,6 @@
* Returns this object's value as a double. Might involve rounding.
*
* @return the primitive double value of this object.
- * @since Android 1.0
*/
public abstract double doubleValue();
@@ -60,7 +54,6 @@
* Returns this object's value as a float. Might involve rounding.
*
* @return the primitive float value of this object.
- * @since Android 1.0
*/
public abstract float floatValue();
@@ -69,7 +62,6 @@
* truncating the value, so it fits into an int.
*
* @return the primitive int value of this object.
- * @since Android 1.0
*/
public abstract int intValue();
@@ -78,7 +70,6 @@
* truncating the value, so it fits into a long.
*
* @return the primitive long value of this object.
- * @since Android 1.0
*/
public abstract long longValue();
@@ -87,7 +78,6 @@
* truncating the value, so it fits into a short.
*
* @return the primitive short value of this object.
- * @since Android 1.0
*/
public short shortValue() {
return (short) intValue();
diff --git a/luni/src/main/java/java/lang/NumberFormatException.java b/luni/src/main/java/java/lang/NumberFormatException.java
index ed5433d..9d2f0c7 100644
--- a/luni/src/main/java/java/lang/NumberFormatException.java
+++ b/luni/src/main/java/java/lang/NumberFormatException.java
@@ -20,8 +20,6 @@
/**
* Thrown when an invalid value is passed to a string-to-number conversion
* method.
- *
- * @since Android 1.0
*/
public class NumberFormatException extends java.lang.IllegalArgumentException {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code NumberFormatException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public NumberFormatException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NumberFormatException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/OutOfMemoryError.java b/luni/src/main/java/java/lang/OutOfMemoryError.java
index 2c54ad1..a8f8a2c 100644
--- a/luni/src/main/java/java/lang/OutOfMemoryError.java
+++ b/luni/src/main/java/java/lang/OutOfMemoryError.java
@@ -21,8 +21,6 @@
* Thrown when a request for memory is made that can not be satisfied using the
* available platform resources. Such a request may be made by both the running
* application or by an internal function of the virtual machine.
- *
- * @since Android 1.0
*/
public class OutOfMemoryError extends java.lang.VirtualMachineError {
@@ -31,8 +29,6 @@
/**
* Constructs a new {@code OutOfMemoryError} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public OutOfMemoryError() {
super();
@@ -44,7 +40,6 @@
*
* @param detailMessage
* the detail message for this error.
- * @since Android 1.0
*/
public OutOfMemoryError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/Override.java b/luni/src/main/java/java/lang/Override.java
index 864357d..c4049cb 100644
--- a/luni/src/main/java/java/lang/Override.java
+++ b/luni/src/main/java/java/lang/Override.java
@@ -1,12 +1,12 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,19 +16,19 @@
package java.lang;
-import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
- * Annotation type used to mark methods that override a method declaration in a superclass.
- * Compilers produce an error if a method annotated with @Override does not actually override
- * a method in a superclass.
- *
- * @since Android 1.0
+ * Annotation type used to mark methods that override a method declaration in a
+ * superclass. Compilers produce an error if a method annotated with @Override
+ * does not actually override a method in a superclass.
+ *
+ * @since 1.5
*/
-@Retention(value=java.lang.annotation.RetentionPolicy.SOURCE)
-@Target(value=java.lang.annotation.ElementType.METHOD)
-public @interface Override
-{
-
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface Override {
}
diff --git a/luni/src/main/java/java/lang/Process.java b/luni/src/main/java/java/lang/Process.java
index 5fe8be7..c030fcc 100644
--- a/luni/src/main/java/java/lang/Process.java
+++ b/luni/src/main/java/java/lang/Process.java
@@ -17,25 +17,20 @@
package java.lang;
-
import java.io.InputStream;
import java.io.OutputStream;
/**
* Represents an external process. Enables writing to, reading from, destroying,
* and waiting for the external process, as well as querying its exit value.
- *
+ *
* @see Runtime#exec
* @see ProcessBuilder#start()
- *
- * @since Android 1.0
*/
public abstract class Process {
/**
* Terminates this process and closes any associated streams.
- *
- * @since Android 1.0
*/
abstract public void destroy();
@@ -46,7 +41,6 @@
* @return the exit value of this process.
* @throws IllegalThreadStateException
* if this process has not terminated.
- * @since Android 1.0
*/
abstract public int exitValue();
@@ -56,7 +50,6 @@
*
* @return the input stream to read from the error stream associated with
* the native process.
- * @since Android 1.0
*/
abstract public InputStream getErrorStream();
@@ -66,7 +59,6 @@
*
* @return the input stream to read from the output stream associated with
* the native process.
- * @since Android 1.0
*/
abstract public InputStream getInputStream();
@@ -76,7 +68,6 @@
*
* @return the output stream to write to the input stream associated with
* the native process.
- * @since Android 1.0
*/
abstract public OutputStream getOutputStream();
@@ -87,7 +78,6 @@
* @return the exit value of the native process being waited on.
* @throws InterruptedException
* if the calling thread is interrupted.
- * @since Android 1.0
*/
abstract public int waitFor() throws InterruptedException;
}
diff --git a/luni/src/main/java/java/lang/ProcessBuilder.java b/luni/src/main/java/java/lang/ProcessBuilder.java
index 9d6b90b..f649fec 100644
--- a/luni/src/main/java/java/lang/ProcessBuilder.java
+++ b/luni/src/main/java/java/lang/ProcessBuilder.java
@@ -24,8 +24,8 @@
/**
* Creates operating system processes.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public final class ProcessBuilder {
@@ -40,10 +40,9 @@
/**
* Constructs a new {@code ProcessBuilder} instance with the specified
* operating system program and its arguments.
- *
+ *
* @param command
* the requested operating system program and its arguments.
- * @since Android 1.0
*/
public ProcessBuilder(String... command) {
this(toList(command));
@@ -54,12 +53,11 @@
* operating system program and its arguments. Note that the list passed to
* this constructor is not copied, so any subsequent updates to it are
* reflected in this instance's state.
- *
+ *
* @param command
* the requested operating system program and its arguments.
* @throws NullPointerException
* if {@code command} is {@code null}.
- * @since Android 1.0
*/
public ProcessBuilder(List<String> command) {
super();
@@ -76,9 +74,8 @@
* Returns this process builder's current program and arguments. Note that
* the returned list is not a copy and modifications to it will change the
* state of this instance.
- *
+ *
* @return this process builder's program and arguments.
- * @since Android 1.0
*/
public List<String> command() {
return command;
@@ -86,11 +83,10 @@
/**
* Changes the program and arguments of this process builder.
- *
+ *
* @param command
* the new operating system program and its arguments.
* @return this process builder instance.
- * @since Android 1.0
*/
public ProcessBuilder command(String... command) {
return command(toList(command));
@@ -100,13 +96,12 @@
* Changes the program and arguments of this process builder. Note that the
* list passed to this method is not copied, so any subsequent updates to it
* are reflected in this instance's state.
- *
+ *
* @param command
* the new operating system program and its arguments.
* @return this process builder instance.
* @throws NullPointerException
* if {@code command} is {@code null}.
- * @since Android 1.0
*/
public ProcessBuilder command(List<String> command) {
if (command == null) {
@@ -120,9 +115,8 @@
* Returns the working directory of this process builder. If {@code null} is
* returned, then the working directory of the Java process is used when a
* process is started.
- *
+ *
* @return the current working directory, may be {@code null}.
- * @since Android 1.0
*/
public File directory() {
return directory;
@@ -132,11 +126,10 @@
* Changes the working directory of this process builder. If the specified
* directory is {@code null}, then the working directory of the Java
* process is used when a process is started.
- *
+ *
* @param directory
* the new working directory for this process builder.
* @return this process builder instance.
- * @since Android 1.0
*/
public ProcessBuilder directory(File directory) {
this.directory = directory;
@@ -149,9 +142,8 @@
* the environment, as returned by {@link System#getenv()}. Note that the
* map returned by this method is not a copy and any changes made to it are
* reflected in this instance's state.
- *
+ *
* @return the map containing this process builder's environment variables.
- * @since Android 1.0
*/
public Map<String, String> environment() {
return environment;
@@ -162,10 +154,9 @@
* output. If redirected, the {@link Process#getErrorStream()} will always
* return end of stream and standard error is written to
* {@link Process#getInputStream()}.
- *
+ *
* @return {@code true} if the standard error is redirected; {@code false}
* otherwise.
- * @since Android 1.0
*/
public boolean redirectErrorStream() {
return redirectErrorStream;
@@ -174,12 +165,11 @@
/**
* Changes the state of whether or not standard error is redirected to
* standard output.
- *
+ *
* @param redirectErrorStream
* {@code true} to redirect standard error, {@code false}
* otherwise.
* @return this process builder instance.
- * @since Android 1.0
*/
public ProcessBuilder redirectErrorStream(boolean redirectErrorStream) {
this.redirectErrorStream = redirectErrorStream;
@@ -188,7 +178,7 @@
/**
* Starts a new process based on the current state of this process builder.
- *
+ *
* @return the new {@code Process} instance.
* @throws NullPointerException
* if any of the elements of {@link #command()} is {@code null}.
@@ -199,7 +189,6 @@
* process creation.
* @throws IOException
* if an I/O error happens.
- * @since Android 1.0
*/
public Process start() throws IOException {
if (command.isEmpty()) {
diff --git a/luni/src/main/java/java/lang/Readable.java b/luni/src/main/java/java/lang/Readable.java
index 1eca6cc..b536f59 100644
--- a/luni/src/main/java/java/lang/Readable.java
+++ b/luni/src/main/java/java/lang/Readable.java
@@ -22,8 +22,6 @@
/**
* Represents a sequence of characters that can be incrementally read (copied)
* into a {@link CharBuffer}.
- *
- * @since Android 1.0
*/
public interface Readable {
@@ -37,7 +35,6 @@
* {@code Readable} reaches its end
* @throws IOException
* if an I/O error occurs.
- * @since Android 1.0
*/
int read(CharBuffer cb) throws IOException;
}
diff --git a/luni/src/main/java/java/lang/Runnable.java b/luni/src/main/java/java/lang/Runnable.java
index 2cca717..b09d914 100644
--- a/luni/src/main/java/java/lang/Runnable.java
+++ b/luni/src/main/java/java/lang/Runnable.java
@@ -21,8 +21,6 @@
/**
* Represents a command that can be executed. Often used to run code in a
* different {@link Thread}.
- *
- * @since Android 1.0
*/
public interface Runnable {
@@ -30,8 +28,6 @@
* Starts executing the active part of the class' code. This method is
* called when a thread is started that has been created with a class which
* implements {@code Runnable}.
- *
- * @since Android 1.0
*/
public void run();
}
diff --git a/luni/src/main/java/java/lang/RuntimeException.java b/luni/src/main/java/java/lang/RuntimeException.java
index e519bf1..9229b0c 100644
--- a/luni/src/main/java/java/lang/RuntimeException.java
+++ b/luni/src/main/java/java/lang/RuntimeException.java
@@ -23,8 +23,6 @@
* the virtual machine. Unlike checked exceptions (exceptions where the type
* doesn't extend {@code RuntimeException} or {@link Error}), the compiler does
* not require code to handle runtime exceptions.
- *
- * @since Android 1.0
*/
public class RuntimeException extends Exception {
@@ -33,8 +31,6 @@
/**
* Constructs a new {@code RuntimeException} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public RuntimeException() {
super();
@@ -46,7 +42,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public RuntimeException(String detailMessage) {
super(detailMessage);
@@ -60,7 +55,6 @@
* the detail message for this exception.
* @param throwable
* the cause of this exception.
- * @since Android 1.0
*/
public RuntimeException(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
@@ -72,7 +66,6 @@
*
* @param throwable
* the cause of this exception.
- * @since Android 1.0
*/
public RuntimeException(Throwable throwable) {
super(throwable);
diff --git a/luni/src/main/java/java/lang/RuntimePermission.java b/luni/src/main/java/java/lang/RuntimePermission.java
index 0f856a0..ba7e665 100644
--- a/luni/src/main/java/java/lang/RuntimePermission.java
+++ b/luni/src/main/java/java/lang/RuntimePermission.java
@@ -23,8 +23,6 @@
* Represents the permission to execute a runtime-related function. There is no
* action list associated with a {@code RuntimePermission}; the user either has
* the permission or he doesn't.
- *
- * @since Android 1.0
*/
public final class RuntimePermission extends BasicPermission {
@@ -83,7 +81,6 @@
*
* @param permissionName
* the name of the new permission.
- * @since Android 1.0
*/
public RuntimePermission(String permissionName) {
super(permissionName);
@@ -97,7 +94,6 @@
* the name of the new permission.
* @param actions
* ignored.
- * @since Android 1.0
*/
public RuntimePermission(String name, String actions) {
super(name, actions);
diff --git a/luni/src/main/java/java/lang/SecurityException.java b/luni/src/main/java/java/lang/SecurityException.java
index 7387088..c977be0 100644
--- a/luni/src/main/java/java/lang/SecurityException.java
+++ b/luni/src/main/java/java/lang/SecurityException.java
@@ -19,8 +19,6 @@
/**
* Thrown when a security manager check fails.
- *
- * @since Android 1.0
*/
public class SecurityException extends java.lang.RuntimeException {
@@ -29,8 +27,6 @@
/**
* Constructs a new {@code SecurityException} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public SecurityException() {
super();
@@ -42,7 +38,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public SecurityException(String detailMessage) {
super(detailMessage);
@@ -56,7 +51,7 @@
* the detail message for this exception.
* @param cause
* the optional cause of this exception, may be {@code null}.
- * @since Android 1.0
+ * @since 1.5
*/
public SecurityException(String message, Throwable cause) {
super(message, cause);
@@ -68,7 +63,7 @@
*
* @param cause
* the optional cause of this exception, may be {@code null}.
- * @since Android 1.0
+ * @since 1.5
*/
public SecurityException(Throwable cause) {
super((cause == null ? null : cause.toString()), cause);
diff --git a/luni/src/main/java/java/lang/SecurityManager.java b/luni/src/main/java/java/lang/SecurityManager.java
index dc624e3..9125850 100644
--- a/luni/src/main/java/java/lang/SecurityManager.java
+++ b/luni/src/main/java/java/lang/SecurityManager.java
@@ -49,8 +49,6 @@
* operation is not allowed, then they throw a {@link SecurityException}. The
* only exception is {@link #checkTopLevelWindow(Object)}, which returns a
* boolean to indicate permission.
- *
- * @since Android 1.0
*/
public class SecurityManager {
@@ -63,9 +61,8 @@
/**
* Flag to indicate whether a security check is in progress.
- *
+ *
* @deprecated Use {@link #checkPermission}
- * @since Android 1.0
*/
@Deprecated
protected boolean inCheck;
@@ -75,9 +72,6 @@
* <p>
* The {@code RuntimePermission("createSecurityManager")} is checked if a
* security manager is installed.
- * </p>
- *
- * @since Android 1.0
*/
public SecurityManager() {
SecurityManager security = System.getSecurityManager();
@@ -94,7 +88,7 @@
/**
* Checks whether the calling thread is allowed to accept socket
* connections.
- *
+ *
* @param host
* the address of the host that attempts to connect.
* @param port
@@ -104,7 +98,6 @@
* @throws SecurityException
* if the calling thread is not allowed to accept socket
* connections from {@code host} through {@code port}.
- * @since Android 1.0
*/
public void checkAccept(String host, int port) {
if (host == null) {
@@ -116,12 +109,11 @@
/**
* Checks whether the calling thread is allowed to modify the specified
* thread.
- *
+ *
* @param thread
* the thread to access.
* @throws SecurityException
* if the calling thread is not allowed to access {@code thread}.
- * @since Android 1.0
*/
public void checkAccess(Thread thread) {
// Only worry about system threads. Dead threads have a null group.
@@ -134,14 +126,13 @@
/**
* Checks whether the calling thread is allowed to modify the specified
* thread group.
- *
+ *
* @param group
* the thread group to access.
* @throws NullPointerException
* if {@code group} is {@code null}.
* @throws SecurityException
* if the calling thread is not allowed to access {@code group}.
- * @since Android 1.0
*/
public void checkAccess(ThreadGroup group) {
// Only worry about system threads.
@@ -157,7 +148,7 @@
* Checks whether the calling thread is allowed to establish socket
* connections. A -1 port indicates the caller is trying to resolve the
* hostname.
- *
+ *
* @param host
* the address of the host to connect to.
* @param port
@@ -167,7 +158,6 @@
* @throws SecurityException
* if the calling thread is not allowed to connect to {@code
* host} through {@code port}.
- * @since Android 1.0
*/
public void checkConnect(String host, int port) {
if (host == null) {
@@ -184,7 +174,7 @@
* Checks whether the specified security context is allowed to establish
* socket connections. A -1 port indicates the caller is trying to resolve
* the hostname.
- *
+ *
* @param host
* the address of the host to connect to.
* @param port
@@ -196,7 +186,6 @@
* @throws SecurityException
* if {@code context} is not allowed to connect to {@code host}
* through {@code port}.
- * @since Android 1.0
*/
public void checkConnect(String host, int port, Object context) {
// BEGIN android-added
@@ -214,11 +203,10 @@
/**
* Checks whether the calling thread is allowed to create a class loader.
- *
+ *
* @throws SecurityException
* if the calling thread is not allowed to create a class
* loader.
- * @since Android 1.0
*/
public void checkCreateClassLoader() {
checkPermission(RuntimePermission.permissionToCreateClassLoader);
@@ -227,12 +215,11 @@
/**
* Checks whether the calling thread is allowed to delete the file with the
* specified name, which should be passed in canonical form.
- *
+ *
* @param file
* the name of the file to delete.
* @throws SecurityException
* if the calling thread is not allowed to delete {@code file}.
- * @since Android 1.0
*/
public void checkDelete(String file) {
checkPermission(new FilePermission(file, "delete")); //$NON-NLS-1$
@@ -241,12 +228,11 @@
/**
* Checks whether the calling thread is allowed to execute the specified
* platform specific command.
- *
+ *
* @param cmd
* the command line to execute.
* @throws SecurityException
* if the calling thread is not allowed to execute {@code cmd}.
- * @since Android 1.0
*/
public void checkExec(String cmd) {
checkPermission(new FilePermission(new File(cmd).isAbsolute() ? cmd
@@ -256,14 +242,13 @@
/**
* Checks whether the calling thread is allowed to terminate the virtual
* machine.
- *
+ *
* @param status
* the status that the virtual machine returns when it is
* terminated.
* @throws SecurityException
* if the calling thread is not allowed to terminate the virtual
* machine with {@code status}.
- * @since Android 1.0
*/
public void checkExit(int status) {
checkPermission(RuntimePermission.permissionToExitVM);
@@ -272,12 +257,11 @@
/**
* Checks whether the calling thread is allowed to load the specified native
* library.
- *
+ *
* @param libName
* the name of the library to load.
* @throws SecurityException
* if the calling thread is not allowed to load {@code libName}.
- * @since Android 1.0
*/
public void checkLink(String libName) {
if (libName == null) {
@@ -289,12 +273,11 @@
/**
* Checks whether the calling thread is allowed to listen on the specified
* port.
- *
+ *
* @param port
* the port number to check.
* @throws SecurityException
* if the calling thread is not allowed listen on {@code port}.
- * @since Android 1.0
*/
public void checkListen(int port) {
if (port == 0) {
@@ -312,7 +295,7 @@
* reflect API). Due to the nature of the check, overriding implementations
* cannot call {@code super.checkMemberAccess()} since the stack would no
* longer be of the expected shape.
- *
+ *
* @param cls
* the class of which members are accessed.
* @param type
@@ -322,7 +305,6 @@
* @throws SecurityException
* if the calling thread is not allowed to access members of
* {@code cls}.
- * @since Android 1.0
*/
public void checkMemberAccess(Class<?> cls, int type) {
if (cls == null) {
@@ -352,12 +334,11 @@
/**
* Checks whether the calling thread is allowed to use the specified IP
* multicast group address.
- *
+ *
* @param maddr
* the internet group address to use.
* @throws SecurityException
* if the calling thread is not allowed to use {@code maddr}.
- * @since Android 1.0
*/
public void checkMulticast(InetAddress maddr) {
checkPermission(new SocketPermission(maddr.getHostAddress(),
@@ -367,7 +348,7 @@
/**
* Checks whether the calling thread is allowed to use the specified IP
* multicast group address.
- *
+ *
* @param maddr
* the internet group address to use.
* @param ttl
@@ -376,7 +357,6 @@
* @throws SecurityException
* if the calling thread is not allowed to use {@code maddr}.
* @deprecated use {@link #checkMulticast(java.net.InetAddress)}
- * @since Android 1.0
*/
@Deprecated
public void checkMulticast(InetAddress maddr, byte ttl) {
@@ -387,13 +367,12 @@
/**
* Checks whether the calling thread is allowed to access the specified
* package.
- *
+ *
* @param packageName
* the name of the package to access.
* @throws SecurityException
* if the calling thread is not allowed to access {@code
* packageName}.
- * @since Android 1.0
*/
public void checkPackageAccess(String packageName) {
if (packageName == null) {
@@ -408,13 +387,12 @@
/**
* Checks whether the calling thread is allowed to define new classes in the
* specified package.
- *
+ *
* @param packageName
* the name of the package to add a class to.
* @throws SecurityException
* if the calling thread is not allowed to add classes to
* {@code packageName}.
- * @since Android 1.0
*/
public void checkPackageDefinition(String packageName) {
if (packageName == null) {
@@ -459,11 +437,10 @@
/**
* Checks whether the calling thread is allowed to access the system
* properties.
- *
+ *
* @throws SecurityException
* if the calling thread is not allowed to access system
* properties.
- * @since Android 1.0
*/
public void checkPropertiesAccess() {
checkPermission(READ_WRITE_ALL_PROPERTIES_PERMISSION);
@@ -472,13 +449,12 @@
/**
* Checks whether the calling thread is allowed to access a particular
* system property.
- *
+ *
* @param key
* the name of the property to access.
* @throws SecurityException
* if the calling thread is not allowed to access the {@code
* key} system property.
- * @since Android 1.0
*/
public void checkPropertyAccess(String key) {
checkPermission(new PropertyPermission(key, "read")); //$NON-NLS-1$
@@ -487,12 +463,11 @@
/**
* Checks whether the calling thread is allowed to read from the file with
* the specified file descriptor.
- *
+ *
* @param fd
* the file descriptor of the file to read from.
* @throws SecurityException
* if the calling thread is not allowed to read from {@code fd}.
- * @since Android 1.0
*/
public void checkRead(FileDescriptor fd) {
if (fd == null) {
@@ -504,13 +479,12 @@
/**
* Checks whether the calling thread is allowed to read from the file with
* the specified name, which should be passed in canonical form.
- *
+ *
* @param file
* the name of the file or directory to read from.
* @throws SecurityException
* if the calling thread is not allowed to read from {@code
* file}.
- * @since Android 1.0
*/
public void checkRead(String file) {
checkPermission(new FilePermission(file, "read")); //$NON-NLS-1$
@@ -519,14 +493,13 @@
/**
* Checks whether the given security context is allowed to read from the
* file named by the argument, which should be passed in canonical form.
- *
+ *
* @param file
* the name of the file or directory to check.
* @param context
* the security context to use for the check.
* @throws SecurityException
* if {@code context} is not allowed to read from {@code file}.
- * @since Android 1.0
*/
public void checkRead(String file, Object context) {
checkPermission(new FilePermission(file, "read"), context); //$NON-NLS-1$
@@ -535,13 +508,12 @@
/**
* Checks whether the calling thread is allowed to perform the security
* operation named by the target.
- *
+ *
* @param target
* the name of the operation to perform.
* @throws SecurityException
* if the calling thread is not allowed to perform
* {@code target}.
- * @since Android 1.0
*/
public void checkSecurityAccess(String target) {
checkPermission(new SecurityPermission(target));
@@ -550,11 +522,10 @@
/**
* Checks whether the calling thread is allowed to set the net object
* factories.
- *
+ *
* @throws SecurityException
* if the calling thread is not allowed to set the net object
* factories.
- * @since Android 1.0
*/
public void checkSetFactory() {
checkPermission(RuntimePermission.permissionToSetFactory);
@@ -563,14 +534,13 @@
/**
* Checks whether the calling thread is trusted to show the specified top
* level window.
- *
+ *
* @param window
* the window to show.
* @return {@code true} if the calling thread is allowed to show {@code
* window}; {@code false} otherwise.
* @throws NullPointerException
* if {@code window} is {@code null}.
- * @since Android 1.0
*/
public boolean checkTopLevelWindow(Object window) {
if (window == null) {
@@ -597,11 +567,10 @@
/**
* Checks whether the calling thread is allowed to access the system
* clipboard.
- *
+ *
* @throws SecurityException
* if the calling thread is not allowed to access the system
* clipboard.
- * @since Android 1.0
*/
public void checkSystemClipboardAccess() {
try {
@@ -623,11 +592,10 @@
/**
* Checks whether the calling thread is allowed to access the AWT event
* queue.
- *
+ *
* @throws SecurityException
* if the calling thread is not allowed to access the AWT event
* queue.
- * @since Android 1.0
*/
public void checkAwtEventQueueAccess() {
try {
@@ -648,11 +616,10 @@
/**
* Checks whether the calling thread is allowed to start a new print job.
- *
+ *
* @throws SecurityException
* if the calling thread is not allowed to start a new print
* job.
- * @since Android 1.0
*/
public void checkPrintJobAccess() {
checkPermission(RuntimePermission.permissionToQueuePrintJob);
@@ -661,12 +628,11 @@
/**
* Checks whether the calling thread is allowed to write to the file with
* the specified file descriptor.
- *
+ *
* @param fd
* the file descriptor of the file to write to.
* @throws SecurityException
* if the calling thread is not allowed to write to {@code fd}.
- * @since Android 1.0
*/
public void checkWrite(FileDescriptor fd) {
if (fd == null) {
@@ -678,13 +644,12 @@
/**
* Checks whether the calling thread is allowed to write to the file with
* the specified name, which should be passed in canonical form.
- *
+ *
* @param file
* the name of the file or directory to write to.
* @throws SecurityException
- * if the calling thread is not allowed to write to
+ * if the calling thread is not allowed to write to
* {@code file}.
- * @since Android 1.0
*/
public void checkWrite(String file) {
checkPermission(new FilePermission(file, "write")); //$NON-NLS-1$
@@ -692,11 +657,10 @@
/**
* Indicates if this security manager is currently checking something.
- *
+ *
* @return {@code true} if this security manager is executing a security
* check method; {@code false} otherwise.
* @deprecated Use {@link #checkPermission}.
- * @since Android 1.0
*/
@Deprecated
public boolean getInCheck() {
@@ -707,9 +671,8 @@
* Returns an array containing one entry for each method in the current
* execution stack. Each entry is the {@code java.lang.Class} which
* represents the class in which the method is defined.
- *
+ *
* @return all classes in the execution stack.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
protected Class[] getClassContext() {
@@ -719,10 +682,9 @@
/**
* Returns the class loader of the first class in the execution stack whose
* class loader is not a system class loader.
- *
+ *
* @return the most recent non-system class loader.
* @deprecated Use {@link #checkPermission}.
- * @since Android 1.0
*/
@Deprecated
protected ClassLoader currentClassLoader() {
@@ -755,11 +717,10 @@
/**
* Returns the index in the call stack of the first class whose class loader
* is not a system class loader.
- *
+ *
* @return the frame index of the first method whose class was loaded by a
* non-system class loader.
* @deprecated Use {@link #checkPermission}.
- * @since Android 1.0
*/
@Deprecated
protected int classLoaderDepth() {
@@ -791,10 +752,9 @@
/**
* Returns the first class in the call stack that was loaded by a class
* loader which is not a system class loader.
- *
+ *
* @return the most recent class loaded by a non-system class loader.
* @deprecated Use {@link #checkPermission}.
- * @since Android 1.0
*/
@Deprecated
protected Class<?> currentLoadedClass() {
@@ -827,13 +787,12 @@
* Returns the index in the call stack of the first method which is
* contained in the class with the specified name. Returns -1 if no methods
* from this class are in the stack.
- *
+ *
* @param name
* the name of the class to look for.
* @return the frame index of the first method found is contained in the
* class identified by {@code name}.
* @deprecated Use {@link #checkPermission}.
- * @since Android 1.0
*/
@Deprecated
protected int classDepth(String name) {
@@ -849,13 +808,12 @@
/**
* Indicates whether there is a method in the call stack from the class with
* the specified name.
- *
+ *
* @param name
* the name of the class to look for.
* @return {@code true} if a method from the class identified by {@code
* name} is executing; {@code false} otherwise.
* @deprecated Use {@link #checkPermission}.
- * @since Android 1.0
*/
@Deprecated
protected boolean inClass(String name) {
@@ -865,11 +823,10 @@
/**
* Indicates whether there is a method in the call stack from a class which
* was defined by a non-system class loader.
- *
+ *
* @return {@code true} if a method from a class that was defined by a
* non-system class loader is executing; {@code false} otherwise.
* @deprecated Use {@link #checkPermission}
- * @since Android 1.0
*/
@Deprecated
protected boolean inClassLoader() {
@@ -880,9 +837,8 @@
* Returns the thread group which should be used to instantiate new threads.
* By default, this is the same as the thread group of the thread running
* this method.
- *
+ *
* @return ThreadGroup the thread group to create new threads in.
- * @since Android 1.0
*/
public ThreadGroup getThreadGroup() {
return Thread.currentThread().getThreadGroup();
@@ -890,12 +846,11 @@
/**
* Returns an object which encapsulates the security state of the current
- * point in the execution. In the Android reference implementation, this is
- * an {@link java.security.AccessControlContext}.
- *
+ * point in the execution. In our case, this is an {@link
+ * java.security.AccessControlContext}.
+ *
* @return an object that encapsulates information about the current
* execution environment.
- * @since Android 1.0
*/
public Object getSecurityContext() {
return AccessController.getContext();
@@ -904,13 +859,12 @@
/**
* Checks whether the calling thread is allowed to access the resource being
* guarded by the specified permission object.
- *
+ *
* @param permission
* the permission to check.
* @throws SecurityException
* if the requested {@code permission} is denied according to
* the current security policy.
- * @since Android 1.0
*/
public void checkPermission(Permission permission) {
try {
@@ -924,7 +878,7 @@
/**
* Checks whether the specified security context is allowed to access the
* resource being guarded by the specified permission object.
- *
+ *
* @param permission
* the permission to check.
* @param context
@@ -934,7 +888,6 @@
* AccessControlContext} or if the requested {@code permission}
* is denied for {@code context} according to the current
* security policy.
- * @since Android 1.0
*/
public void checkPermission(Permission permission, Object context) {
try {
diff --git a/luni/src/main/java/java/lang/Short.java b/luni/src/main/java/java/lang/Short.java
index cf95d22..9baf3a8 100644
--- a/luni/src/main/java/java/lang/Short.java
+++ b/luni/src/main/java/java/lang/Short.java
@@ -21,11 +21,11 @@
* The wrapper for the primitive type {@code short}.
*
* @see java.lang.Number
- * @since Android 1.0
+ * @since 1.1
*/
public final class Short extends Number implements Comparable<Short> {
- private static final long serialVersionUID = 7515723908773894738L;
+ private static final long serialVersionUID = 7515723908773894738L;
/**
* The value which the receiver represents.
@@ -34,69 +34,61 @@
/**
* Constant for the maximum {@code short} value, 2<sup>15</sup>-1.
- *
- * @since Android 1.0
*/
public static final short MAX_VALUE = (short) 0x7FFF;
/**
* Constant for the minimum {@code short} value, -2<sup>15</sup>.
- *
- * @since Android 1.0
*/
public static final short MIN_VALUE = (short) 0x8000;
/**
* Constant for the number of bits needed to represent a {@code short} in
* two's complement form.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public static final int SIZE = 16;
/**
- * The {@link Class} object that represents the primitive type {@code
+ * The {@link Class} object that represents the primitive type {@code
* short}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Class<Short> TYPE = (Class<Short>) new short[0]
.getClass().getComponentType();
- // Note: This can't be set to "short.class", since *that* is
- // defined to be "java.lang.Short.TYPE";
+ // Note: This can't be set to "short.class", since *that* is
+ // defined to be "java.lang.Short.TYPE";
/**
* Constructs a new {@code Short} from the specified string.
- *
+ *
* @param string
* the string representation of a short value.
* @throws NumberFormatException
* if {@code string} can not be decoded into a short value.
* @see #parseShort(String)
- * @since Android 1.0
*/
- public Short(String string) throws NumberFormatException {
- this(parseShort(string));
- }
+ public Short(String string) throws NumberFormatException {
+ this(parseShort(string));
+ }
/**
* Constructs a new {@code Short} with the specified primitive short value.
- *
+ *
* @param value
* the primitive short value to store in the new instance.
- * @since Android 1.0
*/
- public Short(short value) {
- this.value = value;
- }
+ public Short(short value) {
+ this.value = value;
+ }
- @Override
+ @Override
public byte byteValue() {
- return (byte) value;
- }
+ return (byte) value;
+ }
/**
* Compares this object to the specified short object to determine their
@@ -108,98 +100,97 @@
* value of {@code object}; 0 if the value of this short and the
* value of {@code object} are equal; a positive value if the value
* of this short is greater than the value of {@code object}.
+ * @throws NullPointerException
+ * if {@code object} is null.
* @see java.lang.Comparable
- * @since Android 1.0
+ * @since 1.2
*/
- public int compareTo(Short object) {
- return value > object.value ? 1 : (value < object.value ? -1 : 0);
- }
+ public int compareTo(Short object) {
+ return value > object.value ? 1 : (value < object.value ? -1 : 0);
+ }
/**
* Parses the specified string and returns a {@code Short} instance if the
* string can be decoded into a short value. The string may be an optional
* minus sign "-" followed by a hexadecimal ("0x..." or "#..."), octal
* ("0..."), or decimal ("...") representation of a short.
- *
+ *
* @param string
* a string representation of a short value.
* @return a {@code Short} containing the value represented by
* {@code string}.
* @throws NumberFormatException
* if {@code string} can not be parsed as a short value.
- * @since Android 1.0
*/
- public static Short decode(String string) throws NumberFormatException {
- int intValue = Integer.decode(string).intValue();
- short result = (short) intValue;
- if (result == intValue) {
+ public static Short decode(String string) throws NumberFormatException {
+ int intValue = Integer.decode(string).intValue();
+ short result = (short) intValue;
+ if (result == intValue) {
return valueOf(result);
}
- throw new NumberFormatException();
- }
+ throw new NumberFormatException();
+ }
- @Override
+ @Override
public double doubleValue() {
- return value;
- }
+ return value;
+ }
/**
* Compares this instance with the specified object and indicates if they
* are equal. In order to be equal, {@code object} must be an instance of
* {@code Short} and have the same short value as this object.
- *
+ *
* @param object
* the object to compare this short with.
* @return {@code true} if the specified object is equal to this
* {@code Short}; {@code false} otherwise.
- * @since Android 1.0
*/
- @Override
+ @Override
public boolean equals(Object object) {
- return (object instanceof Short)
- && (value == ((Short) object).value);
- }
+ return (object instanceof Short)
+ && (value == ((Short) object).value);
+ }
- @Override
+ @Override
public float floatValue() {
- return value;
- }
+ return value;
+ }
- @Override
+ @Override
public int hashCode() {
- return value;
- }
+ return value;
+ }
- @Override
+ @Override
public int intValue() {
- return value;
- }
+ return value;
+ }
- @Override
+ @Override
public long longValue() {
- return value;
- }
+ return value;
+ }
/**
* Parses the specified string as a signed decimal short value. The ASCII
* character \u002d ('-') is recognized as the minus sign.
- *
+ *
* @param string
* the string representation of a short value.
* @return the primitive short value represented by {@code string}.
* @throws NumberFormatException
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a short value.
- * @since Android 1.0
*/
- public static short parseShort(String string) throws NumberFormatException {
- return parseShort(string, 10);
- }
+ public static short parseShort(String string) throws NumberFormatException {
+ return parseShort(string, 10);
+ }
/**
* Parses the specified string as a signed short value using the specified
* radix. The ASCII character \u002d ('-') is recognized as the minus sign.
- *
+ *
* @param string
* the string representation of a short value.
* @param radix
@@ -211,50 +202,47 @@
* {@code radix < Character.MIN_RADIX},
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as a short value.
- * @since Android 1.0
*/
- public static short parseShort(String string, int radix)
- throws NumberFormatException {
- int intValue = Integer.parseInt(string, radix);
- short result = (short) intValue;
- if (result == intValue) {
+ public static short parseShort(String string, int radix)
+ throws NumberFormatException {
+ int intValue = Integer.parseInt(string, radix);
+ short result = (short) intValue;
+ if (result == intValue) {
return result;
}
- throw new NumberFormatException();
- }
+ throw new NumberFormatException();
+ }
/**
* Gets the primitive value of this short.
- *
+ *
* @return this object's primitive value.
- * @since Android 1.0
*/
@Override
public short shortValue() {
- return value;
- }
+ return value;
+ }
- @Override
+ @Override
public String toString() {
- return Integer.toString(value);
- }
+ return Integer.toString(value);
+ }
/**
* Returns a string containing a concise, human-readable description of the
* specified short value with radix 10.
- *
+ *
* @param value
* the short to convert to a string.
* @return a printable representation of {@code value}.
- * @since Android 1.0
*/
- public static String toString(short value) {
- return Integer.toString(value);
- }
+ public static String toString(short value) {
+ return Integer.toString(value);
+ }
/**
* Parses the specified string as a signed decimal short value.
- *
+ *
* @param string
* the string representation of a short value.
* @return a {@code Short} instance containing the short value represented
@@ -263,16 +251,15 @@
* if {@code string} is {@code null}, has a length of zero or
* can not be parsed as a short value.
* @see #parseShort(String)
- * @since Android 1.0
*/
- public static Short valueOf(String string) throws NumberFormatException {
- return valueOf(parseShort(string));
- }
+ public static Short valueOf(String string) throws NumberFormatException {
+ return valueOf(parseShort(string));
+ }
/**
* Parses the specified string as a signed short value using the specified
* radix.
- *
+ *
* @param string
* the string representation of a short value.
* @param radix
@@ -285,12 +272,11 @@
* {@code radix > Character.MAX_RADIX}, or if {@code string}
* can not be parsed as a short value.
* @see #parseShort(String, int)
- * @since Android 1.0
*/
- public static Short valueOf(String string, int radix)
- throws NumberFormatException {
- return valueOf(parseShort(string, radix));
- }
+ public static Short valueOf(String string, int radix)
+ throws NumberFormatException {
+ return valueOf(parseShort(string, radix));
+ }
/**
* Reverses the bytes of the specified short.
@@ -298,7 +284,7 @@
* @param s
* the short value for which to reverse bytes.
* @return the reversed value.
- * @since Android 1.0
+ * @since 1.5
*/
public static short reverseBytes(short s) {
int high = (s >> 8) & 0xFF;
@@ -312,12 +298,11 @@
* If it is not necessary to get a new {@code Short} instance, it is
* recommended to use this method instead of the constructor, since it
* maintains a cache of instances which may result in better performance.
- * </p>
- *
+ *
* @param s
* the short value to store in the instance.
* @return a {@code Short} instance containing {@code s}.
- * @since Android 1.0
+ * @since 1.5
*/
public static Short valueOf(short s) {
if (s < -128 || s > 127) {
@@ -328,9 +313,7 @@
static class valueOfCache {
/**
- * <p>
* A cache of instances used by {@link Short#valueOf(short)} and auto-boxing.
- * </p>
*/
private static final Short[] CACHE = new Short[256];
diff --git a/luni/src/main/java/java/lang/StackOverflowError.java b/luni/src/main/java/java/lang/StackOverflowError.java
index dd63b6b..3cbc0c7 100644
--- a/luni/src/main/java/java/lang/StackOverflowError.java
+++ b/luni/src/main/java/java/lang/StackOverflowError.java
@@ -22,8 +22,6 @@
* platform or virtual machine specific limit. Typically, this will occur only
* when a program becomes infinitely recursive, but it can also occur in
* correctly written (but deeply recursive) programs.
- *
- * @since Android 1.0
*/
public class StackOverflowError extends java.lang.VirtualMachineError {
@@ -32,8 +30,6 @@
/**
* Constructs a new {@code StackOverflowError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public StackOverflowError() {
super();
@@ -45,7 +41,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public StackOverflowError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/StrictMath.java b/luni/src/main/java/java/lang/StrictMath.java
index 66e4771..7a2da8e 100644
--- a/luni/src/main/java/java/lang/StrictMath.java
+++ b/luni/src/main/java/java/lang/StrictMath.java
@@ -37,25 +37,19 @@
* Library" (fdlibm), version 5.3.
* <p>
* <a href="http://www.netlib.org/fdlibm/">http://www.netlib.org/fdlibm/</a>
- *
- * @since Android 1.0
*/
public final class StrictMath {
- /**
+ /**
* The double value closest to e, the base of the natural logarithm.
- *
- * @since Android 1.0
- */
- public final static double E = Math.E;
+ */
+ public final static double E = Math.E;
- /**
+ /**
* The double value closest to pi, the ratio of a circle's circumference to
* its diameter.
- *
- * @since Android 1.0
- */
- public final static double PI = Math.PI;
+ */
+ public final static double PI = Math.PI;
private static java.util.Random random;
@@ -65,7 +59,7 @@
private StrictMath() {
}
- /**
+ /**
* Returns the absolute value of the argument.
* <p>
* Special cases:
@@ -75,18 +69,16 @@
* <li>{@code abs(-infinity) = +infinity}</li>
* <li>{@code abs(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose absolute value has to be computed.
* @return the absolute value of the argument.
- * @since Android 1.0
*/
- public static double abs(double d) {
- long bits = Double.doubleToLongBits(d);
- bits &= 0x7fffffffffffffffL;
- return Double.longBitsToDouble(bits);
- }
+ public static double abs(double d) {
+ long bits = Double.doubleToLongBits(d);
+ bits &= 0x7fffffffffffffffL;
+ return Double.longBitsToDouble(bits);
+ }
/**
* Returns the absolute value of the argument.
@@ -98,52 +90,47 @@
* <li>{@code abs(-infinity) = +infinity}</li>
* <li>{@code abs(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param f
* the value whose absolute value has to be computed.
* @return the argument if it is positive, otherwise the negation of the
* argument.
- * @since Android 1.0
*/
- public static float abs(float f) {
- int bits = Float.floatToIntBits(f);
- bits &= 0x7fffffff;
- return Float.intBitsToFloat(bits);
- }
+ public static float abs(float f) {
+ int bits = Float.floatToIntBits(f);
+ bits &= 0x7fffffff;
+ return Float.intBitsToFloat(bits);
+ }
/**
* Returns the absolute value of the argument.
* <p>
* If the argument is {@code Integer.MIN_VALUE}, {@code Integer.MIN_VALUE}
* is returned.
- *
+ *
* @param i
* the value whose absolute value has to be computed.
* @return the argument if it is positive, otherwise the negation of the
* argument.
- * @since Android 1.0
*/
- public static int abs(int i) {
- return i >= 0 ? i : -i;
- }
+ public static int abs(int i) {
+ return i >= 0 ? i : -i;
+ }
/**
* Returns the absolute value of the argument.
* <p>
* If the argument is {@code Long.MIN_VALUE}, {@code Long.MIN_VALUE} is
* returned.
- * </p>
- *
+ *
* @param l
* the value whose absolute value has to be computed.
* @return the argument if it is positive, otherwise the negation of the
* argument.
- * @since Android 1.0
*/
- public static long abs(long l) {
- return l >= 0 ? l : -l;
- }
+ public static long abs(long l) {
+ return l >= 0 ? l : -l;
+ }
/**
* Returns the closest double approximation of the arc cosine of the
@@ -155,14 +142,12 @@
* <li>{@code acos((anything < -1) = NaN}</li>
* <li>{@code acos(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to compute arc cosine of.
* @return the arc cosine of the argument.
- * @since Android 1.0
*/
- public static native double acos(double d);
+ public static native double acos(double d);
/**
* Returns the closest double approximation of the arc sine of the argument
@@ -174,14 +159,12 @@
* <li>{@code asin((anything < -1)) = NaN}</li>
* <li>{@code asin(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose arc sine has to be computed.
* @return the arc sine of the argument.
- * @since Android 1.0
*/
- public static native double asin(double d);
+ public static native double asin(double d);
/**
* Returns the closest double approximation of the arc tangent of the
@@ -195,14 +178,12 @@
* <li>{@code atan(-infinity) = -pi/2}</li>
* <li>{@code atan(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose arc tangent has to be computed.
* @return the arc tangent of the argument.
- * @since Android 1.0
*/
- public static native double atan(double d);
+ public static native double atan(double d);
/**
* Returns the closest double approximation of the arc tangent of
@@ -234,20 +215,15 @@
* <li>{@code atan2(-infinity, (anything but,0, NaN, and infinity))}
* {@code =} {@code -pi/2}</li>
* </ul>
- * </p>
- *
+ *
* @param y
* the numerator of the value whose atan has to be computed.
* @param x
* the denominator of the value whose atan has to be computed.
* @return the arc tangent of {@code y/x}.
- * @since Android 1.0
*/
- public static native double atan2(double y, double x);
- // BEGIN android-note
- // parameter names changed from d1 / d2 to x / y
- // END android-note
-
+ public static native double atan2(double y, double x);
+
/**
* Returns the closest double approximation of the cube root of the
* argument.
@@ -260,12 +236,10 @@
* <li>{@code cbrt(-infinity) = -infinity}</li>
* <li>{@code cbrt(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose cube root has to be computed.
* @return the cube root of the argument.
- * @since Android 1.0
*/
public static native double cbrt(double d);
@@ -282,15 +256,14 @@
* <li>{@code ceil(-infinity) = -infinity}</li>
* <li>{@code ceil(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose closest integer value has to be computed.
* @return the ceiling of the argument.
- * @since Android 1.0
*/
- public static native double ceil(double d);
-
+ public static native double ceil(double d);
+
+
/**
* Returns the closest double approximation of the hyperbolic cosine of the
* argument.
@@ -301,12 +274,10 @@
* <li>{@code cosh(-infinity) = +infinity}</li>
* <li>{@code cosh(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose hyperbolic cosine has to be computed.
* @return the hyperbolic cosine of the argument.
- * @since Android 1.0
*/
public static native double cosh(double d);
@@ -319,12 +290,10 @@
* <li>{@code cos(-infinity) = NaN}</li>
* <li>{@code cos(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the angle whose cosine has to be computed, in radians.
* @return the cosine of the argument.
- * @since Android 1.0
*/
public static native double cos(double d);
@@ -338,15 +307,13 @@
* <li>{@code exp(-infinity) = +0.0}</li>
* <li>{@code exp(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose exponential has to be computed.
* @return the exponential of the argument.
- * @since Android 1.0
*/
public static native double exp(double d);
-
+
/**
* Returns the closest double approximation of <i>{@code e}</i><sup>
* {@code d}</sup>{@code - 1}. If the argument is very close to 0, it is
@@ -361,14 +328,12 @@
* <li>{@code expm1(-infinity) = -1.0}</li>
* <li>{@code expm1(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to compute the <i>{@code e}</i><sup>{@code d}</sup>
* {@code - 1} of.
* @return the <i>{@code e}</i><sup>{@code d}</sup>{@code - 1} value
* of the argument.
- * @since Android 1.0
*/
public static native double expm1(double d);
@@ -384,14 +349,12 @@
* <li>{@code floor(-infinity) = -infinity}</li>
* <li>{@code floor(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d the value whose closest integer value has to be computed.
* @return the floor of the argument.
- * @since Android 1.0
*/
public static native double floor(double d);
-
+
/**
* Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +}
* <i> {@code y}</i><sup>{@code 2}</sup>{@code )}. The final result is
@@ -405,8 +368,7 @@
* <li>{@code hypot((anything including NaN), -infinity) = +infinity}</li>
* <li>{@code hypot(NaN, NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param x
* a double number.
* @param y
@@ -414,7 +376,6 @@
* @return the {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +}
* <i> {@code y}</i><sup>{@code 2}</sup>{@code )} value of the
* arguments.
- * @since Android 1.0
*/
public static native double hypot(double x, double y);
@@ -436,19 +397,14 @@
* <li>{@code IEEEremainder(x, -infinity) = x } where x is anything but
* +/-infinity</li>
* </ul>
- * </p>
- *
+ *
* @param x
* the numerator of the operation.
* @param y
* the denominator of the operation.
* @return the IEEE754 floating point reminder of of {@code x/y}.
- * @since Android 1.0
*/
- public static native double IEEEremainder(double x, double y);
- // BEGIN android-note
- // parameter names changed from d1 / d2 to x / y
- // END android-note
+ public static native double IEEEremainder(double x, double y);
/**
* Returns the closest double approximation of the natural logarithm of the
@@ -463,15 +419,13 @@
* <li>{@code log(-infinity) = NaN}</li>
* <li>{@code log(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose log has to be computed.
* @return the natural logarithm of the argument.
- * @since Android 1.0
*/
public static native double log(double d);
-
+
/**
* Returns the closest double approximation of the base 10 logarithm of the
* argument.
@@ -485,15 +439,13 @@
* <li>{@code log10(-infinity) = NaN}</li>
* <li>{@code log10(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose base 10 log has to be computed.
* @return the natural logarithm of the argument.
- * @since Android 1.0
*/
public static native double log10(double d);
-
+
/**
* Returns the closest double approximation of the natural logarithm of the
* sum of the argument and 1. If the argument is very close to 0, it is much
@@ -510,12 +462,10 @@
* <li>{@code log1p(-infinity) = NaN}</li>
* <li>{@code log1p(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to compute the {@code ln(1+d)} of.
* @return the natural logarithm of the sum of the argument and 1.
- * @since Android 1.0
*/
public static native double log1p(double d);
@@ -530,29 +480,27 @@
* <li>{@code max(+0.0, -0.0) = +0.0}</li>
* <li>{@code max(-0.0, +0.0) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param d1
* the first argument.
* @param d2
* the second argument.
* @return the larger of {@code d1} and {@code d2}.
- * @since Android 1.0
*/
- public static double max(double d1, double d2) {
- if (d1 > d2)
- return d1;
- if (d1 < d2)
- return d2;
- /* if either arg is NaN, return NaN */
- if (d1 != d2)
- return Double.NaN;
- /* max( +0.0,-0.0) == +0.0 */
- if (d1 == 0.0
- && ((Double.doubleToLongBits(d1) & Double.doubleToLongBits(d2)) & 0x8000000000000000L) == 0)
- return 0.0;
- return d1;
- }
+ public static double max(double d1, double d2) {
+ if (d1 > d2)
+ return d1;
+ if (d1 < d2)
+ return d2;
+ /* if either arg is NaN, return NaN */
+ if (d1 != d2)
+ return Double.NaN;
+ /* max( +0.0,-0.0) == +0.0 */
+ if (d1 == 0.0
+ && ((Double.doubleToLongBits(d1) & Double.doubleToLongBits(d2)) & 0x8000000000000000L) == 0)
+ return 0.0;
+ return d1;
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
@@ -565,59 +513,55 @@
* <li>{@code max(+0.0, -0.0) = +0.0}</li>
* <li>{@code max(-0.0, +0.0) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param f1
* the first argument.
* @param f2
* the second argument.
* @return the larger of {@code f1} and {@code f2}.
- * @since Android 1.0
*/
- public static float max(float f1, float f2) {
- if (f1 > f2)
- return f1;
- if (f1 < f2)
- return f2;
- /* if either arg is NaN, return NaN */
- if (f1 != f2)
- return Float.NaN;
- /* max( +0.0,-0.0) == +0.0 */
- if (f1 == 0.0f
- && ((Float.floatToIntBits(f1) & Float.floatToIntBits(f2)) & 0x80000000) == 0)
- return 0.0f;
- return f1;
- }
+ public static float max(float f1, float f2) {
+ if (f1 > f2)
+ return f1;
+ if (f1 < f2)
+ return f2;
+ /* if either arg is NaN, return NaN */
+ if (f1 != f2)
+ return Float.NaN;
+ /* max( +0.0,-0.0) == +0.0 */
+ if (f1 == 0.0f
+ && ((Float.floatToIntBits(f1) & Float.floatToIntBits(f2)) & 0x80000000) == 0)
+ return 0.0f;
+ return f1;
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
* arguments.
- *
+ *
* @param i1
* the first argument.
* @param i2
* the second argument.
* @return the larger of {@code i1} and {@code i2}.
- * @since Android 1.0
*/
- public static int max(int i1, int i2) {
- return i1 > i2 ? i1 : i2;
- }
+ public static int max(int i1, int i2) {
+ return i1 > i2 ? i1 : i2;
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
* arguments.
- *
+ *
* @param l1
* the first argument.
* @param l2
* the second argument.
* @return the larger of {@code l1} and {@code l2}.
- * @since Android 1.0
*/
- public static long max(long l1, long l2) {
- return l1 > l2 ? l1 : l2;
- }
+ public static long max(long l1, long l2) {
+ return l1 > l2 ? l1 : l2;
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
@@ -630,29 +574,27 @@
* <li>{@code min(+0.0, -0.0) = -0.0}</li>
* <li>{@code min(-0.0, +0.0) = -0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param d1
* the first argument.
* @param d2
* the second argument.
* @return the smaller of {@code d1} and {@code d2}.
- * @since Android 1.0
*/
- public static double min(double d1, double d2) {
- if (d1 > d2)
- return d2;
- if (d1 < d2)
- return d1;
- /* if either arg is NaN, return NaN */
- if (d1 != d2)
- return Double.NaN;
- /* min( +0.0,-0.0) == -0.0 */
- if (d1 == 0.0
- && ((Double.doubleToLongBits(d1) | Double.doubleToLongBits(d2)) & 0x8000000000000000l) != 0)
- return 0.0 * (-1.0);
- return d1;
- }
+ public static double min(double d1, double d2) {
+ if (d1 > d2)
+ return d2;
+ if (d1 < d2)
+ return d1;
+ /* if either arg is NaN, return NaN */
+ if (d1 != d2)
+ return Double.NaN;
+ /* min( +0.0,-0.0) == -0.0 */
+ if (d1 == 0.0
+ && ((Double.doubleToLongBits(d1) | Double.doubleToLongBits(d2)) & 0x8000000000000000l) != 0)
+ return 0.0 * (-1.0);
+ return d1;
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
@@ -665,59 +607,55 @@
* <li>{@code min(+0.0, -0.0) = -0.0}</li>
* <li>{@code min(-0.0, +0.0) = -0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param f1
* the first argument.
* @param f2
* the second argument.
* @return the smaller of {@code f1} and {@code f2}.
- * @since Android 1.0
*/
- public static float min(float f1, float f2) {
- if (f1 > f2)
- return f2;
- if (f1 < f2)
- return f1;
- /* if either arg is NaN, return NaN */
- if (f1 != f2)
- return Float.NaN;
- /* min( +0.0,-0.0) == -0.0 */
- if (f1 == 0.0f
- && ((Float.floatToIntBits(f1) | Float.floatToIntBits(f2)) & 0x80000000) != 0)
- return 0.0f * (-1.0f);
- return f1;
- }
+ public static float min(float f1, float f2) {
+ if (f1 > f2)
+ return f2;
+ if (f1 < f2)
+ return f1;
+ /* if either arg is NaN, return NaN */
+ if (f1 != f2)
+ return Float.NaN;
+ /* min( +0.0,-0.0) == -0.0 */
+ if (f1 == 0.0f
+ && ((Float.floatToIntBits(f1) | Float.floatToIntBits(f2)) & 0x80000000) != 0)
+ return 0.0f * (-1.0f);
+ return f1;
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
* arguments.
- *
+ *
* @param i1
* the first argument.
* @param i2
* the second argument.
* @return the smaller of {@code i1} and {@code i2}.
- * @since Android 1.0
*/
- public static int min(int i1, int i2) {
- return i1 < i2 ? i1 : i2;
- }
+ public static int min(int i1, int i2) {
+ return i1 < i2 ? i1 : i2;
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
* arguments.
- *
+ *
* @param l1
* the first argument.
* @param l2
* the second argument.
* @return the smaller of {@code l1} and {@code l2}.
- * @since Android 1.0
*/
- public static long min(long l1, long l2) {
- return l1 < l2 ? l1 : l2;
- }
+ public static long min(long l1, long l2) {
+ return l1 < l2 ? l1 : l2;
+ }
/**
* Returns the closest double approximation of the result of raising
@@ -750,26 +688,20 @@
* <li>{@code pow((-anything except 0 and infinity), (non-integer))}
* {@code =} {@code NAN}</li>
* </ul>
- * </p>
- *
+ *
* @param x
* the base of the operation.
* @param y
* the exponent of the operation.
* @return {@code x} to the power of {@code y}.
- * @since Android 1.0
*/
- public static native double pow(double x, double y);
- // BEGIN android-note
- // parameter names changed from d1 / d2 to x / y
- // END android-note
+ public static native double pow(double x, double y);
/**
* Returns a pseudo-random number between 0.0 (inclusive) and 1.0
* (exclusive).
- *
+ *
* @return a pseudo-random number.
- * @since Android 1.0
*/
public static double random() {
// BEGIN android-changed
@@ -777,8 +709,8 @@
random = new java.util.Random();
}
// END android-changed
- return random.nextDouble();
- }
+ return random.nextDouble();
+ }
/**
* Returns the double conversion of the result of rounding the argument to
@@ -792,12 +724,10 @@
* <li>{@code rint(-infinity) = -infinity}</li>
* <li>{@code rint(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to be rounded.
* @return the closest integer to the argument (as a double).
- * @since Android 1.0
*/
public static native double rint(double d);
@@ -815,19 +745,17 @@
* <li>{@code round(-infinity) = Long.MIN_VALUE}</li>
* <li>{@code round(NaN) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value to be rounded.
* @return the closest integer to the argument.
- * @since Android 1.0
*/
- public static long round(double d) {
- // check for NaN
- if (d != d)
- return 0L;
- return (long) Math.floor(d + 0.5d);
- }
+ public static long round(double d) {
+ // check for NaN
+ if (d != d)
+ return 0L;
+ return (long) Math.floor(d + 0.5d);
+ }
/**
* Returns the result of rounding the argument to an integer. The result is
@@ -843,19 +771,17 @@
* <li>{@code round(-infinity) = Integer.MIN_VALUE}</li>
* <li>{@code round(NaN) = +0.0}</li>
* </ul>
- * </p>
- *
+ *
* @param f
* the value to be rounded.
* @return the closest integer to the argument.
- * @since Android 1.0
*/
- public static int round(float f) {
- // check for NaN
- if (f != f)
- return 0;
- return (int) Math.floor(f + 0.5f);
- }
+ public static int round(float f) {
+ // check for NaN
+ if (f != f)
+ return 0;
+ return (int) Math.floor(f + 0.5f);
+ }
/**
* Returns the signum function of the argument. If the argument is less than
@@ -871,12 +797,10 @@
* <li>{@code signum(-infinity) = -1.0}</li>
* <li>{@code signum(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose signum has to be computed.
* @return the value of the signum function.
- * @since Android 1.0
*/
public static double signum(double d){
if(Double.isNaN(d)){
@@ -905,12 +829,10 @@
* <li>{@code signum(-infinity) = -1.0}</li>
* <li>{@code signum(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param f
* the value whose signum has to be computed.
* @return the value of the signum function.
- * @since Android 1.0
*/
public static float signum(float f){
if(Float.isNaN(f)){
@@ -937,15 +859,13 @@
* <li>{@code sinh(-infinity) = -infinity}</li>
* <li>{@code sinh(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose hyperbolic sine has to be computed.
* @return the hyperbolic sine of the argument.
- * @since Android 1.0
*/
public static native double sinh(double d);
-
+
/**
* Returns the closest double approximation of the sine of the argument.
* <p>
@@ -957,12 +877,10 @@
* <li>{@code sin(-infinity) = NaN}</li>
* <li>{@code sin(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the angle whose sin has to be computed, in radians.
* @return the sine of the argument.
- * @since Android 1.0
*/
public static native double sin(double d);
@@ -978,12 +896,10 @@
* <li>{@code sqrt(+infinity) = +infinity}</li>
* <li>{@code sqrt(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose square root has to be computed.
* @return the square root of the argument.
- * @since Android 1.0
*/
public static native double sqrt(double d);
@@ -998,12 +914,10 @@
* <li>{@code tan(-infinity) = NaN}</li>
* <li>{@code tan(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the angle whose tangens has to be computed, in radians.
* @return the tangent of the argument.
- * @since Android 1.0
*/
public static native double tan(double d);
@@ -1019,15 +933,13 @@
* <li>{@code tanh(-infinity) = -1.0}</li>
* <li>{@code tanh(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the value whose hyperbolic tangent has to be computed.
* @return the hyperbolic tangent of the argument
- * @since Android 1.0
*/
public static native double tanh(double d);
-
+
/**
* Returns the measure in degrees of the supplied radian angle. The result
* is {@code angrad * 180 / pi}.
@@ -1040,16 +952,14 @@
* <li>{@code toDegrees(-infinity) = -infinity}</li>
* <li>{@code toDegrees(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param angrad
* an angle in radians.
* @return the degree measure of the angle.
- * @since Android 1.0
*/
- public static double toDegrees(double angrad) {
- return angrad * 180d / PI;
- }
+ public static double toDegrees(double angrad) {
+ return angrad * 180d / PI;
+ }
/**
* Returns the measure in radians of the supplied degree angle. The result
@@ -1063,18 +973,16 @@
* <li>{@code toRadians(-infinity) = -infinity}</li>
* <li>{@code toRadians(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param angdeg
* an angle in degrees.
* @return the radian measure of the angle.
- * @since Android 1.0
*/
- public static double toRadians(double angdeg) {
- return angdeg / 180d * PI;
- }
-
- /**
+ public static double toRadians(double angdeg) {
+ return angdeg / 180d * PI;
+ }
+
+ /**
* Returns the argument's ulp (unit in the last place). The size of a ulp of
* a double value is the positive distance between this value and the double
* value next larger in magnitude. For non-NaN {@code x},
@@ -1088,12 +996,10 @@
* <li>{@code ulp(-infintiy) = infinity}</li>
* <li>{@code ulp(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param d
* the floating-point value to compute ulp of.
* @return the size of a ulp of the argument.
- * @since Android 1.0
*/
public static double ulp(double d) {
// special cases
@@ -1120,12 +1026,10 @@
* <li>{@code ulp(-infintiy) = infinity}</li>
* <li>{@code ulp(NaN) = NaN}</li>
* </ul>
- * </p>
- *
+ *
* @param f
* the floating-point value to compute ulp of.
* @return the size of a ulp of the argument.
- * @since Android 1.0
*/
public static float ulp(float f) {
// special cases
diff --git a/luni/src/main/java/java/lang/String.java b/luni/src/main/java/java/lang/String.java
index b257a36..22f72cb 100644
--- a/luni/src/main/java/java/lang/String.java
+++ b/luni/src/main/java/java/lang/String.java
@@ -21,9 +21,6 @@
import java.io.UnsupportedEncodingException;
import java.util.Comparator;
import java.util.Formatter;
-// BEGIN android-added
-import java.util.IllegalFormatException;
-// END android-added
import java.util.Locale;
import java.util.regex.Pattern;
@@ -50,7 +47,7 @@
* @see StringBuffer
* @see StringBuilder
* @see Charset
- * @since Android 1.0
+ * @since 1.0
*/
public final class String implements Serializable, Comparable<String>,
CharSequence {
@@ -80,7 +77,7 @@
/**
* Create a ConsolePrintStream on the specified OutputStream, usually
* System.out.
- *
+ *
* @param out
* the console OutputStream
*/
@@ -138,8 +135,6 @@
/**
* A comparator ignoring the case of the characters.
- *
- * @since Android 1.0
*/
public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
@@ -166,8 +161,6 @@
/**
* Creates an empty string.
- *
- * @since Android 1.0
*/
public String() {
value = new char[0];
@@ -189,10 +182,9 @@
* specified by the file.encoding system property. If the system property is
* not defined, the default encoding is ISO8859_1 (ISO-Latin-1). If 8859-1
* is not available, an ASCII encoding is used.
- *
+ *
* @param data
* the byte array to convert to a string.
- * @since Android 1.0
*/
public String(byte[] data) {
this(data, 0, data.length);
@@ -201,14 +193,15 @@
/**
* Converts the byte array to a string, setting the high byte of every
* character to the specified value.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param high
* the high byte to use.
+ * @throws NullPointerException
+ * when {@code data} is {@code null}.
* @deprecated Use {@link #String(byte[])} or
* {@link #String(byte[], String)} instead.
- * @since Android 1.0
*/
@Deprecated
public String(byte[] data, int high) {
@@ -220,17 +213,18 @@
* specified by the file.encoding system property. If the system property is
* not defined, the default encoding is ISO8859_1 (ISO-Latin-1). If 8859-1
* is not available, an ASCII encoding is used.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param start
* the starting offset in the byte array.
* @param length
* the number of bytes to convert.
+ * @throws NullPointerException
+ * when {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code length < 0, start < 0} or {@code start + length >
* data.length}.
- * @since Android 1.0
*/
public String(byte[] data, int start, int length) {
// start + length could overflow, start/length maybe MaxInt
@@ -264,13 +258,13 @@
* the starting offset in the byte array.
* @param length
* the number of bytes to convert.
- *
+ * @throws NullPointerException
+ * when {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code length < 0, start < 0} or
* {@code start + length > data.length}
*
* @deprecated Use {@link #String(byte[], int, int)} instead.
- * @since Android 1.0
*/
@Deprecated
public String(byte[] data, int high, int start, int length) {
@@ -294,7 +288,7 @@
/**
* Converts the byte array to a string using the specified encoding.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param start
@@ -303,12 +297,13 @@
* the number of bytes to convert.
* @param encoding
* the encoding.
+ * @throws NullPointerException
+ * when {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code length < 0, start < 0} or {@code start + length >
* data.length}.
* @throws UnsupportedEncodingException
* if {@code encoding} is not supported.
- * @since Android 1.0
*/
public String(byte[] data, int start, int length, final String encoding)
throws UnsupportedEncodingException {
@@ -444,7 +439,7 @@
try {
cb = charset.decode(ByteBuffer.wrap(data, start, length));
} catch (Exception e) {
- // do nothing. according to spec:
+ // do nothing. according to spec:
// behavior is unspecified for invalid array
cb = CharBuffer.wrap("\u003f".toCharArray()); //$NON-NLS-1$
}
@@ -462,14 +457,15 @@
/**
* Converts the byte array to a string using the specified encoding.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param encoding
* the encoding.
+ * @throws NullPointerException
+ * when {@code data} is {@code null}.
* @throws UnsupportedEncodingException
* if {@code encoding} is not supported.
- * @since Android 1.0
*/
public String(byte[] data, String encoding) throws UnsupportedEncodingException {
this(data, 0, data.length, encoding);
@@ -479,10 +475,11 @@
* Initializes this string to contain the characters in the specified
* character array. Modifying the character array after creating the string
* has no effect on the string.
- *
+ *
* @param data
* the array of characters.
- * @since Android 1.0
+ * @throws NullPointerException
+ * when {@code data} is {@code null}.
*/
public String(char[] data) {
this(data, 0, data.length);
@@ -492,17 +489,18 @@
* Initializes this string to contain the specified characters in the
* character array. Modifying the character array after creating the string
* has no effect on the string.
- *
+ *
* @param data
* the array of characters.
* @param start
* the starting offset in the character array.
* @param length
* the number of characters to use.
+ * @throws NullPointerException
+ * when {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code length < 0, start < 0} or {@code start + length >
* data.length}
- * @since Android 1.0
*/
public String(char[] data, int start, int length) {
// range check everything so a new char[] is not created
@@ -529,10 +527,9 @@
/**
* Creates a {@code String} that is a copy of the specified string.
- *
+ *
* @param string
* the string to copy.
- * @since Android 1.0
*/
public String(String string) {
value = string.value;
@@ -543,10 +540,9 @@
/**
* Creates a {@code String} from the contents of the specified
* {@code StringBuffer}.
- *
+ *
* @param stringbuffer
* the buffer to get the contents from.
- * @since Android 1.0
*/
public String(StringBuffer stringbuffer) {
offset = 0;
@@ -558,7 +554,7 @@
/**
* Creates a {@code String} from the sub-array of Unicode code points.
- *
+ *
* @param codePoints
* the array of Unicode code points to convert.
* @param offset
@@ -566,13 +562,15 @@
* converting from.
* @param count
* the number of elements in {@code codePoints} to copy.
+ * @throws NullPointerException
+ * if {@code codePoints} is {@code null}.
* @throws IllegalArgumentException
* if any of the elements of {@code codePoints} are not valid
* Unicode code points.
* @throws IndexOutOfBoundsException
* if {@code offset} or {@code count} are not within the bounds
* of {@code codePoints}.
- * @since Android 1.0
+ * @since 1.5
*/
public String(int[] codePoints, int offset, int count) {
super();
@@ -596,10 +594,12 @@
/**
* Creates a {@code String} from the contents of the specified {@code
* StringBuilder}.
- *
+ *
* @param sb
* the {@code StringBuilder} to copy the contents from.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code sb} is {@code null}.
+ * @since 1.5
*/
public String(StringBuilder sb) {
if (sb == null) {
@@ -630,13 +630,12 @@
/**
* Returns the character at the specified offset in this string.
- *
+ *
* @param index
* the zero-based index in this string.
* @return the character at the index.
* @throws IndexOutOfBoundsException
* if {@code index < 0} or {@code index >= length()}.
- * @since Android 1.0
*/
public char charAt(int index) {
if (0 <= index && index < count) {
@@ -645,6 +644,39 @@
throw new StringIndexOutOfBoundsException();
}
+ // Optimized for ASCII
+ private char compareValue(char ch) {
+ if (ch < 128) {
+ if ('A' <= ch && ch <= 'Z') {
+ return (char) (ch + ('a' - 'A'));
+ }
+ return ch;
+ }
+ return Character.toLowerCase(Character.toUpperCase(ch));
+ }
+
+ // Optimized for ASCII
+ private char toLowerCase(char ch) {
+ if (ch < 128) {
+ if ('A' <= ch && ch <= 'Z') {
+ return (char) (ch + ('a' - 'A'));
+ }
+ return ch;
+ }
+ return Character.toLowerCase(ch);
+ }
+
+ // Optimized for ASCII
+ private char toUpperCase(char ch) {
+ if (ch < 128) {
+ if ('a' <= ch && ch <= 'z') {
+ return (char) (ch - ('a' - 'A'));
+ }
+ return ch;
+ }
+ return Character.toUpperCase(ch);
+ }
+
/**
* Compares the specified string to this string using the Unicode values of
* the characters. Returns 0 if the strings contain the same characters in
@@ -656,13 +688,14 @@
* Unicode value which is greater than the Unicode value of the character at
* the same position in the specified string, or if the specified string is
* a prefix of this string.
- *
+ *
* @param string
* the string to compare.
* @return 0 if the strings are equal, a negative integer if this string is
* before the specified string, or a positive integer if this string
* is after the specified string.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
*/
public int compareTo(String string) {
// Code adapted from K&R, pg 101
@@ -688,13 +721,14 @@
* this string has a Unicode value which is greater than the Unicode value
* of the character at the same position in the specified string, or if the
* specified string is a prefix of this string.
- *
+ *
* @param string
* the string to compare.
* @return 0 if the strings are equal, a negative integer if this string is
* before the specified string, or a positive integer if this string
* is after the specified string.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
*/
public int compareToIgnoreCase(String string) {
int o1 = offset, o2 = string.offset, result;
@@ -705,8 +739,8 @@
if ((c1 = value[o1++]) == (c2 = target[o2++])) {
continue;
}
- c1 = Character.toLowerCase(Character.toUpperCase(c1));
- c2 = Character.toLowerCase(Character.toUpperCase(c2));
+ c1 = compareValue(c1);
+ c2 = compareValue(c2);
if ((result = c1 - c2) != 0) {
return result;
}
@@ -716,12 +750,11 @@
/**
* Concatenates this string and the specified string.
- *
+ *
* @param string
* the string to concatenate
* @return a new string which is the concatenation of this string and the
* specified string.
- * @since Android 1.0
*/
public String concat(String string) {
if (string.count > 0 && count > 0) {
@@ -738,11 +771,12 @@
* Creates a new string containing the characters in the specified character
* array. Modifying the character array after creating the string has no
* effect on the string.
- *
+ *
* @param data
* the array of characters.
* @return the new string.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code data} is {@code null}.
*/
public static String copyValueOf(char[] data) {
return new String(data, 0, data.length);
@@ -752,7 +786,7 @@
* Creates a new string containing the specified characters in the character
* array. Modifying the character array after creating the string has no
* effect on the string.
- *
+ *
* @param data
* the array of characters.
* @param start
@@ -760,10 +794,11 @@
* @param length
* the number of characters to use.
* @return the new string.
+ * @throws NullPointerException
+ * if {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code length < 0, start < 0} or {@code start + length >
* data.length}.
- * @since Android 1.0
*/
public static String copyValueOf(char[] data, int start, int length) {
return new String(data, start, length);
@@ -794,12 +829,13 @@
/**
* Compares the specified string to this string to determine if the
* specified string is a suffix.
- *
+ *
* @param suffix
* the suffix to look for.
* @return {@code true} if the specified string is a suffix of this string,
* {@code false} otherwise.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code suffix} is {@code null}.
*/
public boolean endsWith(String suffix) {
return regionMatches(count - suffix.count, suffix, 0, suffix.count);
@@ -809,13 +845,12 @@
* Compares the specified object to this string and returns true if they are
* equal. The object must be an instance of string with the same characters
* in the same order.
- *
+ *
* @param object
* the object to compare.
* @return {@code true} if the specified object is equal to this string,
* {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -850,12 +885,11 @@
/**
* Compares the specified string to this string ignoring the case of the
* characters and returns true if they are equal.
- *
+ *
* @param string
* the string to compare.
* @return {@code true} if the specified string is equal to this string,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean equalsIgnoreCase(String string) {
if (string == this) {
@@ -871,9 +905,9 @@
char[] target = string.value;
while (o1 < end) {
if ((c1 = value[o1++]) != (c2 = target[o2++])
- && Character.toUpperCase(c1) != Character.toUpperCase(c2)
+ && toUpperCase(c1) != toUpperCase(c2)
// Required for unicode that we test both cases
- && Character.toLowerCase(c1) != Character.toLowerCase(c2)) {
+ && toLowerCase(c1) != toLowerCase(c2)) {
return false;
}
}
@@ -885,9 +919,8 @@
* specified by the file.encoding system property. If the system property is
* not defined, the default encoding is ISO8859_1 (ISO-Latin-1). If 8859-1
* is not available, an ASCII encoding is used.
- *
+ *
* @return the byte array encoding of this string.
- * @since Android 1.0
*/
public byte[] getBytes() {
ByteBuffer buffer = defaultCharset().encode(
@@ -900,7 +933,7 @@
/**
* Converts this string to a byte array, ignoring the high order bits of
* each character.
- *
+ *
* @param start
* the starting offset of characters to copy.
* @param end
@@ -909,11 +942,12 @@
* the destination byte array.
* @param index
* the starting offset in the destination byte array.
+ * @throws NullPointerException
+ * if {@code data} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code start < 0}, {@code end > length()}, {@code index <
* 0} or {@code end - start > data.length - index}.
* @deprecated Use {@link #getBytes()} or {@link #getBytes(String)}
- * @since Android 1.0
*/
@Deprecated
public void getBytes(int start, int end, byte[] data, int index) {
@@ -933,13 +967,12 @@
/**
* Converts this string to a byte array using the specified encoding.
- *
+ *
* @param encoding
* the encoding to use.
* @return the encoded byte array of this string.
* @throws UnsupportedEncodingException
* if the encoding is not supported.
- * @since Android 1.0
*/
public byte[] getBytes(String encoding) throws UnsupportedEncodingException {
ByteBuffer buffer = getCharset(encoding).encode(
@@ -970,7 +1003,7 @@
/**
* Copies the specified characters in this string to the character array
* starting at the specified offset in the character array.
- *
+ *
* @param start
* the starting offset of characters to copy.
* @param end
@@ -979,11 +1012,12 @@
* the destination character array.
* @param index
* the starting offset in the character array.
+ * @throws NullPointerException
+ * if {@code buffer} is {@code null}.
* @throws IndexOutOfBoundsException
* if {@code start < 0}, {@code end > length()}, {@code start >
* end}, {@code index < 0}, {@code end - start > buffer.length -
* index}
- * @since Android 1.0
*/
public void getChars(int start, int end, char[] buffer, int index) {
// NOTE last character not copied!
@@ -1031,12 +1065,11 @@
* Searches in this string for the first index of the specified character.
* The search for the character starts at the beginning and moves towards
* the end of this string.
- *
+ *
* @param c
* the character to find.
* @return the index in this string of the specified character, -1 if the
* character isn't found.
- * @since Android 1.0
*/
public int indexOf(int c) {
// BEGIN android-changed
@@ -1059,14 +1092,13 @@
* Searches in this string for the index of the specified character. The
* search for the character starts at the specified offset and moves towards
* the end of this string.
- *
+ *
* @param c
* the character to find.
* @param start
* the starting offset.
* @return the index in this string of the specified character, -1 if the
* character isn't found.
- * @since Android 1.0
*/
public int indexOf(int c, int start) {
// BEGIN android-changed
@@ -1092,12 +1124,13 @@
* Searches in this string for the first index of the specified string. The
* search for the string starts at the beginning and moves towards the end
* of this string.
- *
+ *
* @param string
* the string to find.
* @return the index of the first character of the specified string in this
* string, -1 if the specified string is not a substring.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
*/
public int indexOf(String string) {
// BEGIN android-changed
@@ -1136,14 +1169,15 @@
* Searches in this string for the index of the specified string. The search
* for the string starts at the specified offset and moves towards the end
* of this string.
- *
+ *
* @param subString
* the string to find.
* @param start
* the starting offset.
* @return the index of the first character of the specified string in this
* string, -1 if the specified string is not a substring.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code subString} is {@code null}.
*/
public int indexOf(String subString, int start) {
// BEGIN android-changed
@@ -1185,9 +1219,8 @@
* If the string is not in the table, it is added. Returns the string
* contained in the table which is equal to this string. The same string
* object is always returned for strings which are equal.
- *
+ *
* @return the interned string equal to this string.
- * @since Android 1.0
*/
native public String intern();
@@ -1196,12 +1229,11 @@
* Searches in this string for the last index of the specified character.
* The search for the character starts at the end and moves towards the
* beginning of this string.
- *
+ *
* @param c
* the character to find.
* @return the index in this string of the specified character, -1 if the
* character isn't found.
- * @since Android 1.0
*/
public int lastIndexOf(int c) {
// BEGIN android-changed
@@ -1221,14 +1253,13 @@
* Searches in this string for the index of the specified character. The
* search for the character starts at the specified offset and moves towards
* the beginning of this string.
- *
+ *
* @param c
* the character to find.
* @param start
* the starting offset.
* @return the index in this string of the specified character, -1 if the
* character isn't found.
- * @since Android 1.0
*/
public int lastIndexOf(int c, int start) {
// BEGIN android-changed
@@ -1253,12 +1284,13 @@
* Searches in this string for the last index of the specified string. The
* search for the string starts at the end and moves towards the beginning
* of this string.
- *
+ *
* @param string
* the string to find.
* @return the index of the first character of the specified string in this
* string, -1 if the specified string is not a substring.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
*/
public int lastIndexOf(String string) {
// Use count instead of count - 1 so lastIndexOf("") returns count
@@ -1269,14 +1301,15 @@
* Searches in this string for the index of the specified string. The search
* for the string starts at the specified offset and moves towards the
* beginning of this string.
- *
+ *
* @param subString
* the string to find.
* @param start
* the starting offset.
* @return the index of the first character of the specified string in this
* string , -1 if the specified string is not a substring.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code subString} is {@code null}.
*/
public int lastIndexOf(String subString, int start) {
int subCount = subString.count;
@@ -1312,9 +1345,8 @@
/**
* Returns the size of this string.
- *
+ *
* @return the number of characters in this string.
- * @since Android 1.0
*/
public int length() {
return count;
@@ -1323,7 +1355,7 @@
/**
* Compares the specified string to this string and compares the specified
* range of characters to determine if they are the same.
- *
+ *
* @param thisStart
* the starting offset in this string.
* @param string
@@ -1334,7 +1366,8 @@
* the number of characters to compare.
* @return {@code true} if the ranges of characters are equal, {@code false}
* otherwise
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
*/
public boolean regionMatches(int thisStart, String string, int start,
int length) {
@@ -1367,7 +1400,7 @@
* Compares the specified string to this string and compares the specified
* range of characters to determine if they are the same. When ignoreCase is
* true, the case of the characters is ignored during the comparison.
- *
+ *
* @param ignoreCase
* specifies if case should be ignored.
* @param thisStart
@@ -1380,7 +1413,8 @@
* the number of characters to compare.
* @return {@code true} if the ranges of characters are equal, {@code false}
* otherwise.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
*/
public boolean regionMatches(boolean ignoreCase, int thisStart,
String string, int start, int length) {
@@ -1403,11 +1437,9 @@
char[] target = string.value;
while (thisStart < end) {
if ((c1 = value[thisStart++]) != (c2 = target[start++])
- && Character.toUpperCase(c1) != Character
- .toUpperCase(c2)
+ && toUpperCase(c1) != toUpperCase(c2)
// Required for unicode that we test both cases
- && Character.toLowerCase(c1) != Character
- .toLowerCase(c2)) {
+ && toLowerCase(c1) != toLowerCase(c2)) {
return false;
}
}
@@ -1419,13 +1451,12 @@
/**
* Copies this string replacing occurrences of the specified character with
* another character.
- *
+ *
* @param oldChar
* the character to replace.
* @param newChar
* the replacement character.
* @return a new string with occurrences of oldChar replaced by newChar.
- * @since Android 1.0
*/
public String replace(char oldChar, char newChar) {
// BEGIN endroid-changed
@@ -1454,18 +1485,19 @@
return copied ? new String(0, count, buffer) : this;
// END android-changed
}
-
+
/**
* Copies this string replacing occurrences of the specified target sequence
* with another sequence. The string is processed from the beginning to the
* end.
- *
+ *
* @param target
* the sequence to replace.
* @param replacement
* the replacement sequence.
* @return the resulting string.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code target} or {@code replacement} is {@code null}.
*/
public String replace(CharSequence target, CharSequence replacement) {
if (target == null) {
@@ -1489,7 +1521,7 @@
buffer.append(rs);
tail = index + tl;
} while ((index = indexOf(ts, tail)) != -1);
- //append trailing chars
+ //append trailing chars
buffer.append(value, offset + tail, count - tail);
return buffer.toString();
@@ -1498,12 +1530,13 @@
/**
* Compares the specified string to this string to determine if the
* specified string is a prefix.
- *
+ *
* @param prefix
* the string to look for.
* @return {@code true} if the specified string is a prefix of this string,
* {@code false} otherwise
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code prefix} is {@code null}.
*/
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
@@ -1512,14 +1545,15 @@
/**
* Compares the specified string to this string, starting at the specified
* offset, to determine if the specified string is a prefix.
- *
+ *
* @param prefix
* the string to look for.
* @param start
* the starting offset.
* @return {@code true} if the specified string occurs in this string at the
* specified offset, {@code false} otherwise.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code prefix} is {@code null}.
*/
public boolean startsWith(String prefix, int start) {
return regionMatches(start, prefix, 0, prefix.count);
@@ -1527,14 +1561,13 @@
/**
* Copies a range of characters into a new string.
- *
+ *
* @param start
* the offset of the first character.
* @return a new string containing the characters from start to the end of
* the string.
* @throws IndexOutOfBoundsException
* if {@code start < 0} or {@code start > length()}.
- * @since Android 1.0
*/
public String substring(int start) {
if (start == 0) {
@@ -1548,7 +1581,7 @@
/**
* Copies a range of characters into a new string.
- *
+ *
* @param start
* the offset of the first character.
* @param end
@@ -1557,7 +1590,6 @@
* @throws IndexOutOfBoundsException
* if {@code start < 0}, {@code start > end} or {@code end >
* length()}.
- * @since Android 1.0
*/
public String substring(int start, int end) {
if (start == 0 && end == count) {
@@ -1573,9 +1605,8 @@
/**
* Copies the characters in this string to a character array.
- *
+ *
* @return a character array containing the characters of this string.
- * @since Android 1.0
*/
public char[] toCharArray() {
char[] buffer = new char[count];
@@ -1586,10 +1617,9 @@
/**
* Converts the characters in this string to lowercase, using the default
* Locale.
- *
+ *
* @return a new string containing the lowercase characters equivalent to
* the characters in this string.
- * @since Android 1.0
*/
public String toLowerCase() {
return toLowerCase(Locale.getDefault());
@@ -1598,17 +1628,16 @@
/**
* Converts the characters in this string to lowercase, using the specified
* Locale.
- *
+ *
* @param locale
* the Locale to use.
* @return a new string containing the lowercase characters equivalent to
* the characters in this string.
- * @since Android 1.0
*/
public String toLowerCase(Locale locale) {
for (int o = offset, end = offset + count; o < end; o++) {
char ch = value[o];
- if (ch != Character.toLowerCase(ch)) {
+ if (ch != toLowerCase(ch)) {
char[] buffer = new char[count];
int i = o - offset;
// Not worth checking for i == 0 case
@@ -1616,12 +1645,12 @@
// Turkish
if (!"tr".equals(locale.getLanguage())) { //$NON-NLS-1$
while (i < count) {
- buffer[i++] = Character.toLowerCase(value[o++]);
+ buffer[i++] = toLowerCase(value[o++]);
}
} else {
while (i < count) {
- buffer[i++] = (ch = value[o++]) != 0x49 ? Character
- .toLowerCase(ch) : (char) 0x131;
+ buffer[i++] = (ch = value[o++]) != 0x49 ? toLowerCase(ch)
+ : (char) 0x131;
}
}
return new String(0, count, buffer);
@@ -1634,7 +1663,6 @@
* Returns this string.
*
* @return this string.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -1644,15 +1672,17 @@
/**
* Converts the characters in this string to uppercase, using the default
* Locale.
- *
+ *
* @return a new string containing the uppercase characters equivalent to
* the characters in this string.
- * @since Android 1.0
*/
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
+ // BEGIN android-note
+ // put this in a helper class so that it's only initialized on demand?
+ // END android-note
private static final char[] upperValues = "SS\u0000\u02bcN\u0000J\u030c\u0000\u0399\u0308\u0301\u03a5\u0308\u0301\u0535\u0552\u0000H\u0331\u0000T\u0308\u0000W\u030a\u0000Y\u030a\u0000A\u02be\u0000\u03a5\u0313\u0000\u03a5\u0313\u0300\u03a5\u0313\u0301\u03a5\u0313\u0342\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f08\u0399\u0000\u1f09\u0399\u0000\u1f0a\u0399\u0000\u1f0b\u0399\u0000\u1f0c\u0399\u0000\u1f0d\u0399\u0000\u1f0e\u0399\u0000\u1f0f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f28\u0399\u0000\u1f29\u0399\u0000\u1f2a\u0399\u0000\u1f2b\u0399\u0000\u1f2c\u0399\u0000\u1f2d\u0399\u0000\u1f2e\u0399\u0000\u1f2f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1f68\u0399\u0000\u1f69\u0399\u0000\u1f6a\u0399\u0000\u1f6b\u0399\u0000\u1f6c\u0399\u0000\u1f6d\u0399\u0000\u1f6e\u0399\u0000\u1f6f\u0399\u0000\u1fba\u0399\u0000\u0391\u0399\u0000\u0386\u0399\u0000\u0391\u0342\u0000\u0391\u0342\u0399\u0391\u0399\u0000\u1fca\u0399\u0000\u0397\u0399\u0000\u0389\u0399\u0000\u0397\u0342\u0000\u0397\u0342\u0399\u0397\u0399\u0000\u0399\u0308\u0300\u0399\u0308\u0301\u0399\u0342\u0000\u0399\u0308\u0342\u03a5\u0308\u0300\u03a5\u0308\u0301\u03a1\u0313\u0000\u03a5\u0342\u0000\u03a5\u0308\u0342\u1ffa\u0399\u0000\u03a9\u0399\u0000\u038f\u0399\u0000\u03a9\u0342\u0000\u03a9\u0342\u0399\u03a9\u0399\u0000FF\u0000FI\u0000FL\u0000FFIFFLST\u0000ST\u0000\u0544\u0546\u0000\u0544\u0535\u0000\u0544\u053b\u0000\u054e\u0546\u0000\u0544\u053d\u0000".value; //$NON-NLS-1$
/**
@@ -1716,12 +1746,11 @@
/**
* Converts the characters in this string to uppercase, using the specified
* Locale.
- *
+ *
* @param locale
* the Locale to use.
* @return a new string containing the uppercase characters equivalent to
* the characters in this string.
- * @since Android 1.0
*/
public String toUpperCase(Locale locale) {
boolean turkish = "tr".equals(locale.getLanguage()); //$NON-NLS-1$
@@ -1736,8 +1765,8 @@
System.arraycopy(output, 0, newoutput, 0, output.length);
output = newoutput;
}
- char upch = !turkish ? Character.toUpperCase(ch)
- : (ch != 0x69 ? Character.toUpperCase(ch)
+ char upch = !turkish ? toUpperCase(ch)
+ : (ch != 0x69 ? toUpperCase(ch)
: (char) 0x130);
if (ch != upch) {
if (output == null) {
@@ -1782,10 +1811,9 @@
/**
* Copies this string removing white space characters from the beginning and
* end of the string.
- *
+ *
* @return a new string with characters <code><= \\u0020</code> removed from
* the beginning and the end.
- * @since Android 1.0
*/
public String trim() {
int start = offset, last = offset + count - 1;
@@ -1806,11 +1834,12 @@
* Creates a new string containing the characters in the specified character
* array. Modifying the character array after creating the string has no
* effect on the string.
- *
+ *
* @param data
* the array of characters.
* @return the new string.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code data} is {@code null}.
*/
public static String valueOf(char[] data) {
return new String(data, 0, data.length);
@@ -1820,7 +1849,7 @@
* Creates a new string containing the specified characters in the character
* array. Modifying the character array after creating the string has no
* effect on the string.
- *
+ *
* @param data
* the array of characters.
* @param start
@@ -1831,7 +1860,8 @@
* @throws IndexOutOfBoundsException
* if {@code length < 0}, {@code start < 0} or {@code start +
* length > data.length}
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code data} is {@code null}.
*/
public static String valueOf(char[] data, int start, int length) {
return new String(data, start, length);
@@ -1839,11 +1869,10 @@
/**
* Converts the specified character to its string representation.
- *
+ *
* @param value
* the character.
* @return the character converted to a string.
- * @since Android 1.0
*/
public static String valueOf(char value) {
String s;
@@ -1858,11 +1887,10 @@
/**
* Converts the specified double to its string representation.
- *
+ *
* @param value
* the double.
* @return the double converted to a string.
- * @since Android 1.0
*/
public static String valueOf(double value) {
return Double.toString(value);
@@ -1870,11 +1898,10 @@
/**
* Converts the specified float to its string representation.
- *
+ *
* @param value
* the float.
* @return the float converted to a string.
- * @since Android 1.0
*/
public static String valueOf(float value) {
return Float.toString(value);
@@ -1882,11 +1909,10 @@
/**
* Converts the specified integer to its string representation.
- *
+ *
* @param value
* the integer.
* @return the integer converted to a string.
- * @since Android 1.0
*/
public static String valueOf(int value) {
return Integer.toString(value);
@@ -1894,11 +1920,10 @@
/**
* Converts the specified long to its string representation.
- *
+ *
* @param value
* the long.
* @return the long converted to a string.
- * @since Android 1.0
*/
public static String valueOf(long value) {
return Long.toString(value);
@@ -1908,11 +1933,10 @@
* Converts the specified object to its string representation. If the object
* is null return the string {@code "null"}, otherwise use {@code
* toString()} to get the string representation.
- *
+ *
* @param value
* the object.
* @return the object converted to a string, or the string {@code "null"}.
- * @since Android 1.0
*/
public static String valueOf(Object value) {
return value != null ? value.toString() : "null"; //$NON-NLS-1$
@@ -1922,11 +1946,10 @@
* Converts the specified boolean to its string representation. When the
* boolean is {@code true} return {@code "true"}, otherwise return {@code
* "false"}.
- *
+ *
* @param value
* the boolean.
* @return the boolean converted to a string.
- * @since Android 1.0
*/
public static String valueOf(boolean value) {
return value ? "true" : "false"; //$NON-NLS-1$ //$NON-NLS-2$
@@ -1935,13 +1958,15 @@
/**
* Returns whether the characters in the StringBuffer {@code strbuf} are the
* same as those in this string.
- *
+ *
* @param strbuf
* the StringBuffer to compare this string to.
* @return {@code true} if the characters in {@code strbuf} are identical to
* those in this string. If they are not, {@code false} will be
* returned.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code strbuf} is {@code null}.
+ * @since 1.4
*/
public boolean contentEquals(StringBuffer strbuf) {
synchronized (strbuf) {
@@ -1957,11 +1982,11 @@
/**
* Compares a {@code CharSequence} to this {@code String} to determine if
* their contents are equal.
- *
+ *
* @param cs
* the character sequence to compare to.
* @return {@code true} if equal, otherwise {@code false}
- * @since Android 1.0
+ * @since 1.5
*/
public boolean contentEquals(CharSequence cs) {
if (cs == null) {
@@ -1983,14 +2008,16 @@
/**
* Determines whether this string matches a given regular expression.
- *
+ *
* @param expr
* the regular expression to be matched.
* @return {@code true} if the expression matches, otherwise {@code false}.
* @throws PatternSyntaxException
* if the syntax of the supplied regular expression is not
* valid.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code expr} is {@code null}.
+ * @since 1.4
*/
public boolean matches(String expr) {
return Pattern.matches(expr, this);
@@ -1999,7 +2026,7 @@
/**
* Replace any substrings within this string that match the supplied regular
* expression {@code expr}, with the string {@code substitute}.
- *
+ *
* @param expr
* the regular expression to match.
* @param substitute
@@ -2009,7 +2036,7 @@
* if the syntax of the supplied regular expression is not
* valid.
* @see Pattern
- * @since Android 1.0
+ * @since 1.4
*/
public String replaceAll(String expr, String substitute) {
return Pattern.compile(expr).matcher(this).replaceAll(substitute);
@@ -2018,7 +2045,7 @@
/**
* Replace the first substring within this string that matches the supplied
* regular expression {@code expr}, with the string {@code substitute}.
- *
+ *
* @param expr
* the regular expression to match.
* @param substitute
@@ -2027,8 +2054,10 @@
* @throws PatternSyntaxException
* if the syntax of the supplied regular expression is not
* valid.
+ * @throws NullPointerException
+ * if {@code strbuf} is {@code null}.
* @see Pattern
- * @since Android 1.0
+ * @since 1.4
*/
public String replaceFirst(String expr, String substitute) {
return Pattern.compile(expr).matcher(this).replaceFirst(substitute);
@@ -2036,16 +2065,18 @@
/**
* Splits this string using the supplied regular expression {@code expr}.
- *
+ *
* @param expr
* the regular expression used to divide the string.
* @return an array of Strings created by separating the string along
* matches of the regular expression.
+ * @throws NullPointerException
+ * if {@code expr} is {@code null}.
* @throws PatternSyntaxException
* if the syntax of the supplied regular expression is not
* valid.
* @see Pattern
- * @since Android 1.0
+ * @since 1.4
*/
public String[] split(String expr) {
return Pattern.compile(expr).split(this);
@@ -2055,18 +2086,20 @@
* Splits this string using the supplied regular expression {@code expr}.
* The parameter {@code max} controls the behavior how many times the
* pattern is applied to the string.
- *
+ *
* @param expr
* the regular expression used to divide the string.
* @param max
* the number of entries in the resulting array.
* @return an array of Strings created by separating the string along
* matches of the regular expression.
+ * @throws NullPointerException
+ * if {@code expr} is {@code null}.
* @throws PatternSyntaxException
* if the syntax of the supplied regular expression is not
* valid.
* @see Pattern#split(CharSequence, int)
- * @since Android 1.0
+ * @since 1.4
*/
public String[] split(String expr, int max) {
return Pattern.compile(expr).split(this, max);
@@ -2075,7 +2108,7 @@
/**
* Has the same result as the substring function, but is present so that
* string may implement the CharSequence interface.
- *
+ *
* @param start
* the offset the first character.
* @param end
@@ -2085,7 +2118,7 @@
* if {@code start < 0}, {@code end < 0}, {@code start > end} or
* {@code end > length()}.
* @see java.lang.CharSequence#subSequence(int, int)
- * @since Android 1.0
+ * @since 1.4
*/
public CharSequence subSequence(int start, int end) {
return substring(start, end);
@@ -2094,7 +2127,7 @@
/**
* Retrieves the Unicode code point (character) value at the specified
* {@code index}.
- *
+ *
* @param index
* the index to the {@code char} code unit within this string.
* @return the Unicode code point value.
@@ -2102,7 +2135,7 @@
* if {@code index} is negative or greater than or equal to
* {@code length()}.
* @see Character#codePointAt(char[], int, int)
- * @since Android 1.0
+ * @since 1.5
*/
public int codePointAt(int index) {
if (index < 0 || index >= count) {
@@ -2115,7 +2148,7 @@
/**
* Retrieves the Unicode code point value that precedes the specified
* {@code index}.
- *
+ *
* @param index
* the index to the {@code char} code unit within this string.
* @return the Unicode code point value.
@@ -2123,7 +2156,7 @@
* if {@code index} is less than 1 or greater than
* {@code length()}.
* @see Character#codePointBefore(char[], int, int)
- * @since Android 1.0
+ * @since 1.5
*/
public int codePointBefore(int index) {
if (index < 1 || index > count) {
@@ -2136,7 +2169,7 @@
/**
* Calculates the number of Unicode code points between {@code beginIndex}
* and {@code endIndex}.
- *
+ *
* @param beginIndex
* the inclusive beginning index of the subsequence.
* @param endIndex
@@ -2147,7 +2180,7 @@
* endIndex} or {@code endIndex} is greater than {@code
* length()}.
* @see Character#codePointCount(CharSequence, int, int)
- * @since Android 1.0
+ * @since 1.5
*/
public int codePointCount(int beginIndex, int endIndex) {
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
@@ -2160,12 +2193,12 @@
/**
* Determines if this {@code String} contains the sequence of characters in
* the {@code CharSequence} passed.
- *
+ *
* @param cs
* the character sequence to search for.
* @return {@code true} if the sequence of characters are contained in this
* string, otherwise {@code false}.
- * @since Android 1.0
+ * @since 1.5
*/
public boolean contains(CharSequence cs) {
if (cs == null) {
@@ -2177,7 +2210,7 @@
/**
* Returns the index within this object that is offset from {@code index} by
* {@code codePointOffset} code points.
- *
+ *
* @param index
* the index within this object to calculate the offset from.
* @param codePointOffset
@@ -2187,7 +2220,7 @@
* if {@code index} is negative or greater than {@code length()}
* or if there aren't enough code points before or after {@code
* index} to match {@code codePointOffset}.
- * @since Android 1.0
+ * @since 1.5
*/
public int offsetByCodePoints(int index, int codePointOffset) {
int s = index + offset;
@@ -2199,16 +2232,18 @@
/**
* Returns a formatted string, using the supplied format and arguments,
* using the default locale.
- *
+ *
* @param format
* a format string.
* @param args
* arguments to replace format specifiers (may be none).
* @return the formatted string.
- * @throws IllegalFormatException
+ * @throws NullPointerException
+ * if {@code format} is {@code null}.
+ * @throws java.util.IllegalFormatException
* if the format is invalid.
* @see java.util.Formatter
- * @since Android 1.0
+ * @since 1.5
*/
public static String format(String format, Object... args) {
return format(Locale.getDefault(), format, args);
@@ -2224,7 +2259,7 @@
* if you use the method only rarely, but if you rely on it for formatting a
* large number of strings, consider creating and reusing your own
* {@link java.util.Formatter} instance instead.
- *
+ *
* @param loc
* the locale to apply; {@code null} value means no localization.
* @param format
@@ -2232,10 +2267,12 @@
* @param args
* arguments to replace format specifiers (may be none).
* @return the formatted string.
- * @throws IllegalFormatException
+ * @throws NullPointerException
+ * if {@code format} is {@code null}.
+ * @throws java.util.IllegalFormatException
* if the format is invalid.
* @see java.util.Formatter
- * @since Android 1.0
+ * @since 1.5
*/
public static String format(Locale loc, String format, Object... args) {
if (format == null) {
diff --git a/luni/src/main/java/java/lang/StringBuffer.java b/luni/src/main/java/java/lang/StringBuffer.java
index 5cb5c24..3ec43dc 100644
--- a/luni/src/main/java/java/lang/StringBuffer.java
+++ b/luni/src/main/java/java/lang/StringBuffer.java
@@ -39,7 +39,7 @@
*
* @see String
* @see StringBuilder
- * @since Android 1.0
+ * @since 1.0
*/
public final class StringBuffer extends AbstractStringBuilder implements
Appendable, Serializable, CharSequence {
@@ -53,8 +53,6 @@
/**
* Constructs a new StringBuffer using the default capacity which is 16.
- *
- * @since Android 1.0
*/
public StringBuffer() {
super();
@@ -65,7 +63,6 @@
*
* @param capacity
* the initial capacity.
- * @since Android 1.0
*/
public StringBuffer(int capacity) {
super(capacity);
@@ -73,12 +70,13 @@
/**
* Constructs a new StringBuffer containing the characters in the specified
- * stringy. The capacity of the new buffer will be the length of the
+ * string. The capacity of the new buffer will be the length of the
* {@code String} plus the default capacity.
*
* @param string
* the string content with which to initialize the new instance.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code string} is {@code null}.
*/
public StringBuffer(String string) {
super(string);
@@ -91,7 +89,9 @@
*
* @param cs
* the content to initialize the instance.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code cs} is {@code null}.
+ * @since 1.5
*/
public StringBuffer(CharSequence cs) {
super(cs.toString());
@@ -103,13 +103,11 @@
* <p>
* If the argument is {@code true} the string {@code "true"} is appended,
* otherwise the string {@code "false"} is appended.
- * </p>
- *
+ *
* @param b
* the boolean to append.
* @return this StringBuffer.
* @see String#valueOf(boolean)
- * @since Android 1.0
*/
public StringBuffer append(boolean b) {
return append(b ? "true" : "false"); //$NON-NLS-1$//$NON-NLS-2$
@@ -122,7 +120,6 @@
* the character to append.
* @return this StringBuffer.
* @see String#valueOf(char)
- * @since Android 1.0
*/
public synchronized StringBuffer append(char ch) {
append0(ch);
@@ -137,7 +134,6 @@
* the double to append.
* @return this StringBuffer.
* @see String#valueOf(double)
- * @since Android 1.0
*/
public StringBuffer append(double d) {
return append(Double.toString(d));
@@ -151,7 +147,6 @@
* the float to append.
* @return this StringBuffer.
* @see String#valueOf(float)
- * @since Android 1.0
*/
public StringBuffer append(float f) {
return append(Float.toString(f));
@@ -165,7 +160,6 @@
* the integer to append.
* @return this StringBuffer.
* @see String#valueOf(int)
- * @since Android 1.0
*/
public StringBuffer append(int i) {
return append(Integer.toString(i));
@@ -179,7 +173,6 @@
* the long to append.
* @return this StringBuffer.
* @see String#valueOf(long)
- * @since Android 1.0
*/
public StringBuffer append(long l) {
return append(Long.toString(l));
@@ -192,13 +185,11 @@
* If the specified object is {@code null} the string {@code "null"} is
* appended, otherwise the objects {@code toString} is used to get its
* string representation.
- * </p>
- *
+ *
* @param obj
* the object to append (may be null).
* @return this StringBuffer.
* @see String#valueOf(Object)
- * @since Android 1.0
*/
public synchronized StringBuffer append(Object obj) {
if (obj == null) {
@@ -214,12 +205,10 @@
* <p>
* If the specified string is {@code null} the string {@code "null"} is
* appended, otherwise the contents of the specified string is appended.
- * </p>
- *
+ *
* @param string
* the string to append (may be null).
* @return this StringBuffer.
- * @since Android 1.0
*/
public synchronized StringBuffer append(String string) {
append0(string);
@@ -232,12 +221,12 @@
* If the specified StringBuffer is {@code null} the string {@code "null"}
* is appended, otherwise the contents of the specified StringBuffer is
* appended.
- * </p>
- *
+ *
* @param sb
* the StringBuffer to append (may be null).
* @return this StringBuffer.
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public synchronized StringBuffer append(StringBuffer sb) {
if (sb == null) {
@@ -256,7 +245,8 @@
* @param chars
* the character array to append.
* @return this StringBuffer.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code chars} is {@code null}.
*/
public synchronized StringBuffer append(char chars[]) {
append0(chars);
@@ -276,7 +266,8 @@
* @throws ArrayIndexOutOfBoundsException
* if {@code length < 0} , {@code start < 0} or {@code start +
* length > chars.length}.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code chars} is {@code null}.
*/
public synchronized StringBuffer append(char chars[], int start, int length) {
append0(chars, start, length);
@@ -289,12 +280,11 @@
* If the specified CharSequence is {@code null} the string {@code "null"}
* is appended, otherwise the contents of the specified CharSequence is
* appended.
- * </p>
- *
+ *
* @param s
* the CharSequence to append.
* @return this StringBuffer.
- * @since Android 1.0
+ * @since 1.5
*/
public synchronized StringBuffer append(CharSequence s) {
if (s == null) {
@@ -310,8 +300,7 @@
* <p>
* If the specified CharSequence is {@code null}, then the string {@code
* "null"} is used to extract a subsequence.
- * </p>
- *
+ *
* @param s
* the CharSequence to append.
* @param start
@@ -323,7 +312,7 @@
* if {@code start} or {@code end} are negative, {@code start}
* is greater than {@code end} or {@code end} is greater than
* the length of {@code s}.
- * @since Android 1.0
+ * @since 1.5
*/
public synchronized StringBuffer append(CharSequence s, int start, int end) {
append0(s, start, end);
@@ -336,13 +325,12 @@
* <p>
* The code point is converted to a {@code char[]} as defined by
* {@link Character#toChars(int)}.
- * </p>
- *
+ *
* @param codePoint
* the Unicode code point to encode and append.
* @return this StringBuffer.
* @see Character#toChars(int)
- * @since Android 1.0
+ * @since 1.5
*/
public StringBuffer appendCodePoint(int codePoint) {
return append(Character.toChars(codePoint));
@@ -379,7 +367,6 @@
* @throws StringIndexOutOfBoundsException
* if {@code start < 0}, {@code start > end} or {@code end >
* length()}.
- * @since Android 1.0
*/
public synchronized StringBuffer delete(int start, int end) {
delete0(start, end);
@@ -394,7 +381,6 @@
* @return this StringBuffer.
* @throws StringIndexOutOfBoundsException
* if {@code location < 0} or {@code location >= length()}
- * @since Android 1.0
*/
public synchronized StringBuffer deleteCharAt(int location) {
deleteCharAt0(location);
@@ -405,6 +391,7 @@
public synchronized void ensureCapacity(int min) {
super.ensureCapacity(min);
}
+
/**
* Copies the requested sequence of characters to the {@code char[]} passed
* starting at {@code idx}.
@@ -421,7 +408,6 @@
* if {@code start < 0}, {@code end > length()}, {@code start >
* end}, {@code index < 0}, {@code end - start > buffer.length -
* index}
- * @since Android 1.0
*/
@Override
public synchronized void getChars(int start, int end, char[] buffer, int idx) {
@@ -443,7 +429,6 @@
* @return this buffer.
* @throws ArrayIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public synchronized StringBuffer insert(int index, char ch) {
insert0(index, ch);
@@ -461,7 +446,6 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public StringBuffer insert(int index, boolean b) {
return insert(index, b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -478,7 +462,6 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public StringBuffer insert(int index, int i) {
return insert(index, Integer.toString(i));
@@ -495,7 +478,6 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public StringBuffer insert(int index, long l) {
return insert(index, Long.toString(l));
@@ -512,7 +494,6 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public StringBuffer insert(int index, double d) {
return insert(index, Double.toString(d));
@@ -529,7 +510,6 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public StringBuffer insert(int index, float f) {
return insert(index, Float.toString(f));
@@ -542,8 +522,7 @@
* If the specified object is {@code null}, the string {@code "null"} is
* inserted, otherwise the objects {@code toString} method is used to get
* its string representation.
- * </p>
- *
+ *
* @param index
* the index at which to insert.
* @param obj
@@ -551,7 +530,6 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public StringBuffer insert(int index, Object obj) {
return insert(index, obj == null ? "null" : obj.toString()); //$NON-NLS-1$
@@ -562,8 +540,7 @@
* <p>
* If the specified string is {@code null}, the string {@code "null"} is
* inserted, otherwise the contents of the string is inserted.
- * </p>
- *
+ *
* @param index
* the index at which to insert.
* @param string
@@ -571,7 +548,6 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
*/
public synchronized StringBuffer insert(int index, String string) {
insert0(index, string);
@@ -588,7 +564,8 @@
* @return this buffer.
* @throws StringIndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code chars} is {@code null}.
*/
public synchronized StringBuffer insert(int index, char[] chars) {
insert0(index, chars);
@@ -608,11 +585,12 @@
* @param length
* the number of characters.
* @return this buffer.
+ * @throws NullPointerException
+ * if {@code chars} is {@code null}.
* @throws StringIndexOutOfBoundsException
* if {@code length < 0}, {@code start < 0}, {@code start +
* length > chars.length}, {@code index < 0} or {@code index >
* length()}
- * @since Android 1.0
*/
public synchronized StringBuffer insert(int index, char chars[], int start,
int length) {
@@ -626,8 +604,7 @@
* <p>
* If the specified CharSequence is {@code null}, the string {@code "null"}
* is inserted, otherwise the contents of the CharSequence.
- * </p>
- *
+ *
* @param index
* The index at which to insert.
* @param s
@@ -635,7 +612,7 @@
* @return this buffer.
* @throws IndexOutOfBoundsException
* if {@code index < 0} or {@code index > length()}.
- * @since Android 1.0
+ * @since 1.5
*/
public synchronized StringBuffer insert(int index, CharSequence s) {
insert0(index, s == null ? "null" : s.toString()); //$NON-NLS-1$
@@ -648,7 +625,6 @@
* <p>
* If the specified CharSequence is {@code null}, the string {@code "null"}
* is inserted, otherwise the contents of the CharSequence.
- * </p>
*
* @param index
* The index at which to insert.
@@ -664,7 +640,7 @@
* length, {@code start} or {@code end} are negative, {@code
* start} is greater than {@code end} or {@code end} is greater
* than the length of {@code s}.
- * @since Android 1.0
+ * @since 1.5
*/
public synchronized StringBuffer insert(int index, CharSequence s,
int start, int end) {
@@ -697,7 +673,6 @@
* if {@code start} or {@code end} are negative, {@code start}
* is greater than {@code end} or {@code end} is greater than
* the length of {@code s}.
- * @since Android 1.0
*/
public synchronized StringBuffer replace(int start, int end, String string) {
replace0(start, end, string);
@@ -708,7 +683,6 @@
* Reverses the order of characters in this buffer.
*
* @return this buffer.
- * @since Android 1.0
*/
public synchronized StringBuffer reverse() {
reverse0();
diff --git a/luni/src/main/java/java/lang/StringBuilder.java b/luni/src/main/java/java/lang/StringBuilder.java
index d62f900..12d401f 100644
--- a/luni/src/main/java/java/lang/StringBuilder.java
+++ b/luni/src/main/java/java/lang/StringBuilder.java
@@ -32,13 +32,13 @@
* StringBuilder}, so that, like {@code StringBuffer}s, they can be used in
* chaining method calls together. For example, {@code new StringBuilder("One
* should ").append("always strive ").append("to achieve Harmony")}.
- * </p>
*
* @see CharSequence
* @see Appendable
* @see StringBuffer
* @see String
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public final class StringBuilder extends AbstractStringBuilder implements
Appendable, CharSequence, Serializable {
@@ -49,7 +49,6 @@
* Constructs an instance with an initial capacity of {@code 16}.
*
* @see #capacity()
- * @since Android 1.0
*/
public StringBuilder() {
super();
@@ -57,13 +56,12 @@
/**
* Constructs an instance with the specified capacity.
- *
+ *
* @param capacity
* the initial capacity to use.
* @throws NegativeArraySizeException
* if the specified {@code capacity} is negative.
* @see #capacity()
- * @since Android 1.0
*/
public StringBuilder(int capacity) {
super(capacity);
@@ -73,10 +71,11 @@
* Constructs an instance that's initialized with the contents of the
* specified {@code CharSequence}. The capacity of the new builder will be
* the length of the {@code CharSequence} plus 16.
- *
+ *
* @param seq
* the {@code CharSequence} to copy into the builder.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code seq} is {@code null}.
*/
public StringBuilder(CharSequence seq) {
super(seq.toString());
@@ -86,10 +85,11 @@
* Constructs an instance that's initialized with the contents of the
* specified {@code String}. The capacity of the new builder will be the
* length of the {@code String} plus 16.
- *
+ *
* @param str
* the {@code String} to copy into the builder.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code str} is {@code null}.
*/
public StringBuilder(String str) {
super(str);
@@ -99,12 +99,11 @@
* Appends the string representation of the specified {@code boolean} value.
* The {@code boolean} value is converted to a String according to the rule
* defined by {@link String#valueOf(boolean)}.
- *
+ *
* @param b
* the {@code boolean} value to append.
* @return this builder.
* @see String#valueOf(boolean)
- * @since Android 1.0
*/
public StringBuilder append(boolean b) {
append0(b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -115,12 +114,11 @@
* Appends the string representation of the specified {@code char} value.
* The {@code char} value is converted to a string according to the rule
* defined by {@link String#valueOf(char)}.
- *
+ *
* @param c
* the {@code char} value to append.
* @return this builder.
* @see String#valueOf(char)
- * @since Android 1.0
*/
public StringBuilder append(char c) {
append0(c);
@@ -131,12 +129,11 @@
* Appends the string representation of the specified {@code int} value. The
* {@code int} value is converted to a string according to the rule defined
* by {@link String#valueOf(int)}.
- *
+ *
* @param i
* the {@code int} value to append.
* @return this builder.
* @see String#valueOf(int)
- * @since Android 1.0
*/
public StringBuilder append(int i) {
append0(Integer.toString(i));
@@ -147,12 +144,11 @@
* Appends the string representation of the specified {@code long} value.
* The {@code long} value is converted to a string according to the rule
* defined by {@link String#valueOf(long)}.
- *
+ *
* @param lng
* the {@code long} value.
* @return this builder.
* @see String#valueOf(long)
- * @since Android 1.0
*/
public StringBuilder append(long lng) {
append0(Long.toString(lng));
@@ -163,12 +159,11 @@
* Appends the string representation of the specified {@code float} value.
* The {@code float} value is converted to a string according to the rule
* defined by {@link String#valueOf(float)}.
- *
+ *
* @param f
* the {@code float} value to append.
* @return this builder.
* @see String#valueOf(float)
- * @since Android 1.0
*/
public StringBuilder append(float f) {
append0(Float.toString(f));
@@ -179,12 +174,11 @@
* Appends the string representation of the specified {@code double} value.
* The {@code double} value is converted to a string according to the rule
* defined by {@link String#valueOf(double)}.
- *
+ *
* @param d
* the {@code double} value to append.
* @return this builder.
* @see String#valueOf(double)
- * @since Android 1.0
*/
public StringBuilder append(double d) {
append0(Double.toString(d));
@@ -195,12 +189,11 @@
* Appends the string representation of the specified {@code Object}.
* The {@code Object} value is converted to a string according to the rule
* defined by {@link String#valueOf(Object)}.
- *
+ *
* @param obj
* the {@code Object} to append.
* @return this builder.
* @see String#valueOf(Object)
- * @since Android 1.0
*/
public StringBuilder append(Object obj) {
if (obj == null) {
@@ -214,11 +207,10 @@
/**
* Appends the contents of the specified string. If the string is {@code
* null}, then the string {@code "null"} is appended.
- *
+ *
* @param str
* the string to append.
* @return this builder.
- * @since Android 1.0
*/
public StringBuilder append(String str) {
append0(str);
@@ -229,11 +221,10 @@
* Appends the contents of the specified {@code StringBuffer}. If the
* StringBuffer is {@code null}, then the string {@code "null"} is
* appended.
- *
+ *
* @param sb
* the {@code StringBuffer} to append.
* @return this builder.
- * @since Android 1.0
*/
public StringBuilder append(StringBuffer sb) {
if (sb == null) {
@@ -248,12 +239,11 @@
* Appends the string representation of the specified {@code char[]}.
* The {@code char[]} is converted to a string according to the rule
* defined by {@link String#valueOf(char[])}.
- *
+ *
* @param ch
* the {@code char[]} to append..
* @return this builder.
* @see String#valueOf(char[])
- * @since Android 1.0
*/
public StringBuilder append(char[] ch) {
append0(ch);
@@ -264,7 +254,7 @@
* Appends the string representation of the specified subset of the {@code
* char[]}. The {@code char[]} value is converted to a String according to
* the rule defined by {@link String#valueOf(char[],int,int)}.
- *
+ *
* @param str
* the {@code char[]} to append.
* @param offset
@@ -276,7 +266,6 @@
* if {@code offset} and {@code len} do not specify a valid
* subsequence.
* @see String#valueOf(char[],int,int)
- * @since Android 1.0
*/
public StringBuilder append(char[] str, int offset, int len) {
append0(str, offset, len);
@@ -287,11 +276,10 @@
* Appends the string representation of the specified {@code CharSequence}.
* If the {@code CharSequence} is {@code null}, then the string {@code
* "null"} is appended.
- *
+ *
* @param csq
* the {@code CharSequence} to append.
* @return this builder.
- * @since Android 1.0
*/
public StringBuilder append(CharSequence csq) {
if (csq == null) {
@@ -306,7 +294,7 @@
* Appends the string representation of the specified subsequence of the
* {@code CharSequence}. If the {@code CharSequence} is {@code null}, then
* the string {@code "null"} is used to extract the subsequence from.
- *
+ *
* @param csq
* the {@code CharSequence} to append.
* @param start
@@ -318,7 +306,6 @@
* if {@code start} or {@code end} are negative, {@code start}
* is greater than {@code end} or {@code end} is greater than
* the length of {@code csq}.
- * @since Android 1.0
*/
public StringBuilder append(CharSequence csq, int start, int end) {
append0(csq, start, end);
@@ -328,12 +315,11 @@
/**
* Appends the encoded Unicode code point. The code point is converted to a
* {@code char[]} as defined by {@link Character#toChars(int)}.
- *
+ *
* @param codePoint
* the Unicode code point to encode and append.
* @return this builder.
* @see Character#toChars(int)
- * @since Android 1.0
*/
public StringBuilder appendCodePoint(int codePoint) {
append0(Character.toChars(codePoint));
@@ -352,7 +338,6 @@
* @throws StringIndexOutOfBoundsException
* if {@code start} is less than zero, greater than the current
* length or greater than {@code end}.
- * @since Android 1.0
*/
public StringBuilder delete(int start, int end) {
delete0(start, end);
@@ -369,7 +354,6 @@
* @throws StringIndexOutOfBoundsException
* if {@code index} is less than zero or is greater than or
* equal to the current length.
- * @since Android 1.0
*/
public StringBuilder deleteCharAt(int index) {
deleteCharAt0(index);
@@ -381,7 +365,7 @@
* at the specified {@code offset}. The {@code boolean} value is converted
* to a string according to the rule defined by
* {@link String#valueOf(boolean)}.
- *
+ *
* @param offset
* the index to insert at.
* @param b
@@ -391,7 +375,6 @@
* if {@code offset} is negative or greater than the current
* {@code length}.
* @see String#valueOf(boolean)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, boolean b) {
insert0(offset, b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
@@ -402,7 +385,7 @@
* Inserts the string representation of the specified {@code char} value at
* the specified {@code offset}. The {@code char} value is converted to a
* string according to the rule defined by {@link String#valueOf(char)}.
- *
+ *
* @param offset
* the index to insert at.
* @param c
@@ -412,7 +395,6 @@
* if {@code offset} is negative or greater than the current
* {@code length()}.
* @see String#valueOf(char)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, char c) {
insert0(offset, c);
@@ -423,7 +405,7 @@
* Inserts the string representation of the specified {@code int} value at
* the specified {@code offset}. The {@code int} value is converted to a
* String according to the rule defined by {@link String#valueOf(int)}.
- *
+ *
* @param offset
* the index to insert at.
* @param i
@@ -433,7 +415,6 @@
* if {@code offset} is negative or greater than the current
* {@code length()}.
* @see String#valueOf(int)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, int i) {
insert0(offset, Integer.toString(i));
@@ -444,7 +425,7 @@
* Inserts the string representation of the specified {@code long} value at
* the specified {@code offset}. The {@code long} value is converted to a
* String according to the rule defined by {@link String#valueOf(long)}.
- *
+ *
* @param offset
* the index to insert at.
* @param l
@@ -454,7 +435,6 @@
* if {@code offset} is negative or greater than the current
* {code length()}.
* @see String#valueOf(long)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, long l) {
insert0(offset, Long.toString(l));
@@ -465,7 +445,7 @@
* Inserts the string representation of the specified {@code float} value at
* the specified {@code offset}. The {@code float} value is converted to a
* string according to the rule defined by {@link String#valueOf(float)}.
- *
+ *
* @param offset
* the index to insert at.
* @param f
@@ -475,7 +455,6 @@
* if {@code offset} is negative or greater than the current
* {@code length()}.
* @see String#valueOf(float)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, float f) {
insert0(offset, Float.toString(f));
@@ -487,7 +466,7 @@
* at the specified {@code offset}. The {@code double} value is converted
* to a String according to the rule defined by
* {@link String#valueOf(double)}.
- *
+ *
* @param offset
* the index to insert at.
* @param d
@@ -497,7 +476,6 @@
* if {@code offset} is negative or greater than the current
* {@code length()}.
* @see String#valueOf(double)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, double d) {
insert0(offset, Double.toString(d));
@@ -508,7 +486,7 @@
* Inserts the string representation of the specified {@code Object} at the
* specified {@code offset}. The {@code Object} value is converted to a
* String according to the rule defined by {@link String#valueOf(Object)}.
- *
+ *
* @param offset
* the index to insert at.
* @param obj
@@ -518,7 +496,6 @@
* if {@code offset} is negative or greater than the current
* {@code length()}.
* @see String#valueOf(Object)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, Object obj) {
insert0(offset, obj == null ? "null" : obj.toString()); //$NON-NLS-1$
@@ -528,7 +505,7 @@
/**
* Inserts the specified string at the specified {@code offset}. If the
* specified string is null, then the String {@code "null"} is inserted.
- *
+ *
* @param offset
* the index to insert at.
* @param str
@@ -537,7 +514,6 @@
* @throws StringIndexOutOfBoundsException
* if {@code offset} is negative or greater than the current
* {@code length()}.
- * @since Android 1.0
*/
public StringBuilder insert(int offset, String str) {
insert0(offset, str);
@@ -548,7 +524,7 @@
* Inserts the string representation of the specified {@code char[]} at the
* specified {@code offset}. The {@code char[]} value is converted to a
* String according to the rule defined by {@link String#valueOf(char[])}.
- *
+ *
* @param offset
* the index to insert at.
* @param ch
@@ -558,7 +534,6 @@
* if {@code offset} is negative or greater than the current
* {@code length()}.
* @see String#valueOf(char[])
- * @since Android 1.0
*/
public StringBuilder insert(int offset, char[] ch) {
insert0(offset, ch);
@@ -570,7 +545,7 @@
* {@code char[]} at the specified {@code offset}. The {@code char[]} value
* is converted to a String according to the rule defined by
* {@link String#valueOf(char[],int,int)}.
- *
+ *
* @param offset
* the index to insert at.
* @param str
@@ -585,7 +560,6 @@
* {@code length()}, or {@code strOffset} and {@code strLen} do
* not specify a valid subsequence.
* @see String#valueOf(char[],int,int)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, char[] str, int strOffset,
int strLen) {
@@ -598,7 +572,7 @@
* at the specified {@code offset}. The {@code CharSequence} is converted
* to a String as defined by {@link CharSequence#toString()}. If {@code s}
* is {@code null}, then the String {@code "null"} is inserted.
- *
+ *
* @param offset
* the index to insert at.
* @param s
@@ -608,7 +582,6 @@
* if {@code offset} is negative or greater than the current
* {@code length()}.
* @see CharSequence#toString()
- * @since Android 1.0
*/
public StringBuilder insert(int offset, CharSequence s) {
insert0(offset, s == null ? "null" : s.toString()); //$NON-NLS-1$
@@ -622,7 +595,7 @@
* {@link CharSequence#subSequence(int, int)}. If the {@code CharSequence}
* is {@code null}, then the string {@code "null"} is used to determine the
* subsequence.
- *
+ *
* @param offset
* the index to insert at.
* @param s
@@ -637,7 +610,6 @@
* {@code length()}, or {@code start} and {@code end} do not
* specify a valid subsequence.
* @see CharSequence#subSequence(int, int)
- * @since Android 1.0
*/
public StringBuilder insert(int offset, CharSequence s, int start, int end) {
insert0(offset, s, start, end);
@@ -658,7 +630,8 @@
* @throws StringIndexOutOfBoundsException
* if {@code start} is negative, greater than the current
* {@code length()} or greater than {@code end}.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code str} is {@code null}.
*/
public StringBuilder replace(int start, int end, String str) {
replace0(start, end, str);
@@ -669,7 +642,6 @@
* Reverses the order of characters in this builder.
*
* @return this buffer.
- * @since Android 1.0
*/
public StringBuilder reverse() {
reverse0();
@@ -680,7 +652,6 @@
* Returns the contents of this builder.
*
* @return the string representation of the data in this builder.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -695,7 +666,7 @@
/**
* Reads the state of a {@code StringBuilder} from the passed stream and
* restores it to this instance.
- *
+ *
* @param in
* the stream to read the state from.
* @throws IOException
@@ -713,7 +684,7 @@
/**
* Writes the state of this object to the stream passed.
- *
+ *
* @param out
* the stream to write the state to.
* @throws IOException
diff --git a/luni/src/main/java/java/lang/StringIndexOutOfBoundsException.java b/luni/src/main/java/java/lang/StringIndexOutOfBoundsException.java
index a2fca9a..b3fbf7e 100644
--- a/luni/src/main/java/java/lang/StringIndexOutOfBoundsException.java
+++ b/luni/src/main/java/java/lang/StringIndexOutOfBoundsException.java
@@ -23,8 +23,6 @@
/**
* Thrown when the a string is indexed with a value less than zero, or greater
* than or equal to the size of the array.
- *
- * @since Android 1.0
*/
public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException {
@@ -33,8 +31,6 @@
/**
* Constructs a new {@code StringIndexOutOfBoundsException} that includes
* the current stack trace.
- *
- * @since Android 1.0
*/
public StringIndexOutOfBoundsException() {
super();
@@ -47,7 +43,6 @@
*
* @param index
* the index which is out of bounds.
- * @since Android 1.0
*/
public StringIndexOutOfBoundsException(int index) {
super(Msg.getString("K0055", index)); //$NON-NLS-1$
@@ -59,7 +54,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public StringIndexOutOfBoundsException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/SuppressWarnings.java b/luni/src/main/java/java/lang/SuppressWarnings.java
index d3b4289..1ff0e42 100644
--- a/luni/src/main/java/java/lang/SuppressWarnings.java
+++ b/luni/src/main/java/java/lang/SuppressWarnings.java
@@ -1,12 +1,12 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,15 +16,9 @@
package java.lang;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
@@ -35,18 +29,17 @@
* <p>
* It is recommended that programmers always use this annotation on the most
* deeply nested element where it is actually needed.
- * </p>
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
-@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
-@Retention(value=SOURCE)
-public @interface SuppressWarnings
-{
+@Target( { ElementType.TYPE, ElementType.FIELD, ElementType.METHOD,
+ ElementType.PARAMETER, ElementType.CONSTRUCTOR,
+ ElementType.LOCAL_VARIABLE })
+@Retention(RetentionPolicy.SOURCE)
+public @interface SuppressWarnings {
+
/**
* The list of warnings a compiler should not issue.
- *
- * @since Android 1.0
*/
- String[] value();
+ public String[] value();
}
diff --git a/luni/src/main/java/java/lang/ThreadDeath.java b/luni/src/main/java/java/lang/ThreadDeath.java
index e4f2cc2..3006865 100644
--- a/luni/src/main/java/java/lang/ThreadDeath.java
+++ b/luni/src/main/java/java/lang/ThreadDeath.java
@@ -20,8 +20,6 @@
/**
* ThreadDeath is thrown when a thread stops executing. It is used to aid in the
* orderly unrolling of the thread's stack (eg. cleanup of monitors).
- *
- * @since Android 1.0
*/
public class ThreadDeath extends Error {
@@ -31,8 +29,6 @@
* Constructs a new instance of this class. Note that in the case of
* ThreadDeath, the stacktrace may <em>not</em> be filled in a way which
* allows a stack trace to be printed.
- *
- * @since Android 1.0
*/
public ThreadDeath() {
}
diff --git a/luni/src/main/java/java/lang/ThreadLocal.java b/luni/src/main/java/java/lang/ThreadLocal.java
index 58e85be..90250b3 100644
--- a/luni/src/main/java/java/lang/ThreadLocal.java
+++ b/luni/src/main/java/java/lang/ThreadLocal.java
@@ -16,6 +16,12 @@
package java.lang;
+/*
+ * Android's thread local is not derived from Harmony's classlib. It is used in
+ * Harmony's DRLVM, however, whose source is here:
+ * http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/
+ */
+
import java.lang.ref.WeakReference;
import java.lang.ref.Reference;
import java.util.concurrent.atomic.AtomicInteger;
@@ -29,7 +35,6 @@
*
* @see java.lang.Thread
* @author Bob Lee
- * @since Android 1.0
*/
public class ThreadLocal<T> {
@@ -97,6 +102,8 @@
* is followed by a {@link #get()} before a {@link #set},
* {@code #get()} will call {@link #initialValue()} and create a new
* entry with the resulting value.
+ *
+ * @since 1.5
*/
public void remove() {
Thread currentThread = Thread.currentThread();
diff --git a/luni/src/main/java/java/lang/TypeNotPresentException.java b/luni/src/main/java/java/lang/TypeNotPresentException.java
index 11ef4c1..d96f766 100644
--- a/luni/src/main/java/java/lang/TypeNotPresentException.java
+++ b/luni/src/main/java/java/lang/TypeNotPresentException.java
@@ -21,8 +21,8 @@
* type through a string that contains the type's name and the type cannot be
* found. This exception is an unchecked alternative to
* {@link java.lang.ClassNotFoundException}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public class TypeNotPresentException extends RuntimeException {
private static final long serialVersionUID = -5101214195716534496L;
@@ -38,7 +38,6 @@
* the fully qualified name of the type that could not be found.
* @param cause
* the optional cause of this exception, may be {@code null}.
- * @since Android 1.0
*/
public TypeNotPresentException(String typeName, Throwable cause) {
super("Type " + typeName + " not present", cause);
diff --git a/luni/src/main/java/java/lang/UnknownError.java b/luni/src/main/java/java/lang/UnknownError.java
index a98a5d4..ecdb008 100644
--- a/luni/src/main/java/java/lang/UnknownError.java
+++ b/luni/src/main/java/java/lang/UnknownError.java
@@ -20,8 +20,6 @@
/**
* Thrown when the virtual machine must throw an error which does not match any
* known exceptional condition.
- *
- * @since Android 1.0
*/
public class UnknownError extends VirtualMachineError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code UnknownError} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public UnknownError() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UnknownError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/UnsatisfiedLinkError.java b/luni/src/main/java/java/lang/UnsatisfiedLinkError.java
index 489601f..12429a0 100644
--- a/luni/src/main/java/java/lang/UnsatisfiedLinkError.java
+++ b/luni/src/main/java/java/lang/UnsatisfiedLinkError.java
@@ -20,8 +20,6 @@
/**
* Thrown when an attempt is made to invoke a native for which an implementation
* could not be found.
- *
- * @since Android 1.0
*/
public class UnsatisfiedLinkError extends LinkageError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code UnsatisfiedLinkError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public UnsatisfiedLinkError() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UnsatisfiedLinkError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/UnsupportedClassVersionError.java b/luni/src/main/java/java/lang/UnsupportedClassVersionError.java
index 3ee8f8c..7670f70 100644
--- a/luni/src/main/java/java/lang/UnsupportedClassVersionError.java
+++ b/luni/src/main/java/java/lang/UnsupportedClassVersionError.java
@@ -20,8 +20,6 @@
/**
* Thrown when an attempt is made to load a class with a format version that is
* not supported by the virtual machine.
- *
- * @since Android 1.0
*/
public class UnsupportedClassVersionError extends ClassFormatError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code UnsupportedClassVersionError} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public UnsupportedClassVersionError() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UnsupportedClassVersionError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/UnsupportedOperationException.java b/luni/src/main/java/java/lang/UnsupportedOperationException.java
index 8b78226..ac27518 100644
--- a/luni/src/main/java/java/lang/UnsupportedOperationException.java
+++ b/luni/src/main/java/java/lang/UnsupportedOperationException.java
@@ -19,8 +19,6 @@
/**
* Thrown when an unsupported operation is attempted.
- *
- * @since Android 1.0
*/
public class UnsupportedOperationException extends RuntimeException {
@@ -29,13 +27,8 @@
/**
* Constructs a new {@code UnsupportedOperationException} that includes the
* current stack trace.
- *
- * @since Android 1.0
*/
public UnsupportedOperationException() {
- // BEGIN android-added
- super();
- // END android-added
}
/**
@@ -44,7 +37,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UnsupportedOperationException(String detailMessage) {
super(detailMessage);
@@ -58,7 +50,7 @@
* the detail message for this exception.
* @param cause
* the optional cause of this exception, may be {@code null}.
- * @since Android 1.0
+ * @since 1.5
*/
public UnsupportedOperationException(String message, Throwable cause) {
super(message, cause);
@@ -70,7 +62,7 @@
*
* @param cause
* the optional cause of this exception, may be {@code null}.
- * @since Android 1.0
+ * @since 1.5
*/
public UnsupportedOperationException(Throwable cause) {
super((cause == null ? null : cause.toString()), cause);
diff --git a/luni/src/main/java/java/lang/VerifyError.java b/luni/src/main/java/java/lang/VerifyError.java
index ddf4de7..35cf34b 100644
--- a/luni/src/main/java/java/lang/VerifyError.java
+++ b/luni/src/main/java/java/lang/VerifyError.java
@@ -20,8 +20,6 @@
/**
* Thrown when the virtual machine notices that an attempt is made to load a
* class which does not pass the class verification phase.
- *
- * @since Android 1.0
*/
public class VerifyError extends LinkageError {
@@ -30,8 +28,6 @@
/**
* Constructs a new {@code VerifyError} that includes the current stack
* trace.
- *
- * @since Android 1.0
*/
public VerifyError() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public VerifyError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/VirtualMachineError.java b/luni/src/main/java/java/lang/VirtualMachineError.java
index 107f562..87a6342 100644
--- a/luni/src/main/java/java/lang/VirtualMachineError.java
+++ b/luni/src/main/java/java/lang/VirtualMachineError.java
@@ -23,7 +23,6 @@
* during the operation of the virtual machine.
*
* @see Error
- * @since Android 1.0
*/
public abstract class VirtualMachineError extends Error {
@@ -32,8 +31,6 @@
/**
* Constructs a new {@code VirtualMachineError} that includes the current
* stack trace.
- *
- * @since Android 1.0
*/
public VirtualMachineError() {
super();
@@ -45,7 +42,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public VirtualMachineError(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/lang/Void.java b/luni/src/main/java/java/lang/Void.java
index 8d06b64..4132e41 100644
--- a/luni/src/main/java/java/lang/Void.java
+++ b/luni/src/main/java/java/lang/Void.java
@@ -21,15 +21,13 @@
/**
* Placeholder class for the Java keyword {@code void}.
- *
- * @since Android 1.0
+ *
+ * @since 1.1
*/
public final class Void extends Object {
/**
* The {@link Class} object that represents the primitive type {@code void}.
- *
- * @since Android 1.0
*/
public static final Class<Void> TYPE = lookupType();
@@ -48,6 +46,6 @@
return (Class<Void>) voidType;
}
- private Void() {
- }
+ private Void() {
+ }
}
diff --git a/luni/src/main/java/java/lang/ref/ReferenceQueue.java b/luni/src/main/java/java/lang/ref/ReferenceQueue.java
index eb6280b..ac6d695 100644
--- a/luni/src/main/java/java/lang/ref/ReferenceQueue.java
+++ b/luni/src/main/java/java/lang/ref/ReferenceQueue.java
@@ -16,25 +16,24 @@
*/
// BEGIN android-note
-// This implementation was changed significantly. Changes where not marked.
+// This implementation is quite different from Harmony. Changes are not marked.
// END android-note
+
package java.lang.ref;
/**
* The {@code ReferenceQueue} is the container on which reference objects are
* enqueued when the garbage collector detects the reachability type specified
* for the referent.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public class ReferenceQueue<T> {
-
+
private Reference<? extends T> head;
/**
* Constructs a new instance of this class.
- *
- * @since Android 1.0
*/
public ReferenceQueue() {
super();
@@ -43,11 +42,9 @@
/**
* Returns the next available reference from the queue, removing it in the
* process. Does not wait for a reference to become available.
- *
+ *
* @return the next available reference, or {@code null} if no reference is
* immediately available
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public synchronized Reference<? extends T> poll() {
@@ -73,37 +70,31 @@
/**
* Returns the next available reference from the queue, removing it in the
* process. Waits indefinitely for a reference to become available.
- *
+ *
* @return the next available reference
- *
+ *
* @throws InterruptedException
- * if the blocking call was interrupted for some reason
- *
- * @since Android 1.0
+ * if the blocking call was interrupted for some reason
*/
public Reference<? extends T> remove() throws InterruptedException {
return remove(0L);
}
-
+
/**
* Returns the next available reference from the queue, removing it in the
* process. Waits for a reference to become available or the given timeout
* period to elapse, whichever happens first.
- *
+ *
* @param timeout
* maximum time (in ms) to spend waiting for a reference object
* to become available. A value of zero results in the method
* waiting indefinitely.
- *
* @return the next available reference, or {@code null} if no reference
* becomes available within the timeout period
- *
* @throws IllegalArgumentException
* if the wait period is negative.
* @throws InterruptedException
- * if the blocking call was interrupted for some reason
- *
- * @since Android 1.0
+ * if the blocking call was interrupted for some reason
*/
public synchronized Reference<? extends T> remove(long timeout) throws IllegalArgumentException,
InterruptedException {
@@ -128,20 +119,20 @@
}
/**
- * Enqueues the reference object on the receiver.
- *
- * @param toQueue
+ * Enqueue the reference object on the receiver.
+ *
+ * @param reference
* reference object to be enqueued.
- *
- * @since Android 1.0
+ * @return boolean true if reference is enqueued. false if reference failed
+ * to enqueue.
*/
- synchronized void enqueue(Reference<? extends T> toQueue) {
+ synchronized void enqueue(Reference<? extends T> reference) {
if (head == null) {
- toQueue.queueNext = toQueue;
+ reference.queueNext = reference;
} else {
- toQueue.queueNext = head;
+ reference.queueNext = head;
}
- head = toQueue;
+ head = reference;
notify();
}
}
diff --git a/luni/src/main/java/java/lang/reflect/AnnotatedElement.java b/luni/src/main/java/java/lang/reflect/AnnotatedElement.java
index 1f081b9..426daba 100644
--- a/luni/src/main/java/java/lang/reflect/AnnotatedElement.java
+++ b/luni/src/main/java/java/lang/reflect/AnnotatedElement.java
@@ -21,8 +21,8 @@
/**
* This interface provides reflective access to annotation information.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public interface AnnotatedElement {
@@ -33,13 +33,9 @@
*
* @param annotationType
* the type of the annotation to search for
- *
* @return the annotation with the specified type or {@code null}
- *
* @throws NullPointerException
* if {@code annotationType} is {@code null}
- *
- * @since Android 1.0
*/
<T extends Annotation> T getAnnotation(Class<T> annotationType);
@@ -49,8 +45,6 @@
* returns a zero length array.
*
* @return an array of all annotations for this element
- *
- * @since Android 1.0
*/
Annotation[] getAnnotations();
@@ -60,8 +54,6 @@
* method returns a zero length array.
*
* @return an array of annotations declared for this element
- *
- * @since Android 1.0
*/
Annotation[] getDeclaredAnnotations();
@@ -71,13 +63,9 @@
*
* @param annotationType
* the type of the annotation to search for
- *
* @return {@code true} if the annotation exists, {@code false} otherwise
- *
* @throws NullPointerException
* if {@code annotationType} is {@code null}
- *
- * @since Android 1.0
*/
boolean isAnnotationPresent(Class<? extends Annotation> annotationType);
}
diff --git a/luni/src/main/java/java/lang/reflect/GenericArrayType.java b/luni/src/main/java/java/lang/reflect/GenericArrayType.java
index 81fb39f..56f873d 100644
--- a/luni/src/main/java/java/lang/reflect/GenericArrayType.java
+++ b/luni/src/main/java/java/lang/reflect/GenericArrayType.java
@@ -21,22 +21,19 @@
* This interface represents an array type with a component type that is either
* a parameterized type or a type variable.
*
- * @since Android 1.0
+ * @since 1.5
*/
public interface GenericArrayType extends Type {
-
/**
* Returns the component type of this array.
*
* @return the component type of this array
- *
+ *
* @throws TypeNotPresentException
* if the component type points to a missing type
* @throws MalformedParameterizedTypeException
* if the component type points to a type that cannot be
* instantiated for some reason
- *
- * @since Android 1.0
*/
Type getGenericComponentType();
-}
+}
\ No newline at end of file
diff --git a/luni/src/main/java/java/lang/reflect/GenericDeclaration.java b/luni/src/main/java/java/lang/reflect/GenericDeclaration.java
index c7cedcf..880350b 100644
--- a/luni/src/main/java/java/lang/reflect/GenericDeclaration.java
+++ b/luni/src/main/java/java/lang/reflect/GenericDeclaration.java
@@ -18,8 +18,8 @@
/**
* Common interface for language constructs that declare type parameters.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public interface GenericDeclaration {
@@ -28,11 +28,8 @@
* no type parameters, this method returns a zero length array.
*
* @return the declared type parameters in declaration order
- *
* @throws GenericSignatureFormatError
* if the signature is malformed
- *
- * @since Android 1.0
*/
TypeVariable<?>[] getTypeParameters();
}
diff --git a/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java b/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
index bb901fd..c113006 100644
--- a/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
+++ b/luni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
@@ -20,8 +20,8 @@
/**
* Indicates that a malformed signature has been encountered via a reflective
* method.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public class GenericSignatureFormatError extends ClassFormatError {
@@ -29,8 +29,6 @@
/**
* Constructs a new {@code GenericSignatureFormatError} instance.
- *
- * @since Android 1.0
*/
public GenericSignatureFormatError() {
super();
diff --git a/luni/src/main/java/java/lang/reflect/InvocationHandler.java b/luni/src/main/java/java/lang/reflect/InvocationHandler.java
index b28d535..fe3eaba 100644
--- a/luni/src/main/java/java/lang/reflect/InvocationHandler.java
+++ b/luni/src/main/java/java/lang/reflect/InvocationHandler.java
@@ -21,8 +21,6 @@
* Implementors of this interface dispatch methods invoked on proxy instances.
*
* @see Proxy
- *
- * @since Android 1.0
*/
public interface InvocationHandler {
@@ -58,8 +56,6 @@
* The exception must match one of the declared exception types
* of the invoked method or any unchecked exception type. If not
* then an {@code UndeclaredThrowableException} is thrown
- *
- * @since Android 1.0
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
diff --git a/luni/src/main/java/java/lang/reflect/InvocationTargetException.java b/luni/src/main/java/java/lang/reflect/InvocationTargetException.java
index 2d69135..6dc44e7 100644
--- a/luni/src/main/java/java/lang/reflect/InvocationTargetException.java
+++ b/luni/src/main/java/java/lang/reflect/InvocationTargetException.java
@@ -23,8 +23,6 @@
*
* @see Method#invoke
* @see Constructor#newInstance
- *
- * @since Android 1.0
*/
public class InvocationTargetException extends Exception {
@@ -35,8 +33,6 @@
/**
* Constructs a new {@code InvocationTargetException} instance with a
* {@code null} cause / target exception.
- *
- * @since Android 1.0
*/
protected InvocationTargetException() {
super((Throwable) null);
@@ -49,8 +45,6 @@
* @param exception
* the exception which occurred while running the Method or
* Constructor
- *
- * @since Android 1.0
*/
public InvocationTargetException(Throwable exception) {
super(null, exception);
@@ -66,8 +60,6 @@
* @param exception
* the exception which occurred while running the Method or
* Constructor
- *
- * @since Android 1.0
*/
public InvocationTargetException(Throwable exception, String detailMessage) {
super(detailMessage, exception);
@@ -78,8 +70,6 @@
* Returns the target exception, which may be {@code null}.
*
* @return the target exception
- *
- * @since Android 1.0
*/
public Throwable getTargetException() {
return target;
@@ -89,8 +79,6 @@
* Returns the cause of this exception, which may be {@code null}.
*
* @return the cause of this exception
- *
- * @since Android 1.0
*/
@Override
public Throwable getCause() {
diff --git a/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java b/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java
index 7dfbc6f..71f2819 100644
--- a/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java
+++ b/luni/src/main/java/java/lang/reflect/MalformedParameterizedTypeException.java
@@ -21,7 +21,7 @@
* Indicates that a malformed parameterized type has been encountered by a
* reflective method.
*
- * @since Android 1.0
+ * @since 1.5
*/
public class MalformedParameterizedTypeException extends RuntimeException {
@@ -29,8 +29,6 @@
/**
* Constructs a new {@code MalformedParameterizedTypeException} instance.
- *
- * @since Android 1.0
*/
public MalformedParameterizedTypeException() {
super();
diff --git a/luni/src/main/java/java/lang/reflect/Member.java b/luni/src/main/java/java/lang/reflect/Member.java
index fb0739f..a91e108 100644
--- a/luni/src/main/java/java/lang/reflect/Member.java
+++ b/luni/src/main/java/java/lang/reflect/Member.java
@@ -8,11 +8,11 @@
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package java.lang.reflect;
@@ -23,28 +23,22 @@
* @see Field
* @see Constructor
* @see Method
- *
- * @since Android 1.0
*/
public interface Member {
/**
* Designates all public members of a class or interface (including
* inherited members).
- *
+ *
* @see java.lang.SecurityManager#checkMemberAccess
- *
- * @since Android 1.0
*/
public static final int PUBLIC = 0;
/**
* Designates all declared members of a class or interface (without
* inherited members).
- *
+ *
* @see java.lang.SecurityManager#checkMemberAccess
- *
- * @since Android 1.0
*/
public static final int DECLARED = 1;
@@ -52,8 +46,6 @@
* Returns the class that declares this member.
*
* @return the declaring class
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
Class getDeclaringClass();
@@ -63,10 +55,8 @@
* be used to decode the result.
*
* @return the modifiers for this member
- *
+ *
* @see Modifier
- *
- * @since Android 1.0
*/
int getModifiers();
@@ -74,8 +64,6 @@
* Returns the name of this member.
*
* @return the name of this member
- *
- * @since Android 1.0
*/
String getName();
@@ -84,8 +72,6 @@
* introduced by the compiler).
*
* @return {@code true} if this member is synthetic, {@code false} otherwise
- *
- * @since Android 1.0
*/
boolean isSynthetic();
}
diff --git a/luni/src/main/java/java/lang/reflect/Modifier.java b/luni/src/main/java/java/lang/reflect/Modifier.java
index ed201aa..0f9dc98 100644
--- a/luni/src/main/java/java/lang/reflect/Modifier.java
+++ b/luni/src/main/java/java/lang/reflect/Modifier.java
@@ -22,100 +22,74 @@
*
* @see Class#getModifiers()
* @see Member#getModifiers()
- *
- * @since Android 1.0
*/
public class Modifier {
/**
* The {@code int} value representing the {@code public}
* modifier.
- *
- * @since Android 1.0
*/
public static final int PUBLIC = 0x1;
/**
* The {@code int} value representing the {@code private}
* modifier.
- *
- * @since Android 1.0
*/
public static final int PRIVATE = 0x2;
/**
* The {@code int} value representing the {@code protected}
* modifier.
- *
- * @since Android 1.0
*/
public static final int PROTECTED = 0x4;
/**
* The {@code int} value representing the {@code static} modifier.
- *
- * @since Android 1.0
*/
public static final int STATIC = 0x8;
/**
* The {@code int} value representing the {@code final} modifier.
- *
- * @since Android 1.0
*/
public static final int FINAL = 0x10;
/**
* The {@code int} value representing the {@code synchronized}
* modifier.
- *
- * @since Android 1.0
*/
public static final int SYNCHRONIZED = 0x20;
/**
* The {@code int} value representing the {@code volatile}
* modifier.
- *
- * @since Android 1.0
*/
public static final int VOLATILE = 0x40;
/**
* The {@code int} value representing the {@code transient}
* modifier.
- *
- * @since Android 1.0
*/
public static final int TRANSIENT = 0x80;
/**
* The {@code int} value representing the {@code native} modifier.
- *
- * @since Android 1.0
*/
public static final int NATIVE = 0x100;
/**
* The {@code int} value representing the {@code interface}
* modifier.
- *
- * @since Android 1.0
*/
public static final int INTERFACE = 0x200;
/**
* The {@code int} value representing the {@code abstract}
* modifier.
- *
- * @since Android 1.0
*/
public static final int ABSTRACT = 0x400;
/**
* The {@code int} value representing the {@code strict} modifier.
- *
- * @since Android 1.0
*/
public static final int STRICT = 0x800;
@@ -132,8 +106,6 @@
/**
* Constructs a new {@code Modifier} instance.
- *
- * @since Android 1.0
*/
public Modifier() {
}
@@ -144,11 +116,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* abstract} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isAbstract(int modifiers) {
return ((modifiers & ABSTRACT) != 0);
@@ -160,11 +129,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* final} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isFinal(int modifiers) {
return ((modifiers & FINAL) != 0);
@@ -176,11 +142,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* interface} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isInterface(int modifiers) {
return ((modifiers & INTERFACE) != 0);
@@ -192,11 +155,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* native} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isNative(int modifiers) {
return ((modifiers & NATIVE) != 0);
@@ -208,11 +168,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* private} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isPrivate(int modifiers) {
return ((modifiers & PRIVATE) != 0);
@@ -224,11 +181,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* protected} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isProtected(int modifiers) {
return ((modifiers & PROTECTED) != 0);
@@ -240,11 +194,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* public} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isPublic(int modifiers) {
return ((modifiers & PUBLIC) != 0);
@@ -256,11 +207,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* static} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isStatic(int modifiers) {
return ((modifiers & STATIC) != 0);
@@ -272,11 +220,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* strict} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isStrict(int modifiers) {
return ((modifiers & STRICT) != 0);
@@ -288,11 +233,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* synchronized} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isSynchronized(int modifiers) {
return ((modifiers & SYNCHRONIZED) != 0);
@@ -304,11 +246,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* transient} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isTransient(int modifiers) {
return ((modifiers & TRANSIENT) != 0);
@@ -320,11 +259,8 @@
*
* @param modifiers
* the modifiers to test
- *
* @return {@code true} if the specified modifiers contain the {@code
* volatile} modifier, {@code false} otherwise
- *
- * @since Android 1.0
*/
public static boolean isVolatile(int modifiers) {
return ((modifiers & VOLATILE) != 0);
@@ -339,10 +275,7 @@
*
* @param modifiers
* the modifiers to print
- *
* @return a printable representation of the modifiers
- *
- * @since Android 1.0
*/
@SuppressWarnings("nls")
public static java.lang.String toString(int modifiers) {
diff --git a/luni/src/main/java/java/lang/reflect/ParameterizedType.java b/luni/src/main/java/java/lang/reflect/ParameterizedType.java
index 3d03921..91f2520 100644
--- a/luni/src/main/java/java/lang/reflect/ParameterizedType.java
+++ b/luni/src/main/java/java/lang/reflect/ParameterizedType.java
@@ -18,10 +18,10 @@
package java.lang.reflect;
/**
- * This interface represents a parameterized type such as {@code
+ * This interface represents a parameterized type such as {@code
* 'Set<String>'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public interface ParameterizedType extends Type {
@@ -32,25 +32,23 @@
* parameterized type, this method returns a zero length array. The generic
* type of the following {@code field} declaration is an example for a
* parameterized type without type arguments.
- *
+ *
* <pre>
* A<String>.B field;
- *
+ *
* class A<T> {
* class B {
* }
* }</pre>
- *
- *
+ *
+ *
* @return the actual type arguments
- *
+ *
* @throws TypeNotPresentException
* if one of the type arguments cannot be found
* @throws MalformedParameterizedTypeException
* if one of the type arguments cannot be instantiated for some
* reason
- *
- * @since Android 1.0
*/
Type[] getActualTypeArguments();
@@ -59,13 +57,11 @@
* {@code null} is returned if this is a top-level type.
*
* @return the owner type or {@code null} if this is a top-level type
- *
+ *
* @throws TypeNotPresentException
* if one of the type arguments cannot be found
* @throws MalformedParameterizedTypeException
* if the owner type cannot be instantiated for some reason
- *
- * @since Android 1.0
*/
Type getOwnerType();
@@ -73,10 +69,8 @@
* Returns the declaring type of this parameterized type.
* <p>
* The raw type of {@code Set<String> field;} is {@code Set}.
- *
+ *
* @return the raw type of this parameterized type
- *
- * @since Android 1.0
*/
Type getRawType();
}
diff --git a/luni/src/main/java/java/lang/reflect/Proxy.java b/luni/src/main/java/java/lang/reflect/Proxy.java
index 29d15c5..cc0c956 100644
--- a/luni/src/main/java/java/lang/reflect/Proxy.java
+++ b/luni/src/main/java/java/lang/reflect/Proxy.java
@@ -35,8 +35,7 @@
* invocations to an {@code InvocationHandler}.
*
* @see InvocationHandler
- *
- * @since Android 1.0
+ * @since 1.3
*/
public class Proxy implements Serializable {
@@ -52,8 +51,6 @@
/**
* The invocation handler on which the method calls are dispatched.
- *
- * @since Android 1.0
*/
protected InvocationHandler h;
@@ -64,11 +61,9 @@
/**
* Constructs a new {@code Proxy} instance with the specified invocation
* handler.
- *
+ *
* @param h
* the invocation handler for the newly created proxy
- *
- * @since Android 1.0
*/
protected Proxy(InvocationHandler h) {
this.h = h;
@@ -81,24 +76,20 @@
* different order result in different generated classes. The interfaces
* must be visible from the supplied class loader; no duplicates are
* permitted. All non-public interfaces must be defined in the same package.
- *
+ *
* @param loader
* the class loader that will define the proxy class
* @param interfaces
* an array of {@code Class} objects, each one identifying an
* interface that will be implemented by the returned proxy
* class
- *
* @return a proxy class that implements all of the interfaces referred to
* in the contents of {@code interfaces}
- *
* @throws IllegalArgumentException
* if any of the interface restrictions are violated
* @throws NullPointerException
* if either {@code interfaces} or any of its elements are
* {@code null}
- *
- * @since Android 1.0
*/
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces) throws IllegalArgumentException {
@@ -174,19 +165,17 @@
WeakReference<Class<?>> ref = interfaceCache.get(interfaceKey);
if (ref == null) {
String nextClassName = "$Proxy" + NextClassNameIndex++; //$NON-NLS-1$
- if (commonPackageName != null) {
+ if (commonPackageName != null && commonPackageName.length() > 0) {
nextClassName = commonPackageName + "." + nextClassName; //$NON-NLS-1$
}
// BEGIN android-changed
- //byte[] classFileBytes = ProxyClassFile.generateBytes(
- // nextClassName, interfaces);
- // END android-changed
+ // byte[] classFileBytes = ProxyClassFile.generateBytes(
+ // nextClassName, interfaces);
+ // newClass = defineClassImpl(loader, nextClassName.replace('.',
+ // '/'), classFileBytes);
if (loader == null) {
loader = ClassLoader.getSystemClassLoader();
}
- // BEGIN android-changed
- //newClass = defineClassImpl(loader, nextClassName.replace('.',
- // '/'), classFileBytes);
newClass = generateProxy(nextClassName.replace('.', '/'),
interfaces, loader);
// END android-changed
@@ -200,6 +189,10 @@
}
} else {
newClass = ref.get();
+ assert newClass != null : "\ninterfaceKey=\"" + interfaceKey + "\""
+ + "\nloaderCache=\"" + loaderCache + "\""
+ + "\nintfCache=\"" + interfaceCache + "\""
+ + "\nproxyCache=\"" + proxyCache + "\"";
}
return newClass;
}
@@ -211,7 +204,7 @@
* the specified invocation handler. The interfaces must be visible from the
* supplied class loader; no duplicates are permitted. All non-public
* interfaces must be defined in the same package.
- *
+ *
* @param loader
* the class loader that will define the proxy class
* @param interfaces
@@ -221,15 +214,11 @@
* @param h
* the invocation handler that handles the dispatched method
* invocations
- *
* @return a new proxy object that delegates to the handler {@code h}
- *
* @throws IllegalArgumentException
* if any of the interface restrictions are violated
* @throws NullPointerException
* if the interfaces or any of its elements are null
- *
- * @since Android 1.0
*/
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h)
@@ -260,17 +249,13 @@
/**
* Indicates whether or not the specified class is a dynamically generated
* proxy class.
- *
+ *
* @param cl
* the class
- *
* @return {@code true} if the class is a proxy class, {@code false}
* otherwise
- *
* @throws NullPointerException
* if the class is {@code null}
- *
- * @since Android 1.0
*/
public static boolean isProxyClass(Class<?> cl) {
if (cl == null) {
@@ -283,16 +268,12 @@
/**
* Returns the invocation handler of the specified proxy instance.
- *
+ *
* @param proxy
* the proxy instance
- *
* @return the invocation handler of the specified proxy instance
- *
* @throws IllegalArgumentException
* if the supplied {@code proxy} is not a proxy object
- *
- * @since Android 1.0
*/
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException {
diff --git a/luni/src/main/java/java/lang/reflect/ReflectPermission.java b/luni/src/main/java/java/lang/reflect/ReflectPermission.java
index b568663..93eef39 100644
--- a/luni/src/main/java/java/lang/reflect/ReflectPermission.java
+++ b/luni/src/main/java/java/lang/reflect/ReflectPermission.java
@@ -22,8 +22,6 @@
/**
* A {@code ReflectPermission} object represents a permission to access
* operations in the reflection layer.
- *
- * @since Android 1.0
*/
public final class ReflectPermission extends BasicPermission {
@@ -35,13 +33,10 @@
*
* @param permissionName
* the name of the new permission
- *
* @throws IllegalArgumentException
* if {@code name} is empty
* @throws NullPointerException
* if {@code name} is {@code null}
- *
- * @since Android 1.0
*/
public ReflectPermission(String permissionName) {
super(permissionName);
@@ -55,13 +50,10 @@
* the name of the new permission
* @param actions
* this parameter will be ignored
- *
* @throws IllegalArgumentException
* if {@code name} is empty
* @throws NullPointerException
* if {@code name} is {@code null}
- *
- * @since Android 1.0
*/
public ReflectPermission(String name, String actions) {
super(name, actions);
diff --git a/luni/src/main/java/java/lang/reflect/Type.java b/luni/src/main/java/java/lang/reflect/Type.java
index abd4978..a057088 100644
--- a/luni/src/main/java/java/lang/reflect/Type.java
+++ b/luni/src/main/java/java/lang/reflect/Type.java
@@ -18,8 +18,8 @@
/**
* Common interface implemented by all Java types.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public interface Type {
// Empty
diff --git a/luni/src/main/java/java/lang/reflect/TypeVariable.java b/luni/src/main/java/java/lang/reflect/TypeVariable.java
index 99aca77..e3f8c1d 100644
--- a/luni/src/main/java/java/lang/reflect/TypeVariable.java
+++ b/luni/src/main/java/java/lang/reflect/TypeVariable.java
@@ -17,15 +17,14 @@
package java.lang.reflect;
/**
- * This interface represents a type variables such as {@code 'T'} in {@code
- * 'public interface Comparable<T>'}, the bounded {@code 'T'} in {@code
+ * This interface represents a type variables such as {@code 'T'} in {@code
+ * 'public interface Comparable<T>'}, the bounded {@code 'T'} in {@code
* 'public interface A<T extends Number>'} or the multiple bounded {@code
* 'T'} in {@code 'public interface B<T extends Number & Cloneable>'}.
- *
+ *
* @param <D>
* the generic declaration that declares this type variable
- *
- * @since Android 1.0
+ * @since 1.5
*/
public interface TypeVariable<D extends GenericDeclaration> extends Type {
@@ -33,15 +32,13 @@
* Returns the upper bounds of this type variable. {@code Object} is the
* implicit upper bound if no other bounds are declared.
*
- * @return the upper bounds of this type variable
- *
+ * @return the upper bounds of this type variable
+ *
* @throws TypeNotPresentException
* if any of the bounds points to a missing type
* @throws MalformedParameterizedTypeException
* if any of the bounds points to a type that cannot be
* instantiated for some reason
- *
- * @since Android 1.0
*/
Type[] getBounds();
@@ -49,8 +46,6 @@
* Returns the language construct that declares this type variable.
*
* @return the generic declaration
- *
- * @since Android 1.0
*/
D getGenericDeclaration();
@@ -59,8 +54,6 @@
* code.
*
* @return the name of this type variable
- *
- * @since Android 1.0
*/
String getName();
}
diff --git a/luni/src/main/java/java/lang/reflect/UndeclaredThrowableException.java b/luni/src/main/java/java/lang/reflect/UndeclaredThrowableException.java
index 108f98a..bd5adfa 100644
--- a/luni/src/main/java/java/lang/reflect/UndeclaredThrowableException.java
+++ b/luni/src/main/java/java/lang/reflect/UndeclaredThrowableException.java
@@ -22,8 +22,6 @@
* an InvocationHandler.
*
* @see java.lang.reflect.InvocationHandler#invoke
- *
- * @since Android 1.0
*/
public class UndeclaredThrowableException extends RuntimeException {
@@ -37,8 +35,6 @@
*
* @param exception
* the undeclared, checked exception that occurred
- *
- * @since Android 1.0
*/
public UndeclaredThrowableException(Throwable exception) {
super();
@@ -54,8 +50,6 @@
* the detail message for the exception
* @param exception
* the undeclared, checked exception that occurred
- *
- * @since Android 1.0
*/
public UndeclaredThrowableException(Throwable exception,
String detailMessage) {
@@ -69,8 +63,6 @@
* {@code null}.
*
* @return the undeclared, checked exception that occurred
- *
- * @since Android 1.0
*/
public Throwable getUndeclaredThrowable() {
return undeclaredThrowable;
@@ -81,8 +73,6 @@
* {@code null}.
*
* @return the undeclared, checked exception that occurred
- *
- * @since Android 1.0
*/
@Override
public Throwable getCause() {
diff --git a/luni/src/main/java/java/lang/reflect/WildcardType.java b/luni/src/main/java/java/lang/reflect/WildcardType.java
index 72a022d..affd526 100644
--- a/luni/src/main/java/java/lang/reflect/WildcardType.java
+++ b/luni/src/main/java/java/lang/reflect/WildcardType.java
@@ -22,24 +22,21 @@
* {@code '?'}, the upper bounded wildcard {@code '? extends Closeable'}, the
* multiple upper bounded wildcard {@code '? extends Closeable & Flushable'} or
* the lower bounded wildcard {@code '? super OutputStream'}.
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public interface WildcardType extends Type {
-
/**
* Returns the array of types that represent the upper bounds of this type.
* The default upper bound is {@code Object}.
*
* @return an array containing the upper bounds types
- *
+ *
* @throws TypeNotPresentException
* if any of the bounds points to a missing type
* @throws MalformedParameterizedTypeException
* if any bound points to a type that cannot be instantiated for
* some reason
- *
- * @since Android 1.0
*/
Type[] getUpperBounds();
@@ -48,16 +45,14 @@
* The default lower bound is {@code null}, in which case an empty array is
* returned. Since only one lower bound is allowed, the returned array's
* length will never exceed one.
- *
+ *
* @return an array containing the lower bounds types
- *
+ *
* @throws TypeNotPresentException
* if any of the bounds points to a missing type
* @throws MalformedParameterizedTypeException
* if any of the bounds points to a type that cannot be
* instantiated for some reason
- *
- * @since Android 1.0
*/
Type[] getLowerBounds();
}
diff --git a/luni/src/main/java/java/net/Authenticator.java b/luni/src/main/java/java/net/Authenticator.java
index 1eea8d8..75d68fa 100644
--- a/luni/src/main/java/java/net/Authenticator.java
+++ b/luni/src/main/java/java/net/Authenticator.java
@@ -27,7 +27,6 @@
*
* @see #setDefault
* @see #getPasswordAuthentication
- * @since Android 1.0
*/
public abstract class Authenticator {
@@ -63,10 +62,8 @@
* default which is {@code null}.
* <p>
* Returns {@code null} by default.
- * </p>
- *
+ *
* @return collected password authentication data.
- * @since Android 1.0
*/
protected PasswordAuthentication getPasswordAuthentication() {
return null;
@@ -76,7 +73,6 @@
* Returns the port of the connection that requests authorization.
*
* @return port of the connection.
- * @since Android 1.0
*/
protected final int getRequestingPort() {
return this.port;
@@ -87,7 +83,6 @@
* {@code null} if unknown.
*
* @return address of the connection.
- * @since Android 1.0
*/
protected final InetAddress getRequestingSite() {
return this.addr;
@@ -98,7 +93,6 @@
* authorization.
*
* @return prompt string of the connection.
- * @since Android 1.0
*/
protected final String getRequestingPrompt() {
return this.prompt;
@@ -108,7 +102,6 @@
* Returns the protocol of the connection that requests authorization.
*
* @return protocol of the connection.
- * @since Android 1.0
*/
protected final String getRequestingProtocol() {
return this.protocol;
@@ -119,7 +112,6 @@
* example HTTP Basic Authentication.
*
* @return scheme of the connection.
- * @since Android 1.0
*/
protected final String getRequestingScheme() {
return this.scheme;
@@ -145,7 +137,6 @@
* @throws SecurityException
* if a security manager denies the password authentication
* permission.
- * @since Android 1.0
*/
public static synchronized PasswordAuthentication requestPasswordAuthentication(
InetAddress rAddr, int rPort, String rProtocol, String rPrompt,
@@ -182,7 +173,6 @@
* @throws SecurityException
* if a security manager denies the password authentication
* permission.
- * @since Android 1.0
*/
public static void setDefault(Authenticator a) {
SecurityManager sm = System.getSecurityManager();
@@ -214,7 +204,6 @@
* @throws SecurityException
* if a security manager denies the password authentication
* permission.
- * @since Android 1.0
*/
public static synchronized PasswordAuthentication requestPasswordAuthentication(
String rHost, InetAddress rAddr, int rPort, String rProtocol,
@@ -244,9 +233,8 @@
/**
* Returns the host name of the connection that requests authentication or
* {@code null} if unknown.
- *
+ *
* @return name of the requesting host or {@code null}.
- * @since Android 1.0
*/
protected final String getRequestingHost() {
return host;
@@ -278,7 +266,6 @@
* @throws SecurityException
* if a security manager denies the password authentication
* permission.
- * @since Android 1.0
*/
public static PasswordAuthentication requestPasswordAuthentication(
String rHost, InetAddress rAddr, int rPort, String rProtocol,
@@ -312,7 +299,6 @@
* Returns the URL of the authentication request.
*
* @return authentication request url.
- * @since Android 1.0
*/
protected URL getRequestingURL() {
return url;
@@ -322,7 +308,6 @@
* Returns the type of this request, it can be {@code PROXY} or {@code SERVER}.
*
* @return RequestorType of the authentication request.
- * @since Android 1.0
*/
protected Authenticator.RequestorType getRequestorType() {
return rt;
@@ -330,8 +315,6 @@
/**
* Enumeration class for the origin of the authentication request.
- *
- * @since Android 1.0
*/
public enum RequestorType {
diff --git a/luni/src/main/java/java/net/BindException.java b/luni/src/main/java/java/net/BindException.java
index 69be315..48f1cf6 100644
--- a/luni/src/main/java/java/net/BindException.java
+++ b/luni/src/main/java/java/net/BindException.java
@@ -20,8 +20,6 @@
/**
* A {@code BindException} is thrown when a process cannot bind a local
* address/port, either because it is already bound or reserved by the OS.
- *
- * @since Android 1.0
*/
public class BindException extends SocketException {
@@ -29,8 +27,6 @@
/**
* Constructs a new instance with its walkback filled in.
- *
- * @since Android 1.0
*/
public BindException() {
super();
@@ -41,7 +37,6 @@
*
* @param detailMessage
* detail message of the exception.
- * @since Android 1.0
*/
public BindException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/CacheRequest.java b/luni/src/main/java/java/net/CacheRequest.java
index 8c67a44..778cb13 100644
--- a/luni/src/main/java/java/net/CacheRequest.java
+++ b/luni/src/main/java/java/net/CacheRequest.java
@@ -29,14 +29,11 @@
* the current cache store operation is abandoned.
*
* @see ResponseCache
- * @since Android 1.0
*/
public abstract class CacheRequest {
/**
* This implementation does nothing.
- *
- * @since Android 1.0
*/
public CacheRequest() {
super();
@@ -46,8 +43,6 @@
* Aborts the current cache operation. If an {@code IOException} occurs
* while reading the response or writing resource data to the cache, the
* current cache store operation is aborted.
- *
- * @since Android 1.0
*/
public abstract void abort();
@@ -58,7 +53,6 @@
* @throws IOException
* if an I/O error is encountered during writing response body
* operation.
- * @since Android 1.0
*/
public abstract OutputStream getBody() throws IOException;
}
diff --git a/luni/src/main/java/java/net/CacheResponse.java b/luni/src/main/java/java/net/CacheResponse.java
index ae5be44..b0ad094 100644
--- a/luni/src/main/java/java/net/CacheResponse.java
+++ b/luni/src/main/java/java/net/CacheResponse.java
@@ -28,13 +28,10 @@
* getHeaders()} to fetch the response headers.
*
* @see ResponseCache
- * @since Android 1.0
*/
public abstract class CacheResponse {
/**
* This implementation does nothing.
- *
- * @since Android 1.0
*/
public CacheResponse() {
super();
@@ -48,7 +45,6 @@
* @throws IOException
* if an I/O error is encountered while retrieving the response
* body.
- * @since Android 1.0
*/
public abstract InputStream getBody() throws IOException;
@@ -62,7 +58,6 @@
* @throws IOException
* if an I/O error is encountered while retrieving the response
* headers.
- * @since Android 1.0
*/
public abstract Map<String, List<String>> getHeaders() throws IOException;
}
diff --git a/luni/src/main/java/java/net/ConnectException.java b/luni/src/main/java/java/net/ConnectException.java
index 42389c7..84cd2bb 100644
--- a/luni/src/main/java/java/net/ConnectException.java
+++ b/luni/src/main/java/java/net/ConnectException.java
@@ -20,8 +20,6 @@
/**
* A {@code ConnectException} is thrown if a connection cannot be established to
* a remote host on a specific port.
- *
- * @since Android 1.0
*/
public class ConnectException extends SocketException {
@@ -29,8 +27,6 @@
/**
* This implementation does nothing.
- *
- * @since Android 1.0
*/
public ConnectException() {
super();
@@ -38,10 +34,9 @@
/**
* This implementation does nothing.
- *
+ *
* @param detailMessage
* detail message of the exception.
- * @since Android 1.0
*/
public ConnectException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/ContentHandler.java b/luni/src/main/java/java/net/ContentHandler.java
index 05c6acf..8e0bbb7 100644
--- a/luni/src/main/java/java/net/ContentHandler.java
+++ b/luni/src/main/java/java/net/ContentHandler.java
@@ -23,28 +23,26 @@
* This class converts the content of a certain format (i.e. a MIME type) into a
* Java type object. It is created by {@code ContentHandlerFactory}. The data
* values should be accessed via {@code URL} or {@code URLConnection}.
- *
+ *
* @see ContentHandlerFactory
* @see URL#getContent()
* @see URLConnection#getContent()
- * @since Android 1.0
*/
public abstract class ContentHandler {
/**
* Returns the object pointed by the specified URL connection {@code uConn}.
- *
+ *
* @param uConn
* URL connection that points to the desired object.
* @return object referred by {@code uConn}.
* @throws IOException
* if an IO error occurs during the retrieval of the object
- * @since Android 1.0
*/
public abstract Object getContent(URLConnection uConn) throws IOException;
/**
* Returns the object pointed by the specified URL connection {@code uConn}.
- *
+ *
* @param uConn
* URL connection that points to the desired object.
* @param types
@@ -53,7 +51,6 @@
* content doesn't match one of the specified content types.
* @throws IOException
* if an error occurred while obtaining the content.
- * @since Android 1.0
*/
// Class arg not generified in the spec.
@SuppressWarnings("unchecked")
diff --git a/luni/src/main/java/java/net/ContentHandlerFactory.java b/luni/src/main/java/java/net/ContentHandlerFactory.java
index 1a564ee..3089c04 100644
--- a/luni/src/main/java/java/net/ContentHandlerFactory.java
+++ b/luni/src/main/java/java/net/ContentHandlerFactory.java
@@ -21,7 +21,6 @@
* Defines a factory which is responsible for creating a {@code ContentHandler}.
*
* @see ContentHandler
- * @since Android 1.0
*/
public interface ContentHandlerFactory {
/**
@@ -31,7 +30,6 @@
* specifies the content type which is handled by the returned
* {@code ContentHandler}.
* @return content handler object for a specific content type.
- * @since Android 1.0
*/
ContentHandler createContentHandler(String contentType);
}
diff --git a/luni/src/main/java/java/net/CookieHandler.java b/luni/src/main/java/java/net/CookieHandler.java
index 29428ec..05eddde 100644
--- a/luni/src/main/java/java/net/CookieHandler.java
+++ b/luni/src/main/java/java/net/CookieHandler.java
@@ -22,8 +22,6 @@
/**
* This class provides a way to manage cookies with a HTTP protocol handler.
- *
- * @since Android 1.0
*/
public abstract class CookieHandler {
@@ -37,9 +35,8 @@
/**
* Returns the system-wide cookie handler or {@code null} if not set.
- *
+ *
* @return the system-wide cookie handler.
- * @since Android 1.0
*/
public static CookieHandler getDefault() {
SecurityManager sm = System.getSecurityManager();
@@ -51,10 +48,9 @@
/**
* Sets the system-wide cookie handler.
- *
+ *
* @param cHandler
* a cookie handler to set as the system-wide default handler.
- * @since Android 1.0
*/
public static void setDefault(CookieHandler cHandler) {
SecurityManager sm = System.getSecurityManager();
@@ -66,7 +62,7 @@
/**
* Gets all cookies for a specific URI from the cookie cache.
- *
+ *
* @param uri
* a URI to search for applicable cookies.
* @param requestHeaders
@@ -74,7 +70,6 @@
* @return an unchangeable map of all appropriate cookies.
* @throws IOException
* if an error occurs during the I/O operation.
- * @since Android 1.0
*/
public abstract Map<String, List<String>> get(URI uri,
Map<String, List<String>> requestHeaders) throws IOException;
@@ -82,14 +77,13 @@
/**
* Sets all cookies of a specific URI in the {@code responseHeaders} into
* the cookie cache.
- *
+ *
* @param uri
* the origin URI of the cookies.
* @param responseHeaders
* a list of request headers.
* @throws IOException
* if an error occurs during the I/O operation.
- * @since Android 1.0
*/
public abstract void put(URI uri, Map<String, List<String>> responseHeaders)
throws IOException;
diff --git a/luni/src/main/java/java/net/DatagramPacket.java b/luni/src/main/java/java/net/DatagramPacket.java
index bcc531e..7bbf553 100644
--- a/luni/src/main/java/java/net/DatagramPacket.java
+++ b/luni/src/main/java/java/net/DatagramPacket.java
@@ -25,20 +25,30 @@
* such as its source or destination host.
*
* @see DatagramSocket
- * @since Android 1.0
*/
public final class DatagramPacket {
byte[] data;
+ /**
+ * Length of the data to be sent or size of data that was received via
+ * DatagramSocket#receive() method call.
+ */
int length;
+ /**
+ * Size of internal buffer that is used to store received data. Should be
+ * greater or equal to "length" field.
+ */
+ int capacity;
+
InetAddress address;
int port = -1; // The default port number is -1
int offset = 0;
+
/**
* Constructs a new {@code DatagramPacket} object to receive data up to
* {@code length} bytes.
@@ -47,7 +57,6 @@
* a byte array to store the read characters.
* @param length
* the length of the data buffer.
- * @since Android 1.0
*/
public DatagramPacket(byte[] data, int length) {
this(data, 0, length);
@@ -63,7 +72,6 @@
* the offset of the byte array where the bytes is written.
* @param length
* the length of the data.
- * @since Android 1.0
*/
public DatagramPacket(byte[] data, int offset, int length) {
super();
@@ -75,7 +83,7 @@
* {@code aPort} of the address {@code host}. The {@code length} must be
* lesser than or equal to the size of {@code data}. The first {@code
* length} bytes from the byte array position {@code offset} are sent.
- *
+ *
* @param data
* a byte array which stores the characters to be sent.
* @param offset
@@ -86,7 +94,6 @@
* the address of the target host.
* @param aPort
* the port of the target host.
- * @since Android 1.0
*/
public DatagramPacket(byte[] data, int offset, int length,
InetAddress host, int aPort) {
@@ -100,7 +107,7 @@
* {@code aPort} of the address {@code host}. The {@code length} must be
* lesser than or equal to the size of {@code data}. The first {@code
* length} bytes are sent.
- *
+ *
* @param data
* a byte array which stores the characters to be sent.
* @param length
@@ -109,7 +116,6 @@
* the address of the target host.
* @param port
* the port of the target host.
- * @since Android 1.0
*/
public DatagramPacket(byte[] data, int length, InetAddress host, int port) {
this(data, 0, length, host, port);
@@ -120,7 +126,6 @@
*
* @return the address from where the datagram was received or to which it
* is sent.
- * @since Android 1.0
*/
public synchronized InetAddress getAddress() {
return address;
@@ -130,7 +135,6 @@
* Gets the data of this datagram packet.
*
* @return the received data or the data to be sent.
- * @since Android 1.0
*/
public synchronized byte[] getData() {
return data;
@@ -140,7 +144,6 @@
* Gets the length of the data stored in this datagram packet.
*
* @return the length of the received data or the data to be sent.
- * @since Android 1.0
*/
public synchronized int getLength() {
return length;
@@ -150,7 +153,6 @@
* Gets the offset of the data stored in this datagram packet.
*
* @return the position of the received data or the data to be sent.
- * @since Android 1.0
*/
public synchronized int getOffset() {
return offset;
@@ -159,9 +161,8 @@
/**
* Gets the port number of the target or sender host of this datagram
* packet.
- *
+ *
* @return the port number of the origin or target host.
- * @since Android 1.0
*/
public synchronized int getPort() {
return port;
@@ -172,7 +173,6 @@
*
* @param addr
* the target host address.
- * @since Android 1.0
*/
public synchronized void setAddress(InetAddress addr) {
address = addr;
@@ -188,7 +188,6 @@
* @param aLength
* the length of the data to be sent or the length of buffer to
* store the received data.
- * @since Android 1.0
*/
public synchronized void setData(byte[] buf, int anOffset, int aLength) {
if (0 > anOffset || anOffset > buf.length || 0 > aLength
@@ -198,6 +197,7 @@
data = buf;
offset = anOffset;
length = aLength;
+ capacity = aLength;
}
/**
@@ -206,10 +206,10 @@
*
* @param buf
* the buffer to store the data.
- * @since Android 1.0
*/
public synchronized void setData(byte[] buf) {
length = buf.length; // This will check for null
+ capacity = buf.length;
data = buf;
offset = 0;
}
@@ -220,13 +220,13 @@
*
* @param len
* the length of this datagram packet.
- * @since Android 1.0
*/
public synchronized void setLength(int len) {
if (0 > len || offset + len > data.length) {
throw new IllegalArgumentException(Msg.getString("K002f")); //$NON-NLS-1$
}
length = len;
+ capacity = len;
}
/**
@@ -234,7 +234,6 @@
*
* @param aPort
* the target host port number.
- * @since Android 1.0
*/
public synchronized void setPort(int aPort) {
if (aPort < 0 || aPort > 65535) {
@@ -257,9 +256,9 @@
* the target host address and port.
* @throws SocketException
* if an error in the underlying protocol occurs.
- * @since Android 1.0
*/
- public DatagramPacket(byte[] data, int length, SocketAddress sockAddr) throws SocketException {
+ public DatagramPacket(byte[] data, int length, SocketAddress sockAddr)
+ throws SocketException {
this(data, 0, length);
setSocketAddress(sockAddr);
}
@@ -280,7 +279,6 @@
* the target host address and port.
* @throws SocketException
* if an error in the underlying protocol occurs.
- * @since Android 1.0
*/
public DatagramPacket(byte[] data, int offset, int length,
SocketAddress sockAddr) throws SocketException {
@@ -291,9 +289,8 @@
/**
* Gets the host address and the port to which this datagram packet is sent
* as a {@code SocketAddress} object.
- *
+ *
* @return the SocketAddress of the target host.
- * @since Android 1.0
*/
public synchronized SocketAddress getSocketAddress() {
return new InetSocketAddress(getAddress(), getPort());
@@ -304,7 +301,6 @@
*
* @param sockAddr
* the SocketAddress of the target host.
- * @since Android 1.0
*/
public synchronized void setSocketAddress(SocketAddress sockAddr) {
if (!(sockAddr instanceof InetSocketAddress)) {
diff --git a/luni/src/main/java/java/net/DatagramSocket.java b/luni/src/main/java/java/net/DatagramSocket.java
index 0c7745f..6b3b6cc 100644
--- a/luni/src/main/java/java/net/DatagramSocket.java
+++ b/luni/src/main/java/java/net/DatagramSocket.java
@@ -20,19 +20,17 @@
import java.io.IOException;
import java.nio.channels.DatagramChannel;
-import org.apache.harmony.luni.net.SocketImplProvider;
+import org.apache.harmony.luni.net.PlainDatagramSocketImpl;
import org.apache.harmony.luni.platform.Platform;
-
import org.apache.harmony.luni.util.Msg;
/**
* This class implements a UDP socket for sending and receiving {@code
* DatagramPacket}. A {@code DatagramSocket} object can be used for both
* endpoints of a connection for a packet delivery service.
- *
+ *
* @see DatagramPacket
* @see DatagramSocketImplFactory
- * @since Android 1.0
*/
public class DatagramSocket {
@@ -56,16 +54,15 @@
static {
Platform.getNetworkSystem().oneTimeInitialization(true);
}
-
+
private Object lock = new Lock();
/**
* Constructs a UDP datagram socket which is bound to any available port on
* the localhost.
- *
+ *
* @throws SocketException
* if an error occurs while creating or binding the socket.
- * @since Android 1.0
*/
public DatagramSocket() throws SocketException {
this(0);
@@ -75,12 +72,11 @@
* Constructs a UDP datagram socket which is bound to the specific port
* {@code aPort} on the localhost. Valid values for {@code aPort} are
* between 0 and 65535 inclusive.
- *
+ *
* @param aPort
* the port to bind on the localhost.
* @throws SocketException
* if an error occurs while creating or binding the socket.
- * @since Android 1.0
*/
public DatagramSocket(int aPort) throws SocketException {
super();
@@ -92,14 +88,13 @@
* Constructs a UDP datagram socket which is bound to the specific local
* address {@code addr} on port {@code aPort}. Valid values for {@code
* aPort} are between 0 and 65535 inclusive.
- *
+ *
* @param aPort
* the port to bind on the localhost.
* @param addr
* the address to bind on the localhost.
* @throws SocketException
* if an error occurs while creating or binding the socket.
- * @since Android 1.0
*/
public DatagramSocket(int aPort, InetAddress addr) throws SocketException {
super();
@@ -111,10 +106,9 @@
* Sends prior to attempting to bind the socket, checks whether the port is
* within the valid port range and verifies with the security manager that
* the port may be bound by the current context.
- *
+ *
* @param aPort
* the port on the localhost that is to be bound.
- * @since Android 1.0
*/
void checkListen(int aPort) {
if (aPort < 0 || aPort > 65535) {
@@ -128,8 +122,6 @@
/**
* Closes this UDP datagram socket and all possibly associated channels.
- *
- * @since Android 1.0
*/
// In the documentation jdk1.1.7a/guide/net/miscNet.html, this method is
// noted as not being synchronized.
@@ -144,12 +136,11 @@
* validated, thereafter the only validation on {@code send()} and {@code
* receive()} is to check whether the packet address/port matches the
* connected target.
- *
+ *
* @param anAddress
* the target address of this socket.
* @param aPort
* the target port of this socket.
- * @since Android 1.0
*/
public void connect(InetAddress anAddress, int aPort) {
if (anAddress == null || aPort < 0 || aPort > 65535) {
@@ -189,8 +180,6 @@
/**
* Disconnects this UDP datagram socket from the remote host. This method
* called on an unconnected socket does nothing.
- *
- * @since Android 1.0
*/
public void disconnect() {
if (isClosed() || !isConnected()) {
@@ -205,7 +194,7 @@
synchronized void createSocket(int aPort, InetAddress addr)
throws SocketException {
impl = factory != null ? factory.createDatagramSocketImpl()
- : SocketImplProvider.getDatagramSocketImpl();
+ : new PlainDatagramSocketImpl();
impl.create();
try {
impl.bind(aPort, addr);
@@ -219,10 +208,9 @@
/**
* Gets the {@code InetAddress} instance representing the remote address to
* which this UDP datagram socket is connected.
- *
+ *
* @return the remote address this socket is connected to or {@code null} if
* this socket is not connected.
- * @since Android 1.0
*/
public InetAddress getInetAddress() {
return address;
@@ -231,10 +219,9 @@
/**
* Gets the {@code InetAddress} instance representing the bound local
* address of this UDP datagram socket.
- *
+ *
* @return the local address to which this socket is bound to or {@code
* null} if this socket is closed.
- * @since Android 1.0
*/
public InetAddress getLocalAddress() {
if (isClosed()) {
@@ -257,10 +244,9 @@
/**
* Gets the local port which this socket is bound to.
- *
+ *
* @return the local port of this socket or {@code -1} if this socket is
* closed and {@code 0} if it is unbound.
- * @since Android 1.0
*/
public int getLocalPort() {
if (isClosed()) {
@@ -274,10 +260,9 @@
/**
* Gets the remote port which this socket is connected to.
- *
+ *
* @return the remote port of this socket. The return value {@code -1}
* indicates that this socket is not connected.
- * @since Android 1.0
*/
public int getPort() {
return port;
@@ -285,9 +270,8 @@
/**
* Indicates whether this socket is multicast or not.
- *
+ *
* @return the return value is always {@code false}.
- * @since Android 1.0
*/
boolean isMulticastSocket() {
return false;
@@ -295,11 +279,10 @@
/**
* Gets the socket receive buffer size. ( {@code SocketOptions.SO_RCVBUF} )
- *
+ *
* @return the input buffer size.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while getting the option value.
- * @since Android 1.0
*/
public synchronized int getReceiveBufferSize() throws SocketException {
checkClosedAndBind(false);
@@ -308,11 +291,10 @@
/**
* Gets the socket send buffer size. ( {@code SocketOptions.SO_SNDBUF} )
- *
+ *
* @return the output buffer size.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while getting the option value.
- * @since Android 1.0
*/
public synchronized int getSendBufferSize() throws SocketException {
checkClosedAndBind(false);
@@ -323,11 +305,10 @@
* Gets the socket receive timeout in milliseconds. The return value {@code
* 0} implies the timeout is disabled/infinitive. ( {@code
* SocketOptions.SO_TIMEOUT} )
- *
+ *
* @return the socket receive timeout.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while getting the option value.
- * @since Android 1.0
*/
public synchronized int getSoTimeout() throws SocketException {
checkClosedAndBind(false);
@@ -342,42 +323,49 @@
* has expired. If a security manager exists, its {@code checkAccept} method
* determines whether or not a packet is discarded. Any packets from
* unacceptable origins are silently discarded.
- *
+ *
* @param pack
* the {@code DatagramPacket} to store the received data.
- * @exception IOException
+ * @throws IOException
* if an error occurs while receiving the packet.
- * @since Android 1.0
*/
public synchronized void receive(DatagramPacket pack) throws IOException {
checkClosedAndBind(true);
- boolean secure = true;
-
- InetAddress senderAddr = null;
-
- int senderPort = 0;
+ InetAddress senderAddr;
+ int senderPort;
DatagramPacket tempPack = new DatagramPacket(new byte[1], 1);
+
+ // means that we have received the packet into the temporary buffer
boolean copy = false;
SecurityManager security = System.getSecurityManager();
- if (address != null || security != null) { // The socket is connected
+
+ if (address != null || security != null) {
+ // The socket is connected or we need to check security permissions
+
// Check pack before peeking
if (pack == null) {
throw new NullPointerException();
}
- secure = false;
- while (!secure) {
+
+ // iterate over incoming packets
+ while (true) {
copy = false;
+
+ // let's get sender's address and port
try {
senderPort = impl.peekData(tempPack);
senderAddr = tempPack.getAddress();
} catch (SocketException e) {
if (e.getMessage().equals(
"The socket does not support the operation")) { //$NON-NLS-1$
- tempPack = new DatagramPacket(new byte[pack.length],
- pack.getLength());
+ // receive packet to temporary buffer
+ tempPack = new DatagramPacket(new byte[pack.capacity],
+ pack.capacity);
impl.receive(tempPack);
+ // tempPack's length field is now updated, capacity is unchanged
+ // let's extract address & port
senderAddr = tempPack.getAddress();
senderPort = tempPack.getPort();
copy = true;
@@ -385,46 +373,45 @@
throw e;
}
}
+
if (address == null) {
+ // if we are not connected let's check if we are allowed to
+ // receive packets from sender's address and port
try {
security.checkAccept(senderAddr.getHostName(),
senderPort);
- if (!copy) {
- secure = true;
- }
+ // address & port are valid
break;
} catch (SecurityException e) {
if (!copy) {
- if (tempPack == null) {
- tempPack = new DatagramPacket(
- new byte[pack.length], pack.length);
- }
+ // drop this packet and continue
impl.receive(tempPack);
}
}
} else if (port == senderPort && address.equals(senderAddr)) {
- if (!copy) {
- secure = true;
- }
+ // we are connected and the packet came
+ // from the address & port we are connected to
break;
} else if (!copy) {
- if (tempPack == null) {
- tempPack = new DatagramPacket(new byte[pack.length],
- pack.length);
- }
+ // drop packet and continue
impl.receive(tempPack);
}
}
}
+
if (copy) {
System.arraycopy(tempPack.getData(), 0, pack.getData(), pack
.getOffset(), tempPack.getLength());
- pack.setLength(tempPack.getLength());
+ // we shouldn't update the pack's capacity field in order to be
+ // compatible with RI
+ pack.length = tempPack.length;
pack.setAddress(tempPack.getAddress());
pack.setPort(tempPack.getPort());
- }
- if (secure) {
+ } else {
+ pack.setLength(pack.capacity);
impl.receive(pack);
+ // pack's length field is now updated by native code call;
+ // pack's capacity field is unchanged
}
}
@@ -433,12 +420,11 @@
* policy before it may be sent. If a security manager is installed, this
* method checks whether it is allowed to send this packet to the specified
* address.
- *
+ *
* @param pack
* the {@code DatagramPacket} which has to be sent.
- * @exception IOException
+ * @throws IOException
* if an error occurs while sending the packet.
- * @since Android 1.0
*/
public void send(DatagramPacket pack) throws IOException {
checkClosedAndBind(true);
@@ -480,12 +466,11 @@
* maximum packet size is that can be sent over this socket. It depends on
* the network implementation what will happen if the packet is bigger than
* the buffer size. ( {@code SocketOptions.SO_SNDBUF} )
- *
+ *
* @param size
* the buffer size in bytes. The size must be at least one byte.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while setting the option.
- * @since Android 1.0
*/
public synchronized void setSendBufferSize(int size) throws SocketException {
if (size < 1) {
@@ -500,12 +485,11 @@
* the maximum packet size is that can be received over this socket. It
* depends on the network implementation what will happen if the packet is
* bigger than the buffer size. ( {@code SocketOptions.SO_RCVBUF} )
- *
+ *
* @param size
* the buffer size in bytes. The size must be at least one byte.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while setting the option.
- * @since Android 1.0
*/
public synchronized void setReceiveBufferSize(int size)
throws SocketException {
@@ -523,12 +507,11 @@
* {@code 0} (default) is used to set an infinite timeout. To have effect
* this option must be set before the blocking method was called. ( {@code
* SocketOptions.SO_TIMEOUT} )
- *
+ *
* @param timeout
* the timeout period in milliseconds or {@code 0} for infinite.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while setting the option.
- * @since Android 1.0
*/
public synchronized void setSoTimeout(int timeout) throws SocketException {
if (timeout < 0) {
@@ -545,13 +528,12 @@
* method {@code checkSetFactory()} is called to check if the operation is
* allowed. A {@code SecurityException} is thrown if the operation is not
* allowed.
- *
+ *
* @param fac
* the socket factory to use.
- * @exception IOException
+ * @throws IOException
* if the factory has already been set.
* @see DatagramSocketImplFactory
- * @since Android 1.0
*/
public static synchronized void setDatagramSocketImplFactory(
DatagramSocketImplFactory fac) throws IOException {
@@ -569,10 +551,9 @@
* Constructs a new {@code DatagramSocket} using the specific datagram
* socket implementation {@code socketImpl}. The created {@code
* DatagramSocket} will not be bound.
- *
+ *
* @param socketImpl
* the DatagramSocketImpl to use.
- * @since Android 1.0
*/
protected DatagramSocket(DatagramSocketImpl socketImpl) {
if (socketImpl == null) {
@@ -585,12 +566,13 @@
* Constructs a new {@code DatagramSocket} bound to the host/port specified
* by the {@code SocketAddress} {@code localAddr} or an unbound {@code
* DatagramSocket} if the {@code SocketAddress} is {@code null}.
- *
+ *
* @param localAddr
* the local machine address and port to bind to.
+ * @throws IllegalArgumentException
+ * if the SocketAddress is not supported
* @throws SocketException
* if a problem occurs creating or binding the socket.
- * @since Android 1.0
*/
public DatagramSocket(SocketAddress localAddr) throws SocketException {
if (localAddr != null) {
@@ -601,7 +583,7 @@
checkListen(((InetSocketAddress) localAddr).getPort());
}
impl = factory != null ? factory.createDatagramSocketImpl()
- : SocketImplProvider.getDatagramSocketImpl();
+ : new PlainDatagramSocketImpl();
impl.create();
if (localAddr != null) {
try {
@@ -630,13 +612,14 @@
* Binds this socket to the local address and port specified by {@code
* localAddr}. If this value is {@code null} any free port on a valid local
* address is used.
- *
+ *
* @param localAddr
* the local machine address and port to bind on.
+ * @throws IllegalArgumentException
+ * if the SocketAddress is not supported
* @throws SocketException
* if the socket is already bound or a problem occurs during
* binding.
- * @since Android 1.0
*/
public void bind(SocketAddress localAddr) throws SocketException {
checkClosedAndBind(false);
@@ -665,12 +648,11 @@
* {@code remoteAddr}. The host and port are validated, thereafter the only
* validation on {@code send()} and {@code receive()} is that the packet
* address/port matches the connected target.
- *
+ *
* @param remoteAddr
* the address and port of the target host.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs during connecting.
- * @since Android 1.0
*/
public void connect(SocketAddress remoteAddr) throws SocketException {
if (remoteAddr == null) {
@@ -720,9 +702,8 @@
/**
* Determines whether the socket is bound to an address or not.
- *
+ *
* @return {@code true} if the socket is bound, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isBound() {
return isBound;
@@ -730,9 +711,8 @@
/**
* Determines whether the socket is connected to a target host.
- *
+ *
* @return {@code true} if the socket is connected, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isConnected() {
return isConnected;
@@ -741,9 +721,8 @@
/**
* Gets the address and port of the connected remote host. If this socket is
* not connected yet, {@code null} is returned.
- *
+ *
* @return the remote socket address.
- * @since Android 1.0
*/
public SocketAddress getRemoteSocketAddress() {
if (!isConnected()) {
@@ -755,9 +734,8 @@
/**
* Gets the bound local address and port of this socket. If the socket is
* unbound, {@code null} is returned.
- *
+ *
* @return the local socket address.
- * @since Android 1.0
*/
public SocketAddress getLocalSocketAddress() {
if (!isBound()) {
@@ -773,13 +751,11 @@
* <p>
* There is an undefined behavior if this option is set after the socket is
* already bound.
- * </p>
- *
+ *
* @param reuse
* the socket option value to enable or disable this option.
* @throws SocketException
* if the socket is closed or the option could not be set.
- * @since Android 1.0
*/
public void setReuseAddress(boolean reuse) throws SocketException {
checkClosedAndBind(false);
@@ -789,11 +765,10 @@
/**
* Gets the state of the socket option {@code SocketOptions.SO_REUSEADDR}.
- *
+ *
* @return {@code true} if the option is enabled, {@code false} otherwise.
* @throws SocketException
* if the socket is closed or the option is invalid.
- * @since Android 1.0
*/
public boolean getReuseAddress() throws SocketException {
checkClosedAndBind(false);
@@ -804,12 +779,11 @@
/**
* Sets the socket option {@code SocketOptions.SO_BROADCAST}. This option
* must be enabled to send broadcast messages.
- *
+ *
* @param broadcast
* the socket option value to enable or disable this option.
* @throws SocketException
* if the socket is closed or the option could not be set.
- * @since Android 1.0
*/
public void setBroadcast(boolean broadcast) throws SocketException {
checkClosedAndBind(false);
@@ -819,11 +793,10 @@
/**
* Gets the state of the socket option {@code SocketOptions.SO_BROADCAST}.
- *
+ *
* @return {@code true} if the option is enabled, {@code false} otherwise.
* @throws SocketException
* if the socket is closed or the option is invalid.
- * @since Android 1.0
*/
public boolean getBroadcast() throws SocketException {
checkClosedAndBind(false);
@@ -839,13 +812,11 @@
* <p>
* Values between {@code 0} and {@code 255} inclusive are valid for this
* option.
- * </p>
- *
+ *
* @param value
* the socket option value to be set as type-of-service.
* @throws SocketException
* if the socket is closed or the option could not be set.
- * @since Android 1.0
*/
public void setTrafficClass(int value) throws SocketException {
checkClosedAndBind(false);
@@ -858,11 +829,10 @@
/**
* Gets the value of the type-of-service socket option {@code
* SocketOptions.IP_TOS}.
- *
+ *
* @return the type-of-service socket option value.
* @throws SocketException
* if the socket is closed or the option is invalid.
- * @since Android 1.0
*/
public int getTrafficClass() throws SocketException {
checkClosedAndBind(false);
@@ -871,9 +841,8 @@
/**
* Gets the state of this socket.
- *
+ *
* @return {@code true} if the socket is closed, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isClosed() {
return isClosed;
@@ -882,10 +851,9 @@
/**
* Gets the related DatagramChannel of this socket. This implementation
* returns always {@code null}.
- *
+ *
* @return the related DatagramChannel or {@code null} if this socket was
* not created by a {@code DatagramChannel} object.
- * @since Android 1.0
*/
public DatagramChannel getChannel() {
return null;
diff --git a/luni/src/main/java/java/net/DatagramSocketImpl.java b/luni/src/main/java/java/net/DatagramSocketImpl.java
index 7915156..db3b9ec 100644
--- a/luni/src/main/java/java/net/DatagramSocketImpl.java
+++ b/luni/src/main/java/java/net/DatagramSocketImpl.java
@@ -25,29 +25,21 @@
/**
* The abstract superclass for datagram and multicast socket implementations.
- *
- * @since Android 1.0
*/
public abstract class DatagramSocketImpl implements SocketOptions {
/**
* File descriptor that is used to address this socket.
- *
- * @since Android 1.0
*/
protected FileDescriptor fd;
/**
* The number of the local port to which this socket is bound.
- *
- * @since Android 1.0
*/
protected int localPort;
/**
* Constructs an unbound datagram socket implementation.
- *
- * @since Android 1.0
*/
public DatagramSocketImpl() {
localPort = -1;
@@ -61,28 +53,24 @@
* the port on the localhost to bind.
* @param addr
* the address on the multihomed localhost to bind.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while binding, for example, if the port
* has been already bound.
- * @since Android 1.0
*/
protected abstract void bind(int port, InetAddress addr)
throws SocketException;
/**
* Closes this socket.
- *
- * @since Android 1.0
*/
protected abstract void close();
/**
* This method allocates the socket descriptor in the underlying operating
* system.
- *
+ *
* @throws SocketException
* if an error occurs while creating the socket.
- * @since Android 1.0
*/
protected abstract void create() throws SocketException;
@@ -91,7 +79,6 @@
* if the socket is closed or not bound.
*
* @return the current file descriptor of this socket.
- * @since Android 1.0
*/
protected FileDescriptor getFileDescriptor() {
return fd;
@@ -101,7 +88,6 @@
* Gets the local address to which the socket is bound.
*
* @return the local address to which the socket is bound.
- * @since Android 1.0
*/
InetAddress getLocalAddress() {
return Platform.getNetworkSystem().getSocketLocalAddress(fd,
@@ -112,7 +98,6 @@
* Gets the local port of this socket.
*
* @return the local port to which this socket is bound.
- * @since Android 1.0
*/
protected int getLocalPort() {
return localPort;
@@ -124,9 +109,8 @@
* @param optID
* the ID of the socket option to be retrieved.
* @return the requested option value.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while accessing the option.
- * @since Android 1.0
*/
public abstract Object getOption(int optID) throws SocketException;
@@ -139,7 +123,6 @@
* value.
* @deprecated Replaced by {@link #getTimeToLive}
* @see #getTimeToLive()
- * @since Android 1.0
*/
@Deprecated
protected abstract byte getTTL() throws IOException;
@@ -148,12 +131,11 @@
* Gets the time-to-live (TTL) for multicast packets sent on this socket.
* The TTL option defines how many routers a packet may be pass before it is
* discarded.
- *
+ *
* @return the time-to-live option as an integer value.
* @throws IOException
* if an error occurs while getting the time-to-live option
* value.
- * @since Android 1.0
*/
protected abstract int getTimeToLive() throws IOException;
@@ -167,7 +149,6 @@
* @throws IOException
* if an error occurs while joining the specified multicast
* group.
- * @since Android 1.0
*/
protected abstract void join(InetAddress addr) throws IOException;
@@ -184,7 +165,6 @@
* @throws IOException
* if an error occurs while joining the specified multicast
* group.
- * @since Android 1.0
*/
protected abstract void joinGroup(SocketAddress addr,
NetworkInterface netInterface) throws IOException;
@@ -197,7 +177,6 @@
* @throws IOException
* if an error occurs while leaving the group or no multicast
* address was assigned.
- * @since Android 1.0
*/
protected abstract void leave(InetAddress addr) throws IOException;
@@ -211,7 +190,6 @@
* removed.
* @throws IOException
* if an error occurs while leaving the group.
- * @since Android 1.0
*/
protected abstract void leaveGroup(SocketAddress addr,
NetworkInterface netInterface) throws IOException;
@@ -224,9 +202,8 @@
* @param sender
* the origin address of a packet.
* @return the address of {@code sender} as an integer value.
- * @exception IOException
+ * @throws IOException
* if an error or a timeout occurs while reading the address.
- * @since Android 1.0
*/
protected abstract int peek(InetAddress sender) throws IOException;
@@ -238,9 +215,8 @@
*
* @param pack
* the datagram packet container to fill in the received data.
- * @exception IOException
+ * @throws IOException
* if an error or timeout occurs while receiving data.
- * @since Android 1.0
*/
protected abstract void receive(DatagramPacket pack) throws IOException;
@@ -250,9 +226,8 @@
*
* @param pack
* the datagram packet to be sent.
- * @exception IOException
+ * @throws IOException
* if an error occurs while sending the packet.
- * @since Android 1.0
*/
protected abstract void send(DatagramPacket pack) throws IOException;
@@ -263,9 +238,8 @@
* the ID of the socket option to be set.
* @param val
* the value of the option.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while setting the option.
- * @since Android 1.0
*/
public abstract void setOption(int optID, Object val)
throws SocketException;
@@ -279,7 +253,6 @@
* <= 255.
* @throws IOException
* if an error occurs while setting the option.
- * @since Android 1.0
*/
protected abstract void setTimeToLive(int ttl) throws IOException;
@@ -294,7 +267,6 @@
* if an error occurs while setting the option.
* @deprecated Replaced by {@link #setTimeToLive}
* @see #setTimeToLive(int)
- * @since Android 1.0
*/
@Deprecated
protected abstract void setTTL(byte ttl) throws IOException;
@@ -306,10 +278,9 @@
* the address of the target host which has to be connected.
* @param port
* the port on the target host which has to be connected.
- * @exception SocketException
+ * @throws SocketException
* if the datagram socket cannot be connected to the
* specified remote address and port.
- * @since Android 1.0
*/
protected void connect(InetAddress inetAddr, int port)
throws SocketException {
@@ -318,8 +289,6 @@
/**
* Disconnects this socket from the remote host.
- *
- * @since Android 1.0
*/
protected void disconnect() {
// do nothing
@@ -335,9 +304,8 @@
* @param pack
* the datagram packet used to store the data.
* @return the port the packet was received from.
- * @exception IOException
+ * @throws IOException
* if an error occurs while peeking at the data.
- * @since Android 1.0
*/
protected abstract int peekData(DatagramPacket pack) throws IOException;
}
diff --git a/luni/src/main/java/java/net/DatagramSocketImplFactory.java b/luni/src/main/java/java/net/DatagramSocketImplFactory.java
index b97146e..ce91738 100644
--- a/luni/src/main/java/java/net/DatagramSocketImplFactory.java
+++ b/luni/src/main/java/java/net/DatagramSocketImplFactory.java
@@ -23,7 +23,6 @@
* implementation.
*
* @see DatagramSocket
- * @since Android 1.0
*/
public interface DatagramSocketImplFactory {
@@ -31,7 +30,6 @@
* Creates a new {@code DatagramSocketImpl} instance.
*
* @return the new datagram socket implementation.
- * @since Android 1.0
*/
DatagramSocketImpl createDatagramSocketImpl();
}
diff --git a/luni/src/main/java/java/net/FileNameMap.java b/luni/src/main/java/java/net/FileNameMap.java
index e8ac35f..16fa0e0 100644
--- a/luni/src/main/java/java/net/FileNameMap.java
+++ b/luni/src/main/java/java/net/FileNameMap.java
@@ -26,7 +26,6 @@
* @see URLConnection#getFileNameMap()
* @see URLConnection#guessContentTypeFromName(String)
* @see URLStreamHandler
- * @since Android 1.0
*/
public interface FileNameMap {
@@ -36,7 +35,6 @@
* @param fileName
* the name of the file to consider.
* @return the appropriate MIME type of the given file.
- * @since Android 1.0
*/
public String getContentTypeFor(String fileName);
}
diff --git a/luni/src/main/java/java/net/HttpRetryException.java b/luni/src/main/java/java/net/HttpRetryException.java
index 5f613ab..4ad14bd 100644
--- a/luni/src/main/java/java/net/HttpRetryException.java
+++ b/luni/src/main/java/java/net/HttpRetryException.java
@@ -21,8 +21,6 @@
/**
* If a HTTP request has to be retried, this exception will be thrown if the
* request cannot be retried automatically.
- *
- * @since Android 1.0
*/
public class HttpRetryException extends IOException {
@@ -40,7 +38,6 @@
* the detail message for this exception.
* @param code
* the HTTP response code from target host.
- * @since Android 1.0
*/
public HttpRetryException(String detail, int code) {
super(detail);
@@ -58,7 +55,6 @@
* the HTTP response code from target host.
* @param location
* the destination URL of the redirection.
- * @since Android 1.0
*/
public HttpRetryException(String detail, int code, String location) {
super(detail);
@@ -68,9 +64,8 @@
/**
* Gets the location value.
- *
+ *
* @return the stored location from the HTTP header.
- * @since Android 1.0
*/
public String getLocation() {
return location;
@@ -78,9 +73,8 @@
/**
* Gets the detail message.
- *
+ *
* @return the detail message.
- * @since Android 1.0
*/
public String getReason() {
return getMessage();
@@ -88,9 +82,8 @@
/**
* Gets the response code.
- *
+ *
* @return the HTTP response code.
- * @since Android 1.0
*/
public int responseCode() {
return responseCode;
diff --git a/luni/src/main/java/java/net/HttpURLConnection.java b/luni/src/main/java/java/net/HttpURLConnection.java
index 55cc363..6be891f 100644
--- a/luni/src/main/java/java/net/HttpURLConnection.java
+++ b/luni/src/main/java/java/net/HttpURLConnection.java
@@ -29,7 +29,6 @@
* @see URL
* @see URLConnection
* @see URLStreamHandler
- * @since Android 1.0
*/
public abstract class HttpURLConnection extends URLConnection {
@SuppressWarnings("nls")
@@ -39,8 +38,6 @@
/**
* The HTTP request method of this {@code HttpURLConnection}. The default
* value is {@code "GET"}.
- *
- * @since Android 1.0
*/
protected String method = "GET"; //$NON-NLS-1$
@@ -53,24 +50,17 @@
* <li>3xx: Relocation/Redirection</li>
* <li>4xx: Client Error</li>
* <li>5xx: Server Error</li>
- * </p>
- *
- * @since Android 1.0
*/
protected int responseCode = -1;
/**
* The HTTP response message which corresponds to the response code.
- *
- * @since Android 1.0
*/
protected String responseMessage;
/**
* Flag to define whether the protocol will automatically follow redirects
* or not. The default value is {@code true}.
- *
- * @since Android 1.0
*/
protected boolean instanceFollowRedirects = followRedirects;
@@ -80,8 +70,6 @@
* If the HTTP chunked encoding is enabled this parameter defines the
* chunk-length. Default value is {@code -1} that means the chunked encoding
* mode is disabled.
- *
- * @since Android 1.0
*/
protected int chunkLength = -1;
@@ -89,8 +77,6 @@
* If using HTTP fixed-length streaming mode this parameter defines the
* fixed length of content. Default value is {@code -1} that means the
* fixed-length streaming mode is disabled.
- *
- * @since Android 1.0
*/
protected int fixedContentLength = -1;
@@ -102,255 +88,184 @@
// 5XX: server error
/**
* Numeric status code, 202: Accepted
- *
- * @since Android 1.0
*/
public final static int HTTP_ACCEPTED = 202;
/**
* Numeric status code, 502: Bad Gateway
- *
- * @since Android 1.0
*/
public final static int HTTP_BAD_GATEWAY = 502;
/**
* Numeric status code, 405: Bad Method
- *
- * @since Android 1.0
*/
public final static int HTTP_BAD_METHOD = 405;
/**
* Numeric status code, 400: Bad Request
- *
- * @since Android 1.0
*/
public final static int HTTP_BAD_REQUEST = 400;
/**
* Numeric status code, 408: Client Timeout
- *
- * @since Android 1.0
*/
public final static int HTTP_CLIENT_TIMEOUT = 408;
/**
* Numeric status code, 409: Conflict
- *
- * @since Android 1.0
*/
public final static int HTTP_CONFLICT = 409;
/**
* Numeric status code, 201: Created
- *
- * @since Android 1.0
*/
public final static int HTTP_CREATED = 201;
/**
* Numeric status code, 413: Entity too large
- *
- * @since Android 1.0
*/
public final static int HTTP_ENTITY_TOO_LARGE = 413;
/**
* Numeric status code, 403: Forbidden
- *
- * @since Android 1.0
*/
public final static int HTTP_FORBIDDEN = 403;
/**
* Numeric status code, 504: Gateway timeout
- *
- * @since Android 1.0
*/
public final static int HTTP_GATEWAY_TIMEOUT = 504;
/**
* Numeric status code, 410: Gone
- *
- * @since Android 1.0
*/
public final static int HTTP_GONE = 410;
/**
* Numeric status code, 500: Internal error
- *
- * @since Android 1.0
*/
public final static int HTTP_INTERNAL_ERROR = 500;
/**
* Numeric status code, 411: Length required
- *
- * @since Android 1.0
*/
public final static int HTTP_LENGTH_REQUIRED = 411;
/**
* Numeric status code, 301 Moved permanently
- *
- * @since Android 1.0
*/
public final static int HTTP_MOVED_PERM = 301;
/**
* Numeric status code, 302: Moved temporarily
- *
- * @since Android 1.0
*/
public final static int HTTP_MOVED_TEMP = 302;
/**
* Numeric status code, 300: Multiple choices
- *
- * @since Android 1.0
*/
public final static int HTTP_MULT_CHOICE = 300;
/**
* Numeric status code, 204: No content
- *
- * @since Android 1.0
*/
public final static int HTTP_NO_CONTENT = 204;
/**
* Numeric status code, 406: Not acceptable
- *
- * @since Android 1.0
*/
public final static int HTTP_NOT_ACCEPTABLE = 406;
/**
* Numeric status code, 203: Not authoritative
- *
- * @since Android 1.0
*/
public final static int HTTP_NOT_AUTHORITATIVE = 203;
/**
* Numeric status code, 404: Not found
- *
- * @since Android 1.0
*/
public final static int HTTP_NOT_FOUND = 404;
/**
* Numeric status code, 501: Not implemented
- *
- * @since Android 1.0
*/
public final static int HTTP_NOT_IMPLEMENTED = 501;
/**
* Numeric status code, 304: Not modified
- *
- * @since Android 1.0
*/
public final static int HTTP_NOT_MODIFIED = 304;
/**
* Numeric status code, 200: OK
- *
- * @since Android 1.0
*/
public final static int HTTP_OK = 200;
/**
* Numeric status code, 206: Partial
- *
- * @since Android 1.0
*/
public final static int HTTP_PARTIAL = 206;
/**
* Numeric status code, 402: Payment required
- *
- * @since Android 1.0
*/
public final static int HTTP_PAYMENT_REQUIRED = 402;
/**
* Numeric status code, 412: Precondition failed
- *
- * @since Android 1.0
*/
public final static int HTTP_PRECON_FAILED = 412;
/**
* Numeric status code, 407: Proxy authentication required
- *
- * @since Android 1.0
*/
public final static int HTTP_PROXY_AUTH = 407;
/**
* Numeric status code, 414: Request too long
- *
- * @since Android 1.0
*/
public final static int HTTP_REQ_TOO_LONG = 414;
/**
* Numeric status code, 205: Reset
- *
- * @since Android 1.0
*/
public final static int HTTP_RESET = 205;
/**
* Numeric status code, 303: See other
- *
- * @since Android 1.0
*/
public final static int HTTP_SEE_OTHER = 303;
/**
* Numeric status code, 500: Internal error
- *
+ *
* @deprecated Use {@link #HTTP_INTERNAL_ERROR}
- * @since Android 1.0
*/
@Deprecated
public final static int HTTP_SERVER_ERROR = 500;
/**
* Numeric status code, 305: Use proxy
- *
- * @since Android 1.0
*/
public final static int HTTP_USE_PROXY = 305;
/**
* Numeric status code, 401: Unauthorized
- *
- * @since Android 1.0
*/
public final static int HTTP_UNAUTHORIZED = 401;
/**
* Numeric status code, 415: Unsupported type
- *
- * @since Android 1.0
*/
public final static int HTTP_UNSUPPORTED_TYPE = 415;
/**
* Numeric status code, 503: Unavailable
- *
- * @since Android 1.0
*/
public final static int HTTP_UNAVAILABLE = 503;
/**
* Numeric status code, 505: Version not supported
- *
- * @since Android 1.0
*/
public final static int HTTP_VERSION = 505;
@@ -362,7 +277,6 @@
* the URL of this connection.
* @see URL
* @see URLConnection
- * @since Android 1.0
*/
protected HttpURLConnection(URL url) {
super(url);
@@ -373,7 +287,6 @@
*
* @see URLConnection#connect()
* @see URLConnection#connected
- * @since Android 1.0
*/
public abstract void disconnect();
@@ -383,7 +296,6 @@
* can be used to read the data the server will send back.
*
* @return the error input stream returned by the server.
- * @since Android 1.0
*/
public java.io.InputStream getErrorStream() {
return null;
@@ -396,7 +308,6 @@
*
* @return the value of the flag.
* @see #setFollowRedirects
- * @since Android 1.0
*/
public static boolean getFollowRedirects() {
return followRedirects;
@@ -412,7 +323,6 @@
* @throws IOException
* if an IO exception occurs during the creation of the
* permission object.
- * @since Android 1.0
*/
@Override
public java.security.Permission getPermission() throws IOException {
@@ -432,7 +342,6 @@
* @return the request method string.
* @see #method
* @see #setRequestMethod
- * @since Android 1.0
*/
public String getRequestMethod() {
return method;
@@ -445,7 +354,6 @@
* @throws IOException
* if there is an IO error during the retrieval.
* @see #getResponseMessage
- * @since Android 1.0
*/
public int getResponseCode() throws IOException {
// Call getInputStream() first since getHeaderField() doesn't return
@@ -478,7 +386,6 @@
* @throws IOException
* if there is an error during the retrieval.
* @see #getResponseCode()
- * @since Android 1.0
*/
public String getResponseMessage() throws IOException {
if (responseMessage != null) {
@@ -496,7 +403,6 @@
* @param auto
* the value to enable or disable this option.
* @see SecurityManager#checkSetFactory()
- * @since Android 1.0
*/
public static void setFollowRedirects(boolean auto) {
SecurityManager security = System.getSecurityManager();
@@ -517,7 +423,6 @@
* supported by this HTTP implementation.
* @see #getRequestMethod()
* @see #method
- * @since Android 1.0
*/
public void setRequestMethod(String method) throws ProtocolException {
if (connected) {
@@ -540,7 +445,6 @@
*
* @return {@code true} if this connection passes a proxy server, false
* otherwise.
- * @since Android 1.0
*/
public abstract boolean usingProxy();
@@ -549,7 +453,6 @@
*
* @return {@code true} if this connection follows redirects, false
* otherwise.
- * @since Android 1.0
*/
public boolean getInstanceFollowRedirects() {
return instanceFollowRedirects;
@@ -561,7 +464,6 @@
* @param followRedirects
* {@code true} if this connection will follows redirects, false
* otherwise.
- * @since Android 1.0
*/
public void setInstanceFollowRedirects(boolean followRedirects) {
instanceFollowRedirects = followRedirects;
@@ -579,7 +481,6 @@
* found.
* @return the header field represented in milliseconds since January 1,
* 1970 GMT.
- * @since Android 1.0
*/
@Override
public long getHeaderFieldDate(String field, long defaultValue) {
@@ -598,7 +499,6 @@
* if already connected or an other mode already set.
* @throws IllegalArgumentException
* if {@code contentLength} is less than zero.
- * @since Android 1.0
*/
public void setFixedLengthStreamingMode(int contentLength) {
if (super.connected) {
@@ -624,7 +524,6 @@
* the length of a chunk.
* @throws IllegalStateException
* if already connected or an other mode already set.
- * @since Android 1.0
*/
public void setChunkedStreamingMode(int chunklen) {
if (super.connected) {
diff --git a/luni/src/main/java/java/net/Inet4Address.java b/luni/src/main/java/java/net/Inet4Address.java
index dd6b088..23efa5e 100644
--- a/luni/src/main/java/java/net/Inet4Address.java
+++ b/luni/src/main/java/java/net/Inet4Address.java
@@ -28,8 +28,6 @@
* address ({@code b.bbb} ) allows to represent a class A network address as
* <i>net.host</i>. If there is only one part ({@code bbbb} ) the address is
* represented without any byte rearrangement.
- *
- * @since Android 1.0
*/
public final class Inet4Address extends InetAddress {
@@ -50,7 +48,6 @@
*
* @return {@code true} if this instance represents a multicast address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMulticastAddress() {
@@ -63,7 +60,6 @@
*
* @return {@code true} if this instance represents the wildcard ANY
* address, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isAnyLocalAddress() {
@@ -81,7 +77,6 @@
*
* @return {@code true} if this instance represents a lookback address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isLoopbackAddress() {
@@ -95,11 +90,9 @@
* Default Address Selection for Internet Protocol Version 6 (IPv6) states
* IPv4 auto-configuration addresses, prefix 169.254/16, IPv4 loopback
* addresses, prefix 127/8, are assigned link-local scope.
- * </p>
- *
+ *
* @return {@code true} if this instance represents a link-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isLinkLocalAddress() {
@@ -115,11 +108,9 @@
* Default Address Selection for Internet Protocol Version 6 (IPv6) states
* IPv4 private addresses, prefixes 10/8, 172.16/12, and 192.168/16, are
* assigned site-local scope.
- * </p>
*
* @return {@code true} if this instance represents a site-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isSiteLocalAddress() {
@@ -135,7 +126,6 @@
*
* @return {@code true} if the address is in the global multicast group,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCGlobal() {
@@ -174,7 +164,6 @@
* addresses.
*
* @return {@code false} for all IPv4 addresses.
- * @since Android 1.0
*/
@Override
public boolean isMCNodeLocal() {
@@ -188,7 +177,6 @@
*
* @return {@code true} if this instance represents a link-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCLinkLocal() {
@@ -202,7 +190,6 @@
*
* @return {@code true} if this instance represents a site-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCSiteLocal() {
@@ -217,7 +204,6 @@
*
* @return {@code true} if this instance represents a organization-local
* address, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCOrgLocal() {
@@ -229,7 +215,6 @@
* Returns a textual representation of this IP address.
*
* @return the textual representation of this host address.
- * @since Android 1.0
*/
@Override
public String getHostAddress() {
@@ -247,7 +232,6 @@
* Gets the hashcode of the represented IP address.
*
* @return the appropriate hashcode value.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -262,7 +246,6 @@
* @param obj
* the object to be tested for equality.
* @return {@code true} if the addresses are equal, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object obj) {
diff --git a/luni/src/main/java/java/net/Inet6Address.java b/luni/src/main/java/java/net/Inet6Address.java
index 4c10faa..0569829 100644
--- a/luni/src/main/java/java/net/Inet6Address.java
+++ b/luni/src/main/java/java/net/Inet6Address.java
@@ -28,8 +28,6 @@
/**
* This class represents a 128 bit long IPv6 address.
- *
- * @since Android 1.0
*/
public final class Inet6Address extends InetAddress {
@@ -80,7 +78,6 @@
* the name associated with the address.
* @param scope_id
* the scope id for link- or site-local addresses.
- * @since Android 1.0
*/
Inet6Address(byte address[], String name, int scope_id) {
hostName = name;
@@ -104,7 +101,6 @@
* @return the Inet6Address instance representing the IP address.
* @throws UnknownHostException
* if the address is null or has an invalid length.
- * @since Android 1.0
*/
public static Inet6Address getByAddress(String host, byte[] addr,
int scope_id) throws UnknownHostException {
@@ -135,7 +131,6 @@
* if the address is {@code null} or has an invalid length or
* the interface doesn't have a numeric scope id for the given
* address type.
- * @since Android 1.0
*/
public static Inet6Address getByAddress(String host, byte[] addr,
NetworkInterface nif) throws UnknownHostException {
@@ -177,10 +172,11 @@
/**
* Returns {@code true} if one of following cases applies:
* <p>
- * <li>1. both addresses are site local</li>
- * <li>2. both addresses are link local</li>
- * <li>3. {@code ia} is neither site local nor link local</li>
- * </p>
+ * <ol>
+ * <li>both addresses are site local</li>
+ * <li>both addresses are link local</li>
+ * <li>{@code ia} is neither site local nor link local</li>
+ * </ol>
*/
private boolean compareLocalType(Inet6Address ia) {
if (ia.isSiteLocalAddress() && isSiteLocalAddress()) {
@@ -203,7 +199,6 @@
* the network address.
* @param scope_id
* the scope id for link- or site-local addresses.
- * @since Android 1.0
*/
Inet6Address(byte address[], int scope_id) {
ipaddress = address;
@@ -219,7 +214,6 @@
*
* @return {@code true} if this address is in the multicast group, {@code
* false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMulticastAddress() {
@@ -233,7 +227,6 @@
*
* @return {@code true} if this instance represents a wildcard address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isAnyLocalAddress() {
@@ -251,7 +244,6 @@
*
* @return {@code true} if this instance represents the loopback address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isLoopbackAddress() {
@@ -277,7 +269,6 @@
*
* @return {@code true} if this instance represents a link-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isLinkLocalAddress() {
@@ -292,7 +283,6 @@
*
* @return {@code true} if this instance represents a site-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isSiteLocalAddress() {
@@ -307,7 +297,6 @@
*
* @return {@code true} if this instance represents a global multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCGlobal() {
@@ -323,7 +312,6 @@
*
* @return {@code true} if this instance represents a node-local multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCNodeLocal() {
@@ -339,7 +327,6 @@
*
* @return {@code true} if this instance represents a link-local multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCLinkLocal() {
@@ -355,7 +342,6 @@
*
* @return {@code true} if this instance represents a site-local multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCSiteLocal() {
@@ -371,7 +357,6 @@
*
* @return {@code true} if this instance represents a org-local multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean isMCOrgLocal() {
@@ -384,7 +369,6 @@
* Gets the textual representation of this IP address.
*
* @return the as a dotted string formatted IP address.
- * @since Android 1.0
*/
@Override
public String getHostAddress() {
@@ -397,7 +381,6 @@
*
* @return the scope_id of this address or 0 when not linked with an
* interface.
- * @since Android 1.0
*/
public int getScopeId() {
if (scope_id_set) {
@@ -411,7 +394,6 @@
* network interface. Otherwise returns {@code null}.
*
* @return the scoped network interface of this address.
- * @since Android 1.0
*/
public NetworkInterface getScopedInterface() {
if (scope_ifname_set) {
@@ -424,7 +406,6 @@
* Gets the hashcode of the represented IP address.
*
* @return the appropriate hashcode value.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -441,7 +422,6 @@
* @param obj
* the object to be tested for equality.
* @return {@code true} if the addresses are equal, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object obj) {
@@ -455,7 +435,6 @@
*
* @return {@code true} if this instance represents an IPv4 compatible
* address, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isIPv4CompatibleAddress() {
for (int i = 0; i < 12; i++) {
@@ -506,7 +485,6 @@
* IP address.
*
* @return the description, as host/address.
- * @since Android 1.0
*/
@Override
public String toString() {
diff --git a/luni/src/main/java/java/net/InetAddress.java b/luni/src/main/java/java/net/InetAddress.java
index 72c7669..fa3859b 100644
--- a/luni/src/main/java/java/net/InetAddress.java
+++ b/luni/src/main/java/java/net/InetAddress.java
@@ -41,8 +41,6 @@
* encapsulates an IP address and provides name and reverse name resolution
* functions. The address is stored in network order, but as a signed (rather
* than unsigned) integer.
- *
- * @since Android 1.0
*/
public class InetAddress extends Object implements Serializable {
@@ -59,7 +57,7 @@
private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused"; //$NON-NLS-1$
- private static final long serialVersionUID = 3286316764910316507L;
+ private static final long serialVersionUID = 3286316764910316507L;
// BEGIN android-added
/**
@@ -86,7 +84,7 @@
// BEGIN android-removed
// // Fill in the JNI id caches
// private static native void oneTimeInitialization(boolean supportsIPv6);
- //
+ //
// static {
// oneTimeInitialization(true);
// }
@@ -102,7 +100,7 @@
/**
* Constructs an {@code InetAddress}, representing the {@code address} and
* {@code hostName}.
- *
+ *
* @param address
* the network address.
*/
@@ -114,7 +112,7 @@
/**
* Constructs an {@code InetAddress}, representing the {@code address} and
* {@code hostName}.
- *
+ *
* @param address
* the network address.
*/
@@ -124,26 +122,6 @@
this.hostName = hostName;
}
- // BEGIN android-removed
- // Removed in newer version of harmony
- // /**
- // * Returns the IP address of the argument {@code addr} as a byte array. The
- // * elements are in network order (the highest order address byte is in the
- // * zeroth element).
- // *
- // * @return the network address as a byte array.
- // */
- // static byte[] addressOf(int addr) {
- // int temp = addr;
- // byte array[] = new byte[4];
- // array[3] = (byte) (temp & 0xFF);
- // array[2] = (byte) ((temp >>>= 8) & 0xFF);
- // array[1] = (byte) ((temp >>>= 8) & 0xFF);
- // array[0] = (byte) ((temp >>>= 8) & 0xFF);
- // return array;
- // }
- // BEGIN android-removed
-
CacheElement cacheElement() {
return new CacheElement();
}
@@ -152,11 +130,10 @@
* Compares this {@code InetAddress} instance against the specified address
* in {@code obj}. Two addresses are equal if their address byte arrays have
* the same length and if the bytes in the arrays are equal.
- *
+ *
* @param obj
* the object to be tested for equality.
* @return {@code true} if both objects are equal, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object obj) {
@@ -185,9 +162,8 @@
* Returns the IP address represented by this {@code InetAddress} instance
* as a byte array. The elements are in network order (the highest order
* address byte is in the zeroth element).
- *
+ *
* @return the address in form of a byte array.
- * @since Android 1.0
*/
public byte[] getAddress() {
return ipaddress.clone();
@@ -200,25 +176,21 @@
* {@code UnknownHostException} is thrown. If the host name is a dotted IP
* address string an array with the corresponding single {@code InetAddress}
* is returned.
- *
+ *
* @param host
* the host's name or IP to be resolved to an address.
* @return the array of addresses associated with the specified host.
* @throws UnknownHostException
* if the address lookup fails.
- * @since Android 1.0
*/
public static InetAddress[] getAllByName(String host)
throws UnknownHostException {
// BEGIN android-changed
- // Added change taken from newer harmony concerning zero length hostname.
- // Added special handling for localhost, since it doesn't work properly.
+ // Added special handling for "localhost", since it doesn't work properly.
// TODO Get rid of this later...
- if (host == null || 0 == host.length() ||
- "localhost".equalsIgnoreCase(host)) {
- return new InetAddress[] { preferIPv6Addresses()
- ? Inet6Address.LOOPBACK
- : LOOPBACK };
+ if (host == null || 0 == host.length() || "localhost".equalsIgnoreCase(host)) {
+ return new InetAddress[] { preferIPv6Addresses() ? Inet6Address.LOOPBACK
+ : LOOPBACK };
}
// END android-changed
@@ -241,7 +213,7 @@
} else {
// Cannot happen, because the underlying code only returns
// addresses that are 4 or 16 bytes long.
- throw new AssertionError("Impossible address length " +
+ throw new AssertionError("Impossible address length " +
rawAddress.length);
}
}
@@ -289,14 +261,12 @@
}
byte[] hBytes = Inet6Util.createByteArrayFromIPAddressString(host);
- // BEGIN android-added
- // Copied from a newer version of harmony
if (hBytes.length == 4) {
return (new InetAddress[] { new Inet4Address(hBytes) });
} else if (hBytes.length == 16) {
return (new InetAddress[] { new Inet6Address(hBytes) });
}
- // END android-added
+
return (new InetAddress[] { new InetAddress(hBytes) });
}
@@ -306,20 +276,19 @@
* string IP address. If the latter, the {@code hostName} field is
* determined upon demand. {@code host} can be {@code null} which means that
* an address of the loopback interface is returned.
- *
+ *
* @param host
* the hostName to be resolved to an address or {@code null}.
* @return the {@code InetAddress} instance representing the host.
* @throws UnknownHostException
* if the address lookup fails.
- * @since Android 1.0
*/
public static InetAddress getByName(String host)
throws UnknownHostException {
// BEGIN android-changed
// Added special handling for localhost, since it doesn't work properly.
// TODO Get rid of this later...
- if (host == null || 0 == host.length() ||
+ if (host == null || 0 == host.length() ||
"localhost".equalsIgnoreCase(host)) {
return InetAddress.LOOPBACK;
}
@@ -341,10 +310,9 @@
/**
* Gets the textual representation of this IP address.
- *
+ *
* @return the textual representation of this host address in form of a
* dotted string.
- * @since Android 1.0
*/
public String getHostAddress() {
return inetNtoaImpl(bytesToInt(ipaddress, 0));
@@ -354,9 +322,8 @@
* Gets the host name of this IP address. If the IP address could not be
* resolved, the textual representation in a dotted-quad-notation is
* returned.
- *
+ *
* @return the corresponding string name of this IP address.
- * @since Android 1.0
*/
public String getHostName() {
try {
@@ -395,9 +362,8 @@
* address. If a security manager is set, it is checked if the method caller
* is allowed to get the hostname. Otherwise, the textual representation in
* a dotted-quad-notation is returned.
- *
+ *
* @return the fully qualified domain name of this IP address.
- * @since Android 1.0
*/
public String getCanonicalHostName() {
String canonicalName;
@@ -429,14 +395,10 @@
* Gets the local host address if the security policy allows this.
* Otherwise, gets the loopback address which allows this machine to be
* contacted.
- * <p>
- * The current implementation returns always the loopback address.
- * </p>
- *
+ *
* @return the {@code InetAddress} representing the local host.
* @throws UnknownHostException
* if the address lookup fails.
- * @since Android 1.0
*/
public static InetAddress getLocalHost() throws UnknownHostException {
String host = getHostNameImpl();
@@ -453,9 +415,8 @@
/**
* Gets the hashcode of the represented IP address.
- *
+ *
* @return the appropriate hashcode value.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -464,10 +425,9 @@
/**
* Returns whether this address is an IP multicast address or not.
- *
+ *
* @return {@code true} if this address is in the multicast group, {@code
* false} otherwise.
- * @since Android 1.0
*/
public boolean isMulticastAddress() {
return ((ipaddress[0] & 255) >>> 4) == 0xE;
@@ -507,10 +467,12 @@
return element.inetAddress();
}
+ // TODO Clean up NegativeCache; there's no need to maintain the failure message
+
// now try the negative cache
String failedMessage = NegativeCache.getFailedMessage(host);
if (failedMessage != null) {
- throw new UnknownHostException(host + " - " + failedMessage); //$NON-NLS-1$
+ throw new UnknownHostException(host);
}
InetAddress anInetAddress;
@@ -519,7 +481,8 @@
} catch (UnknownHostException e) {
// put the entry in the negative cache
NegativeCache.put(host, e.getMessage());
- throw new UnknownHostException(host + " - " + e.getMessage()); //$NON-NLS-1$
+ // use host for message to match RI, save the cause for giggles
+ throw (UnknownHostException)new UnknownHostException(host).initCause(e);
}
Cache.add(anInetAddress);
@@ -540,17 +503,17 @@
// throws UnknownHostException;
// END android-deleted
- // BEGIN android-changed
+ // BEGIN android-added
/**
* Resolves a host name to its IP addresses. Thread safe.
*/
private static native byte[][] getallbyname(String name,
boolean preferIPv4Stack);
- // END android-changed
+ // END android-added
/**
* Query the IP stack for the host address. The host is in address form.
- *
+ *
* @param addr
* the host address to lookup.
* @throws UnknownHostException
@@ -587,12 +550,12 @@
// TODO Probably not exactly what we want, and also inefficient. Provide native later.
try {
String[] args = host.split("\\.");
-
+
int a = Integer.parseInt(args[0]) << 24;
int b = Integer.parseInt(args[1]) << 16;
int c = Integer.parseInt(args[2]) << 8;
int d = Integer.parseInt(args[3]) ;
-
+
return a | b | c | d;
} catch (Exception ex) {
throw new UnknownHostException(host);
@@ -612,17 +575,17 @@
int b = (hipAddr >> 16) & 0xFF;
int c = (hipAddr >> 8) & 0xFF;
int d = (hipAddr ) & 0xFF;
-
+
return "" + a + "." + b + "." + c + "." + d;
}
// END android-changed
/**
* Query the IP stack for the host address. The host is in string name form.
- *
+ *
* @param name
* the host name to lookup
- * @param preferIPv6Addresses
+ * @param preferIPv6Address
* address preference if underlying platform is V4/V6
* @return InetAddress the host address
* @throws UnknownHostException
@@ -640,7 +603,7 @@
/**
* Gets the host name of the system.
- *
+ *
* @return String the system hostname
*/
// BEGIN android-changed
@@ -665,9 +628,8 @@
/**
* Returns a string containing a concise, human-readable description of this
* IP address.
- *
+ *
* @return the description, as host/address.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -695,8 +657,6 @@
}
}
- // BEGIN android-changed
- // Copied from a newer version of harmony
static class Cache {
private static int maxSize = 5;
@@ -764,7 +724,6 @@
}
}
}
- // END android-changed
/**
* Returns true if the string is a host name, false if it is an IP Address.
@@ -778,10 +737,9 @@
* Returns whether this address is a loopback address or not. This
* implementation returns always {@code false}. Valid IPv4 loopback
* addresses are 127.d.d.d The only valid IPv6 loopback address is ::1.
- *
+ *
* @return {@code true} if this instance represents a loopback address,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isLoopbackAddress() {
return false;
@@ -793,14 +751,11 @@
* <p>
* Valid IPv6 link-local addresses are FE80::0 through to
* FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
- * </p>
* <p>
* There are no valid IPv4 link-local addresses.
- * </p>
- *
+ *
* @return {@code true} if this instance represents a link-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isLinkLocalAddress() {
return false;
@@ -812,14 +767,11 @@
* <p>
* Valid IPv6 site-local addresses are FEC0::0 through to
* FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF.
- * </p>
* <p>
* There are no valid IPv4 site-local addresses.
- * </p>
- *
+ *
* @return {@code true} if this instance represents a site-local address,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isSiteLocalAddress() {
return false;
@@ -832,15 +784,12 @@
* Valid IPv6 link-global multicast addresses are FFxE:/112 where x is a set
* of flags, and the additional 112 bits make up the global multicast
* address space.
- * </p>
* <p>
* Valid IPv4 global multicast addresses are between: 224.0.1.0 to
* 238.255.255.255.
- * </p>
- *
+ *
* @return {@code true} if this instance represents a global multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isMCGlobal() {
return false;
@@ -853,14 +802,11 @@
* Valid IPv6 node-local multicast addresses are FFx1:/112 where x is a set
* of flags, and the additional 112 bits make up the node-local multicast
* address space.
- * </p>
* <p>
* There are no valid IPv4 node-local multicast addresses.
- * </p>
- *
+ *
* @return {@code true} if this instance represents a node-local multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isMCNodeLocal() {
return false;
@@ -873,14 +819,11 @@
* Valid IPv6 link-local multicast addresses are FFx2:/112 where x is a set
* of flags, and the additional 112 bits make up the link-local multicast
* address space.
- * </p>
* <p>
* Valid IPv4 link-local addresses are between: 224.0.0.0 to 224.0.0.255
- * </p>
- *
+ *
* @return {@code true} if this instance represents a link-local multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isMCLinkLocal() {
return false;
@@ -893,15 +836,12 @@
* Valid IPv6 site-local multicast addresses are FFx5:/112 where x is a set
* of flags, and the additional 112 bits make up the site-local multicast
* address space.
- * </p>
* <p>
* Valid IPv4 site-local addresses are between: 239.252.0.0 to
* 239.255.255.255
- * </p>
- *
+ *
* @return {@code true} if this instance represents a site-local multicast
* address, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isMCSiteLocal() {
return false;
@@ -914,15 +854,12 @@
* Valid IPv6 organization-local multicast addresses are FFx8:/112 where x
* is a set of flags, and the additional 112 bits make up the
* organization-local multicast address space.
- * </p>
* <p>
* Valid IPv4 organization-local addresses are between: 239.192.0.0 to
* 239.251.255.255
- * </p>
- *
+ *
* @return {@code true} if this instance represents a organization-local
* multicast address, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isMCOrgLocal() {
return false;
@@ -931,10 +868,9 @@
/**
* Returns whether this is a wildcard address or not. This implementation
* returns always {@code false}.
- *
+ *
* @return {@code true} if this instance represents a wildcard address,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isAnyLocalAddress() {
return false;
@@ -944,7 +880,7 @@
* Tries to reach this {@code InetAddress}. This method first tries to use
* ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
* on port 7 (Echo) of the remote host is established.
- *
+ *
* @param timeout
* timeout in milliseconds before the test fails if no connection
* could be established.
@@ -954,7 +890,6 @@
* if an error occurs during an I/O operation.
* @throws IllegalArgumentException
* if timeout is less than zero.
- * @since Android 1.0
*/
public boolean isReachable(int timeout) throws IOException {
return isReachable(null, 0, timeout);
@@ -964,7 +899,7 @@
* Tries to reach this {@code InetAddress}. This method first tries to use
* ICMP <i>(ICMP ECHO REQUEST)</i>. When first step fails, a TCP connection
* on port 7 (Echo) of the remote host is established.
- *
+ *
* @param netif
* the network interface on which to connection should be
* established.
@@ -979,7 +914,6 @@
* if an error occurs during an I/O operation.
* @throws IllegalArgumentException
* if ttl or timeout is less than zero.
- * @since Android 1.0
*/
public boolean isReachable(NetworkInterface netif, final int ttl,
final int timeout) throws IOException {
@@ -1073,8 +1007,8 @@
// InetAddress.this, addr, ttl, timeout);
// } else {
try {
- threadReached = isReachableByTCP(InetAddress.this,
- addr, timeout);
+ threadReached = isReachableByTCP(addr,
+ InetAddress.this, timeout);
} catch (IOException e) {
// do nothing
}
@@ -1122,7 +1056,7 @@
// int ttl, int timeout) throws IOException {
// return isReachableByMultiThread(netif, ttl, timeout, true);
// }
- //
+ //
// private boolean isReachableByTCPUseMultiThread(NetworkInterface netif,
// int ttl, int timeout) throws IOException {
// return isReachableByMultiThread(netif, ttl, timeout, false);
@@ -1135,10 +1069,10 @@
// define traffic only for parameter
int traffic = 0;
boolean reached = false;
- NETIMPL.createSocket(fd, NetUtil.preferIPv4Stack());
+ NETIMPL.createStreamSocket(fd, NetUtil.preferIPv4Stack());
try {
if (null != source) {
- NETIMPL.bind(fd, 0, source);
+ NETIMPL.bind(fd, source, 0);
}
NETIMPL.connectStreamWithTimeoutSocket(fd, 7, timeout, traffic,
dest);
@@ -1161,18 +1095,15 @@
* exactly 16 bytes. If not, an {@code UnknownHostException} is thrown.
* <p>
* The IP address is not validated by a name service.
- * </p>
* <p>
* The high order byte is {@code ipAddress[0]}.
- * </p>
- *
+ *
* @param ipAddress
* is either a 4 (IPv4) or 16 (IPv6) byte long array.
* @return an {@code InetAddress} instance representing the given IP address
* {@code ipAddress}.
* @throws UnknownHostException
* if the given byte array has no valid length.
- * @since Android 1.0
*/
public static InetAddress getByAddress(byte[] ipAddress)
throws UnknownHostException {
@@ -1187,7 +1118,7 @@
* exactly 16 bytes. If not, an {@code UnknownHostException} is thrown. The
* IP address is not validated by a name service. The high order byte is
* {@code ipAddress[0]}.
- *
+ *
* @param ipAddress
* either a 4 (IPv4) or 16 (IPv6) byte array.
* @param scope_id
@@ -1204,10 +1135,7 @@
for (int i = 0; i < 4; i++) {
copy_address[i] = ipAddress[i];
}
- // BEGIN adnroid-changed
- // Copied from a newer version of harmony
return new Inet4Address(copy_address);
- // END android-changed
}
if (ipAddress != null && ipAddress.length == 16) {
@@ -1224,6 +1152,8 @@
copy_address = ipAddress.clone();
return new Inet6Address(copy_address, scope_id);
}
+
+ // K0339=Invalid IP Address is neither 4 or 16 bytes
throw new UnknownHostException(Msg.getString("K0339")); //$NON-NLS-1$
}
@@ -1251,15 +1181,12 @@
* UnknownHostException} will be thrown.
* <p>
* The host name and IP address are not validated.
- * </p>
* <p>
* The hostname either be a machine alias or a valid IPv6 or IPv4 address
* format.
- * </p>
* <p>
* The high order byte is {@code ipAddress[0]}.
- * </p>
- *
+ *
* @param hostName
* the string representation of hostname or IP address.
* @param ipAddress
@@ -1268,7 +1195,6 @@
* and hostname.
* @throws UnknownHostException
* if the given byte array has no valid length.
- * @since Android 1.0
*/
public static InetAddress getByAddress(String hostName, byte[] ipAddress)
throws UnknownHostException {
@@ -1284,7 +1210,7 @@
* UnknownHostException} is thrown. The host name and IP address are not
* validated. The hostname either be a machine alias or a valid IPv6 or IPv4
* address format. The high order byte is {@code ipAddress[0]}.
- *
+ *
* @param hostName
* string representation of hostname or IP address.
* @param ipAddress
diff --git a/luni/src/main/java/java/net/InetSocketAddress.java b/luni/src/main/java/java/net/InetSocketAddress.java
index 6901053..13c10f2 100644
--- a/luni/src/main/java/java/net/InetSocketAddress.java
+++ b/luni/src/main/java/java/net/InetSocketAddress.java
@@ -23,8 +23,6 @@
/**
* This class represents a socket endpoint described by a IP address and a port
* number. It is a concrete implementation of {@code SocketAddress} for IP.
- *
- * @since Android 1.0
*/
public class InetSocketAddress extends SocketAddress {
@@ -40,10 +38,9 @@
* Creates a socket endpoint with the given port number {@code port} and the
* wildcard address {@code InetAddress.ANY}. The range for valid port numbers
* is between 0 and 65535 inclusive.
- *
+ *
* @param port
* the specified port number to which this socket is bound.
- * @since Android 1.0
*/
public InetSocketAddress(int port) {
this((InetAddress) null, port);
@@ -54,12 +51,11 @@
* {@code address}. The range for valid port numbers is between 0 and 65535
* inclusive. If {@code address} is {@code null} this socket is bound to the
* wildcard address {@code InetAddress.ANY}.
- *
+ *
* @param port
* the specified port number to which this socket is bound.
* @param address
* the specified address to which this socket is bound.
- * @since Android 1.0
*/
public InetSocketAddress(InetAddress address, int port) {
if (port < 0 || port > 65535) {
@@ -79,7 +75,7 @@
* hostname {@code host}. The hostname is tried to be resolved and cannot be
* {@code null}. The range for valid port numbers is between 0 and 65535
* inclusive.
- *
+ *
* @param port
* the specified port number to which this socket is bound.
* @param host
@@ -88,14 +84,13 @@
* if a {@link SecurityManager} is installed and its {@code
* checkConnect()} method does not allow the resolving of the
* host name.
- * @since Android 1.0
*/
public InetSocketAddress(String host, int port) {
this(host, port, true);
}
/*
- * Internal contructor for InetSocketAddress(String, int) and
+ * Internal constructor for InetSocketAddress(String, int) and
* createUnresolved(String, int);
*/
InetSocketAddress(String host, int port, boolean needResolved) {
@@ -126,7 +121,7 @@
* Creates an {@code InetSocketAddress} without trying to resolve the
* hostname into an {@code InetAddress}. The address field is marked as
* unresolved.
- *
+ *
* @param host
* the specified hostname to which this socket is bound.
* @param port
@@ -135,7 +130,6 @@
* @throws IllegalArgumentException
* if the hostname {@code host} is {@code null} or the port is
* not in the range between 0 and 65535.
- * @since Android 1.0
*/
public static InetSocketAddress createUnresolved(String host, int port) {
return new InetSocketAddress(host, port, false);
@@ -143,9 +137,8 @@
/**
* Gets the port number of this socket.
- *
+ *
* @return the socket endpoint port number.
- * @since Android 1.0
*/
public final int getPort() {
return port;
@@ -153,9 +146,8 @@
/**
* Gets the address of this socket.
- *
+ *
* @return the socket endpoint address.
- * @since Android 1.0
*/
public final InetAddress getAddress() {
return addr;
@@ -163,9 +155,8 @@
/**
* Gets the hostname of this socket.
- *
+ *
* @return the socket endpoint hostname.
- * @since Android 1.0
*/
public final String getHostName() {
return (null != addr) ? addr.getHostName() : hostname;
@@ -173,10 +164,9 @@
/**
* Returns whether this socket address is unresolved or not.
- *
+ *
* @return {@code true} if this socket address is unresolved, {@code false}
* otherwise.
- * @since Android 1.0
*/
public final boolean isUnresolved() {
return addr == null;
@@ -185,9 +175,8 @@
/**
* Gets a string representation of this socket included the address and the
* port number.
- *
+ *
* @return the address and port number as a textual representation.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -204,12 +193,11 @@
* Compares two socket endpoints and returns true if they are equal. Two
* socket endpoints are equal if the IP address or the hostname of both are
* equal and they are bound to the same port.
- *
+ *
* @param socketAddr
* the object to be tested for equality.
* @return {@code true} if this socket and the given socket object {@code
* socketAddr} are equal, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public final boolean equals(Object socketAddr) {
@@ -243,9 +231,8 @@
/**
* Gets the hashcode of this socket.
- *
+ *
* @return the appropriate hashcode.
- * @since Android 1.0
*/
@Override
public final int hashCode() {
diff --git a/luni/src/main/java/java/net/JarURLConnection.java b/luni/src/main/java/java/net/JarURLConnection.java
index 11545fa..da39d9c 100644
--- a/luni/src/main/java/java/net/JarURLConnection.java
+++ b/luni/src/main/java/java/net/JarURLConnection.java
@@ -38,15 +38,11 @@
* jar:http://www.example.com/applets/archive.jar!/test.class}</li>
* <li>Directory Entry: {@code
* jar:http://www.example.com/applets/archive.jar!/applets/}</li>
- *
- * @since Android 1.0
*/
public abstract class JarURLConnection extends URLConnection {
/**
* The location part of the represented URL.
- *
- * @since Android 1.0
*/
protected URLConnection jarFileURLConnection;
@@ -60,12 +56,11 @@
/**
* Constructs an instance of {@code JarURLConnection} that refers to the
* specified URL.
- *
+ *
* @param url
* the URL that contains the location to connect to.
* @throws MalformedURLException
* if an invalid URL has been entered.
- * @since Android 1.0
*/
protected JarURLConnection(URL url) throws MalformedURLException {
super(url);
@@ -74,10 +69,12 @@
if ((sepIdx = file.indexOf("!/")) < 0) { //$NON-NLS-1$
throw new MalformedURLException();
}
- if (file.length() == sepIdx + 2) {
+ fileURL = new URL(url.getFile().substring(0,sepIdx)); //$NON-NLS-1$
+ sepIdx += 2;
+ if (file.length() == sepIdx) {
return;
}
- entryName = file.substring(sepIdx + 2, file.length());
+ entryName = file.substring(sepIdx, file.length());
if (null != url.getRef()) {
entryName += "#" + url.getRef(); //$NON-NLS-1$
}
@@ -86,12 +83,11 @@
/**
* Returns all attributes of the {@code JarEntry} referenced by this {@code
* JarURLConnection}.
- *
+ *
* @return the attributes of the referenced {@code JarEntry}.
- * @exception IOException
+ * @throws IOException
* if an I/O exception occurs while retrieving the
* JAR-entries.
- * @since Android 1.0
*/
public Attributes getAttributes() throws java.io.IOException {
JarEntry jEntry = getJarEntry();
@@ -102,12 +98,11 @@
* Returns all certificates of the {@code JarEntry} referenced by this
* {@code JarURLConnection} instance. This method will return {@code null}
* until the {@code InputStream} has been completely verified.
- *
+ *
* @return the certificates of the {@code JarEntry} as an array.
- * @exception IOException
+ * @throws IOException
* if there is an I/O exception occurs while getting the
* {@code JarEntry}.
- * @since Android 1.0
*/
public Certificate[] getCertificates() throws java.io.IOException {
JarEntry jEntry = getJarEntry();
@@ -122,9 +117,8 @@
* Gets the name of the entry referenced by this {@code JarURLConnection}.
* The return value will be {@code null} if this instance refers to a JAR
* file rather than an JAR file entry.
- *
+ *
* @return the {@code JarEntry} name this instance refers to.
- * @since Android 1.0
*/
public String getEntryName() {
return entryName;
@@ -133,12 +127,11 @@
/**
* Gets the {@code JarEntry} object of the entry referenced by this {@code
* JarURLConnection}.
- *
+ *
* @return the referenced {@code JarEntry} object or {@code null} if no
* entry name is specified.
* @throws IOException
* if an error occurs while getting the file or file-entry.
- * @since Android 1.0
*/
public JarEntry getJarEntry() throws IOException {
if (!connected) {
@@ -153,56 +146,44 @@
/**
* Gets the manifest file associated with this JAR-URL.
- *
+ *
* @return the manifest of the referenced JAR-file.
* @throws IOException
* if an error occurs while getting the manifest file.
- * @since Android 1.0
*/
public Manifest getManifest() throws java.io.IOException {
- return getJarFile().getManifest();
+ return (Manifest)getJarFile().getManifest().clone();
}
/**
* Gets the {@code JarFile} object referenced by this {@code
* JarURLConnection}.
- *
+ *
* @return the referenced JarFile object.
- * @exception IOException
+ * @throws IOException
* if an I/O exception occurs while retrieving the JAR-file.
- * @since Android 1.0
*/
public abstract JarFile getJarFile() throws java.io.IOException;
/**
* Gets the URL to the JAR-file referenced by this {@code JarURLConnection}.
- *
+ *
* @return the URL to the JAR-file or {@code null} if there was an error
* retrieving the URL.
- * @since Android 1.0
*/
public URL getJarFileURL() {
- if (fileURL != null) {
- return fileURL;
- }
- try {
- return fileURL = new URL(url.getFile().substring(0,
- url.getFile().indexOf("!/"))); //$NON-NLS-1$
- } catch (MalformedURLException e) {
- return null;
- }
+ return fileURL;
}
/**
* Gets all attributes of the manifest file referenced by this {@code
* JarURLConnection}. If this instance refers to a JAR-file rather than a
* JAR-file entry, {@code null} will be returned.
- *
+ *
* @return the attributes of the manifest file or {@code null}.
- * @exception IOException
+ * @throws IOException
* if an I/O exception occurs while retrieving the {@code
* JarFile}.
- * @since Android 1.0
*/
public Attributes getMainAttributes() throws java.io.IOException {
Manifest m = getJarFile().getManifest();
diff --git a/luni/src/main/java/java/net/MalformedURLException.java b/luni/src/main/java/java/net/MalformedURLException.java
index 386228b..cf8aa46 100644
--- a/luni/src/main/java/java/net/MalformedURLException.java
+++ b/luni/src/main/java/java/net/MalformedURLException.java
@@ -24,7 +24,6 @@
* incorrect specification.
*
* @see URL
- * @since Android 1.0
*/
public class MalformedURLException extends IOException {
@@ -32,8 +31,6 @@
/**
* Constructs a new instance of this class with its walkback filled in.
- *
- * @since Android 1.0
*/
public MalformedURLException() {
super();
@@ -45,7 +42,6 @@
*
* @param detailMessage
* the detail message for this exception instance.
- * @since Android 1.0
*/
public MalformedURLException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/MulticastSocket.java b/luni/src/main/java/java/net/MulticastSocket.java
index cf20890..0b1c99b 100644
--- a/luni/src/main/java/java/net/MulticastSocket.java
+++ b/luni/src/main/java/java/net/MulticastSocket.java
@@ -20,15 +20,14 @@
import java.io.IOException;
import java.util.Enumeration;
-import org.apache.harmony.luni.net.SocketImplProvider;
+import org.apache.harmony.luni.net.PlainDatagramSocketImpl;
import org.apache.harmony.luni.util.Msg;
/**
* This class implements a multicast socket for sending and receiving IP
* multicast datagram packets.
- *
+ *
* @see DatagramSocket
- * @since Android 1.0
*/
public class MulticastSocket extends DatagramSocket {
@@ -39,10 +38,9 @@
/**
* Constructs a multicast socket, bound to any available port on the
* localhost.
- *
+ *
* @throws IOException
* if an error occurs creating or binding the socket.
- * @since Android 1.0
*/
public MulticastSocket() throws IOException {
super();
@@ -52,12 +50,11 @@
/**
* Constructs a multicast socket, bound to the specified port on the
* localhost.
- *
+ *
* @param aPort
* the port to bind on the localhost.
* @throws IOException
* if an error occurs creating or binding the socket.
- * @since Android 1.0
*/
public MulticastSocket(int aPort) throws IOException {
super(aPort);
@@ -67,12 +64,11 @@
/**
* Gets the network address used by this socket. This is useful on
* multihomed machines.
- *
+ *
* @return the address of the network interface through which the datagram
* packets are sent or received.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while getting the interface address.
- * @since Android 1.0
*/
public InetAddress getInterface() throws SocketException {
checkClosedAndBind(false);
@@ -104,12 +100,12 @@
/**
* Gets the network interface used by this socket. This is useful on
* multihomed machines.
- *
+ *
* @return the network interface used by this socket or {@code null} if no
* interface is set.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while getting the interface.
- * @since Android 1.0
+ * @since 1.4
*/
public NetworkInterface getNetworkInterface() throws SocketException {
checkClosedAndBind(false);
@@ -162,11 +158,10 @@
/**
* Gets the time-to-live (TTL) for multicast packets sent on this socket.
- *
+ *
* @return the default value for the time-to-life field.
- * @exception IOException
+ * @throws IOException
* if an error occurs reading the default value.
- * @since Android 1.0
*/
public int getTimeToLive() throws IOException {
checkClosedAndBind(false);
@@ -175,13 +170,12 @@
/**
* Gets the time-to-live (TTL) for multicast packets sent on this socket.
- *
+ *
* @return the default value for the time-to-life field.
- * @exception IOException
+ * @throws IOException
* if an error occurs reading the default value.
* @deprecated Replaced by {@link #getTimeToLive}
* @see #getTimeToLive()
- * @since Android 1.0
*/
@Deprecated
public byte getTTL() throws IOException {
@@ -189,21 +183,15 @@
return impl.getTTL();
}
- @Override
- boolean isMulticastSocket() {
- return true;
- }
-
/**
* Adds this socket to the specified multicast group. A socket must join a
* group before data may be received. A socket may be a member of multiple
* groups but may join any group only once.
- *
+ *
* @param groupAddr
* the multicast group to be joined.
- * @exception IOException
+ * @throws IOException
* if an error occurs while joining a group.
- * @since Android 1.0
*/
public void joinGroup(InetAddress groupAddr) throws IOException {
checkClosedAndBind(false);
@@ -221,19 +209,19 @@
* Adds this socket to the specified multicast group. A socket must join a
* group before data may be received. A socket may be a member of multiple
* groups but may join any group only once.
- *
+ *
* @param groupAddress
* the multicast group to be joined.
* @param netInterface
* the network interface on which the datagram packets will be
* received.
- * @exception IOException
+ * @throws IOException
* if the specified address is not a multicast address.
- * @exception SecurityException
+ * @throws SecurityException
* if the caller is not authorized to join the group.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if no multicast group is specified.
- * @since Android 1.0
+ * @since 1.4
*/
public void joinGroup(SocketAddress groupAddress,
NetworkInterface netInterface) throws IOException {
@@ -271,14 +259,15 @@
/**
* Removes this socket from the specified multicast group.
- *
+ *
* @param groupAddr
* the multicast group to be left.
- * @exception IOException
+ * @throws NullPointerException
+ * if {@code groupAddr} is {@code null}.
+ * @throws IOException
* if the specified group address is not a multicast address.
- * @exception SecurityException
+ * @throws SecurityException
* if the caller is not authorized to leave the group.
- * @since Android 1.0
*/
public void leaveGroup(InetAddress groupAddr) throws IOException {
checkClosedAndBind(false);
@@ -294,19 +283,19 @@
/**
* Removes this socket from the specified multicast group.
- *
+ *
* @param groupAddress
* the multicast group to be left.
* @param netInterface
* the network interface on which the addresses should be
* dropped.
- * @exception IOException
+ * @throws IOException
* if the specified group address is not a multicast address.
- * @exception SecurityException
+ * @throws SecurityException
* if the caller is not authorized to leave the group.
- * @exception IllegalArgumentException
- * if no multicast group is specified.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if {@code groupAddress} is {@code null}.
+ * @since 1.4
*/
public void leaveGroup(SocketAddress groupAddress,
NetworkInterface netInterface) throws IOException {
@@ -344,16 +333,15 @@
/**
* Send the packet on this socket. The packet must satisfy the security
* policy before it may be sent.
- *
+ *
* @param pack
* the {@code DatagramPacket} to send
* @param ttl
* the TTL setting for this transmission, overriding the socket
* default
- * @exception IOException
+ * @throws IOException
* if an error occurs while sending data or setting options.
* @deprecated use {@link #setTimeToLive}.
- * @since Android 1.0
*/
@Deprecated
public void send(DatagramPacket pack, byte ttl) throws IOException {
@@ -384,13 +372,12 @@
* Sets the interface address used by this socket. This allows to send
* multicast packets on a different interface than the default interface of
* the local system. This is useful on multihomed machines.
- *
+ *
* @param addr
* the multicast interface network address to set.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while setting the network interface
* address option.
- * @since Android 1.0
*/
public void setInterface(InetAddress addr) throws SocketException {
checkClosedAndBind(false);
@@ -435,13 +422,13 @@
/**
* Sets the network interface used by this socket. This is useful for
* multihomed machines.
- *
+ *
* @param netInterface
* the multicast network interface to set.
- * @exception SocketException
+ * @throws SocketException
* if an error occurs while setting the network interface
* option.
- * @since Android 1.0
+ * @since 1.4
*/
public void setNetworkInterface(NetworkInterface netInterface)
throws SocketException {
@@ -529,13 +516,12 @@
/**
* Sets the time-to-live (TTL) for multicast packets sent on this socket.
* Valid TTL values are between 0 and 255 inclusive.
- *
+ *
* @param ttl
* the default time-to-live field value for packets sent on this
* socket. {@code 0 <= ttl <= 255}.
- * @exception IOException
+ * @throws IOException
* if an error occurs while setting the TTL option value.
- * @since Android 1.0
*/
public void setTimeToLive(int ttl) throws IOException {
checkClosedAndBind(false);
@@ -548,15 +534,14 @@
/**
* Sets the time-to-live (TTL) for multicast packets sent on this socket.
* Valid TTL values are between 0 and 255 inclusive.
- *
+ *
* @param ttl
* the default time-to-live field value for packets sent on this
* socket: {@code 0 <= ttl <= 255}.
- * @exception IOException
+ * @throws IOException
* if an error occurs while setting the TTL option value.
* @deprecated Replaced by {@link #setTimeToLive}
* @see #setTimeToLive(int)
- * @since Android 1.0
*/
@Deprecated
public void setTTL(byte ttl) throws IOException {
@@ -568,11 +553,10 @@
synchronized void createSocket(int aPort, InetAddress addr)
throws SocketException {
impl = factory != null ? factory.createDatagramSocketImpl()
- : SocketImplProvider.getMulticastSocketImpl();
+ : new PlainDatagramSocketImpl();
impl.create();
try {
- // the required default options are now set in the VM where they
- // should be
+ impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.TRUE);
impl.bind(aPort, addr);
isBound = true;
} catch (SocketException e) {
@@ -585,14 +569,14 @@
* Constructs a {@code MulticastSocket} bound to the host/port specified by
* the {@code SocketAddress}, or an unbound {@code DatagramSocket} if the
* {@code SocketAddress} is {@code null}.
- *
+ *
* @param localAddr
* the local machine address and port to bind to.
* @throws IllegalArgumentException
* if the {@code SocketAddress} is not supported.
* @throws IOException
* if an error occurs creating or binding the socket.
- * @since Android 1.0
+ * @since 1.4
*/
public MulticastSocket(SocketAddress localAddr) throws IOException {
super(localAddr);
@@ -601,12 +585,12 @@
/**
* Gets the state of the {@code SocketOptions.IP_MULTICAST_LOOP}.
- *
+ *
* @return {@code true} if the IP multicast loop is enabled, {@code false}
* otherwise.
* @throws SocketException
* if the socket is closed or the option is invalid.
- * @since Android 1.0
+ * @since 1.4
*/
public boolean getLoopbackMode() throws SocketException {
checkClosedAndBind(false);
@@ -616,13 +600,13 @@
/**
* Sets the {@code SocketOptions.IP_MULTICAST_LOOP}.
- *
+ *
* @param loop
* the value for the socket option socket {@code
* SocketOptions.IP_MULTICAST_LOOP}.
* @throws SocketException
* if the socket is closed or the option is invalid.
- * @since Android 1.0
+ * @since 1.4
*/
public void setLoopbackMode(boolean loop) throws SocketException {
checkClosedAndBind(false);
diff --git a/luni/src/main/java/java/net/NegCacheElement.java b/luni/src/main/java/java/net/NegCacheElement.java
index 7285a14..e166db4 100644
--- a/luni/src/main/java/java/net/NegCacheElement.java
+++ b/luni/src/main/java/java/net/NegCacheElement.java
@@ -18,28 +18,27 @@
/**
* This class is used to hold information about failed host name lookups.
- *
+ *
* @see NegativeCache
- * @since Android 1.0
*/
class NegCacheElement {
// we need the time to figure out when the entry is stale
// BEGIN android-changed
final long nanoTimeAdded = System.nanoTime();
+ // END android-changed
// holds the name of the host for which the lookup failed
final String hostName;
-
+
/**
* Constructor used to set the hostname for the entry for which the lookup
* failed.
- *
+ *
* @param hostName
* name of the host for which the lookup failed.
*/
NegCacheElement(String hostName) {
this.hostName = hostName;
}
- // END android-changed
}
diff --git a/luni/src/main/java/java/net/NegativeCache.java b/luni/src/main/java/java/net/NegativeCache.java
index 58078fc..e66d3f3 100644
--- a/luni/src/main/java/java/net/NegativeCache.java
+++ b/luni/src/main/java/java/net/NegativeCache.java
@@ -25,16 +25,13 @@
/**
* This class is used to maintain the negative name lookup cache, which caches
* host names which could not be resolved, as a security feature.
- *
+ *
* @see NegCacheElement
- * @since Android 1.0
*/
class NegativeCache<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
- // BEGIN android-changed
- // Copied from a newer version of harmony
private static NegativeCache<String, NegCacheElement> negCache;
// maximum number of entries in the cache
@@ -42,13 +39,17 @@
// the loading for the cache
private static final float LOADING = 0.75F;
- // END android-changed
/**
- * Returns the hostname for the cache element.
- *
- * @return hostName name of the host for which the lookup failed.
- * @since Android 1.0
+ * Constructs a negative cache for name lookups.
+ *
+ * @param initialCapacity
+ * the initial size of the cache.
+ * @param loadFactor
+ * the load factor of the backing map.
+ * @param accessOrder
+ * if {@code true} indicates that traversal order should begin
+ * with most recently accessed element.
*/
NegativeCache(int initialCapacity, float loadFactor, boolean accessOrder) {
super(initialCapacity, loadFactor, accessOrder);
@@ -59,10 +60,9 @@
* size has grown beyond the maximum size allowed for the cache. A {@code
* LinkedHashMap} is created such that the least recently used entry is
* deleted.
- *
+ *
* @param eldest
* the map entry which will be deleted if we return {@code true}.
- * @since Android 1.0
*/
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
@@ -72,17 +72,13 @@
/**
* Adds the host name and the corresponding name lookup fail message to the
* cache.
- *
+ *
* @param hostName
* the name of the host for which the lookup failed.
* @param failedMessage
* the message returned when the lookup fails.
- * @since Android 1.0
*/
static synchronized void put(String hostName, String failedMessage) {
- // BEGIN android-note
- // Made synchronized. copied from a newer version of harmony
- // END android-note
checkCacheExists();
negCache.put(hostName, new NegCacheElement(failedMessage));
}
@@ -90,17 +86,13 @@
/**
* Returns the message of the negative cache if the entry has not yet
* expired.
- *
+ *
* @param hostName
* the name of the host for which we look up the entry.
* @return the message which was returned when the host lookup failed if the
* entry has not yet expired.
- * @since Android 1.0
*/
static synchronized String getFailedMessage(String hostName) {
- // BEGIN android-note
- // Made synchronized. copied from a newer version of harmony
- // END android-note
checkCacheExists();
NegCacheElement element = negCache.get(hostName);
if (element != null) {
@@ -130,10 +122,7 @@
}
}
if (element != null) {
- // BEGIN android-changed
- // Copied from a newer version of harmony
return element.hostName;
- // END android-changed
}
return null;
}
@@ -148,13 +137,9 @@
// END android-added
/**
- * This method checks whether the cache was already created and if not
- * creates it.
+ * This method checks if we have created the cache and if not creates it
*/
static synchronized void checkCacheExists() {
- // BEGIN android-note
- // Made synchronized. copied from a newer version of harmony
- // END android-note
if (negCache == null) {
/*
* Create with the access order set so ordering is based on when the
diff --git a/luni/src/main/java/java/net/NetPermission.java b/luni/src/main/java/java/net/NetPermission.java
index e7cca8b..bac9d89 100644
--- a/luni/src/main/java/java/net/NetPermission.java
+++ b/luni/src/main/java/java/net/NetPermission.java
@@ -31,11 +31,9 @@
* <dd>Allows a stream (protocol) handler to be set when constructing an URL
* object</dd>
* </dl>
- * </p>
*
* @see java.security.BasicPermission
* @see SecurityManager
- * @since Android 1.0
*/
public final class NetPermission extends java.security.BasicPermission {
@@ -46,7 +44,6 @@
*
* @param name
* the name of the new NetPermission instance.
- * @since Android 1.0
*/
public NetPermission(String name) {
super(name);
@@ -60,7 +57,6 @@
* the name of the new {@code NetPermission} instance.
* @param actions
* the ignored action string.
- * @since Android 1.0
*/
public NetPermission(String name, String actions) {
super(name, actions);
diff --git a/luni/src/main/java/java/net/NetworkInterface.java b/luni/src/main/java/java/net/NetworkInterface.java
index 68452e6b..091eb9f 100644
--- a/luni/src/main/java/java/net/NetworkInterface.java
+++ b/luni/src/main/java/java/net/NetworkInterface.java
@@ -28,8 +28,6 @@
* interface is defined by its address and a platform dependent name. The class
* provides methods to get all information about the available interfaces of the
* system or to identify the local interface of a joined multicast group.
- *
- * @since Android 1.0
*/
public final class NetworkInterface extends Object {
@@ -115,7 +113,6 @@
* Gets the name associated with this network interface.
*
* @return the name of this {@code NetworkInterface} instance.
- * @since Android 1.0
*/
public String getName() {
return name;
@@ -125,7 +122,6 @@
* Gets a list of addresses bound to this network interface.
*
* @return the address list of the represented network interface.
- * @since Android 1.0
*/
public Enumeration<InetAddress> getInetAddresses() {
/*
@@ -192,7 +188,6 @@
*
* @return the display name of this network interface or the name if the
* display name is not available.
- * @since Android 1.0
*/
public String getDisplayName() {
/*
@@ -217,7 +212,6 @@
* information.
* @throws NullPointerException
* if the given interface's name is {@code null}.
- * @since Android 1.0
*/
public static NetworkInterface getByName(String interfaceName)
throws SocketException {
@@ -244,7 +238,7 @@
/**
* Gets the specific network interface according to the given address.
- *
+ *
* @param address
* the address to identify the searched network interface.
* @return the network interface with the specified address if one exists or
@@ -254,7 +248,6 @@
* information.
* @throws NullPointerException
* if the given interface address is invalid.
- * @since Android 1.0
*/
public static NetworkInterface getByInetAddress(InetAddress address)
throws SocketException {
@@ -302,7 +295,6 @@
* @throws SocketException
* if an error occurs while getting the network interface
* information.
- * @since Android 1.0
*/
public static Enumeration<NetworkInterface> getNetworkInterfaces()
throws SocketException {
@@ -343,7 +335,6 @@
* @return {@code true} if the specified object is equal to this {@code
* NetworkInterface}, {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object obj) {
@@ -412,7 +403,6 @@
* generated using this name.
*
* @return the hashcode value for this {@code NetworkInterface} instance.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -427,7 +417,6 @@
* network interface.
*
* @return the textual representation for this network interface.
- * @since Android 1.0
*/
@Override
public String toString() {
diff --git a/luni/src/main/java/java/net/NoRouteToHostException.java b/luni/src/main/java/java/net/NoRouteToHostException.java
index 042ccd4..f2e2c36 100644
--- a/luni/src/main/java/java/net/NoRouteToHostException.java
+++ b/luni/src/main/java/java/net/NoRouteToHostException.java
@@ -21,8 +21,6 @@
* The {@code NoRouteToHostException} will be thrown while attempting to connect
* to a remote host but the host cannot be reached for instance because of a
* badly configured router or a blocking firewall.
- *
- * @since Android 1.0
*/
public class NoRouteToHostException extends SocketException {
@@ -30,8 +28,6 @@
/**
* Constructs a new instance of this exception with its walkback filled in.
- *
- * @since Android 1.0
*/
public NoRouteToHostException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public NoRouteToHostException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/PasswordAuthentication.java b/luni/src/main/java/java/net/PasswordAuthentication.java
index 324f878..735810d 100644
--- a/luni/src/main/java/java/net/PasswordAuthentication.java
+++ b/luni/src/main/java/java/net/PasswordAuthentication.java
@@ -20,9 +20,8 @@
/**
* This immutable class is a data structure that encapsulates username and
* password which is used by the {@code Authenticator} class.
- *
+ *
* @see Authenticator
- * @since Android 1.0
*/
public final class PasswordAuthentication {
@@ -38,7 +37,6 @@
* the username to store.
* @param password
* the associated password to store.
- * @since Android 1.0
*/
public PasswordAuthentication(String userName, char[] password) {
this.userName = userName;
@@ -51,7 +49,6 @@
* longer needed.
*
* @return the copied password.
- * @since Android 1.0
*/
public char[] getPassword() {
return password.clone();
@@ -61,7 +58,6 @@
* Gets the username stored by this instance.
*
* @return the stored username.
- * @since Android 1.0
*/
public String getUserName() {
return userName;
diff --git a/luni/src/main/java/java/net/PortUnreachableException.java b/luni/src/main/java/java/net/PortUnreachableException.java
index 973a978..2b5b25b 100644
--- a/luni/src/main/java/java/net/PortUnreachableException.java
+++ b/luni/src/main/java/java/net/PortUnreachableException.java
@@ -27,8 +27,6 @@
/**
* Constructs a new instance of this class with its walkback filled in.
- *
- * @since Android 1.0
*/
public PortUnreachableException() {
}
@@ -39,7 +37,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public PortUnreachableException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/ProtocolException.java b/luni/src/main/java/java/net/ProtocolException.java
index f32dedc..ebbdc44 100644
--- a/luni/src/main/java/java/net/ProtocolException.java
+++ b/luni/src/main/java/java/net/ProtocolException.java
@@ -21,8 +21,6 @@
* Signals that either a connection attempt to a socket of the wrong type, the
* application of an unsupported operation or that a general error in the
* underlying protocol has occurred.
- *
- * @since Android 1.0
*/
public class ProtocolException extends java.io.IOException {
@@ -30,8 +28,6 @@
/**
* Constructs a new instance of this class with its walkback filled in.
- *
- * @since Android 1.0
*/
public ProtocolException() {
super();
@@ -43,7 +39,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public ProtocolException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/Proxy.java b/luni/src/main/java/java/net/Proxy.java
index df0383d..3442339 100644
--- a/luni/src/main/java/java/net/Proxy.java
+++ b/luni/src/main/java/java/net/Proxy.java
@@ -25,8 +25,6 @@
* <li>DIRECT</li>
* <li>HTTP</li>
* <li>SOCKS</li></ul
- *
- * @since Android 1.0
*/
public class Proxy {
@@ -34,8 +32,6 @@
* Represents the proxy type setting {@code Proxy.Type.DIRECT}. It tells
* protocol handlers that there is no proxy to be used. The address is set
* to {@code null}.
- *
- * @since Android 1.0
*/
public static final Proxy NO_PROXY = new Proxy();
@@ -58,7 +54,6 @@
* if the parameter {@code type} is set to {@code
* Proxy.Type.DIRECT} or the value for {@code SocketAddress} is
* {@code null}.
- * @since Android 1.0
*/
public Proxy(Proxy.Type type, SocketAddress sa) {
/*
@@ -86,7 +81,6 @@
* Gets the type of this {@code Proxy} instance.
*
* @return the stored proxy type.
- * @since Android 1.0
*/
public Proxy.Type type() {
return type;
@@ -97,7 +91,6 @@
*
* @return the stored proxy address or {@code null} if the proxy type is
* {@code DIRECT}.
- * @since Android 1.0
*/
public SocketAddress address() {
return address;
@@ -107,9 +100,8 @@
* Gets a textual representation of this {@code Proxy} instance. The string
* includes the two parts {@code type.toString()} and {@code
* address.toString()} if {@code address} is not {@code null}.
- *
+ *
* @return the representing string of this proxy.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -131,7 +123,6 @@
* @return {@code true} if the given object represents the same {@code
* Proxy} as this instance, {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public final boolean equals(Object obj) {
@@ -150,7 +141,6 @@
* Gets the hashcode for this {@code Proxy} instance.
*
* @return the hashcode value for this Proxy instance.
- * @since Android 1.0
*/
@Override
public final int hashCode() {
@@ -165,8 +155,6 @@
/**
* {@code Enum} class for the proxy type. Possible options are {@code
* DIRECT}, {@code HTTP} and {@code SOCKS}.
- *
- * @since Android 1.0
*/
public enum Type {
/**
diff --git a/luni/src/main/java/java/net/ProxySelector.java b/luni/src/main/java/java/net/ProxySelector.java
index aad4bcc..334ea1e 100644
--- a/luni/src/main/java/java/net/ProxySelector.java
+++ b/luni/src/main/java/java/net/ProxySelector.java
@@ -24,8 +24,6 @@
* can be set as default by calling the {@code setDefault()} method. If a
* connection can't be established, the caller should notify the proxy selector
* by invoking the {@code connectFailed()} method.
- *
- * @since Android 1.0
*/
public abstract class ProxySelector {
@@ -47,8 +45,6 @@
/**
* Creates a new {@code ProxySelector} instance.
- *
- * @since Android 1.0
*/
public ProxySelector() {
super();
@@ -61,7 +57,6 @@
* @throws SecurityException
* if a security manager is installed but it doesn't have the
* NetPermission("getProxySelector").
- * @since Android 1.0
*/
public static ProxySelector getDefault() {
SecurityManager sm = System.getSecurityManager();
@@ -83,7 +78,6 @@
* @throws SecurityException
* if a security manager is installed but it doesn't have the
* NetPermission("setProxySelector").
- * @since Android 1.0
*/
public static void setDefault(ProxySelector selector) {
SecurityManager sm = System.getSecurityManager();
@@ -101,14 +95,14 @@
* <li>https URI stands for https connection.</li>
* <li>ftp URI stands for ftp connection.</li>
* <li>socket:://ip:port URI stands for tcp client sockets connection.</li>
- * </p>
- *
+ *
* @param uri
* the target URI object.
* @return a list containing all applicable proxies. If no proxy is
* available, the list contains only the {@code Proxy.NO_PROXY}
* element.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if {@code uri} is {@code null}.
*/
public abstract List<Proxy> select(URI uri);
@@ -125,8 +119,9 @@
* @param ioe
* the exception which was thrown during connection
* establishment.
+ * @throws IllegalArgumentException
+ * if any argument is {@code null}.
* @see #select(URI)
- * @since Android 1.0
*/
public abstract void connectFailed(URI uri, SocketAddress sa,
IOException ioe);
diff --git a/luni/src/main/java/java/net/ProxySelectorImpl.java b/luni/src/main/java/java/net/ProxySelectorImpl.java
index 79ce0cf..fa8d049 100644
--- a/luni/src/main/java/java/net/ProxySelectorImpl.java
+++ b/luni/src/main/java/java/net/ProxySelectorImpl.java
@@ -30,9 +30,8 @@
/**
* Default implementation for {@code ProxySelector}.
- *
- * @since Android 1.0
*/
+@SuppressWarnings("unchecked")
class ProxySelectorImpl extends ProxySelector {
private static final int HTTP_PROXY_PORT = 80;
@@ -239,7 +238,7 @@
*/
private boolean isNonProxyHost(String host, String nonProxyHosts) {
// nonProxyHosts is not set
- if (null == nonProxyHosts) {
+ if (null == host || null == nonProxyHosts) {
return false;
}
// Construct regex expression of nonProxyHosts
diff --git a/luni/src/main/java/java/net/ResponseCache.java b/luni/src/main/java/java/net/ResponseCache.java
index e7a0aca..427b63d 100644
--- a/luni/src/main/java/java/net/ResponseCache.java
+++ b/luni/src/main/java/java/net/ResponseCache.java
@@ -28,24 +28,20 @@
* getDefault()}. If {@code URLConnection#useCaches} is set, {@code
* URLConnection} class will use {@code ResponseCache} to store and get
* resources.
- * </p>
* <p>
* Whether the resource is cached depends on the implementation of {@code
* ResponseCache}. If so, a {@code CacheResponse} is returned from which the
* stream handler reads. If the stream handler fails to get a resource from the
* cache, it must get the resource from its original location.
- * </p>
* <p>
* To write to the cache, the protocol handlers call {@code put()}, upon which a
* {@code CacheRequest} is supplied to which the resources are written.
- * </p>
- *
+ *
* @see #put(URI, URLConnection)
* @see CacheRequest
* @see CacheResponse
* @see URLConnection
* @see URLStreamHandler
- * @since Android 1.0
*/
public abstract class ResponseCache {
@@ -92,8 +88,6 @@
/**
* Creates a new instance of this class.
- *
- * @since Android 1.0
*/
public ResponseCache() {
super();
@@ -106,7 +100,6 @@
* @throws SecurityException
* if a security manager is installed but it doesn't have the
* {@code NetPermission("getResponseCache")}.
- * @since Android 1.0
*/
public static ResponseCache getDefault() {
checkGetResponseCachePermission();
@@ -126,7 +119,6 @@
* @throws SecurityException
* if a security manager is installed but it doesn't have the
* {@code NetPermission("setResponseCache")}.
- * @since Android 1.0
*/
public static void setDefault(ResponseCache responseCache) {
checkSetResponseCachePermission();
@@ -149,7 +141,6 @@
* if an I/O error occurs while getting the cached data.
* @throws IllegalArgumentException
* if any one of the parameters is set to {@code null}.
- * @since Android 1.0
*/
public abstract CacheResponse get(URI uri, String rqstMethod,
Map<String, List<String>> rqstHeaders) throws IOException;
@@ -171,7 +162,6 @@
* if an I/O error occurs while adding the resource.
* @throws IllegalArgumentException
* if any one of the parameters is set to {@code null}.
- * @since Android 1.0
*/
public abstract CacheRequest put(URI uri, URLConnection conn)
throws IOException;
diff --git a/luni/src/main/java/java/net/SecureCacheResponse.java b/luni/src/main/java/java/net/SecureCacheResponse.java
index fff6b82..0031b3a 100644
--- a/luni/src/main/java/java/net/SecureCacheResponse.java
+++ b/luni/src/main/java/java/net/SecureCacheResponse.java
@@ -27,14 +27,11 @@
* protocol like TLS or SSL.
*
* @see ResponseCache
- * @since Android 1.0
*/
public abstract class SecureCacheResponse extends CacheResponse {
/**
* Creates a new instance of this class.
- *
- * @since Android 1.0
*/
public SecureCacheResponse() {
super();
@@ -45,7 +42,6 @@
* to retrieve the network resource.
*
* @return the cipher suite string.
- * @since Android 1.0
*/
public abstract String getCipherSuite();
@@ -57,7 +53,6 @@
*
* @return the certificate chain that was sent to the server. If no
* certificate chain was sent, the method returns {@code null}.
- * @since Android 1.0
*/
public abstract List<Certificate> getLocalCertificateChain();
@@ -71,7 +66,6 @@
* @return the server's certificate chain.
* @throws SSLPeerUnverifiedException
* if the peer is unverified.
- * @since Android 1.0
*/
public abstract List<Certificate> getServerCertificateChain()
throws SSLPeerUnverifiedException;
@@ -84,7 +78,6 @@
* @return a principal object representing the server's principal.
* @throws SSLPeerUnverifiedException
* if the peer is unverified.
- * @since Android 1.0
*/
public abstract Principal getPeerPrincipal()
throws SSLPeerUnverifiedException;
@@ -97,7 +90,6 @@
* @return the local principal object being sent to the server. Returns an
* {@code X500Principal} object for X509-based cipher suites. If no
* principal was sent, it returns {@code null}.
- * @since Android 1.0
*/
public abstract Principal getLocalPrincipal();
}
diff --git a/luni/src/main/java/java/net/ServerSocket.java b/luni/src/main/java/java/net/ServerSocket.java
index 5f7e079..fc3ad10 100644
--- a/luni/src/main/java/java/net/ServerSocket.java
+++ b/luni/src/main/java/java/net/ServerSocket.java
@@ -20,9 +20,8 @@
import java.io.IOException;
import java.nio.channels.ServerSocketChannel;
-import org.apache.harmony.luni.net.SocketImplProvider;
+import org.apache.harmony.luni.net.PlainServerSocketImpl;
import org.apache.harmony.luni.platform.Platform;
-
import org.apache.harmony.luni.util.Msg;
/**
@@ -30,8 +29,6 @@
* connections. A {@code ServerSocket} handles the requests and sends back an
* appropriate reply. The actual tasks that a server socket must accomplish are
* implemented by an internal {@code SocketImpl} instance.
- *
- * @since Android 1.0
*/
public class ServerSocket {
@@ -44,7 +41,7 @@
private boolean isBound;
private boolean isClosed;
-
+
static {
Platform.getNetworkSystem().oneTimeInitialization(true);
}
@@ -52,14 +49,13 @@
/**
* Constructs a new {@code ServerSocket} instance which is not bound to any
* port. The default number of pending connections may be backlogged.
- *
+ *
* @throws IOException
* if an error occurs while creating the server socket.
- * @since Android 1.0
*/
public ServerSocket() throws IOException {
impl = factory != null ? factory.createSocketImpl()
- : SocketImplProvider.getServerSocketImpl();
+ : new PlainServerSocketImpl();
}
/**
@@ -81,12 +77,11 @@
* Constructs a new {@code ServerSocket} instance bound to the nominated
* port on the localhost. The default number of pending connections may be
* backlogged. If {@code aport} is 0 a free port is assigned to the socket.
- *
+ *
* @param aport
* the port number to listen for connection requests on.
* @throws IOException
* if an error occurs while creating the server socket.
- * @since Android 1.0
*/
public ServerSocket(int aport) throws IOException {
this(aport, defaultBacklog(), InetAddress.ANY);
@@ -97,7 +92,7 @@
* port on the localhost. The number of pending connections that may be
* backlogged is specified by {@code backlog}. If {@code aport} is 0 a free
* port is assigned to the socket.
- *
+ *
* @param aport
* the port number to listen for connection requests on.
* @param backlog
@@ -105,7 +100,6 @@
* will be rejected.
* @throws IOException
* if an error occurs while creating the server socket.
- * @since Android 1.0
*/
public ServerSocket(int aport, int backlog) throws IOException {
this(aport, backlog, InetAddress.ANY);
@@ -116,7 +110,7 @@
* local host address and port. The number of pending connections that may
* be backlogged is specified by {@code backlog}. If {@code aport} is 0 a
* free port is assigned to the socket.
- *
+ *
* @param aport
* the port number to listen for connection requests on.
* @param localAddr
@@ -126,14 +120,13 @@
* will be rejected.
* @throws IOException
* if an error occurs while creating the server socket.
- * @since Android 1.0
*/
public ServerSocket(int aport, int backlog, InetAddress localAddr)
throws IOException {
super();
checkListen(aport);
impl = factory != null ? factory.createSocketImpl()
- : SocketImplProvider.getServerSocketImpl();
+ : new PlainServerSocketImpl();
InetAddress addr = localAddr == null ? InetAddress.ANY : localAddr;
synchronized (this) {
@@ -154,11 +147,10 @@
* Waits for an incoming request and blocks until the connection is opened.
* This method returns a socket object representing the just opened
* connection.
- *
+ *
* @return the connection representing socket.
* @throws IOException
* if an error occurs while accepting a new connection.
- * @since Android 1.0
*/
public Socket accept() throws IOException {
checkClosedAndCreate(false);
@@ -190,10 +182,9 @@
* Checks whether the server may listen for connection requests on {@code
* aport}. Throws an exception if the port is outside the valid range
* {@code 0 <= aport <= 65535 }or does not satisfy the security policy.
- *
+ *
* @param aPort
* the candidate port to listen on.
- * @since Android 1.0
*/
void checkListen(int aPort) {
if (aPort < 0 || aPort > 65535) {
@@ -208,10 +199,9 @@
/**
* Closes this server socket and its implementation. Any attempt to connect
* to this socket thereafter will fail.
- *
+ *
* @throws IOException
* if an error occurs while closing this socket.
- * @since Android 1.0
*/
public void close() throws IOException {
isClosed = true;
@@ -222,7 +212,7 @@
* Answer the default number of pending connections on a server socket. If
* the backlog value maximum is reached, any subsequent incoming request is
* rejected.
- *
+ *
* @return int the default number of pending connection requests
*/
static int defaultBacklog() {
@@ -232,9 +222,8 @@
/**
* Gets the local IP address of this server socket or {@code null} if the
* socket is unbound. This is useful for multihomed hosts.
- *
+ *
* @return the local address of this server socket.
- * @since Android 1.0
*/
public InetAddress getInetAddress() {
if (!isBound()) {
@@ -246,9 +235,8 @@
/**
* Gets the local port of this server socket or {@code -1} if the socket is
* unbound.
- *
+ *
* @return the local port this server is listening on.
- * @since Android 1.0
*/
public int getLocalPort() {
if (!isBound()) {
@@ -260,11 +248,10 @@
/**
* Gets the timeout period of this server socket. This is the time the
* server will wait listening for accepted connections before exiting.
- *
+ *
* @return the listening timeout value of this server socket.
* @throws IOException
* if the option cannot be retrieved.
- * @since Android 1.0
*/
public synchronized int getSoTimeout() throws IOException {
if (!isCreated) {
@@ -287,13 +274,12 @@
/**
* Invokes the server socket implementation to accept a connection on the
* given socket {@code aSocket}.
- *
+ *
* @param aSocket
* the concrete {@code SocketImpl} to accept the connection
* request on.
* @throws IOException
* if the connection cannot be accepted.
- * @since Android 1.0
*/
protected final void implAccept(Socket aSocket) throws IOException {
impl.accept(aSocket.impl);
@@ -304,13 +290,12 @@
* Sets the server socket implementation factory of this instance. This
* method may only be invoked with sufficient security privilege and only
* once during the application lifetime.
- *
+ *
* @param aFactory
* the streaming socket factory to be used for further socket
* instantiations.
* @throws IOException
* if the factory could not be set or is already set.
- * @since Android 1.0
*/
public static synchronized void setSocketFactory(SocketImplFactory aFactory)
throws IOException {
@@ -328,12 +313,11 @@
* Sets the timeout period of this server socket. This is the time the
* server will wait listening for accepted connections before exiting. This
* value must be a positive number.
- *
+ *
* @param timeout
* the listening timeout value of this server socket.
* @throws SocketException
* if an error occurs while setting the option.
- * @since Android 1.0
*/
public synchronized void setSoTimeout(int timeout) throws SocketException {
checkClosedAndCreate(true);
@@ -347,9 +331,8 @@
* Returns a textual representation of this server socket including the
* address, port and the state. The port field is set to {@code 0} if there
* is no connection to the server socket.
- *
+ *
* @return the textual socket representation.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -371,7 +354,7 @@
* number of pending connections may be backlogged. If the {@code localAddr}
* is set to {@code null} the socket will be bound to an available local
* address on any free port of the system.
- *
+ *
* @param localAddr
* the local address and port to bind on.
* @throws IllegalArgumentException
@@ -379,7 +362,6 @@
* @throws IOException
* if the socket is already bound or a problem occurs during
* binding.
- * @since Android 1.0
*/
public void bind(SocketAddress localAddr) throws IOException {
bind(localAddr, defaultBacklog());
@@ -391,7 +373,7 @@
* available local address on any free port of the system. The value for
* {@code backlog} must e greater than {@code 0} otherwise the default value
* will be used.
- *
+ *
* @param localAddr
* the local machine address and port to bind on.
* @param backlog
@@ -402,7 +384,6 @@
* @throws IOException
* if the socket is already bound or a problem occurs during
* binding.
- * @since Android 1.0
*/
public void bind(SocketAddress localAddr, int backlog) throws IOException {
checkClosedAndCreate(true);
@@ -443,9 +424,8 @@
/**
* Gets the local socket address of this server socket or {@code null} if
* the socket is unbound. This is useful on multihomed hosts.
- *
+ *
* @return the local socket address and port this socket is bound to.
- * @since Android 1.0
*/
public SocketAddress getLocalSocketAddress() {
if (!isBound()) {
@@ -457,9 +437,8 @@
/**
* Returns whether this server socket is bound to a local address and port
* or not.
- *
+ *
* @return {@code true} if this socket is bound, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isBound() {
return isBound;
@@ -467,9 +446,8 @@
/**
* Returns whether this server socket is closed or not.
- *
+ *
* @return {@code true} if this socket is closed, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isClosed() {
return isClosed;
@@ -504,12 +482,11 @@
/**
* Sets the value for the socket option {@code SocketOptions.SO_REUSEADDR}.
- *
+ *
* @param reuse
* the socket option setting.
* @throws SocketException
* if an error occurs while setting the option value.
- * @since Android 1.0
*/
public void setReuseAddress(boolean reuse) throws SocketException {
checkClosedAndCreate(true);
@@ -519,11 +496,10 @@
/**
* Gets the value of the socket option {@code SocketOptions.SO_REUSEADDR}.
- *
+ *
* @return {@code true} if the option is enabled, {@code false} otherwise.
* @throws SocketException
* if an error occurs while reading the option value.
- * @since Android 1.0
*/
public boolean getReuseAddress() throws SocketException {
checkClosedAndCreate(true);
@@ -534,13 +510,12 @@
/**
* Sets the server socket receive buffer size {@code
* SocketOptions.SO_RCVBUF}.
- *
+ *
* @param size
* the buffer size in bytes.
* @throws SocketException
* if an error occurs while setting the size or the size is
* invalid.
- * @since Android 1.0
*/
public void setReceiveBufferSize(int size) throws SocketException {
checkClosedAndCreate(true);
@@ -553,11 +528,10 @@
/**
* Gets the value for the receive buffer size socket option {@code
* SocketOptions.SO_RCVBUF}.
- *
+ *
* @return the receive buffer size of this socket.
* @throws SocketException
* if an error occurs while reading the option value.
- * @since Android 1.0
*/
public int getReceiveBufferSize() throws SocketException {
checkClosedAndCreate(true);
@@ -568,9 +542,8 @@
* Gets the related channel if this instance was created by a
* {@code ServerSocketChannel}. The current implementation returns always {@code
* null}.
- *
+ *
* @return the related {@code ServerSocketChannel} if any.
- * @since Android 1.0
*/
public ServerSocketChannel getChannel() {
return null;
@@ -580,8 +553,7 @@
* Sets performance preferences for connection time, latency and bandwidth.
* <p>
* This method does currently nothing.
- * </p>
- *
+ *
* @param connectionTime
* the value representing the importance of a short connecting
* time.
@@ -589,7 +561,6 @@
* the value representing the importance of low latency.
* @param bandwidth
* the value representing the importance of high bandwidth.
- * @since Android 1.0
*/
public void setPerformancePreferences(int connectionTime, int latency,
int bandwidth) {
diff --git a/luni/src/main/java/java/net/Socket.java b/luni/src/main/java/java/net/Socket.java
index b29b965..97bfc2e 100644
--- a/luni/src/main/java/java/net/Socket.java
+++ b/luni/src/main/java/java/net/Socket.java
@@ -24,15 +24,13 @@
import java.security.AccessController;
import org.apache.harmony.luni.net.NetUtil;
-import org.apache.harmony.luni.net.SocketImplProvider;
+import org.apache.harmony.luni.net.PlainSocketImpl;
import org.apache.harmony.luni.platform.Platform;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
/**
* Provides a client-side TCP socket.
- *
- * @since Android 1.0
*/
public class Socket {
@@ -66,7 +64,7 @@
static final int TCP_NODELAY = 4;
static final int FLAG_SHUTDOWN = 8;
-
+
static {
Platform.getNetworkSystem().oneTimeInitialization(true);
}
@@ -75,14 +73,13 @@
* Creates a new unconnected socket. When a SocketImplFactory is defined it
* creates the internal socket implementation, otherwise the default socket
* implementation will be used for this socket.
- *
+ *
* @see SocketImplFactory
* @see SocketImpl
- * @since Android 1.0
*/
public Socket() {
impl = factory != null ? factory.createSocketImpl()
- : SocketImplProvider.getSocketImpl();
+ : new PlainSocketImpl();
}
/**
@@ -95,8 +92,7 @@
* proxy server: <br>
* {@code Socket sock = new Socket(new Proxy(Proxy.Type.SOCKS, new
* InetSocketAddress("test.domain.org", 2130)));}
- * </p>
- *
+ *
* @param proxy
* the specified proxy for this socket.
* @throws IllegalArgumentException
@@ -107,7 +103,6 @@
* connect to the given proxy.
* @see SocketImplFactory
* @see SocketImpl
- * @since Android 1.0
*/
public Socket(Proxy proxy) {
if (null == proxy || Proxy.Type.HTTP == proxy.type()) {
@@ -127,7 +122,7 @@
checkConnectPermission(host, port);
}
impl = factory != null ? factory.createSocketImpl()
- : SocketImplProvider.getSocketImpl(proxy);
+ : new PlainSocketImpl(proxy);
this.proxy = proxy;
}
@@ -135,7 +130,7 @@
* Creates a new streaming socket connected to the target host specified by
* the parameters {@code dstName} and {@code dstPort}. The socket is bound
* to any available port on the local host.
- *
+ *
* @param dstName
* the target host name or IP address to connect to.
* @param dstPort
@@ -147,7 +142,6 @@
* @throws SecurityException
* if a security manager exists and it denies the permission to
* connect to the given address and port.
- * @since Android 1.0
*/
public Socket(String dstName, int dstPort) throws UnknownHostException,
IOException {
@@ -162,9 +156,9 @@
* the parameters {@code dstName} and {@code dstPort}. On the local endpoint
* the socket is bound to the given address {@code localAddress} on port
* {@code localPort}.
- *
+ *
* If {@code host} is {@code null} a loopback address is used to connect to.
- *
+ *
* @param dstName
* the target host name or IP address to connect to.
* @param dstPort
@@ -180,7 +174,6 @@
* @throws SecurityException
* if a security manager exists and it denies the permission to
* connect to the given address and port.
- * @since Android 1.0
*/
public Socket(String dstName, int dstPort, InetAddress localAddress,
int localPort) throws IOException {
@@ -194,7 +187,7 @@
* Creates a new streaming or datagram socket connected to the target host
* specified by the parameters {@code hostName} and {@code port}. The socket
* is bound to any available port on the local host.
- *
+ *
* @param hostName
* the target host name or IP address to connect to.
* @param port
@@ -212,7 +205,6 @@
* @deprecated Use {@code Socket(String, int)} instead of this for streaming
* sockets or an appropriate constructor of {@code
* DatagramSocket} for UDP transport.
- * @since Android 1.0
*/
@Deprecated
public Socket(String hostName, int port, boolean streaming)
@@ -227,7 +219,7 @@
* Creates a new streaming socket connected to the target host specified by
* the parameters {@code dstAddress} and {@code dstPort}. The socket is
* bound to any available port on the local host.
- *
+ *
* @param dstAddress
* the target host address to connect to.
* @param dstPort
@@ -237,7 +229,6 @@
* @throws SecurityException
* if a security manager exists and it denies the permission to
* connect to the given address and port.
- * @since Android 1.0
*/
public Socket(InetAddress dstAddress, int dstPort) throws IOException {
this();
@@ -250,7 +241,7 @@
* the parameters {@code dstAddress} and {@code dstPort}. On the local
* endpoint the socket is bound to the given address {@code localAddress} on
* port {@code localPort}.
- *
+ *
* @param dstAddress
* the target host address to connect to.
* @param dstPort
@@ -264,7 +255,6 @@
* @throws SecurityException
* if a security manager exists and it denies the permission to
* connect to the given address and port.
- * @since Android 1.0
*/
public Socket(InetAddress dstAddress, int dstPort,
InetAddress localAddress, int localPort) throws IOException {
@@ -277,7 +267,7 @@
* Creates a new streaming or datagram socket connected to the target host
* specified by the parameters {@code addr} and {@code port}. The socket is
* bound to any available port on the local host.
- *
+ *
* @param addr
* the Internet address to connect to.
* @param port
@@ -293,7 +283,6 @@
* @deprecated Use {@code Socket(InetAddress, int)} instead of this for
* streaming sockets or an appropriate constructor of {@code
* DatagramSocket} for UDP transport.
- * @since Android 1.0
*/
@Deprecated
public Socket(InetAddress addr, int port, boolean streaming)
@@ -305,12 +294,11 @@
/**
* Creates an unconnected socket with the given socket implementation.
- *
+ *
* @param anImpl
* the socket implementation to be used.
* @throws SocketException
* if an error occurs while creating the socket.
- * @since Android 1.0
*/
protected Socket(SocketImpl anImpl) throws SocketException {
impl = anImpl;
@@ -319,7 +307,7 @@
/**
* Checks whether the connection destination satisfies the security policy
* and the validity of the port range.
- *
+ *
* @param destAddr
* the destination host address.
* @param dstPort
@@ -336,7 +324,7 @@
/**
* Checks whether the connection destination satisfies the security policy.
- *
+ *
* @param hostname
* the destination hostname.
* @param dstPort
@@ -352,10 +340,9 @@
/**
* Closes the socket. It is not possible to reconnect or rebind to this
* socket thereafter which means a new socket instance has to be created.
- *
+ *
* @throws IOException
* if an error occurs while closing the socket.
- * @since Android 1.0
*/
public synchronized void close() throws IOException {
isClosed = true;
@@ -364,10 +351,9 @@
/**
* Gets the IP address of the target host this socket is connected to.
- *
+ *
* @return the IP address of the connected target host or {@code null} if
* this socket is not yet connected.
- * @since Android 1.0
*/
public InetAddress getInetAddress() {
if (!isConnected()) {
@@ -378,12 +364,11 @@
/**
* Gets an input stream to read data from this socket.
- *
+ *
* @return the byte-oriented input stream.
* @throws IOException
* if an error occurs while creating the input stream or the
* socket is in an invalid state.
- * @since Android 1.0
*/
public InputStream getInputStream() throws IOException {
checkClosedAndCreate(false);
@@ -395,13 +380,12 @@
/**
* Gets the setting of the socket option {@code SocketOptions.SO_KEEPALIVE}.
- *
+ *
* @return {@code true} if the {@code SocketOptions.SO_KEEPALIVE} is
* enabled, {@code false} otherwise.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#SO_KEEPALIVE
- * @since Android 1.0
*/
public boolean getKeepAlive() throws SocketException {
checkClosedAndCreate(true);
@@ -411,10 +395,9 @@
/**
* Gets the local IP address this socket is bound to.
- *
+ *
* @return the local IP address of this socket or {@code InetAddress.ANY} if
* the socket is unbound.
- * @since Android 1.0
*/
public InetAddress getLocalAddress() {
if (!isBound()) {
@@ -426,10 +409,9 @@
/**
* Gets the local port this socket is bound to.
- *
+ *
* @return the local port of this socket or {@code -1} if the socket is
* unbound.
- * @since Android 1.0
*/
public int getLocalPort() {
if (!isBound()) {
@@ -440,12 +422,11 @@
/**
* Gets an output stream to write data into this socket.
- *
+ *
* @return the byte-oriented output stream.
* @throws IOException
* if an error occurs while creating the output stream or the
* socket is in an invalid state.
- * @since Android 1.0
*/
public OutputStream getOutputStream() throws IOException {
checkClosedAndCreate(false);
@@ -457,10 +438,9 @@
/**
* Gets the port number of the target host this socket is connected to.
- *
+ *
* @return the port number of the connected target host or {@code 0} if this
* socket is not yet connected.
- * @since Android 1.0
*/
public int getPort() {
if (!isConnected()) {
@@ -471,13 +451,12 @@
/**
* Gets the value of the socket option {@code SocketOptions.SO_LINGER}.
- *
+ *
* @return the current value of the option {@code SocketOptions.SO_LINGER}
* or {@code -1} if this option is disabled.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#SO_LINGER
- * @since Android 1.0
*/
public int getSoLinger() throws SocketException {
checkClosedAndCreate(true);
@@ -486,12 +465,11 @@
/**
* Gets the receive buffer size of this socket.
- *
+ *
* @return the current value of the option {@code SocketOptions.SO_RCVBUF}.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#SO_RCVBUF
- * @since Android 1.0
*/
public synchronized int getReceiveBufferSize() throws SocketException {
checkClosedAndCreate(true);
@@ -500,12 +478,11 @@
/**
* Gets the send buffer size of this socket.
- *
+ *
* @return the current value of the option {@code SocketOptions.SO_SNDBUF}.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#SO_SNDBUF
- * @since Android 1.0
*/
public synchronized int getSendBufferSize() throws SocketException {
checkClosedAndCreate(true);
@@ -515,13 +492,12 @@
/**
* Gets the timeout for this socket during which a reading operation shall
* block while waiting for data.
- *
+ *
* @return the current value of the option {@code SocketOptions.SO_TIMEOUT}
* or {@code 0} which represents an infinite timeout.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#SO_TIMEOUT
- * @since Android 1.0
*/
public synchronized int getSoTimeout() throws SocketException {
checkClosedAndCreate(true);
@@ -530,13 +506,12 @@
/**
* Gets the setting of the socket option {@code SocketOptions.TCP_NODELAY}.
- *
+ *
* @return {@code true} if the {@code SocketOptions.TCP_NODELAY} is enabled,
* {@code false} otherwise.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#TCP_NODELAY
- * @since Android 1.0
*/
public boolean getTcpNoDelay() throws SocketException {
checkClosedAndCreate(true);
@@ -546,13 +521,12 @@
/**
* Sets the state of the {@code SocketOptions.SO_KEEPALIVE} for this socket.
- *
+ *
* @param value
* the state whether this option is enabled or not.
* @throws SocketException
* if an error occurs while setting the option.
* @see SocketOptions#SO_KEEPALIVE
- * @since Android 1.0
*/
public void setKeepAlive(boolean value) throws SocketException {
if (impl != null) {
@@ -565,12 +539,11 @@
/**
* Sets the internal factory for creating socket implementations. This may
* only be executed once during the lifetime of the application.
- *
+ *
* @param fac
* the socket implementation factory to be set.
* @throws IOException
* if the factory has been already set.
- * @since Android 1.0
*/
public static synchronized void setSocketImplFactory(SocketImplFactory fac)
throws IOException {
@@ -586,7 +559,7 @@
/**
* Sets the send buffer size of this socket.
- *
+ *
* @param size
* the buffer size in bytes. This value must be a positive number
* greater than {@code 0}.
@@ -594,7 +567,6 @@
* if an error occurs while setting the size or the given value
* is an invalid size.
* @see SocketOptions#SO_SNDBUF
- * @since Android 1.0
*/
public synchronized void setSendBufferSize(int size) throws SocketException {
checkClosedAndCreate(true);
@@ -606,7 +578,7 @@
/**
* Sets the receive buffer size of this socket.
- *
+ *
* @param size
* the buffer size in bytes. This value must be a positive number
* greater than {@code 0}.
@@ -614,7 +586,6 @@
* if an error occurs while setting the size or the given value
* is an invalid size.
* @see SocketOptions#SO_RCVBUF
- * @since Android 1.0
*/
public synchronized void setReceiveBufferSize(int size)
throws SocketException {
@@ -629,7 +600,7 @@
* Sets the state of the {@code SocketOptions.SO_LINGER} with the given
* timeout in seconds. The timeout value for this option is silently limited
* to the maximum of {@code 65535}.
- *
+ *
* @param on
* the state whether this option is enabled or not.
* @param timeout
@@ -637,7 +608,6 @@
* @throws SocketException
* if an error occurs while setting the option.
* @see SocketOptions#SO_LINGER
- * @since Android 1.0
*/
public void setSoLinger(boolean on, int timeout) throws SocketException {
checkClosedAndCreate(true);
@@ -665,14 +635,13 @@
* operation will block indefinitely if this option value is set to {@code
* 0}. The timeout must be set before calling the read operation. A
* {@code SocketTimeoutException} is thrown when this timeout expires.
- *
+ *
* @param timeout
* the reading timeout value as number greater than {@code 0} or
* {@code 0} for an infinite timeout.
* @throws SocketException
* if an error occurs while setting the option.
* @see SocketOptions#SO_TIMEOUT
- * @since Android 1.0
*/
public synchronized void setSoTimeout(int timeout) throws SocketException {
checkClosedAndCreate(true);
@@ -684,13 +653,12 @@
/**
* Sets the state of the {@code SocketOptions.TCP_NODELAY} for this socket.
- *
+ *
* @param on
* the state whether this option is enabled or not.
* @throws SocketException
* if an error occurs while setting the option.
* @see SocketOptions#TCP_NODELAY
- * @since Android 1.0
*/
public void setTcpNoDelay(boolean on) throws SocketException {
checkClosedAndCreate(true);
@@ -700,7 +668,7 @@
/**
* Creates a stream socket, binds it to the nominated local address/port,
* then connects it to the nominated destination address/port.
- *
+ *
* @param dstAddress
* the destination host address.
* @param dstPort
@@ -743,9 +711,8 @@
/**
* Returns a {@code String} containing a concise, human-readable description of the
* socket.
- *
+ *
* @return the textual representation of this socket.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -759,12 +726,11 @@
* Closes the input stream of this socket. Any further data sent to this
* socket will be discarded. Reading from this socket after this method has
* been called will return the value {@code EOF}.
- *
+ *
* @throws IOException
* if an error occurs while closing the socket input stream.
* @throws SocketException
* if the input stream is already closed.
- * @since Android 1.0
*/
public void shutdownInput() throws IOException {
if (isInputShutdown()) {
@@ -779,12 +745,11 @@
* Closes the output stream of this socket. All buffered data will be sent
* followed by the termination sequence. Writing to the closed output stream
* will cause an {@code IOException}.
- *
+ *
* @throws IOException
* if an error occurs while closing the socket output stream.
* @throws SocketException
* if the output stream is already closed.
- * @since Android 1.0
*/
public void shutdownOutput() throws IOException {
if (isOutputShutdown()) {
@@ -798,7 +763,7 @@
/**
* Checks whether the socket is closed, and throws an exception. Otherwise
* creates the underlying SocketImpl.
- *
+ *
* @throws SocketException
* if the socket is closed.
*/
@@ -840,9 +805,8 @@
* Gets the local address and port of this socket as a SocketAddress or
* {@code null} if the socket is unbound. This is useful on multihomed
* hosts.
- *
+ *
* @return the bound local socket address and port.
- * @since Android 1.0
*/
public SocketAddress getLocalSocketAddress() {
if (!isBound()) {
@@ -854,9 +818,8 @@
/**
* Gets the remote address and port of this socket as a {@code
* SocketAddress} or {@code null} if the socket is not connected.
- *
+ *
* @return the remote socket address and port.
- * @since Android 1.0
*/
public SocketAddress getRemoteSocketAddress() {
if (!isConnected()) {
@@ -867,10 +830,9 @@
/**
* Returns whether this socket is bound to a local address and port.
- *
+ *
* @return {@code true} if the socket is bound to a local address, {@code
* false} otherwise.
- * @since Android 1.0
*/
public boolean isBound() {
return isBound;
@@ -878,9 +840,8 @@
/**
* Returns whether this socket is connected to a remote host.
- *
+ *
* @return {@code true} if the socket is connected, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isConnected() {
return isConnected;
@@ -888,9 +849,8 @@
/**
* Returns whether this socket is closed.
- *
+ *
* @return {@code true} if the socket is closed, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isClosed() {
return isClosed;
@@ -901,7 +861,7 @@
* the SocketAddress {@code localAddr}. If {@code localAddr} is set to
* {@code null}, this socket will be bound to an available local address on
* any free port.
- *
+ *
* @param localAddr
* the specific address and port on the local machine to bind to.
* @throws IllegalArgumentException
@@ -909,7 +869,6 @@
* @throws IOException
* if the socket is already bound or an error occurs while
* binding.
- * @since Android 1.0
*/
public void bind(SocketAddress localAddr) throws IOException {
checkClosedAndCreate(true);
@@ -946,7 +905,7 @@
/**
* Connects this socket to the given remote host address and port specified
* by the SocketAddress {@code remoteAddr}.
- *
+ *
* @param remoteAddr
* the address and port of the remote host to connect to.
* @throws IllegalArgumentException
@@ -954,7 +913,6 @@
* @throws IOException
* if the socket is already connected or an error occurs while
* connecting.
- * @since Android 1.0
*/
public void connect(SocketAddress remoteAddr) throws IOException {
connect(remoteAddr, 0);
@@ -965,7 +923,7 @@
* by the SocketAddress {@code remoteAddr} with the specified timeout. The
* connecting method will block until the connection is established or an
* error occurred.
- *
+ *
* @param remoteAddr
* the address and port of the remote host to connect to.
* @param timeout
@@ -977,7 +935,6 @@
* @throws IOException
* if the socket is already connected or an error occurs while
* connecting.
- * @since Android 1.0
*/
public void connect(SocketAddress remoteAddr, int timeout)
throws IOException {
@@ -1028,22 +985,20 @@
/**
* Returns whether the incoming channel of the socket has already been
* closed.
- *
+ *
* @return {@code true} if reading from this socket is not possible anymore,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isInputShutdown() {
return isInputShutdown;
}
/**
- * Returns whether the outgoing channel of the socket has already been
+ * Returns whether the outgoing channel of the socket has already been
* closed.
- *
+ *
* @return {@code true} if writing to this socket is not possible anymore,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isOutputShutdown() {
return isOutputShutdown;
@@ -1051,13 +1006,12 @@
/**
* Sets the state of the {@code SocketOptions.SO_REUSEADDR} for this socket.
- *
+ *
* @param reuse
* the state whether this option is enabled or not.
* @throws SocketException
* if an error occurs while setting the option.
* @see SocketOptions#SO_REUSEADDR
- * @since Android 1.0
*/
public void setReuseAddress(boolean reuse) throws SocketException {
checkClosedAndCreate(true);
@@ -1067,13 +1021,12 @@
/**
* Gets the setting of the socket option {@code SocketOptions.SO_REUSEADDR}.
- *
+ *
* @return {@code true} if the {@code SocketOptions.SO_REUSEADDR} is
* enabled, {@code false} otherwise.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#SO_REUSEADDR
- * @since Android 1.0
*/
public boolean getReuseAddress() throws SocketException {
checkClosedAndCreate(true);
@@ -1085,13 +1038,12 @@
* Sets the state of the {@code SocketOptions.SO_OOBINLINE} for this socket.
* When this option is enabled urgent data can be received in-line with
* normal data.
- *
+ *
* @param oobinline
* whether this option is enabled or not.
* @throws SocketException
* if an error occurs while setting the option.
* @see SocketOptions#SO_OOBINLINE
- * @since Android 1.0
*/
public void setOOBInline(boolean oobinline) throws SocketException {
checkClosedAndCreate(true);
@@ -1101,13 +1053,12 @@
/**
* Gets the setting of the socket option {@code SocketOptions.SO_OOBINLINE}.
- *
+ *
* @return {@code true} if the {@code SocketOptions.SO_OOBINLINE} is
* enabled, {@code false} otherwise.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#SO_OOBINLINE
- * @since Android 1.0
*/
public boolean getOOBInline() throws SocketException {
checkClosedAndCreate(true);
@@ -1119,14 +1070,13 @@
* Sets the value of the {@code SocketOptions.IP_TOS} for this socket. See
* the specification RFC 1349 for more information about the type of service
* field.
- *
+ *
* @param value
* the value to be set for this option with a valid range of
* {@code 0-255}.
* @throws SocketException
* if an error occurs while setting the option.
* @see SocketOptions#IP_TOS
- * @since Android 1.0
*/
public void setTrafficClass(int value) throws SocketException {
checkClosedAndCreate(true);
@@ -1138,12 +1088,11 @@
/**
* Gets the value of the socket option {@code SocketOptions.IP_TOS}.
- *
+ *
* @return the value which represents the type of service.
* @throws SocketException
* if an error occurs while reading the socket option.
* @see SocketOptions#IP_TOS
- * @since Android 1.0
*/
public int getTrafficClass() throws SocketException {
checkClosedAndCreate(true);
@@ -1153,12 +1102,11 @@
/**
* Sends the given single byte data which is represented by the lowest octet
* of {@code value} as "TCP urgent data".
- *
+ *
* @param value
* the byte of urgent data to be sent.
* @throws IOException
* if an error occurs while sending urgent data.
- * @since Android 1.0
*/
public void sendUrgentData(int value) throws IOException {
if (!impl.supportsUrgentData()) {
@@ -1170,7 +1118,7 @@
/**
* Set the appropriate flags for a socket created by {@code
* ServerSocket.accept()}.
- *
+ *
* @see ServerSocket#implAccept
*/
void accepted() {
@@ -1186,9 +1134,8 @@
/**
* Gets the SocketChannel of this socket, if one is available. The current
* implementation of this method returns always {@code null}.
- *
+ *
* @return the related SocketChannel or {@code null} if no channel exists.
- * @since Android 1.0
*/
public SocketChannel getChannel() {
return null;
@@ -1198,8 +1145,7 @@
* Sets performance preferences for connectionTime, latency and bandwidth.
* <p>
* This method does currently nothing.
- * </p>
- *
+ *
* @param connectionTime
* the value representing the importance of a short connecting
* time.
@@ -1207,7 +1153,6 @@
* the value representing the importance of low latency.
* @param bandwidth
* the value representing the importance of high bandwidth.
- * @since Android 1.0
*/
public void setPerformancePreferences(int connectionTime, int latency,
int bandwidth) {
diff --git a/luni/src/main/java/java/net/SocketAddress.java b/luni/src/main/java/java/net/SocketAddress.java
index 756b5fd..32a4c36 100644
--- a/luni/src/main/java/java/net/SocketAddress.java
+++ b/luni/src/main/java/java/net/SocketAddress.java
@@ -23,15 +23,11 @@
* This abstract class represents a protocol-independent base for
* socket-endpoint representing classes. The class has to be implemented
* according to a specific protocol.
- *
- * @since Android 1.0
*/
public abstract class SocketAddress implements Serializable {
/**
* Creates a new {@code SocketAddress} instance.
- *
- * @since Android 1.0
*/
public SocketAddress() {
super();
diff --git a/luni/src/main/java/java/net/SocketException.java b/luni/src/main/java/java/net/SocketException.java
index b9b3a14..23d3744 100644
--- a/luni/src/main/java/java/net/SocketException.java
+++ b/luni/src/main/java/java/net/SocketException.java
@@ -22,8 +22,6 @@
/**
* This {@code SocketException} may be thrown during socket creation or setting
* options, and is the superclass of all other socket related exceptions.
- *
- * @since Android 1.0
*/
public class SocketException extends IOException {
@@ -32,8 +30,6 @@
/**
* Constructs a new {@code SocketException} instance with its walkback
* filled in.
- *
- * @since Android 1.0
*/
public SocketException() {
super();
@@ -45,7 +41,6 @@
*
* @param detailMessage
* the detail message of this exception.
- * @since Android 1.0
*/
public SocketException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/SocketImpl.java b/luni/src/main/java/java/net/SocketImpl.java
index f011e63..be13eca 100644
--- a/luni/src/main/java/java/net/SocketImpl.java
+++ b/luni/src/main/java/java/net/SocketImpl.java
@@ -20,7 +20,6 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InterruptedIOException;
import java.io.OutputStream;
import org.apache.harmony.luni.platform.INetworkSystem;
@@ -35,36 +34,26 @@
* ServerSocket} on a well known port (referred to as listener) used to
* establish a connection and the resulting {@code Socket} (referred to as
* host).
- *
- * @since Android 1.0
*/
public abstract class SocketImpl implements SocketOptions {
/**
* The remote address this socket is connected to.
- *
- * @since Android 1.0
*/
protected InetAddress address;
/**
* The remote port this socket is connected to.
- *
- * @since Android 1.0
*/
protected int port;
/**
* The file descriptor of this socket.
- *
- * @since Android 1.0
*/
protected FileDescriptor fd;
/**
* The local port this socket is connected to.
- *
- * @since Android 1.0
*/
protected int localport;
@@ -80,9 +69,8 @@
/**
* Creates a new connection-oriented socket implementation.
- *
+ *
* @see SocketImplFactory
- * @since Android 1.0
*/
public SocketImpl() {
this.netImpl = Platform.getNetworkSystem();
@@ -91,73 +79,67 @@
/**
* Waits for an incoming request and blocks until the connection is opened
* on the given socket.
- *
+ *
* @param newSocket
* the socket to accept connections on.
* @throws IOException
* if an error occurs while accepting a new connection.
- * @since Android 1.0
*/
protected abstract void accept(SocketImpl newSocket) throws IOException;
/**
* Returns the available number of bytes which are readable from this socket
* without blocking.
- *
+ *
* @return the number of bytes that may be read without blocking.
* @throws IOException
* if an error occurs while reading the number of bytes.
- * @since Android 1.0
*/
protected abstract int available() throws IOException;
/**
* Binds this socket to the specified local host address and port number.
- *
+ *
* @param address
* the local machine address to bind this socket to.
* @param port
* the port on the local machine to bind this socket to.
* @throws IOException
* if an error occurs while binding this socket.
- * @since Android 1.0
*/
protected abstract void bind(InetAddress address, int port)
throws IOException;
/**
* Closes this socket. This makes later access invalid.
- *
+ *
* @throws IOException
* if an error occurs while closing this socket.
- * @since Android 1.0
*/
protected abstract void close() throws IOException;
/**
* Connects this socket to the specified remote host and port number.
- *
+ *
* @param host
* the remote host this socket has to be connected to.
* @param port
* the remote port on which this socket has to be connected.
* @throws IOException
* if an error occurs while connecting to the remote host.
- * @since Android 1.0
*/
protected abstract void connect(String host, int port) throws IOException;
/**
* Connects this socket to the specified remote host address and port
* number.
- *
+ *
* @param address
* the remote host address this socket has to be connected to.
* @param port
* the remote port on which this socket has to be connected.
* @throws IOException
* if an error occurs while connecting to the remote host.
- * @since Android 1.0
*/
protected abstract void connect(InetAddress address, int port)
throws IOException;
@@ -165,21 +147,19 @@
/**
* Creates a new unconnected socket. The argument {@code isStreaming}
* defines whether the new socket is a streaming or a datagram socket.
- *
+ *
* @param isStreaming
* defines whether the type of the new socket is streaming or
* datagram.
* @throws IOException
* if an error occurs while creating the socket.
- * @since Android 1.0
*/
protected abstract void create(boolean isStreaming) throws IOException;
/**
* Gets the file descriptor of this socket.
- *
+ *
* @return the file descriptor of this socket.
- * @since Android 1.0
*/
protected FileDescriptor getFileDescriptor() {
return fd;
@@ -187,9 +167,8 @@
/**
* Gets the remote address this socket is connected to.
- *
+ *
* @return the remote address of this socket.
- * @since Android 1.0
*/
protected InetAddress getInetAddress() {
return address;
@@ -197,11 +176,10 @@
/**
* Gets the input stream of this socket.
- *
+ *
* @return the input stream of this socket.
* @throws IOException
* if an error occurs while accessing the input stream.
- * @since Android 1.0
*/
protected abstract InputStream getInputStream() throws IOException;
@@ -209,9 +187,8 @@
* Gets the local port number of this socket. The field is initialized to
* {@code -1} and upon demand will go to the IP stack to get the bound
* value. See the class comment for the context of the local port.
- *
+ *
* @return the local port number this socket is bound to.
- * @since Android 1.0
*/
protected int getLocalPort() {
return localport;
@@ -219,32 +196,29 @@
/**
* Gets the value of the given socket option.
- *
+ *
* @param optID
* the socket option to retrieve.
* @return the option value.
* @throws SocketException
* if an error occurs while accessing the option.
- * @since Android 1.0
*/
public abstract Object getOption(int optID) throws SocketException;
/**
* Gets the output stream of this socket.
- *
+ *
* @return the output stream of this socket.
* @throws IOException
* if an error occurs while accessing the output stream.
- * @since Android 1.0
*/
protected abstract OutputStream getOutputStream() throws IOException;
/**
* Gets the remote port number of this socket. This value is not meaningful
* when this instance is wrapped by a {@code ServerSocket}.
- *
+ *
* @return the remote port this socket is connected to.
- * @since Android 1.0
*/
protected int getPort() {
return port;
@@ -255,60 +229,23 @@
* connection requests are queued up to the limit specified by {@code
* backlog}. Additional requests are rejected. The method {@code listen()}
* may only be invoked on streaming sockets.
- *
+ *
* @param backlog
* the maximum number of outstanding connection requests.
* @throws IOException
* if an error occurs while listening.
- * @since Android 1.0
*/
protected abstract void listen(int backlog) throws IOException;
/**
- * In the IP stack, read at most {@code count} bytes off the socket
- * into the {@code buffer}, at the {@code offset}. If the timeout
- * is zero, block indefinitely waiting for data, otherwise wait the
- * specified period (in milliseconds).
- *
- * @param buffer
- * the buffer to read into
- * @param offset
- * the offset into the buffer
- * @param count
- * the max number of bytes to read
- * @return int the actual number of bytes read
- * @exception IOException
- * thrown if an error occurs while reading
- */
- int read(byte[] buffer, int offset, int count) throws IOException {
- if (shutdownInput) {
- return -1;
- }
- try {
- // BEGIN android-added
- int receiveTimeout = (Integer)getOption(SocketOptions.SO_TIMEOUT);
- // END android-added
- int read = this.netImpl.receiveStream(fd, buffer, offset, count,
- receiveTimeout);
- if (read == -1) {
- shutdownInput = true;
- }
- return read;
- } catch (InterruptedIOException e) {
- throw new SocketTimeoutException(e.getMessage());
- }
- }
-
- /**
* Sets the value for the specified socket option.
- *
+ *
* @param optID
* the socket option to be set.
* @param val
* the option value.
* @throws SocketException
* if an error occurs while setting the option.
- * @since Android 1.0
*/
public abstract void setOption(int optID, Object val)
throws SocketException;
@@ -316,9 +253,8 @@
/**
* Returns a string containing a concise, human-readable description of the
* socket.
- *
+ *
* @return the textual representation of this socket.
- * @since Android 1.0
*/
@SuppressWarnings("nls")
@Override
@@ -331,7 +267,7 @@
/**
* In the IP stack, write at most {@code count} bytes on the socket
* from the {@code buffer}, from the {@code offset}.
- *
+ *
* @param buffer
* the buffer to read into
* @param offset
@@ -339,18 +275,15 @@
* @param count
* the number of bytes to write
* @return int the actual number of bytes written
- * @exception IOException
+ * @throws IOException
* thrown if an error occurs while writing
*/
int write(byte[] buffer, int offset, int count) throws IOException {
if (!streaming) {
- // BEGIN android-changed
- // copied from newer harmony version
- return this.netImpl
- .sendDatagram2(fd, buffer, offset, count, port, address);
- // END android-changed
+ return this.netImpl.sendDatagram2(fd, buffer, offset, count, port,
+ address);
}
- return this.netImpl.sendStream(fd, buffer, offset, count);
+ return this.netImpl.write(fd, buffer, offset, count);
}
/**
@@ -358,11 +291,9 @@
* <p>
* This default implementation always throws an {@link IOException} to
* indicate that the subclass should have overridden this method.
- * </p>
- *
+ *
* @throws IOException
* always because this method should be overridden.
- * @since Android 1.0
*/
protected void shutdownInput() throws IOException {
// KA025=Method has not been implemented
@@ -374,11 +305,9 @@
* <p>
* This default implementation always throws an {@link IOException} to
* indicate that the subclass should have overridden this method.
- * </p>
- *
+ *
* @throws IOException
* always because this method should be overridden.
- * @since Android 1.0
*/
protected void shutdownOutput() throws IOException {
// KA025=Method has not been implemented
@@ -389,14 +318,13 @@
* Connects this socket to the remote host address and port number specified
* by the {@code SocketAddress} object with the given timeout. This method
* will block indefinitely if the timeout is set to zero.
- *
+ *
* @param remoteAddr
* the remote host address and port number to connect to.
* @param timeout
* the timeout value in milliseconds.
* @throws IOException
* if an error occurs while connecting.
- * @since Android 1.0
*/
protected abstract void connect(SocketAddress remoteAddr, int timeout)
throws IOException;
@@ -404,9 +332,8 @@
/**
* Returns whether the socket supports urgent data or not. Subclasses should
* override this method.
- *
+ *
* @return {@code false} because subclasses must override this method.
- * @since Android 1.0
*/
protected boolean supportsUrgentData() {
return false;
@@ -414,26 +341,24 @@
/**
* Sends the single byte of urgent data on the socket.
- *
+ *
* @param value
* the byte of urgent data.
* @throws IOException
* if an error occurs sending urgent data.
- * @since Android 1.0
*/
protected abstract void sendUrgentData(int value) throws IOException;
/**
* Sets performance preference for connection time, latency and bandwidth.
* Does nothing by default.
- *
+ *
* @param connectionTime
* the importance of connect time.
* @param latency
* the importance of latency.
* @param bandwidth
* the importance of bandwidth.
- * @since Android 1.0
*/
protected void setPerformancePreferences(int connectionTime, int latency,
int bandwidth) {
diff --git a/luni/src/main/java/java/net/SocketImplFactory.java b/luni/src/main/java/java/net/SocketImplFactory.java
index 3cc42b0..57b0bc3 100644
--- a/luni/src/main/java/java/net/SocketImplFactory.java
+++ b/luni/src/main/java/java/net/SocketImplFactory.java
@@ -19,16 +19,13 @@
/**
* This interface defines a factory for socket implementations.
- *
- * @since Android 1.0
*/
public interface SocketImplFactory {
-
+
/**
* Creates a new {@code SocketImpl} instance.
*
* @return the created {@code SocketImpl} instance.
- * @since Android 1.0
*/
SocketImpl createSocketImpl();
}
diff --git a/luni/src/main/java/java/net/SocketOptions.java b/luni/src/main/java/java/net/SocketOptions.java
index 6e1753f..38c9301 100644
--- a/luni/src/main/java/java/net/SocketOptions.java
+++ b/luni/src/main/java/java/net/SocketOptions.java
@@ -25,7 +25,6 @@
*
* @see SocketImpl
* @see DatagramSocketImpl
- * @since Android 1.0
*/
public interface SocketOptions {
@@ -38,8 +37,6 @@
* during this timeout the socket is closed normally otherwise forcefully.
* Valid values for this option are in the range {@code 0 <= SO_LINGER <=
* 65535}.
- *
- * @since Android 1.0
*/
public static final int SO_LINGER = 128;
@@ -47,8 +44,6 @@
* Timeout for blocking operations. The argument value is specified in
* milliseconds. An {@code InterruptedIOException} is thrown if this timeout
* expires.
- *
- * @since Android 1.0
*/
public static final int SO_TIMEOUT = 4102;
@@ -57,8 +52,6 @@
* a side-effect though, this could lead to a low packet efficiency. The
* socket implementation uses the Nagle's algorithm to try to reach a higher
* packet efficiency if this option is disabled.
- *
- * @since Android 1.0
*/
public static final int TCP_NODELAY = 1;
@@ -69,8 +62,6 @@
/**
* This option specifies the interface which is used to send multicast
* packets. It's only available on a {@code MulticastSocket}.
- *
- * @since Android 1.0
*/
public static final int IP_MULTICAST_IF = 16;
@@ -78,8 +69,6 @@
* This option can be used to set one specific interface on a multihomed
* host on which incoming connections are accepted. It's only available on
* server-side sockets.
- *
- * @since Android 1.0
*/
public static final int SO_BINDADDR = 15;
@@ -87,8 +76,6 @@
* This option specifies whether a reuse of a local address is allowed even
* if an other socket is not yet removed by the operating system. It's only
* available on a {@code MulticastSocket}.
- *
- * @since Android 1.0
*/
public static final int SO_REUSEADDR = 4;
@@ -96,15 +83,11 @@
/**
* Buffer size of the outgoing channel.
- *
- * @since Android 1.0
*/
public static final int SO_SNDBUF = 4097;
/**
* Buffer size of the incoming channel.
- *
- * @since Android 1.0
*/
public static final int SO_RCVBUF = 4098;
@@ -113,16 +96,12 @@
/**
* This option specifies whether socket implementations can send keepalive
* messages if no data has been sent for a longer time.
- *
- * @since Android 1.0
*/
public static final int SO_KEEPALIVE = 8;
/**
* This option specifies the value for the Type-of-Service (TOS) field of
* the IP header.
- *
- * @since Android 1.0
*/
public static final int IP_TOS = 3;
@@ -130,23 +109,17 @@
* This option specifies whether the local loopback of multicast packets is
* enabled or disabled. This option is enabled by default on multicast
* sockets.
- *
- * @since Android 1.0
*/
public static final int IP_MULTICAST_LOOP = 18;
/**
* This option can be used to enable broadcasting on datagram sockets.
- *
- * @since Android 1.0
*/
public static final int SO_BROADCAST = 32;
/**
* This option specifies whether sending TCP urgent data is supported on
* this socket or not.
- *
- * @since Android 1.0
*/
public static final int SO_OOBINLINE = 4099;
@@ -155,8 +128,6 @@
* host on which incoming connections are accepted. It's only available on
* server-side sockets. This option supports setting outgoing interfaces
* with either IPv4 or IPv6 addresses.
- *
- * @since Android 1.0
*/
public static final int IP_MULTICAST_IF2 = 31;
@@ -168,7 +139,6 @@
* the option identifier.
* @throws SocketException
* if an error occurs reading the option value.
- * @since Android 1.0
*/
public Object getOption(int optID) throws SocketException;
@@ -181,7 +151,6 @@
* the value to be set for the option.
* @throws SocketException
* if an error occurs setting the option value.
- * @since Android 1.0
*/
public void setOption(int optID, Object val) throws SocketException;
}
diff --git a/luni/src/main/java/java/net/SocketPermission.java b/luni/src/main/java/java/net/SocketPermission.java
index 72d77e7..25cc43f 100644
--- a/luni/src/main/java/java/net/SocketPermission.java
+++ b/luni/src/main/java/java/net/SocketPermission.java
@@ -14,9 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// BEGIN andorid-note
-// This class was copied from a newer version of harmony
-// END andorid-note
package java.net;
@@ -57,16 +54,13 @@
* <i>LOW-HIGH</i> where <i>LOW</i> and <i>HIGH</i> are valid port numbers. If
* either <i>LOW</i> or <i>HIGH</i> is omitted it is equivalent to entering the
* lowest or highest possible value respectively. For example:
- *
+ *
* <pre>
* {@code SocketPermission("www.company.com:7000-", "connect,accept")}
* </pre>
- *
+ *
* represents the permission to connect to and accept connections from {@code
* www.company.com} on ports in the range {@code 7000} to {@code 65535}.
- * </p>
- *
- * @since Android 1.0
*/
public final class SocketPermission extends Permission implements Serializable {
@@ -122,13 +116,11 @@
* possible operations {@code "connect"}, {@code "listen"}, {@code "accept"}
* , and {@code "resolve"}. They are case-insensitive and can be put
* together in any order. {@code "resolve"} is implied per default.
- * </p>
- *
+ *
* @param host
* the hostname this permission is valid for.
* @param action
* the action string of this permission.
- * @since Android 1.0
*/
public SocketPermission(String host, String action) {
super(host.equals("") ? "localhost" : host); //$NON-NLS-1$ //$NON-NLS-2$
@@ -149,14 +141,13 @@
/**
* Compares the argument {@code o} to this instance and returns {@code true}
* if they represent the same permission using a class specific comparison.
- *
+ *
* @param o
* the object to compare with this {@code SocketPermission}
* instance.
* @return {@code true} if they represent the same permission, {@code false}
* otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object o) {
@@ -187,10 +178,9 @@
* Returns the hash value for this {@code SocketPermission} instance. Any
* two objects which returns {@code true} when passed to {@code equals()}
* must return the same value as a result of this method.
- *
+ *
* @return the hashcode value for this instance.
* @see #equals
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -201,9 +191,8 @@
* Gets a comma-separated list of all actions allowed by this permission. If
* more than one action is returned they follow this order: {@code connect},
* {@code listen}, {@code accept}, {@code resolve}.
- *
+ *
* @return the comma-separated action list.
- * @since Android 1.0
*/
@Override
public String getActions() {
@@ -212,7 +201,7 @@
/**
* Stores the actions for this permission as a bit field.
- *
+ *
* @param actions
* java.lang.String the action list
*/
@@ -255,13 +244,12 @@
* permission actions, hosts and ports must be implied by this permission
* instance in order to return {@code true}. This permission may imply
* additional actions not present in the argument permission.
- *
+ *
* @param p
* the socket permission which has to be implied by this
* instance.
* @return {@code true} if this permission instance implies all permissions
* represented by {@code p}, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean implies(Permission p) {
@@ -293,15 +281,14 @@
/**
* Creates a new {@code PermissionCollection} to store {@code
* SocketPermission} objects.
- *
+ *
* @return the new permission collection.
- * @since Android 1.0
*/
@Override
public PermissionCollection newPermissionCollection() {
return new SocketPermissionCollection();
}
-
+
/**
* Parse the port, including the minPort, maxPort
* @param hostPort the host[:port] one
@@ -319,14 +306,14 @@
portMax = 80;
return;
}
-
+
if (":*".equals(port)) {
// The port range should be 0-65535
portMin = 0;
portMax = 65535;
return;
}
-
+
// Omit ':'
port = port.substring(1);
int negIdx = port.indexOf('-');
@@ -349,21 +336,23 @@
try {
portMin = Integer.valueOf(strPortMin).intValue();
portMax = Integer.valueOf(strPortMax).intValue();
-
+
if (portMin > portMax) {
- throw new IllegalArgumentException(Msg.getString("K0049") + " " + port); //$NON-NLS-1$
+ // K0049=MinPort is greater than MaxPort\: {0}
+ throw new IllegalArgumentException(Msg.getString("K0049", port)); //$NON-NLS-1$
}
} catch (NumberFormatException e) {
- throw new IllegalArgumentException(Msg.getString("K004a") + " " + port); //$NON-NLS-1$
+ // K004a=Invalid port number specified\: {0}
+ throw new IllegalArgumentException(Msg.getString("K004a", port)); //$NON-NLS-1$
}
}
/**
* Creates a canonical action list.
- *
+ *
* @param action
* java.lang.String
- *
+ *
* @return java.lang.String
*/
private String toCanonicalActionString(String action) {
@@ -403,15 +392,20 @@
}
/**
- * Get the host part from the host[:port] one.
- * The host should be
+ * Get the host part from the host[:port] one. The host should be
+ *
+ * <pre>
* host = (hostname | IPv4address | IPv6reference | IPv6 in full uncompressed form)
- * The wildcard "*" may be included once in a DNS name host specification. If it is included,
- * it must be in the leftmost position
- *
+ * </pre>
+ *
+ * The wildcard "*" may be included once in a DNS name host specification.
+ * If it is included, it must be in the leftmost position
+ *
* @param host
- * @return
- * @throws IllegalArgumentException if the host is invalid.
+ * the {@code host[:port]} string.
+ * @return the host name.
+ * @throws IllegalArgumentException
+ * if the host is invalid.
*/
private String getHostString(String host) throws IllegalArgumentException {
host = host.trim();
@@ -431,7 +425,7 @@
}
int lastIdx = host.lastIndexOf(':');
-
+
if (idx == lastIdx) {
if (-1 != idx) {
// only one colon, should be port
@@ -456,21 +450,22 @@
if (Inet6Util.isIP6AddressInFullForm(host)) {
return host.toLowerCase();
}
- throw new IllegalArgumentException(Msg.getString("K004a") + " "
- + host);
+ // K004a=Invalid port number specified\: {0}
+ throw new IllegalArgumentException(Msg.getString("K004a", host));
}
// forward bracket found
int bbracketIdx = host.indexOf(']');
if (-1 == bbracketIdx) {
// no back bracket found, wrong
- throw new IllegalArgumentException(Msg.getString("K004a") + " "
- + host);
+ // K004a=Invalid port number specified\: {0}
+ throw new IllegalArgumentException(Msg.getString("K004a", host));
}
host = host.substring(0, bbracketIdx + 1);
if (Inet6Util.isValidIP6Address(host)) {
return host.toLowerCase();
}
- throw new IllegalArgumentException(Msg.getString("K004a") + " " + host);
+ // K004a=Invalid port number specified\: {0}
+ throw new IllegalArgumentException(Msg.getString("K004a", host));
}
/**
diff --git a/luni/src/main/java/java/net/SocketPermissionCollection.java b/luni/src/main/java/java/net/SocketPermissionCollection.java
index 777f9a7..60bb831 100644
--- a/luni/src/main/java/java/net/SocketPermissionCollection.java
+++ b/luni/src/main/java/java/net/SocketPermissionCollection.java
@@ -26,8 +26,6 @@
* This class represents a list of {@code SocketPermission} objects and provides
* a method to check whether or not a specific permission is implied by this
* {@code SocketPermissionCollection}.
- *
- * @since Android 1.0
*/
final class SocketPermissionCollection extends PermissionCollection {
@@ -62,8 +60,6 @@
* Returns whether this permission collection implies {@code permission}.
* Basically it tests whether {@code permission} is the subset of this
* collection.
- *
- * @since Android 1.0
*/
@Override
public boolean implies(Permission permission) {
diff --git a/luni/src/main/java/java/net/SocketTimeoutException.java b/luni/src/main/java/java/net/SocketTimeoutException.java
index 32ba183..c1c762e 100644
--- a/luni/src/main/java/java/net/SocketTimeoutException.java
+++ b/luni/src/main/java/java/net/SocketTimeoutException.java
@@ -22,8 +22,6 @@
/**
* This exception is thrown when a timeout expired on a socket {@code read} or
* {@code accept} operation.
- *
- * @since Android 1.0
*/
public class SocketTimeoutException extends InterruptedIOException {
@@ -32,8 +30,6 @@
/**
* Creates a new {@code SocketTimeoutException} instance with its walkback
* filled in.
- *
- * @since Android 1.0
*/
public SocketTimeoutException() {
super();
@@ -45,7 +41,6 @@
*
* @param detailMessage
* the detail message of this exception.
- * @since Android 1.0
*/
public SocketTimeoutException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/URI.java b/luni/src/main/java/java/net/URI.java
index 4b1f4df..7fd08a5 100644
--- a/luni/src/main/java/java/net/URI.java
+++ b/luni/src/main/java/java/net/URI.java
@@ -28,8 +28,6 @@
/**
* This class represents an instance of a URI as defined by RFC 2396.
- *
- * @since Android 1.0
*/
public final class URI implements Comparable<URI>, Serializable {
@@ -78,13 +76,12 @@
/**
* Creates a new URI instance according to the given string {@code uri}.
- *
+ *
* @param uri
* the textual URI representation to be parsed into a URI object.
* @throws URISyntaxException
* if the given string {@code uri} doesn't fit to the
* specification RFC2396 or could not be parsed correctly.
- * @since Android 1.0
*/
public URI(String uri) throws URISyntaxException {
new Helper().parseURI(uri, false);
@@ -96,8 +93,7 @@
* string will be parsed later on to create the URI instance.
* <p>
* {@code [scheme:]scheme-specific-part[#fragment]}
- * </p>
- *
+ *
* @param scheme
* the scheme part of the URI.
* @param ssp
@@ -107,7 +103,6 @@
* @throws URISyntaxException
* if the temporary created string doesn't fit to the
* specification RFC2396 or could not be parsed correctly.
- * @since Android 1.0
*/
public URI(String scheme, String ssp, String frag)
throws URISyntaxException {
@@ -135,8 +130,7 @@
* string will be parsed later on to create the URI instance.
* <p>
* {@code [scheme:][user-info@]host[:port][path][?query][#fragment]}
- * </p>
- *
+ *
* @param scheme
* the scheme part of the URI.
* @param userinfo
@@ -156,7 +150,6 @@
* @throws URISyntaxException
* if the temporary created string doesn't fit to the
* specification RFC2396 or could not be parsed correctly.
- * @since Android 1.0
*/
public URI(String scheme, String userinfo, String host, int port,
String path, String query, String fragment)
@@ -230,8 +223,7 @@
* string will be parsed later on to create the URI instance.
* <p>
* {@code [scheme:]host[path][#fragment]}
- * </p>
- *
+ *
* @param scheme
* the scheme part of the URI.
* @param host
@@ -243,7 +235,6 @@
* @throws URISyntaxException
* if the temporary created string doesn't fit to the
* specification RFC2396 or could not be parsed correctly.
- * @since Android 1.0
*/
public URI(String scheme, String host, String path, String fragment)
throws URISyntaxException {
@@ -256,8 +247,7 @@
* string will be parsed later on to create the URI instance.
* <p>
* {@code [scheme:][//authority][path][?query][#fragment]}
- * </p>
- *
+ *
* @param scheme
* the scheme part of the URI.
* @param authority
@@ -272,7 +262,6 @@
* @throws URISyntaxException
* if the temporary created string doesn't fit to the
* specification RFC2396 or could not be parsed correctly.
- * @since Android 1.0
*/
public URI(String scheme, String authority, String path, String query,
String fragment) throws URISyntaxException {
@@ -718,7 +707,7 @@
// case for a closed bracket at end of IP [x:x:x:...x]
case ']':
if (i != length - 1) {
- return false; // must be last charcter
+ return false; // must be last character
}
if (ipAddress.charAt(0) != '[') {
return false; // must have a open [
@@ -856,11 +845,10 @@
* in the natural case-sensitive way. A hierarchical URI is less than an
* opaque URI and if one part is {@code null} the URI with the undefined
* part is less than the other one.
- *
+ *
* @param uri
* the URI this instance has to compare with.
* @return the value representing the order of the two instances.
- * @since Android 1.0
*/
public int compareTo(URI uri) {
int ret = 0;
@@ -969,11 +957,10 @@
/**
* Parses the given argument {@code uri} and creates an appropriate URI
* instance.
- *
+ *
* @param uri
* the string which has to be parsed to create the URI instance.
* @return the created instance representing the given URI.
- * @since Android 1.0
*/
public static URI create(String uri) {
URI result = null;
@@ -1057,12 +1044,11 @@
* Compares this URI instance with the given argument {@code o} and
* determines if both are equal. Two URI instances are equal if all single
* parts are identical in their meaning.
- *
+ *
* @param o
* the URI this instance has to be compared with.
* @return {@code true} if both URI instances point to the same resource,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object o) {
@@ -1147,9 +1133,8 @@
/**
* Gets the decoded authority part of this URI.
- *
+ *
* @return the decoded authority part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getAuthority() {
return decode(authority);
@@ -1159,7 +1144,6 @@
* Gets the decoded fragment part of this URI.
*
* @return the decoded fragment part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getFragment() {
return decode(fragment);
@@ -1169,7 +1153,6 @@
* Gets the host part of this URI.
*
* @return the host part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getHost() {
return host;
@@ -1179,7 +1162,6 @@
* Gets the decoded path part of this URI.
*
* @return the decoded path part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getPath() {
return decode(path);
@@ -1189,7 +1171,6 @@
* Gets the port number of this URI.
*
* @return the port number or {@code -1} if undefined.
- * @since Android 1.0
*/
public int getPort() {
return port;
@@ -1199,7 +1180,6 @@
* Gets the decoded query part of this URI.
*
* @return the decoded query part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getQuery() {
return decode(query);
@@ -1209,7 +1189,6 @@
* Gets the authority part of this URI in raw form.
*
* @return the encoded authority part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getRawAuthority() {
return authority;
@@ -1219,7 +1198,6 @@
* Gets the fragment part of this URI in raw form.
*
* @return the encoded fragment part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getRawFragment() {
return fragment;
@@ -1229,7 +1207,6 @@
* Gets the path part of this URI in raw form.
*
* @return the encoded path part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getRawPath() {
return path;
@@ -1239,7 +1216,6 @@
* Gets the query part of this URI in raw form.
*
* @return the encoded query part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getRawQuery() {
return query;
@@ -1249,17 +1225,15 @@
* Gets the scheme-specific part of this URI in raw form.
*
* @return the encoded scheme-specific part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getRawSchemeSpecificPart() {
return schemespecificpart;
}
-
+
/**
* Gets the user-info part of this URI in raw form.
*
* @return the encoded user-info part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getRawUserInfo() {
return userinfo;
@@ -1269,17 +1243,15 @@
* Gets the scheme part of this URI.
*
* @return the scheme part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getScheme() {
return scheme;
}
-
+
/**
* Gets the decoded scheme-specific part of this URI.
*
* @return the decoded scheme-specific part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getSchemeSpecificPart() {
return decode(schemespecificpart);
@@ -1289,7 +1261,6 @@
* Gets the decoded user-info part of this URI.
*
* @return the decoded user-info part or {@code null} if undefined.
- * @since Android 1.0
*/
public String getUserInfo() {
return decode(userinfo);
@@ -1297,9 +1268,8 @@
/**
* Gets the hashcode value of this URI instance.
- *
+ *
* @return the appropriate hashcode value.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -1314,7 +1284,6 @@
* defined in this URI.
*
* @return {@code true} if this URI is absolute, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isAbsolute() {
return absolute;
@@ -1327,7 +1296,6 @@
* undefined.
*
* @return {@code true} if the URI is opaque, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isOpaque() {
return opaque;
@@ -1424,10 +1392,9 @@
/**
* Normalizes the path part of this URI.
- *
+ *
* @return an URI object which represents this instance with a normalized
* path.
- * @since Android 1.0
*/
public URI normalize() {
if (opaque) {
@@ -1450,12 +1417,11 @@
* Tries to parse the authority component of this URI to divide it into the
* host, port, and user-info. If this URI is already determined as a
* ServerAuthority this instance will be returned without changes.
- *
+ *
* @return this instance with the components of the parsed server authority.
* @throws URISyntaxException
* if the authority part could not be parsed as a server-based
* authority.
- * @since Android 1.0
*/
public URI parseServerAuthority() throws URISyntaxException {
if (!serverAuthority) {
@@ -1467,11 +1433,10 @@
/**
* Makes the given URI {@code relative} to a relative URI against the URI
* represented by this instance.
- *
+ *
* @param relative
* the URI which has to be relativized against this URI.
* @return the relative URI.
- * @since Android 1.0
*/
public URI relativize(URI relative) {
if (relative.opaque || opaque) {
@@ -1516,17 +1481,17 @@
result.query = relative.query;
// the result URI is the remainder of the relative URI's path
result.path = relativePath.substring(thisPath.length());
+ result.setSchemeSpecificPart();
return result;
}
/**
* Resolves the given URI {@code relative} against the URI represented by
* this instance.
- *
+ *
* @param relative
* the URI which has to be resolved against this URI.
* @return the resolved URI.
- * @since Android 1.0
*/
public URI resolve(URI relative) {
if (relative.absolute || opaque) {
@@ -1602,12 +1567,11 @@
* Creates a new URI instance by parsing the given string {@code relative}
* and resolves the created URI against the URI represented by this
* instance.
- *
+ *
* @param relative
* the given string to create the new URI instance which has to
* be resolved later on.
* @return the created and resolved URI.
- * @since Android 1.0
*/
public URI resolve(String relative) {
return resolve(create(relative));
@@ -1652,9 +1616,8 @@
/**
* Returns the textual string representation of this URI instance using the
* US-ASCII encoding.
- *
+ *
* @return the US-ASCII string representation of this URI.
- * @since Android 1.0
*/
public String toASCIIString() {
return encodeOthers(toString());
@@ -1662,9 +1625,8 @@
/**
* Returns the textual string representation of this URI instance.
- *
+ *
* @return the textual string representation of this URI.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -1751,12 +1713,11 @@
/**
* Converts this URI instance to a URL.
- *
+ *
* @return the created URL representing the same resource as this URI.
* @throws MalformedURLException
* if an error occurs while creating the URL or no protocol
* handler could be found.
- * @since Android 1.0
*/
public URL toURL() throws MalformedURLException {
if (!absolute) {
diff --git a/luni/src/main/java/java/net/URIEncoderDecoder.java b/luni/src/main/java/java/net/URIEncoderDecoder.java
index a9ef3c1..4bf95ab 100644
--- a/luni/src/main/java/java/net/URIEncoderDecoder.java
+++ b/luni/src/main/java/java/net/URIEncoderDecoder.java
@@ -27,8 +27,6 @@
* application/x-www-form-urlencoded} MIME content type. It contains helper
* methods used by the URI class, and performs encoding and decoding in a
* slightly different way than {@code URLEncoder} and {@code URLDecoder}.
- *
- * @since Android 1.0
*/
class URIEncoderDecoder {
@@ -43,8 +41,7 @@
* US-ASCII set, and are not ISO Control or are not ISO Space characters)
* <p>
* called from {@code URI.Helper.parseURI()} to validate each component
- * </p>
- *
+ *
* @param s
* {@code java.lang.String} the string to be validated
* @param legal
@@ -100,14 +97,12 @@
* by '%'.
* <p>
* For example: '#' -> %23
- * </p>
* Other characters, which are unicode chars that are not US-ASCII, and are
* not ISO Control or are not ISO Space chars, are preserved.
* <p>
* Called from {@code URI.quoteComponent()} (for multiple argument
* constructors)
- * </p>
- *
+ *
* @param s
* java.lang.String the string to be converted
* @param legal
@@ -145,10 +140,9 @@
* converted into their hexidecimal value prepended by '%'.
* <p>
* For example: Euro currency symbol -> "%E2%82%AC".
- * </p>
+ * <p>
* Called from URI.toASCIIString()
- * </p>
- *
+ *
* @param s
* java.lang.String the string to be converted
* @return java.lang.String the converted string
@@ -178,11 +172,10 @@
*'%' and two following hex digit characters are converted to the
* equivalent byte value. All other characters are passed through
* unmodified.
- * </p>
+ * <p>
* e.g. "A%20B%20C %24%25" -> "A B C $%"
* <p>
* Called from URI.getXYZ() methods
- * </p>
*
* @param s
* java.lang.String The encoded string.
diff --git a/luni/src/main/java/java/net/URISyntaxException.java b/luni/src/main/java/java/net/URISyntaxException.java
index e7e332e..2daf35f 100644
--- a/luni/src/main/java/java/net/URISyntaxException.java
+++ b/luni/src/main/java/java/net/URISyntaxException.java
@@ -22,8 +22,6 @@
/**
* A {@code URISyntaxException} will be thrown if some information could not be parsed
* while creating a URI.
- *
- * @since Android 1.0
*/
public class URISyntaxException extends Exception {
@@ -49,7 +47,6 @@
* {@code null}.
* @throws IllegalArgumentException
* if the value for {@code index} is lesser than {@code -1}.
- * @since Android 1.0
*/
public URISyntaxException(String input, String reason, int index) {
super(reason);
@@ -77,7 +74,6 @@
* @throws NullPointerException
* if one of the arguments {@code input} or {@code reason} is
* {@code null}.
- * @since Android 1.0
*/
public URISyntaxException(String input, String reason) {
super(reason);
@@ -95,7 +91,6 @@
* index is unknown/unavailable.
*
* @return the index of the syntax error.
- * @since Android 1.0
*/
public int getIndex() {
return index;
@@ -105,7 +100,6 @@
* Gets a description of the syntax error.
*
* @return the string describing the syntax error.
- * @since Android 1.0
*/
public String getReason() {
return super.getMessage();
@@ -115,7 +109,6 @@
* Gets the initial string that contains an invalid syntax.
*
* @return the string that caused the exception.
- * @since Android 1.0
*/
public String getInput() {
return input;
@@ -128,7 +121,6 @@
*
* @return a sting containing information about the exception.
* @see java.lang.Throwable#getMessage()
- * @since Android 1.0
*/
@Override
public String getMessage() {
diff --git a/luni/src/main/java/java/net/URL.java b/luni/src/main/java/java/net/URL.java
index 2bc8c6c..9b0fdc4 100644
--- a/luni/src/main/java/java/net/URL.java
+++ b/luni/src/main/java/java/net/URL.java
@@ -34,8 +34,6 @@
* which generates the output dynamically. A URL is divided in its parts
* protocol, host name, port, path, file, user-info, query, reference and
* authority. However, not each of this parts has to be defined.
- *
- * @since Android 1.0
*/
public final class URL implements java.io.Serializable {
private static final long serialVersionUID = -7627629688361524110L;
@@ -131,11 +129,9 @@
* <p>
* A security check is performed to verify whether the current policy allows
* to set the stream handler factory.
- * </p>
- *
+ *
* @param streamFactory
* the factory to be used for creating stream protocol handlers.
- * @since Android 1.0
*/
public static synchronized void setURLStreamHandlerFactory(
URLStreamHandlerFactory streamFactory) {
@@ -158,7 +154,6 @@
* @throws MalformedURLException
* if the given string {@code spec} could not be parsed as a
* URL.
- * @since Android 1.0
*/
public URL(String spec) throws MalformedURLException {
this((URL) null, spec, (URLStreamHandler) null);
@@ -178,7 +173,6 @@
* @throws MalformedURLException
* if the given string {@code spec} could not be parsed as a URL
* or an invalid protocol has been found.
- * @since Android 1.0
*/
public URL(URL context, String spec) throws MalformedURLException {
this(context, spec, (URLStreamHandler) null);
@@ -202,7 +196,6 @@
* @throws MalformedURLException
* if the given string {@code spec} could not be parsed as a URL
* or an invalid protocol has been found.
- * @since Android 1.0
*/
public URL(URL context, String spec, URLStreamHandler handler)
throws MalformedURLException {
@@ -235,8 +228,6 @@
// According to RFC 2396 scheme part should match
// the following expression:
// alpha *( alpha | digit | "+" | "-" | "." )
- // BEGIN android-changed
- // copied from newer version of harmony
char c = protocol.charAt(0);
boolean valid = ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
for (int i = 1; valid && (i < protocol.length()); i++) {
@@ -253,10 +244,9 @@
index = -1;
} else {
// Ignore case in protocol names.
- // Scheme is defined by ASCII characters.
+ // Scheme is defined by ASCII characters.
protocol = Util.toASCIILowerCase(protocol);
}
- // END android-changed
}
}
@@ -338,7 +328,6 @@
* @throws MalformedURLException
* if the combination of all arguments do not represent a valid
* URL or the protocol is invalid.
- * @since Android 1.0
*/
public URL(String protocol, String host, String file)
throws MalformedURLException {
@@ -361,7 +350,6 @@
* @throws MalformedURLException
* if the combination of all arguments do not represent a valid
* URL or the protocol is invalid.
- * @since Android 1.0
*/
public URL(String protocol, String host, int port, String file)
throws MalformedURLException {
@@ -371,7 +359,7 @@
/**
* Creates a new URL instance using the given arguments. The URL uses the
* specified port instead of the default port for the given protocol.
- *
+ *
* @param protocol
* the protocol of the new URL.
* @param host
@@ -386,25 +374,26 @@
* @throws MalformedURLException
* if the combination of all arguments do not represent a valid
* URL or the protocol is invalid.
- * @since Android 1.0
+ * @throws SecurityException
+ * if {@code handler} is non-{@code null}, and a security
+ * manager is installed that disallows user-defined protocol
+ * handlers.
*/
public URL(String protocol, String host, int port, String file,
URLStreamHandler handler) throws MalformedURLException {
if (port < -1) {
- throw new MalformedURLException(org.apache.harmony.luni.util.Msg
- .getString("K0325", port)); //$NON-NLS-1$
+ throw new MalformedURLException(Msg.getString("K0325", port)); //$NON-NLS-1$
}
if (host != null && host.indexOf(":") != -1 && host.charAt(0) != '[') { //$NON-NLS-1$
host = "[" + host + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
- if (protocol != null) {
- this.protocol = protocol;
- } else {
- throw new NullPointerException(Msg.getString("K00b3", protocol)); //$NON-NLS-1$
+ if (protocol == null) {
+ throw new NullPointerException(Msg.getString("K00b3", "null")); //$NON-NLS-1$ //$NON-NLS-2$
}
+ this.protocol = protocol;
this.host = host;
this.port = port;
@@ -427,8 +416,7 @@
setupStreamHandler();
if (strmHandler == null) {
throw new MalformedURLException(
- org.apache.harmony.luni.util.Msg.getString(
- "K00b3", protocol)); //$NON-NLS-1$
+ Msg.getString("K00b3", protocol)); //$NON-NLS-1$
}
} else {
SecurityManager sm = System.getSecurityManager();
@@ -479,7 +467,6 @@
* the file to be set.
* @param ref
* the reference to be set.
- * @since Android 1.0
*/
protected void set(String protocol, String host, int port, String file,
String ref) {
@@ -506,8 +493,7 @@
* the URL this instance has to be compared with.
* @return {@code true} if both instances represents the same URL, {@code
* false} otherwise.
- * @see #hashCode
- * @since Android 1.0
+ * @see #hashCode()
*/
@Override
public boolean equals(Object o) {
@@ -532,7 +518,6 @@
* the URL to compare against.
* @return {@code true} if both instances refer to the same resource,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean sameFile(URL otherURL) {
return strmHandler.sameFile(this, otherURL);
@@ -542,7 +527,6 @@
* Gets the hashcode value of this URL instance.
*
* @return the appropriate hashcode value.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -560,7 +544,6 @@
* Note that this will overwrite any existing stream handler with the new
* one. Senders must check if the strmHandler is null before calling the
* method if they do not want this behavior (a speed optimization).
- * </p>
*/
void setupStreamHandler() {
// Check for a cached (previously looked up) handler for
@@ -629,12 +612,10 @@
* <li>Image for pictures</li>
* <li>AudioClip for audio sequences</li>
* <li>{@link InputStream} for all other data</li>
- * </p>
*
* @return the content of the referred resource.
* @throws IOException
* if an error occurs obtaining the content.
- * @since Android 1.0
*/
public final Object getContent() throws IOException {
return openConnection().getContent();
@@ -654,7 +635,6 @@
* type.
* @throws IOException
* if an error occurs obtaining the content.
- * @since Android 1.0
*/
// Param not generic in spec
@SuppressWarnings("unchecked")
@@ -668,7 +648,6 @@
* @return the stream which allows to read the resource.
* @throws IOException
* if an error occurs while opening the InputStream.
- * @since Android 1.0
*/
public final InputStream openStream() throws java.io.IOException {
return openConnection().getInputStream();
@@ -681,7 +660,6 @@
* @return the connection to this URL.
* @throws IOException
* if an error occurs while opening the connection.
- * @since Android 1.0
*/
public URLConnection openConnection() throws IOException {
return strmHandler.openConnection(this);
@@ -693,7 +671,6 @@
* @return the URI instance that represents this URL.
* @throws URISyntaxException
* if this URL cannot be converted into a URI.
- * @since Android 1.0
*/
public URI toURI() throws URISyntaxException {
return new URI(toExternalForm());
@@ -718,7 +695,6 @@
* @throws UnsupportedOperationException
* if the protocol handler does not support opening connections
* through proxies.
- * @since Android 1.0
*/
public URLConnection openConnection(Proxy proxy) throws IOException {
if (null == proxy) {
@@ -733,7 +709,6 @@
* {@code toExternalForm()}.
*
* @return the string representation of this URL.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -745,7 +720,6 @@
* this URL.
*
* @return the string representation of this URL.
- * @since Android 1.0
*/
public String toExternalForm() {
if (strmHandler == null) {
@@ -798,8 +772,7 @@
* <p>
* Note that, we really only need the readObject method but the spec that
* says readObject will be ignored if no writeObject is present.
- * </p>
- *
+ *
* @param s
* the stream to write on.
* @throws IOException
@@ -814,7 +787,6 @@
*
* @return the file name this URL refers to or an empty string if the file
* part is not set.
- * @since Android 1.0
*/
public String getFile() {
return file;
@@ -824,7 +796,6 @@
* Gets the value of the host part of this URL.
*
* @return the host name or IP address of this URL.
- * @since Android 1.0
*/
public String getHost() {
return host;
@@ -834,7 +805,6 @@
* Gets the port number of this URL or {@code -1} if the port is not set.
*
* @return the port number of this URL.
- * @since Android 1.0
*/
public int getPort() {
return port;
@@ -844,7 +814,6 @@
* Gets the protocol of this URL.
*
* @return the protocol type of this URL.
- * @since Android 1.0
*/
public String getProtocol() {
return protocol;
@@ -854,7 +823,6 @@
* Gets the value of the reference part of this URL.
*
* @return the reference part of this URL.
- * @since Android 1.0
*/
public String getRef() {
return ref;
@@ -864,7 +832,6 @@
* Gets the value of the query part of this URL.
*
* @return the query part of this URL.
- * @since Android 1.0
*/
public String getQuery() {
return query;
@@ -874,7 +841,6 @@
* Gets the value of the path part of this URL.
*
* @return the path part of this URL.
- * @since Android 1.0
*/
public String getPath() {
return path;
@@ -884,7 +850,6 @@
* Gets the value of the user-info part of this URL.
*
* @return the user-info part of this URL.
- * @since Android 1.0
*/
public String getUserInfo() {
return userInfo;
@@ -894,7 +859,6 @@
* Gets the value of the authority part of this URL.
*
* @return the authority part of this URL.
- * @since Android 1.0
*/
public String getAuthority() {
return authority;
@@ -921,7 +885,6 @@
* the query to be set.
* @param ref
* the reference to be set.
- * @since Android 1.0
*/
protected void set(String protocol, String host, int port,
String authority, String userInfo, String path, String query,
@@ -941,21 +904,13 @@
this.query = query;
}
- // BEGIN android-removed
- // copied from newer version of harmony
- // URLStreamHandler getStreamHandler() {
- // return strmHandler;
- // }
- // END android-removed
-
/**
* Gets the default port number of the protocol used by this URL. If no
* default port is defined by the protocol or the {@code URLStreamHandler},
* {@code -1} will be returned.
- *
+ *
* @return the default port number according to the protocol of this URL.
* @see URLStreamHandler#getDefaultPort
- * @since Android 1.0
*/
public int getDefaultPort() {
return strmHandler.getDefaultPort();
diff --git a/luni/src/main/java/java/net/URLClassLoader.java b/luni/src/main/java/java/net/URLClassLoader.java
index c70ed45..dd3c9bf 100644
--- a/luni/src/main/java/java/net/URLClassLoader.java
+++ b/luni/src/main/java/java/net/URLClassLoader.java
@@ -17,12 +17,15 @@
package java.net;
+import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.AccessControlContext;
import java.security.AccessController;
@@ -35,22 +38,14 @@
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.IdentityHashMap;
import java.util.List;
-import java.util.ListIterator;
import java.util.Map;
-import java.util.Set;
import java.util.StringTokenizer;
-import java.util.Vector;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
-import java.util.zip.ZipEntry;
-import org.apache.harmony.luni.util.InvalidJarIndexException;
import org.apache.harmony.luni.util.Msg;
/**
@@ -58,33 +53,17 @@
* list of URLs which can refer to either directories or JAR files. Classes
* loaded by this {@code URLClassLoader} are granted permission to access the
* URLs contained in the URL search list.
- *
- * @since Android 1.0
*/
public class URLClassLoader extends SecureClassLoader {
- private static URL[] NO_PATH = new URL[0];
+ ArrayList<URL> originalUrls;
- @SuppressWarnings("unchecked")
- private static <K, V> Hashtable<K, V>[] newHashtableArray(int size) {
- return new Hashtable[size];
- }
-
- URL[] urls, orgUrls;
-
- Set<URL> invalidUrls = Collections.synchronizedSet(new HashSet<URL>());
-
- private Map<URL, JarFile> resCache =
- Collections.synchronizedMap(new IdentityHashMap<URL, JarFile>(32));
-
- private Object lock = new Object();
+ List<URL> searchList;
+ ArrayList<URLHandler> handlerList;
+ Map<URL, URLHandler> handlerMap = new HashMap<URL, URLHandler>();
private URLStreamHandlerFactory factory;
- HashMap<URL, URL[]> extensions;
-
- Hashtable<String, URL[]>[] indexes;
-
private AccessControlContext currentContext;
static class SubURLClassLoader extends URLClassLoader {
@@ -103,7 +82,7 @@
* Overrides the {@code loadClass()} of {@code ClassLoader}. It calls
* the security manager's {@code checkPackageAccess()} before
* attempting to load the class.
- *
+ *
* @return the Class object.
* @param className
* String the name of the class to search for.
@@ -115,7 +94,7 @@
*/
@Override
protected synchronized Class<?> loadClass(String className,
- boolean resolveClass) throws ClassNotFoundException {
+ boolean resolveClass) throws ClassNotFoundException {
SecurityManager sm = System.getSecurityManager();
if (sm != null && !checkingPackageAccess) {
int index = className.lastIndexOf('.');
@@ -132,12 +111,503 @@
}
}
+ static class IndexFile {
+
+ private HashMap<String, ArrayList<URL>> map;
+ //private URLClassLoader host;
+
+
+ static IndexFile readIndexFile(JarFile jf, JarEntry indexEntry, URL url) {
+ BufferedReader in = null;
+ InputStream is = null;
+ try {
+ // Add mappings from resource to jar file
+ String parentURLString = getParentURL(url).toExternalForm();
+ String prefix = "jar:" //$NON-NLS-1$
+ + parentURLString + "/"; //$NON-NLS-1$
+ is = jf.getInputStream(indexEntry);
+ in = new BufferedReader(new InputStreamReader(is, "UTF8"));
+ HashMap<String, ArrayList<URL>> pre_map = new HashMap<String, ArrayList<URL>>();
+ // Ignore the 2 first lines (index version)
+ if (in.readLine() == null) return null;
+ if (in.readLine() == null) return null;
+ TOP_CYCLE:
+ while (true) {
+ String line = in.readLine();
+ if (line == null) {
+ break;
+ }
+ URL jar = new URL(prefix + line + "!/"); //$NON-NLS-1$
+ while (true) {
+ line = in.readLine();
+ if (line == null) {
+ break TOP_CYCLE;
+ }
+ if ("".equals(line)) {
+ break;
+ }
+ ArrayList<URL> list;
+ if (pre_map.containsKey(line)) {
+ list = pre_map.get(line);
+ } else {
+ list = new ArrayList<URL>();
+ pre_map.put(line, list);
+ }
+ list.add(jar);
+ }
+ }
+ if (!pre_map.isEmpty()) {
+ return new IndexFile(pre_map);
+ }
+ } catch (MalformedURLException e) {
+ // Ignore this jar's index
+ } catch (IOException e) {
+ // Ignore this jar's index
+ }
+ finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ return null;
+ }
+
+ private static URL getParentURL(URL url) throws IOException {
+ URL fileURL = ((JarURLConnection) url.openConnection()).getJarFileURL();
+ String file = fileURL.getFile();
+ String parentFile = new File(file).getParent();
+ parentFile = parentFile.replace(File.separatorChar, '/');
+ if (parentFile.charAt(0) != '/') {
+ parentFile = "/" + parentFile; //$NON-NLS-1$
+ }
+ URL parentURL = new URL(fileURL.getProtocol(), fileURL
+ .getHost(), fileURL.getPort(), parentFile);
+ return parentURL;
+ }
+
+ public IndexFile(HashMap<String, ArrayList<URL>> map) {
+ this.map = map;
+ }
+
+ ArrayList<URL> get(String name) {
+ return map.get(name);
+ }
+ }
+
+ class URLHandler {
+ URL url;
+ URL codeSourceUrl;
+
+ public URLHandler(URL url) {
+ this.url = url;
+ this.codeSourceUrl = url;
+ }
+
+ void findResources(String name, ArrayList<URL> resources) {
+ URL res = findResource(name);
+ if (res != null && !resources.contains(res)) {
+ resources.add(res);
+ }
+ }
+
+ Class<?> findClass(String packageName, String name, String origName) {
+ URL resURL = targetURL(url, name);
+ if (resURL != null) {
+ try {
+ InputStream is = resURL.openStream();
+ return createClass(is, packageName, origName);
+ } catch (IOException e) {
+ }
+ }
+ return null;
+ }
+
+
+ Class<?> createClass(InputStream is, String packageName, String origName) {
+ if (is == null) {
+ return null;
+ }
+ byte[] clBuf = null;
+ try {
+ clBuf = getBytes(is);
+ } catch (IOException e) {
+ return null;
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ if (packageName != null) {
+ String packageDotName = packageName.replace('/', '.');
+ Package packageObj = getPackage(packageDotName);
+ if (packageObj == null) {
+ definePackage(packageDotName, null, null,
+ null, null, null, null, null);
+ } else {
+ if (packageObj.isSealed()) {
+ throw new SecurityException(Msg
+ .getString("K004c")); //$NON-NLS-1$
+ }
+ }
+ }
+ return defineClass(origName, clBuf, 0, clBuf.length, new CodeSource(codeSourceUrl, (Certificate[]) null));
+ }
+
+ URL findResource(String name) {
+ URL resURL = targetURL(url, name);
+ if (resURL != null) {
+ try {
+ URLConnection uc = resURL.openConnection();
+ uc.getInputStream().close();
+ // HTTP can return a stream on a non-existent file
+ // So check for the return code;
+ if (!resURL.getProtocol().equals("http")) { //$NON-NLS-1$
+ return resURL;
+ }
+ int code;
+ if ((code = ((HttpURLConnection) uc).getResponseCode()) >= 200
+ && code < 300) {
+ return resURL;
+ }
+ } catch (SecurityException e) {
+ return null;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ URL targetURL(URL base, String name) {
+ try {
+ String file = base.getFile() + URIEncoderDecoder.quoteIllegal(name,
+ "/@" + URI.someLegal);
+
+ return new URL(base.getProtocol(), base.getHost(), base.getPort(),
+ file, null);
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ }
+
+ class URLJarHandler extends URLHandler {
+ final JarFile jf;
+ final String prefixName;
+ final IndexFile index;
+ final Map<URL, URLHandler> subHandlers = new HashMap<URL, URLHandler>();
+
+ public URLJarHandler(URL url, URL jarURL, JarFile jf, String prefixName) {
+ super(url);
+ this.jf = jf;
+ this.prefixName = prefixName;
+ this.codeSourceUrl = jarURL;
+ final JarEntry je = jf.getJarEntry("META-INF/INDEX.LIST"); //$NON-NLS-1$
+ this.index = (je == null ? null : IndexFile.readIndexFile(jf, je, url));
+ }
+
+ public URLJarHandler(URL url, URL jarURL, JarFile jf, String prefixName, IndexFile index) {
+ super(url);
+ this.jf = jf;
+ this.prefixName = prefixName;
+ this.index = index;
+ this.codeSourceUrl = jarURL;
+ }
+
+ IndexFile getIndex() {
+ return index;
+ }
+
+ @Override
+ void findResources(String name, ArrayList<URL> resources) {
+ URL res = findResourceInOwn(name);
+ if (res != null && !resources.contains(res)) {
+ resources.add(res);
+ }
+ if (index != null) {
+ int pos = name.lastIndexOf("/"); //$NON-NLS-1$
+ // only keep the directory part of the resource
+ // as index.list only keeps track of directories and root files
+ String indexedName = (pos > 0) ? name.substring(0, pos) : name;
+ ArrayList<URL> urls = index.get(indexedName);
+ if (urls != null) {
+ urls.remove(url);
+ for (URL url : urls) {
+ URLHandler h = getSubHandler(url);
+ if (h != null) {
+ h.findResources(name, resources);
+ }
+ }
+ }
+ }
+
+ }
+
+ @Override
+ Class<?> findClass(String packageName, String name, String origName) {
+ String entryName = prefixName + name;
+ JarEntry entry = jf.getJarEntry(entryName);
+ if (entry != null) {
+ /**
+ * Avoid recursive load class, especially the class
+ * is an implementation class of security provider
+ * and the jar is signed.
+ */
+ try {
+ Manifest manifest = jf.getManifest();
+ return createClass(entry, manifest, packageName, origName);
+ } catch (IOException e) {
+ }
+ }
+ if (index != null) {
+ ArrayList<URL> urls;
+ if (packageName == null) {
+ urls = index.get(name);
+ } else {
+ urls = index.get(packageName);
+ }
+ if (urls != null) {
+ urls.remove(url);
+ for (URL url : urls) {
+ URLHandler h = getSubHandler(url);
+ if (h != null) {
+ Class<?> res = h.findClass(packageName, name, origName);
+ if (res != null) {
+ return res;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private Class<?> createClass(JarEntry entry, Manifest manifest, String packageName, String origName) {
+ InputStream is = null;
+ byte[] clBuf = null;
+ try {
+ is = jf.getInputStream(entry);
+ clBuf = getBytes(is);
+ } catch (IOException e) {
+ return null;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ if (packageName != null) {
+ String packageDotName = packageName.replace('/', '.');
+ Package packageObj = getPackage(packageDotName);
+ if (packageObj == null) {
+ if (manifest != null) {
+ definePackage(packageDotName, manifest,
+ codeSourceUrl);
+ } else {
+ definePackage(packageDotName, null, null,
+ null, null, null, null, null);
+ }
+ } else {
+ boolean exception = packageObj.isSealed();
+ if (manifest != null) {
+ if (isSealed(manifest, packageName + "/")) {
+ exception = !packageObj
+ .isSealed(codeSourceUrl);
+ }
+ }
+ if (exception) {
+ throw new SecurityException(Msg
+ .getString("K0352", packageName)); //$NON-NLS-1$
+ }
+ }
+ }
+ CodeSource codeS = new CodeSource(codeSourceUrl, entry.getCertificates());
+ return defineClass(origName, clBuf, 0, clBuf.length, codeS);
+ }
+
+ URL findResourceInOwn(String name) {
+ String entryName = prefixName + name;
+ if (jf.getEntry(entryName) != null) {
+ return targetURL(url, name);
+ }
+ return null;
+ }
+
+ @Override
+ URL findResource(String name) {
+ URL res = findResourceInOwn(name);
+ if (res != null) {
+ return res;
+ }
+ if (index != null) {
+ int pos = name.lastIndexOf("/"); //$NON-NLS-1$
+ // only keep the directory part of the resource
+ // as index.list only keeps track of directories and root files
+ String indexedName = (pos > 0) ? name.substring(0, pos) : name;
+ ArrayList<URL> urls = index.get(indexedName);
+ if (urls != null) {
+ urls.remove(url);
+ for (URL url : urls) {
+ URLHandler h = getSubHandler(url);
+ if (h != null) {
+ res = h.findResource(name);
+ if (res != null) {
+ return res;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private synchronized URLHandler getSubHandler(URL url) {
+ URLHandler sub = subHandlers.get(url);
+ if (sub != null) {
+ return sub;
+ }
+ String protocol = url.getProtocol();
+ if (protocol.equals("jar")) { //$NON-NLS-1$
+ sub = createURLJarHandler(url);
+ } else if (protocol.equals("file")) { //$NON-NLS-1$
+ sub = createURLSubJarHandler(url);
+ } else {
+ sub = createURLHandler(url);
+ }
+ if (sub != null) {
+ subHandlers.put(url, sub);
+ }
+ return sub;
+ }
+
+ private URLHandler createURLSubJarHandler(URL url) {
+ String prefixName;
+ String file = url.getFile();
+ if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
+ prefixName = "";
+ } else {
+ int sepIdx = file.lastIndexOf("!/"); //$NON-NLS-1$
+ if (sepIdx == -1) {
+ // Invalid URL, don't look here again
+ return null;
+ }
+ sepIdx += 2;
+ prefixName = file.substring(sepIdx);
+ }
+ try {
+ URL jarURL = ((JarURLConnection) url
+ .openConnection()).getJarFileURL();
+ JarURLConnection juc = (JarURLConnection) new URL(
+ "jar", "", //$NON-NLS-1$ //$NON-NLS-2$
+ jarURL.toExternalForm() + "!/").openConnection(); //$NON-NLS-1$
+ JarFile jf = juc.getJarFile();
+ URLJarHandler jarH = new URLJarHandler(url, jarURL, jf, prefixName, null);
+ // TODO : to think what we should do with indexes & manifest.class file here
+ return jarH;
+ } catch (IOException e) {
+ }
+ return null;
+ }
+
+ }
+
+ class URLFileHandler extends URLHandler {
+ private String prefix;
+
+ public URLFileHandler(URL url) {
+ super(url);
+ String baseFile = url.getFile();
+ String host = url.getHost();
+ int hostLength = 0;
+ if (host != null) {
+ hostLength = host.length();
+ }
+ StringBuilder buf = new StringBuilder(2 + hostLength
+ + baseFile.length());
+ if (hostLength > 0) {
+ buf.append("//").append(host); //$NON-NLS-1$
+ }
+ // baseFile always ends with '/'
+ buf.append(baseFile);
+ prefix = buf.toString();
+ }
+
+ @Override
+ Class<?> findClass(String packageName, String name, String origName) {
+ String filename = prefix + name;
+ try {
+ filename = URLDecoder.decode(filename, "UTF-8"); //$NON-NLS-1$
+ } catch (IllegalArgumentException e) {
+ return null;
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ }
+
+ File file = new File(filename);
+ if (file.exists()) {
+ try {
+ InputStream is = new FileInputStream(file);
+ return createClass(is, packageName, origName);
+ } catch (FileNotFoundException e) {
+ }
+ }
+ return null;
+ }
+
+ @Override
+ URL findResource(String name) {
+ int idx = 0;
+ String filename;
+
+ // Do not create a UNC path, i.e. \\host
+ while (idx < name.length() &&
+ ((name.charAt(idx) == '/') || (name.charAt(idx) == '\\'))) {
+ idx++;
+ }
+
+ if (idx > 0) {
+ name = name.substring(idx);
+ }
+
+ try {
+ filename = URLDecoder.decode(prefix, "UTF-8") + name; //$NON-NLS-1$
+
+ if (new File(filename).exists()) {
+ return targetURL(url, name);
+ }
+ return null;
+ } catch (IllegalArgumentException e) {
+ return null;
+ } catch (UnsupportedEncodingException e) {
+ // must not happen
+ throw new AssertionError(e);
+ }
+ }
+
+ }
+
+
/**
* Constructs a new {@code URLClassLoader} instance. The newly created
* instance will have the system ClassLoader as its parent. URLs that end
* with "/" are assumed to be directories, otherwise they are assumed to be
* JAR files.
- *
+ *
* @param urls
* the list of URLs where a specific class or file could be
* found.
@@ -145,7 +615,6 @@
* if a security manager exists and its {@code
* checkCreateClassLoader()} method doesn't allow creation of
* new ClassLoaders.
- * @since Android 1.0
*/
public URLClassLoader(URL[] urls) {
this(urls, ClassLoader.getSystemClassLoader(), null);
@@ -155,7 +624,7 @@
* Constructs a new URLClassLoader instance. The newly created instance will
* have the system ClassLoader as its parent. URLs that end with "/" are
* assumed to be directories, otherwise they are assumed to be JAR files.
- *
+ *
* @param urls
* the list of URLs where a specific class or file could be
* found.
@@ -165,7 +634,6 @@
* if a security manager exists and its {@code
* checkCreateClassLoader()} method doesn't allow creation of
* new class loaders.
- * @since Android 1.0
*/
public URLClassLoader(URL[] urls, ClassLoader parent) {
this(urls, parent, null);
@@ -173,267 +641,81 @@
/**
* Adds the specified URL to the search list.
- *
+ *
* @param url
* the URL which is to add.
- * @since Android 1.0
*/
protected void addURL(URL url) {
try {
- URL search = createSearchURL(url);
- urls = addURL(urls, search);
- orgUrls = addURL(orgUrls, url);
- synchronized (extensions) {
- extensions.put(search, null);
- }
+ originalUrls.add(url);
+ searchList.add(createSearchURL(url));
} catch (MalformedURLException e) {
}
}
/**
- * Returns an array with the given URL added to the given array.
- *
- * @param urlArray
- * {@code java.net.URL[]} the source array
- * @param url
- * {@code java.net.URL} the URL to be added
- * @return java.net.URL[] an array made of the given array and the new URL
- */
- URL[] addURL(URL[] urlArray, URL url) {
- URL[] newPath = new URL[urlArray.length + 1];
- System.arraycopy(urlArray, 0, newPath, 0, urlArray.length);
- newPath[urlArray.length] = url;
- Hashtable<String, URL[]>[] newIndexes = newHashtableArray(indexes.length + 1);
- System.arraycopy(indexes, 0, newIndexes, 0, indexes.length);
- indexes = newIndexes;
- return newPath;
- }
-
- /**
* Returns all known URLs which point to the specified resource.
- *
+ *
* @param name
* the name of the requested resource.
* @return the enumeration of URLs which point to the specified resource.
* @throws IOException
* if an I/O error occurs while attempting to connect.
- * @since Android 1.0
*/
@Override
public Enumeration<URL> findResources(final String name) throws IOException {
if (name == null) {
return null;
}
- Vector<URL> result = AccessController.doPrivileged(
- new PrivilegedAction<Vector<URL>>() {
- public Vector<URL> run() {
- return findResources(urls, name, new Vector<URL>());
+ ArrayList<URL> result = AccessController.doPrivileged(
+ new PrivilegedAction<ArrayList<URL>>() {
+ public ArrayList<URL> run() {
+ ArrayList<URL> results = new ArrayList<URL>();
+ findResourcesImpl(name, results);
+ return results;
}
}, currentContext);
SecurityManager sm;
int length = result.size();
if (length > 0 && (sm = System.getSecurityManager()) != null) {
- Vector<URL> reduced = new Vector<URL>(length);
+ ArrayList<URL> reduced = new ArrayList<URL>(length);
for (int i = 0; i < length; i++) {
- URL url = result.elementAt(i);
+ URL url = result.get(i);
try {
sm.checkPermission(url.openConnection().getPermission());
- reduced.addElement(url);
+ reduced.add(url);
} catch (IOException e) {
} catch (SecurityException e) {
}
}
result = reduced;
}
- return result.elements();
+ return Collections.enumeration(result);
}
- /**
- * Returns a Vector of URLs among the given ones that contain the specified
- * resource.
- *
- * @return Vector the enumeration of URLs that contain the specified
- * resource.
- * @param searchURLs
- * {@code java.net.URL[]} the array to be searched.
- * @param name
- * {@code java.lang.String} the name of the requested resource.
- */
- Vector<URL> findResources(URL[] searchURLs, String name, Vector<URL> result) {
- boolean findInExtensions = searchURLs == urls;
- for (int i = 0; i < searchURLs.length; i++) {
- if (!invalidUrls.contains(searchURLs[i])) {
- URL[] search = new URL[] { searchURLs[i] };
- URL res = findResourceImpl(search, name);
- if (!invalidUrls.contains(search[0])) {
- if (res != null && !result.contains(res)) {
- result.addElement(res);
- }
- if (findInExtensions) {
- findInExtensions(explore(searchURLs[i], i), name, i,
- result, false);
- }
- }
+ void findResourcesImpl(String name, ArrayList<URL> result) {
+ int n = 0;
+ while (true) {
+ URLHandler handler = getHandler(n++);
+ if (handler == null) {
+ break;
}
+ handler.findResources(name, result);
}
- return result;
}
- /**
- * Returns an {@code Object[]} containing a class, a URL, and a vector of
- * URLs, two of which are {@code null}, according to the caller, which is
- * identified by the {@code int} type.
- *
- * @return Object[] a 3-element array : {Class, URL, Vector}. The non-null
- * element contains the resource(s) found, which are searched in in
- * {@code indexes[i]}.
- * @param i
- * the index of 'indexes' array to use.
- * @param name
- * the resource to look for : either a resource or a class.
- * @param resources
- * {@code boolean} indicates that a vector of URL should be
- * returned as the non {@code null} element in {@code Object[]}.
- * @param url
- * if {@code true} a URL should be returned as the non-null
- * element, if {@code false} a class should be returned.
- */
- Object findInIndex(int i, String name, Vector<URL> resources, boolean url) {
- Hashtable<String, URL[]> index = indexes[i];
- if (index != null) {
- int pos = name.lastIndexOf("/"); //$NON-NLS-1$
- // only keep the directory part of the resource
- // as index.list only keeps track of directories and root files
- String indexedName = (pos > 0) ? name.substring(0, pos) : name;
- URL[] jarURLs;
- if (resources != null) {
- jarURLs = index.get(indexedName);
- if (jarURLs != null) {
- findResources(jarURLs, name, resources);
- }
- } else if (url) {
- jarURLs = index.get(indexedName);
- if (jarURLs != null) {
- return findResourceImpl(jarURLs, name);
- }
- } else {
- String clsName = name;
- String partialName = clsName.replace('.', '/');
- int position;
- if ((position = partialName.lastIndexOf('/')) != -1) {
- String packageName = partialName.substring(0, position);
- jarURLs = index.get(packageName);
- } else {
- String className = partialName.substring(0, partialName
- .length())
- + ".class"; //$NON-NLS-1$
- jarURLs = index.get(className);
- }
- if (jarURLs != null) {
- Class<?> c = findClassImpl(jarURLs, clsName);
- // InvalidJarException is thrown when a mapping for a class
- // is not valid, i.e. we can't find the class by following
- // the mapping.
- if (c == null) {
- throw new InvalidJarIndexException();
- }
- return c;
- }
- }
- }
- return null;
- }
-
- /**
- * Returns an {@code Object[]} containing a Class, a URL, and a Vector of
- * URLs, two of which are {@code null}, according to the caller, which is
- * identified by the {@code int} type.
- *
- * @return Object[] a 3-element array : {Class, URL, Vector}. The non-null
- * element contains the resource(s) found, which are searched in
- * newExtensions.
- * @param newExtensions
- * URL[] the URLs to look in for.
- * @param name
- * the resource to look for : either a resource or a class.
- * @param i
- * the index of 'indexes' array to use.
- * @param resources
- * indicates that a Vector of URL should be returned as the
- * non-null element in {@code Object[]}.
- * @param url
- * if {@code true} a URL should be returned as the non-null
- * element, if {@code false} a class should be returned.
- */
- Object findInExtensions(URL[] newExtensions, String name, int i,
- Vector<URL> resources, boolean url) {
- if (newExtensions != null) {
- for (int k = 0; k < newExtensions.length; k++) {
- if (newExtensions[k] != null) {
- URL[] search = new URL[] { newExtensions[k] };
- if (resources != null) {
- URL res = findResourceImpl(search, name);
- if (!invalidUrls.contains(search[0])) { // the URL does
- // not exist
- if (res != null && !resources.contains(res)) {
- resources.addElement(res);
- }
- findInExtensions(explore(newExtensions[k], i),
- name, i, resources, url);
- }
- } else {
- Object result;
- if (url) {
- result = findResourceImpl(search, name);
- } else {
- result = findClassImpl(search, name);
- }
- if (result != null) {
- return result;
- }
- if (!invalidUrls.contains(search[0])) { // the URL
- // exists
- result = findInExtensions(explore(newExtensions[k],
- i), name, i, null, url);
- if (result != null) {
- return result;
- }
- }
- }
- }
- }
- } else {
- try {
- return findInIndex(i, name, resources, url);
- } catch (InvalidJarIndexException ex) {
- // Ignore misleading/wrong jar index
- return null;
- }
- }
- return null;
- }
/**
* Converts an input stream into a byte array.
- *
- * @return byte[] the byte array
+ *
* @param is
* the input stream
+ * @return byte[] the byte array
*/
- private static byte[] getBytes(InputStream is, boolean readAvailable)
+ private static byte[] getBytes(InputStream is)
throws IOException {
- if (readAvailable) {
- byte[] buf = new byte[is.available()];
- is.read(buf, 0, buf.length);
- is.close();
- return buf;
- }
byte[] buf = new byte[4096];
- int size = is.available();
- if (size < 1024) {
- size = 1024;
- }
- ByteArrayOutputStream bos = new ByteArrayOutputStream(size);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(4096);
int count;
while ((count = is.read(buf)) > 0) {
bos.write(buf, 0, count);
@@ -448,11 +730,10 @@
* read permission to the file is added to the permission collection.
* Otherwise, connecting to and accepting connections from the URL is
* granted.
- *
+ *
* @param codesource
* the code source object whose permissions have to be known.
* @return the list of permissions according to the code source object.
- * @since Android 1.0
*/
@Override
protected PermissionCollection getPermissions(final CodeSource codesource) {
@@ -494,12 +775,11 @@
/**
* Returns the search list of this {@code URLClassLoader}.
- *
+ *
* @return the list of all known URLs of this instance.
- * @since Android 1.0
*/
public URL[] getURLs() {
- return orgUrls.clone();
+ return originalUrls.toArray(new URL[originalUrls.size()]);
}
/**
@@ -515,12 +795,11 @@
* system {@code ClassLoader} as its parent. The method {@code loadClass()}
* of the new instance will call {@code
* SecurityManager.checkPackageAccess()} before loading a class.
- *
+ *
* @param urls
* the list of URLs that is passed to the new {@code
* URLClassloader}.
* @return the created {@code URLClassLoader} instance.
- * @since Android 1.0
*/
public static URLClassLoader newInstance(final URL[] urls) {
URLClassLoader sub = AccessController
@@ -538,17 +817,16 @@
* specified {@code ClassLoader} as its parent. The method {@code
* loadClass()} of the new instance will call the SecurityManager's {@code
* checkPackageAccess()} before loading a class.
- *
+ *
* @param urls
* the list of URLs that is passed to the new URLClassloader.
* @param parentCl
* the parent class loader that is passed to the new
* URLClassloader.
* @return the created {@code URLClassLoader} instance.
- * @since Android 1.0
*/
public static URLClassLoader newInstance(final URL[] urls,
- final ClassLoader parentCl) {
+ final ClassLoader parentCl) {
URLClassLoader sub = AccessController
.doPrivileged(new PrivilegedAction<URLClassLoader>() {
public URLClassLoader run() {
@@ -565,7 +843,7 @@
* use the specified factory to create stream handlers. URLs that end with
* "/" are assumed to be directories, otherwise they are assumed to be JAR
* files.
- *
+ *
* @param searchUrls
* the list of URLs where a specific class or file could be
* found.
@@ -578,10 +856,9 @@
* if a security manager exists and its {@code
* checkCreateClassLoader()} method doesn't allow creation of
* new {@code ClassLoader}s.
- * @since Android 1.0
*/
public URLClassLoader(URL[] searchUrls, ClassLoader parent,
- URLStreamHandlerFactory factory) {
+ URLStreamHandlerFactory factory) {
super(parent);
// Required for pre-v1.2 security managers to work
SecurityManager security = System.getSecurityManager();
@@ -592,33 +869,28 @@
// capture the context of the thread that creates this URLClassLoader
currentContext = AccessController.getContext();
int nbUrls = searchUrls.length;
- urls = new URL[nbUrls];
- orgUrls = new URL[nbUrls];
- // Search each jar for CLASS-PATH attribute in manifest
- extensions = new HashMap<URL, URL[]>(nbUrls * 2);
+ originalUrls = new ArrayList<URL>(nbUrls);
+ handlerList = new ArrayList<URLHandler>(nbUrls);
+ searchList = Collections.synchronizedList(new ArrayList<URL>(nbUrls));
for (int i = 0; i < nbUrls; i++) {
+ originalUrls.add(searchUrls[i]);
try {
- urls[i] = createSearchURL(searchUrls[i]);
- extensions.put(urls[i], null);
+ searchList.add(createSearchURL(searchUrls[i]));
} catch (MalformedURLException e) {
}
- orgUrls[i] = searchUrls[i];
}
- // Search each jar for META-INF/INDEX.LIST
- indexes = newHashtableArray(nbUrls);
}
/**
* Tries to locate and load the specified class using the known URLs. If the
* class could be found, a class object representing the loaded class will
* be returned.
- *
- * @return the class that has been loaded.
+ *
* @param clsName
* the name of the class which has to be found.
+ * @return the class that has been loaded.
* @throws ClassNotFoundException
* if the specified class cannot be loaded.
- * @since Android 1.0
*/
@Override
protected Class<?> findClass(final String clsName)
@@ -626,7 +898,7 @@
Class<?> cls = AccessController.doPrivileged(
new PrivilegedAction<Class<?>>() {
public Class<?> run() {
- return findClassImpl(urls, clsName);
+ return findClassImpl(clsName);
}
}, currentContext);
if (cls != null) {
@@ -639,7 +911,7 @@
* Returns an URL that will be checked if it contains the class or resource.
* If the file component of the URL is not a directory, a Jar URL will be
* created.
- *
+ *
* @return java.net.URL a test URL
*/
private URL createSearchURL(URL url) throws MalformedURLException {
@@ -656,19 +928,19 @@
return new URL("jar", "", //$NON-NLS-1$ //$NON-NLS-2$
-1, url.toString() + "!/"); //$NON-NLS-1$
}
+ // use jar protocol as the stream handler protocol
return new URL("jar", "", //$NON-NLS-1$ //$NON-NLS-2$
-1, url.toString() + "!/", //$NON-NLS-1$
- factory.createURLStreamHandler(protocol));
+ factory.createURLStreamHandler("jar"));//$NON-NLS-1$
}
/**
* Returns an URL referencing the specified resource or {@code null} if the
* resource could not be found.
- *
+ *
* @param name
* the name of the requested resource.
* @return the URL which points to the given resource.
- * @since Android 1.0
*/
@Override
public URL findResource(final String name) {
@@ -677,7 +949,7 @@
}
URL result = AccessController.doPrivileged(new PrivilegedAction<URL>() {
public URL run() {
- return findResourceImpl(urls, name);
+ return findResourceImpl(name);
}
}, currentContext);
SecurityManager sm;
@@ -696,161 +968,108 @@
/**
* Returns a URL among the given ones referencing the specified resource or
* null if no resource could be found.
- *
+ *
+ * @param resName java.lang.String the name of the requested resource
* @return URL URL for the resource.
- * @param searchList
- * java.net.URL[] the array to be searched
- * @param resName
- * java.lang.String the name of the requested resource
*/
- URL findResourceImpl(URL[] searchList, String resName) {
- boolean findInExtensions = searchList == urls;
- int i = 0;
- while (i < searchList.length) {
- if (searchList[i] == null) {
- // KA024=One of urls is null
+ URL findResourceImpl(String resName) {
+ int n = 0;
+
+ while (true) {
+ URLHandler handler = getHandler(n++);
+ if (handler == null) {
+ break;
+ }
+ URL res = handler.findResource(resName);
+ if (res != null) {
+ return res;
+ }
+ }
+ return null;
+ }
+
+ URLHandler getHandler(int num) {
+ if (num < handlerList.size()) {
+ return handlerList.get(num);
+ }
+ makeNewHandler();
+ if (num < handlerList.size()) {
+ return handlerList.get(num);
+ }
+ return null;
+ }
+
+ private synchronized void makeNewHandler() {
+ while (!searchList.isEmpty()) {
+ URL nextCandidate = searchList.remove(0);
+ if (nextCandidate == null) { // KA024=One of urls is null
throw new NullPointerException(Msg.getString("KA024")); //$NON-NLS-1$
- } else if (!invalidUrls.contains(searchList[i])) {
- JarFile jf = null;
- try {
- URL currentUrl = searchList[i];
- String protocol = currentUrl.getProtocol();
-
- if (protocol.equals("jar")) { //$NON-NLS-1$
- jf = resCache.get(currentUrl);
- if (jf == null) {
- if (invalidUrls.contains(currentUrl)) {
- continue;
- }
- // each jf should be found only once
- // so we do this job in the synchronized block
- synchronized (lock) {
- // Check the cache again in case another thread
- // updated it while we're waiting on lock
- jf = resCache.get(currentUrl);
- if (jf == null) {
- if (invalidUrls.contains(currentUrl)) {
- continue;
- }
- /*
- * If the connection for currentUrl or resURL is
- * used, getJarFile() will throw an exception if the
- * entry doesn't exist.
- */
- URL jarURL = ((JarURLConnection) currentUrl
- .openConnection()).getJarFileURL();
- try {
- JarURLConnection juc = (JarURLConnection) new URL(
- "jar", "", //$NON-NLS-1$ //$NON-NLS-2$
- jarURL.toExternalForm() + "!/").openConnection(); //$NON-NLS-1$
- jf = juc.getJarFile();
- resCache.put(currentUrl, jf);
- } catch (IOException e) {
- // Don't look for this jar file again
- invalidUrls.add(searchList[i]);
- throw e;
- }
- }
- }
- }
- String entryName;
- if (currentUrl.getFile().endsWith("!/")) { //$NON-NLS-1$
- entryName = resName;
- } else {
- String file = currentUrl.getFile();
- int sepIdx = file.lastIndexOf("!/"); //$NON-NLS-1$
- if (sepIdx == -1) {
- // Invalid URL, don't look here again
- invalidUrls.add(searchList[i]);
- continue;
- }
- sepIdx += 2;
- entryName = new StringBuffer(file.length() - sepIdx
- + resName.length()).append(
- file.substring(sepIdx)).append(resName)
- .toString();
- }
- if (jf.getEntry(entryName) != null) {
- return targetURL(currentUrl, resName);
- }
- } else if (protocol.equals("file")) { //$NON-NLS-1$
- String baseFile = currentUrl.getFile();
- String host = currentUrl.getHost();
- int hostLength = 0;
- if (host != null) {
- hostLength = host.length();
- }
- StringBuffer buf = new StringBuffer(2 + hostLength
- + baseFile.length() + resName.length());
- if (hostLength > 0) {
- buf.append("//").append(host); //$NON-NLS-1$
- }
- // baseFile always ends with '/'
- buf.append(baseFile);
- String fixedResName = resName;
- // Do not create a UNC path, i.e. \\host
- while (fixedResName.startsWith("/") //$NON-NLS-1$
- || fixedResName.startsWith("\\")) { //$NON-NLS-1$
- fixedResName = fixedResName.substring(1);
- }
- buf.append(fixedResName);
-
- String filename = buf.toString();
-
- try {
- filename = URLDecoder.decode(filename, "UTF-8"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- return null;
- }
-
- if (new File(filename).exists()) {
- return targetURL(currentUrl, fixedResName);
- }
- } else {
- URL resURL = targetURL(currentUrl, resName);
- URLConnection uc = resURL.openConnection();
- try {
- uc.getInputStream().close();
- } catch (SecurityException e) {
- return null;
- }
- // HTTP can return a stream on a non-existent file
- // So check for the return code;
- if (!resURL.getProtocol().equals("http")) { //$NON-NLS-1$
- return resURL;
- }
- int code;
- if ((code = ((HttpURLConnection) uc).getResponseCode()) >= 200
- && code < 300) {
- return resURL;
- }
- }
- } catch (MalformedURLException e) {
- // Keep iterating through the URL list
- } catch (IOException e) {
- } catch (SecurityException e) {
+ }
+ if (!handlerMap.containsKey(nextCandidate)) {
+ URLHandler result;
+ String protocol = nextCandidate.getProtocol();
+ if (protocol.equals("jar")) { //$NON-NLS-1$
+ result = createURLJarHandler(nextCandidate);
+ } else if (protocol.equals("file")) { //$NON-NLS-1$
+ result = createURLFileHandler(nextCandidate);
+ } else {
+ result = createURLHandler(nextCandidate);
}
- if ((jf != null) && findInExtensions) {
- if (indexes[i] != null) {
- try {
- URL result = (URL) findInIndex(i, resName, null,
- true);
- if (result != null) {
- return result;
- }
- } catch (InvalidJarIndexException ex) {
- // Ignore invalid/misleading JAR index file
- }
- } else {
- URL result = (URL) findInExtensions(explore(
- searchList[i], i), resName, i, null, true);
- if (result != null) {
- return result;
- }
- }
+ if (result != null) {
+ handlerMap.put(nextCandidate, result);
+ handlerList.add(result);
+ return;
}
}
- ++i;
+ }
+ }
+
+ private URLHandler createURLHandler(URL url) {
+ return new URLHandler(url);
+ }
+
+ private URLHandler createURLFileHandler(URL url) {
+ return new URLFileHandler(url);
+ }
+
+ private URLHandler createURLJarHandler(URL url) {
+ String prefixName;
+ String file = url.getFile();
+ if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
+ prefixName = "";
+ } else {
+ int sepIdx = file.lastIndexOf("!/"); //$NON-NLS-1$
+ if (sepIdx == -1) {
+ // Invalid URL, don't look here again
+ return null;
+ }
+ sepIdx += 2;
+ prefixName = file.substring(sepIdx);
+ }
+ try {
+ URL jarURL = ((JarURLConnection) url
+ .openConnection()).getJarFileURL();
+ JarURLConnection juc = (JarURLConnection) new URL(
+ "jar", "", //$NON-NLS-1$ //$NON-NLS-2$
+ jarURL.toExternalForm() + "!/").openConnection(); //$NON-NLS-1$
+ JarFile jf = juc.getJarFile();
+ URLJarHandler jarH = new URLJarHandler(url, jarURL, jf, prefixName);
+
+ if (jarH.getIndex() == null) {
+ try {
+ Manifest manifest = jf.getManifest();
+ if (manifest != null) {
+ String classpath = manifest.getMainAttributes().getValue(
+ Attributes.Name.CLASS_PATH);
+ if (classpath != null) {
+ searchList.addAll(0, getInternalURLs(url, classpath));
+ }
+ }
+ } catch (IOException e) {
+ }
+ }
+ return jarH;
+ } catch (IOException e) {
}
return null;
}
@@ -858,7 +1077,7 @@
/**
* Defines a new package using the information extracted from the specified
* manifest.
- *
+ *
* @param packageName
* the name of the new package.
* @param manifest
@@ -869,10 +1088,9 @@
* @return the created package.
* @throws IllegalArgumentException
* if a package with the given name already exists.
- * @since Android 1.0
*/
protected Package definePackage(String packageName, Manifest manifest,
- URL url) throws IllegalArgumentException {
+ URL url) throws IllegalArgumentException {
Attributes mainAttributes = manifest.getMainAttributes();
String dirName = packageName.replace('.', '/') + "/"; //$NON-NLS-1$
Attributes packageAttributes = manifest.getAttributes(dirName);
@@ -921,7 +1139,7 @@
return definePackage(packageName, specificationTitle,
specificationVersion, specificationVendor, implementationTitle,
implementationVersion, implementationVendor, isSealed(manifest,
- dirName) ? url : null);
+ dirName) ? url : null);
}
private boolean isSealed(Manifest manifest, String dirName) {
@@ -940,19 +1158,18 @@
/**
* returns URLs referenced in the string classpath.
- *
+ *
* @param root
* the jar URL that classpath is related to
* @param classpath
* the relative URLs separated by spaces
- *
* @return URL[] the URLs contained in the string classpath.
*/
- private URL[] getInternalURLs(URL root, String classpath) {
+ private ArrayList<URL> getInternalURLs(URL root, String classpath) {
// Class-path attribute is composed of space-separated values.
StringTokenizer tokenizer = new java.util.StringTokenizer(classpath);
- Vector<URL> addedURLs = new Vector<URL>();
- String file = root.getFile();
+ ArrayList<URL> addedURLs = new ArrayList<URL>();
+ String file = root.getFile();
int jarIndex = file.lastIndexOf("!/") - 1; //$NON-NLS-1$
int index = file.lastIndexOf("/", jarIndex) + 1; //$NON-NLS-1$
if (index == 0) {
@@ -969,381 +1186,40 @@
try {
URL newURL = new URL(protocol, host, port, file + element
+ "!/"); //$NON-NLS-1$
- synchronized (extensions) {
- if (!extensions.containsKey(newURL)) {
- extensions.put(newURL, null);
- addedURLs.add(newURL);
- }
- }
+ addedURLs.add(newURL);
} catch (MalformedURLException e) {
// Nothing is added
}
}
}
- URL[] newURLs = addedURLs.toArray(new URL[] {});
- return newURLs;
+ return addedURLs;
}
- /**
- * @param in
- * InputStream the stream to read lines from
- * @return List a list of String lines
- */
- private List<String> readLines(InputStream in) throws IOException {
- byte[] buff = new byte[144];
- List<String> lines = new ArrayList<String>();
- int pos = 0;
- int next;
- while ((next = in.read()) != -1) {
- if (next == '\n') {
- lines.add(new String(buff, 0, pos, "UTF8")); //$NON-NLS-1$
- pos = 0;
- continue;
- }
- if (next == '\r') {
- lines.add(new String(buff, 0, pos, "UTF8")); //$NON-NLS-1$
- pos = 0;
- if ((next = in.read()) == '\n') {
- continue;
- }
- }
- if (pos == buff.length) {
- byte[] newBuf = new byte[buff.length * 2];
- System.arraycopy(buff, 0, newBuf, 0, buff.length);
- buff = newBuf;
- }
- buff[pos++] = (byte) next;
+ Class<?> findClassImpl(String className) {
+ Class<?> loadedClass = findLoadedClass(className);
+ if (null != loadedClass) {
+ return loadedClass;
}
- if (pos > 0) {
- lines.add(new String(buff, 0, pos, "UTF8")); //$NON-NLS-1$
+ String partialName = className.replace('.', '/');
+ final String classFileName = new StringBuilder(partialName).append(".class").toString(); //$NON-NLS-1$
+ String packageName = null;
+ int position = partialName.lastIndexOf('/');
+ if ((position = partialName.lastIndexOf('/')) != -1) {
+ packageName = partialName.substring(0, position);
}
- return lines;
- }
-
- private URL targetURL(URL base, String name) throws MalformedURLException {
- try {
- String file = base.getFile() + URIEncoderDecoder.quoteIllegal(name,
- "/@" + URI.someLegal);
-
- return new URL(base.getProtocol(), base.getHost(), base.getPort(),
- file, null);
- } catch (UnsupportedEncodingException e) {
- MalformedURLException e2 = new MalformedURLException(e.toString());
-
- e2.initCause(e);
- throw e2;
- }
-
- }
-
- /**
- * @param searchURLs
- * java.net.URL[] the URLs to search in
- * @param clsName
- * java.lang.String the class name to be found
- * @return Class the class found or null if not found
- */
- Class<?> findClassImpl(URL[] searchURLs, String clsName) {
- boolean readAvailable = false;
- boolean findInExtensions = searchURLs == urls;
- final String name = new StringBuffer(clsName.replace('.', '/')).append(
- ".class").toString(); //$NON-NLS-1$
- for (int i = 0; i < searchURLs.length; i++) {
- if (searchURLs[i] == null) {
- // KA024=One of urls is null
- throw new NullPointerException(Msg.getString("KA024")); //$NON-NLS-1$
- } else if (!invalidUrls.contains(searchURLs[i])) {
- Manifest manifest = null;
- InputStream is = null;
- JarEntry entry = null;
- JarFile jf = null;
- byte[] clBuf = null;
- try {
- URL thisURL = searchURLs[i];
- String protocol = thisURL.getProtocol();
- if (protocol.equals("jar")) { //$NON-NLS-1$
- jf = resCache.get(thisURL);
- if ((jf == null) && (!invalidUrls.contains(thisURL))) {
- synchronized (lock) {
- // Check the cache again in case another thread updated it
- // updated it while we're waiting on lock
- jf = resCache.get(thisURL);
- if (jf == null) {
- if (invalidUrls.contains(thisURL)) {
- continue;
- }
- // If the connection for testURL or thisURL is used,
- // getJarFile() will throw an exception if the entry
- // doesn't exist.
- URL jarURL = ((JarURLConnection) thisURL
- .openConnection()).getJarFileURL();
- try {
- JarURLConnection juc = (JarURLConnection) new URL(
- "jar", "", jarURL.toExternalForm() + "!/") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- .openConnection();
- jf = juc.getJarFile();
- resCache.put(thisURL, jf);
- } catch (IOException e) {
- // Don't look for this jar file again
- invalidUrls.add(searchURLs[i]);
- throw e;
- }
- }
- }
- }
- if (thisURL.getFile().endsWith("!/")) { //$NON-NLS-1$
- entry = jf.getJarEntry(name);
- } else {
- String file = thisURL.getFile();
- int sepIdx = file.lastIndexOf("!/"); //$NON-NLS-1$
- if (sepIdx == -1) {
- // Invalid URL, don't look here again
- invalidUrls.add(searchURLs[i]);
- continue;
- }
- sepIdx += 2;
- String entryName = new StringBuffer(file.length()
- - sepIdx + name.length()).append(
- file.substring(sepIdx)).append(name)
- .toString();
- entry = jf.getJarEntry(entryName);
- }
- if (entry != null) {
- readAvailable = true;
- is = jf.getInputStream(entry);
- /**
- * Avoid recursive load class, especially the class
- * is an implementation class of security provider
- * and the jar is signed.
- */
- Class loadedClass = findLoadedClass(clsName);
- if (null != loadedClass) {
- is.close();
- return loadedClass;
- }
- manifest = jf.getManifest();
- }
- } else if (protocol.equals("file")) { //$NON-NLS-1$
- String filename = thisURL.getFile();
- String host = thisURL.getHost();
- if (host != null && host.length() > 0) {
- filename = new StringBuffer(host.length()
- + filename.length() + name.length() + 2)
- .append("//").append(host).append(filename) //$NON-NLS-1$
- .append(name).toString();
- } else {
- filename = new StringBuffer(filename.length()
- + name.length()).append(filename).append(
- name).toString();
- }
-
- // Just return null for caller to throw
- // ClassNotFoundException.
- try {
- filename = URLDecoder.decode(filename, "UTF-8"); //$NON-NLS-1$
- } catch (IllegalArgumentException e) {
- return null;
- }
-
- File file = new File(filename);
- // Don't throw exceptions for speed
- if (file.exists()) {
- is = new FileInputStream(file);
- readAvailable = true;
- } else {
- continue;
- }
- } else {
- is = targetURL(thisURL, name).openStream();
- }
- } catch (MalformedURLException e) {
- // Keep iterating through the URL list
- } catch (IOException e) {
- }
- if (is != null) {
- URL codeSourceURL = null;
- Certificate[] certificates = null;
- CodeSource codeS = null;
- try {
- codeSourceURL = findInExtensions ? orgUrls[i]
- : ((JarURLConnection) searchURLs[i]
- .openConnection()).getJarFileURL();
- } catch (IOException e) {
- codeSourceURL = searchURLs[i];
- }
- if (is != null) {
- try {
- clBuf = getBytes(is, readAvailable);
- is.close();
- } catch (IOException e) {
- return null;
- }
- }
- if (entry != null) {
- certificates = entry.getCertificates();
- }
- // Use the original URL, not the possible jar URL
- codeS = new CodeSource(codeSourceURL, certificates);
- int dotIndex = clsName.lastIndexOf("."); //$NON-NLS-1$
- if (dotIndex != -1) {
- String packageName = clsName.substring(0, dotIndex);
- synchronized (this) {
- Package packageObj = getPackage(packageName);
- if (packageObj == null) {
- if (manifest != null) {
- definePackage(packageName, manifest,
- codeSourceURL);
- } else {
- definePackage(packageName, null, null,
- null, null, null, null, null);
- }
- } else {
- boolean exception = false;
- if (manifest != null) {
- String dirName = packageName.replace('.',
- '/')
- + "/"; //$NON-NLS-1$
- if (isSealed(manifest, dirName)) {
- exception = !packageObj
- .isSealed(codeSourceURL);
- }
- } else {
- exception = packageObj.isSealed();
- }
- if (exception) {
- throw new SecurityException(Msg
- .getString("K004c")); //$NON-NLS-1$
- }
- }
- }
- }
- return defineClass(clsName, clBuf, 0, clBuf.length, codeS);
- }
- if ((jf != null) && findInExtensions) {
- if (indexes[i] != null) {
- try {
- Class<?> c = (Class<?>) findInIndex(i, clsName,
- null, false);
- if (c != null) {
- return c;
- }
- } catch (InvalidJarIndexException ex) {
- // Ignore misleading/wrong jar index
- }
- } else {
- Class<?> c = (Class<?>) findInExtensions(explore(
- searchURLs[i], i), clsName, i, null, false);
- if (c != null) {
- return c;
- }
- }
- }
+ int n = 0;
+ while (true) {
+ URLHandler handler = getHandler(n++);
+ if (handler == null) {
+ break;
+ }
+ Class<?> res = handler.findClass(packageName, classFileName, className);
+ if (res != null) {
+ return res;
}
}
return null;
+
}
- /**
- * @param url
- * URL the URL to explore
- * @param indexNumber
- * int the index in extensions to consider
- *
- * @return URL[] the URLs of bundled extensions that have been found (i.e.
- * the URL of jar files in the class-path attribute), or null if
- * none. if an INDEX.LIST has been found, an empty array is returned
- */
- URL[] explore(URL url, int indexNumber) {
- URL[] internal;
- synchronized (extensions) {
- internal = extensions.get(url);
- }
- if (internal != null) {
- return internal;
- }
- if (indexes[indexNumber] != null) {
- return null;
- }
-
- if (!url.getProtocol().equals("jar")) { //$NON-NLS-1$
- return null;
- }
-
- JarFile jf = resCache.get(url);
- // Add mappings from INDEX.LIST
- ZipEntry ze = jf.getEntry("META-INF/INDEX.LIST"); //$NON-NLS-1$
- if (ze != null) {
- if (url.equals(urls[indexNumber])) {
- try {
- Hashtable<String, URL[]> index = new Hashtable<String, URL[]>(
- 15);
- InputStream indexIS = jf.getInputStream(ze);
- List<String> lines = readLines(indexIS);
- indexIS.close();
- ListIterator<String> iterator = lines.listIterator();
- // Ignore the 2 first lines (index version)
- iterator.next();
- iterator.next();
- // Add mappings from resource to jar file
- URL fileURL = ((JarURLConnection) url.openConnection())
- .getJarFileURL();
- String file = fileURL.getFile();
- String parentFile = new File(file).getParent();
- parentFile = parentFile.replace(File.separatorChar, '/');
- if (parentFile.charAt(0) != '/') {
- parentFile = "/" + parentFile; //$NON-NLS-1$
- }
- URL parentURL = new URL(fileURL.getProtocol(), fileURL
- .getHost(), fileURL.getPort(), parentFile);
- while (iterator.hasNext()) {
- URL jar = new URL("jar:" //$NON-NLS-1$
- + parentURL.toExternalForm() + "/" //$NON-NLS-1$
- + iterator.next() + "!/"); //$NON-NLS-1$
- String resource = null;
- while (iterator.hasNext()
- && !(resource = iterator.next()).equals("")) { //$NON-NLS-1$
- if (index.containsKey(resource)) {
- URL[] jars = index.get(resource);
- URL[] newJars = new URL[jars.length + 1];
- System.arraycopy(jars, 0, newJars, 0,
- jars.length);
- newJars[jars.length] = jar;
- index.put(resource, newJars);
- } else {
- URL[] jars = { jar };
- index.put(resource, jars);
- }
- }
- }
- indexes[indexNumber] = index;
- } catch (MalformedURLException e) {
- // Ignore this jar's index
- } catch (IOException e) {
- // Ignore this jar's index
- }
- }
- return null;
- }
-
- // Returns URLs referenced by the class-path attribute.
- Manifest manifest = null;
- try {
- manifest = jf.getManifest();
- } catch (IOException e) {
- }
- String classpath = null;
- if (manifest != null) {
- classpath = manifest.getMainAttributes().getValue(
- Attributes.Name.CLASS_PATH);
- }
- synchronized (extensions) {
- internal = extensions.get(url);
- if (internal == null) {
- internal = classpath != null ? getInternalURLs(url, classpath)
- : NO_PATH;
- extensions.put(url, internal);
- }
- }
- return internal;
- }
}
diff --git a/luni/src/main/java/java/net/URLConnection.java b/luni/src/main/java/java/net/URLConnection.java
index 6c1a192..b87b11a 100644
--- a/luni/src/main/java/java/net/URLConnection.java
+++ b/luni/src/main/java/java/net/URLConnection.java
@@ -23,6 +23,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
+import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
@@ -31,22 +32,17 @@
import org.apache.harmony.luni.internal.net.www.MimeTable;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
-import org.apache.harmony.luni.util.Util;
/**
* Concrete implementations of the abstract {@code URLConnection} class provide
* a communication link to a URL for exchanging data with a specific protocol
* type. A {@code URLConnection} can only be set up after the instantiation but
* before connecting to the remote resource.
- *
- * @since Android 1.0
*/
public abstract class URLConnection {
/**
* The URL which represents the remote target of this {@code URLConnection}.
- *
- * @since Android 1.0
*/
protected URL url;
@@ -63,16 +59,12 @@
/**
* The data must be modified more recently than this time in milliseconds
* since January 1, 1970, GMT to be transmitted.
- *
- * @since Android 1.0
*/
protected long ifModifiedSince;
/**
* Specifies whether the using of caches is enabled or the data has to be
* recent for every request.
- *
- * @since Android 1.0
*/
protected boolean useCaches = defaultUseCaches;
@@ -80,30 +72,22 @@
* Specifies whether this {@code URLConnection} is already connected to the
* remote resource. If this field is set to {@code true} the flags for
* setting up the connection are not changeable anymore.
- *
- * @since Android 1.0
*/
protected boolean connected;
/**
* Specifies whether this {@code URLConnection} allows sending data.
- *
- * @since Android 1.0
*/
protected boolean doOutput;
/**
* Specifies whether this {@code URLConnection} allows receiving data.
- *
- * @since Android 1.0
*/
protected boolean doInput = true;
/**
* Specifies whether this {@code URLConnection} allows user interaction as
* it is needed for authentication purposes.
- *
- * @since Android 1.0
*/
protected boolean allowUserInteraction = defaultAllowUserInteraction;
@@ -127,11 +111,10 @@
/**
* Creates a new {@code URLConnection} instance pointing to the resource
* specified by the given URL.
- *
+ *
* @param url
* the URL which represents the resource this {@code
* URLConnection} will point to.
- * @since Android 1.0
*/
protected URLConnection(URL url) {
this.url = url;
@@ -140,20 +123,18 @@
/**
* Establishes the connection to the earlier configured resource. The
* connection can only be set up before this method has been called.
- *
+ *
* @throws IOException
* if an error occurs while connecting to the resource.
- * @since Android 1.0
*/
public abstract void connect() throws IOException;
/**
* Gets the option value which indicates whether user interaction is allowed
* on this {@code URLConnection}.
- *
+ *
* @return the value of the option {@code allowUserInteraction}.
* @see #allowUserInteraction
- * @since Android 1.0
*/
public boolean getAllowUserInteraction() {
return allowUserInteraction;
@@ -166,11 +147,10 @@
* header field "Content-Type". If none is found it will guess the content
* type from the filename extension. If that fails the stream itself will be
* used to guess the content type.
- *
+ *
* @return the content representing object.
* @throws IOException
* if an error occurs obtaining the content.
- * @since Android 1.0
*/
public Object getContent() throws java.io.IOException {
if (!connected) {
@@ -196,14 +176,13 @@
* type from the filename extension. If that fails the stream itself will be
* used to guess the content type. The content type must match with one of
* the list {@code types}.
- *
+ *
* @param types
* the list of acceptable content types.
* @return the content representing object or {@code null} if the content
* type does not match with one of the specified types.
* @throws IOException
* if an error occurs obtaining the content.
- * @since Android 1.0
*/
// Param is not generic in spec
@SuppressWarnings("unchecked")
@@ -226,9 +205,8 @@
/**
* Gets the content encoding type specified by the response header field
* {@code content-encoding} or {@code null} if this field is not set.
- *
+ *
* @return the value of the response header field {@code content-encoding}.
- * @since Android 1.0
*/
public String getContentEncoding() {
return getHeaderField("Content-Encoding"); //$NON-NLS-1$
@@ -237,7 +215,7 @@
/**
* Returns the specific ContentHandler that will handle the type {@code
* contentType}.
- *
+ *
* @param type
* The type that needs to be handled
* @return An instance of the Content Handler
@@ -286,7 +264,8 @@
.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
- String className = "org.apache.harmony.luni.internal.net.www.content." //$NON-NLS-1$
+ // Try looking up AWT image content handlers
+ String className = "org.apache.harmony.awt.www.content." //$NON-NLS-1$
+ typeString;
return Class.forName(className).newInstance();
} catch (ClassNotFoundException e) {
@@ -312,9 +291,8 @@
/**
* Gets the content length in bytes specified by the response header field
* {@code content-length} or {@code -1} if this field is not set.
- *
+ *
* @return the value of the response header field {@code content-length}.
- * @since Android 1.0
*/
public int getContentLength() {
return getHeaderFieldInt("Content-Length", -1); //$NON-NLS-1$
@@ -323,9 +301,8 @@
/**
* Gets the MIME-type of the content specified by the response header field
* {@code content-type} or {@code null} if type is unknown.
- *
+ *
* @return the value of the response header field {@code content-type}.
- * @since Android 1.0
*/
public String getContentType() {
return getHeaderField("Content-Type"); //$NON-NLS-1$
@@ -335,9 +312,8 @@
* Gets the timestamp when this response has been sent as a date in
* milliseconds since January 1, 1970 GMT or {@code 0} if this timestamp is
* unknown.
- *
+ *
* @return the sending timestamp of the current response.
- * @since Android 1.0
*/
public long getDate() {
return getHeaderFieldDate("Date", 0); //$NON-NLS-1$
@@ -345,11 +321,10 @@
/**
* Gets the default setting whether this connection allows user interaction.
- *
+ *
* @return the value of the default setting {@code
* defaultAllowUserInteraction}.
* @see #allowUserInteraction
- * @since Android 1.0
*/
public static boolean getDefaultAllowUserInteraction() {
return defaultAllowUserInteraction;
@@ -359,12 +334,11 @@
* Gets the default value for the specified request {@code field} or {@code
* null} if the field could not be found. The current implementation of this
* method returns always {@code null}.
- *
+ *
* @param field
* the request field whose default value shall be returned.
* @return the default value for the given field.
* @deprecated Use {@link #getRequestProperty}
- * @since Android 1.0
*/
@Deprecated
public static String getDefaultRequestProperty(String field) {
@@ -373,10 +347,9 @@
/**
* Gets the default setting whether this connection allows using caches.
- *
+ *
* @return the value of the default setting {@code defaultUseCaches}.
* @see #useCaches
- * @since Android 1.0
*/
public boolean getDefaultUseCaches() {
return defaultUseCaches;
@@ -385,11 +358,10 @@
/**
* Gets the value of the option {@code doInput} which specifies whether this
* connection allows to receive data.
- *
+ *
* @return {@code true} if this connection allows input, {@code false}
* otherwise.
* @see #doInput
- * @since Android 1.0
*/
public boolean getDoInput() {
return doInput;
@@ -398,11 +370,10 @@
/**
* Gets the value of the option {@code doOutput} which specifies whether
* this connection allows to send data.
- *
+ *
* @return {@code true} if this connection allows output, {@code false}
* otherwise.
* @see #doOutput
- * @since Android 1.0
*/
public boolean getDoOutput() {
return doOutput;
@@ -411,9 +382,8 @@
/**
* Gets the timestamp when this response will be expired in milliseconds
* since January 1, 1970 GMT or {@code 0} if this timestamp is unknown.
- *
+ *
* @return the value of the response header field {@code expires}.
- * @since Android 1.0
*/
public long getExpiration() {
return getHeaderFieldDate("Expires", 0); //$NON-NLS-1$
@@ -422,9 +392,8 @@
/**
* Gets the table which is used by all {@code URLConnection} instances to
* determine the MIME-type according to a file extension.
- *
+ *
* @return the file name map to determine the MIME-type.
- * @since Android 1.0
*/
public static FileNameMap getFileNameMap() {
// Must use lazy initialization or there is a bootstrap problem
@@ -440,11 +409,10 @@
* Gets the header value at the field position {@code pos} or {@code null}
* if the header has fewer than {@code pos} fields. The current
* implementation of this method returns always {@code null}.
- *
+ *
* @param pos
* the field position of the response header.
* @return the value of the field at position {@code pos}.
- * @since Android 1.0
*/
public String getHeaderField(int pos) {
return null;
@@ -454,9 +422,9 @@
* Gets an unchangeable map of the response-header fields and values. The
* response-header field names are the key values of the map. The map values
* are lists of header field values associated with a particular key name.
- *
+ *
* @return the response-header representing generic map.
- * @since Android 1.0
+ * @since 1.4
*/
public Map<String, List<String>> getHeaderFields() {
return Collections.emptyMap();
@@ -466,9 +434,9 @@
* Gets an unchangeable map of general request properties used by this
* connection. The request property names are the key values of the map. The
* map values are lists of property values of the corresponding key name.
- *
+ *
* @return the request-property representing generic map.
- * @since Android 1.0
+ * @since 1.4
*/
public Map<String, List<String>> getRequestProperties() {
if (connected) {
@@ -480,7 +448,7 @@
/**
* Adds the given property to the request header. Existing properties with
* the same name will not be overwritten by this method.
- *
+ *
* @param field
* the request property field name to add.
* @param newValue
@@ -489,7 +457,7 @@
* if the connection has been already established.
* @throws NullPointerException
* if the property name is {@code null}.
- * @since Android 1.0
+ * @since 1.4
*/
public void addRequestProperty(String field, String newValue) {
if (connected) {
@@ -504,11 +472,10 @@
* Gets the value of the header field specified by {@code key} or {@code
* null} if there is no field with this name. The current implementation of
* this method returns always {@code null}.
- *
+ *
* @param key
* the name of the header field.
* @return the value of the header field.
- * @since Android 1.0
*/
public String getHeaderField(String key) {
return null;
@@ -518,34 +485,37 @@
* Gets the specified header value as a date in milliseconds since January
* 1, 1970 GMT. Returns the {@code defaultValue} if no such header field
* could be found.
- *
+ *
* @param field
* the header field name whose value is needed.
* @param defaultValue
* the default value if no field has been found.
* @return the value of the specified header field as a date in
* milliseconds.
- * @since Android 1.0
*/
+ @SuppressWarnings("deprecation")
public long getHeaderFieldDate(String field, long defaultValue) {
String date = getHeaderField(field);
if (date == null) {
return defaultValue;
}
- return Util.parseDate(date);
+ try {
+ return Date.parse(date);
+ } catch (Exception e) {
+ return defaultValue;
+ }
}
/**
* Gets the specified header value as a number. Returns the {@code
* defaultValue} if no such header field could be found or the value could
* not be parsed as an {@code Integer}.
- *
+ *
* @param field
* the header field name whose value is needed.
* @param defaultValue
* the default value if no field has been found.
* @return the value of the specified header field as a number.
- * @since Android 1.0
*/
public int getHeaderFieldInt(String field, int defaultValue) {
try {
@@ -559,11 +529,10 @@
* Gets the name of the header field at the given position {@code posn} or
* {@code null} if there are fewer than {@code posn} fields. The current
* implementation of this method returns always {@code null}.
- *
+ *
* @param posn
* the position of the header field which has to be returned.
* @return the header field name at the given position.
- * @since Android 1.0
*/
public String getHeaderFieldKey(int posn) {
return null;
@@ -573,10 +542,9 @@
* Gets the point of time since when the data must be modified to be
* transmitted. Some protocols transmit data only if it has been modified
* more recently than a particular time.
- *
+ *
* @return the time in milliseconds since January 1, 1970 GMT.
* @see #ifModifiedSince
- * @since Android 1.0
*/
public long getIfModifiedSince() {
return ifModifiedSince;
@@ -586,11 +554,10 @@
* Gets an {@code InputStream} for reading data from the resource pointed by
* this {@code URLConnection}. It throws an UnknownServiceException by
* default. This method must be overridden by its subclasses.
- *
+ *
* @return the InputStream to read data from.
* @throws IOException
* if no InputStream could be created.
- * @since Android 1.0
*/
public InputStream getInputStream() throws IOException {
throw new UnknownServiceException(Msg.getString("K004d")); //$NON-NLS-1$
@@ -599,9 +566,8 @@
/**
* Gets the value of the response header field {@code last-modified} or
* {@code 0} if this value is not set.
- *
+ *
* @return the value of the {@code last-modified} header field.
- * @since Android 1.0
*/
public long getLastModified() {
if (lastModified != -1) {
@@ -614,11 +580,10 @@
* Gets an {@code OutputStream} for writing data to this {@code
* URLConnection}. It throws an {@code UnknownServiceException} by default.
* This method must be overridden by its subclasses.
- *
+ *
* @return the OutputStream to write data.
* @throws IOException
* if no OutputStream could be created.
- * @since Android 1.0
*/
public OutputStream getOutputStream() throws IOException {
throw new UnknownServiceException(Msg.getString("K005f")); //$NON-NLS-1$
@@ -631,12 +596,11 @@
* necessary. By default, this method returns {@code AllPermission}.
* Subclasses should overwrite this method to return an appropriate
* permission object.
- *
+ *
* @return the permission object representing the needed permissions to open
* this connection.
* @throws IOException
* if an I/O error occurs while creating the permission object.
- * @since Android 1.0
*/
public java.security.Permission getPermission() throws IOException {
return new java.security.AllPermission();
@@ -646,13 +610,12 @@
* Gets the value of the request header property specified by {code field}
* or {@code null} if there is no field with this name. The current
* implementation of this method returns always {@code null}.
- *
+ *
* @param field
* the name of the request header property.
* @return the value of the property.
* @throws IllegalStateException
* if the connection has been already established.
- * @since Android 1.0
*/
public String getRequestProperty(String field) {
if (connected) {
@@ -663,9 +626,8 @@
/**
* Gets the URL represented by this {@code URLConnection}.
- *
+ *
* @return the URL of this connection.
- * @since Android 1.0
*/
public URL getURL() {
return url;
@@ -674,9 +636,8 @@
/**
* Gets the value of the flag which specifies whether this {@code
* URLConnection} allows to use caches.
- *
+ *
* @return {@code true} if using caches is allowed, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean getUseCaches() {
return useCaches;
@@ -686,12 +647,11 @@
* Determines the MIME-type of the given resource {@code url} by resolving
* the filename extension with the internal FileNameMap. Any fragment
* identifier is removed before processing.
- *
+ *
* @param url
* the URL with the filename to get the MIME type.
* @return the guessed content type or {@code null} if the type could not be
* determined.
- * @since Android 1.0
*/
public static String guessContentTypeFromName(String url) {
return getFileNameMap().getContentTypeFor(url);
@@ -700,7 +660,7 @@
/**
* Determines the MIME-type of the resource represented by the input stream
* {@code is} by reading its first few characters.
- *
+ *
* @param is
* the resource representing input stream to determine the
* content type.
@@ -708,35 +668,91 @@
* determined.
* @throws IOException
* if an I/O error occurs while reading from the input stream.
- * @since Android 1.0
*/
+ @SuppressWarnings("nls")
public static String guessContentTypeFromStream(InputStream is)
throws IOException {
+
if (!is.markSupported()) {
return null;
}
- is.mark(4);
- char[] chars = new char[4];
- for (int i = 0; i < chars.length; i++) {
- chars[i] = (char) is.read();
- }
+ // Look ahead up to 64 bytes for the longest encoded header
+ is.mark(64);
+ byte[] bytes = new byte[64];
+ int length = is.read(bytes);
is.reset();
- if ((chars[0] == 'P') && (chars[1] == 'K')) {
- return "application/zip"; //$NON-NLS-1$
+
+ // Check for Unicode BOM encoding indicators
+ String encoding = "ASCII";
+ int start = 0;
+ if (length > 1) {
+ if ((bytes[0] == (byte) 0xFF) && (bytes[1] == (byte) 0xFE)) {
+ encoding = "UTF-16LE";
+ start = 2;
+ length -= length & 1;
+ }
+ if ((bytes[0] == (byte) 0xFE) && (bytes[1] == (byte) 0xFF)) {
+ encoding = "UTF-16BE";
+ start = 2;
+ length -= length & 1;
+ }
+ if (length > 2) {
+ if ((bytes[0] == (byte) 0xEF) && (bytes[1] == (byte) 0xBB)
+ && (bytes[2] == (byte) 0xBF)) {
+ encoding = "UTF-8";
+ start = 3;
+ }
+ if (length > 3) {
+ if ((bytes[0] == (byte) 0x00) && (bytes[1] == (byte) 0x00)
+ && (bytes[2] == (byte) 0xFE)
+ && (bytes[3] == (byte) 0xFF)) {
+ encoding = "UTF-32BE";
+ start = 4;
+ length -= length & 3;
+ }
+ if ((bytes[0] == (byte) 0xFF) && (bytes[1] == (byte) 0xFE)
+ && (bytes[2] == (byte) 0x00)
+ && (bytes[3] == (byte) 0x00)) {
+ encoding = "UTF-32LE";
+ start = 4;
+ length -= length & 3;
+ }
+ }
+ }
}
- if ((chars[0] == 'G') && (chars[1] == 'I')) {
- return "image/gif"; //$NON-NLS-1$
+
+ String header = new String(bytes, start, length - start, encoding);
+
+ // Check binary types
+ if (header.startsWith("PK")) {
+ return "application/zip";
}
- if (new String(chars).trim().startsWith("<")) { //$NON-NLS-1$
- return "text/html"; //$NON-NLS-1$
+ if (header.startsWith("GI")) {
+ return "image/gif";
}
+
+ // Check text types
+ String textHeader = header.trim().toUpperCase();
+ if (textHeader.startsWith("<!DOCTYPE HTML") ||
+ textHeader.startsWith("<HTML") ||
+ textHeader.startsWith("<HEAD") ||
+ textHeader.startsWith("<BODY") ||
+ textHeader.startsWith("<HEAD")) {
+ return "text/html";
+ }
+
+ if (textHeader.startsWith("<?XML")) {
+ return "application/xml";
+ }
+
+ // Give up
return null;
}
/**
* Performs any necessary string parsing on the input string such as
* converting non-alphanumeric character into underscore.
- *
+ *
* @param typeString
* the parsed string
* @return the string to be parsed
@@ -757,14 +773,13 @@
* Sets the flag indicating whether this connection allows user interaction
* or not. This method can only be called prior to the connection
* establishment.
- *
+ *
* @param newValue
* the value of the flag to be set.
* @throws IllegalStateException
* if this method attempts to change the flag after the
* connection has been established.
* @see #allowUserInteraction
- * @since Android 1.0
*/
public void setAllowUserInteraction(boolean newValue) {
if (connected) {
@@ -777,13 +792,12 @@
* Sets the internally used content handler factory. The content factory can
* only be set if it is allowed by the security manager and only once during
* the lifetime of the application.
- *
+ *
* @param contentFactory
* the content factory to be set.
* @throws Error
* if the security manager does not allow to set the content
* factory or it has been already set earlier ago.
- * @since Android 1.0
*/
public static synchronized void setContentHandlerFactory(
ContentHandlerFactory contentFactory) {
@@ -801,12 +815,11 @@
* Sets the default value for the flag indicating whether this connection
* allows user interaction or not. Existing {@code URLConnection}s are
* unaffected.
- *
+ *
* @param allows
* the default value of the flag to be used for new connections.
* @see #defaultAllowUserInteraction
* @see #allowUserInteraction
- * @since Android 1.0
*/
public static void setDefaultAllowUserInteraction(boolean allows) {
defaultAllowUserInteraction = allows;
@@ -816,14 +829,13 @@
* Sets the default value of the specified request header field. This value
* will be used for the specific field of every newly created connection.
* The current implementation of this method does nothing.
- *
+ *
* @param field
* the request header field to be set.
* @param value
* the default value to be used.
* @deprecated Use {@link #setRequestProperty} of an existing {@code
* URLConnection} instance.
- * @since Android 1.0
*/
@Deprecated
public static void setDefaultRequestProperty(String field, String value) {
@@ -832,12 +844,11 @@
/**
* Sets the default value for the flag indicating whether this connection
* allows to use caches. Existing {@code URLConnection}s are unaffected.
- *
+ *
* @param newValue
* the default value of the flag to be used for new connections.
* @see #defaultUseCaches
* @see #useCaches
- * @since Android 1.0
*/
public void setDefaultUseCaches(boolean newValue) {
// BEGIN android-removed
@@ -852,14 +863,13 @@
/**
* Sets the flag indicating whether this {@code URLConnection} allows input.
* It cannot be set after the connection is established.
- *
+ *
* @param newValue
* the new value for the flag to be set.
* @throws IllegalAccessError
* if this method attempts to change the value after the
* connection has been already established.
* @see #doInput
- * @since Android 1.0
*/
public void setDoInput(boolean newValue) {
if (connected) {
@@ -871,14 +881,13 @@
/**
* Sets the flag indicating whether this {@code URLConnection} allows
* output. It cannot be set after the connection is established.
- *
+ *
* @param newValue
* the new value for the flag to be set.
* @throws IllegalAccessError
* if this method attempts to change the value after the
* connection has been already established.
* @see #doOutput
- * @since Android 1.0
*/
public void setDoOutput(boolean newValue) {
if (connected) {
@@ -890,10 +899,9 @@
/**
* Sets the internal map which is used by all {@code URLConnection}
* instances to determine the MIME-type according to a filename extension.
- *
+ *
* @param map
* the MIME table to be set.
- * @since Android 1.0
*/
public static void setFileNameMap(FileNameMap map) {
SecurityManager manager = System.getSecurityManager();
@@ -908,13 +916,12 @@
* transmitted. Some protocols transmit data only if it has been modified
* more recently than a particular time. The data will be transmitted
* regardless of its timestamp if this option is set to {@code 0}.
- *
+ *
* @param newValue
* the time in milliseconds since January 1, 1970 GMT.
* @throws IllegalStateException
* if this {@code URLConnection} has already been connected.
* @see #ifModifiedSince
- * @since Android 1.0
*/
public void setIfModifiedSince(long newValue) {
if (connected) {
@@ -927,7 +934,7 @@
* Sets the value of the specified request header field. The value will only
* be used by the current {@code URLConnection} instance. This method can
* only be called before the connection is established.
- *
+ *
* @param field
* the request header field to be set.
* @param newValue
@@ -936,7 +943,6 @@
* if the connection has been already established.
* @throws NullPointerException
* if the parameter {@code field} is {@code null}.
- * @since Android 1.0
*/
public void setRequestProperty(String field, String newValue) {
if (connected) {
@@ -951,14 +957,13 @@
* Sets the flag indicating whether this connection allows to use caches or
* not. This method can only be called prior to the connection
* establishment.
- *
+ *
* @param newValue
* the value of the flag to be set.
* @throws IllegalStateException
* if this method attempts to change the flag after the
* connection has been established.
* @see #useCaches
- * @since Android 1.0
*/
public void setUseCaches(boolean newValue) {
if (connected) {
@@ -973,12 +978,11 @@
* SocketTimeoutException} is thrown if the connection could not be
* established in this time. Default is {@code 0} which stands for an
* infinite timeout.
- *
+ *
* @param timeout
* the connecting timeout in milliseconds.
* @throws IllegalArgumentException
* if the parameter {@code timeout} is less than zero.
- * @since Android 1.0
*/
public void setConnectTimeout(int timeout) {
if (0 > timeout) {
@@ -989,9 +993,8 @@
/**
* Gets the configured connecting timeout.
- *
+ *
* @return the connecting timeout value in milliseconds.
- * @since Android 1.0
*/
public int getConnectTimeout() {
return connectTimeout;
@@ -1003,12 +1006,11 @@
* SocketTimeoutException} is thrown if the connection could not be
* established in this time. Default is {@code 0} which stands for an
* infinite timeout.
- *
+ *
* @param timeout
* the reading timeout in milliseconds.
* @throws IllegalArgumentException
* if the parameter {@code timeout} is less than zero.
- * @since Android 1.0
*/
public void setReadTimeout(int timeout) {
if (0 > timeout) {
@@ -1020,9 +1022,8 @@
/**
* Gets the configured timeout for reading from the input stream of an
* established connection to the resource.
- *
+ *
* @return the reading timeout value in milliseconds.
- * @since Android 1.0
*/
public int getReadTimeout() {
return readTimeout;
@@ -1031,9 +1032,8 @@
/**
* Returns the string representation containing the name of this class and
* the URL.
- *
+ *
* @return the string representation of this {@code URLConnection} instance.
- * @since Android 1.0
*/
@Override
public String toString() {
diff --git a/luni/src/main/java/java/net/URLDecoder.java b/luni/src/main/java/java/net/URLDecoder.java
index d272aa7..fd2753c 100644
--- a/luni/src/main/java/java/net/URLDecoder.java
+++ b/luni/src/main/java/java/net/URLDecoder.java
@@ -17,20 +17,23 @@
package java.net;
-import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
import org.apache.harmony.luni.util.Msg;
-import org.apache.harmony.luni.util.Util;
/**
* This class is used to decode a string which is encoded in the {@code
* application/x-www-form-urlencoded} MIME content type.
- *
- * @since Android 1.0
*/
public class URLDecoder {
+ static Charset defaultCharset;
+
/**
* Decodes the argument which is assumed to be encoded in the {@code
* x-www-form-urlencoded} MIME content type.
@@ -39,19 +42,32 @@
* characters are converted to the equivalent byte value. All other
* characters are passed through unmodified. For example "A+B+C %24%25" ->
* "A B C $%".
- * </p>
- *
+ *
* @param s
* the encoded string.
* @return the decoded clear-text representation of the given string.
* @deprecated use {@link #decode(String, String)} instead.
- * @since Android 1.0
*/
@Deprecated
public static String decode(String s) {
- return Util.decode(s, true);
+
+ if (defaultCharset == null) {
+ try {
+ defaultCharset = Charset.forName(
+ System.getProperty("file.encoding")); //$NON-NLS-1$
+ } catch (IllegalCharsetNameException e) {
+ // Ignored
+ } catch (UnsupportedCharsetException e) {
+ // Ignored
+ }
+
+ if (defaultCharset == null) {
+ defaultCharset = Charset.forName("ISO-8859-1"); //$NON-NLS-1$
+ }
+ }
+ return decode(s, defaultCharset);
}
-
+
/**
* Decodes the argument which is assumed to be encoded in the {@code
* x-www-form-urlencoded} MIME content type using the specified encoding
@@ -61,8 +77,7 @@
* characters are converted to the equivalent byte value. All other
* characters are passed through unmodified. For example "A+B+C %24%25" ->
* "A B C $%".
- * </p>
- *
+ *
* @param s
* the encoded string.
* @param enc
@@ -70,7 +85,6 @@
* @return the decoded clear-text representation of the given string.
* @throws UnsupportedEncodingException
* if the specified encoding scheme is invalid.
- * @since Android 1.0
*/
public static String decode(String s, String enc)
throws UnsupportedEncodingException {
@@ -81,40 +95,80 @@
// If the given encoding is an empty string throw an exception.
if (enc.length() == 0) {
- throw new UnsupportedEncodingException(Msg
- .getString("K00a5", "enc")); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new UnsupportedEncodingException(
+ // K00a5=Invalid parameter - {0}
+ Msg.getString("K00a5", "enc")); //$NON-NLS-1$ //$NON-NLS-2$
}
- StringBuffer result = new StringBuffer(s.length());
- ByteArrayOutputStream out = new ByteArrayOutputStream();
+ if (s.indexOf('%') == -1) {
+ if (s.indexOf('+') == -1)
+ return s;
+ char str[] = s.toCharArray();
+ for (int i = 0; i < str.length; i++) {
+ if (str[i] == '+')
+ str[i] = ' ';
+ }
+ return new String(str);
+ }
+
+ Charset charset = null;
+ try {
+ charset = Charset.forName(enc);
+ } catch (IllegalCharsetNameException e) {
+ throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
+ enc).initCause(e));
+ } catch (UnsupportedCharsetException e) {
+ throw (UnsupportedEncodingException) (new UnsupportedEncodingException(
+ enc).initCause(e));
+ }
+
+ return decode(s, charset);
+ }
+
+ private static String decode(String s, Charset charset) {
+
+ char str_buf[] = new char[s.length()];
+ byte buf[] = new byte[s.length() / 3];
+ int buf_len = 0;
+
for (int i = 0; i < s.length();) {
char c = s.charAt(i);
if (c == '+') {
- result.append(' ');
+ str_buf[buf_len] = ' ';
} else if (c == '%') {
- out.reset();
+
+ int len = 0;
do {
if (i + 2 >= s.length()) {
- throw new IllegalArgumentException(Msg.getString(
- "K01fe", i)); //$NON-NLS-1$
+ throw new IllegalArgumentException(
+ // K01fe=Incomplete % sequence at\: {0}
+ Msg.getString("K01fe", i)); //$NON-NLS-1$
}
int d1 = Character.digit(s.charAt(i + 1), 16);
int d2 = Character.digit(s.charAt(i + 2), 16);
if (d1 == -1 || d2 == -1) {
- throw new IllegalArgumentException(Msg.getString(
- "K01ff", //$NON-NLS-1$
- s.substring(i, i + 3), String.valueOf(i)));
+ throw new IllegalArgumentException(
+ // K01ff=Invalid % sequence ({0}) at\: {1}
+ Msg.getString(
+ "K01ff", //$NON-NLS-1$
+ s.substring(i, i + 3),
+ String.valueOf(i)));
}
- out.write((byte) ((d1 << 4) + d2));
+ buf[len++] = (byte) ((d1 << 4) + d2);
i += 3;
} while (i < s.length() && s.charAt(i) == '%');
- result.append(out.toString(enc));
+
+ CharBuffer cb = charset.decode(ByteBuffer.wrap(buf, 0, len));
+ len = cb.length();
+ System.arraycopy(cb.array(), 0, str_buf, buf_len, len);
+ buf_len += len;
continue;
} else {
- result.append(c);
+ str_buf[buf_len] = c;
}
i++;
+ buf_len++;
}
- return result.toString();
+ return new String(str_buf, 0, buf_len);
}
}
diff --git a/luni/src/main/java/java/net/URLEncoder.java b/luni/src/main/java/java/net/URLEncoder.java
index 69f2d37..2c21aa6 100644
--- a/luni/src/main/java/java/net/URLEncoder.java
+++ b/luni/src/main/java/java/net/URLEncoder.java
@@ -22,8 +22,6 @@
/**
* This class is used to encode a string using the format required by
* {@code application/x-www-form-urlencoded} MIME content type.
- *
- * @since Android 1.0
*/
public class URLEncoder {
@@ -43,13 +41,11 @@
* and characters '.', '-', '*', '_' are converted into their hexadecimal
* value prepended by '%'. For example: '#' -> %23. In addition, spaces are
* substituted by '+'
- * </p>
- *
+ *
* @param s
* the string to be encoded.
* @return the encoded string.
* @deprecated use {@link #encode(String, String)} instead.
- * @since Android 1.0
*/
@Deprecated
public static String encode(String s) {
@@ -81,8 +77,7 @@
* and characters '.', '-', '*', '_' are converted into their hexadecimal
* value prepended by '%'. For example: '#' -> %23. In addition, spaces are
* substituted by '+'
- * </p>
- *
+ *
* @param s
* the string to be encoded.
* @param enc
@@ -90,10 +85,10 @@
* @return the encoded string.
* @throws UnsupportedEncodingException
* if the specified encoding scheme is invalid.
- * @since Android 1.0
*/
public static String encode(String s, String enc)
throws UnsupportedEncodingException {
+
if (s == null || enc == null) {
throw new NullPointerException();
}
diff --git a/luni/src/main/java/java/net/URLStreamHandler.java b/luni/src/main/java/java/net/URLStreamHandler.java
index f05c8bd..f039b00 100644
--- a/luni/src/main/java/java/net/URLStreamHandler.java
+++ b/luni/src/main/java/java/net/URLStreamHandler.java
@@ -26,11 +26,8 @@
* The abstract class {@code URLStreamHandler} is the base for all classes which
* can handle the communication with a URL object over a particular protocol
* type.
- *
- * @since Android 1.0
*/
public abstract class URLStreamHandler {
-
/**
* Establishes a new connection to the resource specified by the URL {@code
* u}. Since different protocols also have unique ways of connecting, it
@@ -41,7 +38,6 @@
* @return the opened URLConnection to the specified resource.
* @throws IOException
* if an I/O error occurs during opening the connection.
- * @since Android 1.0
*/
protected abstract URLConnection openConnection(URL u) throws IOException;
@@ -62,7 +58,6 @@
* wrong.
* @throws UnsupportedOperationException
* if the protocol handler doesn't support this method.
- * @since Android 1.0
*/
protected URLConnection openConnection(URL u, Proxy proxy)
throws IOException {
@@ -74,7 +69,7 @@
* generally have the following format:
* <p>
* http://www.company.com/java/file1.java#reference
- * </p>
+ * <p>
* The string is parsed in HTTP format. If the protocol has a different URL
* format this method must be overridden.
*
@@ -88,7 +83,6 @@
* the string position to stop parsing.
* @see #toExternalForm
* @see URL
- * @since Android 1.0
*/
protected void parseURL(URL u, String str, int start, int end) {
// For compatibility, refer to Harmony-2941
@@ -259,7 +253,6 @@
* the reference.
* @deprecated use setURL(URL, String String, int, String, String, String,
* String, String) instead.
- * @since Android 1.0
*/
@Deprecated
protected void setURL(URL u, String protocol, String host, int port,
@@ -292,7 +285,6 @@
* the query.
* @param ref
* the reference.
- * @since Android 1.0
*/
protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String file, String query,
@@ -311,7 +303,6 @@
* @return the clear text representation of the specified URL.
* @see #parseURL
* @see URL#toExternalForm()
- * @since Android 1.0
*/
protected String toExternalForm(URL url) {
StringBuffer answer = new StringBuffer(url.getProtocol().length()
@@ -346,7 +337,6 @@
* the second URL to compare.
* @return {@code true} if the URLs are the same, {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
protected boolean equals(URL url1, URL url2) {
if (!sameFile(url1, url2)) {
@@ -364,9 +354,8 @@
/**
* Returns the default port of the protocol used by the handled URL. The
* current implementation returns always {@code -1}.
- *
+ *
* @return the appropriate default port number of the protocol.
- * @since Android 1.0
*/
protected int getDefaultPort() {
return -1;
@@ -374,11 +363,10 @@
/**
* Returns the host address of the given URL.
- *
+ *
* @param url
* the URL object where to read the host address from.
* @return the host address of the specified URL.
- * @since Android 1.0
*/
protected InetAddress getHostAddress(URL url) {
try {
@@ -398,7 +386,6 @@
* @param url
* the URL to determine the hashcode.
* @return the hashcode of the given URL.
- * @since Android 1.0
*/
protected int hashCode(URL url) {
return toExternalForm(url).hashCode();
@@ -406,14 +393,13 @@
/**
* Compares two URL objects whether they refer to the same host.
- *
+ *
* @param url1
* the first URL to be compared.
* @param url2
* the second URL to be compared.
* @return {@code true} if both URLs refer to the same host, {@code false}
* otherwise.
- * @since Android 1.0
*/
protected boolean hostsEqual(URL url1, URL url2) {
String host1 = getHost(url1), host2 = getHost(url2);
@@ -439,7 +425,6 @@
* the second URL to be compared.
* @return {@code true} if both URLs refer to the same file, {@code false}
* otherwise.
- * @since Android 1.0
*/
protected boolean sameFile(URL url1, URL url2) {
String s1 = url1.getProtocol();
diff --git a/luni/src/main/java/java/net/URLStreamHandlerFactory.java b/luni/src/main/java/java/net/URLStreamHandlerFactory.java
index e696410..4e50792 100644
--- a/luni/src/main/java/java/net/URLStreamHandlerFactory.java
+++ b/luni/src/main/java/java/net/URLStreamHandlerFactory.java
@@ -20,11 +20,9 @@
/**
* Defines a factory which creates an {@code URLStreamHandler} for a specified
* protocol. It is used by the class {@code URL}.
- *
- * @since Android 1.0
*/
public interface URLStreamHandlerFactory {
-
+
/**
* Creates a new {@code URLStreamHandler} instance for the given {@code
* protocol}.
@@ -32,7 +30,6 @@
* @param protocol
* the protocol for which a handler is needed.
* @return the created handler.
- * @since Android 1.0
*/
URLStreamHandler createURLStreamHandler(String protocol);
}
diff --git a/luni/src/main/java/java/net/UnknownHostException.java b/luni/src/main/java/java/net/UnknownHostException.java
index 9f7c63a..db05558 100644
--- a/luni/src/main/java/java/net/UnknownHostException.java
+++ b/luni/src/main/java/java/net/UnknownHostException.java
@@ -21,8 +21,6 @@
/**
* Is thrown when a hostname can not be resolved.
- *
- * @since Android 1.0
*/
public class UnknownHostException extends IOException {
@@ -31,8 +29,6 @@
/**
* Constructs a new {@code UnknownHostException} instance with its walkback
* filled in.
- *
- * @since Android 1.0
*/
public UnknownHostException() {
super();
@@ -44,7 +40,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UnknownHostException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/net/UnknownServiceException.java b/luni/src/main/java/java/net/UnknownServiceException.java
index 4865d6d..6ad2a19 100644
--- a/luni/src/main/java/java/net/UnknownServiceException.java
+++ b/luni/src/main/java/java/net/UnknownServiceException.java
@@ -24,8 +24,6 @@
* particular service requested by the URL connection. This could be happened if
* there is an invalid MIME type or the application wants to send data over a
* read-only connection.
- *
- * @since Android 1.0
*/
public class UnknownServiceException extends IOException {
@@ -34,8 +32,6 @@
/**
* Constructs a new {@code UnknownServiceException} instance with its
* walkback filled in.
- *
- * @since Android 1.0
*/
public UnknownServiceException() {
super();
@@ -47,7 +43,6 @@
*
* @param detailMessage
* the detail message for this exception.
- * @since Android 1.0
*/
public UnknownServiceException(String detailMessage) {
super(detailMessage);
diff --git a/luni/src/main/java/java/util/AbstractCollection.java b/luni/src/main/java/java/util/AbstractCollection.java
index 9f26445..6511b11 100644
--- a/luni/src/main/java/java/util/AbstractCollection.java
+++ b/luni/src/main/java/java/util/AbstractCollection.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.lang.reflect.Array;
/**
@@ -26,23 +25,18 @@
* iterator()} and {@code size()} to create an immutable collection. To create a
* modifiable collection it's necessary to override the {@code add()} method that
* currently throws an {@code UnsupportedOperationException}.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public abstract class AbstractCollection<E> implements Collection<E> {
/**
- * Constructs a new instance of this {@code AbstractCollection}.
- *
- * @since Android 1.0
+ * Constructs a new instance of this AbstractCollection.
*/
protected AbstractCollection() {
super();
}
- /**
- * @see Collection#add
- */
public boolean add(E object) {
throw new UnsupportedOperationException();
}
@@ -64,18 +58,17 @@
* the collection of objects.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when adding to this {@code Collection} is not supported.
- * @exception ClassCastException
- * when the class of an object is inappropriate for this
+ * @throws UnsupportedOperationException
+ * if adding to this {@code Collection} is not supported.
+ * @throws ClassCastException
+ * if the class of an object is inappropriate for this
* {@code Collection}.
- * @exception IllegalArgumentException
- * when an object cannot be added to this {@code Collection}.
- * @exception NullPointerException
- * when {@code collection} is {@code null}, or if it contains
+ * @throws IllegalArgumentException
+ * if an object cannot be added to this {@code Collection}.
+ * @throws NullPointerException
+ * if {@code collection} is {@code null}, or if it contains
* {@code null} elements and this {@code Collection} does not support
* such elements.
- * @since Android 1.0
*/
public boolean addAll(Collection<? extends E> collection) {
boolean result = false;
@@ -97,13 +90,12 @@
* Concrete implementations usually can clear a {@code Collection} more efficiently
* and should therefore overwrite this method.
*
- * @exception UnsupportedOperationException
- * when the iterator does not support removing elements from
+ * @throws UnsupportedOperationException
+ * it the iterator does not support removing elements from
* this {@code Collection}
* @see #iterator
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
public void clear() {
Iterator<E> it = iterator();
@@ -126,12 +118,11 @@
* the object to search for.
* @return {@code true} if object is an element of this {@code Collection}, {@code
* false} otherwise.
- * @exception ClassCastException
+ * @throws ClassCastException
* if the object to look for isn't of the correct type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if the object to look for is {@code null} and this
* {@code Collection} doesn't support {@code null} elements.
- * @since Android 1.0
*/
public boolean contains(Object object) {
Iterator<E> it = iterator();
@@ -161,16 +152,15 @@
* the collection of objects.
* @return {@code true} if all objects in the specified {@code Collection} are
* elements of this {@code Collection}, {@code false} otherwise.
- * @exception ClassCastException
+ * @throws ClassCastException
* if one or more elements of {@code collection} isn't of the
* correct type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} contains at least one {@code null}
* element and this {@code Collection} doesn't support {@code null}
* elements.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} is {@code null}.
- * @since Android 1.0
*/
public boolean containsAll(Collection<?> collection) {
Iterator<?> it = collection.iterator();
@@ -188,9 +178,8 @@
*
* @return {@code true} if this {@code Collection} has no elements, {@code false}
* otherwise.
- *
+ *
* @see #size
- * @since Android 1.0
*/
public boolean isEmpty() {
return size() == 0;
@@ -206,7 +195,6 @@
* by concrete {@code Collection} implementations.
*
* @return an iterator for accessing the {@code Collection} contents.
- * @since Android 1.0
*/
public abstract Iterator<E> iterator();
@@ -226,14 +214,13 @@
* the object to remove.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code Collection} is not supported.
- * @exception ClassCastException
- * when the object passed is not of the correct type.
- * @exception NullPointerException
+ * @throws UnsupportedOperationException
+ * if removing from this {@code Collection} is not supported.
+ * @throws ClassCastException
+ * if the object passed is not of the correct type.
+ * @throws NullPointerException
* if {@code object} is {@code null} and this {@code Collection}
* doesn't support {@code null} elements.
- * @since Android 1.0
*/
public boolean remove(Object object) {
Iterator<?> it = iterator();
@@ -272,18 +259,17 @@
* the collection of objects to remove.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code Collection} is not supported.
- * @exception ClassCastException
+ * @throws UnsupportedOperationException
+ * if removing from this {@code Collection} is not supported.
+ * @throws ClassCastException
* if one or more elements of {@code collection} isn't of the
* correct type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} contains at least one {@code null}
* element and this {@code Collection} doesn't support {@code null}
* elements.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} is {@code null}.
- * @since Android 1.0
*/
public boolean removeAll(Collection<?> collection) {
boolean result = false;
@@ -314,18 +300,17 @@
* the collection of objects to retain.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code Collection} is not supported.
- * @exception ClassCastException
+ * @throws UnsupportedOperationException
+ * if removing from this {@code Collection} is not supported.
+ * @throws ClassCastException
* if one or more elements of {@code collection}
* isn't of the correct type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} contains at least one
* {@code null} element and this {@code Collection} doesn't support
* {@code null} elements.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} is {@code null}.
- * @since Android 1.0
*/
public boolean retainAll(Collection<?> collection) {
boolean result = false;
@@ -348,7 +333,6 @@
* @return how many objects this {@code Collection} contains, or {@code Integer.MAX_VALUE}
* if there are more than {@code Integer.MAX_VALUE} elements in this
* {@code Collection}.
- * @since Android 1.0
*/
public abstract int size();
@@ -367,10 +351,10 @@
int size = size(), index = 0;
if (size > contents.length) {
Class<?> ct = contents.getClass().getComponentType();
- contents = (T[])Array.newInstance(ct, size);
+ contents = (T[]) Array.newInstance(ct, size);
}
- for (E entry: this) {
- contents[index++] = (T)entry;
+ for (E entry : this) {
+ contents[index++] = (T) entry;
}
if (index < contents.length) {
contents[index] = null;
@@ -384,7 +368,6 @@
* are separated by ', ' (comma and space).
*
* @return the string representation of this {@code Collection}.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -402,7 +385,7 @@
} else {
buffer.append("(this Collection)"); //$NON-NLS-1$
}
- if(it.hasNext()) {
+ if (it.hasNext()) {
buffer.append(", "); //$NON-NLS-1$
}
}
diff --git a/luni/src/main/java/java/util/AbstractList.java b/luni/src/main/java/java/util/AbstractList.java
index cfd8c6f..899affd 100644
--- a/luni/src/main/java/java/util/AbstractList.java
+++ b/luni/src/main/java/java/util/AbstractList.java
@@ -24,16 +24,14 @@
* methods {@code get()} and {@code size()}, and to create a
* modifiable {@code List} it's necessary to override the {@code add()} method that
* currently throws an {@code UnsupportedOperationException}.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public abstract class AbstractList<E> extends AbstractCollection<E> implements
List<E> {
/**
* A counter for changes to the list.
- *
- * @since Android 1.0
*/
protected transient int modCount;
@@ -67,22 +65,25 @@
}
public void remove() {
- if (expectedModCount == modCount) {
- try {
- AbstractList.this.remove(lastPosition);
- } catch (IndexOutOfBoundsException e) {
- throw new IllegalStateException();
- }
- if (modCount != expectedModCount) {
- expectedModCount++;
- }
- if (pos == lastPosition) {
- pos--;
- }
- lastPosition = -1;
- } else {
+ if (this.lastPosition == -1) {
+ throw new IllegalStateException();
+ }
+
+ if (expectedModCount != modCount) {
throw new ConcurrentModificationException();
}
+
+ try {
+ AbstractList.this.remove(lastPosition);
+ } catch (IndexOutOfBoundsException e) {
+ throw new ConcurrentModificationException();
+ }
+
+ expectedModCount = modCount;
+ if (pos == lastPosition) {
+ pos--;
+ }
+ lastPosition = -1;
}
}
@@ -107,7 +108,7 @@
pos++;
lastPosition = -1;
if (modCount != expectedModCount) {
- expectedModCount++;
+ expectedModCount = modCount;
}
} else {
throw new ConcurrentModificationException();
@@ -374,8 +375,6 @@
/**
* Constructs a new instance of this AbstractList.
- *
- * @since Android 1.0
*/
protected AbstractList() {
super();
@@ -386,15 +385,15 @@
* The object is inserted before any previous element at the specified
* location. If the location is equal to the size of this List, the object
* is added at the end.
- *
+ * <p>
* Concrete implementations that would like to support the add functionality
- * must override this method.
- *
+ * must override this method.
+ *
* @param location
* the index at which to insert.
* @param object
* the object to add.
- *
+ *
* @throws UnsupportedOperationException
* if adding to this List is not supported.
* @throws ClassCastException
@@ -404,7 +403,6 @@
* if the object cannot be added to this List
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
- * @since Android 1.0
*/
public void add(int location, E object) {
throw new UnsupportedOperationException();
@@ -412,12 +410,12 @@
/**
* Adds the specified object at the end of this List.
- *
- *
+ *
+ *
* @param object
* the object to add
* @return true
- *
+ *
* @throws UnsupportedOperationException
* if adding to this List is not supported
* @throws ClassCastException
@@ -425,7 +423,6 @@
* List
* @throws IllegalArgumentException
* if the object cannot be added to this List
- * @since Android 1.0
*/
@Override
public boolean add(E object) {
@@ -437,7 +434,7 @@
* Inserts the objects in the specified Collection at the specified location
* in this List. The objects are added in the order they are returned from
* the collection's iterator.
- *
+ *
* @param location
* the index at which to insert.
* @param collection
@@ -451,7 +448,6 @@
* if an object cannot be added to this list.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || > size()}
- * @since Android 1.0
*/
public boolean addAll(int location, Collection<? extends E> collection) {
Iterator<? extends E> it = collection.iterator();
@@ -463,12 +459,11 @@
/**
* Removes all elements from this list, leaving it empty.
- *
+ *
* @throws UnsupportedOperationException
* if removing from this list is not supported.
* @see List#isEmpty
* @see List#size
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -479,13 +474,12 @@
* Compares the specified object to this list and return true if they are
* equal. Two lists are equal when they both contain the same objects in the
* same order.
- *
+ *
* @param object
* the object to compare to this object.
* @return {@code true} if the specified object is equal to this list,
* {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -512,24 +506,22 @@
/**
* Returns the element at the specified location in this list.
- *
+ *
* @param location
* the index of the element to return.
* @return the element at the specified index.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
- * @since Android 1.0
*/
public abstract E get(int location);
/**
* Returns the hash code of this list. The hash code is calculated by taking
* each element's hashcode into account.
- *
+ *
* @return the hash code.
* @see #equals
* @see List#hashCode()
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -545,12 +537,11 @@
/**
* Searches this list for the specified object and returns the index of the
* first occurrence.
- *
+ *
* @param object
* the object to search for.
* @return the index of the first occurrence of the object, or -1 if it was
* not found.
- * @since Android 1.0
*/
public int indexOf(Object object) {
ListIterator<?> it = listIterator();
@@ -573,10 +564,9 @@
/**
* Returns an iterator on the elements of this list. The elements are
* iterated in the same order as they occur in the list.
- *
+ *
* @return an iterator on the elements of this list.
* @see Iterator
- * @since Android 1.0
*/
@Override
public Iterator<E> iterator() {
@@ -586,12 +576,11 @@
/**
* Searches this list for the specified object and returns the index of the
* last occurrence.
- *
+ *
* @param object
* the object to search for.
* @return the index of the last occurrence of the object, or -1 if the
* object was not found.
- * @since Android 1.0
*/
public int lastIndexOf(Object object) {
ListIterator<?> it = listIterator(size());
@@ -614,10 +603,9 @@
/**
* Returns a ListIterator on the elements of this list. The elements are
* iterated in the same order that they occur in the list.
- *
+ *
* @return a ListIterator on the elements of this list
* @see ListIterator
- * @since Android 1.0
*/
public ListIterator<E> listIterator() {
return listIterator(0);
@@ -627,14 +615,13 @@
* Returns a list iterator on the elements of this list. The elements are
* iterated in the same order as they occur in the list. The iteration
* starts at the specified location.
- *
+ *
* @param location
* the index at which to start the iteration.
* @return a ListIterator on the elements of this list.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || location > size()}
* @see ListIterator
- * @since Android 1.0
*/
public ListIterator<E> listIterator(int location) {
return new FullListIterator(location);
@@ -642,7 +629,7 @@
/**
* Removes the object at the specified location from this list.
- *
+ *
* @param location
* the index of the object to remove.
* @return the removed object.
@@ -650,7 +637,6 @@
* if removing from this list is not supported.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
- * @since Android 1.0
*/
public E remove(int location) {
throw new UnsupportedOperationException();
@@ -659,7 +645,7 @@
/**
* Removes the objects in the specified range from the start to the end
* index minus one.
- *
+ *
* @param start
* the index at which to start removing.
* @param end
@@ -668,7 +654,6 @@
* if removing from this list is not supported.
* @throws IndexOutOfBoundsException
* if {@code start < 0} or {@code start >= size()}.
- * @since Android 1.0
*/
protected void removeRange(int start, int end) {
Iterator<?> it = listIterator(start);
@@ -681,7 +666,7 @@
/**
* Replaces the element at the specified location in this list with the
* specified object.
- *
+ *
* @param location
* the index at which to put the specified object.
* @param object
@@ -695,7 +680,6 @@
* if an object cannot be added to this list.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
- * @since Android 1.0
*/
public E set(int location, E object) {
throw new UnsupportedOperationException();
@@ -733,7 +717,7 @@
* <p>
* All methods will throw a ConcurrentModificationException if the modCount
* of the original list is not equal to the expected value.
- *
+ *
* @param start
* start index of the subList (inclusive).
* @param end
@@ -744,7 +728,6 @@
* if (start < 0 || end > size())
* @throws IllegalArgumentException
* if (start > end)
- * @since Android 1.0
*/
public List<E> subList(int start, int end) {
if (0 <= start && end <= size()) {
diff --git a/luni/src/main/java/java/util/AbstractMap.java b/luni/src/main/java/java/util/AbstractMap.java
index 00266a7..b687e72 100644
--- a/luni/src/main/java/java/util/AbstractMap.java
+++ b/luni/src/main/java/java/util/AbstractMap.java
@@ -17,17 +17,12 @@
package java.util;
-// BEGIN android-added
-// copied from newer harmony
-import java.util.Map.Entry;
-// END android-added
-
/**
* This class is an abstract implementation of the {@code Map} interface. This
* implementation does not support adding. A subclass must implement the
* abstract method entrySet().
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public abstract class AbstractMap<K, V> implements Map<K, V> {
@@ -38,8 +33,6 @@
/**
* Constructs a new instance of this {@code AbstractMap}.
- *
- * @since Android 1.0
*/
protected AbstractMap() {
super();
@@ -47,12 +40,11 @@
/**
* Removes all elements from this map, leaving it empty.
- *
+ *
* @throws UnsupportedOperationException
* if removing from this map is not supported.
* @see #isEmpty()
* @see #size()
- * @since Android 1.0
*/
public void clear() {
entrySet().clear();
@@ -60,12 +52,11 @@
/**
* Returns whether this map contains the specified key.
- *
+ *
* @param key
* the key to search for.
* @return {@code true} if this map contains the specified key,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean containsKey(Object key) {
Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -87,12 +78,11 @@
/**
* Returns whether this map contains the specified value.
- *
+ *
* @param value
* the value to search for.
* @return {@code true} if this map contains the specified value,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean containsValue(Object value) {
Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -116,23 +106,21 @@
* Returns a set containing all of the mappings in this map. Each mapping is
* an instance of {@link Map.Entry}. As the set is backed by this map,
* changes in one will be reflected in the other.
- *
+ *
* @return a set of the mappings.
- * @since Android 1.0
*/
public abstract Set<Map.Entry<K, V>> entrySet();
/**
* Compares the specified object to this instance, and returns {@code true}
* if the specified object is a map and both maps contain the same mappings.
- *
+ *
* @param object
* the object to compare with this object.
* @return boolean {@code true} if the object is the same as this object,
* and {@code false} if it is different from this object.
* @see #hashCode()
* @see #entrySet()
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -145,19 +133,21 @@
return false;
}
- // BEGIN android-changed
- // copied from newer version of harmony
Iterator<Map.Entry<K, V>> it = entrySet().iterator();
- while (it.hasNext()) {
- Entry<K, V> entry = it.next();
- K key = entry.getKey();
- V value = entry.getValue();
- Object obj = map.get(key);
- if( null != obj && (!obj.equals(value)) || null == obj && obj != value) {
- return false;
+
+ try {
+ while (it.hasNext()) {
+ Entry<K, V> entry = it.next();
+ K key = entry.getKey();
+ V value = entry.getValue();
+ Object obj = map.get(key);
+ if( null != obj && (!obj.equals(value)) || null == obj && obj != value) {
+ return false;
+ }
}
+ } catch (ClassCastException cce) {
+ return false;
}
- // END android-changed
return true;
}
return false;
@@ -165,12 +155,11 @@
/**
* Returns the value of the mapping with the specified key.
- *
+ *
* @param key
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
- * @since Android 1.0
*/
public V get(Object key) {
Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -195,10 +184,9 @@
/**
* Returns the hash code for this object. Objects which are equal must
* return the same value for this method.
- *
+ *
* @return the hash code of this object.
* @see #equals(Object)
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -212,11 +200,10 @@
/**
* Returns whether this map is empty.
- *
+ *
* @return {@code true} if this map has no elements, {@code false}
* otherwise.
* @see #size()
- * @since Android 1.0
*/
public boolean isEmpty() {
return size() == 0;
@@ -226,9 +213,8 @@
* Returns a set of the keys contained in this map. The set is backed by
* this map so changes to one are reflected by the other. The returned set
* does not support adding.
- *
+ *
* @return a set of the keys.
- * @since Android 1.0
*/
public Set<K> keySet() {
if (keySet == null) {
@@ -269,7 +255,7 @@
/**
* Maps the specified key to the specified value.
- *
+ *
* @param key
* the key.
* @param value
@@ -286,7 +272,6 @@
* @throws NullPointerException
* if the key or value is {@code null} and this Map does not
* support {@code null} keys or values.
- * @since Android 1.0
*/
public V put(K key, V value) {
throw new UnsupportedOperationException();
@@ -294,7 +279,7 @@
/**
* Copies every mapping in the specified map to this map.
- *
+ *
* @param map
* the map to copy mappings from.
* @throws UnsupportedOperationException
@@ -307,7 +292,6 @@
* @throws NullPointerException
* if a key or value is {@code null} and this map does not
* support {@code null} keys or values.
- * @since Android 1.0
*/
public void putAll(Map<? extends K, ? extends V> map) {
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
@@ -317,14 +301,13 @@
/**
* Removes a mapping with the specified key from this Map.
- *
+ *
* @param key
* the key of the mapping to remove.
* @return the value of the removed mapping or {@code null} if no mapping
* for the specified key was found.
* @throws UnsupportedOperationException
* if removing from this map is not supported.
- * @since Android 1.0
*/
public V remove(Object key) {
Iterator<Map.Entry<K, V>> it = entrySet().iterator();
@@ -350,9 +333,8 @@
/**
* Returns the number of elements in this map.
- *
+ *
* @return the number of elements in this map.
- * @since Android 1.0
*/
public int size() {
return entrySet().size();
@@ -360,9 +342,8 @@
/**
* Returns the string representation of this map.
- *
+ *
* @return the string representation of this map.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -407,16 +388,13 @@
* "wrapper object" over the iterator of map's entrySet(). The {@code size}
* method wraps the map's size method and the {@code contains} method wraps
* the map's containsValue method.
- * </p>
* <p>
* The collection is created when this method is called for the first time
* and returned in response to all subsequent calls. This method may return
* different collections when multiple concurrent calls occur to this
* method, since no synchronization is performed.
- * </p>
- *
+ *
* @return a collection of the values contained in this map.
- * @since Android 1.0
*/
public Collection<V> values() {
if (valuesCollection == null) {
@@ -458,12 +436,11 @@
/**
* Returns a new instance of the same class as this instance, whose slots
* have been filled in with the values of the slots of this instance.
- *
+ *
* @return a shallow copy of this object.
* @throws CloneNotSupportedException
* if the receiver's class does not implement the interface
* {@code Cloneable}.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
diff --git a/luni/src/main/java/java/util/AbstractQueue.java b/luni/src/main/java/java/util/AbstractQueue.java
index 0b9bdf1..4b4fccf 100644
--- a/luni/src/main/java/java/util/AbstractQueue.java
+++ b/luni/src/main/java/java/util/AbstractQueue.java
@@ -22,18 +22,15 @@
* {@code element} are based on {@code offer, poll}, and {@code peek} except
* that they throw exceptions to indicate some error instead of returning true
* or false.
- *
+ *
* @param <E>
* the type of the element in the collection.
- * @since Android 1.0
*/
public abstract class AbstractQueue<E> extends AbstractCollection<E> implements
Queue<E> {
/**
* Constructor to be used by subclasses.
- *
- * @since Android 1.0
*/
protected AbstractQueue() {
super();
@@ -47,7 +44,6 @@
* @return {@code true} if the operation succeeds, otherwise {@code false}.
* @throws IllegalStateException
* if the element is not allowed to be added to the queue.
- * @since Android 1.0
*/
@Override
public boolean add(E o) {
@@ -76,7 +72,6 @@
* @throws IllegalArgumentException
* If the collection to be added to the queue is the queue
* itself.
- * @since Android 1.0
*/
@Override
public boolean addAll(Collection<? extends E> c) {
@@ -95,7 +90,6 @@
* @return the element at the head of the queue.
* @throws NoSuchElementException
* if the queue is empty.
- * @since Android 1.0
*/
public E remove() {
E o = poll();
@@ -111,7 +105,6 @@
* @return the element at the head of the queue.
* @throws NoSuchElementException
* if the queue is empty.
- * @since Android 1.0
*/
public E element() {
E o = peek();
@@ -123,8 +116,6 @@
/**
* Removes all elements of the queue, leaving it empty.
- *
- * @since Android 1.0
*/
@Override
public void clear() {
diff --git a/luni/src/main/java/java/util/AbstractSequentialList.java b/luni/src/main/java/java/util/AbstractSequentialList.java
index 4ca8f7b..dcdecaa 100644
--- a/luni/src/main/java/java/util/AbstractSequentialList.java
+++ b/luni/src/main/java/java/util/AbstractSequentialList.java
@@ -17,20 +17,17 @@
package java.util;
-
/**
* AbstractSequentialList is an abstract implementation of the List interface.
* This implementation does not support adding. A subclass must implement the
* abstract method listIterator().
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public abstract class AbstractSequentialList<E> extends AbstractList<E> {
/**
* Constructs a new instance of this AbstractSequentialList.
- *
- * @since Android 1.0
*/
protected AbstractSequentialList() {
super();
@@ -45,24 +42,11 @@
public boolean addAll(int location, Collection<? extends E> collection) {
ListIterator<E> it = listIterator(location);
Iterator<? extends E> colIt = collection.iterator();
- // BEGIN android-removed
- // int next = it.nextIndex();
- // while (colIt.hasNext()) {
- // it.add(colIt.next());
- // it.previous();
- // }
- // return next != it.nextIndex();
- // END android-removed
-
- // BEGIN android-added
- // BUG: previous/next inconsistant. We care for list
- // modification NOT iterator modification.
- int size = this.size();
+ int next = it.nextIndex();
while (colIt.hasNext()) {
it.add(colIt.next());
}
- return size != this.size();
- // END android-added
+ return next != it.nextIndex();
}
@Override
@@ -97,6 +81,9 @@
@Override
public E set(int location, E object) {
ListIterator<E> it = listIterator(location);
+ if (!it.hasNext()) {
+ throw new IndexOutOfBoundsException();
+ }
E result = it.next();
it.set(object);
return result;
diff --git a/luni/src/main/java/java/util/AbstractSet.java b/luni/src/main/java/java/util/AbstractSet.java
index a19b1f7..e6ef0bb 100644
--- a/luni/src/main/java/java/util/AbstractSet.java
+++ b/luni/src/main/java/java/util/AbstractSet.java
@@ -22,15 +22,13 @@
* implementation does not support adding. A subclass must implement the
* abstract methods iterator() and size().
*
- * @since Android 1.0
+ * @since 1.2
*/
public abstract class AbstractSet<E> extends AbstractCollection<E> implements
Set<E> {
/**
* Constructs a new instance of this AbstractSet.
- *
- * @since Android 1.0
*/
protected AbstractSet() {
super();
@@ -46,7 +44,6 @@
* @return {@code true} if the specified object is equal to this set,
* {@code false} otherwise
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -55,14 +52,12 @@
}
if (object instanceof Set) {
Set<?> s = (Set<?>) object;
- // BEGIN android-changed
- // copied from a newer version of harmony
+
try {
return size() == s.size() && containsAll(s);
} catch (ClassCastException cce) {
return false;
}
- // END android-changed
}
return false;
}
@@ -74,7 +69,6 @@
*
* @return the hash code of this set.
* @see #equals
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -95,9 +89,8 @@
* the collection of objects to remove.
* @return {@code true} if this collection was modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when removing from this collection is not supported.
- * @since Android 1.0
+ * @throws UnsupportedOperationException
+ * if removing from this collection is not supported.
*/
@Override
public boolean removeAll(Collection<?> collection) {
diff --git a/luni/src/main/java/java/util/ArrayList.java b/luni/src/main/java/java/util/ArrayList.java
index 78f9690..ade5d27 100644
--- a/luni/src/main/java/java/util/ArrayList.java
+++ b/luni/src/main/java/java/util/ArrayList.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -29,11 +28,11 @@
* ArrayList is an implementation of {@link List}, backed by an array. All
* optional operations adding, removing, and replacing are supported. The
* elements can be any objects.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
-public class ArrayList<E> extends AbstractList<E> implements List<E>, Cloneable,
- Serializable, RandomAccess {
+public class ArrayList<E> extends AbstractList<E> implements List<E>,
+ Cloneable, Serializable, RandomAccess {
private static final long serialVersionUID = 8683452581122892189L;
@@ -43,53 +42,53 @@
// END android-added
private transient int firstIndex;
-
+
private transient int lastIndex;
private transient E[] array;
/**
* Constructs a new instance of {@code ArrayList} with zero capacity.
- *
- * @since Android 1.0
*/
public ArrayList() {
+ // BEGIN android-changed
+ // default capacity is zero, not ten
this(0);
+ // END android-changed
}
/**
* Constructs a new instance of {@code ArrayList} with the specified
* capacity.
- *
+ *
* @param capacity
* the initial capacity of this {@code ArrayList}.
- * @since Android 1.0
*/
public ArrayList(int capacity) {
- firstIndex = lastIndex = 0;
- try {
- array = newElementArray(capacity);
- } catch (NegativeArraySizeException e) {
+ if (capacity < 0) {
throw new IllegalArgumentException();
}
+ firstIndex = lastIndex = 0;
+ array = newElementArray(capacity);
}
/**
* Constructs a new instance of {@code ArrayList} containing the elements of
* the specified collection. The initial size of the {@code ArrayList} will
* be 10% higher than the size of the specified collection.
- *
+ *
* @param collection
* the collection of elements to add.
- * @since Android 1.0
*/
public ArrayList(Collection<? extends E> collection) {
int size = collection.size();
- firstIndex = lastIndex = 0;
+ firstIndex = 0;
array = newElementArray(size + (size / 10));
- addAll(collection);
+ collection.toArray(array);
+ lastIndex = size;
+ modCount = 1;
}
-
+
@SuppressWarnings("unchecked")
private E[] newElementArray(int size) {
// BEGIN android-added
@@ -98,7 +97,7 @@
}
// END android-added
- return (E[])new Object[size];
+ return (E[]) new Object[size];
}
/**
@@ -106,20 +105,17 @@
* location. The object is inserted before any previous element at the
* specified location. If the location is equal to the size of this
* {@code ArrayList}, the object is added at the end.
- *
+ *
* @param location
* the index at which to insert the object.
* @param object
* the object to add.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || > size()}
- * @since Android 1.0
*/
@Override
public void add(int location, E object) {
- // BEGIN android-changed: slight performance improvement
int size = lastIndex - firstIndex;
- // END android-changed
if (0 < location && location < size) {
if (firstIndex == 0 && lastIndex == array.length) {
growForInsert(location, 1);
@@ -153,11 +149,10 @@
/**
* Adds the specified object at the end of this {@code ArrayList}.
- *
+ *
* @param object
* the object to add.
* @return always true
- * @since Android 1.0
*/
@Override
public boolean add(E object) {
@@ -173,7 +168,7 @@
* Inserts the objects in the specified collection at the specified location
* in this List. The objects are added in the order they are returned from
* the collection's iterator.
- *
+ *
* @param location
* the index at which to insert.
* @param collection
@@ -182,14 +177,16 @@
* otherwise.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || > size()}
- * @since Android 1.0
*/
@Override
public boolean addAll(int location, Collection<? extends E> collection) {
- int size = size();
+ int size = lastIndex - firstIndex;
if (location < 0 || location > size) {
throw new IndexOutOfBoundsException();
}
+ if (this == collection) {
+ collection = (ArrayList)clone();
+ }
int growSize = collection.size();
if (0 < location && location < size) {
if (array.length - size < growSize) {
@@ -223,12 +220,10 @@
}
if (growSize > 0) {
- Iterator<? extends E> it = collection.iterator();
- int index = location + firstIndex;
- int end = index + growSize;
- while (index < end) {
- array[index++] = it.next();
- }
+ Object[] dumparray = new Object[growSize];
+ collection.toArray(dumparray);
+ System.arraycopy(dumparray, 0, this.array, location + firstIndex,
+ growSize);
modCount++;
return true;
}
@@ -237,37 +232,32 @@
/**
* Adds the objects in the specified collection to this {@code ArrayList}.
- *
+ *
* @param collection
* the collection of objects.
* @return {@code true} if this {@code ArrayList} is modified, {@code false}
* otherwise.
- * @since Android 1.0
*/
@Override
public boolean addAll(Collection<? extends E> collection) {
- int growSize = collection.size();
- if (growSize > 0) {
- if (lastIndex > array.length - growSize) {
- growAtEnd(growSize);
- }
- Iterator<? extends E> it = collection.iterator();
- int end = lastIndex + growSize;
- while (lastIndex < end) {
- array[lastIndex++] = it.next();
- }
- modCount++;
- return true;
+ Object[] dumpArray = collection.toArray();
+ if (dumpArray.length == 0) {
+ return false;
}
- return false;
+ if (dumpArray.length > array.length - lastIndex) {
+ growAtEnd(dumpArray.length);
+ }
+ System.arraycopy(dumpArray, 0, this.array, lastIndex, dumpArray.length);
+ lastIndex += dumpArray.length;
+ modCount++;
+ return true;
}
/**
* Removes all elements from this {@code ArrayList}, leaving it empty.
- *
+ *
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -281,10 +271,9 @@
/**
* Returns a new {@code ArrayList} with the same elements, the same size and
* the same capacity as this {@code ArrayList}.
- *
+ *
* @return a shallow copy of this {@code ArrayList}
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -300,12 +289,11 @@
/**
* Searches this {@code ArrayList} for the specified object.
- *
+ *
* @param object
* the object to search for.
* @return {@code true} if {@code object} is an element of this
* {@code ArrayList}, {@code false} otherwise
- * @since Android 1.0
*/
@Override
public boolean contains(Object object) {
@@ -328,10 +316,9 @@
/**
* Ensures that after this operation the {@code ArrayList} can hold the
* specified number of elements without further growing.
- *
+ *
* @param minimumCapacity
* the minimum capacity asked for.
- * @since Android 1.0
*/
public void ensureCapacity(int minimumCapacity) {
if (array.length < minimumCapacity) {
@@ -356,7 +343,7 @@
}
private void growAtEnd(int required) {
- int size = size();
+ int size = lastIndex - firstIndex;
if (firstIndex >= required - (array.length - lastIndex)) {
int newLast = lastIndex - firstIndex;
if (size > 0) {
@@ -385,8 +372,8 @@
}
private void growAtFront(int required) {
- int size = size();
- if (array.length - lastIndex >= required) {
+ int size = lastIndex - firstIndex;
+ if (array.length - lastIndex + firstIndex >= required) {
int newFirst = array.length - size;
if (size > 0) {
System.arraycopy(array, firstIndex, array, newFirst, size);
@@ -416,7 +403,8 @@
}
private void growForInsert(int location, int required) {
- int size = size(), increment = size / 2;
+ int size = lastIndex - firstIndex;
+ int increment = size / 2;
if (required > increment) {
increment = required;
}
@@ -480,20 +468,17 @@
/**
* Removes the object at the specified location from this list.
- *
+ *
* @param location
* the index of the object to remove.
* @return the removed object.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || >= size()}
- * @since Android 1.0
*/
@Override
public E remove(int location) {
E result;
- // BEGIN android-changed: slight performance improvement
int size = lastIndex - firstIndex;
- // END android-changed
if (0 <= location && location < size) {
if (location == size - 1) {
result = array[--lastIndex];
@@ -514,6 +499,9 @@
array[--lastIndex] = null;
}
}
+ if (firstIndex == lastIndex) {
+ firstIndex = lastIndex = 0;
+ }
} else {
throw new IndexOutOfBoundsException();
}
@@ -522,41 +510,34 @@
return result;
}
- // BEGIN android-added
- /*
- * The remove(Object) implementation from AbstractCollection creates
- * a new Iterator on every remove and ends up calling remove(int).
- */
@Override
public boolean remove(Object object) {
- int index = indexOf(object);
- if (index >= 0) {
- remove(index);
+ int location = indexOf(object);
+ if (location >= 0) {
+ remove(location);
return true;
}
return false;
}
- // END android-added
/**
* Removes the objects in the specified range from the start to the end, but
* not including the end index.
- *
+ *
* @param start
* the index at which to start removing.
* @param end
* the index one after the end of the range to remove.
* @throws IndexOutOfBoundsException
* when {@code start < 0, start > end} or {@code end > size()}
- * @since Android 1.0
*/
@Override
protected void removeRange(int start, int end) {
- if (start >= 0 && start <= end && end <= size()) {
+ if (start >= 0 && start <= end && end <= (lastIndex - firstIndex)) {
if (start == end) {
return;
}
- int size = size();
+ int size = lastIndex - firstIndex;
if (end == size) {
Arrays.fill(array, firstIndex + start, lastIndex, null);
lastIndex = firstIndex + start;
@@ -579,7 +560,7 @@
/**
* Replaces the element at the specified location in this {@code ArrayList}
* with the specified object.
- *
+ *
* @param location
* the index at which to put the specified object.
* @param object
@@ -587,13 +568,10 @@
* @return the previous element at the index.
* @throws IndexOutOfBoundsException
* when {@code location < 0 || >= size()}
- * @since Android 1.0
*/
@Override
public E set(int location, E object) {
- // BEGIN android-changed: slight performance improvement
if (0 <= location && location < (lastIndex - firstIndex)) {
- // END android-changed
E result = array[firstIndex + location];
array[firstIndex + location] = object;
return result;
@@ -603,9 +581,8 @@
/**
* Returns the number of elements in this {@code ArrayList}.
- *
+ *
* @return the number of elements in this {@code ArrayList}.
- * @since Android 1.0
*/
@Override
public int size() {
@@ -615,13 +592,12 @@
/**
* Returns a new array containing all elements contained in this
* {@code ArrayList}.
- *
+ *
* @return an array of the elements from this {@code ArrayList}
- * @since Android 1.0
*/
@Override
public Object[] toArray() {
- int size = size();
+ int size = lastIndex - firstIndex;
Object[] result = new Object[size];
System.arraycopy(array, firstIndex, result, 0, size);
return result;
@@ -634,19 +610,18 @@
* type is created. If the specified array is used and is larger than this
* {@code ArrayList}, the array element following the collection elements
* is set to null.
- *
+ *
* @param contents
* the array.
* @return an array of the elements from this {@code ArrayList}.
* @throws ArrayStoreException
* when the type of an element in this {@code ArrayList} cannot
* be stored in the type of the specified array.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] contents) {
- int size = size();
+ int size = lastIndex - firstIndex;
if (size > contents.length) {
Class<?> ct = contents.getClass().getComponentType();
contents = (T[]) Array.newInstance(ct, size);
@@ -661,17 +636,17 @@
/**
* Sets the capacity of this {@code ArrayList} to be the same as the current
* size.
- *
+ *
* @see #size
- * @since Android 1.0
*/
public void trimToSize() {
- int size = size();
+ int size = lastIndex - firstIndex;
E[] newArray = newElementArray(size);
System.arraycopy(array, firstIndex, newArray, 0, size);
array = newArray;
firstIndex = 0;
lastIndex = array.length;
+ modCount = 0;
}
private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField(
@@ -679,7 +654,7 @@
private void writeObject(ObjectOutputStream stream) throws IOException {
ObjectOutputStream.PutField fields = stream.putFields();
- fields.put("size", size()); //$NON-NLS-1$
+ fields.put("size", lastIndex - firstIndex); //$NON-NLS-1$
stream.writeFields();
stream.writeInt(array.length);
Iterator<?> it = iterator();
@@ -695,7 +670,7 @@
lastIndex = fields.get("size", 0); //$NON-NLS-1$
array = newElementArray(stream.readInt());
for (int i = 0; i < lastIndex; i++) {
- array[i] = (E)stream.readObject();
+ array[i] = (E) stream.readObject();
}
}
}
diff --git a/luni/src/main/java/java/util/Arrays.java b/luni/src/main/java/java/util/Arrays.java
index d479945..4fc1e85 100644
--- a/luni/src/main/java/java/util/Arrays.java
+++ b/luni/src/main/java/java/util/Arrays.java
@@ -22,11 +22,16 @@
/**
* {@code Arrays} contains static methods which operate on arrays.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public class Arrays {
+ // BEGIN android-removed
+ /* Specifies when to switch to insertion sort */
+ // private static final int SIMPLE_LENGTH = 7;
+ // END android-removed
+
private static class ArrayList<E> extends AbstractList<E> implements
List<E>, Serializable, RandomAccess {
@@ -152,11 +157,10 @@
* {@code List} cannot be modified, i.e. adding and removing are unsupported, but
* the elements can be set. Setting an element modifies the underlying
* array.
- *
+ *
* @param array
* the array.
* @return a {@code List} of the elements of the specified array.
- * @since Android 1.0
*/
public static <T> List<T> asList(T... array) {
return new ArrayList<T>(array);
@@ -167,19 +171,18 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code byte} array to search.
* @param value
* the {@code byte} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @since Android 1.0
*/
public static int binarySearch(byte[] array, byte value) {
int low = 0, mid = -1, high = array.length - 1;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if (value > array[mid]) {
low = mid + 1;
} else if (value == array[mid]) {
@@ -200,19 +203,18 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code char} array to search.
* @param value
* the {@code char} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @since Android 1.0
*/
public static int binarySearch(char[] array, char value) {
int low = 0, mid = -1, high = array.length - 1;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if (value > array[mid]) {
low = mid + 1;
} else if (value == array[mid]) {
@@ -232,20 +234,19 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code double} array to search.
* @param value
* the {@code double} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @since Android 1.0
*/
public static int binarySearch(double[] array, double value) {
long longBits = Double.doubleToLongBits(value);
int low = 0, mid = -1, high = array.length - 1;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if (lessThan(array[mid], value)) {
low = mid + 1;
} else if (longBits == Double.doubleToLongBits(array[mid])) {
@@ -265,20 +266,19 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code float} array to search.
* @param value
* the {@code float} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @since Android 1.0
*/
public static int binarySearch(float[] array, float value) {
int intBits = Float.floatToIntBits(value);
int low = 0, mid = -1, high = array.length - 1;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if (lessThan(array[mid], value)) {
low = mid + 1;
} else if (intBits == Float.floatToIntBits(array[mid])) {
@@ -298,19 +298,18 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code int} array to search.
* @param value
* the {@code int} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @since Android 1.0
*/
public static int binarySearch(int[] array, int value) {
int low = 0, mid = -1, high = array.length - 1;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if (value > array[mid]) {
low = mid + 1;
} else if (value == array[mid]) {
@@ -330,19 +329,18 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code long} array to search.
* @param value
* the {@code long} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @since Android 1.0
*/
public static int binarySearch(long[] array, long value) {
int low = 0, mid = -1, high = array.length - 1;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if (value > array[mid]) {
low = mid + 1;
} else if (value == array[mid]) {
@@ -362,28 +360,27 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code Object} array to search.
* @param object
* the {@code Object} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @exception ClassCastException
+ * @throws ClassCastException
* if an element in the array or the search element does not
* implement {@code Comparable}, or cannot be compared to each other.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static int binarySearch(Object[] array, Object object) {
if (array.length == 0) {
return -1;
}
- Comparable<Object> key = (Comparable<Object>) object;
+
int low = 0, mid = 0, high = array.length - 1, result = 0;
while (low <= high) {
- mid = (low + high) >> 1;
- if ((result = key.compareTo(array[mid])) > 0) {
+ mid = (low + high) >>> 1;
+ if ((result = ((Comparable<Object>)array[mid]).compareTo(object)) < 0){
low = mid + 1;
} else if (result == 0) {
return mid;
@@ -391,7 +388,7 @@
high = mid - 1;
}
}
- return -mid - (result <= 0 ? 1 : 2);
+ return -mid - (result >= 0 ? 1 : 2);
}
/**
@@ -400,7 +397,7 @@
* Searching in an unsorted array has an undefined result. It's also
* undefined which element is found if there are multiple occurrences of the
* same element.
- *
+ *
* @param array
* the sorted array to search
* @param object
@@ -409,10 +406,9 @@
* the {@code Comparator} sued to compare the elements.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @exception ClassCastException
- * if an element in the array cannot be compared to the search element
+ * @throws ClassCastException
+ * if an element in the array cannot be compared to the search element
* using the {@code Comparator}.
- * @since Android 1.0
*/
public static <T> int binarySearch(T[] array, T object,
Comparator<? super T> comparator) {
@@ -422,7 +418,7 @@
int low = 0, mid = 0, high = array.length - 1, result = 0;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if ((result = comparator.compare(array[mid], object)) < 0) {
low = mid + 1;
} else if (result == 0) {
@@ -439,19 +435,18 @@
* ascending sorted array. Searching in an unsorted array has an undefined
* result. It's also undefined which element is found if there are multiple
* occurrences of the same element.
- *
+ *
* @param array
* the sorted {@code short} array to search.
* @param value
* the {@code short} element to find.
* @return the non-negative index of the element, or a negative index which
* is {@code -index - 1} where the element would be inserted.
- * @since Android 1.0
*/
public static int binarySearch(short[] array, short value) {
int low = 0, mid = -1, high = array.length - 1;
while (low <= high) {
- mid = (low + high) >> 1;
+ mid = (low + high) >>> 1;
if (value > array[mid]) {
low = mid + 1;
} else if (value == array[mid]) {
@@ -468,12 +463,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code byte} array to fill.
* @param value
* the {@code byte} element.
- * @since Android 1.0
*/
public static void fill(byte[] array, byte value) {
for (int i = 0; i < array.length; i++) {
@@ -483,7 +477,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code byte} array to fill.
* @param start
@@ -492,11 +486,10 @@
* the last + 1 index to fill.
* @param value
* the {@code byte} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(byte[] array, int start, int end, byte value) {
// Check for null first
@@ -514,12 +507,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code short} array to fill.
* @param value
* the {@code short} element.
- * @since Android 1.0
*/
public static void fill(short[] array, short value) {
for (int i = 0; i < array.length; i++) {
@@ -529,7 +521,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code short} array to fill.
* @param start
@@ -538,11 +530,10 @@
* the last + 1 index to fill.
* @param value
* the {@code short} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(short[] array, int start, int end, short value) {
// Check for null first
@@ -560,12 +551,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code char} array to fill.
* @param value
* the {@code char} element.
- * @since Android 1.0
*/
public static void fill(char[] array, char value) {
for (int i = 0; i < array.length; i++) {
@@ -575,7 +565,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code char} array to fill.
* @param start
@@ -584,11 +574,10 @@
* the last + 1 index to fill.
* @param value
* the {@code char} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(char[] array, int start, int end, char value) {
// Check for null first
@@ -606,12 +595,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code int} array to fill.
* @param value
* the {@code int} element.
- * @since Android 1.0
*/
public static void fill(int[] array, int value) {
for (int i = 0; i < array.length; i++) {
@@ -621,7 +609,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code int} array to fill.
* @param start
@@ -630,11 +618,10 @@
* the last + 1 index to fill.
* @param value
* the {@code int} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(int[] array, int start, int end, int value) {
// Check for null first
@@ -652,12 +639,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code long} array to fill.
* @param value
* the {@code long} element.
- * @since Android 1.0
*/
public static void fill(long[] array, long value) {
for (int i = 0; i < array.length; i++) {
@@ -667,7 +653,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code long} array to fill.
* @param start
@@ -676,11 +662,10 @@
* the last + 1 index to fill.
* @param value
* the {@code long} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(long[] array, int start, int end, long value) {
// Check for null first
@@ -698,12 +683,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code float} array to fill.
* @param value
* the {@code float} element.
- * @since Android 1.0
*/
public static void fill(float[] array, float value) {
for (int i = 0; i < array.length; i++) {
@@ -713,7 +697,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code float} array to fill.
* @param start
@@ -722,11 +706,10 @@
* the last + 1 index to fill.
* @param value
* the {@code float} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(float[] array, int start, int end, float value) {
// Check for null first
@@ -744,12 +727,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code double} array to fill.
* @param value
* the {@code double} element.
- * @since Android 1.0
*/
public static void fill(double[] array, double value) {
for (int i = 0; i < array.length; i++) {
@@ -759,7 +741,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code double} array to fill.
* @param start
@@ -768,11 +750,10 @@
* the last + 1 index to fill.
* @param value
* the {@code double} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(double[] array, int start, int end, double value) {
// Check for null first
@@ -790,12 +771,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code boolean} array to fill.
* @param value
* the {@code boolean} element.
- * @since Android 1.0
*/
public static void fill(boolean[] array, boolean value) {
for (int i = 0; i < array.length; i++) {
@@ -805,7 +785,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code boolean} array to fill.
* @param start
@@ -814,11 +794,10 @@
* the last + 1 index to fill.
* @param value
* the {@code boolean} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(boolean[] array, int start, int end, boolean value) {
// Check for null first
@@ -836,12 +815,11 @@
/**
* Fills the specified array with the specified element.
- *
+ *
* @param array
* the {@code Object} array to fill.
* @param value
* the {@code Object} element.
- * @since Android 1.0
*/
public static void fill(Object[] array, Object value) {
for (int i = 0; i < array.length; i++) {
@@ -851,7 +829,7 @@
/**
* Fills the specified range in the array with the specified element.
- *
+ *
* @param array
* the {@code Object} array to fill.
* @param start
@@ -860,11 +838,10 @@
* the last + 1 index to fill.
* @param value
* the {@code Object} element.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void fill(Object[] array, int start, int end, Object value) {
// Check for null first
@@ -882,7 +859,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * {@code boolean} arrays {@code a} and {@code b}, if
+ * {@code boolean} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -891,11 +868,10 @@
* containing a sequence of {@link Boolean}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(boolean[] array) {
if (array == null) {
@@ -911,7 +887,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * not-null {@code int} arrays {@code a} and {@code b}, if
+ * not-null {@code int} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -920,11 +896,10 @@
* containing a sequence of {@link Integer}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(int[] array) {
if (array == null) {
@@ -940,7 +915,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * {@code short} arrays {@code a} and {@code b}, if
+ * {@code short} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -949,11 +924,10 @@
* containing a sequence of {@link Short}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(short[] array) {
if (array == null) {
@@ -969,7 +943,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * {@code char} arrays {@code a} and {@code b}, if
+ * {@code char} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -978,11 +952,10 @@
* containing a sequence of {@link Character}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(char[] array) {
if (array == null) {
@@ -998,7 +971,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * {@code byte} arrays {@code a} and {@code b}, if
+ * {@code byte} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -1007,11 +980,10 @@
* containing a sequence of {@link Byte}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(byte[] array) {
if (array == null) {
@@ -1027,7 +999,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * {@code long} arrays {@code a} and {@code b}, if
+ * {@code long} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -1036,11 +1008,10 @@
* containing a sequence of {@link Long}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(long[] array) {
if (array == null) {
@@ -1060,7 +1031,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * {@code float} arrays {@code a} and {@code b}, if
+ * {@code float} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -1069,11 +1040,10 @@
* containing a sequence of {@link Float}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(float[] array) {
if (array == null) {
@@ -1092,7 +1062,7 @@
/**
* Returns a hash code based on the contents of the given array. For any two
- * {@code double} arrays {@code a} and {@code b}, if
+ * {@code double} arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
* that the return value of {@code Arrays.hashCode(a)} equals {@code Arrays.hashCode(b)}.
* <p>
@@ -1101,11 +1071,10 @@
* containing a sequence of {@link Double}} instances representing the
* elements of array in the same order. If the array is {@code null}, the return
* value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(double[] array) {
if (array == null) {
@@ -1131,19 +1100,18 @@
* method on an array that contains itself as an element, either directly or
* indirectly.
* <p>
- * For any two arrays {@code a} and {@code b}, if
+ * For any two arrays {@code a} and {@code b}, if
* {@code Arrays.equals(a, b)} returns {@code true}, it means
- * that the return value of {@code Arrays.hashCode(a)} equals
+ * that the return value of {@code Arrays.hashCode(a)} equals
* {@code Arrays.hashCode(b)}.
* <p>
* The value returned by this method is the same value as the method
* Arrays.asList(array).hashCode(). If the array is {@code null}, the return value
* is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int hashCode(Object[] array) {
if (array == null) {
@@ -1170,7 +1138,7 @@
* this method on an array that contains itself as an element, either
* directly or indirectly.
* <p>
- * For any two arrays {@code a} and {@code b}, if
+ * For any two arrays {@code a} and {@code b}, if
* {@code Arrays.deepEquals(a, b)} returns {@code true}, it
* means that the return value of {@code Arrays.deepHashCode(a)} equals
* {@code Arrays.deepHashCode(b)}.
@@ -1185,11 +1153,10 @@
* an array of a reference type. The value returned by this method is the
* same value as the method {@code Arrays.asList(array).hashCode()}. If the array is
* {@code null}, the return value is 0.
- *
+ *
* @param array
* the array whose hash code to compute.
* @return the hash code for {@code array}.
- * @since Android 1.0
*/
public static int deepHashCode(Object[] array) {
if (array == null) {
@@ -1247,7 +1214,7 @@
/**
* Compares the two arrays.
- *
+ *
* @param array1
* the first {@code byte} array.
* @param array2
@@ -1255,7 +1222,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean equals(byte[] array1, byte[] array2) {
if (array1 == array2) {
@@ -1274,7 +1240,7 @@
/**
* Compares the two arrays.
- *
+ *
* @param array1
* the first {@code short} array.
* @param array2
@@ -1282,7 +1248,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean equals(short[] array1, short[] array2) {
if (array1 == array2) {
@@ -1301,7 +1266,7 @@
/**
* Compares the two arrays.
- *
+ *
* @param array1
* the first {@code char} array.
* @param array2
@@ -1309,7 +1274,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean equals(char[] array1, char[] array2) {
if (array1 == array2) {
@@ -1328,7 +1292,7 @@
/**
* Compares the two arrays.
- *
+ *
* @param array1
* the first {@code int} array.
* @param array2
@@ -1336,7 +1300,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean equals(int[] array1, int[] array2) {
if (array1 == array2) {
@@ -1355,7 +1318,7 @@
/**
* Compares the two arrays.
- *
+ *
* @param array1
* the first {@code long} array.
* @param array2
@@ -1363,7 +1326,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean equals(long[] array1, long[] array2) {
if (array1 == array2) {
@@ -1383,7 +1345,7 @@
/**
* Compares the two arrays. The values are compared in the same manner as
* {@code Float.equals()}.
- *
+ *
* @param array1
* the first {@code float} array.
* @param array2
@@ -1392,7 +1354,6 @@
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
* @see Float#equals(Object)
- * @since Android 1.0
*/
public static boolean equals(float[] array1, float[] array2) {
if (array1 == array2) {
@@ -1413,7 +1374,7 @@
/**
* Compares the two arrays. The values are compared in the same manner as
* {@code Double.equals()}.
- *
+ *
* @param array1
* the first {@code double} array.
* @param array2
@@ -1422,7 +1383,6 @@
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
* @see Double#equals(Object)
- * @since Android 1.0
*/
public static boolean equals(double[] array1, double[] array2) {
if (array1 == array2) {
@@ -1442,7 +1402,7 @@
/**
* Compares the two arrays.
- *
+ *
* @param array1
* the first {@code boolean} array.
* @param array2
@@ -1450,7 +1410,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean equals(boolean[] array1, boolean[] array2) {
if (array1 == array2) {
@@ -1469,7 +1428,7 @@
/**
* Compares the two arrays.
- *
+ *
* @param array1
* the first {@code Object} array.
* @param array2
@@ -1477,7 +1436,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal according to {@code equals()}, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean equals(Object[] array1, Object[] array2) {
if (array1 == array2) {
@@ -1522,7 +1480,7 @@
* <p>
* If either of the given arrays contain themselves as elements, the
* behavior of this method is uncertain.
- *
+ *
* @param array1
* the first {@code Object} array.
* @param array2
@@ -1530,7 +1488,6 @@
* @return {@code true} if both arrays are {@code null} or if the arrays have the
* same length and the elements at each index in the two arrays are
* equal according to {@code equals()}, {@code false} otherwise.
- * @since Android 1.0
*/
public static boolean deepEquals(Object[] array1, Object[] array2) {
if (array1 == array2) {
@@ -1603,41 +1560,58 @@
}
private static boolean lessThan(double double1, double double2) {
- long d1, d2;
- long NaNbits = Double.doubleToLongBits(Double.NaN);
- if ((d1 = Double.doubleToLongBits(double1)) == NaNbits) {
- return false;
- }
- if ((d2 = Double.doubleToLongBits(double2)) == NaNbits) {
+ // A slightly specialized version of
+ // Double.compare(double1, double2) < 0.
+
+ // Non-zero and non-NaN checking.
+ if (double1 < double2) {
return true;
}
- if (double1 == double2) {
- if (d1 == d2) {
- return false;
- }
- // check for -0
- return d1 < d2;
+ if (double1 > double2) {
+ return false;
}
- return double1 < double2;
+ if (double1 == double2 && 0.0d != double1) {
+ return false;
+ }
+
+ // NaNs are equal to other NaNs and larger than any other double.
+ if (Double.isNaN(double1)) {
+ return false;
+ } else if (Double.isNaN(double2)) {
+ return true;
+ }
+
+ // Deal with +0.0 and -0.0.
+ long d1 = Double.doubleToRawLongBits(double1);
+ long d2 = Double.doubleToRawLongBits(double2);
+ return d1 < d2;
}
private static boolean lessThan(float float1, float float2) {
- int f1, f2;
- int NaNbits = Float.floatToIntBits(Float.NaN);
- if ((f1 = Float.floatToIntBits(float1)) == NaNbits) {
- return false;
- }
- if ((f2 = Float.floatToIntBits(float2)) == NaNbits) {
+ // A slightly specialized version of Float.compare(float1, float2) < 0.
+
+ // Non-zero and non-NaN checking.
+ if (float1 < float2) {
return true;
}
- if (float1 == float2) {
- if (f1 == f2) {
- return false;
- }
- // check for -0
- return f1 < f2;
+ if (float1 > float2) {
+ return false;
}
- return float1 < float2;
+ if (float1 == float2 && 0.0f != float1) {
+ return false;
+ }
+
+ // NaNs are equal to other NaNs and larger than any other float
+ if (Float.isNaN(float1)) {
+ return false;
+ } else if (Float.isNaN(float2)) {
+ return true;
+ }
+
+ // Deal with +0.0 and -0.0
+ int f1 = Float.floatToRawIntBits(float1);
+ int f2 = Float.floatToRawIntBits(float2);
+ return f1 < f2;
}
private static int med3(byte[] array, int a, int b, int c) {
@@ -1684,10 +1658,9 @@
/**
* Sorts the specified array in ascending numerical order.
- *
+ *
* @param array
* the {@code byte} array to be sorted.
- * @since Android 1.0
*/
public static void sort(byte[] array) {
sort(0, array.length, array);
@@ -1695,18 +1668,17 @@
/**
* Sorts the specified range in the array in ascending numerical order.
- *
+ *
* @param array
* the {@code byte} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void sort(byte[] array, int start, int end) {
if (array == null) {
@@ -1718,8 +1690,8 @@
private static void checkBounds(int arrLength, int start, int end) {
if (start > end) {
- throw new IllegalArgumentException("fromIndex(" + start //$NON-NLS-1$
- + ") > toIndex(" + end + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new IllegalArgumentException("start(" + start //$NON-NLS-1$
+ + ") > end(" + end + ")"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (start < 0 || end > arrLength) {
throw new ArrayIndexOutOfBoundsException();
@@ -1806,10 +1778,9 @@
/**
* Sorts the specified array in ascending numerical order.
- *
+ *
* @param array
* the {@code char} array to be sorted.
- * @since Android 1.0
*/
public static void sort(char[] array) {
sort(0, array.length, array);
@@ -1817,18 +1788,17 @@
/**
* Sorts the specified range in the array in ascending numerical order.
- *
+ *
* @param array
* the {@code char} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void sort(char[] array, int start, int end) {
if (array == null) {
@@ -1918,11 +1888,10 @@
/**
* Sorts the specified array in ascending numerical order.
- *
+ *
* @param array
* the {@code double} array to be sorted.
* @see #sort(double[], int, int)
- * @since Android 1.0
*/
public static void sort(double[] array) {
sort(0, array.length, array);
@@ -1931,19 +1900,18 @@
/**
* Sorts the specified range in the array in ascending numerical order. The
* values are sorted according to the order imposed by {@code Double.compareTo()}.
- *
+ *
* @param array
* the {@code double} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
* @see Double#compareTo(Double)
- * @since Android 1.0
*/
public static void sort(double[] array, int start, int end) {
if (array == null) {
@@ -2033,11 +2001,10 @@
/**
* Sorts the specified array in ascending numerical order.
- *
+ *
* @param array
* the {@code float} array to be sorted.
* @see #sort(float[], int, int)
- * @since Android 1.0
*/
public static void sort(float[] array) {
sort(0, array.length, array);
@@ -2046,19 +2013,18 @@
/**
* Sorts the specified range in the array in ascending numerical order. The
* values are sorted according to the order imposed by {@code Float.compareTo()}.
- *
+ *
* @param array
* the {@code float} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
* @see Float#compareTo(Float)
- * @since Android 1.0
*/
public static void sort(float[] array, int start, int end) {
if (array == null) {
@@ -2148,10 +2114,9 @@
/**
* Sorts the specified array in ascending numerical order.
- *
+ *
* @param array
* the {@code int} array to be sorted.
- * @since Android 1.0
*/
public static void sort(int[] array) {
sort(0, array.length, array);
@@ -2159,18 +2124,17 @@
/**
* Sorts the specified range in the array in ascending numerical order.
- *
+ *
* @param array
* the {@code int} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void sort(int[] array, int start, int end) {
if (array == null) {
@@ -2260,10 +2224,9 @@
/**
* Sorts the specified array in ascending numerical order.
- *
+ *
* @param array
* the {@code long} array to be sorted.
- * @since Android 1.0
*/
public static void sort(long[] array) {
sort(0, array.length, array);
@@ -2271,18 +2234,17 @@
/**
* Sorts the specified range in the array in ascending numerical order.
- *
+ *
* @param array
* the {@code long} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void sort(long[] array, int start, int end) {
if (array == null) {
@@ -2370,7 +2332,7 @@
}
}
-// BEGIN android-changed
+// BEGIN android-note
/*
* <p>If this platform has an optimizing VM, check whether ComparableTimSort
@@ -2405,19 +2367,22 @@
// sort(a, fromIndex, toIndex, NATURAL_ORDER);
// }
+// END android-note
+
/**
* Sorts the specified array in ascending natural order.
- *
+ *
* @param array
* the {@code Object} array to be sorted.
- * @exception ClassCastException
+ * @throws ClassCastException
* if an element in the array does not implement {@code Comparable}
* or if some elements cannot be compared to each other.
* @see #sort(Object[], int, int)
- * @since Android 1.0
*/
public static void sort(Object[] array) {
+ // BEGIN android-changed
ComparableTimSort.sort(array);
+ // END android-changed
}
/**
@@ -2425,31 +2390,76 @@
* elements must implement the {@code Comparable} interface and must be
* comparable to each other without a {@code ClassCastException} being
* thrown.
- *
+ *
* @param array
* the {@code Object} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception ClassCastException
+ * @throws ClassCastException
* if an element in the array does not implement {@code Comparable}
* or some elements cannot be compared to each other.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void sort(Object[] array, int start, int end) {
+ // BEGIN android-changed
ComparableTimSort.sort(array, start, end);
+ // END android-changed
}
+ // BEGIN android-removed
+ /*
+ private static void sort(int start, int end, Object[] array) {
+ ...
+ }
+ private static void swap(int a, int b, Object[] arr) {
+ ...
+ }
+ private static void mergeSort(Object[] in, Object[] out, int start,
+ int end) {
+ ...
+ }
+ private static void mergeSort(Object[] in, Object[] out, int start,
+ int end, Comparator c) {
+ ...
+ }
+ private static int find(Object[] arr, Comparable val, int bnd, int l, int r) {
+ ...
+ }
+ private static int find(Object[] arr, Object val, int bnd, int l, int r,
+ Comparator c) {
+ ...
+ }
+ private static int medChar(int a, int b, int c, String[] arr, int id) {
+ ...
+ }
+ private static int charAt(String str, int i) {
+ ...
+ }
+ private static void copySwap(Object[] src, int from, Object[] dst, int to,
+ int len) {
+ ...
+ }
+ private static void stableStringSort(String[] arr, int start,
+ int end) {
+ ...
+ }
+ private static void stableStringSort(String[] arr, String[] src,
+ String[] dst, int start, int end, int chId) {
+ ...
+ }
+ */
+ // END android-removed
+
/**
* Sorts the specified range in the array using the specified {@code Comparator}.
* All elements must be comparable to each other without a
* {@code ClassCastException} being thrown.
- *
+ *
* @param array
* the {@code Object} array to be sorted.
* @param start
@@ -2458,45 +2468,44 @@
* the last + 1 index to sort.
* @param comparator
* the {@code Comparator}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if elements in the array cannot be compared to each other
* using the {@code Comparator}.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static <T> void sort(T[] array, int start, int end,
Comparator<? super T> comparator) {
+ // BEGIN android-changed
TimSort.sort(array, start, end, comparator);
+ // END android-changed
}
/**
* Sorts the specified array using the specified {@code Comparator}. All elements
* must be comparable to each other without a {@code ClassCastException} being thrown.
- *
+ *
* @param array
* the {@code Object} array to be sorted.
* @param comparator
* the {@code Comparator}.
- * @exception ClassCastException
+ * @throws ClassCastException
* if elements in the array cannot be compared to each other
* using the {@code Comparator}.
- * @since Android 1.0
*/
public static <T> void sort(T[] array, Comparator<? super T> comparator) {
+ // BEGIN android-changed
TimSort.sort(array, comparator);
+ // END android-changed
}
-// END android-changed
-
/**
* Sorts the specified array in ascending numerical order.
- *
+ *
* @param array
* the {@code short} array to be sorted.
- * @since Android 1.0
*/
public static void sort(short[] array) {
sort(0, array.length, array);
@@ -2504,18 +2513,17 @@
/**
* Sorts the specified range in the array in ascending numerical order.
- *
+ *
* @param array
* the {@code short} array to be sorted.
* @param start
* the start index to sort.
* @param end
* the last + 1 index to sort.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code start > end}.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if {@code start < 0} or {@code end > array.length}.
- * @since Android 1.0
*/
public static void sort(short[] array, int start, int end) {
if (array == null) {
@@ -2604,18 +2612,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code boolean[]} passed.
* The result is surrounded by brackets ({@code "[]"}), each
* element is converted to a {@code String} via the
* {@link String#valueOf(boolean)} and separated by {@code ", "}.
* If the array is {@code null}, then {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code boolean} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(boolean[] array) {
if (array == null) {
@@ -2636,18 +2642,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code byte[]} passed. The
* result is surrounded by brackets ({@code "[]"}), each element
* is converted to a {@code String} via the {@link String#valueOf(int)} and
* separated by {@code ", "}. If the array is {@code null}, then
* {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code byte} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(byte[] array) {
if (array == null) {
@@ -2668,18 +2672,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code char[]} passed. The
* result is surrounded by brackets ({@code "[]"}), each element
* is converted to a {@code String} via the {@link String#valueOf(char)} and
* separated by {@code ", "}. If the array is {@code null}, then
* {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code char} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(char[] array) {
if (array == null) {
@@ -2700,18 +2702,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code double[]} passed.
* The result is surrounded by brackets ({@code "[]"}), each
* element is converted to a {@code String} via the
* {@link String#valueOf(double)} and separated by {@code ", "}.
* If the array is {@code null}, then {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code double} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(double[] array) {
if (array == null) {
@@ -2732,18 +2732,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code float[]} passed.
* The result is surrounded by brackets ({@code "[]"}), each
* element is converted to a {@code String} via the
* {@link String#valueOf(float)} and separated by {@code ", "}.
* If the array is {@code null}, then {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code float} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(float[] array) {
if (array == null) {
@@ -2764,18 +2762,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code int[]} passed. The
* result is surrounded by brackets ({@code "[]"}), each element
* is converted to a {@code String} via the {@link String#valueOf(int)} and
* separated by {@code ", "}. If the array is {@code null}, then
* {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code int} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(int[] array) {
if (array == null) {
@@ -2796,18 +2792,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code long[]} passed. The
* result is surrounded by brackets ({@code "[]"}), each element
* is converted to a {@code String} via the {@link String#valueOf(long)} and
* separated by {@code ", "}. If the array is {@code null}, then
* {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code long} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(long[] array) {
if (array == null) {
@@ -2828,18 +2822,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code short[]} passed.
* The result is surrounded by brackets ({@code "[]"}), each
* element is converted to a {@code String} via the
* {@link String#valueOf(int)} and separated by {@code ", "}. If
* the array is {@code null}, then {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code short} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(short[] array) {
if (array == null) {
@@ -2860,18 +2852,16 @@
}
/**
- * <p>
* Creates a {@code String} representation of the {@code Object[]} passed.
* The result is surrounded by brackets ({@code "[]"}), each
* element is converted to a {@code String} via the
* {@link String#valueOf(Object)} and separated by {@code ", "}.
* If the array is {@code null}, then {@code "null"} is returned.
- * </p>
- *
+ *
* @param array
* the {@code Object} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String toString(Object[] array) {
if (array == null) {
@@ -2892,11 +2882,9 @@
}
/**
- * <p>
* Creates a <i>"deep"</i> {@code String} representation of the
* {@code Object[]} passed, such that if the array contains other arrays,
* the {@code String} representation of those arrays is generated as well.
- * </p>
* <p>
* If any of the elements are primitive arrays, the generation is delegated
* to the other {@code toString} methods in this class. If any element
@@ -2904,12 +2892,11 @@
* as {@code "[...]"}. If an element is an {@code Object[]}, then its
* representation is generated by a recursive call to this method. All other
* elements are converted via the {@link String#valueOf(Object)} method.
- * </p>
- *
+ *
* @param array
* the {@code Object} array to convert.
* @return the {@code String} representation of {@code array}.
- * @since Android 1.0
+ * @since 1.5
*/
public static String deepToString(Object[] array) {
// Special case null to prevent NPE
@@ -2923,10 +2910,8 @@
}
/**
- * <p>
* Implementation method used by {@link #deepToString(Object[])}.
- * </p>
- *
+ *
* @param array
* the {@code Object[]} to dive into.
* @param origArrays
@@ -3010,11 +2995,9 @@
}
/**
- * <p>
* Utility method used to assist the implementation of
* {@link #deepToString(Object[])}.
- * </p>
- *
+ *
* @param origArrays
* An array of Object[] references.
* @param array
diff --git a/luni/src/main/java/java/util/BitSet.java b/luni/src/main/java/java/util/BitSet.java
index aa60be0..d2d7c0a 100644
--- a/luni/src/main/java/java/util/BitSet.java
+++ b/luni/src/main/java/java/util/BitSet.java
@@ -17,6 +17,8 @@
package java.util;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.Serializable;
import org.apache.harmony.luni.util.Msg;
@@ -26,20 +28,43 @@
* {@code BitSet} can be on(1) or off(0). A {@code BitSet} is created with a
* given size and grows if this size is exceeded. Growth is always rounded to a
* 64 bit boundary.
- *
- * @since Android 1.0
*/
public class BitSet implements Serializable, Cloneable {
private static final long serialVersionUID = 7997698588986878753L;
- // Size in bits of the data type being used in the bits array
- private static final int ELM_SIZE = 64;
+ private static final int OFFSET = 6;
+
+ private static final int ELM_SIZE = 1 << OFFSET;
+
+ private static final int RIGHT_BITS = ELM_SIZE - 1;
+
+ private static final long[] TWO_N_ARRAY = new long[] { 0x1L, 0x2L, 0x4L,
+ 0x8L, 0x10L, 0x20L, 0x40L, 0x80L, 0x100L, 0x200L, 0x400L, 0x800L,
+ 0x1000L, 0x2000L, 0x4000L, 0x8000L, 0x10000L, 0x20000L, 0x40000L,
+ 0x80000L, 0x100000L, 0x200000L, 0x400000L, 0x800000L, 0x1000000L,
+ 0x2000000L, 0x4000000L, 0x8000000L, 0x10000000L, 0x20000000L,
+ 0x40000000L, 0x80000000L, 0x100000000L, 0x200000000L, 0x400000000L,
+ 0x800000000L, 0x1000000000L, 0x2000000000L, 0x4000000000L,
+ 0x8000000000L, 0x10000000000L, 0x20000000000L, 0x40000000000L,
+ 0x80000000000L, 0x100000000000L, 0x200000000000L, 0x400000000000L,
+ 0x800000000000L, 0x1000000000000L, 0x2000000000000L,
+ 0x4000000000000L, 0x8000000000000L, 0x10000000000000L,
+ 0x20000000000000L, 0x40000000000000L, 0x80000000000000L,
+ 0x100000000000000L, 0x200000000000000L, 0x400000000000000L,
+ 0x800000000000000L, 0x1000000000000000L, 0x2000000000000000L,
+ 0x4000000000000000L, 0x8000000000000000L };
private long[] bits;
+ private transient boolean needClear;
+
+ private transient int actualArrayLength;
+
+ private transient boolean isLengthActual;
+
/**
* Create a new {@code BitSet} with size equal to 64 bits.
- *
+ *
* @see #clear(int)
* @see #set(int)
* @see #clear()
@@ -47,17 +72,18 @@
* @see #set(int, boolean)
* @see #set(int, int)
* @see #set(int, int, boolean)
- * @since Android 1.0
*/
public BitSet() {
- this(64);
+ bits = new long[1];
+ actualArrayLength = 0;
+ isLengthActual = true;
}
/**
* Create a new {@code BitSet} with size equal to nbits. If nbits is not a
* multiple of 64, then create a {@code BitSet} with size nbits rounded to
* the next closest multiple of 64.
- *
+ *
* @param nbits
* the size of the bit set.
* @throws NegativeArraySizeException
@@ -69,31 +95,34 @@
* @see #set(int, boolean)
* @see #set(int, int)
* @see #set(int, int, boolean)
- * @since Android 1.0
*/
public BitSet(int nbits) {
- if (nbits >= 0) {
- bits = new long[(nbits / ELM_SIZE) + (nbits % ELM_SIZE > 0 ? 1 : 0)];
- } else {
+ if (nbits < 0) {
throw new NegativeArraySizeException();
}
+ bits = new long[(nbits >> OFFSET) + ((nbits & RIGHT_BITS) > 0 ? 1 : 0)];
+ actualArrayLength = 0;
+ isLengthActual = true;
}
/**
* Private constructor called from get(int, int) method
- *
+ *
* @param bits
* the size of the bit set
*/
- private BitSet(long[] bits) {
+ private BitSet(long[] bits, boolean needClear, int actualArrayLength,
+ boolean isLengthActual) {
this.bits = bits;
+ this.needClear = needClear;
+ this.actualArrayLength = actualArrayLength;
+ this.isLengthActual = isLengthActual;
}
/**
* Creates a copy of this {@code BitSet}.
- *
+ *
* @return a copy of this {@code BitSet}.
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -110,13 +139,12 @@
* Compares the argument to this {@code BitSet} and returns whether they are
* equal. The object must be an instance of {@code BitSet} with the same
* bits set.
- *
+ *
* @param obj
* the {@code BitSet} object to compare.
* @return a {@code boolean} indicating whether or not this {@code BitSet} and
* {@code obj} are equal.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object obj) {
@@ -125,10 +153,13 @@
}
if (obj instanceof BitSet) {
long[] bsBits = ((BitSet) obj).bits;
- int length1 = bits.length, length2 = bsBits.length;
+ int length1 = this.actualArrayLength, length2 = ((BitSet) obj).actualArrayLength;
+ if (this.isLengthActual && ((BitSet) obj).isLengthActual
+ && length1 != length2) {
+ return false;
+ }
// If one of the BitSets is larger than the other, check to see if
- // any of
- // its extra bits are set. If so return false.
+ // any of its extra bits are set. If so return false.
if (length1 <= length2) {
for (int i = 0; i < length1; i++) {
if (bits[i] != bsBits[i]) {
@@ -160,35 +191,29 @@
/**
* Increase the size of the internal array to accommodate {@code pos} bits.
* The new array max index will be a multiple of 64.
- *
- * @param pos
+ *
+ * @param len
* the index the new array needs to be able to access.
- * @since Android 1.0
*/
- private void growBits(int pos) {
- pos++; // Inc to get correct bit count
- long[] tempBits = new long[(pos / ELM_SIZE)
- + (pos % ELM_SIZE > 0 ? 1 : 0)];
- System.arraycopy(bits, 0, tempBits, 0, bits.length);
+ private final void growLength(int len) {
+ long[] tempBits = new long[Math.max(len, bits.length * 2)];
+ System.arraycopy(bits, 0, tempBits, 0, this.actualArrayLength);
bits = tempBits;
}
/**
* Computes the hash code for this {@code BitSet}. If two {@code BitSet}s are equal
* the have to return the same result for {@code hashCode()}.
- *
+ *
* @return the {@code int} representing the hash code for this bit
* set.
* @see #equals
* @see java.util.Hashtable
- * @since Android 1.0
*/
@Override
public int hashCode() {
long x = 1234;
- // for (int i = 0, length = bits.length; i < length; i+=2)
- // x ^= (bits[i] + ((long)bits[i+1] << 32)) * (i/2 + 1);
- for (int i = 0, length = bits.length; i < length; i++) {
+ for (int i = 0, length = actualArrayLength; i < length; i++) {
x ^= bits[i] * (i + 1);
}
return (int) ((x >> 32) ^ x);
@@ -197,7 +222,7 @@
/**
* Retrieves the bit at index {@code pos}. Grows the {@code BitSet} if
* {@code pos > size}.
- *
+ *
* @param pos
* the index of the bit to be retrieved.
* @return {@code true} if the bit at {@code pos} is set,
@@ -211,89 +236,98 @@
* @see #set(int, boolean)
* @see #set(int, int)
* @see #set(int, int, boolean)
- * @since Android 1.0
*/
public boolean get(int pos) {
- if (pos >= 0) {
- if (pos < bits.length * ELM_SIZE) {
- return (bits[pos / ELM_SIZE] & (1L << (pos % ELM_SIZE))) != 0;
- }
- return false;
+ if (pos < 0) {
+ // Negative index specified
+ throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
}
- // Negative index specified
- throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
+
+ int arrayPos = pos >> OFFSET;
+ if (arrayPos < actualArrayLength) {
+ return (bits[arrayPos] & TWO_N_ARRAY[pos & RIGHT_BITS]) != 0;
+ }
+ return false;
}
/**
* Retrieves the bits starting from {@code pos1} to {@code pos2} and returns
* back a new bitset made of these bits. Grows the {@code BitSet} if
* {@code pos2 > size}.
- *
+ *
* @param pos1
- * beginning position.
+ * inclusive beginning position.
* @param pos2
- * ending position.
+ * exclusive ending position.
* @return new bitset of the range specified.
* @throws IndexOutOfBoundsException
* if {@code pos1} or {@code pos2} is negative, or if
* {@code pos2} is smaller than {@code pos1}.
* @see #get(int)
- * @since Android 1.0
*/
public BitSet get(int pos1, int pos2) {
- if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
- int last = (bits.length * ELM_SIZE);
- if (pos1 >= last || pos1 == pos2) {
+ if (pos1 < 0 || pos2 < 0 || pos2 < pos1) {
+ throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
+ }
+
+ int last = actualArrayLength << OFFSET;
+ if (pos1 >= last || pos1 == pos2) {
+ return new BitSet(0);
+ }
+ if (pos2 > last) {
+ pos2 = last;
+ }
+
+ int idx1 = pos1 >> OFFSET;
+ int idx2 = (pos2 - 1) >> OFFSET;
+ long factor1 = (~0L) << (pos1 & RIGHT_BITS);
+ long factor2 = (~0L) >>> (ELM_SIZE - (pos2 & RIGHT_BITS));
+
+ if (idx1 == idx2) {
+ long result = (bits[idx1] & (factor1 & factor2)) >>> (pos1 % ELM_SIZE);
+ if (result == 0) {
return new BitSet(0);
}
- if (pos2 > last) {
- pos2 = last;
- }
+ return new BitSet(new long[] { result }, needClear, 1, true);
+ }
+ long[] newbits = new long[idx2 - idx1 + 1];
+ // first fill in the first and last indexes in the new bitset
+ newbits[0] = bits[idx1] & factor1;
+ newbits[newbits.length - 1] = bits[idx2] & factor2;
- int idx1 = pos1 / ELM_SIZE;
- int idx2 = (pos2 - 1) / ELM_SIZE;
- long factor1 = (~0L) << (pos1 % ELM_SIZE);
- long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));
+ // fill in the in between elements of the new bitset
+ for (int i = 1; i < idx2 - idx1; i++) {
+ newbits[i] = bits[idx1 + i];
+ }
- if (idx1 == idx2) {
- long result = (bits[idx1] & (factor1 & factor2)) >>> (pos1 % ELM_SIZE);
- return new BitSet(new long[] { result });
- }
- long[] newbits = new long[idx2 - idx1 + 1];
- // first fill in the first and last indexes in the new bitset
- newbits[0] = bits[idx1] & factor1;
- newbits[newbits.length - 1] = bits[idx2] & factor2;
+ // shift all the elements in the new bitset to the right by pos1
+ // % ELM_SIZE
+ int numBitsToShift = pos1 & RIGHT_BITS;
+ int actualLen = newbits.length;
+ if (numBitsToShift != 0) {
+ for (int i = 0; i < newbits.length; i++) {
+ // shift the current element to the right regardless of
+ // sign
+ newbits[i] = newbits[i] >>> (numBitsToShift);
- // fill in the in between elements of the new bitset
- for (int i = 1; i < idx2 - idx1; i++) {
- newbits[i] = bits[idx1 + i];
- }
-
- // shift all the elements in the new bitset to the right by pos1
- // % ELM_SIZE
- int numBitsToShift = pos1 % ELM_SIZE;
- if (numBitsToShift != 0) {
- for (int i = 0; i < newbits.length; i++) {
- // shift the current element to the right regardless of
- // sign
- newbits[i] = newbits[i] >>> (numBitsToShift);
-
- // apply the last x bits of newbits[i+1] to the current
- // element
- if (i != newbits.length - 1) {
- newbits[i] |= newbits[i + 1] << (ELM_SIZE - (numBitsToShift));
- }
+ // apply the last x bits of newbits[i+1] to the current
+ // element
+ if (i != newbits.length - 1) {
+ newbits[i] |= newbits[i + 1] << (ELM_SIZE - (numBitsToShift));
+ }
+ if (newbits[i] != 0) {
+ actualLen = i + 1;
}
}
- return new BitSet(newbits);
}
- throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
+ return new BitSet(newbits, needClear, actualLen,
+ newbits[actualLen - 1] != 0);
}
/**
* Sets the bit at index {@code pos} to 1. Grows the {@code BitSet} if
* {@code pos > size}.
- *
+ *
* @param pos
* the index of the bit to set.
* @throws IndexOutOfBoundsException
@@ -301,23 +335,28 @@
* @see #clear(int)
* @see #clear()
* @see #clear(int, int)
- * @since Android 1.0
*/
public void set(int pos) {
- if (pos >= 0) {
- if (pos >= bits.length * ELM_SIZE) {
- growBits(pos);
- }
- bits[pos / ELM_SIZE] |= 1L << (pos % ELM_SIZE);
- } else {
+ if (pos < 0) {
throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
}
+
+ int len = (pos >> OFFSET) + 1;
+ if (len > bits.length) {
+ growLength(len);
+ }
+ bits[len - 1] |= TWO_N_ARRAY[pos & RIGHT_BITS];
+ if (len > actualArrayLength) {
+ actualArrayLength = len;
+ isLengthActual = true;
+ }
+ needClear();
}
/**
* Sets the bit at index {@code pos} to {@code val}. Grows the
* {@code BitSet} if {@code pos > size}.
- *
+ *
* @param pos
* the index of the bit to set.
* @param val
@@ -325,7 +364,6 @@
* @throws IndexOutOfBoundsException
* if {@code pos} is negative.
* @see #set(int)
- * @since Android 1.0
*/
public void set(int pos, boolean val) {
if (val) {
@@ -338,60 +376,68 @@
/**
* Sets the bits starting from {@code pos1} to {@code pos2}. Grows the
* {@code BitSet} if {@code pos2 > size}.
- *
+ *
* @param pos1
- * beginning position.
+ * inclusive beginning position.
* @param pos2
- * ending position.
+ * exclusive ending position.
* @throws IndexOutOfBoundsException
* if {@code pos1} or {@code pos2} is negative, or if
* {@code pos2} is smaller than {@code pos1}.
* @see #set(int)
- * @since Android 1.0
*/
public void set(int pos1, int pos2) {
- if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
- if (pos1 == pos2) {
- return;
- }
- if (pos2 >= bits.length * ELM_SIZE) {
- growBits(pos2);
- }
-
- int idx1 = pos1 / ELM_SIZE;
- int idx2 = (pos2 - 1) / ELM_SIZE;
- long factor1 = (~0L) << (pos1 % ELM_SIZE);
- long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));
-
- if (idx1 == idx2) {
- bits[idx1] |= (factor1 & factor2);
- } else {
- bits[idx1] |= factor1;
- bits[idx2] |= factor2;
- for (int i = idx1 + 1; i < idx2; i++) {
- bits[i] |= (~0L);
- }
- }
- } else {
+ if (pos1 < 0 || pos2 < 0 || pos2 < pos1) {
throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
}
+
+ if (pos1 == pos2) {
+ return;
+ }
+ int len2 = ((pos2 - 1) >> OFFSET) + 1;
+ if (len2 > bits.length) {
+ growLength(len2);
+ }
+
+ int idx1 = pos1 >> OFFSET;
+ int idx2 = (pos2 - 1) >> OFFSET;
+ long factor1 = (~0L) << (pos1 & RIGHT_BITS);
+ long factor2 = (~0L) >>> (ELM_SIZE - (pos2 & RIGHT_BITS));
+
+ if (idx1 == idx2) {
+ bits[idx1] |= (factor1 & factor2);
+ } else {
+ bits[idx1] |= factor1;
+ bits[idx2] |= factor2;
+ for (int i = idx1 + 1; i < idx2; i++) {
+ bits[i] |= (~0L);
+ }
+ }
+ if (idx2 + 1 > actualArrayLength) {
+ actualArrayLength = idx2 + 1;
+ isLengthActual = true;
+ }
+ needClear();
+ }
+
+ private void needClear() {
+ this.needClear = true;
}
/**
* Sets the bits starting from {@code pos1} to {@code pos2} to the given
* {@code val}. Grows the {@code BitSet} if {@code pos2 > size}.
- *
+ *
* @param pos1
- * beginning position.
+ * inclusive beginning position.
* @param pos2
- * ending position.
+ * exclusive ending position.
* @param val
* value to set these bits.
* @throws IndexOutOfBoundsException
* if {@code pos1} or {@code pos2} is negative, or if
* {@code pos2} is smaller than {@code pos1}.
* @see #set(int,int)
- * @since Android 1.0
*/
public void set(int pos1, int pos2, boolean val) {
if (val) {
@@ -403,159 +449,183 @@
/**
* Clears all the bits in this {@code BitSet}.
- *
+ *
* @see #clear(int)
* @see #clear(int, int)
- * @since Android 1.0
*/
public void clear() {
- for (int i = 0; i < bits.length; i++) {
- bits[i] = 0L;
+ if (needClear) {
+ for (int i = 0; i < bits.length; i++) {
+ bits[i] = 0L;
+ }
+ actualArrayLength = 0;
+ isLengthActual = true;
+ needClear = false;
}
}
/**
* Clears the bit at index {@code pos}. Grows the {@code BitSet} if
* {@code pos > size}.
- *
+ *
* @param pos
* the index of the bit to clear.
* @throws IndexOutOfBoundsException
* if {@code pos} is negative.
* @see #clear(int, int)
- * @since Android 1.0
*/
public void clear(int pos) {
- if (pos >= 0) {
- if (pos < bits.length * ELM_SIZE) {
- bits[pos / ELM_SIZE] &= ~(1L << (pos % ELM_SIZE));
- }
- } else {
+ if (pos < 0) {
// Negative index specified
throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
}
+
+ if (!needClear) {
+ return;
+ }
+ int arrayPos = pos >> OFFSET;
+ if (arrayPos < actualArrayLength) {
+ bits[arrayPos] &= ~(TWO_N_ARRAY[pos & RIGHT_BITS]);
+ if (bits[actualArrayLength - 1] == 0) {
+ isLengthActual = false;
+ }
+ }
}
/**
* Clears the bits starting from {@code pos1} to {@code pos2}. Grows the
* {@code BitSet} if {@code pos2 > size}.
- *
+ *
* @param pos1
- * beginning position.
+ * inclusive beginning position.
* @param pos2
- * ending position.
+ * exclusive ending position.
* @throws IndexOutOfBoundsException
* if {@code pos1} or {@code pos2} is negative, or if
* {@code pos2} is smaller than {@code pos1}.
* @see #clear(int)
- * @since Android 1.0
*/
public void clear(int pos1, int pos2) {
- if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
- int last = (bits.length * ELM_SIZE);
- if (pos1 >= last || pos1 == pos2) {
- return;
- }
- if (pos2 > last) {
- pos2 = last;
- }
-
- int idx1 = pos1 / ELM_SIZE;
- int idx2 = (pos2 - 1) / ELM_SIZE;
- long factor1 = (~0L) << (pos1 % ELM_SIZE);
- long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));
-
- if (idx1 == idx2) {
- bits[idx1] &= ~(factor1 & factor2);
- } else {
- bits[idx1] &= ~factor1;
- bits[idx2] &= ~factor2;
- for (int i = idx1 + 1; i < idx2; i++) {
- bits[i] = 0L;
- }
- }
- } else {
+ if (pos1 < 0 || pos2 < 0 || pos2 < pos1) {
throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
}
+
+ if (!needClear) {
+ return;
+ }
+ int last = (actualArrayLength << OFFSET);
+ if (pos1 >= last || pos1 == pos2) {
+ return;
+ }
+ if (pos2 > last) {
+ pos2 = last;
+ }
+
+ int idx1 = pos1 >> OFFSET;
+ int idx2 = (pos2 - 1) >> OFFSET;
+ long factor1 = (~0L) << (pos1 & RIGHT_BITS);
+ long factor2 = (~0L) >>> (ELM_SIZE - (pos2 & RIGHT_BITS));
+
+ if (idx1 == idx2) {
+ bits[idx1] &= ~(factor1 & factor2);
+ } else {
+ bits[idx1] &= ~factor1;
+ bits[idx2] &= ~factor2;
+ for (int i = idx1 + 1; i < idx2; i++) {
+ bits[i] = 0L;
+ }
+ }
+ if ((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0)) {
+ isLengthActual = false;
+ }
}
/**
* Flips the bit at index {@code pos}. Grows the {@code BitSet} if
* {@code pos > size}.
- *
+ *
* @param pos
* the index of the bit to flip.
* @throws IndexOutOfBoundsException
* if {@code pos} is negative.
* @see #flip(int, int)
- * @since Android 1.0
*/
public void flip(int pos) {
- if (pos >= 0) {
- if (pos >= bits.length * ELM_SIZE) {
- growBits(pos);
- }
- bits[pos / ELM_SIZE] ^= 1L << (pos % ELM_SIZE);
- } else {
+ if (pos < 0) {
throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
}
+
+ int len = (pos >> OFFSET) + 1;
+ if (len > bits.length) {
+ growLength(len);
+ }
+ bits[len - 1] ^= TWO_N_ARRAY[pos & RIGHT_BITS];
+ if (len > actualArrayLength) {
+ actualArrayLength = len;
+ }
+ isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
+ needClear();
}
/**
* Flips the bits starting from {@code pos1} to {@code pos2}. Grows the
* {@code BitSet} if {@code pos2 > size}.
- *
+ *
* @param pos1
- * beginning position.
+ * inclusive beginning position.
* @param pos2
- * ending position.
+ * exclusive ending position.
* @throws IndexOutOfBoundsException
* if {@code pos1} or {@code pos2} is negative, or if
* {@code pos2} is smaller than {@code pos1}.
* @see #flip(int)
- * @since Android 1.0
*/
public void flip(int pos1, int pos2) {
- if (pos1 >= 0 && pos2 >= 0 && pos2 >= pos1) {
- if (pos1 == pos2) {
- return;
- }
- if (pos2 >= bits.length * ELM_SIZE) {
- growBits(pos2);
- }
-
- int idx1 = pos1 / ELM_SIZE;
- int idx2 = (pos2 - 1) / ELM_SIZE;
- long factor1 = (~0L) << (pos1 % ELM_SIZE);
- long factor2 = (~0L) >>> (ELM_SIZE - (pos2 % ELM_SIZE));
-
- if (idx1 == idx2) {
- bits[idx1] ^= (factor1 & factor2);
- } else {
- bits[idx1] ^= factor1;
- bits[idx2] ^= factor2;
- for (int i = idx1 + 1; i < idx2; i++) {
- bits[i] ^= (~0L);
- }
- }
- } else {
+ if (pos1 < 0 || pos2 < 0 || pos2 < pos1) {
throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
}
+
+ if (pos1 == pos2) {
+ return;
+ }
+ int len2 = ((pos2 - 1) >> OFFSET) + 1;
+ if (len2 > bits.length) {
+ growLength(len2);
+ }
+
+ int idx1 = pos1 >> OFFSET;
+ int idx2 = (pos2 - 1) >> OFFSET;
+ long factor1 = (~0L) << (pos1 & RIGHT_BITS);
+ long factor2 = (~0L) >>> (ELM_SIZE - (pos2 & RIGHT_BITS));
+
+ if (idx1 == idx2) {
+ bits[idx1] ^= (factor1 & factor2);
+ } else {
+ bits[idx1] ^= factor1;
+ bits[idx2] ^= factor2;
+ for (int i = idx1 + 1; i < idx2; i++) {
+ bits[i] ^= (~0L);
+ }
+ }
+ if (len2 > actualArrayLength) {
+ actualArrayLength = len2;
+ }
+ isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
+ needClear();
}
/**
* Checks if these two {@code BitSet}s have at least one bit set to true in the same
* position.
- *
+ *
* @param bs
* {@code BitSet} used to calculate the intersection.
* @return {@code true} if bs intersects with this {@code BitSet},
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean intersects(BitSet bs) {
long[] bsBits = bs.bits;
- int length1 = bits.length, length2 = bsBits.length;
+ int length1 = actualArrayLength, length2 = bs.actualArrayLength;
if (length1 <= length2) {
for (int i = 0; i < length1; i++) {
@@ -575,19 +645,20 @@
}
/**
- * Performs the logical AND of this {@code BitSet} with another
+ * Performs the logical AND of this {@code BitSet} with another
* {@code BitSet}. The values of this {@code BitSet} are changed accordingly.
- *
+ *
* @param bs
* {@code BitSet} to AND with.
* @see #or
* @see #xor
- * @since Android 1.0
*/
-
public void and(BitSet bs) {
long[] bsBits = bs.bits;
- int length1 = bits.length, length2 = bsBits.length;
+ if (!needClear) {
+ return;
+ }
+ int length1 = actualArrayLength, length2 = bs.actualArrayLength;
if (length1 <= length2) {
for (int i = 0; i < length1; i++) {
bits[i] &= bsBits[i];
@@ -599,109 +670,151 @@
for (int i = length2; i < length1; i++) {
bits[i] = 0;
}
+ actualArrayLength = length2;
}
+ isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
}
/**
* Clears all bits in the receiver which are also set in the parameter
* {@code BitSet}. The values of this {@code BitSet} are changed accordingly.
- *
+ *
* @param bs
* {@code BitSet} to ANDNOT with.
- * @since Android 1.0
*/
public void andNot(BitSet bs) {
long[] bsBits = bs.bits;
- int range = bits.length < bsBits.length ? bits.length : bsBits.length;
+ if (!needClear) {
+ return;
+ }
+ int range = actualArrayLength < bs.actualArrayLength ? actualArrayLength
+ : bs.actualArrayLength;
for (int i = 0; i < range; i++) {
bits[i] &= ~bsBits[i];
}
+
+ if (actualArrayLength < range) {
+ actualArrayLength = range;
+ }
+ isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
}
/**
* Performs the logical OR of this {@code BitSet} with another {@code BitSet}.
* The values of this {@code BitSet} are changed accordingly.
- *
+ *
* @param bs
* {@code BitSet} to OR with.
* @see #xor
* @see #and
- * @since Android 1.0
*/
public void or(BitSet bs) {
- int nbits = bs.length();
- int length = nbits / ELM_SIZE + (nbits % ELM_SIZE > 0 ? 1 : 0);
- if (length > bits.length) {
- growBits(nbits - 1);
+ int bsActualLen = bs.getActualArrayLength();
+ if (bsActualLen > bits.length) {
+ long[] tempBits = new long[bsActualLen];
+ System.arraycopy(bs.bits, 0, tempBits, 0, bs.actualArrayLength);
+ for (int i = 0; i < actualArrayLength; i++) {
+ tempBits[i] |= bits[i];
+ }
+ bits = tempBits;
+ actualArrayLength = bsActualLen;
+ isLengthActual = true;
+ } else {
+ long[] bsBits = bs.bits;
+ for (int i = 0; i < bsActualLen; i++) {
+ bits[i] |= bsBits[i];
+ }
+ if (bsActualLen > actualArrayLength) {
+ actualArrayLength = bsActualLen;
+ isLengthActual = true;
+ }
}
- long[] bsBits = bs.bits;
- for (int i = 0; i < length; i++) {
- bits[i] |= bsBits[i];
- }
+ needClear();
}
/**
* Performs the logical XOR of this {@code BitSet} with another {@code BitSet}.
* The values of this {@code BitSet} are changed accordingly.
- *
+ *
* @param bs
* {@code BitSet} to XOR with.
* @see #or
* @see #and
- * @since Android 1.0
*/
public void xor(BitSet bs) {
- int nbits = bs.length();
- int length = nbits / ELM_SIZE + (nbits % ELM_SIZE > 0 ? 1 : 0);
- if (length > bits.length) {
- growBits(nbits - 1);
+ int bsActualLen = bs.getActualArrayLength();
+ if (bsActualLen > bits.length) {
+ long[] tempBits = new long[bsActualLen];
+ System.arraycopy(bs.bits, 0, tempBits, 0, bs.actualArrayLength);
+ for (int i = 0; i < actualArrayLength; i++) {
+ tempBits[i] ^= bits[i];
+ }
+ bits = tempBits;
+ actualArrayLength = bsActualLen;
+ isLengthActual = !((actualArrayLength > 0) && (bits[actualArrayLength - 1] == 0));
+ } else {
+ long[] bsBits = bs.bits;
+ for (int i = 0; i < bsActualLen; i++) {
+ bits[i] ^= bsBits[i];
+ }
+ if (bsActualLen > actualArrayLength) {
+ actualArrayLength = bsActualLen;
+ isLengthActual = true;
+ }
}
- long[] bsBits = bs.bits;
- for (int i = 0; i < length; i++) {
- bits[i] ^= bsBits[i];
- }
-
+ needClear();
}
/**
* Returns the number of bits this {@code BitSet} has.
- *
+ *
* @return the number of bits contained in this {@code BitSet}.
* @see #length
- * @since Android 1.0
*/
public int size() {
- return bits.length * ELM_SIZE;
+ return bits.length << OFFSET;
}
/**
* Returns the number of bits up to and including the highest bit set.
- *
+ *
* @return the length of the {@code BitSet}.
- * @since Android 1.0
*/
public int length() {
- int idx = bits.length - 1;
+ int idx = actualArrayLength - 1;
while (idx >= 0 && bits[idx] == 0) {
--idx;
}
+ actualArrayLength = idx + 1;
if (idx == -1) {
return 0;
}
int i = ELM_SIZE - 1;
long val = bits[idx];
- while ((val & (1L << i)) == 0 && i > 0) {
+ while ((val & (TWO_N_ARRAY[i])) == 0 && i > 0) {
i--;
}
- return idx * ELM_SIZE + i + 1;
+ return (idx << OFFSET) + i + 1;
+ }
+
+ private final int getActualArrayLength() {
+ if (isLengthActual) {
+ return actualArrayLength;
+ }
+ int idx = actualArrayLength - 1;
+ while (idx >= 0 && bits[idx] == 0) {
+ --idx;
+ }
+ actualArrayLength = idx + 1;
+ isLengthActual = true;
+ return actualArrayLength;
}
/**
* Returns a string containing a concise, human-readable description of the
* receiver.
- *
+ *
* @return a comma delimited list of the indices of all bits that are set.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -715,7 +828,7 @@
continue;
}
for (int j = 0; j < ELM_SIZE; j++) {
- if (((bits[i] & (1L << j)) != 0)) {
+ if (((bits[i] & (TWO_N_ARRAY[j])) != 0)) {
if (comma) {
sb.append(", "); //$NON-NLS-1$
}
@@ -731,131 +844,152 @@
/**
* Returns the position of the first bit that is {@code true} on or after {@code pos}.
- *
+ *
* @param pos
* the starting position (inclusive).
* @return -1 if there is no bits that are set to {@code true} on or after {@code pos}.
- * @since Android 1.0
*/
public int nextSetBit(int pos) {
- if (pos >= 0) {
- if (pos >= bits.length * ELM_SIZE) {
- return -1;
- }
+ if (pos < 0) {
+ throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
+ }
- int idx = pos / ELM_SIZE;
- // first check in the same bit set element
- if (bits[idx] != 0L) {
- for (int j = pos % ELM_SIZE; j < ELM_SIZE; j++) {
- if (((bits[idx] & (1L << j)) != 0)) {
- return idx * ELM_SIZE + j;
- }
- }
-
- }
- idx++;
- while (idx < bits.length && bits[idx] == 0L) {
- idx++;
- }
- if (idx == bits.length) {
- return -1;
- }
-
- // we know for sure there is a bit set to true in this element
- // since the bitset value is not 0L
- for (int j = 0; j < ELM_SIZE; j++) {
- if (((bits[idx] & (1L << j)) != 0)) {
- return idx * ELM_SIZE + j;
- }
- }
-
+ if (pos >= actualArrayLength << OFFSET) {
return -1;
}
- throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
+
+ int idx = pos >> OFFSET;
+ // first check in the same bit set element
+ if (bits[idx] != 0L) {
+ for (int j = pos & RIGHT_BITS; j < ELM_SIZE; j++) {
+ if (((bits[idx] & (TWO_N_ARRAY[j])) != 0)) {
+ return (idx << OFFSET) + j;
+ }
+ }
+
+ }
+ idx++;
+ while (idx < actualArrayLength && bits[idx] == 0L) {
+ idx++;
+ }
+ if (idx == actualArrayLength) {
+ return -1;
+ }
+
+ // we know for sure there is a bit set to true in this element
+ // since the bitset value is not 0L
+ for (int j = 0; j < ELM_SIZE; j++) {
+ if (((bits[idx] & (TWO_N_ARRAY[j])) != 0)) {
+ return (idx << OFFSET) + j;
+ }
+ }
+
+ return -1;
}
/**
* Returns the position of the first bit that is {@code false} on or after {@code pos}.
- *
+ *
* @param pos
* the starting position (inclusive).
* @return the position of the next bit set to {@code false}, even if it is further
* than this {@code BitSet}'s size.
- * @since Android 1.0
*/
public int nextClearBit(int pos) {
- if (pos >= 0) {
- int bssize = bits.length * ELM_SIZE;
- if (pos >= bssize) {
- return pos;
- }
+ if (pos < 0) {
+ throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
+ }
- int idx = pos / ELM_SIZE;
- // first check in the same bit set element
- if (bits[idx] != (~0L)) {
- for (int j = pos % ELM_SIZE; j < ELM_SIZE; j++) {
- if (((bits[idx] & (1L << j)) == 0)) {
- return idx * ELM_SIZE + j;
- }
- }
+ int length = actualArrayLength;
+ int bssize = length << OFFSET;
+ if (pos >= bssize) {
+ return pos;
+ }
- }
- idx++;
- while (idx < bits.length && bits[idx] == (~0L)) {
- idx++;
- }
- if (idx == bits.length) {
- return bssize;
- }
-
- // we know for sure there is a bit set to true in this element
- // since the bitset value is not 0L
- for (int j = 0; j < ELM_SIZE; j++) {
- if (((bits[idx] & (1L << j)) == 0)) {
+ int idx = pos >> OFFSET;
+ // first check in the same bit set element
+ if (bits[idx] != (~0L)) {
+ for (int j = pos % ELM_SIZE; j < ELM_SIZE; j++) {
+ if (((bits[idx] & (TWO_N_ARRAY[j])) == 0)) {
return idx * ELM_SIZE + j;
}
}
-
+ }
+ idx++;
+ while (idx < length && bits[idx] == (~0L)) {
+ idx++;
+ }
+ if (idx == length) {
return bssize;
}
- throw new IndexOutOfBoundsException(Msg.getString("K0006")); //$NON-NLS-1$
+
+ // we know for sure there is a bit set to true in this element
+ // since the bitset value is not 0L
+ for (int j = 0; j < ELM_SIZE; j++) {
+ if (((bits[idx] & (TWO_N_ARRAY[j])) == 0)) {
+ return (idx << OFFSET) + j;
+ }
+ }
+
+ return bssize;
}
/**
* Returns true if all the bits in this {@code BitSet} are set to false.
- *
+ *
* @return {@code true} if the {@code BitSet} is empty,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isEmpty() {
- for (int idx = 0; idx < bits.length; idx++) {
+ if (!needClear) {
+ return true;
+ }
+ int length = bits.length;
+ for (int idx = 0; idx < length; idx++) {
if (bits[idx] != 0L) {
return false;
}
}
-
return true;
}
/**
* Returns the number of bits that are {@code true} in this {@code BitSet}.
- *
+ *
* @return the number of {@code true} bits in the set.
- * @since Android 1.0
*/
public int cardinality() {
+ if (!needClear) {
+ return 0;
+ }
int count = 0;
- for (int idx = 0; idx < bits.length; idx++) {
- long temp = bits[idx];
- if (temp != 0L) {
- for (int i = 0; i < ELM_SIZE; i++) {
- if ((temp & (1L << i)) != 0L) {
- count++;
- }
- }
- }
+ int length = bits.length;
+ // FIXME: need to test performance, if still not satisfied, change it to
+ // 256-bits table based
+ for (int idx = 0; idx < length; idx++) {
+ count += pop(bits[idx] & 0xffffffffL);
+ count += pop(bits[idx] >>> 32);
}
return count;
}
+
+ private final int pop(long x) {
+ // BEGIN android-note
+ // delegate to Integer.bitCount(i); consider using native code
+ // END android-note
+ x = x - ((x >>> 1) & 0x55555555);
+ x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
+ x = (x + (x >>> 4)) & 0x0f0f0f0f;
+ x = x + (x >>> 8);
+ x = x + (x >>> 16);
+ return (int) x & 0x0000003f;
+ }
+
+ private void readObject(ObjectInputStream ois) throws IOException,
+ ClassNotFoundException {
+ ois.defaultReadObject();
+ this.isLengthActual = false;
+ this.actualArrayLength = bits.length;
+ this.needClear = this.getActualArrayLength() != 0;
+ }
}
diff --git a/luni/src/main/java/java/util/Calendar.java b/luni/src/main/java/java/util/Calendar.java
index 98840b2..088347d 100644
--- a/luni/src/main/java/java/util/Calendar.java
+++ b/luni/src/main/java/java/util/Calendar.java
@@ -14,27 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
-*******************************************************************************
-* Copyright (C) 1996-2008, International Business Machines Corporation and *
-* others. All Rights Reserved. *
-*******************************************************************************
-*/
package java.util;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.io.Serializable;
-// BEGIN android-note
-// The class javadoc and some of the method descriptions are copied from ICU4J
-// source files. Changes have been made to the copied descriptions.
-// The icu license header was added to this file.
-// END android-note
/**
* {@code Calendar} is an abstract base class for converting between a
* {@code Date} object and a set of integer fields such as
@@ -42,22 +30,22 @@
* {@code HOUR}, and so on. (A {@code Date} object represents a
* specific instant in time with millisecond precision. See {@link Date} for
* information about the {@code Date} class.)
- *
+ *
* <p>
* Subclasses of {@code Calendar} interpret a {@code Date}
* according to the rules of a specific calendar system.
- *
+ *
* <p>
* Like other locale-sensitive classes, {@code Calendar} provides a class
* method, {@code getInstance}, for getting a default instance of
* this class for general use. {@code Calendar}'s {@code getInstance} method
* returns a calendar whose locale is based on system settings and whose time fields
* have been initialized with the current date and time: <blockquote>
- *
+ *
* <pre>Calendar rightNow = Calendar.getInstance()</pre>
- *
+ *
* </blockquote>
- *
+ *
* <p>
* A {@code Calendar} object can produce all the time field values needed
* to implement the date-time formatting for a particular language and calendar
@@ -68,7 +56,7 @@
* Other values are defined by the concrete subclass, such as {@code ERA}
* and {@code YEAR}. See individual field documentation and subclass
* documentation for details.
- *
+ *
* <p>
* When a {@code Calendar} is <em>lenient</em>, it accepts a wider
* range of field values than it produces. For example, a lenient
@@ -79,14 +67,14 @@
* by {@code get()}, they normalize them. For example, a
* {@code GregorianCalendar} always produces {@code DAY_OF_MONTH}
* values between 1 and the length of the month.
- *
+ *
* <p>
* {@code Calendar} defines a locale-specific seven day week using two
* parameters: the first day of the week and the minimal days in first week
* (from 1 to 7). These numbers are taken from the locale resource data when a
* {@code Calendar} is constructed. They may also be specified explicitly
* through the API.
- *
+ *
* <p>
* When setting or getting the {@code WEEK_OF_MONTH} or
* {@code WEEK_OF_YEAR} fields, {@code Calendar} must determine
@@ -99,76 +87,74 @@
* be different. For example, a specific {@code Calendar} subclass may
* designate the week before week 1 of a year as week <em>n</em> of the
* previous year.
- *
+ *
* <p>
* When computing a {@code Date} from time fields, two special
* circumstances may arise: there may be insufficient information to compute the
* {@code Date} (such as only year and month but no day in the month), or
* there may be inconsistent information (such as "Tuesday, July 15, 1996" --
* July 15, 1996 is actually a Monday).
- *
+ *
* <p>
* <strong>Insufficient information.</strong> The calendar will use default
* information to specify the missing fields. This may vary by calendar; for the
* Gregorian calendar, the default for a field is the same as that of the start
* of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
- *
+ *
* <p>
* <strong>Inconsistent information.</strong> If fields conflict, the calendar
* will give preference to fields set more recently. For example, when
* determining the day, the calendar will look for one of the following
* combinations of fields. The most recent combination, as determined by the
* most recently set single field, will be used.
- *
+ *
* <blockquote>
- *
+ *
* <pre>
* MONTH + DAY_OF_MONTH
* MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
* MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
* DAY_OF_YEAR
* DAY_OF_WEEK + WEEK_OF_YEAR</pre>
- *
+ *
* </blockquote>
- *
+ *
* For the time of day:
- *
+ *
* <blockquote>
- *
+ *
* <pre>
* HOUR_OF_DAY
* AM_PM + HOUR</pre>
- *
+ *
* </blockquote>
- *
+ *
* <p>
* <strong>Note:</strong> There are certain possible ambiguities in
* interpretation of certain singular times, which are resolved in the following
* ways:
* <ol>
* <li> 24:00:00 "belongs" to the following day. That is, 23:59 on Dec 31, 1969
- * < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 form a sequence of
- * three consecutive minutes in time.
- *
+ * < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 form a sequence of
+ * three consecutive minutes in time.
+ *
* <li> Although historically not precise, midnight also belongs to "am", and
* noon belongs to "pm", so on the same day, we have 12:00 am (midnight) < 12:01 am,
* and 12:00 pm (noon) < 12:01 pm
* </ol>
- *
+ *
* <p>
* The date or time format strings are not part of the definition of a calendar,
* as those must be modifiable or overridable by the user at runtime. Use
* {@link java.text.DateFormat} to format dates.
- *
+ *
* <p>
* <strong>Field manipulation methods</strong>
- * </p>
- *
+ *
* <p>
* {@code Calendar} fields can be changed using three methods:
* {@code set()}, {@code add()}, and {@code roll()}.
- * </p>
- *
+ *
* <p>
* <strong>{@code set(f, value)}</strong> changes field {@code f}
* to {@code value}. In addition, it sets an internal member variable to
@@ -182,8 +168,7 @@
* the calendar system. In addition, {@code get(f)} will not necessarily
* return {@code value} after the fields have been recomputed. The
* specifics are determined by the concrete calendar class.
- * </p>
- *
+ *
* <p>
* <em>Example</em>: Consider a {@code GregorianCalendar} originally
* set to August 31, 1999. Calling <code>set(Calendar.MONTH,
@@ -193,15 +178,13 @@
* then called. However, a call to {@code set(Calendar.DAY_OF_MONTH, 30)}
* before the call to {@code getTime()} sets the calendar to September
* 30, 1999, since no recomputation occurs after {@code set()} itself.
- * </p>
- *
+ *
* <p>
* <strong>{@code add(f, delta)}</strong> adds {@code delta} to
* field {@code f}. This is equivalent to calling <code>set(f,
* get(f) + delta)</code>
* with two adjustments:
- * </p>
- *
+ *
* <blockquote>
* <p>
* <strong>Add rule 1</strong>. The value of field {@code f} after the
@@ -210,8 +193,7 @@
* {@code f}. Overflow occurs when a field value exceeds its range and,
* as a result, the next larger field is incremented or decremented and the
* field value is adjusted back into its range.
- * </p>
- *
+ *
* <p>
* <strong>Add rule 2</strong>. If a smaller field is expected to be invariant,
* but it is impossible for it to be equal to its prior value because of
@@ -221,14 +203,12 @@
* smaller field than {@code DAY_OF_MONTH}. No adjustment is made to
* smaller fields that are not expected to be invariant. The calendar system
* determines what fields are expected to be invariant.
- * </p>
* </blockquote>
- *
+ *
* <p>
* In addition, unlike {@code set()}, {@code add()} forces an
* immediate recomputation of the calendar's milliseconds and all fields.
- * </p>
- *
+ *
* <p>
* <em>Example</em>: Consider a {@code GregorianCalendar} originally
* set to August 31, 1999. Calling {@code add(Calendar.MONTH, 13)} sets
@@ -240,22 +220,19 @@
* Although it is a smaller field, {@code DAY_OF_WEEK} is not adjusted by
* rule 2, since it is expected to change when the month changes in a
* {@code GregorianCalendar}.
- * </p>
- *
+ *
* <p>
* <strong>{@code roll(f, delta)}</strong> adds {@code delta} to
* field {@code f} without changing larger fields. This is equivalent to
* calling {@code add(f, delta)} with the following adjustment:
- * </p>
- *
+ *
* <blockquote>
* <p>
* <strong>Roll rule</strong>. Larger fields are unchanged after the call. A
* larger field represents a larger unit of time. {@code DAY_OF_MONTH} is
* a larger field than {@code HOUR}.
- * </p>
* </blockquote>
- *
+ *
* <p>
* <em>Example</em>: Consider a {@code GregorianCalendar} originally
* set to August 31, 1999. Calling <code>roll(Calendar.MONTH,
@@ -265,8 +242,7 @@
* the {@code DAY_OF_MONTH} cannot be 31 in the month April. Add rule 2
* sets it to the closest possible value, 30. Finally, the <strong>roll rule</strong>
* maintains the {@code YEAR} field value of 1999.
- * </p>
- *
+ *
* <p>
* <em>Example</em>: Consider a {@code GregorianCalendar} originally
* set to Sunday June 6, 1999. Calling
@@ -279,8 +255,7 @@
* According to add rule 2, the {@code DAY_OF_WEEK}, an invariant when
* changing the {@code WEEK_OF_MONTH}, is set to Tuesday, the closest
* possible value to Sunday (where Sunday is the first day of the week).
- * </p>
- *
+ *
* <p>
* <strong>Usage model</strong>. To motivate the behavior of {@code add()}
* and {@code roll()}, consider a user interface component with
@@ -294,8 +269,7 @@
* {@code add()} or {@code roll()}, depending on whether larger
* fields should be affected, the user interface can behave as most users will
* intuitively expect.
- * </p>
- *
+ *
* <p>
* <b>Note:</b> You should always use {@code roll} and {@code add} rather than
* attempting to perform arithmetic operations directly on the fields of a
@@ -304,11 +278,10 @@
* during non-leap years. The subclasses' <tt>add</tt> and <tt>roll</tt>
* methods will take this into account, while simple arithmetic manipulations
* may give invalid results.
- *
+ *
* @see Date
* @see GregorianCalendar
* @see TimeZone
- * @since Android 1.0
*/
public abstract class Calendar implements Serializable, Cloneable,
Comparable<Calendar> {
@@ -318,38 +291,28 @@
/**
* Set to {@code true} when the calendar fields have been set from the time, set to
* {@code false} when a field is changed and the fields must be recomputed.
- *
- * @since Android 1.0
*/
protected boolean areFieldsSet;
/**
* An integer array of calendar fields. The length is {@code FIELD_COUNT}.
- *
- * @since Android 1.0
*/
protected int[] fields;
/**
* A boolean array. Each element indicates if the corresponding field has
* been set. The length is {@code FIELD_COUNT}.
- *
- * @since Android 1.0
*/
protected boolean[] isSet;
/**
* Set to {@code true} when the time has been set, set to {@code false} when a field is
* changed and the time must be recomputed.
- *
- * @since Android 1.0
*/
protected boolean isTimeSet;
/**
* The time in milliseconds since January 1, 1970.
- *
- * @since Android 1.0
*/
protected long time;
@@ -365,100 +328,75 @@
private TimeZone zone;
- // BEGIN android-changed
/**
* Value of the {@code MONTH} field indicating the first month of the
* year.
- *
- * @since Android 1.0
*/
public static final int JANUARY = 0;
/**
* Value of the {@code MONTH} field indicating the second month of
* the year.
- *
- * @since Android 1.0
*/
public static final int FEBRUARY = 1;
/**
* Value of the {@code MONTH} field indicating the third month of the
* year.
- *
- * @since Android 1.0
*/
public static final int MARCH = 2;
/**
* Value of the {@code MONTH} field indicating the fourth month of
* the year.
- *
- * @since Android 1.0
*/
public static final int APRIL = 3;
/**
* Value of the {@code MONTH} field indicating the fifth month of the
* year.
- *
- * @since Android 1.0
*/
public static final int MAY = 4;
/**
* Value of the {@code MONTH} field indicating the sixth month of the
* year.
- *
- * @since Android 1.0
*/
public static final int JUNE = 5;
/**
* Value of the {@code MONTH} field indicating the seventh month of
* the year.
- *
- * @since Android 1.0
*/
public static final int JULY = 6;
/**
* Value of the {@code MONTH} field indicating the eighth month of
* the year.
- *
- * @since Android 1.0
*/
public static final int AUGUST = 7;
/**
* Value of the {@code MONTH} field indicating the ninth month of the
* year.
- *
- * @since Android 1.0
*/
public static final int SEPTEMBER = 8;
/**
* Value of the {@code MONTH} field indicating the tenth month of the
* year.
- *
- * @since Android 1.0
*/
public static final int OCTOBER = 9;
/**
* Value of the {@code MONTH} field indicating the eleventh month of
* the year.
- *
- * @since Android 1.0
*/
public static final int NOVEMBER = 10;
/**
* Value of the {@code MONTH} field indicating the twelfth month of
* the year.
- *
- * @since Android 1.0
*/
public static final int DECEMBER = 11;
@@ -466,57 +404,41 @@
* Value of the {@code MONTH} field indicating the thirteenth month
* of the year. Although {@code GregorianCalendar} does not use this
* value, lunar calendars do.
- *
- * @since Android 1.0
*/
public static final int UNDECIMBER = 12;
/**
* Value of the {@code DAY_OF_WEEK} field indicating Sunday.
- *
- * @since Android 1.0
*/
public static final int SUNDAY = 1;
/**
* Value of the {@code DAY_OF_WEEK} field indicating Monday.
- *
- * @since Android 1.0
*/
public static final int MONDAY = 2;
/**
* Value of the {@code DAY_OF_WEEK} field indicating Tuesday.
- *
- * @since Android 1.0
*/
public static final int TUESDAY = 3;
/**
* Value of the {@code DAY_OF_WEEK} field indicating Wednesday.
- *
- * @since Android 1.0
*/
public static final int WEDNESDAY = 4;
/**
* Value of the {@code DAY_OF_WEEK} field indicating Thursday.
- *
- * @since Android 1.0
*/
public static final int THURSDAY = 5;
/**
* Value of the {@code DAY_OF_WEEK} field indicating Friday.
- *
- * @since Android 1.0
*/
public static final int FRIDAY = 6;
/**
* Value of the {@code DAY_OF_WEEK} field indicating Saturday.
- *
- * @since Android 1.0
*/
public static final int SATURDAY = 7;
@@ -524,19 +446,15 @@
* Field number for {@code get} and {@code set} indicating the
* era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
* value; see subclass documentation.
- *
+ *
* @see GregorianCalendar#AD
* @see GregorianCalendar#BC
- *
- * @since Android 1.0
*/
public static final int ERA = 0;
/**
* Field number for {@code get} and {@code set} indicating the
* year. This is a calendar-specific value; see subclass documentation.
- *
- * @since Android 1.0
*/
public static final int YEAR = 1;
@@ -545,7 +463,7 @@
* month. This is a calendar-specific value. The first month of the year is
* {@code JANUARY}; the last depends on the number of months in a
* year.
- *
+ *
* @see #JANUARY
* @see #FEBRUARY
* @see #MARCH
@@ -559,8 +477,6 @@
* @see #NOVEMBER
* @see #DECEMBER
* @see #UNDECIMBER
- *
- * @since Android 1.0
*/
public static final int MONTH = 2;
@@ -571,11 +487,9 @@
* {@code getMinimalDaysInFirstWeek()}, has value 1. Subclasses
* define the value of {@code WEEK_OF_YEAR} for days before the first
* week of the year.
- *
+ *
* @see #getFirstDayOfWeek
* @see #getMinimalDaysInFirstWeek
- *
- * @since Android 1.0
*/
public static final int WEEK_OF_YEAR = 3;
@@ -586,11 +500,9 @@
* {@code getMinimalDaysInFirstWeek()}, has value 1. Subclasses
* define the value of {@code WEEK_OF_MONTH} for days before the
* first week of the month.
- *
+ *
* @see #getFirstDayOfWeek
* @see #getMinimalDaysInFirstWeek
- *
- * @since Android 1.0
*/
public static final int WEEK_OF_MONTH = 4;
@@ -598,10 +510,8 @@
* Field number for {@code get} and {@code set} indicating the
* day of the month. This is a synonym for {@code DAY_OF_MONTH}. The
* first day of the month has value 1.
- *
+ *
* @see #DAY_OF_MONTH
- *
- * @since Android 1.0
*/
public static final int DATE = 5;
@@ -609,10 +519,8 @@
* Field number for {@code get} and {@code set} indicating the
* day of the month. This is a synonym for {@code DATE}. The first
* day of the month has value 1.
- *
+ *
* @see #DATE
- *
- * @since Android 1.0
*/
public static final int DAY_OF_MONTH = 5;
@@ -620,8 +528,6 @@
* Field number for {@code get} and {@code set} indicating the
* day number within the current year. The first day of the year has value
* 1.
- *
- * @since Android 1.0
*/
public static final int DAY_OF_YEAR = 6;
@@ -631,7 +537,7 @@
* {@code MONDAY}, {@code TUESDAY}, {@code WEDNESDAY},
* {@code THURSDAY}, {@code FRIDAY}, and
* {@code SATURDAY}.
- *
+ *
* @see #SUNDAY
* @see #MONDAY
* @see #TUESDAY
@@ -639,8 +545,6 @@
* @see #THURSDAY
* @see #FRIDAY
* @see #SATURDAY
- *
- * @since Android 1.0
*/
public static final int DAY_OF_WEEK = 7;
@@ -664,11 +568,9 @@
* within the month than positive values. For example, if a month has 31
* days, {@code DAY_OF_WEEK_IN_MONTH -1} will overlap
* {@code DAY_OF_WEEK_IN_MONTH 5} and the end of {@code 4}.
- *
+ *
* @see #DAY_OF_WEEK
* @see #WEEK_OF_MONTH
- *
- * @since Android 1.0
*/
public static final int DAY_OF_WEEK_IN_MONTH = 8;
@@ -676,12 +578,10 @@
* Field number for {@code get} and {@code set} indicating
* whether the {@code HOUR} is before or after noon. E.g., at
* 10:04:15.250 PM the {@code AM_PM} is {@code PM}.
- *
+ *
* @see #AM
* @see #PM
* @see #HOUR
- *
- * @since Android 1.0
*/
public static final int AM_PM = 9;
@@ -689,11 +589,9 @@
* Field number for {@code get} and {@code set} indicating the
* hour of the morning or afternoon. {@code HOUR} is used for the
* 12-hour clock. E.g., at 10:04:15.250 PM the {@code HOUR} is 10.
- *
+ *
* @see #AM_PM
* @see #HOUR_OF_DAY
- *
- * @since Android 1.0
*/
public static final int HOUR = 10;
@@ -701,10 +599,8 @@
* Field number for {@code get} and {@code set} indicating the
* hour of the day. {@code HOUR_OF_DAY} is used for the 24-hour
* clock. E.g., at 10:04:15.250 PM the {@code HOUR_OF_DAY} is 22.
- *
+ *
* @see #HOUR
- *
- * @since Android 1.0
*/
public static final int HOUR_OF_DAY = 11;
@@ -712,8 +608,6 @@
* Field number for {@code get} and {@code set} indicating the
* minute within the hour. E.g., at 10:04:15.250 PM the {@code MINUTE}
* is 4.
- *
- * @since Android 1.0
*/
public static final int MINUTE = 12;
@@ -721,8 +615,6 @@
* Field number for {@code get} and {@code set} indicating the
* second within the minute. E.g., at 10:04:15.250 PM the
* {@code SECOND} is 15.
- *
- * @since Android 1.0
*/
public static final int SECOND = 13;
@@ -730,61 +622,46 @@
* Field number for {@code get} and {@code set} indicating the
* millisecond within the second. E.g., at 10:04:15.250 PM the
* {@code MILLISECOND} is 250.
- *
- * @since Android 1.0
*/
public static final int MILLISECOND = 14;
/**
* Field number for {@code get} and {@code set} indicating the
* raw offset from GMT in milliseconds.
- *
- * @since Android 1.0
*/
public static final int ZONE_OFFSET = 15;
/**
* Field number for {@code get} and {@code set} indicating the
* daylight savings offset in milliseconds.
- *
- * @since Android 1.0
*/
public static final int DST_OFFSET = 16;
/**
* This is the total number of fields in this calendar.
- *
- * @since Android 1.0
*/
public static final int FIELD_COUNT = 17;
/**
* Value of the {@code AM_PM} field indicating the period of the day
* from midnight to just before noon.
- *
- * @since Android 1.0
*/
public static final int AM = 0;
/**
* Value of the {@code AM_PM} field indicating the period of the day
* from noon to just before midnight.
- *
- * @since Android 1.0
*/
public static final int PM = 1;
- // END android-changed
private static String[] fieldNames = { "ERA=", "YEAR=", "MONTH=", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- "WEEK_OF_YEAR=", "WEEK_OF_MONTH=", "DAY_OF_MONTH=", "DAY_OF_YEAR=", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- "DAY_OF_WEEK=", "DAY_OF_WEEK_IN_MONTH=", "AM_PM=", "HOUR=", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
+ "WEEK_OF_YEAR=", "WEEK_OF_MONTH=", "DAY_OF_MONTH=", "DAY_OF_YEAR=", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ "DAY_OF_WEEK=", "DAY_OF_WEEK_IN_MONTH=", "AM_PM=", "HOUR=", //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
"HOUR_OF_DAY", "MINUTE=", "SECOND=", "MILLISECOND=", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"ZONE_OFFSET=", "DST_OFFSET=" }; //$NON-NLS-1$ //$NON-NLS-2$
/**
* Constructs a {@code Calendar} instance using the default {@code TimeZone} and {@code Locale}.
- *
- * @since Android 1.0
*/
protected Calendar() {
this(TimeZone.getDefault(), Locale.getDefault());
@@ -800,30 +677,38 @@
/**
* Constructs a {@code Calendar} instance using the specified {@code TimeZone} and {@code Locale}.
- *
+ *
* @param timezone
* the timezone.
* @param locale
* the locale.
- *
- * @since Android 1.0
*/
protected Calendar(TimeZone timezone, Locale locale) {
this(timezone);
+ // BEGIN android-changed
+ // com.ibm.icu.util.Calendar icuCalendar = com.ibm.icu.util.Calendar
+ // .getInstance(com.ibm.icu.util.SimpleTimeZone
+ // .getTimeZone(timezone.getID()), locale);
+ // setFirstDayOfWeek(icuCalendar.getFirstDayOfWeek());
+ // setMinimalDaysInFirstWeek(icuCalendar.getMinimalDaysInFirstWeek());
ResourceBundle bundle = Locale.getBundle("Locale", locale); //$NON-NLS-1$
setFirstDayOfWeek(((Integer) bundle.getObject("First_Day")).intValue()); //$NON-NLS-1$
setMinimalDaysInFirstWeek(((Integer) bundle.getObject("Minimal_Days")) //$NON-NLS-1$
.intValue());
+ // END android-changed
}
+
/**
* Adds the specified amount to a {@code Calendar} field.
- *
+ *
* @param field
* the {@code Calendar} field to modify.
* @param value
* the amount to add to the field.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if {@code field} is {@code DST_OFFSET} or {@code
+ * ZONE_OFFSET}.
*/
abstract public void add(int field, int value);
@@ -831,11 +716,13 @@
* Returns whether the {@code Date} specified by this {@code Calendar} instance is after the {@code Date}
* specified by the parameter. The comparison is not dependent on the time
* zones of the {@code Calendar}.
- *
+ *
* @param calendar
* the {@code Calendar} instance to compare.
* @return {@code true} when this Calendar is after calendar, {@code false} otherwise.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if the time is not set and the time cannot be computed
+ * from the current field values.
*/
public boolean after(Object calendar) {
if (!(calendar instanceof Calendar)) {
@@ -848,11 +735,13 @@
* Returns whether the {@code Date} specified by this {@code Calendar} instance is before the
* {@code Date} specified by the parameter. The comparison is not dependent on the
* time zones of the {@code Calendar}.
- *
+ *
* @param calendar
* the {@code Calendar} instance to compare.
* @return {@code true} when this Calendar is before calendar, {@code false} otherwise.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if the time is not set and the time cannot be computed
+ * from the current field values.
*/
public boolean before(Object calendar) {
if (!(calendar instanceof Calendar)) {
@@ -864,8 +753,6 @@
/**
* Clears all of the fields of this {@code Calendar}. All fields are initialized to
* zero.
- *
- * @since Android 1.0
*/
public final void clear() {
for (int i = 0; i < FIELD_COUNT; i++) {
@@ -877,10 +764,9 @@
/**
* Clears the specified field to zero and sets the isSet flag to {@code false}.
- *
+ *
* @param field
* the field to clear.
- * @since Android 1.0
*/
public final void clear(int field) {
fields[field] = 0;
@@ -890,11 +776,10 @@
/**
* Returns a new {@code Calendar} with the same properties.
- *
+ *
* @return a shallow copy of this {@code Calendar}.
- *
+ *
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -912,11 +797,10 @@
/**
* Computes the time from the fields if the time has not already been set.
* Computes the fields from the time if the fields are not already set.
- *
- * @exception IllegalArgumentException
- * when the time is not set and the time cannot be computed
+ *
+ * @throws IllegalArgumentException
+ * if the time is not set and the time cannot be computed
* from the current field values.
- * @since Android 1.0
*/
protected void complete() {
if (!isTimeSet) {
@@ -931,18 +815,15 @@
/**
* Computes the {@code Calendar} fields from {@code time}.
- *
- * @since Android 1.0
*/
protected abstract void computeFields();
/**
* Computes {@code time} from the Calendar fields.
- *
- * @exception IllegalArgumentException
- * when the time cannot be computed from the current field
+ *
+ * @throws IllegalArgumentException
+ * if the time cannot be computed from the current field
* values.
- * @since Android 1.0
*/
protected abstract void computeTime();
@@ -950,12 +831,11 @@
* Compares the specified object to this {@code Calendar} and returns whether they are
* equal. The object must be an instance of {@code Calendar} and have the same
* properties.
- *
+ *
* @param object
* the object to compare with this object.
* @return {@code true} if the specified object is equal to this {@code Calendar}, {@code false}
* otherwise.
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -977,18 +857,17 @@
/**
* Gets the value of the specified field after computing the field values by
* calling {@code complete()} first.
- *
+ *
* @param field
* the field to get.
* @return the value of the specified field.
- *
- * @exception IllegalArgumentException
- * when the fields are not set, the time is not set, and the
+ *
+ * @throws IllegalArgumentException
+ * if the fields are not set, the time is not set, and the
* time cannot be computed from the current field values.
- * @exception ArrayIndexOutOfBoundsException
+ * @throws ArrayIndexOutOfBoundsException
* if the field is not inside the range of possible fields.
* The range is starting at 0 up to {@code FIELD_COUNT}.
- * @since Android 1.0
*/
public int get(int field) {
complete();
@@ -997,11 +876,10 @@
/**
* Gets the maximum value of the specified field for the current date.
- *
+ *
* @param field
* the field.
* @return the maximum value of the specified field.
- * @since Android 1.0
*/
public int getActualMaximum(int field) {
int value, next;
@@ -1023,11 +901,10 @@
/**
* Gets the minimum value of the specified field for the current date.
- *
+ *
* @param field
* the field.
* @return the minimum value of the specified field.
- * @since Android 1.0
*/
public int getActualMinimum(int field) {
int value, next;
@@ -1049,9 +926,8 @@
/**
* Gets the list of installed {@code Locale}s which support {@code Calendar}.
- *
+ *
* @return an array of {@code Locale}.
- * @since Android 1.0
*/
public static synchronized Locale[] getAvailableLocales() {
return Locale.getAvailableLocales();
@@ -1059,9 +935,8 @@
/**
* Gets the first day of the week for this {@code Calendar}.
- *
+ *
* @return the first day of the week.
- * @since Android 1.0
*/
public int getFirstDayOfWeek() {
return firstDayOfWeek;
@@ -1071,21 +946,19 @@
* Gets the greatest minimum value of the specified field. This is the
* biggest value that {@code getActualMinimum} can return for any possible
* time.
- *
+ *
* @param field
* the field.
* @return the greatest minimum value of the specified field.
- * @since Android 1.0
*/
abstract public int getGreatestMinimum(int field);
/**
* Constructs a new instance of the {@code Calendar} subclass appropriate for the
* default {@code Locale}.
- *
+ *
* @return a {@code Calendar} subclass instance set to the current date and time in
* the default {@code Timezone}.
- * @since Android 1.0
*/
public static synchronized Calendar getInstance() {
return new GregorianCalendar();
@@ -1094,11 +967,10 @@
/**
* Constructs a new instance of the {@code Calendar} subclass appropriate for the
* specified {@code Locale}.
- *
+ *
* @param locale
* the locale to use.
* @return a {@code Calendar} subclass instance set to the current date and time.
- * @since Android 1.0
*/
public static synchronized Calendar getInstance(Locale locale) {
return new GregorianCalendar(locale);
@@ -1107,12 +979,11 @@
/**
* Constructs a new instance of the {@code Calendar} subclass appropriate for the
* default {@code Locale}, using the specified {@code TimeZone}.
- *
+ *
* @param timezone
* the {@code TimeZone} to use.
* @return a {@code Calendar} subclass instance set to the current date and time in
* the specified timezone.
- * @since Android 1.0
*/
public static synchronized Calendar getInstance(TimeZone timezone) {
return new GregorianCalendar(timezone);
@@ -1121,14 +992,13 @@
/**
* Constructs a new instance of the {@code Calendar} subclass appropriate for the
* specified {@code Locale}.
- *
+ *
* @param timezone
* the {@code TimeZone} to use.
* @param locale
* the {@code Locale} to use.
* @return a {@code Calendar} subclass instance set to the current date and time in
* the specified timezone.
- * @since Android 1.0
*/
public static synchronized Calendar getInstance(TimeZone timezone,
Locale locale) {
@@ -1139,30 +1009,27 @@
* Gets the smallest maximum value of the specified field. This is the
* smallest value that {@code getActualMaximum()} can return for any
* possible time.
- *
+ *
* @param field
* the field number.
* @return the smallest maximum value of the specified field.
- * @since Android 1.0
*/
abstract public int getLeastMaximum(int field);
/**
* Gets the greatest maximum value of the specified field. This returns the
* biggest value that {@code get} can return for the specified field.
- *
+ *
* @param field
* the field.
* @return the greatest maximum value of the specified field.
- * @since Android 1.0
*/
abstract public int getMaximum(int field);
/**
* Gets the minimal days in the first week of the year.
- *
+ *
* @return the minimal days in the first week of the year.
- * @since Android 1.0
*/
public int getMinimalDaysInFirstWeek() {
return minimalDaysInFirstWeek;
@@ -1171,23 +1038,21 @@
/**
* Gets the smallest minimum value of the specified field. this returns the
* smallest value thet {@code get} can return for the specified field.
- *
+ *
* @param field
* the field number.
* @return the smallest minimum value of the specified field.
- * @since Android 1.0
*/
abstract public int getMinimum(int field);
/**
* Gets the time of this {@code Calendar} as a {@code Date} object.
- *
+ *
* @return a new {@code Date} initialized to the time of this {@code Calendar}.
- *
- * @exception IllegalArgumentException
- * when the time is not set and the time cannot be computed
+ *
+ * @throws IllegalArgumentException
+ * if the time is not set and the time cannot be computed
* from the current field values.
- * @since Android 1.0
*/
public final Date getTime() {
return new Date(getTimeInMillis());
@@ -1195,13 +1060,12 @@
/**
* Computes the time from the fields if required and returns the time.
- *
+ *
* @return the time of this {@code Calendar}.
- *
- * @exception IllegalArgumentException
- * when the time is not set and the time cannot be computed
+ *
+ * @throws IllegalArgumentException
+ * if the time is not set and the time cannot be computed
* from the current field values.
- * @since Android 1.0
*/
public long getTimeInMillis() {
if (!isTimeSet) {
@@ -1213,9 +1077,8 @@
/**
* Gets the timezone of this {@code Calendar}.
- *
+ *
* @return the {@code TimeZone} used by this {@code Calendar}.
- * @since Android 1.0
*/
public TimeZone getTimeZone() {
return zone;
@@ -1224,11 +1087,10 @@
/**
* Returns an integer hash code for the receiver. Objects which are equal
* return the same value for this method.
- *
+ *
* @return the receiver's hash.
- *
+ *
* @see #equals
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -1238,11 +1100,10 @@
/**
* Gets the value of the specified field without recomputing.
- *
+ *
* @param field
* the field.
* @return the value of the specified field.
- * @since Android 1.0
*/
protected final int internalGet(int field) {
return fields[field];
@@ -1251,9 +1112,8 @@
/**
* Returns if this {@code Calendar} accepts field values which are outside the valid
* range for the field.
- *
+ *
* @return {@code true} if this {@code Calendar} is lenient, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean isLenient() {
return lenient;
@@ -1261,11 +1121,10 @@
/**
* Returns whether the specified field is set.
- *
+ *
* @param field
* a {@code Calendar} field number.
* @return {@code true} if the specified field is set, {@code false} otherwise.
- * @since Android 1.0
*/
public final boolean isSet(int field) {
return isSet[field];
@@ -1276,12 +1135,11 @@
* the field when it goes beyond the maximum or minimum value for the
* current date. Other fields will be adjusted as required to maintain a
* consistent date.
- *
+ *
* @param field
* the field to roll.
* @param value
* the amount to add.
- * @since Android 1.0
*/
public void roll(int field, int value) {
boolean increment = value >= 0;
@@ -1296,23 +1154,21 @@
* field when it goes beyond the maximum or minimum value for the current
* date. Other fields will be adjusted as required to maintain a consistent
* date.
- *
+ *
* @param field
* the number indicating the field to roll.
* @param increment
* {@code true} to increment the field, {@code false} to decrement.
- * @since Android 1.0
*/
abstract public void roll(int field, boolean increment);
/**
* Sets a field to the specified value.
- *
+ *
* @param field
* the code indicating the {@code Calendar} field to modify.
* @param value
* the value.
- * @since Android 1.0
*/
public void set(int field, int value) {
fields[field] = value;
@@ -1332,14 +1188,13 @@
/**
* Sets the year, month and day of the month fields. Other fields are not
* changed.
- *
+ *
* @param year
* the year.
* @param month
* the month.
* @param day
* the day of the month.
- * @since Android 1.0
*/
public final void set(int year, int month, int day) {
set(YEAR, year);
@@ -1350,7 +1205,7 @@
/**
* Sets the year, month, day of the month, hour of day and minute fields.
* Other fields are not changed.
- *
+ *
* @param year
* the year.
* @param month
@@ -1361,7 +1216,6 @@
* the hour of day.
* @param minute
* the minute.
- * @since Android 1.0
*/
public final void set(int year, int month, int day, int hourOfDay,
int minute) {
@@ -1373,7 +1227,7 @@
/**
* Sets the year, month, day of the month, hour of day, minute and second
* fields. Other fields are not changed.
- *
+ *
* @param year
* the year.
* @param month
@@ -1386,7 +1240,6 @@
* the minute.
* @param second
* the second.
- * @since Android 1.0
*/
public final void set(int year, int month, int day, int hourOfDay,
int minute, int second) {
@@ -1396,10 +1249,9 @@
/**
* Sets the first day of the week for this {@code Calendar}.
- *
+ *
* @param value
* a {@code Calendar} day of the week.
- * @since Android 1.0
*/
public void setFirstDayOfWeek(int value) {
firstDayOfWeek = value;
@@ -1408,10 +1260,9 @@
/**
* Sets this {@code Calendar} to accept field values which are outside the valid
* range for the field.
- *
+ *
* @param value
* a boolean value.
- * @since Android 1.0
*/
public void setLenient(boolean value) {
lenient = value;
@@ -1419,10 +1270,9 @@
/**
* Sets the minimal days in the first week of the year.
- *
+ *
* @param value
* the minimal days in the first week of the year.
- * @since Android 1.0
*/
public void setMinimalDaysInFirstWeek(int value) {
minimalDaysInFirstWeek = value;
@@ -1430,10 +1280,9 @@
/**
* Sets the time of this {@code Calendar}.
- *
+ *
* @param date
* a {@code Date} object.
- * @since Android 1.0
*/
public final void setTime(Date date) {
setTimeInMillis(date.getTime());
@@ -1441,43 +1290,45 @@
/**
* Sets the time of this {@code Calendar}.
- *
+ *
* @param milliseconds
* the time as the number of milliseconds since Jan. 1, 1970.
- * @since Android 1.0
*/
public void setTimeInMillis(long milliseconds) {
- time = milliseconds;
- isTimeSet = true;
- areFieldsSet = false;
- complete();
+ if (!isTimeSet || !areFieldsSet || time != milliseconds) {
+ time = milliseconds;
+ isTimeSet = true;
+ areFieldsSet = false;
+ complete();
+ }
}
/**
* Sets the {@code TimeZone} used by this Calendar.
- *
+ *
* @param timezone
* a {@code TimeZone}.
- * @since Android 1.0
*/
public void setTimeZone(TimeZone timezone) {
zone = timezone;
+ areFieldsSet = false;
}
/**
* Returns the string representation of this {@code Calendar}.
- *
+ *
* @return the string representation of this {@code Calendar}.
- * @since Android 1.0
*/
@Override
+ @SuppressWarnings("nls")
public String toString() {
- StringBuffer result = new StringBuffer(getClass().getName() + "[time=" //$NON-NLS-1$
- + (isTimeSet ? String.valueOf(time) : "?") + ",areFieldsSet=" //$NON-NLS-1$//$NON-NLS-2$
- + areFieldsSet +
- // ",areAllFieldsSet=" + areAllFieldsSet +
- ",lenient=" + lenient + ",zone=" + zone + ",firstDayOfWeek=" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + firstDayOfWeek + ",minimalDaysInFirstWeek=" //$NON-NLS-1$
+ StringBuffer result = new StringBuffer(getClass().getName() + "[time="
+ + (isTimeSet ? String.valueOf(time) : "?")
+ + ",areFieldsSet="
+ + areFieldsSet
+ + // ",areAllFieldsSet=" + areAllFieldsSet +
+ ",lenient=" + lenient + ",zone=" + zone + ",firstDayOfWeek="
+ + firstDayOfWeek + ",minimalDaysInFirstWeek="
+ minimalDaysInFirstWeek);
for (int i = 0; i < FIELD_COUNT; i++) {
result.append(',');
@@ -1496,7 +1347,7 @@
/**
* Compares the times of the two {@code Calendar}, which represent the milliseconds
* from the January 1, 1970 00:00:00.000 GMT (Gregorian).
- *
+ *
* @param anotherCalendar
* another calendar that this one is compared with.
* @return 0 if the times of the two {@code Calendar}s are equal, -1 if the time of
@@ -1507,7 +1358,6 @@
* @throws IllegalArgumentException
* if the argument does not include a valid time
* value.
- * @since Android 1.0
*/
public int compareTo(Calendar anotherCalendar) {
if (null == anotherCalendar) {
@@ -1524,6 +1374,7 @@
return -1;
}
+ @SuppressWarnings("nls")
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("areFieldsSet", Boolean.TYPE), //$NON-NLS-1$
new ObjectStreamField("fields", int[].class), //$NON-NLS-1$
@@ -1537,6 +1388,7 @@
new ObjectStreamField("time", Long.TYPE), //$NON-NLS-1$
new ObjectStreamField("zone", TimeZone.class), }; //$NON-NLS-1$
+ @SuppressWarnings("nls")
private void writeObject(ObjectOutputStream stream) throws IOException {
complete();
ObjectOutputStream.PutField putFields = stream.putFields();
@@ -1554,6 +1406,7 @@
stream.writeFields();
}
+ @SuppressWarnings("nls")
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
ObjectInputStream.GetField readFields = stream.readFields();
diff --git a/luni/src/main/java/java/util/Collection.java b/luni/src/main/java/java/util/Collection.java
index e26dba6..6447e39 100644
--- a/luni/src/main/java/java/util/Collection.java
+++ b/luni/src/main/java/java/util/Collection.java
@@ -22,7 +22,7 @@
* {@code Collection} is the root of the collection hierarchy. It defines operations on
* data collections and the behavior that they will have in all implementations
* of {@code Collection}s.
- *
+ *
* All direct or indirect implementations of {@code Collection} should implement at
* least two constuctors. One with no parameters which creates an empty
* collection and one with a parameter of type {@code Collection}. This second
@@ -30,58 +30,55 @@
* initial collection but with the same elements. Implementations of {@code Collection}
* cannot be forced to implement these two constructors but at least all
* implementations under {@code java.util} do.
- *
+ *
* Methods that change the content of a collection throw an
* {@code UnsupportedOperationException} if the underlying collection does not
* support that operation, though it's not mandatory to throw such an {@code Exception}
* in cases where the requested operation would not change the collection. In
* these cases it's up to the implementation whether it throws an
* {@code UnsupportedOperationException} or not.
- *
+ *
* Methods marked with (optional) can throw an
* {@code UnsupportedOperationException} if the underlying collection doesn't
* support that method.
- *
- * @since Android 1.0
*/
public interface Collection<E> extends Iterable<E> {
/**
* Attempts to add {@code object} to the contents of this
* {@code Collection} (optional).
- *
+ *
* After this method finishes successfully it is guaranteed that the object
* is contained in the collection.
- *
+ *
* If the collection was modified it returns {@code true}, {@code false} if
* no changes were made.
- *
+ *
* An implementation of {@code Collection} may narrow the set of accepted
* objects, but it has to specify this in the documentation. If the object
* to be added does not meet this restriction, then an
* {@code IllegalArgumentException} is thrown.
- *
+ *
* If a collection does not yet contain an object that is to be added and
* adding the object fails, this method <i>must</i> throw an appropriate
* unchecked Exception. Returning false is not permitted in this case
* because it would violate the postcondition that the element will be part
* of the collection after this method finishes.
- *
+ *
* @param object
* the object to add.
* @return {@code true} if this {@code Collection} is
* modified, {@code false} otherwise.
- *
- * @exception UnsupportedOperationException
- * when adding to this {@code Collection} is not supported.
- * @exception ClassCastException
- * when the class of the object is inappropriate for this
+ *
+ * @throws UnsupportedOperationException
+ * if adding to this {@code Collection} is not supported.
+ * @throws ClassCastException
+ * if the class of the object is inappropriate for this
* collection.
- * @exception IllegalArgumentException
- * when the object cannot be added to this {@code Collection}.
- * @exception NullPointerException
- * when null elements cannot be added to the {@code Collection}.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if the object cannot be added to this {@code Collection}.
+ * @throws NullPointerException
+ * if null elements cannot be added to the {@code Collection}.
*/
public boolean add(E object);
@@ -90,35 +87,33 @@
* to the contents of this {@code Collection} (optional). If the passed {@code Collection}
* is changed during the process of adding elements to this {@code Collection}, the
* behavior is not defined.
- *
+ *
* @param collection
* the {@code Collection} of objects.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when adding to this {@code Collection} is not supported.
- * @exception ClassCastException
- * when the class of an object is inappropriate for this
+ * @throws UnsupportedOperationException
+ * if adding to this {@code Collection} is not supported.
+ * @throws ClassCastException
+ * if the class of an object is inappropriate for this
* {@code Collection}.
- * @exception IllegalArgumentException
- * when an object cannot be added to this {@code Collection}.
- * @exception NullPointerException
- * when {@code collection} is {@code null}, or if it
+ * @throws IllegalArgumentException
+ * if an object cannot be added to this {@code Collection}.
+ * @throws NullPointerException
+ * if {@code collection} is {@code null}, or if it
* contains {@code null} elements and this {@code Collection} does
* not support such elements.
- * @since Android 1.0
*/
public boolean addAll(Collection<? extends E> collection);
/**
* Removes all elements from this {@code Collection}, leaving it empty (optional).
- *
- * @exception UnsupportedOperationException
- * when removing from this {@code Collection} is not supported.
- *
+ *
+ * @throws UnsupportedOperationException
+ * if removing from this {@code Collection} is not supported.
+ *
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
public void clear();
@@ -127,18 +122,17 @@
* {@code true} if and only if at least one element {@code elem} in this
* {@code Collection} meets following requirement:
* {@code (object==null ? elem==null : object.equals(elem))}.
- *
+ *
* @param object
* the object to search for.
* @return {@code true} if object is an element of this {@code Collection},
* {@code false} otherwise.
- * @exception ClassCastException
+ * @throws ClassCastException
* if the object to look for isn't of the correct
* type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if the object to look for is {@code null} and this
* {@code Collection} doesn't support {@code null} elements.
- * @since Android 1.0
*/
public boolean contains(Object object);
@@ -147,56 +141,52 @@
* specified {@code Collection}. If an elemenet {@code elem} is contained several
* times in the specified {@code Collection}, the method returns {@code true} even
* if {@code elem} is contained only once in this {@code Collection}.
- *
+ *
* @param collection
* the collection of objects.
* @return {@code true} if all objects in the specified {@code Collection} are
* elements of this {@code Collection}, {@code false} otherwise.
- * @exception ClassCastException
+ * @throws ClassCastException
* if one or more elements of {@code collection} isn't of the
* correct type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} contains at least one {@code null}
* element and this {@code Collection} doesn't support {@code null}
* elements.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} is {@code null}.
- * @since Android 1.0
*/
public boolean containsAll(Collection<?> collection);
/**
* Compares the argument to the receiver, and returns true if they represent
* the <em>same</em> object using a class specific comparison.
- *
+ *
* @param object
* the object to compare with this object.
* @return {@code true} if the object is the same as this object and
* {@code false} if it is different from this object.
* @see #hashCode
- * @since Android 1.0
*/
public boolean equals(Object object);
/**
* Returns an integer hash code for the receiver. Objects which are equal
* return the same value for this method.
- *
+ *
* @return the receiver's hash.
- *
+ *
* @see #equals
- * @since Android 1.0
*/
public int hashCode();
/**
* Returns if this {@code Collection} contains no elements.
- *
+ *
* @return {@code true} if this {@code Collection} has no elements, {@code false}
* otherwise.
- *
+ *
* @see #size
- * @since Android 1.0
*/
public boolean isEmpty();
@@ -205,9 +195,8 @@
* objects contained by this {@code Collection}. The order in which the elements are
* returned by the iterator is not defined. Only if the instance of the
* {@code Collection} has a defined order the elements are returned in that order.
- *
+ *
* @return an iterator for accessing the {@code Collection} contents.
- * @since Android 1.0
*/
public Iterator<E> iterator();
@@ -215,19 +204,18 @@
* Removes one instance of the specified object from this {@code Collection} if one
* is contained (optional). The element {@code elem} that is removed
* complies with {@code (object==null ? elem==null : object.equals(elem)}.
- *
+ *
* @param object
* the object to remove.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code Collection} is not supported.
- * @exception ClassCastException
- * when the object passed is not of the correct type.
- * @exception NullPointerException
+ * @throws UnsupportedOperationException
+ * if removing from this {@code Collection} is not supported.
+ * @throws ClassCastException
+ * if the object passed is not of the correct type.
+ * @throws NullPointerException
* if {@code object} is {@code null} and this {@code Collection}
* doesn't support {@code null} elements.
- * @since Android 1.0
*/
public boolean remove(Object object);
@@ -236,24 +224,23 @@
* specified {@code Collection} (optional). After this method returns none of the
* elements in the passed {@code Collection} can be found in this {@code Collection}
* anymore.
- *
+ *
* @param collection
* the collection of objects to remove.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- *
- * @exception UnsupportedOperationException
- * when removing from this {@code Collection} is not supported.
- * @exception ClassCastException
+ *
+ * @throws UnsupportedOperationException
+ * if removing from this {@code Collection} is not supported.
+ * @throws ClassCastException
* if one or more elements of {@code collection}
* isn't of the correct type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} contains at least one
* {@code null} element and this {@code Collection} doesn't support
* {@code null} elements.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} is {@code null}.
- * @since Android 1.0
*/
public boolean removeAll(Collection<?> collection);
@@ -262,48 +249,45 @@
* {@code Collection} passed (optional). After this method returns this {@code Collection}
* will only contain elements that also can be found in the {@code Collection}
* passed to this method.
- *
+ *
* @param collection
* the collection of objects to retain.
* @return {@code true} if this {@code Collection} is modified, {@code false}
* otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code Collection} is not supported.
- * @exception ClassCastException
+ * @throws UnsupportedOperationException
+ * if removing from this {@code Collection} is not supported.
+ * @throws ClassCastException
* if one or more elements of {@code collection}
* isn't of the correct type.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} contains at least one
* {@code null} element and this {@code Collection} doesn't support
* {@code null} elements.
- * @exception NullPointerException
+ * @throws NullPointerException
* if {@code collection} is {@code null}.
- * @since Android 1.0
*/
public boolean retainAll(Collection<?> collection);
/**
* Returns a count of how many objects this {@code Collection} contains.
- *
+ *
* @return how many objects this {@code Collection} contains, or Integer.MAX_VALUE
* if there are more than Integer.MAX_VALUE elements in this
* {@code Collection}.
- * @since Android 1.0
*/
public int size();
/**
* Returns a new array containing all elements contained in this {@code Collection}.
- *
+ *
* If the implementation has ordered elements it will return the element
* array in the same order as an iterator would return them.
- *
+ *
* The array returned does not reflect any changes of the {@code Collection}. A new
* array is created even if the underlying data structure is already an
* array.
- *
+ *
* @return an array of the elements from this {@code Collection}.
- * @since Android 1.0
*/
public Object[] toArray();
@@ -313,21 +297,20 @@
* array is used, otherwise an array of the same type is created. If the
* specified array is used and is larger than this {@code Collection}, the array
* element following the {@code Collection} elements is set to null.
- *
+ *
* If the implementation has ordered elements it will return the element
* array in the same order as an iterator would return them.
- *
+ *
* {@code toArray(new Object[0])} behaves exactly the same way as
* {@code toArray()} does.
- *
+ *
* @param array
* the array.
* @return an array of the elements from this {@code Collection}.
- *
- * @exception ArrayStoreException
- * when the type of an element in this {@code Collection} cannot be
+ *
+ * @throws ArrayStoreException
+ * if the type of an element in this {@code Collection} cannot be
* stored in the type of the specified array.
- * @since Android 1.0
*/
public <T> T[] toArray(T[] array);
}
diff --git a/luni/src/main/java/java/util/Collections.java b/luni/src/main/java/java/util/Collections.java
index 5905bc2..767d98b 100644
--- a/luni/src/main/java/java/util/Collections.java
+++ b/luni/src/main/java/java/util/Collections.java
@@ -27,8 +27,8 @@
/**
* {@code Collections} contains static methods which operate on
* {@code Collection} classes.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public class Collections {
@@ -69,7 +69,7 @@
@SuppressWarnings("unchecked")
private static final class EmptyList extends AbstractList implements
- Serializable {
+ RandomAccess, Serializable {
private static final long serialVersionUID = 8842843931221139166L;
@Override
@@ -171,24 +171,18 @@
/**
* An empty immutable instance of {@link List}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final List EMPTY_LIST = new EmptyList();
/**
* An empty immutable instance of {@link Set}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Set EMPTY_SET = new EmptySet();
/**
* An empty immutable instance of {@link Map}.
- *
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final Map EMPTY_MAP = new EmptyMap();
@@ -532,9 +526,9 @@
* problems. This is necessary since RandomAccess API was introduced
* only in 1.4.
* <p>
- *
+ *
* @return SynchronizedList
- *
+ *
* @see SynchronizedList#readResolve()
*/
private Object writeReplace() {
@@ -591,15 +585,51 @@
}
public int indexOf(Object object) {
+ final int size;
+ final Object[] array;
synchronized (mutex) {
- return list.indexOf(object);
+ size = list.size();
+ array = new Object[size];
+ list.toArray(array);
}
+ if (null != object)
+ for (int i = 0; i < size; i++) {
+ if (object.equals(array[i])) {
+ return i;
+ }
+ }
+ else {
+ for (int i = 0; i < size; i++) {
+ if (null == array[i]) {
+ return i;
+ }
+ }
+ }
+ return -1;
}
public int lastIndexOf(Object object) {
+ final int size;
+ final Object[] array;
synchronized (mutex) {
- return list.lastIndexOf(object);
+ size = list.size();
+ array = new Object[size];
+ list.toArray(array);
}
+ if (null != object)
+ for (int i = size - 1; i >= 0; i--) {
+ if (object.equals(array[i])) {
+ return i;
+ }
+ }
+ else {
+ for (int i = size - 1; i >= 0; i--) {
+ if (null == array[i]) {
+ return i;
+ }
+ }
+ }
+ return -1;
}
public ListIterator<E> listIterator() {
@@ -646,10 +676,10 @@
* replaced with SynchronizedList instances during serialization for
* compliance with JREs before 1.4.
* <p>
- *
+ *
* @return a SynchronizedList instance if the underlying list implements
* RandomAccess interface, or this same object if not.
- *
+ *
* @see SynchronizedRandomAccessList#writeReplace()
*/
private Object readResolve() {
@@ -1033,9 +1063,9 @@
* problems. This is necessary since RandomAccess API was introduced
* only in 1.4.
* <p>
- *
+ *
* @return UnmodifiableList
- *
+ *
* @see UnmodifiableList#readResolve()
*/
private Object writeReplace() {
@@ -1150,11 +1180,11 @@
* replaced with UnmodifiableList instances during serialization for
* compliance with JREs before 1.4.
* <p>
- *
+ *
* @return an UnmodifiableList instance if the underlying list
* implements RandomAccess interface, or this same object if
* not.
- *
+ *
* @see UnmodifiableRandomAccessList#writeReplace()
*/
private Object readResolve() {
@@ -1429,13 +1459,13 @@
/**
* Performs a binary search for the specified element in the specified
- * sorted List. The List needs to be already sorted in natural sorting
+ * sorted list. The list needs to be already sorted in natural sorting
* order. Searching in an unsorted array has an undefined result. It's also
* undefined which element is found if there are multiple occurrences of the
* same element.
- *
+ *
* @param list
- * the sorted List to search.
+ * the sorted list to search.
* @param object
* the element to find.
* @return the non-negative index of the element, or a negative index which
@@ -1443,7 +1473,6 @@
* @throws ClassCastException
* if an element in the List or the search element does not
* implement Comparable, or cannot be compared to each other.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static <T> int binarySearch(
@@ -1455,12 +1484,12 @@
return -1;
}
- Comparable<T> key = (Comparable<T>) object;
+
if (!(list instanceof RandomAccess)) {
- ListIterator<T> it = (ListIterator<T>) list.listIterator();
+ ListIterator<? extends Comparable<? super T>> it = list.listIterator();
while (it.hasNext()) {
int result;
- if ((result = key.compareTo(it.next())) <= 0) {
+ if ((result = -it.next().compareTo(object)) <= 0) {
if (result == 0) {
return it.previousIndex();
}
@@ -1473,7 +1502,7 @@
int low = 0, mid = list.size(), high = mid - 1, result = -1;
while (low <= high) {
mid = (low + high) >> 1;
- if ((result = key.compareTo((T) list.get(mid))) > 0) {
+ if ((result = -list.get(mid).compareTo(object)) > 0) {
low = mid + 1;
} else if (result == 0) {
return mid;
@@ -1486,26 +1515,28 @@
/**
* Performs a binary search for the specified element in the specified
- * sorted List using the specified Comparator. The List needs to be already
+ * sorted list using the specified comparator. The list needs to be already
* sorted according to the comparator passed. Searching in an unsorted array
* has an undefined result. It's also undefined which element is found if
* there are multiple occurrences of the same element.
- *
+ *
* @param list
* the sorted List to search.
* @param object
* the element to find.
* @param comparator
- * the Comparator. If the comparator is {@code null} then the
+ * the comparator. If the comparator is {@code null} then the
* search uses the objects' natural ordering.
* @return the non-negative index of the element, or a negative index which
* is the {@code -index - 1} where the element would be inserted.
* @throws ClassCastException
* when an element in the list and the searched element cannot
- * be compared to each other using the Comparator.
- * @since Android 1.0
+ * be compared to each other using the comparator.
*/
@SuppressWarnings("unchecked")
+ // BEGIN android-note
+ // removed "@param <T> The element type", which is rejected by apicheck
+ // END android-note
public static <T> int binarySearch(List<? extends T> list, T object,
Comparator<? super T> comparator) {
if (comparator == null) {
@@ -1516,7 +1547,7 @@
ListIterator<? extends T> it = list.listIterator();
while (it.hasNext()) {
int result;
- if ((result = comparator.compare(object, it.next())) <= 0) {
+ if ((result = -comparator.compare(it.next(), object)) <= 0) {
if (result == 0) {
return it.previousIndex();
}
@@ -1529,7 +1560,7 @@
int low = 0, mid = list.size(), high = mid - 1, result = -1;
while (low <= high) {
mid = (low + high) >> 1;
- if ((result = comparator.compare(object, list.get(mid))) > 0) {
+ if ((result = -comparator.compare(list.get(mid),object)) > 0) {
low = mid + 1;
} else if (result == 0) {
return mid;
@@ -1545,17 +1576,16 @@
* end both lists will have the same objects at the same index. If the
* destination array is larger than the source list, the elements in the
* destination list with {@code index >= source.size()} will be unchanged.
- *
+ *
* @param destination
* the list whose elements are set from the source list.
* @param source
* the list with the elements to be copied into the destination.
* @throws IndexOutOfBoundsException
- * when the destination List is smaller than the source List.
+ * when the destination list is smaller than the source list.
* @throws UnsupportedOperationException
* when replacing an element in the destination list is not
* supported.
- * @since Android 1.0
*/
public static <T> void copy(List<? super T> destination,
List<? extends T> source) {
@@ -1576,11 +1606,10 @@
/**
* Returns an {@code Enumeration} on the specified collection.
- *
+ *
* @param collection
* the collection to enumerate.
* @return an Enumeration.
- * @since Android 1.0
*/
public static <T> Enumeration<T> enumeration(Collection<T> collection) {
final Collection<T> c = collection;
@@ -1598,15 +1627,14 @@
}
/**
- * Fills the specified List with the specified element.
- *
+ * Fills the specified list with the specified element.
+ *
* @param list
- * the List to fill.
+ * the list to fill.
* @param object
* the element to fill the list with.
* @throws UnsupportedOperationException
* when replacing an element in the List is not supported.
- * @since Android 1.0
*/
public static <T> void fill(List<? super T> list, T object) {
ListIterator<? super T> it = list.listIterator();
@@ -1617,16 +1645,15 @@
}
/**
- * Searches the specified Collection for the maximum element.
- *
+ * Searches the specified collection for the maximum element.
+ *
* @param collection
- * the Collection to search.
+ * the collection to search.
* @return the maximum element in the Collection.
* @throws ClassCastException
- * when an element in the Collection does not implement
+ * when an element in the collection does not implement
* {@code Comparable} or elements cannot be compared to each
* other.
- * @since Android 1.0
*/
public static <T extends Object & Comparable<? super T>> T max(
Collection<? extends T> collection) {
@@ -1642,18 +1669,17 @@
}
/**
- * Searches the specified Collection for the maximum element using the
- * specified Comparator.
- *
+ * Searches the specified collection for the maximum element using the
+ * specified comparator.
+ *
* @param collection
- * the Collection to search.
+ * the collection to search.
* @param comparator
- * the Comparator.
+ * the comparator.
* @return the maximum element in the Collection.
* @throws ClassCastException
- * when elements in the Collection cannot be compared to each
+ * when elements in the collection cannot be compared to each
* other using the {@code Comparator}.
- * @since Android 1.0
*/
public static <T> T max(Collection<? extends T> collection,
Comparator<? super T> comparator) {
@@ -1669,16 +1695,15 @@
}
/**
- * Searches the specified Collection for the minimum element.
- *
+ * Searches the specified collection for the minimum element.
+ *
* @param collection
- * the Collection to search.
- * @return the minimum element in the Collection.
+ * the collection to search.
+ * @return the minimum element in the collection.
* @throws ClassCastException
- * when an element in the Collection does not implement
+ * when an element in the collection does not implement
* {@code Comparable} or elements cannot be compared to each
* other.
- * @since Android 1.0
*/
public static <T extends Object & Comparable<? super T>> T min(
Collection<? extends T> collection) {
@@ -1694,18 +1719,17 @@
}
/**
- * Searches the specified Collection for the minimum element using the
- * specified Comparator.
- *
+ * Searches the specified collection for the minimum element using the
+ * specified comparator.
+ *
* @param collection
- * the Collection to search.
+ * the collection to search.
* @param comparator
- * the Comparator.
- * @return the minimum element in the Collection.
+ * the comparator.
+ * @return the minimum element in the collection.
* @throws ClassCastException
- * when elements in the Collection cannot be compared to each
+ * when elements in the collection cannot be compared to each
* other using the {@code Comparator}.
- * @since Android 1.0
*/
public static <T> T min(Collection<? extends T> collection,
Comparator<? super T> comparator) {
@@ -1721,17 +1745,16 @@
}
/**
- * Returns a List containing the specified number of the specified element.
+ * Returns a list containing the specified number of the specified element.
* The list cannot be modified. The list is serializable.
- *
+ *
* @param length
* the size of the returned list.
* @param object
* the element to be added {@code length} times to a list.
- * @return a List containing {@code length} copies of the element.
+ * @return a list containing {@code length} copies of the element.
* @throws IllegalArgumentException
* when {@code length < 0}.
- * @since Android 1.0
*/
public static <T> List<T> nCopies(final int length, T object) {
return new CopiesList<T>(length, object);
@@ -1740,12 +1763,11 @@
/**
* Modifies the specified {@code List} by reversing the order of the
* elements.
- *
+ *
* @param list
- * the List to reverse.
+ * the list to reverse.
* @throws UnsupportedOperationException
* when replacing an element in the List is not supported.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static void reverse(List<?> list) {
@@ -1762,14 +1784,13 @@
}
/**
- * A Comparator which reverses the natural order of the elements. The
+ * A comparator which reverses the natural order of the elements. The
* {@code Comparator} that's returned is {@link Serializable}.
- *
+ *
* @return a {@code Comparator} instance.
* @see Comparator
* @see Comparable
* @see Serializable
- * @since Android 1.0
*/
public static <T> Comparator<T> reverseOrder() {
return new ReverseComparator<T>();
@@ -1782,13 +1803,12 @@
* <p>
* The {@code Comparator} that's returned is {@link Serializable} if the
* {@code Comparator} passed is serializable or {@code null}.
- * </p>
- *
+ *
* @param c
* the {@code Comparator} to reverse or {@code null}.
* @return a {@code Comparator} instance.
* @see Comparator
- * @since Android 1.0
+ * @since 1.5
*/
public static <T> Comparator<T> reverseOrder(Comparator<T> c) {
if (c == null) {
@@ -1798,38 +1818,35 @@
}
/**
- * Moves every element of the List to a random new position in the list.
- *
+ * Moves every element of the list to a random new position in the list.
+ *
* @param list
* the List to shuffle.
- *
+ *
* @throws UnsupportedOperationException
* when replacing an element in the List is not supported.
- * @since Android 1.0
*/
public static void shuffle(List<?> list) {
shuffle(list, new Random());
}
/**
- * Moves every element of the List to a random new position in the list
+ * Moves every element of the list to a random new position in the list
* using the specified random number generator.
- *
+ *
* @param list
- * the List to shuffle.
+ * the list to shuffle.
* @param random
* the random number generator.
- *
* @throws UnsupportedOperationException
- * when replacing an element in the List is not supported.
- * @since Android 1.0
+ * when replacing an element in the list is not supported.
*/
@SuppressWarnings("unchecked")
public static void shuffle(List<?> list, Random random) {
if (!(list instanceof RandomAccess)) {
Object[] array = list.toArray();
for (int i = array.length - 1; i > 0; i--) {
- int index = random.nextInt() % (i + 1);
+ int index = random.nextInt(i + 1);
if (index < 0) {
index = -index;
}
@@ -1848,7 +1865,7 @@
} else {
List<Object> rawList = (List<Object>) list;
for (int i = rawList.size() - 1; i > 0; i--) {
- int index = random.nextInt() % (i + 1);
+ int index = random.nextInt(i + 1);
if (index < 0) {
index = -index;
}
@@ -1858,26 +1875,24 @@
}
/**
- * Returns a Set containing the specified element. The set cannot be
+ * Returns a set containing the specified element. The set cannot be
* modified. The set is serializable.
- *
+ *
* @param object
* the element.
- * @return a Set containing the element.
- * @since Android 1.0
+ * @return a set containing the element.
*/
public static <E> Set<E> singleton(E object) {
return new SingletonSet<E>(object);
}
/**
- * Returns a List containing the specified element. The list cannot be
+ * Returns a list containing the specified element. The list cannot be
* modified. The list is serializable.
- *
+ *
* @param object
* the element.
- * @return a List containing the element.
- * @since Android 1.0
+ * @return a list containing the element.
*/
public static <E> List<E> singletonList(E object) {
return new SingletonList<E>(object);
@@ -1886,28 +1901,26 @@
/**
* Returns a Map containing the specified key and value. The map cannot be
* modified. The map is serializable.
- *
+ *
* @param key
* the key.
* @param value
* the value.
* @return a Map containing the key and value.
- * @since Android 1.0
*/
public static <K, V> Map<K, V> singletonMap(K key, V value) {
return new SingletonMap<K, V>(key, value);
}
/**
- * Sorts the specified List in ascending natural order. The algorithm is
+ * Sorts the specified list in ascending natural order. The algorithm is
* stable which means equal elements don't get reordered.
- *
+ *
* @param list
- * the List to be sorted.
+ * the list to be sorted.
* @throws ClassCastException
* when an element in the List does not implement Comparable or
* elements cannot be compared to each other.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void sort(List<T> list) {
@@ -1922,17 +1935,16 @@
}
/**
- * Sorts the specified List using the specified Comparator. The algorithm is
+ * Sorts the specified list using the specified comparator. The algorithm is
* stable which means equal elements don't get reordered.
- *
+ *
* @param list
- * the List to be sorted.
+ * the list to be sorted.
* @param comparator
- * the Comparator.
+ * the comparator.
* @throws ClassCastException
- * when elements in the List cannot be compared to each other
- * using the Comparator.
- * @since Android 1.0
+ * when elements in the list cannot be compared to each other
+ * using the comparator.
*/
@SuppressWarnings("unchecked")
public static <T> void sort(List<T> list, Comparator<? super T> comparator) {
@@ -1947,26 +1959,30 @@
}
/**
- * Swaps the elements of List {@code list} at indices {@code index1} and
+ * Swaps the elements of list {@code list} at indices {@code index1} and
* {@code index2}.
- *
+ *
* @param list
- * the List to manipulate.
+ * the list to manipulate.
* @param index1
* position of the first element to swap with the element in
* index2.
* @param index2
* position of the other element.
- *
+ *
* @throws IndexOutOfBoundsException
* if index1 or index2 is out of range of this list.
- * @since Android 1.0
+ * @since 1.4
*/
@SuppressWarnings("unchecked")
public static void swap(List<?> list, int index1, int index2) {
if (list == null) {
throw new NullPointerException();
}
+ final int size = list.size();
+ if (index1 < 0 || index1 >= size || index2 < 0 || index2 >= size) {
+ throw new IndexOutOfBoundsException();
+ }
if (index1 == index2) {
return;
}
@@ -1978,20 +1994,18 @@
* Replaces all occurrences of Object {@code obj} in {@code list} with
* {@code newObj}. If the {@code obj} is {@code null}, then all
* occurrences of {@code null} are replaced with {@code newObj}.
- *
+ *
* @param list
- * the List to modify.
+ * the list to modify.
* @param obj
- * the Object to find and replace occurrences of.
+ * the object to find and replace occurrences of.
* @param obj2
- * the Object to replace all occurrences of {@code obj} in
+ * the object to replace all occurrences of {@code obj} in
* {@code list}.
* @return true, if at least one occurrence of {@code obj} has been found in
* {@code list}.
- *
* @throws UnsupportedOperationException
* if the list does not support setting elements.
- * @since Android 1.0
*/
public static <T> boolean replaceAll(List<T> list, T obj, T obj2) {
int index;
@@ -2005,19 +2019,17 @@
}
/**
- * Rotates the elements in List {@code list} by the distance {@code dist}
+ * Rotates the elements in {@code list} by the distance {@code dist}
* <p>
* e.g. for a given list with elements [1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
* calling rotate(list, 3) or rotate(list, -7) would modify the list to look
* like this: [8, 9, 0, 1, 2, 3, 4, 5, 6, 7]
- * </p>
- *
+ *
* @param lst
* the list whose elements are to be rotated.
* @param dist
* is the distance the list is rotated. This can be any valid
* integer. Negative values rotate the list backwards.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static void rotate(List<?> lst, int dist) {
@@ -2069,14 +2081,13 @@
* index of the first occurrence.
* <p>
* -1 is returned if the {@code sublist} does not exist in {@code list}.
- *
+ *
* @param list
* the List to search {@code sublist} in.
* @param sublist
* the List to search in {@code list}.
* @return the beginning index of the first occurrence of {@code sublist} in
* {@code list}, or -1.
- * @since Android 1.0
*/
public static int indexOfSubList(List<?> list, List<?> sublist) {
int size = list.size();
@@ -2137,14 +2148,13 @@
* index of the last occurrence.
* <p>
* -1 is returned if the {@code sublist} does not exist in {@code list}.
- *
+ *
* @param list
- * the List to search {@code sublist} in.
+ * the list to search {@code sublist} in.
* @param sublist
- * the List to search in {@code list}.
+ * the list to search in {@code list}.
* @return the beginning index of the last occurrence of {@code sublist} in
* {@code list}, or -1.
- * @since Android 1.0
*/
public static int lastIndexOfSubList(List<?> list, List<?> sublist) {
int sublistSize = sublist.size();
@@ -2198,14 +2208,13 @@
}
/**
- * Returns an {@code ArrayList} with all the elements in the
- * {@code enumeration}. The elements in the returned ArrayList are in the
+ * Returns an {@code ArrayList} with all the elements in the {@code
+ * enumeration}. The elements in the returned {@code ArrayList} are in the
* same order as in the {@code enumeration}.
- *
+ *
* @param enumeration
* the source {@link Enumeration}.
* @return an {@code ArrayList} from {@code enumeration}.
- * @since Android 1.0
*/
public static <T> ArrayList<T> list(Enumeration<T> enumeration) {
ArrayList<T> list = new ArrayList<T>();
@@ -2216,13 +2225,12 @@
}
/**
- * Returns a wrapper on the specified Collection which synchronizes all
- * access to the Collection.
- *
+ * Returns a wrapper on the specified collection which synchronizes all
+ * access to the collection.
+ *
* @param collection
* the Collection to wrap in a synchronized collection.
* @return a synchronized Collection.
- * @since Android 1.0
*/
public static <T> Collection<T> synchronizedCollection(
Collection<T> collection) {
@@ -2235,11 +2243,10 @@
/**
* Returns a wrapper on the specified List which synchronizes all access to
* the List.
- *
+ *
* @param list
* the List to wrap in a synchronized list.
* @return a synchronized List.
- * @since Android 1.0
*/
public static <T> List<T> synchronizedList(List<T> list) {
if (list == null) {
@@ -2252,13 +2259,12 @@
}
/**
- * Returns a wrapper on the specified Map which synchronizes all access to
- * the Map.
- *
+ * Returns a wrapper on the specified map which synchronizes all access to
+ * the map.
+ *
* @param map
- * the Map to wrap in a synchronized map.
+ * the map to wrap in a synchronized map.
* @return a synchronized Map.
- * @since Android 1.0
*/
public static <K, V> Map<K, V> synchronizedMap(Map<K, V> map) {
if (map == null) {
@@ -2268,13 +2274,12 @@
}
/**
- * Returns a wrapper on the specified Set which synchronizes all access to
- * the Set.
- *
+ * Returns a wrapper on the specified set which synchronizes all access to
+ * the set.
+ *
* @param set
- * the Set to wrap in a synchronized set.
- * @return a synchronized Set.
- * @since Android 1.0
+ * the set to wrap in a synchronized set.
+ * @return a synchronized set.
*/
public static <E> Set<E> synchronizedSet(Set<E> set) {
if (set == null) {
@@ -2284,13 +2289,12 @@
}
/**
- * Returns a wrapper on the specified SortedMap which synchronizes all
- * access to the SortedMap.
- *
+ * Returns a wrapper on the specified sorted map which synchronizes all
+ * access to the sorted map.
+ *
* @param map
- * the SortedMap to wrap in a synchronized sorted map.
- * @return a synchronized SortedMap.
- * @since Android 1.0
+ * the sorted map to wrap in a synchronized sorted map.
+ * @return a synchronized sorted map.
*/
public static <K, V> SortedMap<K, V> synchronizedSortedMap(
SortedMap<K, V> map) {
@@ -2301,13 +2305,12 @@
}
/**
- * Returns a wrapper on the specified SortedSet which synchronizes all
- * access to the SortedSet.
- *
+ * Returns a wrapper on the specified sorted set which synchronizes all
+ * access to the sorted set.
+ *
* @param set
- * the SortedSet to wrap in a synchronized sorted set.
- * @return a synchronized SortedSet.
- * @since Android 1.0
+ * the sorted set to wrap in a synchronized sorted set.
+ * @return a synchronized sorted set.
*/
public static <E> SortedSet<E> synchronizedSortedSet(SortedSet<E> set) {
if (set == null) {
@@ -2317,14 +2320,13 @@
}
/**
- * Returns a wrapper on the specified Collection which throws an
+ * Returns a wrapper on the specified collection which throws an
* {@code UnsupportedOperationException} whenever an attempt is made to
- * modify the Collection.
- *
+ * modify the collection.
+ *
* @param collection
- * the Collection to wrap in an unmodifiable collection.
- * @return an unmodifiable Collection.
- * @since Android 1.0
+ * the collection to wrap in an unmodifiable collection.
+ * @return an unmodifiable collection.
*/
@SuppressWarnings("unchecked")
public static <E> Collection<E> unmodifiableCollection(
@@ -2336,14 +2338,13 @@
}
/**
- * Returns a wrapper on the specified List which throws an
+ * Returns a wrapper on the specified list which throws an
* {@code UnsupportedOperationException} whenever an attempt is made to
- * modify the List.
- *
+ * modify the list.
+ *
* @param list
- * the List to wrap in an unmodifiable list.
+ * the list to wrap in an unmodifiable list.
* @return an unmodifiable List.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static <E> List<E> unmodifiableList(List<? extends E> list) {
@@ -2357,14 +2358,13 @@
}
/**
- * Returns a wrapper on the specified Map which throws an
+ * Returns a wrapper on the specified map which throws an
* {@code UnsupportedOperationException} whenever an attempt is made to
- * modify the Map.
- *
+ * modify the map.
+ *
* @param map
- * the Map to wrap in an unmodifiable map.
- * @return a unmodifiable Map.
- * @since Android 1.0
+ * the map to wrap in an unmodifiable map.
+ * @return a unmodifiable map.
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> unmodifiableMap(
@@ -2376,14 +2376,13 @@
}
/**
- * Returns a wrapper on the specified Set which throws an
+ * Returns a wrapper on the specified set which throws an
* {@code UnsupportedOperationException} whenever an attempt is made to
- * modify the Set.
- *
+ * modify the set.
+ *
* @param set
- * the Set to wrap in an unmodifiable set.
- * @return a unmodifiable Set.
- * @since Android 1.0
+ * the set to wrap in an unmodifiable set.
+ * @return a unmodifiable set
*/
@SuppressWarnings("unchecked")
public static <E> Set<E> unmodifiableSet(Set<? extends E> set) {
@@ -2394,14 +2393,13 @@
}
/**
- * Returns a wrapper on the specified SortedMap which throws an
+ * Returns a wrapper on the specified sorted map which throws an
* {@code UnsupportedOperationException} whenever an attempt is made to
- * modify the SortedMap.
- *
+ * modify the sorted map.
+ *
* @param map
- * the SortedMap to wrap in an unmodifiable sorted map.
- * @return a unmodifiable SortedMap.
- * @since Android 1.0
+ * the sorted map to wrap in an unmodifiable sorted map.
+ * @return a unmodifiable sorted map
*/
@SuppressWarnings("unchecked")
public static <K, V> SortedMap<K, V> unmodifiableSortedMap(
@@ -2413,14 +2411,13 @@
}
/**
- * Returns a wrapper on the specified SortedSet which throws an
+ * Returns a wrapper on the specified sorted set which throws an
* {@code UnsupportedOperationException} whenever an attempt is made to
- * modify the SortedSet.
- *
+ * modify the sorted set.
+ *
* @param set
- * the SortedSet to wrap in an unmodifiable sorted set.
- * @return a unmodifiable SortedSet.
- * @since Android 1.0
+ * the sorted set to wrap in an unmodifiable sorted set.
+ * @return a unmodifiable sorted set.
*/
public static <E> SortedSet<E> unmodifiableSortedSet(SortedSet<E> set) {
if (set == null) {
@@ -2433,8 +2430,7 @@
* Returns the number of elements in the {@code Collection} that match the
* {@code Object} passed. If the {@code Object} is {@code null}, then the
* number of {@code null} elements is returned.
- * </p>
- *
+ *
* @param c
* the {@code Collection} to search.
* @param o
@@ -2442,7 +2438,7 @@
* @return the number of matching elements.
* @throws NullPointerException
* if the {@code Collection} parameter is {@code null}.
- * @since Android 1.0
+ * @since 1.5
*/
public static int frequency(Collection<?> c, Object o) {
if (c == null) {
@@ -2464,10 +2460,10 @@
/**
* Returns a type-safe empty, immutable {@link List}.
- *
+ *
* @return an empty {@link List}.
+ * @since 1.5
* @see #EMPTY_LIST
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
@@ -2476,10 +2472,10 @@
/**
* Returns a type-safe empty, immutable {@link Set}.
- *
+ *
* @return an empty {@link Set}.
+ * @since 1.5
* @see #EMPTY_SET
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final <T> Set<T> emptySet() {
@@ -2488,10 +2484,10 @@
/**
* Returns a type-safe empty, immutable {@link Map}.
- *
+ *
* @return an empty {@link Map}.
+ * @since 1.5
* @see #EMPTY_MAP
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public static final <K, V> Map<K, V> emptyMap() {
@@ -2503,13 +2499,12 @@
* to insert an element of the wrong type into this collection throws a
* {@code ClassCastException}. At creation time the types in {@code c} are
* not checked for correct type.
- *
+ *
* @param c
* the collection to be wrapped in a typesafe collection.
* @param type
* the type of the elements permitted to insert.
* @return a typesafe collection.
- * @since Android 1.0
*/
public static <E> Collection<E> checkedCollection(Collection<E> c,
Class<E> type) {
@@ -2521,7 +2516,7 @@
* insert an element of the wrong type into this map throws a
* {@code ClassCastException}. At creation time the types in {@code m} are
* not checked for correct type.
- *
+ *
* @param m
* the map to be wrapped in a typesafe map.
* @param keyType
@@ -2529,7 +2524,6 @@
* @param valueType
* the type of the values permitted to insert.
* @return a typesafe map.
- * @since Android 1.0
*/
public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType,
Class<V> valueType) {
@@ -2541,13 +2535,12 @@
* insert an element of the wrong type into this list throws a
* {@code ClassCastException}. At creation time the types in {@code list}
* are not checked for correct type.
- *
+ *
* @param list
* the list to be wrapped in a typesafe list.
* @param type
* the type of the elements permitted to insert.
* @return a typesafe list.
- * @since Android 1.0
*/
public static <E> List<E> checkedList(List<E> list, Class<E> type) {
if (list instanceof RandomAccess) {
@@ -2561,13 +2554,12 @@
* insert an element of the wrong type into this set throws a
* {@code ClassCastException}. At creation time the types in {@code s} are
* not checked for correct type.
- *
+ *
* @param s
* the set to be wrapped in a typesafe set.
* @param type
* the type of the elements permitted to insert.
* @return a typesafe set.
- * @since Android 1.0
*/
public static <E> Set<E> checkedSet(Set<E> s, Class<E> type) {
return new CheckedSet<E>(s, type);
@@ -2578,7 +2570,7 @@
* to insert an element of the wrong type into this sorted map throws a
* {@code ClassCastException}. At creation time the types in {@code m} are
* not checked for correct type.
- *
+ *
* @param m
* the sorted map to be wrapped in a typesafe sorted map.
* @param keyType
@@ -2586,7 +2578,6 @@
* @param valueType
* the type of the values permitted to insert.
* @return a typesafe sorted map.
- * @since Android 1.0
*/
public static <K, V> SortedMap<K, V> checkedSortedMap(SortedMap<K, V> m,
Class<K> keyType, Class<V> valueType) {
@@ -2598,13 +2589,12 @@
* to insert an element of the wrong type into this sorted set throws a
* {@code ClassCastException}. At creation time the types in {@code s} are
* not checked for correct type.
- *
+ *
* @param s
* the sorted set to be wrapped in a typesafe sorted set.
* @param type
* the type of the elements permitted to insert.
* @return a typesafe sorted set.
- * @since Android 1.0
*/
public static <E> SortedSet<E> checkedSortedSet(SortedSet<E> s,
Class<E> type) {
@@ -2613,7 +2603,7 @@
/**
* Adds all the specified elements to the specified collection.
- *
+ *
* @param c
* the collection the elements are to be inserted into.
* @param a
@@ -2628,7 +2618,6 @@
* @throws IllegalArgumentException
* if at least one of the elements can't be inserted into the
* collection.
- * @since Android 1.0
*/
public static <T> boolean addAll(Collection<? super T> c, T... a) {
boolean modified = false;
@@ -2640,7 +2629,7 @@
/**
* Returns whether the specified collections have no elements in common.
- *
+ *
* @param c1
* the first collection.
* @param c2
@@ -2649,7 +2638,6 @@
* {@code false} otherwise.
* @throws NullPointerException
* if one of the collections is {@code null}.
- * @since Android 1.0
*/
public static boolean disjoint(Collection<?> c1, Collection<?> c2) {
if ((c1 instanceof Set) && !(c2 instanceof Set)
@@ -2670,7 +2658,7 @@
/**
* Checks if specified object is instance of specified class. Used for a
* dynamically typesafe view of the collections.
- *
+ *
* @param obj -
* object is to be checked
* @param type -
@@ -2701,7 +2689,7 @@
/**
* Constructs a dynamically typesafe view of the specified collection.
- *
+ *
* @param c -
* the collection for which an unmodifiable view is to be
* constructed.
@@ -2844,7 +2832,7 @@
/**
* Constructs a dynamically typesafe view of the specified ListIterator.
- *
+ *
* @param i -
* the listIterator for which a dynamically typesafe view to
* be constructed.
@@ -2930,7 +2918,7 @@
/**
* Constructs a dynamically typesafe view of the specified list.
- *
+ *
* @param l -
* the list for which a dynamically typesafe view is to be
* constructed.
@@ -3049,7 +3037,7 @@
/**
* Constructs a dynamically typesafe view of the specified
* randomAccessList.
- *
+ *
* @param l -
* the randomAccessList for which a dynamically typesafe view
* is to be constructed.
@@ -3069,7 +3057,7 @@
/**
* Constructs a dynamically typesafe view of the specified set.
- *
+ *
* @param s -
* the set for which a dynamically typesafe view is to be
* constructed.
@@ -3111,7 +3099,7 @@
/**
* Constructs a dynamically typesafe view of the specified map.
- *
+ *
* @param m -
* the map for which a dynamically typesafe view is to be
* constructed.
@@ -3262,10 +3250,12 @@
/**
* Constructs a dynamically typesafe view of the specified map
* entry.
- *
- * @param e -
+ *
+ * @param e
* the map entry for which a dynamically typesafe view is
* to be constructed.
+ * @param valueType
+ * the type of the value
*/
public CheckedEntry(Map.Entry<K, V> e, Class<V> valueType) {
if (e == null) {
diff --git a/luni/src/main/java/java/util/Comparator.java b/luni/src/main/java/java/util/Comparator.java
index 7b09448..2d6f598 100644
--- a/luni/src/main/java/java/util/Comparator.java
+++ b/luni/src/main/java/java/util/Comparator.java
@@ -25,8 +25,8 @@
* method has to return zero for each pair of elements (a,b) where a.equals(b)
* holds true. It is recommended that a {@code Comparator} implements
* {@link java.io.Serializable}.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public interface Comparator<T> {
/**
@@ -42,15 +42,15 @@
* follow {@code compare(a,c) > 0} for all possible combinations of {@code
* (a,b,c)}</li>
* </ul>
- *
+ *
* @param object1
* an {@code Object}.
* @param object2
* a second {@code Object} to compare with {@code object1}.
* @return an integer < 0 if {@code object1} is less than {@code object2}, 0 if they are
* equal, and > 0 if {@code object1} is greater than {@code object2}.
- * @exception ClassCastException
- * when objects are not of the correct type.
+ * @throws ClassCastException
+ * if objects are not of the correct type.
*/
public int compare(T object1, T object2);
@@ -61,7 +61,7 @@
* <p>
* A {@code Comparator} never needs to override this method, but may choose so for
* performance reasons.
- *
+ *
* @param object
* the {@code Object} to compare with this comparator.
* @return boolean {@code true} if specified {@code Object} is the same as this
diff --git a/luni/src/main/java/java/util/Currency.java b/luni/src/main/java/java/util/Currency.java
index 8ac0e6e..79de49d 100644
--- a/luni/src/main/java/java/util/Currency.java
+++ b/luni/src/main/java/java/util/Currency.java
@@ -17,15 +17,15 @@
package java.util;
-import java.io.Serializable;
-
+// BEGIN android-added
import org.apache.harmony.luni.util.Msg;
+// END android-added
+
+import java.io.Serializable;
/**
* This class represents a currency as identified in the ISO 4217 currency
* codes.
- *
- * @since Android 1.0
*/
public final class Currency implements Serializable {
@@ -35,9 +35,11 @@
private String currencyCode;
+ // BEGIN android-added
private static String currencyVars = "EURO, HK, PREEURO"; //$NON-NLS-1$
private transient int defaultFractionDigits;
+ // END android-added
/**
* @param currencyCode
@@ -49,20 +51,20 @@
/**
* Returns the {@code Currency} instance for this currency code.
* <p>
- *
+ *
* @param currencyCode
* the currency code.
* @return the {@code Currency} instance for this currency code.
- *
+ *
* @throws IllegalArgumentException
* if the currency code is not a supported ISO 4217 currency
* code.
- * @since Android 1.0
*/
public static Currency getInstance(String currencyCode) {
Currency currency = codesToCurrencies.get(currencyCode);
if (currency == null) {
+ // BEGIN android-added
ResourceBundle bundle = Locale.getBundle(
"ISO4CurrenciesToDigits", Locale.getDefault()); //$NON-NLS-1$
currency = new Currency(currencyCode);
@@ -77,6 +79,7 @@
}
currency.defaultFractionDigits = Integer
.parseInt(defaultFractionDigits);
+ // END android-added
codesToCurrencies.put(currencyCode, currency);
}
@@ -85,16 +88,26 @@
/**
* Returns the {@code Currency} instance for this {@code Locale}'s country.
- *
+ *
* @param locale
* the {@code Locale} of a country.
* @return the {@code Currency} used in the country defined by the locale parameter.
- *
+ *
* @throws IllegalArgumentException
* if the locale's country is not a supported ISO 3166 Country.
- * @since Android 1.0
*/
public static Currency getInstance(Locale locale) {
+ // BEGIN android-changed
+ // com.ibm.icu.util.Currency currency = null;
+ // try {
+ // currency = com.ibm.icu.util.Currency.getInstance(locale);
+ // } catch (IllegalArgumentException e) {
+ // return null;
+ // }
+ // if (currency == null) {
+ // throw new IllegalArgumentException(locale.getCountry());
+ // }
+ // String currencyCode = currency.getCurrencyCode();
String country = locale.getCountry();
String variant = locale.getVariant();
if (!variant.equals("") && currencyVars.indexOf(variant) > -1) { //$NON-NLS-1$
@@ -110,6 +123,7 @@
throw new IllegalArgumentException(Msg.getString(
"K0323", locale.toString())); //$NON-NLS-1$
}
+ // END android-changed
if (currencyCode.equals("None")) { //$NON-NLS-1$
return null;
@@ -120,9 +134,8 @@
/**
* Returns this {@code Currency}'s ISO 4217 currency code.
- *
+ *
* @return this {@code Currency}'s ISO 4217 currency code.
- * @since Android 1.0
*/
public String getCurrencyCode() {
return currencyCode;
@@ -133,9 +146,8 @@
* if the default locale is the US, the symbol of the US dollar is "$". For
* other locales it may be "US$". If no symbol can be determined, the ISO
* 4217 currency code of the US dollar is returned.
- *
+ *
* @return the symbol for this {@code Currency} in the default {@code Locale}.
- * @since Android 1.0
*/
public String getSymbol() {
return getSymbol(Locale.getDefault());
@@ -157,18 +169,19 @@
* symbol for this currency in this bundle, then the
* ISO 4217 currency code is returned.
* <p>
- *
+ *
* @param locale
* the locale for which the currency symbol should be returned.
* @return the representation of this {@code Currency}'s symbol in the specified
* locale.
- * @since Android 1.0
*/
public String getSymbol(Locale locale) {
if (locale.getCountry().equals("")) { //$NON-NLS-1$
return currencyCode;
}
+ // BEGIN android-changed
+ // return com.ibm.icu.util.Currency.getInstance(currencyCode).getSymbol(locale);
// check in the Locale bundle first, if the local has the same currency
ResourceBundle bundle = Locale.getBundle("Locale", locale); //$NON-NLS-1$
if (((String) bundle.getObject("IntCurrencySymbol")) //$NON-NLS-1$
@@ -197,6 +210,7 @@
return result;
}
return currencyCode;
+ // END android-changed
}
/**
@@ -204,19 +218,20 @@
* instance, the default number of fraction digits for the US dollar is 2.
* For the Japanese Yen the number is 0. In the case of pseudo-currencies,
* such as IMF Special Drawing Rights, -1 is returned.
- *
+ *
* @return the default number of fraction digits for this currency.
- * @since Android 1.0
*/
public int getDefaultFractionDigits() {
+ // BEGIN android-changed
+ // return com.ibm.icu.util.Currency.getInstance(currencyCode).getDefaultFractionDigits();
return defaultFractionDigits;
+ // END android-changed
}
/**
* Returns this currency's ISO 4217 currency code.
- *
+ *
* @return this currency's ISO 4217 currency code.
- * @since Android 1.0
*/
@Override
public String toString() {
diff --git a/luni/src/main/java/java/util/Date.java b/luni/src/main/java/java/util/Date.java
index 172f682..7bd7261 100644
--- a/luni/src/main/java/java/util/Date.java
+++ b/luni/src/main/java/java/util/Date.java
@@ -29,13 +29,12 @@
/**
* {@code Date} represents a specific moment in time, to the millisecond.
- *
+ *
* @see System#currentTimeMillis
* @see Calendar
* @see GregorianCalendar
* @see SimpleTimeZone
* @see TimeZone
- * @since Android 1.0
*/
public class Date implements Serializable, Cloneable, Comparable<Date> {
@@ -46,10 +45,15 @@
private transient long milliseconds;
+ private static String[] dayOfWeekNames = { "Sun", "Mon", "Tue", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "Wed", "Thu", "Fri", "Sat" }; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ private static String[] monthNames = { "Jan", "Feb", "Mar", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ "Apr", "May", "Jun", "Jul", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ "Aug", "Sep", "Oct", "Nov", "Dec"}; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
/**
* Initializes this {@code Date} instance to the current date and time.
- *
- * @since Android 1.0
*/
public Date() {
this(System.currentTimeMillis());
@@ -58,17 +62,16 @@
/**
* Constructs a new {@code Date} initialized to midnight in the default {@code TimeZone} on
* the specified date.
- *
+ *
* @param year
* the year, 0 is 1900.
* @param month
* the month, 0 - 11.
* @param day
* the day of the month, 1 - 31.
- *
+ *
* @deprecated use
* {@link GregorianCalendar#GregorianCalendar(int, int, int)}
- * @since Android 1.0
*/
@Deprecated
public Date(int year, int month, int day) {
@@ -80,7 +83,7 @@
/**
* Constructs a new {@code Date} initialized to the specified date and time in the
* default {@code TimeZone}.
- *
+ *
* @param year
* the year, 0 is 1900.
* @param month
@@ -91,10 +94,9 @@
* the hour of day, 0 - 23.
* @param minute
* the minute of the hour, 0 - 59.
- *
+ *
* @deprecated use
* {@link GregorianCalendar#GregorianCalendar(int, int, int, int, int)}
- * @since Android 1.0
*/
@Deprecated
public Date(int year, int month, int day, int hour, int minute) {
@@ -106,7 +108,7 @@
/**
* Constructs a new {@code Date} initialized to the specified date and time in the
* default {@code TimeZone}.
- *
+ *
* @param year
* the year, 0 is 1900.
* @param month
@@ -119,10 +121,9 @@
* the minute of the hour, 0 - 59.
* @param second
* the second of the minute, 0 - 59.
- *
+ *
* @deprecated use
* {@link GregorianCalendar#GregorianCalendar(int, int, int, int, int, int)}
- * @since Android 1.0
*/
@Deprecated
public Date(int year, int month, int day, int hour, int minute, int second) {
@@ -134,24 +135,22 @@
/**
* Initializes this {@code Date} instance using the specified millisecond value. The
* value is the number of milliseconds since Jan. 1, 1970 GMT.
- *
+ *
* @param milliseconds
* the number of milliseconds since Jan. 1, 1970 GMT.
- * @since Android 1.0
*/
public Date(long milliseconds) {
- this.setTime(milliseconds);
+ this.milliseconds = milliseconds;
}
/**
* Constructs a new {@code Date} initialized to the date and time parsed from the
* specified String.
- *
+ *
* @param string
* the String to parse.
- *
+ *
* @deprecated use {@link DateFormat}
- * @since Android 1.0
*/
@Deprecated
public Date(String string) {
@@ -160,12 +159,11 @@
/**
* Returns if this {@code Date} is after the specified Date.
- *
+ *
* @param date
* a Date instance to compare.
* @return {@code true} if this {@code Date} is after the specified {@code Date},
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean after(Date date) {
return milliseconds > date.milliseconds;
@@ -173,12 +171,11 @@
/**
* Returns if this {@code Date} is before the specified Date.
- *
+ *
* @param date
* a {@code Date} instance to compare.
* @return {@code true} if this {@code Date} is before the specified {@code Date},
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean before(Date date) {
return milliseconds < date.milliseconds;
@@ -186,11 +183,10 @@
/**
* Returns a new {@code Date} with the same millisecond value as this {@code Date}.
- *
+ *
* @return a shallow copy of this {@code Date}.
- *
+ *
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -204,12 +200,11 @@
/**
* Compare the receiver to the specified {@code Date} to determine the relative
* ordering.
- *
+ *
* @param date
* a {@code Date} to compare against.
* @return an {@code int < 0} if this {@code Date} is less than the specified {@code Date}, {@code 0} if
* they are equal, and an {@code int > 0} if this {@code Date} is greater.
- * @since Android 1.0
*/
public int compareTo(Date date) {
if (milliseconds < date.milliseconds) {
@@ -225,14 +220,13 @@
* Compares the specified object to this {@code Date} and returns if they are equal.
* To be equal, the object must be an instance of {@code Date} and have the same millisecond
* value.
- *
+ *
* @param object
* the object to compare with this object.
* @return {@code true} if the specified object is equal to this {@code Date}, {@code false}
* otherwise.
- *
+ *
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -242,11 +236,10 @@
/**
* Returns the gregorian calendar day of the month for this {@code Date} object.
- *
+ *
* @return the day of the month.
- *
+ *
* @deprecated use {@code Calendar.get(Calendar.DATE)}
- * @since Android 1.0
*/
@Deprecated
public int getDate() {
@@ -255,11 +248,10 @@
/**
* Returns the gregorian calendar day of the week for this {@code Date} object.
- *
+ *
* @return the day of the week.
- *
+ *
* @deprecated use {@code Calendar.get(Calendar.DAY_OF_WEEK)}
- * @since Android 1.0
*/
@Deprecated
public int getDay() {
@@ -268,11 +260,10 @@
/**
* Returns the gregorian calendar hour of the day for this {@code Date} object.
- *
+ *
* @return the hour of the day.
- *
+ *
* @deprecated use {@code Calendar.get(Calendar.HOUR_OF_DAY)}
- * @since Android 1.0
*/
@Deprecated
public int getHours() {
@@ -281,11 +272,10 @@
/**
* Returns the gregorian calendar minute of the hour for this {@code Date} object.
- *
+ *
* @return the minutes.
- *
+ *
* @deprecated use {@code Calendar.get(Calendar.MINUTE)}
- * @since Android 1.0
*/
@Deprecated
public int getMinutes() {
@@ -294,11 +284,10 @@
/**
* Returns the gregorian calendar month for this {@code Date} object.
- *
+ *
* @return the month.
- *
+ *
* @deprecated use {@code Calendar.get(Calendar.MONTH)}
- * @since Android 1.0
*/
@Deprecated
public int getMonth() {
@@ -307,11 +296,10 @@
/**
* Returns the gregorian calendar second of the minute for this {@code Date} object.
- *
+ *
* @return the seconds.
- *
+ *
* @deprecated use {@code Calendar.get(Calendar.SECOND)}
- * @since Android 1.0
*/
@Deprecated
public int getSeconds() {
@@ -321,9 +309,8 @@
/**
* Returns this {@code Date} as a millisecond value. The value is the number of
* milliseconds since Jan. 1, 1970, midnight GMT.
- *
+ *
* @return the number of milliseconds since Jan. 1, 1970, midnight GMT.
- * @since Android 1.0
*/
public long getTime() {
return milliseconds;
@@ -331,12 +318,11 @@
/**
* Returns the timezone offset in minutes of the default {@code TimeZone}.
- *
+ *
* @return the timezone offset in minutes of the default {@code TimeZone}.
- *
+ *
* @deprecated use
* {@code (Calendar.get(Calendar.ZONE_OFFSET) + Calendar.get(Calendar.DST_OFFSET)) / 60000}
- * @since Android 1.0
*/
@Deprecated
public int getTimezoneOffset() {
@@ -346,11 +332,10 @@
/**
* Returns the gregorian calendar year since 1900 for this {@code Date} object.
- *
+ *
* @return the year - 1900.
- *
+ *
* @deprecated use {@code Calendar.get(Calendar.YEAR) - 1900}
- * @since Android 1.0
*/
@Deprecated
public int getYear() {
@@ -360,11 +345,10 @@
/**
* Returns an integer hash code for the receiver. Objects which are equal
* return the same value for this method.
- *
+ *
* @return this {@code Date}'s hash.
- *
+ *
* @see #equals
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -384,13 +368,12 @@
* Returns the millisecond value of the date and time parsed from the
* specified {@code String}. Many date/time formats are recognized, including IETF
* standard syntax, i.e. Tue, 22 Jun 1999 12:16:00 GMT-0500
- *
+ *
* @param string
* the String to parse.
* @return the millisecond value parsed from the String.
- *
+ *
* @deprecated use {@link DateFormat}
- * @since Android 1.0
*/
@Deprecated
public static long parse(String string) {
@@ -404,7 +387,7 @@
int commentLevel = 0;
int offset = 0, length = string.length(), state = 0;
int year = -1, month = -1, date = -1;
- int hour = -1, minute = -1, second = -1, zoneOffset = 0;
+ int hour = -1, minute = -1, second = -1, zoneOffset = 0, minutesOffset = 0;
boolean zone = false;
final int PAD = 0, LETTERS = 1, NUMBERS = 2;
StringBuffer buffer = new StringBuffer();
@@ -442,6 +425,14 @@
if (sign == '+' || sign == '-') {
if (zoneOffset == 0) {
zone = true;
+ if (next == ':') {
+ minutesOffset = sign == '-' ? -Integer
+ .parseInt(string.substring(offset,
+ offset + 2)) : Integer
+ .parseInt(string.substring(offset,
+ offset + 2));
+ offset += 2;
+ }
zoneOffset = sign == '-' ? -digit : digit;
sign = 0;
} else {
@@ -557,6 +548,7 @@
} else if (year < 100) {
year += 1900;
}
+ minute -= minutesOffset;
if (zone) {
if (zoneOffset >= 24 || zoneOffset <= -24) {
hour -= zoneOffset / 100;
@@ -574,12 +566,11 @@
/**
* Sets the gregorian calendar day of the month for this {@code Date} object.
- *
+ *
* @param day
* the day of the month.
- *
+ *
* @deprecated use {@code Calendar.set(Calendar.DATE, day)}
- * @since Android 1.0
*/
@Deprecated
public void setDate(int day) {
@@ -590,12 +581,11 @@
/**
* Sets the gregorian calendar hour of the day for this {@code Date} object.
- *
+ *
* @param hour
* the hour of the day.
- *
+ *
* @deprecated use {@code Calendar.set(Calendar.HOUR_OF_DAY, hour)}
- * @since Android 1.0
*/
@Deprecated
public void setHours(int hour) {
@@ -606,12 +596,11 @@
/**
* Sets the gregorian calendar minute of the hour for this {@code Date} object.
- *
+ *
* @param minute
* the minutes.
- *
+ *
* @deprecated use {@code Calendar.set(Calendar.MINUTE, minute)}
- * @since Android 1.0
*/
@Deprecated
public void setMinutes(int minute) {
@@ -622,12 +611,11 @@
/**
* Sets the gregorian calendar month for this {@code Date} object.
- *
+ *
* @param month
* the month.
- *
+ *
* @deprecated use {@code Calendar.set(Calendar.MONTH, month)}
- * @since Android 1.0
*/
@Deprecated
public void setMonth(int month) {
@@ -638,12 +626,11 @@
/**
* Sets the gregorian calendar second of the minute for this {@code Date} object.
- *
+ *
* @param second
* the seconds.
- *
+ *
* @deprecated use {@code Calendar.set(Calendar.SECOND, second)}
- * @since Android 1.0
*/
@Deprecated
public void setSeconds(int second) {
@@ -655,10 +642,9 @@
/**
* Sets this {@code Date} to the specified millisecond value. The value is the
* number of milliseconds since Jan. 1, 1970 GMT.
- *
+ *
* @param milliseconds
* the number of milliseconds since Jan. 1, 1970 GMT.
- * @since Android 1.0
*/
public void setTime(long milliseconds) {
this.milliseconds = milliseconds;
@@ -666,12 +652,11 @@
/**
* Sets the gregorian calendar year since 1900 for this {@code Date} object.
- *
+ *
* @param year
* the year since 1900.
- *
+ *
* @deprecated use {@code Calendar.set(Calendar.YEAR, year + 1900)}
- * @since Android 1.0
*/
@Deprecated
public void setYear(int year) {
@@ -683,11 +668,10 @@
/**
* Returns the string representation of this {@code Date} in GMT in the format: 22
* Jun 1999 13:02:00 GMT
- *
+ *
* @return the string representation of this {@code Date} in GMT.
- *
+ *
* @deprecated use {@link DateFormat}
- * @since Android 1.0
*/
@Deprecated
public String toGMTString() {
@@ -705,11 +689,10 @@
/**
* Returns the string representation of this {@code Date} for the default {@code Locale}.
- *
+ *
* @return the string representation of this {@code Date} for the default {@code Locale}.
- *
+ *
* @deprecated use {@link DateFormat}
- * @since Android 1.0
*/
@Deprecated
public String toLocaleString() {
@@ -719,20 +702,29 @@
/**
* Returns the string representation of this {@code Date} in the format: Tue Jun 22
* 13:07:00 GMT 1999
- *
+ *
* @return the string representation of this {@code Date}.
- * @since Android 1.0
*/
@Override
public String toString() {
- return new SimpleDateFormat("E MMM dd HH:mm:ss z ", Locale.US) //$NON-NLS-1$
- .format(this)
- + new GregorianCalendar(milliseconds).get(Calendar.YEAR);
+ Calendar cal = new GregorianCalendar(milliseconds);
+ return dayOfWeekNames[cal.get(Calendar.DAY_OF_WEEK) - 1] + " " + monthNames[cal.get(Calendar.MONTH)]//$NON-NLS-1$
+ + " " + toTwoDigits(cal.get(Calendar.DAY_OF_MONTH)) + " " + toTwoDigits(cal.get(Calendar.HOUR_OF_DAY))//$NON-NLS-1$ //$NON-NLS-2$
+ + ":" + toTwoDigits(cal.get(Calendar.MINUTE)) + ":" + toTwoDigits(cal.get(Calendar.SECOND))//$NON-NLS-1$ //$NON-NLS-2$
+ + " " + cal.getTimeZone().getID() + " " + cal.get(Calendar.YEAR);//$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private String toTwoDigits(int digit) {
+ if(digit >= 10) {
+ return "" + digit;//$NON-NLS-1$
+ } else {
+ return "0" + digit;//$NON-NLS-1$
+ }
}
/**
* Returns the millisecond value of the specified date and time in GMT.
- *
+ *
* @param year
* the year, 0 is 1900.
* @param month
@@ -746,12 +738,11 @@
* @param second
* the second of the minute, 0 - 59.
* @return the date and time in GMT in milliseconds.
- *
+ *
* @deprecated use: <code>
* Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
* cal.set(year + 1900, month, day, hour, minute, second);
* cal.getTime().getTime();</code>
- * @since Android 1.0
*/
@Deprecated
public static long UTC(int year, int month, int day, int hour, int minute,
diff --git a/luni/src/main/java/java/util/Dictionary.java b/luni/src/main/java/java/util/Dictionary.java
index 236ddf0..c29b11b 100644
--- a/luni/src/main/java/java/util/Dictionary.java
+++ b/luni/src/main/java/java/util/Dictionary.java
@@ -25,14 +25,11 @@
* associate keys with values, such as {@code Hashtable}.
*
* @see Hashtable
- * @since Android 1.0
+ * @since 1.0
*/
-public abstract class Dictionary<K,V> {
-
+public abstract class Dictionary<K, V> {
/**
* Constructs a new instance of this class.
- *
- * @since Android 1.0
*/
public Dictionary() {
super();
@@ -45,7 +42,6 @@
* @see #keys
* @see #size
* @see Enumeration
- * @since Android 1.0
*/
public abstract Enumeration<V> elements();
@@ -57,7 +53,6 @@
* @return the value associated with {@code key}, or {@code null} if the
* specified key does not exist.
* @see #put
- * @since Android 1.0
*/
public abstract V get(Object key);
@@ -67,7 +62,6 @@
* @return {@code true} if this dictionary has no key/value pairs,
* {@code false} otherwise.
* @see #size
- * @since Android 1.0
*/
public abstract boolean isEmpty();
@@ -78,7 +72,6 @@
* @see #elements
* @see #size
* @see Enumeration
- * @since Android 1.0
*/
public abstract Enumeration<K> keys();
@@ -96,7 +89,6 @@
* @see #elements
* @see #get
* @see #keys
- * @since Android 1.0
*/
public abstract V put(K key, V value);
@@ -110,7 +102,6 @@
* {@code key} was not known to this dictionary.
* @see #get
* @see #put
- * @since Android 1.0
*/
public abstract V remove(Object key);
@@ -120,7 +111,6 @@
* @return the number of key/value pairs in this dictionary.
* @see #elements
* @see #keys
- * @since Android 1.0
*/
public abstract int size();
}
diff --git a/luni/src/main/java/java/util/DuplicateFormatFlagsException.java b/luni/src/main/java/java/util/DuplicateFormatFlagsException.java
index 908aa36..3330dcb 100644
--- a/luni/src/main/java/java/util/DuplicateFormatFlagsException.java
+++ b/luni/src/main/java/java/util/DuplicateFormatFlagsException.java
@@ -19,12 +19,11 @@
/**
* The unchecked exception will be thrown out if there are duplicate flags given
* out in the format specifier.
- *
+ *
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class DuplicateFormatFlagsException extends IllegalFormatException {
-
+
private static final long serialVersionUID = 18890531L;
private String flags;
diff --git a/luni/src/main/java/java/util/EmptyStackException.java b/luni/src/main/java/java/util/EmptyStackException.java
index 73d33ba..d8a48cc 100644
--- a/luni/src/main/java/java/util/EmptyStackException.java
+++ b/luni/src/main/java/java/util/EmptyStackException.java
@@ -21,9 +21,8 @@
/**
* An {@code EmptyStackException} is thrown if the pop/peek method of a stack is
* executed on an empty stack.
- *
+ *
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class EmptyStackException extends RuntimeException {
diff --git a/luni/src/main/java/java/util/EnumMap.java b/luni/src/main/java/java/util/EnumMap.java
index 1351069..975fdad 100644
--- a/luni/src/main/java/java/util/EnumMap.java
+++ b/luni/src/main/java/java/util/EnumMap.java
@@ -24,11 +24,14 @@
/**
* An {@code Map} specialized for use with {@code Enum} types as keys.
- *
- * @since Android 1.0
*/
public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V> implements
- Map<K, V>, Serializable, Cloneable {
+ Serializable, Cloneable, Map<K, V> {
+
+ // BEGIN android-changed
+ // added implements Map<K, V> for apicheck
+ // END android-changed
+
private static final long serialVersionUID = 458661240069192865L;
private Class<K> keyType;
@@ -57,6 +60,7 @@
ordinal = ((Enum) theKey).ordinal();
}
+ @SuppressWarnings("unchecked")
@Override
public boolean equals(Object object) {
if (!enumMap.hasMapping[ordinal]) {
@@ -83,18 +87,21 @@
: enumMap.values[ordinal].hashCode());
}
+ @SuppressWarnings("unchecked")
@Override
public KT getKey() {
checkEntryStatus();
return (KT) enumMap.keys[ordinal];
}
+ @SuppressWarnings("unchecked")
@Override
public VT getValue() {
checkEntryStatus();
return (VT) enumMap.values[ordinal];
}
+ @SuppressWarnings("unchecked")
@Override
public VT setValue(VT value) {
checkEntryStatus();
@@ -285,6 +292,7 @@
super(value, em);
}
+ @SuppressWarnings("unchecked")
@Override
public E next() {
if (!hasNext()) {
@@ -354,6 +362,7 @@
return toArray(entryArray);
}
+ @SuppressWarnings("unchecked")
@Override
public Object[] toArray(Object[] array) {
int size = enumMap.size();
@@ -378,10 +387,11 @@
/**
* Constructs an empty {@code EnumMap} using the given key type.
- *
+ *
* @param keyType
* the class object giving the type of the keys used by this {@code EnumMap}.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code keyType} is {@code null}.
*/
public EnumMap(Class<K> keyType) {
initialization(keyType);
@@ -390,10 +400,11 @@
/**
* Constructs an {@code EnumMap} using the same key type as the given {@code EnumMap} and
* initially containing the same mappings.
- *
+ *
* @param map
* the {@code EnumMap} from which this {@code EnumMap} is initialized.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code map} is {@code null}.
*/
public EnumMap(EnumMap<K, ? extends V> map) {
initialization(map);
@@ -402,16 +413,18 @@
/**
* Constructs an {@code EnumMap} initialized from the given map. If the given map
* is an {@code EnumMap} instance, this constructor behaves in the exactly the same
- * way as {@link EnumMap#EnumMap(EnumMap)}}. Otherwise, the given map
+ * way as {@link EnumMap#EnumMap(EnumMap)}}. Otherwise, the given map
* should contain at least one mapping.
- *
+ *
* @param map
* the map from which this {@code EnumMap} is initialized.
* @throws IllegalArgumentException
* if {@code map} is not an {@code EnumMap} instance and does not contain
* any mappings.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code map} is {@code null}.
*/
+ @SuppressWarnings("unchecked")
public EnumMap(Map<K, ? extends V> map) {
if (map instanceof EnumMap) {
initialization((EnumMap<K, V>) map);
@@ -433,10 +446,9 @@
/**
* Removes all elements from this {@code EnumMap}, leaving it empty.
- *
+ *
* @see #isEmpty()
* @see #size()
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -447,10 +459,10 @@
/**
* Returns a shallow copy of this {@code EnumMap}.
- *
+ *
* @return a shallow copy of this {@code EnumMap}.
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
@Override
public EnumMap<K, V> clone() {
try {
@@ -464,12 +476,11 @@
/**
* Returns whether this {@code EnumMap} contains the specified key.
- *
+ *
* @param key
* the key to search for.
* @return {@code true} if this {@code EnumMap} contains the specified key,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsKey(Object key) {
@@ -482,12 +493,11 @@
/**
* Returns whether this {@code EnumMap} contains the specified value.
- *
+ *
* @param value
* the value to search for.
* @return {@code true} if this {@code EnumMap} contains the specified value,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsValue(Object value) {
@@ -511,9 +521,11 @@
* Returns a {@code Set} containing all of the mappings in this {@code EnumMap}. Each mapping is
* an instance of {@link Map.Entry}. As the {@code Set} is backed by this {@code EnumMap},
* changes in one will be reflected in the other.
- *
+ * <p>
+ * The order of the entries in the set will be the order that the enum keys
+ * were declared in.
+ *
* @return a {@code Set} of the mappings.
- * @since Android 1.0
*/
@Override
public Set<Map.Entry<K, V>> entrySet() {
@@ -526,15 +538,15 @@
/**
* Compares the argument to the receiver, and returns {@code true} if the
* specified {@code Object} is an {@code EnumMap} and both {@code EnumMap}s contain the same mappings.
- *
+ *
* @param object
* the {@code Object} to compare with this {@code EnumMap}.
* @return boolean {@code true} if {@code object} is the same as this {@code EnumMap},
* {@code false} otherwise.
* @see #hashCode()
* @see #entrySet()
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
@Override
public boolean equals(Object object) {
if (this == object) {
@@ -553,12 +565,11 @@
/**
* Returns the value of the mapping with the specified key.
- *
+ *
* @param key
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -574,9 +585,11 @@
* Returns a set of the keys contained in this {@code EnumMap}. The {@code Set} is backed by
* this {@code EnumMap} so changes to one are reflected in the other. The {@code Set} does not
* support adding.
- *
+ * <p>
+ * The order of the set will be the order that the enum keys were declared
+ * in.
+ *
* @return a {@code Set} of the keys.
- * @since Android 1.0
*/
@Override
public Set<K> keySet() {
@@ -588,7 +601,7 @@
/**
* Maps the specified key to the specified value.
- *
+ *
* @param key
* the key.
* @param value
@@ -605,7 +618,6 @@
* @throws NullPointerException
* if the key or value is {@code null} and this {@code EnumMap} does not
* support {@code null} keys or values.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -615,7 +627,7 @@
/**
* Copies every mapping in the specified {@code Map} to this {@code EnumMap}.
- *
+ *
* @param map
* the {@code Map} to copy mappings from.
* @throws UnsupportedOperationException
@@ -628,7 +640,6 @@
* @throws NullPointerException
* if a key or value is {@code null} and this {@code EnumMap} does not
* support {@code null} keys or values.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -638,14 +649,13 @@
/**
* Removes a mapping with the specified key from this {@code EnumMap}.
- *
+ *
* @param key
* the key of the mapping to remove.
* @return the value of the removed mapping or {@code null} if no mapping
* for the specified key was found.
* @throws UnsupportedOperationException
* if removing from this {@code EnumMap} is not supported.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -665,9 +675,8 @@
/**
* Returns the number of elements in this {@code EnumMap}.
- *
+ *
* @return the number of elements in this {@code EnumMap}.
- * @since Android 1.0
*/
@Override
public int size() {
@@ -680,9 +689,11 @@
* {@link Map#values()}. The {@code Collection}'s {@code Iterator} will return the values
* in the their corresponding keys' natural order (the {@code Enum} constants are
* declared in this order).
- *
+ * <p>
+ * The order of the values in the collection will be the order that their
+ * corresponding enum keys were declared in.
+ *
* @return a collection of the values contained in this {@code EnumMap}.
- * @since Android 1.0
*/
@Override
public Collection<V> values() {
@@ -692,6 +703,7 @@
return valuesCollection;
}
+ @SuppressWarnings("unchecked")
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
stream.defaultReadObject();
diff --git a/luni/src/main/java/java/util/EnumSet.java b/luni/src/main/java/java/util/EnumSet.java
index 4e44f2e..d49d900 100644
--- a/luni/src/main/java/java/util/EnumSet.java
+++ b/luni/src/main/java/java/util/EnumSet.java
@@ -23,8 +23,6 @@
/**
* An EnumSet is a specialized Set to be used with enums as keys.
- *
- * @since Android 1.0
*/
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, Serializable {
@@ -37,7 +35,7 @@
static /*package*/ LangAccess LANG_BOOTSTRAP = null;
// END android-added
- private static final long serialVersionUID = 4782406773684236311L;
+ private static final long serialVersionUID = 1009687484059888093L;
final Class<E> elementClass;
@@ -48,14 +46,13 @@
/**
* Creates an empty enum set. The permitted elements are of type
* Class<E>.
- *
+ *
* @param elementType
* the class object for the elements contained.
* @return an empty enum set, with permitted elements of type {@code
* elementType}.
* @throws ClassCastException
* if the specified element type is not and enum type.
- * @since Android 1.0
*/
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
if (!elementType.isEnum()) {
@@ -73,13 +70,12 @@
/**
* Creates an enum set filled with all the enum elements of the specified
* {@code elementType}.
- *
+ *
* @param elementType
* the class object for the elements contained.
* @return an enum set with elements solely from the specified element type.
* @throws ClassCastException
* if the specified element type is not and enum type.
- * @since Android 1.0
*/
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
EnumSet<E> set = noneOf(elementType);
@@ -91,13 +87,12 @@
* Creates an enum set. All the contained elements are of type
* Class<E>, and the contained elements are the same as those
* contained in {@code s}.
- *
+ *
* @param s
* the enum set from which to copy.
* @return an enum set with all the elements from the specified enum set.
* @throws ClassCastException
* if the specified element type is not and enum type.
- * @since Android 1.0
*/
public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
EnumSet<E> set = EnumSet.noneOf(s.elementClass);
@@ -109,14 +104,15 @@
* Creates an enum set. The contained elements are the same as those
* contained in collection {@code c}. If c is an enum set, invoking this
* method is the same as invoking {@link #copyOf(EnumSet)}.
- *
+ *
* @param c
* the collection from which to copy. if it is not an enum set,
* it must not be empty.
* @return an enum set with all the elements from the specified collection.
* @throws IllegalArgumentException
* if c is not an enum set and contains no elements at all.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code c} is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
if (c instanceof EnumSet) {
@@ -138,12 +134,13 @@
/**
* Creates an enum set. All the contained elements complement those from the
* specified enum set.
- *
+ *
* @param s
* the specified enum set.
* @return an enum set with all the elements complementary to those from the
* specified enum set.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code s} is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
EnumSet<E> set = EnumSet.noneOf(s.elementClass);
@@ -159,11 +156,12 @@
* six overloadings of the method. They accept from one to five elements
* respectively. The sixth one receives an arbitrary number of elements, and
* runs slower than those that only receive a fixed number of elements.
- *
+ *
* @param e
* the element to be initially contained.
* @return an enum set containing the specified element.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code e} is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> of(E e) {
EnumSet<E> set = EnumSet.noneOf(e.getDeclaringClass());
@@ -172,17 +170,18 @@
}
/**
- * Creates a new enum set, containing only the specified element. There are
+ * Creates a new enum set, containing only the specified elements. There are
* six overloadings of the method. They accept from one to five elements
* respectively. The sixth one receives an arbitrary number of elements, and
* runs slower than those that only receive a fixed number of elements.
- *
+ *
* @param e1
* the initially contained element.
* @param e2
* another initially contained element.
- * @return an enum set containing the specified element.
- * @since Android 1.0
+ * @return an enum set containing the specified elements.
+ * @throws NullPointerException
+ * if any of the specified elements is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
EnumSet<E> set = of(e1);
@@ -191,19 +190,20 @@
}
/**
- * Creates a new enum set, containing only the specified element. There are
+ * Creates a new enum set, containing only the specified elements. There are
* six overloadings of the method. They accept from one to five elements
* respectively. The sixth one receives an arbitrary number of elements, and
* runs slower than those that only receive a fixed number of elements.
- *
+ *
* @param e1
* the initially contained element.
* @param e2
* another initially contained element.
* @param e3
* another initially contained element.
- * @return an enum set containing the specified element.
- * @since Android 1.0
+ * @return an enum set containing the specified elements.
+ * @throws NullPointerException
+ * if any of the specified elements is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
EnumSet<E> set = of(e1, e2);
@@ -212,11 +212,11 @@
}
/**
- * Creates a new enum set, containing only the specified element. There are
+ * Creates a new enum set, containing only the specified elements. There are
* six overloadings of the method. They accept from one to five elements
* respectively. The sixth one receives an arbitrary number of elements, and
* runs slower than those that only receive a fixed number of elements.
- *
+ *
* @param e1
* the initially contained element.
* @param e2
@@ -225,8 +225,9 @@
* another initially contained element.
* @param e4
* another initially contained element.
- * @return an enum set containing the specified element.
- * @since Android 1.0
+ * @return an enum set containing the specified elements.
+ * @throws NullPointerException
+ * if any of the specified elements is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
EnumSet<E> set = of(e1, e2, e3);
@@ -235,11 +236,11 @@
}
/**
- * Creates a new enum set, containing only the specified element. There are
+ * Creates a new enum set, containing only the specified elements. There are
* six overloadings of the method. They accept from one to five elements
* respectively. The sixth one receives an arbitrary number of elements, and
* runs slower than those that only receive a fixed number of elements.
- *
+ *
* @param e1
* the initially contained element.
* @param e2
@@ -250,8 +251,9 @@
* another initially contained element.
* @param e5
* another initially contained element.
- * @return an enum set containing the specified element.
- * @since Android 1.0
+ * @return an enum set containing the specified elements.
+ * @throws NullPointerException
+ * if any of the specified elements is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4, E e5) {
EnumSet<E> set = of(e1, e2, e3, e4);
@@ -263,13 +265,14 @@
* Creates a new enum set, containing only the specified elements. It can
* receive an arbitrary number of elements, and runs slower than those only
* receiving a fixed number of elements.
- *
+ *
* @param start
* the first initially contained element.
* @param others
* the other initially contained elements.
* @return an enum set containing the specified elements.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if any of the specified elements is {@code null}.
*/
public static <E extends Enum<E>> EnumSet<E> of(E start, E... others) {
EnumSet<E> set = of(start);
@@ -283,15 +286,16 @@
* Creates an enum set containing all the elements within the range defined
* by {@code start} and {@code end} (inclusive). All the elements must be in
* order.
- *
+ *
* @param start
* the element used to define the beginning of the range.
* @param end
* the element used to define the end of the range.
* @return an enum set with elements in the range from start to end.
+ * @throws NullPointerException
+ * if any one of {@code start} or {@code end} is {@code null}.
* @throws IllegalArgumentException
* if {@code start} is behind {@code end}.
- * @since Android 1.0
*/
public static <E extends Enum<E>> EnumSet<E> range(E start, E end) {
if (start.compareTo(end) > 0) {
@@ -307,10 +311,9 @@
/**
* Creates a new enum set with the same elements as those contained in this
* enum set.
- *
+ *
* @return a new enum set with the same elements as those contained in this
* enum set.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
@Override
diff --git a/luni/src/main/java/java/util/Enumeration.java b/luni/src/main/java/java/util/Enumeration.java
index d60bdd2..8b8f7bd 100644
--- a/luni/src/main/java/java/util/Enumeration.java
+++ b/luni/src/main/java/java/util/Enumeration.java
@@ -17,18 +17,16 @@
package java.util;
-
/**
* An Enumeration is used to sequence over a collection of objects.
* <p>
- * Preferably an Iterator should be used. Iterator replaces the Enumeration
- * interface and adds a way to remove elements from a collection.
- * </p>
- *
+ * Preferably an {@link Iterator} should be used. {@code Iterator} replaces the
+ * enumeration interface and adds a way to remove elements from a collection.
+ *
* @see Hashtable
* @see Properties
* @see Vector
- * @since Android 1.0
+ * @version 1.0
*/
public interface Enumeration<E> {
@@ -37,7 +35,6 @@
*
* @return {@code true} if there are more elements, {@code false} otherwise.
* @see #nextElement
- * @since Android 1.0
*/
public boolean hasMoreElements();
@@ -48,7 +45,6 @@
* @throws NoSuchElementException
* if there are no more elements.
* @see #hasMoreElements
- * @since Android 1.0
*/
public E nextElement();
}
diff --git a/luni/src/main/java/java/util/EventListener.java b/luni/src/main/java/java/util/EventListener.java
index 9ff4876..b100f0c 100644
--- a/luni/src/main/java/java/util/EventListener.java
+++ b/luni/src/main/java/java/util/EventListener.java
@@ -17,13 +17,11 @@
package java.util;
-
/**
* EventListener is the superclass of all event listener interfaces.
- *
+ *
* @see EventObject
- * @since Android 1.0
*/
public interface EventListener {
- /*empty*/
+ /* empty */
}
diff --git a/luni/src/main/java/java/util/EventListenerProxy.java b/luni/src/main/java/java/util/EventListenerProxy.java
index a165385..1e023f6 100644
--- a/luni/src/main/java/java/util/EventListenerProxy.java
+++ b/luni/src/main/java/java/util/EventListenerProxy.java
@@ -20,8 +20,6 @@
/**
* This abstract class provides a simple wrapper for objects of type {@code EventListener}.
- *
- * @since Android 1.0
*/
public abstract class EventListenerProxy implements EventListener {
@@ -32,7 +30,6 @@
*
* @param listener
* the listener wrapped by this proxy.
- * @since Android 1.0
*/
public EventListenerProxy(EventListener listener) {
super();
@@ -43,7 +40,6 @@
* Returns the wrapped {@code EventListener}.
*
* @return the wrapped {@code EventListener}.
- * @since Android 1.0
*/
public EventListener getListener() {
return listener;
diff --git a/luni/src/main/java/java/util/EventObject.java b/luni/src/main/java/java/util/EventObject.java
index 61e530a..76da7e2 100644
--- a/luni/src/main/java/java/util/EventObject.java
+++ b/luni/src/main/java/java/util/EventObject.java
@@ -25,8 +25,6 @@
* add event specific information.
*
* @see EventListener
- *
- * @since Android 1.0
*/
public class EventObject implements Serializable {
@@ -34,8 +32,6 @@
/**
* The event source.
- *
- * @since Android 1.0
*/
protected transient Object source;
@@ -44,7 +40,6 @@
*
* @param source
* the object which fired the event.
- * @since Android 1.0
*/
public EventObject(Object source) {
if (source != null) {
@@ -58,7 +53,6 @@
* Returns the event source.
*
* @return the object which fired the event.
- * @since Android 1.0
*/
public Object getSource() {
return source;
@@ -68,7 +62,6 @@
* Returns the string representation of this {@code EventObject}.
*
* @return the string representation of this {@code EventObject}.
- * @since Android 1.0
*/
@Override
public String toString() {
diff --git a/luni/src/main/java/java/util/FormatFlagsConversionMismatchException.java b/luni/src/main/java/java/util/FormatFlagsConversionMismatchException.java
index aa0c967..e4f39d2 100644
--- a/luni/src/main/java/java/util/FormatFlagsConversionMismatchException.java
+++ b/luni/src/main/java/java/util/FormatFlagsConversionMismatchException.java
@@ -23,7 +23,6 @@
* conversion and the flags are incompatible.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class FormatFlagsConversionMismatchException extends
IllegalFormatException implements Serializable {
diff --git a/luni/src/main/java/java/util/Formattable.java b/luni/src/main/java/java/util/Formattable.java
index 2564c04..15b66b5 100644
--- a/luni/src/main/java/java/util/Formattable.java
+++ b/luni/src/main/java/java/util/Formattable.java
@@ -20,16 +20,15 @@
* Classes that handle custom formatting for the 's' specifier of {@code Formatter}
* should implement the {@code Formattable} interface. It gives basic control over
* formatting objects.
- *
+ *
* @see Formatter
- * @since Android 1.0
*/
public interface Formattable {
/**
* Formats the object using the specified {@code Formatter}.
- *
+ *
* @param formatter
* the {@code Formatter} to use.
* @param flags
@@ -54,7 +53,6 @@
* is -1, then maximum length is not enforced.
* @throws IllegalFormatException
* if any of the parameters is not supported.
- * @since Android 1.0
*/
void formatTo(Formatter formatter, int flags, int width, int precision)
throws IllegalFormatException;
diff --git a/luni/src/main/java/java/util/FormattableFlags.java b/luni/src/main/java/java/util/FormattableFlags.java
index b5078e4..b8d44d4 100644
--- a/luni/src/main/java/java/util/FormattableFlags.java
+++ b/luni/src/main/java/java/util/FormattableFlags.java
@@ -22,7 +22,6 @@
* flags must be done by the implementations.
*
* @see Formattable
- * @since Android 1.0
*/
public class FormattableFlags {
@@ -37,8 +36,6 @@
* right-justified.
*
* The flag corresponds to '-' ('\u002d') in the format specifier.
- *
- * @since Android 1.0
*/
public static final int LEFT_JUSTIFY = 1;
@@ -48,8 +45,6 @@
* effect as {@code String.toUpperCase(java.util.Locale)}.
*
* This flag corresponds to {@code '^' ('\u005e')} in the format specifier.
- *
- * @since Android 1.0
*/
public static final int UPPERCASE = 2;
@@ -58,8 +53,6 @@
* of the alternate form is determined by the {@code Formattable}.
*
* This flag corresponds to {@code '#' ('\u0023')} in the format specifier.
- *
- * @since Android 1.0
*/
public static final int ALTERNATE = 4;
}
diff --git a/luni/src/main/java/java/util/Formatter.java b/luni/src/main/java/java/util/Formatter.java
index a6f14f0..d1dd417 100644
--- a/luni/src/main/java/java/util/Formatter.java
+++ b/luni/src/main/java/java/util/Formatter.java
@@ -28,6 +28,7 @@
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.math.MathContext;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.AccessController;
@@ -37,63 +38,59 @@
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
-// BEGIN android-note
-// Added quite extensive class documentation. Almost none was present before.
-// END android-note
-
/**
* <p>The {@code Formatter} class is a String-formatting utility that is designed
- * to work like the {@code printf} function of the C programming language.
+ * to work like the {@code printf} function of the C programming language.
* Its key methods are the {@code format} methods which create a formatted
- * {@code String} by replacing a set of placeholders (format tokens) with formatted
+ * {@code String} by replacing a set of placeholders (format tokens) with formatted
* values. The style used to format each value is determined by the format
* token used. For example, the call<br/>
* {@code format("My decimal value is %d and my String is %s.", 3, "Hello");}<br/>
* returns the {@code String}<br/>
- * {@code My decimal value is 3 and my String is Hello.}</p>
- *
- *<p>The format token consists of a percent sign, optionally followed
- * by flags and precision arguments, and then a single character that
+ * {@code My decimal value is 3 and my String is Hello.}
+ *
+ * <p>The format token consists of a percent sign, optionally followed
+ * by flags and precision arguments, and then a single character that
* indicates the type of value
* being formatted. If the type is a time/date, then the type character
- * {@code t} is followed by an additional character that indicates how the
- * date is to be formatted. The two characters {@code <$} immediately
+ * {@code t} is followed by an additional character that indicates how the
+ * date is to be formatted. The two characters {@code <$} immediately
* following the % sign indicate that the previous value should be used again
* instead of moving on to the next value argument. A number {@code n}
* and a dollar sign immediately following the % sign make n the next argument
- * to be used.</p>
- *
- * <p>The available choices are the following:</p>
- *
+ * to be used.
+ *
+ * <p>The available choices are the following:
+ *
* <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Text value types</B></TD>
* </tr>
* <tr>
- * <td width="5%">{@code s}</td>
- * <td width="10%">String</td>
- * <td width="30%">{@code format("%s, %s", "hello", "Hello");}</td>
- * <td width="30%">{@code hello, Hello}</td>
- * </tr>
+ * <td width="5%">{@code s}</td>
+ * <td width="10%">String</td>
+ * <td width="30%">{@code format("%s, %s", "hello", "Hello");}</td>
+ * <td width="30%">{@code hello, Hello}</td>
+ * </tr>
* <tr>
- * <td width="5%">{@code S}, {@code s}</td>
- * <td width="10%">String to capitals</td>
- * <td width="30%">{@code format("%S, %S", "hello", "Hello");}</td>
- * <td width="30%">{@code HELLO, HELLO}</td>
- * </tr>
+ * <td width="5%">{@code S}, {@code s}</td>
+ * <td width="10%">String to capitals</td>
+ * <td width="30%">{@code format("%S, %S", "hello", "Hello");}</td>
+ * <td width="30%">{@code HELLO, HELLO}</td>
+ * </tr>
* <tr>
- * <td width="5%">{@code c}</td>
- * <td width="10%">Character</td>
- * <td width="30%">{@code format("%c, %c", 'd', 0x65);}</td>
+ * <td width="5%">{@code c}</td>
+ * <td width="10%">Character</td>
+ * <td width="30%">{@code format("%c, %c", 'd', 0x65);}</td>
* <td width="30%">{@code d, e}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code C}</td>
- * <td width="10%">Character to capitals</td>
- * <td width="30%">{@code format("%C, %C", 'd', 0x65);}</td>
+ * <td width="5%">{@code C}</td>
+ * <td width="10%">Character to capitals</td>
+ * <td width="30%">{@code format("%C, %C", 'd', 0x65);}</td>
* <td width="30%">{@code D, E}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Text option flags</B><br/>The value between the
@@ -101,33 +98,33 @@
* characters of the formatted value </TD>
* </tr>
* <tr>
- * <td width="5%">{@code -}</td>
- * <td width="10%">Left justify (width value is required)</td>
- * <td width="30%">{@code format("%-3C, %3C", 'd', 0x65);}</td>
+ * <td width="5%">{@code -}</td>
+ * <td width="10%">Left justify (width value is required)</td>
+ * <td width="30%">{@code format("%-3C, %3C", 'd', 0x65);}</td>
* <td width="30%">{@code D , E}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Integer types</B></TD>
* </tr>
* <tr>
- * <td width="5%">{@code d}</td>
- * <td width="10%">int, formatted as decimal</td>
- * <td width="30%">{@code format("%d, %d"1$, 35, 0x10);}</td>
+ * <td width="5%">{@code d}</td>
+ * <td width="10%">int, formatted as decimal</td>
+ * <td width="30%">{@code format("%d, %d"1$, 35, 0x10);}</td>
* <td width="30%">{@code 35, 16}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code o}</td>
- * <td width="10%">int, formatted as octal</td>
- * <td width="30%">{@code format("%o, %o", 8, 010);}</td>
+ * <td width="5%">{@code o}</td>
+ * <td width="10%">int, formatted as octal</td>
+ * <td width="30%">{@code format("%o, %o", 8, 010);}</td>
* <td width="30%">{@code 10, 10}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code X}, {@code x}</td>
- * <td width="10%">int, formatted as hexidecimal</td>
- * <td width="30%">{@code format("%x, %X", 10, 10);}</td>
+ * <td width="5%">{@code X}, {@code x}</td>
+ * <td width="10%">int, formatted as hexidecimal</td>
+ * <td width="30%">{@code format("%x, %X", 10, 10);}</td>
* <td width="30%">{@code a, A}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Integer option flags</B><br/>The value between the
@@ -135,43 +132,43 @@
* characters of the formatted value </TD>
* </tr>
* <tr>
- * <td width="5%">{@code +}</td>
- * <td width="10%">lead with the number's sign</td>
- * <td width="30%">{@code format("%+d, %+4d", 5, 5);}</td>
+ * <td width="5%">{@code +}</td>
+ * <td width="10%">lead with the number's sign</td>
+ * <td width="30%">{@code format("%+d, %+4d", 5, 5);}</td>
* <td width="30%">{@code +5, +5}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code -}</td>
- * <td width="10%">Left justify (width value is required)</td>
- * <td width="30%">{@code format("%-6dx", 5);}</td>
+ * <td width="5%">{@code -}</td>
+ * <td width="10%">Left justify (width value is required)</td>
+ * <td width="30%">{@code format("%-6dx", 5);}</td>
* <td width="30%">{@code 5 x}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code #}</td>
- * <td width="10%">Print the leading characters that indicate
- * hexidecimal or octal (for use only with hex and octal types) </td>
- * <td width="30%">{@code format("%#o", 010);}</td>
+ * <td width="5%">{@code #}</td>
+ * <td width="10%">Print the leading characters that indicate
+ * hexidecimal or octal (for use only with hex and octal types) </td>
+ * <td width="30%">{@code format("%#o", 010);}</td>
* <td width="30%">{@code 010}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code }</td>
- * <td width="10%">A space indicates that non-negative numbers
- * should have a leading space. </td>
- * <td width="30%">{@code format("x% d% 5d", 4, 4);}</td>
+ * <td width="5%">{@code }</td>
+ * <td width="10%">A space indicates that non-negative numbers
+ * should have a leading space. </td>
+ * <td width="30%">{@code format("x% d% 5d", 4, 4);}</td>
* <td width="30%">{@code x 4 4}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code 0}</td>
- * <td width="10%">Pad the number with leading zeros (width value is required)</td>
- * <td width="30%">{@code format("%07d, %03d", 4, 5555);}</td>
+ * <td width="5%">{@code 0}</td>
+ * <td width="10%">Pad the number with leading zeros (width value is required)</td>
+ * <td width="30%">{@code format("%07d, %03d", 4, 5555);}</td>
* <td width="30%">{@code 0000004, 5555}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code (}</td>
- * <td width="10%">Put parentheses around negative numbers (decimal only)</td>
- * <td width="30%">{@code format("%(d, %(d, %(6d", 12, -12, -12);}</td>
+ * <td width="5%">{@code (}</td>
+ * <td width="10%">Put parentheses around negative numbers (decimal only)</td>
+ * <td width="30%">{@code format("%(d, %(d, %(6d", 12, -12, -12);}</td>
* <td width="30%">{@code 12, (12), (12)}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Float types</B><br/>A value immediately following the % symbol
@@ -180,229 +177,223 @@
* gives the precision (6 by default).</TD>
* </tr>
* <tr>
- * <td width="5%">{@code f}</td>
- * <td width="10%">float (or double) formatted as a decimal, where
- * the precision indicates the number of digits after the decimal.</td>
- * <td width="30%">{@code format("%f %<.1f %<1.5f %<10f %<6.0f", 123.456f);}</td>
+ * <td width="5%">{@code f}</td>
+ * <td width="10%">float (or double) formatted as a decimal, where
+ * the precision indicates the number of digits after the decimal.</td>
+ * <td width="30%">{@code format("%f %<.1f %<1.5f %<10f %<6.0f", 123.456f);}</td>
* <td width="30%">{@code 123.456001 123.5 123.45600 123.456001 123}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code E}, {@code e}</td>
+ * <td width="5%">{@code E}, {@code e}</td>
* <td width="10%">float (or double) formatted in decimal exponential
- * notation, where the precision indicates the number of significant digits.</td>
- * <td width="30%">{@code format("%E %<.1e %<1.5E %<10E %<6.0E", 123.456f);}</td>
+ * notation, where the precision indicates the number of significant digits.</td>
+ * <td width="30%">{@code format("%E %<.1e %<1.5E %<10E %<6.0E", 123.456f);}</td>
* <td width="30%">{@code 1.234560E+02 1.2e+02 1.23456E+02 1.234560E+02 1E+02}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code G}, {@code g}</td>
+ * <td width="5%">{@code G}, {@code g}</td>
* <td width="10%">float (or double) formatted in decimal exponential
- * notation , where the precision indicates the maximum number of significant digits.</td>
- * <td width="30%">{@code format("%G %<.1g %<1.5G %<10G %<6.0G", 123.456f);}</td>
+ * notation , where the precision indicates the maximum number of significant digits.</td>
+ * <td width="30%">{@code format("%G %<.1g %<1.5G %<10G %<6.0G", 123.456f);}</td>
* <td width="30%">{@code 123.456 1e+02 123.46 123.456 1E+02}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code A}, {@code a}</td>
+ * <td width="5%">{@code A}, {@code a}</td>
* <td width="10%">float (or double) formatted as a hexidecimal in exponential
- * notation, where the precision indicates the number of significant digits.</td>
- * <td width="30%">{@code format("%A %<.1a %<1.5A %<10A %<6.0A", 123.456f);}</td>
+ * notation, where the precision indicates the number of significant digits.</td>
+ * <td width="30%">{@code format("%A %<.1a %<1.5A %<10A %<6.0A", 123.456f);}</td>
* <td width="30%">{@code 0X1.EDD2F2P6 0x1.fp6 0X1.EDD2FP6 0X1.EDD2F2P6 0X1.FP6}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
- * <B>Float-type option flags</B><br/>See the Integer-type options.
+ * <B>Float-type option flags</B><br/>See the Integer-type options.
* The options for float-types are the
* same as for integer types with one addition: </TD>
* </tr>
* <tr>
- * <td width="5%">{@code ,}</td>
+ * <td width="5%">{@code ,}</td>
* <td width="10%">Use a comma in place of a decimal if the locale
- * requires it. </td>
- * <td width="30%">{@code format(new Locale("fr"), "%,7.2f", 6.03f);}</td>
+ * requires it. </td>
+ * <td width="30%">{@code format(new Locale("fr"), "%,7.2f", 6.03f);}</td>
* <td width="30%">{@code 6,03}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Date types</B></TD>
* </tr>
* <tr>
- * <td width="5%">{@code t}, {@code T}</td>
- * <td width="10%">Date</td>
- * <td width="30%">{@code format(new Locale("fr"), "%tB %TB", Calendar.getInstance(), Calendar.getInstance());}</td>
+ * <td width="5%">{@code t}, {@code T}</td>
+ * <td width="10%">Date</td>
+ * <td width="30%">{@code format(new Locale("fr"), "%tB %TB", Calendar.getInstance(), Calendar.getInstance());}</td>
* <td width="30%">{@code avril AVRIL}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
- * <B>Date format precisions</B><br/>The format precision character
+ * <B>Date format precisions</B><br/>The format precision character
* follows the {@code t}. </TD>
* </tr>
* <tr>
- * <td width="5%">{@code A}, {@code a}</td>
- * <td width="10%">The day of the week</td>
- * <td width="30%">{@code format("%ta %tA", cal, cal);}</td>
+ * <td width="5%">{@code A}, {@code a}</td>
+ * <td width="10%">The day of the week</td>
+ * <td width="30%">{@code format("%ta %tA", cal, cal);}</td>
* <td width="30%">{@code Tue Tuesday}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code b}, {@code B}, {@code h}</td>
- * <td width="10%">The name of the month</td>
- * <td width="30%">{@code format("%tb %<tB %<th", cal, cal, cal);}</td>
+ * <td width="5%">{@code b}, {@code B}, {@code h}</td>
+ * <td width="10%">The name of the month</td>
+ * <td width="30%">{@code format("%tb %<tB %<th", cal, cal, cal);}</td>
* <td width="30%">{@code Apr April Apr}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code C}</td>
- * <td width="10%">The century</td>
- * <td width="30%">{@code format("%tC\n", cal);}</td>
+ * <td width="5%">{@code C}</td>
+ * <td width="10%">The century</td>
+ * <td width="30%">{@code format("%tC\n", cal);}</td>
* <td width="30%">{@code 20}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code d}, {@code e}</td>
- * <td width="10%">The day of the month (with or without leading zeros)</td>
- * <td width="30%">{@code format("%td %te", cal, cal);}</td>
+ * <td width="5%">{@code d}, {@code e}</td>
+ * <td width="10%">The day of the month (with or without leading zeros)</td>
+ * <td width="30%">{@code format("%td %te", cal, cal);}</td>
* <td width="30%">{@code 01 1}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code F}</td>
- * <td width="10%">The complete date formatted as YYYY-MM-DD</td>
- * <td width="30%">{@code format("%tF", cal);}</td>
+ * <td width="5%">{@code F}</td>
+ * <td width="10%">The complete date formatted as YYYY-MM-DD</td>
+ * <td width="30%">{@code format("%tF", cal);}</td>
* <td width="30%">{@code 2008-04-01}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code D}</td>
- * <td width="10%">The complete date formatted as MM/DD/YY
- * (not corrected for locale) </td>
- * <td width="30%">{@code format(new Locale("en_US"), "%tD", cal);<br/>format(new Locale("en_UK"), " %tD", cal);}</td>
+ * <td width="5%">{@code D}</td>
+ * <td width="10%">The complete date formatted as MM/DD/YY
+ * (not corrected for locale) </td>
+ * <td width="30%">{@code format(new Locale("en_US"), "%tD", cal);<br/>format(new Locale("en_UK"), " %tD", cal);}</td>
* <td width="30%">{@code 04/01/08 04/01/08}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code j}</td>
- * <td width="10%">The number of the day (from the beginning of the year).</td>
- * <td width="30%">{@code format("%tj\n", cal);}</td>
+ * <td width="5%">{@code j}</td>
+ * <td width="10%">The number of the day (from the beginning of the year).</td>
+ * <td width="30%">{@code format("%tj\n", cal);}</td>
* <td width="30%">{@code 092}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code m}</td>
- * <td width="10%">The number of the month</td>
- * <td width="30%">{@code format("%tm\n", cal);}</td>
+ * <td width="5%">{@code m}</td>
+ * <td width="10%">The number of the month</td>
+ * <td width="30%">{@code format("%tm\n", cal);}</td>
* <td width="30%">{@code 04}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code y}, {@code Y}</td>
- * <td width="10%">The year</td>
- * <td width="30%">{@code format("%ty %tY", cal, cal);}</td>
+ * <td width="5%">{@code y}, {@code Y}</td>
+ * <td width="10%">The year</td>
+ * <td width="30%">{@code format("%ty %tY", cal, cal);}</td>
* <td width="30%">{@code 08 2008}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code H}, {@code I}, {@code k}, {@code l}</td>
+ * <td width="5%">{@code H}, {@code I}, {@code k}, {@code l}</td>
* <td width="10%">The hour of the day, in 12 or 24 hour format, with or
- * without a leading zero</td>
- * <td width="30%">{@code format("%tH %tI %tk %tl", cal, cal, cal, cal);}</td>
+ * without a leading zero</td>
+ * <td width="30%">{@code format("%tH %tI %tk %tl", cal, cal, cal, cal);}</td>
* <td width="30%">{@code 16 04 16 4}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code p}</td>
- * <td width="10%">a.m. or p.m.</td>
- * <td width="30%">{@code format("%tp %Tp", cal, cal);}</td>
+ * <td width="5%">{@code p}</td>
+ * <td width="10%">a.m. or p.m.</td>
+ * <td width="30%">{@code format("%tp %Tp", cal, cal);}</td>
* <td width="30%">{@code pm PM}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code M}, {@code S}, {@code L}, {@code N}</td>
- * <td width="10%">The minutes, seconds, milliseconds, and nanoseconds</td>
- * <td width="30%">{@code format("%tM %tS %tL %tN", cal, cal, cal, cal);}</td>
+ * <td width="5%">{@code M}, {@code S}, {@code L}, {@code N}</td>
+ * <td width="10%">The minutes, seconds, milliseconds, and nanoseconds</td>
+ * <td width="30%">{@code format("%tM %tS %tL %tN", cal, cal, cal, cal);}</td>
* <td width="30%">{@code 08 17 359 359000000}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code Z}, {@code z}</td>
- * <td width="10%">The time zone: its abbreviation or offset from GMT</td>
- * <td width="30%">{@code format("%tZ %tz", cal, cal);}</td>
+ * <td width="5%">{@code Z}, {@code z}</td>
+ * <td width="10%">The time zone: its abbreviation or offset from GMT</td>
+ * <td width="30%">{@code format("%tZ %tz", cal, cal);}</td>
* <td width="30%">{@code CEST +0100}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code R}, {@code r}, {@code T}</td>
- * <td width="10%">The complete time</td>
- * <td width="30%">{@code format("%tR %tr %tT", cal, cal, cal);}</td>
+ * <td width="5%">{@code R}, {@code r}, {@code T}</td>
+ * <td width="10%">The complete time</td>
+ * <td width="30%">{@code format("%tR %tr %tT", cal, cal, cal);}</td>
* <td width="30%">{@code 16:15 04:15:32 PM 16:15:32}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code s}, {@code Q}</td>
+ * <td width="5%">{@code s}, {@code Q}</td>
* <td width="10%">The number of seconds or milliseconds from "the epoch"
- * (1 January 1970 00:00:00 UTC) </td>
- * <td width="30%">{@code format("%ts %tQ", cal, cal);}</td>
+ * (1 January 1970 00:00:00 UTC) </td>
+ * <td width="30%">{@code format("%ts %tQ", cal, cal);}</td>
* <td width="30%">{@code 1207059412 1207059412656}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code c}</td>
- * <td width="10%">The complete time and date</td>
- * <td width="30%">{@code format("%tc", cal);}</td>
+ * <td width="5%">{@code c}</td>
+ * <td width="10%">The complete time and date</td>
+ * <td width="30%">{@code format("%tc", cal);}</td>
* <td width="30%">{@code Tue Apr 01 16:19:17 CEST 2008}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Other data types</B></TD>
* </tr>
* <tr>
- * <td width="5%">{@code B}, {@code b}</td>
- * <td width="10%">Boolean</td>
- * <td width="30%">{@code format("%b, %B", true, false);}</td>
+ * <td width="5%">{@code B}, {@code b}</td>
+ * <td width="10%">Boolean</td>
+ * <td width="30%">{@code format("%b, %B", true, false);}</td>
* <td width="30%">{@code true, FALSE}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code H}, {@code h}</td>
- * <td width="10%">Hashcode</td>
- * <td width="30%">{@code format("%h, %H", obj, obj);}</td>
+ * <td width="5%">{@code H}, {@code h}</td>
+ * <td width="10%">Hashcode</td>
+ * <td width="30%">{@code format("%h, %H", obj, obj);}</td>
* <td width="30%">{@code 190d11, 190D11}</td>
- * </tr>
+ * </tr>
* <tr>
- * <td width="5%">{@code n}</td>
- * <td width="10%">line separator</td>
- * <td width="30%">{@code format("first%nsecond", "???");}</td>
+ * <td width="5%">{@code n}</td>
+ * <td width="10%">line separator</td>
+ * <td width="30%">{@code format("first%nsecond", "???");}</td>
* <td width="30%">{@code first<br/>second}</td>
- * </tr>
+ * </tr>
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4>
* <B>Escape sequences</B></TD>
* </tr>
* <tr>
- * <td width="5%">{@code %}</td>
- * <td width="10%">Escape the % character</td>
- * <td width="30%">{@code format("%d%%, %d", 50, 60);}</td>
+ * <td width="5%">{@code %}</td>
+ * <td width="10%">Escape the % character</td>
+ * <td width="30%">{@code format("%d%%, %d", 50, 60);}</td>
* <td width="30%">{@code 50%, 60}</td>
- * </tr>
- * </table>
- *
+ * </tr>
+ * </table>
+ *
* <p>An instance of Formatter can be created to write the formatted
- * output to standard types of output streams. Its functionality can
- * also be accessed through the format methods of an output stream
+ * output to standard types of output streams. Its functionality can
+ * also be accessed through the format methods of an output stream
* or of {@code String}:<br/>
* {@code System.out.println(String.format("%ty\n", cal));}<br/>
- * {@code System.out.format("%ty\n", cal);}</p>
- *
- * <p>The class is not multi-threaded safe. The user is responsible for
+ * {@code System.out.format("%ty\n", cal);}
+ *
+ * <p>The class is not multi-threaded safe. The user is responsible for
* maintaining a thread-safe design if a {@code Formatter} is
- * accessed by multiple threads. </p>
- *
- * @since Android 1.0
+ * accessed by multiple threads.
+ *
+ * @since 1.5
*/
public final class Formatter implements Closeable, Flushable {
- // BEGIN android-changed
/**
* The enumeration giving the available styles for formatting very large
* decimal numbers.
- *
- * @since Android 1.0
- */
+ */
public enum BigDecimalLayoutForm {
/**
* Use scientific style for BigDecimals.
- * @since Android 1.0
*/
- SCIENTIFIC,
+ SCIENTIFIC,
/**
* Use normal decimal/float style for BigDecimals.
- * @since Android 1.0
*/
DECIMAL_FLOAT
}
- // END android-changed
private Appendable out;
@@ -414,29 +405,26 @@
/**
* Constructs a {@code Formatter}.
- *
+ *
* The output is written to a {@code StringBuilder} which can be acquired by invoking
* {@link #out()} and whose content can be obtained by calling
* {@code toString()}.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
- * @since Android 1.0
*/
public Formatter() {
this(new StringBuilder(), Locale.getDefault());
}
/**
- * Constructs a {@code Formatter} whose output will be written to the
+ * Constructs a {@code Formatter} whose output will be written to the
* specified {@code Appendable}.
- *
+ *
* The locale for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param a
* the output destination of the {@code Formatter}. If {@code a} is {@code null},
* then a {@code StringBuilder} will be used.
- * @since Android 1.0
*/
public Formatter(Appendable a) {
this(a, Locale.getDefault());
@@ -444,32 +432,30 @@
/**
* Constructs a {@code Formatter} with the specified {@code Locale}.
- *
+ *
* The output is written to a {@code StringBuilder} which can be acquired by invoking
* {@link #out()} and whose content can be obtained by calling
* {@code toString()}.
- *
+ *
* @param l
* the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
* then no localization will be used.
- * @since Android 1.0
*/
public Formatter(Locale l) {
this(new StringBuilder(), l);
}
/**
- * Constructs a {@code Formatter} with the specified {@code Locale}
- * and whose output will be written to the
+ * Constructs a {@code Formatter} with the specified {@code Locale}
+ * and whose output will be written to the
* specified {@code Appendable}.
- *
+ *
* @param a
* the output destination of the {@code Formatter}. If {@code a} is {@code null},
* then a {@code StringBuilder} will be used.
* @param l
* the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
* then no localization will be used.
- * @since Android 1.0
*/
public Formatter(Appendable a, Locale l) {
if (null == a) {
@@ -482,17 +468,16 @@
/**
* Constructs a {@code Formatter} whose output is written to the specified file.
- *
+ *
* The charset of the {@code Formatter} is the default charset.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param fileName
* the filename of the file that is used as the output
* destination for the {@code Formatter}. The file will be truncated to
* zero size if the file exists, or else a new file will be
* created. The output of the {@code Formatter} is buffered.
- *
* @throws FileNotFoundException
* if the filename does not denote a normal and writable file,
* or if a new file cannot be created, or if any error arises when
@@ -500,7 +485,6 @@
* @throws SecurityException
* if there is a {@code SecurityManager} in place which denies permission
* to write to the file in {@code checkWrite(file.getPath())}.
- * @since Android 1.0
*/
public Formatter(String fileName) throws FileNotFoundException {
this(new File(fileName));
@@ -509,9 +493,9 @@
/**
* Constructs a {@code Formatter} whose output is written to the specified file.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param fileName
* the filename of the file that is used as the output
* destination for the {@code Formatter}. The file will be truncated to
@@ -519,7 +503,6 @@
* created. The output of the {@code Formatter} is buffered.
* @param csn
* the name of the charset for the {@code Formatter}.
- *
* @throws FileNotFoundException
* if the filename does not denote a normal and writable file,
* or if a new file cannot be created, or if any error arises when
@@ -529,7 +512,6 @@
* to write to the file in {@code checkWrite(file.getPath())}.
* @throws UnsupportedEncodingException
* if the charset with the specified name is not supported.
- * @since Android 1.0
*/
public Formatter(String fileName, String csn) throws FileNotFoundException,
UnsupportedEncodingException {
@@ -537,9 +519,9 @@
}
/**
- * Constructs a {@code Formatter} with the given {@code Locale} and charset,
+ * Constructs a {@code Formatter} with the given {@code Locale} and charset,
* and whose output is written to the specified file.
- *
+ *
* @param fileName
* the filename of the file that is used as the output
* destination for the {@code Formatter}. The file will be truncated to
@@ -550,7 +532,6 @@
* @param l
* the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null},
* then no localization will be used.
- *
* @throws FileNotFoundException
* if the filename does not denote a normal and writable file,
* or if a new file cannot be created, or if any error arises when
@@ -560,7 +541,6 @@
* to write to the file in {@code checkWrite(file.getPath())}.
* @throws UnsupportedEncodingException
* if the charset with the specified name is not supported.
- * @since Android 1.0
*/
public Formatter(String fileName, String csn, Locale l)
throws FileNotFoundException, UnsupportedEncodingException {
@@ -570,17 +550,16 @@
/**
* Constructs a {@code Formatter} whose output is written to the specified {@code File}.
- *
+ *
* The charset of the {@code Formatter} is the default charset.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param file
* the {@code File} that is used as the output destination for the
* {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
* exists, or else a new {@code File} will be created. The output of the
* {@code Formatter} is buffered.
- *
* @throws FileNotFoundException
* if the {@code File} is not a normal and writable {@code File}, or if a
* new {@code File} cannot be created, or if any error rises when opening or
@@ -588,18 +567,17 @@
* @throws SecurityException
* if there is a {@code SecurityManager} in place which denies permission
* to write to the {@code File} in {@code checkWrite(file.getPath())}.
- * @since Android 1.0
*/
public Formatter(File file) throws FileNotFoundException {
this(new FileOutputStream(file));
}
/**
- * Constructs a {@code Formatter} with the given charset,
+ * Constructs a {@code Formatter} with the given charset,
* and whose output is written to the specified {@code File}.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param file
* the {@code File} that is used as the output destination for the
* {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
@@ -616,7 +594,6 @@
* to write to the {@code File} in {@code checkWrite(file.getPath())}.
* @throws UnsupportedEncodingException
* if the charset with the specified name is not supported.
- * @since Android 1.0
*/
public Formatter(File file, String csn) throws FileNotFoundException,
UnsupportedEncodingException {
@@ -624,9 +601,9 @@
}
/**
- * Constructs a {@code Formatter} with the given {@code Locale} and charset,
+ * Constructs a {@code Formatter} with the given {@code Locale} and charset,
* and whose output is written to the specified {@code File}.
- *
+ *
* @param file
* the {@code File} that is used as the output destination for the
* {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File}
@@ -646,7 +623,6 @@
* to write to the {@code File} in {@code checkWrite(file.getPath())}.
* @throws UnsupportedEncodingException
* if the charset with the specified name is not supported.
- * @since Android 1.0
*/
public Formatter(File file, String csn, Locale l)
throws FileNotFoundException, UnsupportedEncodingException {
@@ -654,9 +630,9 @@
try {
fout = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(fout, csn);
- // BEGIN android-modified
+ // BEGIN android-changed
out = new BufferedWriter(writer, 8192);
- // END android-modified
+ // END android-changed
} catch (RuntimeException e) {
closeOutputStream(fout);
throw e;
@@ -670,37 +646,35 @@
/**
* Constructs a {@code Formatter} whose output is written to the specified {@code OutputStream}.
- *
+ *
* The charset of the {@code Formatter} is the default charset.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param os
* the stream to be used as the destination of the {@code Formatter}.
- * @since Android 1.0
*/
public Formatter(OutputStream os) {
OutputStreamWriter writer = new OutputStreamWriter(os, Charset
.defaultCharset());
- // BEGIN android-modified
+ // BEGIN android-changed
out = new BufferedWriter(writer, 8192);
- // END android-modified
+ // END android-changed
locale = Locale.getDefault();
}
/**
- * Constructs a {@code Formatter} with the given charset,
+ * Constructs a {@code Formatter} with the given charset,
* and whose output is written to the specified {@code OutputStream}.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param os
* the stream to be used as the destination of the {@code Formatter}.
* @param csn
* the name of the charset for the {@code Formatter}.
* @throws UnsupportedEncodingException
* if the charset with the specified name is not supported.
- * @since Android 1.0
*/
public Formatter(OutputStream os, String csn)
throws UnsupportedEncodingException {
@@ -709,9 +683,9 @@
}
/**
- * Constructs a {@code Formatter} with the given {@code Locale} and charset,
+ * Constructs a {@code Formatter} with the given {@code Locale} and charset,
* and whose output is written to the specified {@code OutputStream}.
- *
+ *
* @param os
* the stream to be used as the destination of the {@code Formatter}.
* @param csn
@@ -721,31 +695,29 @@
* then no localization will be used.
* @throws UnsupportedEncodingException
* if the charset with the specified name is not supported.
- * @since Android 1.0
*/
public Formatter(OutputStream os, String csn, Locale l)
throws UnsupportedEncodingException {
OutputStreamWriter writer = new OutputStreamWriter(os, csn);
- // BEGIN android-modified
+ // BEGIN android-changed
out = new BufferedWriter(writer, 8192);
- // END android-modified
+ // END android-changed
locale = l;
}
/**
* Constructs a {@code Formatter} whose output is written to the specified {@code PrintStream}.
- *
+ *
* The charset of the {@code Formatter} is the default charset.
- *
+ *
* The {@code Locale} for the {@code Formatter} is the default {@code Locale}.
- *
+ *
* @param ps
* the {@code PrintStream} used as destination of the {@code Formatter}. If
- * {@code ps} is {@code null}, then a {@ code NullPointerExcepiton} will
+ * {@code ps} is {@code null}, then a {@code NullPointerException} will
* be raised.
- * @since Android 1.0
*/
public Formatter(PrintStream ps) {
if (null == ps) {
@@ -763,11 +735,10 @@
/**
* Returns the {@code Locale} of the {@code Formatter}.
- *
+ *
* @return the {@code Locale} for the {@code Formatter} or {@code null} for no {@code Locale}.
* @throws FormatterClosedException
* if the {@code Formatter} has been closed.
- * @since Android 1.0
*/
public Locale locale() {
checkClosed();
@@ -776,11 +747,10 @@
/**
* Returns the output destination of the {@code Formatter}.
- *
+ *
* @return the output destination of the {@code Formatter}.
* @throws FormatterClosedException
* if the {@code Formatter} has been closed.
- * @since Android 1.0
*/
public Appendable out() {
checkClosed();
@@ -790,12 +760,11 @@
/**
* Returns the content by calling the {@code toString()} method of the output
* destination.
- *
+ *
* @return the content by calling the {@code toString()} method of the output
* destination.
* @throws FormatterClosedException
* if the {@code Formatter} has been closed.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -805,11 +774,10 @@
/**
* Flushes the {@code Formatter}. If the output destination is {@link Flushable},
- * then the method {@ code flush()} will be called on that destination.
- *
+ * then the method {@code flush()} will be called on that destination.
+ *
* @throws FormatterClosedException
* if the {@code Formatter} has been closed.
- * @since Android 1.0
*/
public void flush() {
checkClosed();
@@ -825,14 +793,12 @@
/**
* Closes the {@code Formatter}. If the output destination is {@link Closeable},
* then the method {@code close()} will be called on that destination.
- *
+ *
* If the {@code Formatter} has been closed, then calling the this method will have no
* effect.
- *
+ *
* Any method but the {@link #ioException()} that is called after the
* {@code Formatter} has been closed will raise a {@code FormatterClosedException}.
- *
- * @since Android 1.0
*/
public void close() {
closed = true;
@@ -850,10 +816,9 @@
* Returns the last {@code IOException} thrown by the {@code Formatter}'s output
* destination. If the {@code append()} method of the destination does not throw
* {@code IOException}s, the {@code ioException()} method will always return {@code null}.
- *
+ *
* @return the last {@code IOException} thrown by the {@code Formatter}'s output
* destination.
- * @since Android 1.0
*/
public IOException ioException() {
return lastIOException;
@@ -861,7 +826,7 @@
/**
* Writes a formatted string to the output destination of the {@code Formatter}.
- *
+ *
* @param format
* a format string.
* @param args
@@ -875,23 +840,22 @@
* the format string, or any other illegal situation.
* @throws FormatterClosedException
* if the {@code Formatter} has been closed.
- * @since Android 1.0
*/
public Formatter format(String format, Object... args) {
return format(locale, format, args);
}
-// BEGIN android-changed
+ // BEGIN android-added
/**
* Cached transformer. Improves performance when format() is called multiple
* times.
*/
private Transformer transformer;
-// END android-changed
+ // END android-added
/**
* Writes a formatted string to the output destination of the {@code Formatter}.
- *
+ *
* @param l
* the {@code Locale} used in the method. If {@code locale} is
* {@code null}, then no localization will be applied. This
@@ -910,7 +874,6 @@
* the format string, or any other illegal situation.
* @throws FormatterClosedException
* if the {@code Formatter} has been closed.
- * @since Android 1.0
*/
public Formatter format(Locale l, String format, Object... args) {
checkClosed();
@@ -1275,7 +1238,7 @@
break;
}
case 'n': {
- result = transfromFromLineSeparator();
+ result = transformFromLineSeparator();
break;
}
case 't':
@@ -1499,7 +1462,7 @@
* Transforms line separator to a formatted string. Any flag, the width
* or the precision is illegal.
*/
- private String transfromFromLineSeparator() {
+ private String transformFromLineSeparator() {
if (formatToken.isPrecisionSet()) {
throw new IllegalFormatPrecisionException(formatToken
.getPrecision());
@@ -2121,9 +2084,18 @@
boolean requireScientificRepresentation = true;
double d = ((Number) argument).doubleValue();
d = Math.abs(d);
- long l = Math.round(d);
+ if (Double.isInfinite(d)) {
+ precision = formatToken.getPrecision();
+ precision--;
+ formatToken.setPrecision(precision);
+ transform_e();
+ return;
+ }
+ BigDecimal b = new BigDecimal(d, new MathContext(precision));
+ d = b.doubleValue();
+ long l = b.longValue();
- if (l >= 1) {
+ if (d >= 1 && d < Math.pow(10, precision)) {
if (l < Math.pow(10, precision)) {
requireScientificRepresentation = false;
precision -= String.valueOf(l).length();
@@ -2137,19 +2109,20 @@
}
} else {
- l = Math.round(d * Math.pow(10, 4));
- if (l >= 1) {
+ l = b.movePointRight(4).longValue();
+ b.movePointLeft(4);
+ if (d >= Math.pow(10, -4) && d < 1) {
requireScientificRepresentation = false;
precision += 4 - String.valueOf(l).length();
- l = Math.round(d * Math.pow(10, precision + 1));
+ l = b.movePointRight(precision + 1).longValue();
+ b.movePointLeft(precision + 1);
if (String.valueOf(l).length() <= formatToken
.getPrecision()) {
precision++;
}
- l = Math.round(d * Math.pow(10, precision));
- if (l < Math.pow(10, precision - 4)) {
- requireScientificRepresentation = true;
- } else {
+ l = b.movePointRight(precision).longValue();
+ b.movePointLeft(precision);
+ if (l >= Math.pow(10, precision - 4)) {
formatToken.setPrecision(precision);
}
}
@@ -2461,9 +2434,10 @@
private void transform_Z() {
TimeZone timeZone = calendar.getTimeZone();
- result
- .append(timeZone.getDisplayName(true, TimeZone.SHORT,
- locale));
+ result.append(timeZone
+ .getDisplayName(
+ timeZone.inDaylightTime(calendar.getTime()),
+ TimeZone.SHORT, locale));
}
private void transform_z() {
diff --git a/luni/src/main/java/java/util/FormatterClosedException.java b/luni/src/main/java/java/util/FormatterClosedException.java
index 63d1052..e7e57ba 100644
--- a/luni/src/main/java/java/util/FormatterClosedException.java
+++ b/luni/src/main/java/java/util/FormatterClosedException.java
@@ -23,7 +23,6 @@
* closed.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class FormatterClosedException extends IllegalStateException implements
Serializable {
diff --git a/luni/src/main/java/java/util/GregorianCalendar.java b/luni/src/main/java/java/util/GregorianCalendar.java
index 32368ec..d8cd556 100644
--- a/luni/src/main/java/java/util/GregorianCalendar.java
+++ b/luni/src/main/java/java/util/GregorianCalendar.java
@@ -14,12 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
-*******************************************************************************
-* Copyright (C) 1996-2008, International Business Machines Corporation and *
-* others. All Rights Reserved. *
-*******************************************************************************
-*/
package java.util;
@@ -27,24 +21,19 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-// BEGIN android-note
-// The class javadoc and some of the method descriptions are copied from ICU4J
-// source files. Changes have been made to the copied descriptions.
-// The icu license header was added to this file.
-// END android-note
/**
* {@code GregorianCalendar} is a concrete subclass of {@link Calendar}
* and provides the standard calendar used by most of the world.
- *
+ *
* <p>
* The standard (Gregorian) calendar has 2 eras, BC and AD.
- *
+ *
* <p>
* This implementation handles a single discontinuity, which corresponds by
* default to the date the Gregorian calendar was instituted (October 15, 1582
* in some countries, later in others). The cutover date may be changed by the
* caller by calling {@code setGregorianChange()}.
- *
+ *
* <p>
* Historically, in those countries which adopted the Gregorian calendar first,
* October 4, 1582 was thus followed by October 15, 1582. This calendar models
@@ -53,7 +42,7 @@
* the Julian calendar is the leap year rule. The Julian calendar specifies leap
* years every four years, whereas the Gregorian calendar omits century years
* which are not divisible by 400.
- *
+ *
* <p>
* {@code GregorianCalendar} implements <em>proleptic</em> Gregorian
* and Julian calendars. That is, dates are computed by extrapolating the
@@ -64,13 +53,13 @@
* 4 AD onward, when modern Julian calendar rules were adopted. Before this
* date, leap year rules were applied irregularly, and before 45 BC the Julian
* calendar did not even exist.
- *
+ *
* <p>
* Prior to the institution of the Gregorian calendar, New Year's Day was March
* 25. To avoid confusion, this calendar always uses January 1. A manual
* adjustment may be made if desired for dates that are prior to the Gregorian
* changeover and which fall between January 1 and March 24.
- *
+ *
* <p>
* Values calculated for the {@code WEEK_OF_YEAR} field range from 1 to
* 53. Week 1 for a year is the earliest seven day period starting on
@@ -80,7 +69,7 @@
* {@code getFirstDayOfWeek()}, and the day of the week of January 1.
* Weeks between week 1 of one year and week 1 of the following year are
* numbered sequentially from 2 to 52 or 53 (as needed).
- *
+ *
* <p>
* For example, January 1, 1998 was a Thursday. If
* {@code getFirstDayOfWeek()} is {@code MONDAY} and
@@ -90,7 +79,7 @@
* {@code getFirstDayOfWeek()} is {@code SUNDAY}, then week 1 of
* 1998 starts on January 4, 1998, and ends on January 10, 1998; the first three
* days of 1998 then are part of week 53 of 1997.
- *
+ *
* <p>
* Values calculated for the {@code WEEK_OF_MONTH} field range from 0 or
* 1 to 4 or 5. Week 1 of a month (the days with <code>WEEK_OF_MONTH =
@@ -102,7 +91,7 @@
* {@code getFirstDayOfWeek()}, and will not include days of the
* previous month. Days of a month before week 1 have a
* {@code WEEK_OF_MONTH} of 0.
- *
+ *
* <p>
* For example, if {@code getFirstDayOfWeek()} is {@code SUNDAY}
* and {@code getMinimalDaysInFirstWeek()} is 4, then the first week of
@@ -111,10 +100,10 @@
* Saturday, January 3 have a {@code WEEK_OF_MONTH} of 0. If
* {@code getMinimalDaysInFirstWeek()} is changed to 3, then January 1
* through January 3 have a {@code WEEK_OF_MONTH} of 1.
- *
+ *
* <p>
* <strong>Example:</strong> <blockquote>
- *
+ *
* <pre>
* // get the supported ids for GMT-08:00 (Pacific Standard Time)
* String[] ids = TimeZone.getAvailableIDs(-8 * 60 * 60 * 1000);
@@ -186,13 +175,11 @@
* System.out.println("DST_OFFSET: "
* + (calendar.get(Calendar.DST_OFFSET)/(60*60*1000))); // in hours
* </pre>
- *
+ *
* </blockquote>
- *
+ *
* @see Calendar
* @see TimeZone
- *
- * @since Android 1.0
*/
public class GregorianCalendar extends Calendar {
@@ -200,18 +187,14 @@
/**
* Value for the BC era.
- *
- * @since Android 1.0
*/
public static final int BC = 0;
/**
* Value for the AD era.
- *
- * @since Android 1.0
*/
public static final int AD = 1;
-
+
private static final long defaultGregorianCutover = -12219292800000l;
private long gregorianCutover = defaultGregorianCutover;
@@ -251,8 +234,6 @@
/**
* Constructs a new {@code GregorianCalendar} initialized to the current date and
* time with the default {@code Locale} and {@code TimeZone}.
- *
- * @since Android 1.0
*/
public GregorianCalendar() {
this(TimeZone.getDefault(), Locale.getDefault());
@@ -261,14 +242,13 @@
/**
* Constructs a new {@code GregorianCalendar} initialized to midnight in the default
* {@code TimeZone} and {@code Locale} on the specified date.
- *
+ *
* @param year
* the year.
* @param month
* the month.
* @param day
* the day of the month.
- * @since Android 1.0
*/
public GregorianCalendar(int year, int month, int day) {
super(TimeZone.getDefault(), Locale.getDefault());
@@ -278,7 +258,7 @@
/**
* Constructs a new {@code GregorianCalendar} initialized to the specified date and
* time in the default {@code TimeZone} and {@code Locale}.
- *
+ *
* @param year
* the year.
* @param month
@@ -289,7 +269,6 @@
* the hour.
* @param minute
* the minute.
- * @since Android 1.0
*/
public GregorianCalendar(int year, int month, int day, int hour, int minute) {
super(TimeZone.getDefault(), Locale.getDefault());
@@ -299,7 +278,7 @@
/**
* Constructs a new {@code GregorianCalendar} initialized to the specified date and
* time in the default {@code TimeZone} and {@code Locale}.
- *
+ *
* @param year
* the year.
* @param month
@@ -312,7 +291,6 @@
* the minute.
* @param second
* the second.
- * @since Android 1.0
*/
public GregorianCalendar(int year, int month, int day, int hour,
int minute, int second) {
@@ -328,10 +306,9 @@
/**
* Constructs a new {@code GregorianCalendar} initialized to the current date and
* time and using the specified {@code Locale} and the default {@code TimeZone}.
- *
+ *
* @param locale
* the {@code Locale}.
- * @since Android 1.0
*/
public GregorianCalendar(Locale locale) {
this(TimeZone.getDefault(), locale);
@@ -340,10 +317,9 @@
/**
* Constructs a new {@code GregorianCalendar} initialized to the current date and
* time and using the specified {@code TimeZone} and the default {@code Locale}.
- *
+ *
* @param timezone
* the {@code TimeZone}.
- * @since Android 1.0
*/
public GregorianCalendar(TimeZone timezone) {
this(timezone, Locale.getDefault());
@@ -352,12 +328,11 @@
/**
* Constructs a new {@code GregorianCalendar} initialized to the current date and
* time and using the specified {@code TimeZone} and {@code Locale}.
- *
+ *
* @param timezone
* the {@code TimeZone}.
* @param locale
* the {@code Locale}.
- * @since Android 1.0
*/
public GregorianCalendar(TimeZone timezone, Locale locale) {
super(timezone, locale);
@@ -372,15 +347,14 @@
/**
* Adds the specified amount to a {@code Calendar} field.
- *
+ *
* @param field
* the {@code Calendar} field to modify.
* @param value
* the amount to add to the field.
- *
- * @exception IllegalArgumentException
- * when the specified field is DST_OFFSET or ZONE_OFFSET.
- * @since Android 1.0
+ *
+ * @throws IllegalArgumentException
+ * if the specified field is DST_OFFSET or ZONE_OFFSET.
*/
@Override
public void add(int field, int value) {
@@ -477,9 +451,8 @@
/**
* Creates new instance of {@code GregorianCalendar} with the same properties.
- *
+ *
* @return a shallow copy of this {@code GregorianCalendar}.
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -508,7 +481,7 @@
int dayOfYear = computeYearAndDay(days, timeVal + zoneOffset);
fields[DAY_OF_YEAR] = dayOfYear;
- if(fields[YEAR] == changeYear && gregorianCutover < timeVal + zoneOffset){
+ if(fields[YEAR] == changeYear && gregorianCutover <= timeVal + zoneOffset){
dayOfYear += currentYearSkew;
}
int month = dayOfYear / 32;
@@ -539,7 +512,7 @@
dayOfYear = computeYearAndDay(days, timeVal - zoneOffset
+ dstOffset);
fields[DAY_OF_YEAR] = dayOfYear;
- if(fields[YEAR] == changeYear && gregorianCutover < timeVal - zoneOffset + dstOffset){
+ if(fields[YEAR] == changeYear && gregorianCutover <= timeVal - zoneOffset + dstOffset){
dayOfYear += currentYearSkew;
}
month = dayOfYear / 32;
@@ -621,7 +594,9 @@
protected void computeFields() {
int zoneOffset = getTimeZone().getRawOffset();
- fields[ZONE_OFFSET] = zoneOffset;
+ if(!isSet[ZONE_OFFSET]) {
+ fields[ZONE_OFFSET] = zoneOffset;
+ }
int millis = (int) (time % 86400000);
int savedMillis = millis;
@@ -864,6 +839,9 @@
- (days + daysInMonth(leapYear, month) - 3))
+ fields[DAY_OF_WEEK_IN_MONTH] * 7;
}
+ } else if (isSet[DAY_OF_WEEK]) {
+ int skew = mod7(days - 3 - (getFirstDayOfWeek() - 1));
+ days += mod7(mod7(skew + dayOfWeek - (days - 3)) - skew);
}
}
} else {
@@ -967,7 +945,7 @@
return (year - 1970) * 365 + ((year - 1972) / 4)
- ((year - 2000) / 100) + ((year - 2000) / 400);
}
-
+
private int daysInMonth() {
return daysInMonth(isLeapYear(fields[YEAR]), fields[MONTH]);
}
@@ -1003,16 +981,15 @@
* Compares the specified {@code Object} to this {@code GregorianCalendar} and returns whether
* they are equal. To be equal, the {@code Object} must be an instance of {@code GregorianCalendar} and
* have the same properties.
- *
+ *
* @param object
* the {@code Object} to compare with this {@code GregorianCalendar}.
* @return {@code true} if {@code object} is equal to this
* {@code GregorianCalendar}, {@code false} otherwise.
- * @exception IllegalArgumentException
- * when the time is not set and the time cannot be computed
+ * @throws IllegalArgumentException
+ * if the time is not set and the time cannot be computed
* from the current field values.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -1023,11 +1000,10 @@
/**
* Gets the maximum value of the specified field for the current date. For
* example, the maximum number of days in the current month.
- *
+ *
* @param field
* the field.
* @return the maximum value of the specified field.
- * @since Android 1.0
*/
@Override
public int getActualMaximum(int field) {
@@ -1095,11 +1071,10 @@
* Gets the minimum value of the specified field for the current date. For
* the gregorian calendar, this value is the same as
* {@code getMinimum()}.
- *
+ *
* @param field
* the field.
* @return the minimum value of the specified field.
- * @since Android 1.0
*/
@Override
public int getActualMinimum(int field) {
@@ -1109,11 +1084,10 @@
/**
* Gets the greatest minimum value of the specified field. For the gregorian
* calendar, this value is the same as {@code getMinimum()}.
- *
+ *
* @param field
* the field.
* @return the greatest minimum value of the specified field.
- * @since Android 1.0
*/
@Override
public int getGreatestMinimum(int field) {
@@ -1123,9 +1097,8 @@
/**
* Returns the gregorian change date of this calendar. This is the date on
* which the gregorian calendar came into effect.
- *
+ *
* @return a {@code Date} which represents the gregorian change date.
- * @since Android 1.0
*/
public final Date getGregorianChange() {
return new Date(gregorianCutover);
@@ -1134,11 +1107,10 @@
/**
* Gets the smallest maximum value of the specified field. For example, 28
* for the day of month field.
- *
+ *
* @param field
* the field.
* @return the smallest maximum value of the specified field.
- * @since Android 1.0
*/
@Override
public int getLeastMaximum(int field) {
@@ -1158,11 +1130,10 @@
/**
* Gets the greatest maximum value of the specified field. For example, 31
* for the day of month field.
- *
+ *
* @param field
* the field.
* @return the greatest maximum value of the specified field.
- * @since Android 1.0
*/
@Override
public int getMaximum(int field) {
@@ -1171,11 +1142,10 @@
/**
* Gets the smallest minimum value of the specified field.
- *
+ *
* @param field
* the field.
* @return the smallest minimum value of the specified field.
- * @since Android 1.0
*/
@Override
public int getMinimum(int field) {
@@ -1234,11 +1204,10 @@
/**
* Returns an integer hash code for the receiver. Objects which are equal
* return the same value for this method.
- *
+ *
* @return the receiver's hash.
- *
+ *
* @see #equals
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -1248,12 +1217,11 @@
/**
* Returns whether the specified year is a leap year.
- *
+ *
* @param year
* the year.
* @return {@code true} if the specified year is a leap year, {@code false}
* otherwise.
- * @since Android 1.0
*/
public boolean isLeapYear(int year) {
if (year > changeYear) {
@@ -1288,15 +1256,14 @@
* field when it goes beyond the maximum or minimum value for the current
* date. Other fields will be adjusted as required to maintain a consistent
* date.
- *
+ *
* @param field
* the field to roll.
* @param value
* the amount to add.
- *
- * @exception IllegalArgumentException
- * when an invalid field is specified.
- * @since Android 1.0
+ *
+ * @throws IllegalArgumentException
+ * if an invalid field is specified.
*/
@Override
public void roll(int field, int value) {
@@ -1310,72 +1277,90 @@
isCached = false;
complete();
+ int days, day, mod, maxWeeks, newWeek;
int max = -1;
switch (field) {
- case YEAR:
- max = maximums[field];
- break;
- case WEEK_OF_YEAR:
- case WEEK_OF_MONTH:
- int days,
- day;
- if (field == WEEK_OF_YEAR) {
- days = daysInYear(fields[YEAR]);
- day = DAY_OF_YEAR;
+ case YEAR:
+ max = maximums[field];
+ break;
+ case WEEK_OF_YEAR:
+ days = daysInYear(fields[YEAR]);
+ day = DAY_OF_YEAR;
+ mod = mod7(fields[DAY_OF_WEEK] - fields[day]
+ - (getFirstDayOfWeek() - 1));
+ maxWeeks = (days - 1 + mod) / 7 + 1;
+ newWeek = mod(fields[field] - 1 + value, maxWeeks) + 1;
+ if (newWeek == maxWeeks) {
+ int addDays = (newWeek - fields[field]) * 7;
+ if (fields[day] > addDays && fields[day] + addDays > days) {
+ set(field, 1);
} else {
- days = daysInMonth();
- day = DATE;
+ set(field, newWeek - 1);
}
- int mod = mod7(fields[DAY_OF_WEEK] - fields[day]
- - (getFirstDayOfWeek() - 1));
- int maxWeeks = (days - 1 + mod) / 7 + 1;
- int newWeek = mod(fields[field] - 1 + value, maxWeeks) + 1;
- if (newWeek == maxWeeks) {
- if (fields[day] + (newWeek - fields[field]) * 7 > days) {
- set(day, days);
- } else {
- set(field, newWeek);
- }
- } else if (newWeek == 1) {
- int week = (fields[day] - ((fields[day] - 1) / 7 * 7) - 1 + mod) / 7 + 1;
- if (week > 1) {
- set(day, 1);
- } else {
- set(field, newWeek);
- }
+ } else if (newWeek == 1) {
+ int week = (fields[day] - ((fields[day] - 1) / 7 * 7) - 1 + mod) / 7 + 1;
+ if (week > 1) {
+ set(field, 1);
} else {
set(field, newWeek);
}
- break;
- case DATE:
- max = daysInMonth();
- break;
- case DAY_OF_YEAR:
- max = daysInYear(fields[YEAR]);
- break;
- case DAY_OF_WEEK:
- max = maximums[field];
- lastDateFieldSet = WEEK_OF_MONTH;
- break;
- case DAY_OF_WEEK_IN_MONTH:
- max = (fields[DATE] + ((daysInMonth() - fields[DATE]) / 7 * 7) - 1) / 7 + 1;
- break;
-
- case ERA:
- case MONTH:
- case AM_PM:
- case HOUR:
- case HOUR_OF_DAY:
- case MINUTE:
- case SECOND:
- case MILLISECOND:
- set(field, mod(fields[field] + value, maximums[field] + 1));
- if (field == MONTH && fields[DATE] > daysInMonth()) {
- set(DATE, daysInMonth());
- } else if (field == AM_PM) {
- lastTimeFieldSet = HOUR;
+ } else {
+ set(field, newWeek);
+ }
+ break;
+ case WEEK_OF_MONTH:
+ days = daysInMonth();
+ day = DATE;
+ mod = mod7(fields[DAY_OF_WEEK] - fields[day]
+ - (getFirstDayOfWeek() - 1));
+ maxWeeks = (days - 1 + mod) / 7 + 1;
+ newWeek = mod(fields[field] - 1 + value, maxWeeks) + 1;
+ if (newWeek == maxWeeks) {
+ if (fields[day] + (newWeek - fields[field]) * 7 > days) {
+ set(day, days);
+ } else {
+ set(field, newWeek);
}
- break;
+ } else if (newWeek == 1) {
+ int week = (fields[day] - ((fields[day] - 1) / 7 * 7) - 1 + mod) / 7 + 1;
+ if (week > 1) {
+ set(day, 1);
+ } else {
+ set(field, newWeek);
+ }
+ } else {
+ set(field, newWeek);
+ }
+ break;
+ case DATE:
+ max = daysInMonth();
+ break;
+ case DAY_OF_YEAR:
+ max = daysInYear(fields[YEAR]);
+ break;
+ case DAY_OF_WEEK:
+ max = maximums[field];
+ lastDateFieldSet = WEEK_OF_MONTH;
+ break;
+ case DAY_OF_WEEK_IN_MONTH:
+ max = (fields[DATE] + ((daysInMonth() - fields[DATE]) / 7 * 7) - 1) / 7 + 1;
+ break;
+
+ case ERA:
+ case MONTH:
+ case AM_PM:
+ case HOUR:
+ case HOUR_OF_DAY:
+ case MINUTE:
+ case SECOND:
+ case MILLISECOND:
+ set(field, mod(fields[field] + value, maximums[field] + 1));
+ if (field == MONTH && fields[DATE] > daysInMonth()) {
+ set(DATE, daysInMonth());
+ } else if (field == AM_PM) {
+ lastTimeFieldSet = HOUR;
+ }
+ break;
}
if (max != -1) {
set(field, mod(fields[field] - 1 + value, max) + 1);
@@ -1389,15 +1374,14 @@
* date. Other fields will be adjusted as required to maintain a consistent
* date. For example, March 31 will roll to April 30 when rolling the month
* field.
- *
+ *
* @param field
* the field to roll.
* @param increment
* {@code true} to increment the field, {@code false} to
* decrement.
- * @exception IllegalArgumentException
- * when an invalid field is specified.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if an invalid field is specified.
*/
@Override
public void roll(int field, boolean increment) {
@@ -1406,10 +1390,9 @@
/**
* Sets the gregorian change date of this calendar.
- *
+ *
* @param date
* a {@code Date} which represents the gregorian change date.
- * @since Android 1.0
*/
public void setGregorianChange(Date date) {
gregorianCutover = date.getTime();
diff --git a/luni/src/main/java/java/util/HashMap.java b/luni/src/main/java/java/util/HashMap.java
index 594e8a8..4ec7a1b 100644
--- a/luni/src/main/java/java/util/HashMap.java
+++ b/luni/src/main/java/java/util/HashMap.java
@@ -25,25 +25,46 @@
/**
* HashMap is an implementation of Map. All optional operations (adding and
* removing) are supported. Keys and values can be any objects.
- *
- * @since Android 1.0
*/
public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
Cloneable, Serializable {
+
private static final long serialVersionUID = 362498820763181265L;
+ /*
+ * Actual count of entries
+ */
transient int elementCount;
+ /*
+ * The internal data structure to hold Entries
+ */
transient Entry<K, V>[] elementData;
- final float loadFactor;
-
- int threshold;
-
+ /*
+ * modification count, to keep track of structural modifications between the
+ * HashMap and the iterator
+ */
transient int modCount = 0;
+ /*
+ * default size that an HashMap created using the default constructor would
+ * have.
+ */
private static final int DEFAULT_SIZE = 16;
+ /*
+ * maximum ratio of (stored elements)/(storage size) which does not lead to
+ * rehash
+ */
+ final float loadFactor;
+
+ /*
+ * maximum number of elements that can be put in this map before having to
+ * rehash
+ */
+ int threshold;
+
static class Entry<K, V> extends MapEntry<K, V> {
final int origKeyHash;
@@ -56,7 +77,7 @@
Entry(K theKey, V theValue) {
super(theKey, theValue);
- origKeyHash = (theKey == null ? 0 : theKey.hashCode());
+ origKeyHash = (theKey == null ? 0 : computeHashCode(theKey));
}
@Override
@@ -70,33 +91,27 @@
}
}
- static class HashMapIterator<E, KT, VT> implements Iterator<E> {
+ private static class AbstractMapIterator<K, V> {
private int position = 0;
-
int expectedModCount;
+ Entry<K, V> futureEntry;
+ Entry<K, V> currentEntry;
+ Entry<K, V> prevEntry;
- final MapEntry.Type<E, KT, VT> type;
+ final HashMap<K, V> associatedMap;
- boolean canRemove = false;
-
- Entry<KT, VT> entry;
-
- Entry<KT, VT> lastEntry;
-
- final HashMap<KT, VT> associatedMap;
-
- HashMapIterator(MapEntry.Type<E, KT, VT> value, HashMap<KT, VT> hm) {
+ AbstractMapIterator(HashMap<K, V> hm) {
associatedMap = hm;
- type = value;
expectedModCount = hm.modCount;
+ futureEntry = null;
}
public boolean hasNext() {
- if (entry != null) {
+ if (futureEntry != null) {
return true;
}
// BEGIN android-changed
- Entry<KT, VT>[] elementData = associatedMap.elementData;
+ Entry<K, V>[] elementData = associatedMap.elementData;
int length = elementData.length;
int newPosition = position;
boolean result = false;
@@ -115,58 +130,88 @@
// END android-changed
}
- void checkConcurrentMod() throws ConcurrentModificationException {
+ final void checkConcurrentMod() throws ConcurrentModificationException {
if (expectedModCount != associatedMap.modCount) {
throw new ConcurrentModificationException();
}
}
- public E next() {
+ final void makeNext() {
// BEGIN android-changed
// inline checkConcurrentMod()
if (expectedModCount != associatedMap.modCount) {
throw new ConcurrentModificationException();
}
+ // END android-changed
if (!hasNext()) {
throw new NoSuchElementException();
}
-
- MapEntry<KT, VT> result;
- Entry<KT, VT> _entry = entry;
- if (_entry == null) {
- result = lastEntry = associatedMap.elementData[position++];
- entry = lastEntry.next;
+ if (futureEntry == null) {
+ currentEntry = associatedMap.elementData[position++];
+ futureEntry = currentEntry.next;
+ prevEntry = null;
} else {
- if (lastEntry.next != _entry) {
- lastEntry = lastEntry.next;
+ if(currentEntry!=null){
+ prevEntry = currentEntry;
}
- result = _entry;
- entry = _entry.next;
+ currentEntry = futureEntry;
+ futureEntry = futureEntry.next;
}
- canRemove = true;
- return type.get(result);
- // END android-changed
}
- public void remove() {
+ public final void remove() {
checkConcurrentMod();
- if (!canRemove) {
+ if (currentEntry==null) {
throw new IllegalStateException();
}
-
- canRemove = false;
- associatedMap.modCount++;
- if (lastEntry.next == entry) {
- while (associatedMap.elementData[--position] == null) {
- // Do nothing
- }
- associatedMap.elementData[position] = associatedMap.elementData[position].next;
- entry = null;
+ if(prevEntry==null){
+ int index = currentEntry.origKeyHash & (associatedMap.elementData.length - 1);
+ associatedMap.elementData[index] = associatedMap.elementData[index].next;
} else {
- lastEntry.next = entry;
+ prevEntry.next = currentEntry.next;
}
- associatedMap.elementCount--;
+ currentEntry = null;
expectedModCount++;
+ associatedMap.modCount++;
+ associatedMap.elementCount--;
+
+ }
+ }
+
+
+ private static class EntryIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<Map.Entry<K, V>> {
+
+ EntryIterator (HashMap<K, V> map) {
+ super(map);
+ }
+
+ public Map.Entry<K, V> next() {
+ makeNext();
+ return currentEntry;
+ }
+ }
+
+ private static class KeyIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<K> {
+
+ KeyIterator (HashMap<K, V> map) {
+ super(map);
+ }
+
+ public K next() {
+ makeNext();
+ return currentEntry.key;
+ }
+ }
+
+ private static class ValueIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<V> {
+
+ ValueIterator (HashMap<K, V> map) {
+ super(map);
+ }
+
+ public V next() {
+ makeNext();
+ return currentEntry.value;
}
}
@@ -193,9 +238,13 @@
@Override
public boolean remove(Object object) {
- if (contains(object)) {
- associatedMap.remove(((Map.Entry<?, ?>) object).getKey());
- return true;
+ if (object instanceof Map.Entry) {
+ Map.Entry<?, ?> oEntry = (Map.Entry<?, ?>) object;
+ Entry<KT,VT> entry = associatedMap.getEntry(oEntry.getKey());
+ if(valuesEq(entry, oEntry)) {
+ associatedMap.removeEntry(entry);
+ return true;
+ }
}
return false;
}
@@ -203,31 +252,32 @@
@Override
public boolean contains(Object object) {
if (object instanceof Map.Entry) {
- Object key = ((Map.Entry<?, ?>) object).getKey();
- Entry entry;
- if (key == null) {
- entry = associatedMap.findNullKeyEntry();
- } else {
- int hash = key.hashCode();
- int index = (hash & 0x7FFFFFFF) % associatedMap.elementData.length;
- entry = associatedMap.findNonNullKeyEntry(key, index, hash);
- }
- return object.equals(entry);
+ Map.Entry<?, ?> oEntry = (Map.Entry<?, ?>) object;
+ Entry<KT, VT> entry = associatedMap.getEntry(oEntry.getKey());
+ return valuesEq(entry, oEntry);
}
return false;
}
+ private static boolean valuesEq(Entry entry, Map.Entry<?, ?> oEntry) {
+ return (entry != null) &&
+ ((entry.value == null) ?
+ (oEntry.getValue() == null) :
+ (areEqualValues(entry.value, oEntry.getValue())));
+ }
+
@Override
public Iterator<Map.Entry<KT, VT>> iterator() {
- return new HashMapIterator<Map.Entry<KT, VT>, KT, VT>(
- new MapEntry.Type<Map.Entry<KT, VT>, KT, VT>() {
- public Map.Entry<KT, VT> get(MapEntry<KT, VT> entry) {
- return entry;
- }
- }, associatedMap);
+ return new EntryIterator<KT,VT> (associatedMap);
}
}
+ /**
+ * Create a new element array
+ *
+ * @param s
+ * @return Reference to the element array
+ */
@SuppressWarnings("unchecked")
Entry<K, V>[] newElementArray(int s) {
return new Entry[s];
@@ -235,8 +285,6 @@
/**
* Constructs a new empty {@code HashMap} instance.
- *
- * @since Android 1.0
*/
public HashMap() {
this(DEFAULT_SIZE);
@@ -244,28 +292,47 @@
/**
* Constructs a new {@code HashMap} instance with the specified capacity.
- *
+ *
* @param capacity
* the initial capacity of this hash map.
* @throws IllegalArgumentException
* when the capacity is less than zero.
- * @since Android 1.0
*/
public HashMap(int capacity) {
- if (capacity >= 0) {
- elementCount = 0;
- elementData = newElementArray(capacity == 0 ? 1 : capacity);
- loadFactor = 0.75f; // Default load factor of 0.75
- computeMaxSize();
- } else {
- throw new IllegalArgumentException();
+ this(capacity, 0.75f); // default load factor of 0.75
}
+
+ /**
+ * Calculates the capacity of storage required for storing given number of
+ * elements
+ *
+ * @param x
+ * number of elements
+ * @return storage size
+ */
+ private static final int calculateCapacity(int x) {
+ if(x >= 1 << 30){
+ return 1 << 30;
+ }
+ if(x == 0){
+ return 16;
+ }
+ // BEGIN android-note
+ // this may be better optimized as Integer.highestOneBit(x)
+ // END android-note
+ x = x -1;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ return x + 1;
}
/**
* Constructs a new {@code HashMap} instance with the specified capacity and
* load factor.
- *
+ *
* @param capacity
* the initial capacity of this hash map.
* @param loadFactor
@@ -273,14 +340,14 @@
* @throws IllegalArgumentException
* when the capacity is less than zero or the load factor is
* less or equal to zero.
- * @since Android 1.0
*/
public HashMap(int capacity, float loadFactor) {
if (capacity >= 0 && loadFactor > 0) {
+ capacity = calculateCapacity(capacity);
elementCount = 0;
- elementData = newElementArray(capacity == 0 ? 1 : capacity);
+ elementData = newElementArray(capacity);
this.loadFactor = loadFactor;
- computeMaxSize();
+ computeThreshold();
} else {
throw new IllegalArgumentException();
}
@@ -289,29 +356,29 @@
/**
* Constructs a new {@code HashMap} instance containing the mappings from
* the specified map.
- *
+ *
* @param map
* the mappings to add.
- * @since Android 1.0
*/
public HashMap(Map<? extends K, ? extends V> map) {
- this(map.size() < 6 ? 11 : map.size() * 2);
+ this(calculateCapacity(map.size()));
putAllImpl(map);
}
- // BEGIN android-changed
/**
* Removes all mappings from this hash map, leaving it empty.
- *
+ *
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
@Override
public void clear() {
+ // BEGIN android-changed
internalClear();
+ // END android-changed
}
+ // BEGIN android-added
void internalClear() {
if (elementCount > 0) {
elementCount = 0;
@@ -319,89 +386,71 @@
modCount++;
}
}
- // END android-changed
+ // END android-added
/**
* Returns a shallow copy of this map.
- *
+ *
* @return a shallow copy of this map.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
public Object clone() {
try {
- // BEGIN android-changed
- // copied from newer version of harmony
HashMap<K, V> map = (HashMap<K, V>) super.clone();
+ map.elementCount = 0;
map.elementData = newElementArray(elementData.length);
- map.internalClear();
- Entry<K, V> entry;
- for (int i = 0; i < elementData.length; i++) {
- if ((entry = elementData[i]) != null){
- map.putImpl(entry.getKey(), entry.getValue());
- while (entry.next != null){
- entry = entry.next;
- map.putImpl(entry.getKey(), entry.getValue());
- }
- }
- // END android-changed
- }
+ map.putAll(this);
+
return map;
} catch (CloneNotSupportedException e) {
return null;
}
}
- private void computeMaxSize() {
+ /**
+ * Computes the threshold for rehashing
+ */
+ private void computeThreshold() {
threshold = (int) (elementData.length * loadFactor);
}
/**
* Returns whether this map contains the specified key.
- *
+ *
* @param key
* the key to search for.
* @return {@code true} if this map contains the specified key,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsKey(Object key) {
- Entry<K, V> m;
- if (key == null) {
- m = findNullKeyEntry();
- } else {
- int hash = key.hashCode();
- int index = (hash & 0x7FFFFFFF) % elementData.length;
- m = findNonNullKeyEntry(key, index, hash);
- }
+ Entry<K, V> m = getEntry(key);
return m != null;
}
/**
* Returns whether this map contains the specified value.
- *
+ *
* @param value
* the value to search for.
* @return {@code true} if this map contains the specified value,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsValue(Object value) {
if (value != null) {
- for (int i = elementData.length; --i >= 0;) {
+ for (int i = 0; i < elementData.length; i++) {
Entry<K, V> entry = elementData[i];
while (entry != null) {
- if (value.equals(entry.value)) {
+ if (areEqualValues(value, entry.value)) {
return true;
}
entry = entry.next;
}
}
} else {
- for (int i = elementData.length; --i >= 0;) {
+ for (int i = 0; i < elementData.length; i++) {
Entry<K, V> entry = elementData[i];
while (entry != null) {
if (entry.value == null) {
@@ -418,9 +467,8 @@
* Returns a set containing all of the mappings in this map. Each mapping is
* an instance of {@link Map.Entry}. As the set is backed by this map,
* changes in one will be reflected in the other.
- *
+ *
* @return a set of the mappings.
- * @since Android 1.0
*/
@Override
public Set<Map.Entry<K, V>> entrySet() {
@@ -429,54 +477,49 @@
/**
* Returns the value of the mapping with the specified key.
- *
+ *
* @param key
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
- * @since Android 1.0
*/
@Override
public V get(Object key) {
- Entry<K, V> m;
- if (key == null) {
- m = findNullKeyEntry();
- } else {
- int hash = key.hashCode();
- int index = (hash & 0x7FFFFFFF) % elementData.length;
- m = findNonNullKeyEntry(key, index, hash);
- }
+ Entry<K, V> m = getEntry(key);
if (m != null) {
return m.value;
}
return null;
}
+ final Entry<K, V> getEntry(Object key) {
+ Entry<K, V> m;
+ if (key == null) {
+ m = findNullKeyEntry();
+ } else {
+ int hash = computeHashCode(key);
+ int index = hash & (elementData.length - 1);
+ m = findNonNullKeyEntry(key, index, hash);
+ }
+ return m;
+ }
+
final Entry<K,V> findNonNullKeyEntry(Object key, int index, int keyHash) {
Entry<K,V> m = elementData[index];
+
// BEGIN android-changed
// The VM can optimize String.equals but not Object.equals
if (key instanceof String) {
String keyString = (String) key;
- while (m != null) {
- if (m.origKeyHash == keyHash) {
- if (keyString.equals(m.key)) {
- return m;
- }
- }
+ while (m != null && (m.origKeyHash != keyHash || !keyString.equals(m.key))) {
m = m.next;
}
} else {
- while (m != null) {
- if (m.origKeyHash == keyHash) {
- if (key.equals(m.key)) {
- return m;
- }
- }
+ while (m != null && (m.origKeyHash != keyHash || !areEqualKeys(key, m.key))) {
m = m.next;
}
}
- return null;
+ return m;
// END android-changed
}
@@ -489,11 +532,10 @@
/**
* Returns whether this map is empty.
- *
+ *
* @return {@code true} if this map has no elements, {@code false}
* otherwise.
* @see #size()
- * @since Android 1.0
*/
@Override
public boolean isEmpty() {
@@ -504,9 +546,8 @@
* Returns a set of the keys contained in this map. The set is backed by
* this map so changes to one are reflected by the other. The set does not
* support adding.
- *
+ *
* @return a set of the keys.
- * @since Android 1.0
*/
@Override
public Set<K> keySet() {
@@ -535,12 +576,7 @@
@Override
public Iterator<K> iterator() {
- return new HashMapIterator<K, K, V>(
- new MapEntry.Type<K, K, V>() {
- public K get(MapEntry<K, V> entry) {
- return entry.key;
- }
- }, HashMap.this);
+ return new KeyIterator<K,V> (HashMap.this);
}
};
}
@@ -549,21 +585,20 @@
/**
* Maps the specified key to the specified value.
- *
+ *
* @param key
* the key.
* @param value
* the value.
* @return the value of any previous mapping with the specified key or
* {@code null} if there was no such mapping.
- * @since Android 1.0
*/
@Override
public V put(K key, V value) {
return putImpl(key, value);
}
- private V putImpl(K key, V value) {
+ V putImpl(K key, V value) {
Entry<K,V> entry;
if(key == null) {
entry = findNullKeyEntry();
@@ -572,17 +607,17 @@
if (++elementCount > threshold) {
rehash();
}
- entry = createHashedEntry(key, 0, 0);
+ entry = createHashedEntry(null, 0, 0);
}
} else {
- int hash = key.hashCode();
- int index = (hash & 0x7FFFFFFF) % elementData.length;
+ int hash = computeHashCode(key);
+ int index = hash & (elementData.length - 1);
entry = findNonNullKeyEntry(key, index, hash);
if (entry == null) {
modCount++;
if (++elementCount > threshold) {
rehash();
- index = (hash & 0x7FFFFFFF) % elementData.length;
+ index = hash & (elementData.length - 1);
}
entry = createHashedEntry(key, index, hash);
}
@@ -611,10 +646,11 @@
* Copies all the mappings in the specified map to this map. These mappings
* will replace all mappings that this map had for any of the keys currently
* in the given map.
- *
+ *
* @param map
* the map to copy mappings from.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code map} is {@code null}.
*/
@Override
public void putAll(Map<? extends K, ? extends V> map) {
@@ -634,13 +670,13 @@
}
void rehash(int capacity) {
- int length = (capacity == 0 ? 1 : capacity << 1);
+ int length = calculateCapacity((capacity == 0 ? 1 : capacity << 1));
Entry<K, V>[] newData = newElementArray(length);
for (int i = 0; i < elementData.length; i++) {
Entry<K, V> entry = elementData[i];
while (entry != null) {
- int index = (entry.origKeyHash & 0x7FFFFFFF) % length;
+ int index = entry.origKeyHash & (length - 1);
Entry<K, V> next = entry.next;
entry.next = newData[index];
newData[index] = entry;
@@ -648,7 +684,7 @@
}
}
elementData = newData;
- computeMaxSize();
+ computeThreshold();
}
void rehash() {
@@ -657,12 +693,11 @@
/**
* Removes the mapping with the specified key from this map.
- *
+ *
* @param key
* the key of the mapping to remove.
* @return the value of the removed mapping or {@code null} if no mapping
* for the specified key was found.
- * @since Android 1.0
*/
@Override
public V remove(Object key) {
@@ -673,15 +708,35 @@
return null;
}
- Entry<K, V> removeEntry(Object key) {
+ /*
+ * Remove the given entry from the hashmap.
+ * Assumes that the entry is in the map.
+ */
+ final void removeEntry(Entry<K, V> entry) {
+ int index = entry.origKeyHash & (elementData.length - 1);
+ Entry<K, V> m = elementData[index];
+ if (m == entry) {
+ elementData[index] = entry.next;
+ } else {
+ while (m.next != entry) {
+ m = m.next;
+ }
+ m.next = entry.next;
+
+ }
+ modCount++;
+ elementCount--;
+ }
+
+ final Entry<K, V> removeEntry(Object key) {
int index = 0;
Entry<K, V> entry;
Entry<K, V> last = null;
if (key != null) {
- int hash = key.hashCode();
- index = (hash & 0x7FFFFFFF) % elementData.length;
+ int hash = computeHashCode(key);
+ index = hash & (elementData.length - 1);
entry = elementData[index];
- while (entry != null && !(entry.origKeyHash == hash && key.equals(entry.key))) {
+ while (entry != null && !(entry.origKeyHash == hash && areEqualKeys(key, entry.key))) {
last = entry;
entry = entry.next;
}
@@ -707,9 +762,8 @@
/**
* Returns the number of elements in this map.
- *
+ *
* @return the number of elements in this map.
- * @since Android 1.0
*/
@Override
public int size() {
@@ -727,16 +781,13 @@
* "wrapper object" over the iterator of map's entrySet(). The {@code size}
* method wraps the map's size method and the {@code contains} method wraps
* the map's containsValue method.
- * </p>
* <p>
* The collection is created when this method is called for the first time
* and returned in response to all subsequent calls. This method may return
* different collections when multiple concurrent calls occur, since no
* synchronization is performed.
- * </p>
- *
+ *
* @return a collection of the values contained in this map.
- * @since Android 1.0
*/
@Override
public Collection<V> values() {
@@ -759,12 +810,7 @@
@Override
public Iterator<V> iterator() {
- return new HashMapIterator<V, K, V>(
- new MapEntry.Type<V, K, V>() {
- public V get(MapEntry<K, V> entry) {
- return entry.value;
- }
- }, HashMap.this);
+ return new ValueIterator<K,V> (HashMap.this);
}
};
}
@@ -793,10 +839,25 @@
elementCount = stream.readInt();
for (int i = elementCount; --i >= 0;) {
K key = (K) stream.readObject();
- int index = (null == key) ? 0 : (key.hashCode() & 0x7FFFFFFF)
- % length;
+ int index = (null == key) ? 0 : (computeHashCode(key) & (length - 1));
createEntry(key, index, (V) stream.readObject());
}
}
+ /*
+ * Contract-related functionality
+ */
+ static int computeHashCode(Object key) {
+ return key.hashCode();
+}
+
+ static boolean areEqualKeys(Object key1, Object key2) {
+ return key1.equals(key2);
+ }
+
+ static boolean areEqualValues(Object value1, Object value2) {
+ return value1.equals(value2);
+ }
+
+
}
diff --git a/luni/src/main/java/java/util/HashSet.java b/luni/src/main/java/java/util/HashSet.java
index fe89109..dca764f 100644
--- a/luni/src/main/java/java/util/HashSet.java
+++ b/luni/src/main/java/java/util/HashSet.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -26,8 +25,6 @@
/**
* HashSet is an implementation of a Set. All optional operations (adding and
* removing) are supported. The elements can be any objects.
- *
- * @since Android 1.0
*/
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable,
Serializable {
@@ -38,8 +35,6 @@
/**
* Constructs a new empty instance of {@code HashSet}.
- *
- * @since Android 1.0
*/
public HashSet() {
this(new HashMap<E, HashSet<E>>());
@@ -50,7 +45,6 @@
*
* @param capacity
* the initial capacity of this {@code HashSet}.
- * @since Android 1.0
*/
public HashSet(int capacity) {
this(new HashMap<E, HashSet<E>>(capacity));
@@ -64,7 +58,6 @@
* the initial capacity.
* @param loadFactor
* the initial load factor.
- * @since Android 1.0
*/
public HashSet(int capacity, float loadFactor) {
this(new HashMap<E, HashSet<E>>(capacity, loadFactor));
@@ -76,10 +69,10 @@
*
* @param collection
* the collection of elements to add.
- * @since Android 1.0
*/
public HashSet(Collection<? extends E> collection) {
- this(new HashMap<E, HashSet<E>>(collection.size() < 6 ? 11 : collection.size() * 2));
+ this(new HashMap<E, HashSet<E>>(collection.size() < 6 ? 11 : collection
+ .size() * 2));
for (E e : collection) {
add(e);
}
@@ -96,7 +89,6 @@
* the object to add.
* @return {@code true} when this {@code HashSet} did not already contain
* the object, {@code false} otherwise
- * @since Android 1.0
*/
@Override
public boolean add(E object) {
@@ -108,7 +100,6 @@
*
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -121,7 +112,6 @@
*
* @return a shallow copy of this {@code HashSet}.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -142,7 +132,6 @@
* the object to search for.
* @return {@code true} if {@code object} is an element of this
* {@code HashSet}, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean contains(Object object) {
@@ -155,7 +144,6 @@
* @return {@code true} if this {@code HashSet} has no elements,
* {@code false} otherwise.
* @see #size
- * @since Android 1.0
*/
@Override
public boolean isEmpty() {
@@ -167,7 +155,6 @@
*
* @return an Iterator on the elements of this {@code HashSet}.
* @see Iterator
- * @since Android 1.0
*/
@Override
public Iterator<E> iterator() {
@@ -180,7 +167,6 @@
* @param object
* the object to remove.
* @return {@code true} if the object was removed, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean remove(Object object) {
@@ -191,7 +177,6 @@
* Returns the number of elements in this {@code HashSet}.
*
* @return the number of elements in this {@code HashSet}.
- * @since Android 1.0
*/
@Override
public int size() {
@@ -221,7 +206,7 @@
backingMap = createBackingMap(length, loadFactor);
int elementCount = stream.readInt();
for (int i = elementCount; --i >= 0;) {
- E key = (E)stream.readObject();
+ E key = (E) stream.readObject();
backingMap.put(key, this);
}
}
diff --git a/luni/src/main/java/java/util/Hashtable.java b/luni/src/main/java/java/util/Hashtable.java
index abede2d..f1c1f74 100644
--- a/luni/src/main/java/java/util/Hashtable.java
+++ b/luni/src/main/java/java/util/Hashtable.java
@@ -31,12 +31,11 @@
* factor is a float value which determines how full the Hashtable gets before
* expanding the capacity. If the load factor of the Hashtable is exceeded, the
* capacity is doubled.
- *
+ *
* @see Enumeration
* @see java.io.Serializable
* @see java.lang.Object#equals
* @see java.lang.Object#hashCode
- * @since Android 1.0
*/
public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>,
@@ -68,6 +67,21 @@
}
};
+ private static final Iterator<?> EMPTY_ITERATOR = new Iterator<Object>() {
+
+ public boolean hasNext() {
+ return false;
+ }
+
+ public Object next() {
+ throw new NoSuchElementException();
+ }
+
+ public void remove() {
+ throw new IllegalStateException();
+ }
+ };
+
private static <K, V> Entry<K, V> newEntry(K key, V value, int hash) {
return new Entry<K, V>(key, value);
}
@@ -121,16 +135,16 @@
}
}
- private final class HashIterator<E> implements Iterator<E> {
- private int position, expectedModCount;
+ private class HashIterator<E> implements Iterator<E> {
+ int position, expectedModCount;
- private final MapEntry.Type<E, K, V> type;
+ final MapEntry.Type<E, K, V> type;
- private Entry<K, V> lastEntry;
+ Entry<K, V> lastEntry;
- private int lastPosition;
+ int lastPosition;
- private boolean canRemove = false;
+ boolean canRemove = false;
HashIterator(MapEntry.Type<E, K, V> value) {
type = value;
@@ -218,47 +232,9 @@
}
}
- private final class HashEnumerator<E> implements Enumeration<E> {
- boolean key;
-
- int start;
-
- Entry<K, V> entry;
-
- HashEnumerator(boolean isKey) {
- key = isKey;
- start = lastSlot + 1;
- }
-
- public boolean hasMoreElements() {
- if (entry != null) {
- return true;
- }
- while (--start >= firstSlot) {
- if (elementData[start] != null) {
- entry = elementData[start];
- return true;
- }
- }
- return false;
- }
-
- @SuppressWarnings("unchecked")
- public E nextElement() {
- if (hasMoreElements()) {
- Object result = key ? entry.key : entry.value;
- entry = entry.next;
- return (E) result;
- }
- throw new NoSuchElementException();
- }
- }
-
/**
* Constructs a new {@code Hashtable} using the default capacity and load
* factor.
- *
- * @since Android 1.0
*/
public Hashtable() {
this(11);
@@ -267,10 +243,9 @@
/**
* Constructs a new {@code Hashtable} using the specified capacity and the
* default load factor.
- *
+ *
* @param capacity
* the initial capacity.
- * @since Android 1.0
*/
public Hashtable(int capacity) {
if (capacity >= 0) {
@@ -287,12 +262,11 @@
/**
* Constructs a new {@code Hashtable} using the specified capacity and load
* factor.
- *
+ *
* @param capacity
* the initial capacity.
* @param loadFactor
* the initial load factor.
- * @since Android 1.0
*/
public Hashtable(int capacity, float loadFactor) {
if (capacity >= 0 && loadFactor > 0) {
@@ -309,10 +283,9 @@
/**
* Constructs a new instance of {@code Hashtable} containing the mappings
* from the specified map.
- *
+ *
* @param map
* the mappings to add.
- * @since Android 1.0
*/
public Hashtable(Map<? extends K, ? extends V> map) {
this(map.size() < 6 ? 11 : (map.size() * 4 / 3) + 11);
@@ -327,10 +300,9 @@
/**
* Removes all key/value pairs from this {@code Hashtable}, leaving the
* size zero and the capacity unchanged.
- *
+ *
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
public synchronized void clear() {
elementCount = 0;
@@ -341,17 +313,16 @@
/**
* Returns a new {@code Hashtable} with the same key/value pairs, capacity
* and load factor.
- *
+ *
* @return a shallow copy of this {@code Hashtable}.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
public synchronized Object clone() {
try {
Hashtable<K, V> hashtable = (Hashtable<K, V>) super.clone();
- hashtable.elementData = elementData.clone();
+ hashtable.elementData = new Entry[elementData.length];
Entry<K, V> entry;
for (int i = elementData.length; --i >= 0;) {
if ((entry = elementData[i]) != null) {
@@ -371,14 +342,13 @@
/**
* Returns true if this {@code Hashtable} contains the specified object as
* the value of at least one of the key/value pairs.
- *
+ *
* @param value
* the object to look for as a value in this {@code Hashtable}.
* @return {@code true} if object is a value in this {@code Hashtable},
* {@code false} otherwise.
* @see #containsKey
* @see java.lang.Object#equals
- * @since Android 1.0
*/
public synchronized boolean contains(Object value) {
if (value == null) {
@@ -388,7 +358,7 @@
for (int i = elementData.length; --i >= 0;) {
Entry<K, V> entry = elementData[i];
while (entry != null) {
- if (value.equals(entry.value)) {
+ if (entry.value.equals(value)) {
return true;
}
entry = entry.next;
@@ -400,14 +370,13 @@
/**
* Returns true if this {@code Hashtable} contains the specified object as a
* key of one of the key/value pairs.
- *
+ *
* @param key
* the object to look for as a key in this {@code Hashtable}.
* @return {@code true} if object is a key in this {@code Hashtable},
* {@code false} otherwise.
* @see #contains
* @see java.lang.Object#equals
- * @since Android 1.0
*/
public synchronized boolean containsKey(Object key) {
return getEntry(key) != null;
@@ -415,12 +384,11 @@
/**
* Searches this {@code Hashtable} for the specified value.
- *
+ *
* @param value
* the object to search for.
* @return {@code true} if {@code value} is a value of this
* {@code Hashtable}, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean containsValue(Object value) {
return contains(value);
@@ -430,12 +398,11 @@
* Returns an enumeration on the values of this {@code Hashtable}. The
* results of the Enumeration may be affected if the contents of this
* {@code Hashtable} are modified.
- *
+ *
* @return an enumeration of the values of this {@code Hashtable}.
* @see #keys
* @see #size
* @see Enumeration
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -443,7 +410,11 @@
if (elementCount == 0) {
return (Enumeration<V>) EMPTY_ENUMERATION;
}
- return new HashEnumerator<V>(false);
+ return new HashEnumIterator<V>(new MapEntry.Type<V, K, V>() {
+ public V get(MapEntry<K, V> entry) {
+ return entry.value;
+ }
+ }, true);
}
/**
@@ -451,18 +422,15 @@
* element in the set is a {@link Map.Entry}. The set is backed by this
* {@code Hashtable} so changes to one are reflected by the other. The set
* does not support adding.
- *
+ *
* @return a set of the mappings.
- * @since Android 1.0
*/
public Set<Map.Entry<K, V>> entrySet() {
return new Collections.SynchronizedSet<Map.Entry<K, V>>(
new AbstractSet<Map.Entry<K, V>>() {
@Override
public int size() {
- synchronized (Hashtable.this) {
- return elementCount;
- }
+ return elementCount;
}
@Override
@@ -473,25 +441,20 @@
@Override
@SuppressWarnings("unchecked")
public boolean remove(Object object) {
- synchronized (Hashtable.this) {
- if (contains(object)) {
- Hashtable.this
- .remove(((Map.Entry<K, V>) object)
- .getKey());
- return true;
- }
- return false;
+ if (contains(object)) {
+ Hashtable.this.remove(((Map.Entry<K, V>) object)
+ .getKey());
+ return true;
}
+ return false;
}
@Override
@SuppressWarnings("unchecked")
public boolean contains(Object object) {
- synchronized (Hashtable.this) {
- Entry<K, V> entry = getEntry(((Map.Entry<K, V>) object)
- .getKey());
- return object.equals(entry);
- }
+ Entry<K, V> entry = getEntry(((Map.Entry<K, V>) object)
+ .getKey());
+ return object.equals(entry);
}
@Override
@@ -511,13 +474,12 @@
* Compares this {@code Hashtable} with the specified object and indicates
* if they are equal. In order to be equal, {@code object} must be an
* instance of Map and contain the same key/value pairs.
- *
+ *
* @param object
* the object to compare with this object.
* @return {@code true} if the specified object is equal to this Map,
* {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public synchronized boolean equals(Object object) {
@@ -544,13 +506,12 @@
/**
* Returns the value associated with the specified key in this
* {@code Hashtable}.
- *
+ *
* @param key
* the key of the value returned.
* @return the value associated with the specified key, or {@code null} if
* the specified key does not exist.
* @see #put
- * @since Android 1.0
*/
@Override
public synchronized V get(Object key) {
@@ -597,11 +558,10 @@
/**
* Returns true if this {@code Hashtable} has no key/value pairs.
- *
+ *
* @return {@code true} if this {@code Hashtable} has no key/value pairs,
* {@code false} otherwise.
* @see #size
- * @since Android 1.0
*/
@Override
public synchronized boolean isEmpty() {
@@ -612,12 +572,11 @@
* Returns an enumeration on the keys of this {@code Hashtable} instance.
* The results of the enumeration may be affected if the contents of this
* {@code Hashtable} are modified.
- *
+ *
* @return an enumeration of the keys of this {@code Hashtable}.
* @see #elements
* @see #size
* @see Enumeration
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -625,31 +584,30 @@
if (elementCount == 0) {
return (Enumeration<K>) EMPTY_ENUMERATION;
}
- return new HashEnumerator<K>(true);
+ return new HashEnumIterator<K>(new MapEntry.Type<K, K, V>() {
+ public K get(MapEntry<K, V> entry) {
+ return entry.key;
+ }
+ }, true);
}
/**
* Returns a set of the keys contained in this {@code Hashtable}. The set
* is backed by this {@code Hashtable} so changes to one are reflected by
* the other. The set does not support adding.
- *
+ *
* @return a set of the keys.
- * @since Android 1.0
*/
public Set<K> keySet() {
return new Collections.SynchronizedSet<K>(new AbstractSet<K>() {
@Override
public boolean contains(Object object) {
- synchronized (Hashtable.this) {
- return containsKey(object);
- }
+ return containsKey(object);
}
@Override
public int size() {
- synchronized (Hashtable.this) {
- return elementCount;
- }
+ return elementCount;
}
@Override
@@ -659,18 +617,19 @@
@Override
public boolean remove(Object key) {
- synchronized (Hashtable.this) {
- if (containsKey(key)) {
- Hashtable.this.remove(key);
- return true;
- }
- return false;
+ if (containsKey(key)) {
+ Hashtable.this.remove(key);
+ return true;
}
+ return false;
}
@Override
public Iterator<K> iterator() {
- return new HashIterator<K>(new MapEntry.Type<K, K, V>() {
+ if (this.size() == 0) {
+ return (Iterator<K>) EMPTY_ITERATOR;
+ }
+ return new HashEnumIterator<K>(new MapEntry.Type<K, K, V>() {
public K get(MapEntry<K, V> entry) {
return entry.key;
}
@@ -679,11 +638,89 @@
}, this);
}
+ class HashEnumIterator<E> extends HashIterator<E> implements Enumeration<E> {
+
+ private boolean isEnumeration = false;
+
+ int start;
+
+ Entry<K, V> entry;
+
+ HashEnumIterator(MapEntry.Type<E, K, V> value) {
+ super(value);
+ }
+
+ HashEnumIterator(MapEntry.Type<E, K, V> value, boolean isEnumeration) {
+ super(value);
+ this.isEnumeration = isEnumeration;
+ start = lastSlot + 1;
+ }
+
+ public boolean hasMoreElements() {
+ if (isEnumeration) {
+ if (entry != null) {
+ return true;
+ }
+ while (start > firstSlot) {
+ if (elementData[--start] != null) {
+ entry = elementData[start];
+ return true;
+ }
+ }
+ return false;
+ }
+ // iterator
+ return super.hasNext();
+ }
+
+ public boolean hasNext() {
+ if (isEnumeration) {
+ return hasMoreElements();
+ }
+ // iterator
+ return super.hasNext();
+ }
+
+ public E next() {
+ if (isEnumeration) {
+ if (expectedModCount == modCount) {
+ return nextElement();
+ } else {
+ throw new ConcurrentModificationException();
+ }
+ }
+ // iterator
+ return super.next();
+ }
+
+ @SuppressWarnings("unchecked")
+ public E nextElement() {
+ if (isEnumeration) {
+ if (hasMoreElements()) {
+ Object result = type.get(entry);
+ entry = entry.next;
+ return (E) result;
+ }
+ throw new NoSuchElementException();
+ }
+ // iterator
+ return super.next();
+ }
+
+ public void remove() {
+ if (isEnumeration) {
+ throw new UnsupportedOperationException();
+ } else {
+ super.remove();
+ }
+ }
+ }
+
/**
* Associate the specified value with the specified key in this
* {@code Hashtable}. If the key already exists, the old value is replaced.
* The key and value cannot be null.
- *
+ *
* @param key
* the key to add.
* @param value
@@ -694,7 +731,6 @@
* @see #get
* @see #keys
* @see java.lang.Object#equals
- * @since Android 1.0
*/
@Override
public synchronized V put(K key, V value) {
@@ -731,10 +767,9 @@
/**
* Copies every mapping to this {@code Hashtable} from the specified map.
- *
+ *
* @param map
* the map to copy mappings from.
- * @since Android 1.0
*/
public synchronized void putAll(Map<? extends K, ? extends V> map) {
for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) {
@@ -745,8 +780,6 @@
/**
* Increases the capacity of this {@code Hashtable}. This method is called
* when the size of this {@code Hashtable} exceeds the load factor.
- *
- * @since Android 1.0
*/
protected void rehash() {
int length = (elementData.length << 1) + 1;
@@ -781,14 +814,13 @@
/**
* Removes the key/value pair with the specified key from this
* {@code Hashtable}.
- *
+ *
* @param key
* the key to remove.
* @return the value associated with the specified key, or {@code null} if
* the specified key did not exist.
* @see #get
* @see #put
- * @since Android 1.0
*/
@Override
public synchronized V remove(Object key) {
@@ -817,11 +849,10 @@
/**
* Returns the number of key/value pairs in this {@code Hashtable}.
- *
+ *
* @return the number of key/value pairs in this {@code Hashtable}.
* @see #elements
* @see #keys
- * @since Android 1.0
*/
@Override
public synchronized int size() {
@@ -830,9 +861,8 @@
/**
* Returns the string representation of this {@code Hashtable}.
- *
+ *
* @return the string representation of this {@code Hashtable}.
- * @since Android 1.0
*/
@Override
public synchronized String toString() {
@@ -874,25 +904,20 @@
* Returns a collection of the values contained in this {@code Hashtable}.
* The collection is backed by this {@code Hashtable} so changes to one are
* reflected by the other. The collection does not support adding.
- *
+ *
* @return a collection of the values.
- * @since Android 1.0
*/
public Collection<V> values() {
return new Collections.SynchronizedCollection<V>(
new AbstractCollection<V>() {
@Override
public boolean contains(Object object) {
- synchronized (Hashtable.this) {
- return Hashtable.this.contains(object);
- }
+ return Hashtable.this.contains(object);
}
@Override
public int size() {
- synchronized (Hashtable.this) {
- return elementCount;
- }
+ return elementCount;
}
@Override
diff --git a/luni/src/main/java/java/util/HugeEnumSet.java b/luni/src/main/java/java/util/HugeEnumSet.java
index 1d43360..fd3e1bd 100644
--- a/luni/src/main/java/java/util/HugeEnumSet.java
+++ b/luni/src/main/java/java/util/HugeEnumSet.java
@@ -92,6 +92,8 @@
currentElementMask = unProcessedBits[bitsPosition]
& (-unProcessedBits[bitsPosition]);
unProcessedBits[bitsPosition] -= currentElementMask;
+ int index = Long.numberOfTrailingZeros(currentElementMask)
+ + bitsPosition * BIT_IN_LONG;
if (0 == unProcessedBits[bitsPosition]) {
int oldBitsPosition = bitsPosition;
findNextNoneZeroPosition(bitsPosition + 1);
@@ -99,8 +101,7 @@
canProcess = false;
}
}
- return enums[Long.numberOfTrailingZeros(currentElementMask)
- + bitsPosition * BIT_IN_LONG];
+ return enums[index];
}
public void remove() {
@@ -185,6 +186,7 @@
}
}
+ @SuppressWarnings("unchecked")
@Override
public boolean contains(Object object) {
if (null == object) {
@@ -329,7 +331,7 @@
// endElementInBits + 1 is the number of consecutive ones.
// 63 - endElementInBits is the following zeros of the right most one.
- range = -1l >>> (BIT_IN_LONG - (endElementInBits + 1)) << (63 - endElementInBits);
+ range = -1l >>> (BIT_IN_LONG - (endElementInBits + 1));
size -= Long.bitCount(bits[endBitsIndex]);
bits[endBitsIndex] |= range;
size += Long.bitCount(bits[endBitsIndex]);
diff --git a/luni/src/main/java/java/util/IdentityHashMap.java b/luni/src/main/java/java/util/IdentityHashMap.java
index 3301a99..30330b5 100644
--- a/luni/src/main/java/java/util/IdentityHashMap.java
+++ b/luni/src/main/java/java/util/IdentityHashMap.java
@@ -30,16 +30,15 @@
* <p>
* <b>Note: This class intentionally violates the general contract of {@code
* Map}'s on comparing objects by their {@code equals} method.</b>
- * </p>
* <p>
* IdentityHashMap uses open addressing (linear probing in particular) for
* collision resolution. This is different from HashMap which uses Chaining.
- * </p>
+ * <p>
* Like HashMap, IdentityHashMap is not thread safe, so access by multiple
* threads must be synchronized by an external mechanism such as
* Collections.synchronizedMap.
*
- * @since Android 1.0
+ * @since 1.4
*/
public class IdentityHashMap<K, V> extends AbstractMap<K, V> implements
Map<K, V>, Serializable, Cloneable {
@@ -239,8 +238,6 @@
/**
* Creates an IdentityHashMap with default expected maximum size.
- *
- * @since Android 1.0
*/
public IdentityHashMap() {
this(DEFAULT_MAX_SIZE);
@@ -252,7 +249,6 @@
* @param maxSize
* The estimated maximum number of entries that will be put in
* this map.
- * @since Android 1.0
*/
public IdentityHashMap(int maxSize) {
if (maxSize >= 0) {
@@ -274,6 +270,13 @@
return (int) (((long) threshold * 10000) / loadFactor) * 2;
}
+ /**
+ * Create a new element array
+ *
+ * @param s
+ * the number of elements
+ * @return Reference to the element array
+ */
private Object[] newElementArray(int s) {
return new Object[s];
}
@@ -283,7 +286,6 @@
*
* @param map
* A map of (key,value) pairs to copy into the IdentityHashMap.
- * @since Android 1.0
*/
public IdentityHashMap(Map<? extends K, ? extends V> map) {
this(map.size() < 6 ? 11 : map.size() * 2);
@@ -300,7 +302,6 @@
*
* @see #isEmpty()
* @see #size()
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -318,7 +319,6 @@
* the key to search for.
* @return {@code true} if this map contains the specified key,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsKey(Object key) {
@@ -337,7 +337,6 @@
* the value to search for.
* @return {@code true} if this map contains the specified value,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsValue(Object value) {
@@ -359,7 +358,6 @@
* @param key
* the key.
* @return the value of the mapping with the specified key.
- * @since Android 1.0
*/
@Override
public V get(Object key) {
@@ -390,6 +388,10 @@
return null;
}
+ /**
+ * Convenience method for getting the IdentityHashMapEntry without the
+ * NULL_OBJECT elements
+ */
@SuppressWarnings("unchecked")
private IdentityHashMapEntry<K, V> getEntry(int index) {
Object key = elementData[index];
@@ -405,6 +407,10 @@
return new IdentityHashMapEntry<K, V>((K) key, (V) value);
}
+ /**
+ * Returns the index where the key is found at, or the index of the next
+ * empty spot if the key is not found in this table.
+ */
private int findIndex(Object key, Object[] array) {
int length = array.length;
int index = getModuloHash(key, length);
@@ -435,7 +441,6 @@
* the value.
* @return the value of any previous mapping with the specified key or
* {@code null} if there was no such mapping.
- * @since Android 1.0
*/
@Override
public V put(K key, V value) {
@@ -478,7 +483,8 @@
*
* @param map
* the map to copy mappings from.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code map} is {@code null}.
*/
@Override
public void putAll(Map<? extends K, ? extends V> map) {
@@ -515,7 +521,6 @@
* the key of the mapping to remove.
* @return the value of the removed mapping, or {@code null} if no mapping
* for the specified key was found.
- * @since Android 1.0
*/
@Override
public V remove(Object key) {
@@ -575,7 +580,6 @@
* changes in one will be reflected in the other.
*
* @return a set of the mappings.
- * @since Android 1.0
*/
@Override
public Set<Map.Entry<K, V>> entrySet() {
@@ -588,7 +592,6 @@
* support adding.
*
* @return a set of the keys.
- * @since Android 1.0
*/
@Override
public Set<K> keySet() {
@@ -643,16 +646,13 @@
* "wrapper object" over the iterator of map's entrySet(). The {@code size}
* method wraps the map's size method and the {@code contains} method wraps
* the map's containsValue method.
- * </p>
* <p>
* The collection is created when this method is called for the first time
* and returned in response to all subsequent calls. This method may return
* different collections when multiple concurrent calls occur, since no
* synchronization is performed.
- * </p>
*
* @return a collection of the values contained in this map.
- * @since Android 1.0
*/
@Override
public Collection<V> values() {
@@ -710,7 +710,6 @@
* @param object
* the object to compare to.
* @return whether the argument object is equal to this object.
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -745,7 +744,6 @@
*
* @return a shallow copy of this IdentityHashMap.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -762,7 +760,6 @@
* @return {@code true} if this IdentityHashMap has no elements,
* {@code false} otherwise.
* @see #size()
- * @since Android 1.0
*/
@Override
public boolean isEmpty() {
@@ -773,7 +770,6 @@
* Returns the number of mappings in this IdentityHashMap.
*
* @return the number of mappings in this IdentityHashMap.
- * @since Android 1.0
*/
@Override
public int size() {
diff --git a/luni/src/main/java/java/util/IllegalFormatCodePointException.java b/luni/src/main/java/java/util/IllegalFormatCodePointException.java
index e04eeba..c0d6b6f 100644
--- a/luni/src/main/java/java/util/IllegalFormatCodePointException.java
+++ b/luni/src/main/java/java/util/IllegalFormatCodePointException.java
@@ -24,7 +24,6 @@
* passed as a parameter to a Formatter.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class IllegalFormatCodePointException extends IllegalFormatException
implements Serializable {
diff --git a/luni/src/main/java/java/util/IllegalFormatConversionException.java b/luni/src/main/java/java/util/IllegalFormatConversionException.java
index 769381b..696f4f2 100644
--- a/luni/src/main/java/java/util/IllegalFormatConversionException.java
+++ b/luni/src/main/java/java/util/IllegalFormatConversionException.java
@@ -23,7 +23,8 @@
* is incompatible with the corresponding format specifier.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public class IllegalFormatConversionException extends IllegalFormatException
implements Serializable {
diff --git a/luni/src/main/java/java/util/IllegalFormatException.java b/luni/src/main/java/java/util/IllegalFormatException.java
index 2c1f2d7..3d37cd0 100644
--- a/luni/src/main/java/java/util/IllegalFormatException.java
+++ b/luni/src/main/java/java/util/IllegalFormatException.java
@@ -24,7 +24,6 @@
* allowed to be instantiated.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class IllegalFormatException extends IllegalArgumentException implements
Serializable {
diff --git a/luni/src/main/java/java/util/IllegalFormatFlagsException.java b/luni/src/main/java/java/util/IllegalFormatFlagsException.java
index 6b27c74..4fa2d9c 100644
--- a/luni/src/main/java/java/util/IllegalFormatFlagsException.java
+++ b/luni/src/main/java/java/util/IllegalFormatFlagsException.java
@@ -23,7 +23,6 @@
* the format flags is illegal.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class IllegalFormatFlagsException extends IllegalFormatException
implements Serializable {
diff --git a/luni/src/main/java/java/util/IllegalFormatPrecisionException.java b/luni/src/main/java/java/util/IllegalFormatPrecisionException.java
index 6ccf5d2..5d5113f 100644
--- a/luni/src/main/java/java/util/IllegalFormatPrecisionException.java
+++ b/luni/src/main/java/java/util/IllegalFormatPrecisionException.java
@@ -21,7 +21,6 @@
* a negative other than -1 or in other cases where precision is not supported.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class IllegalFormatPrecisionException extends IllegalFormatException {
diff --git a/luni/src/main/java/java/util/IllegalFormatWidthException.java b/luni/src/main/java/java/util/IllegalFormatWidthException.java
index 8348ec7..01904f8 100644
--- a/luni/src/main/java/java/util/IllegalFormatWidthException.java
+++ b/luni/src/main/java/java/util/IllegalFormatWidthException.java
@@ -22,7 +22,6 @@
* supported.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class IllegalFormatWidthException extends IllegalFormatException {
diff --git a/luni/src/main/java/java/util/InputMismatchException.java b/luni/src/main/java/java/util/InputMismatchException.java
index 0fc5385..eed0b83 100644
--- a/luni/src/main/java/java/util/InputMismatchException.java
+++ b/luni/src/main/java/java/util/InputMismatchException.java
@@ -24,13 +24,12 @@
*
* @see Scanner
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class InputMismatchException extends NoSuchElementException implements
Serializable {
- static final long serialVersionUID = 8811230760997066428L;
-
+ private static final long serialVersionUID = 8811230760997066428L;
+
/**
* Constructs a new {@code InputMismatchException} with the current stack
* trace filled in.
diff --git a/luni/src/main/java/java/util/InvalidPropertiesFormatException.java b/luni/src/main/java/java/util/InvalidPropertiesFormatException.java
index 4e8a3e3..015c3d0 100644
--- a/luni/src/main/java/java/util/InvalidPropertiesFormatException.java
+++ b/luni/src/main/java/java/util/InvalidPropertiesFormatException.java
@@ -30,8 +30,6 @@
* Even though this Exception inherits the {@code Serializable} interface, it is not
* serializable. The methods used for serialization throw
* {@code NotSerializableException}s.
- *
- * @since Android 1.0
*/
public class InvalidPropertiesFormatException extends IOException {
diff --git a/luni/src/main/java/java/util/Iterator.java b/luni/src/main/java/java/util/Iterator.java
index 9f20dc5..6ebae04 100644
--- a/luni/src/main/java/java/util/Iterator.java
+++ b/luni/src/main/java/java/util/Iterator.java
@@ -17,17 +17,18 @@
package java.util;
-
/**
- * An Iterator is used to sequence over a collection of objects. Conceptual, an
- * iterator is always positioned between two elements of a collection. A fresh
- * iterator is always positioned in front of the first element.
+ * An {@code Iterator} is used to sequence over a collection of objects.
+ * Conceptually, an iterator is always positioned between two elements of a
+ * collection. A fresh iterator is always positioned in front of the first
+ * element.
*
* If a collection has been changed since its creation, methods {@code next} and
* {@code hasNext()} may throw a {@code ConcurrentModificationException}.
* Iterators with this behavior are called fail-fast iterators.
*
- * @since Android 1.0
+ * @param <E>
+ * the type of object returned by the iterator.
*/
public interface Iterator<E> {
/**
@@ -36,7 +37,6 @@
*
* @return {@code true} if there are more elements, {@code false} otherwise.
* @see #next
- * @since Android 1.0
*/
public boolean hasNext();
@@ -48,7 +48,6 @@
* @throws NoSuchElementException
* if there are no more elements.
* @see #hasNext
- * @since Android 1.0
*/
public E next();
@@ -62,7 +61,6 @@
* @throws IllegalStateException
* if {@code next} has not been called, or {@code remove} has
* already been called after the last call to {@code next}.
- * @since Android 1.0
*/
public void remove();
}
diff --git a/luni/src/main/java/java/util/LinkedHashMap.java b/luni/src/main/java/java/util/LinkedHashMap.java
index a32a28b..ed526d8 100644
--- a/luni/src/main/java/java/util/LinkedHashMap.java
+++ b/luni/src/main/java/java/util/LinkedHashMap.java
@@ -17,7 +17,6 @@
package java.util;
-
/**
* LinkedHashMap is a variant of HashMap. Its entries are kept in a
* doubly-linked list. The iteration order is, by default, the order in which
@@ -46,8 +45,8 @@
* elements during iteration. It is not possible to guarantee that this
* mechanism works in all cases of unsynchronized concurrent modification. It
* should only be used for debugging purposes.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public class LinkedHashMap<K, V> extends HashMap<K, V> {
@@ -59,8 +58,6 @@
/**
* Constructs a new empty {@code LinkedHashMap} instance.
- *
- * @since Android 1.0
*/
public LinkedHashMap() {
super();
@@ -71,12 +68,11 @@
/**
* Constructs a new {@code LinkedHashMap} instance with the specified
* capacity.
- *
+ *
* @param s
* the initial capacity of this map.
- * @exception IllegalArgumentException
- * when the capacity is less than zero.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if the capacity is less than zero.
*/
public LinkedHashMap(int s) {
super(s);
@@ -87,7 +83,7 @@
/**
* Constructs a new {@code LinkedHashMap} instance with the specified
* capacity and load factor.
- *
+ *
* @param s
* the initial capacity of this map.
* @param lf
@@ -95,7 +91,6 @@
* @throws IllegalArgumentException
* when the capacity is less than zero or the load factor is
* less or equal to zero.
- * @since Android 1.0
*/
public LinkedHashMap(int s, float lf) {
super(s, lf);
@@ -107,7 +102,7 @@
/**
* Constructs a new {@code LinkedHashMap} instance with the specified
* capacity, load factor and a flag specifying the ordering behavior.
- *
+ *
* @param s
* the initial capacity of this hash map.
* @param lf
@@ -120,7 +115,6 @@
* @throws IllegalArgumentException
* when the capacity is less than zero or the load factor is
* less or equal to zero.
- * @since Android 1.0
*/
public LinkedHashMap(int s, float lf, boolean order) {
super(s, lf);
@@ -132,10 +126,9 @@
/**
* Constructs a new {@code LinkedHashMap} instance containing the mappings
* from the specified map. The order of the elements is preserved.
- *
+ *
* @param m
* the mappings to add.
- * @since Android 1.0
*/
public LinkedHashMap(Map<? extends K, ? extends V> m) {
accessOrder = false;
@@ -144,58 +137,47 @@
putAll(m);
}
- static final class LinkedHashIterator<E, KT, VT> extends HashMapIterator<E, KT, VT> {
- LinkedHashIterator(MapEntry.Type<E, KT, VT> value, LinkedHashMap<KT, VT> hm) {
- super(value, hm);
- entry = hm.head;
+ private static class AbstractMapIterator<K, V> {
+ int expectedModCount;
+ LinkedHashMapEntry<K, V> futureEntry;
+ LinkedHashMapEntry<K, V> currentEntry;
+ final LinkedHashMap<K, V> associatedMap;
+
+ AbstractMapIterator(LinkedHashMap<K, V> map) {
+ expectedModCount = map.modCount;
+ futureEntry = map.head;
+ associatedMap = map;
}
- @Override
public boolean hasNext() {
- return (entry != null);
+ return (futureEntry != null);
}
- @Override
- public E next() {
+ final void checkConcurrentMod() throws ConcurrentModificationException {
+ if (expectedModCount != associatedMap.modCount) {
+ throw new ConcurrentModificationException();
+ }
+ }
+
+ final void makeNext() {
checkConcurrentMod();
if (!hasNext()) {
throw new NoSuchElementException();
}
- E result = type.get(entry);
- lastEntry = entry;
- entry = ((LinkedHashMapEntry<KT, VT>)entry).chainForward;
- canRemove = true;
- return result;
+ currentEntry = futureEntry;
+ futureEntry = futureEntry.chainForward;
}
- @Override
public void remove() {
checkConcurrentMod();
- if (!canRemove) {
+ if (currentEntry==null) {
throw new IllegalStateException();
}
-
- canRemove = false;
- associatedMap.modCount++;
-
- int index = (lastEntry.key == null)? 0 : (lastEntry.key.hashCode() & 0x7FFFFFFF) % associatedMap.elementData.length;
- LinkedHashMapEntry<KT, VT> m = (LinkedHashMapEntry<KT, VT>) associatedMap.elementData[index];
- if (m == lastEntry) {
- associatedMap.elementData[index] = lastEntry.next;
- } else {
- while (m.next != null) {
- if (m.next == lastEntry) {
- break;
- }
- m = (LinkedHashMapEntry<KT, VT>) m.next;
- }
- // assert m.next == entry
- m.next = lastEntry.next;
- }
- LinkedHashMapEntry<KT, VT> lhme = (LinkedHashMapEntry<KT, VT>) lastEntry;
- LinkedHashMapEntry<KT, VT> p = lhme.chainBackward;
- LinkedHashMapEntry<KT, VT> n = lhme.chainForward;
- LinkedHashMap<KT, VT> lhm = (LinkedHashMap<KT, VT>) associatedMap;
+ associatedMap.removeEntry(currentEntry);
+ LinkedHashMapEntry<K, V> lhme = currentEntry;
+ LinkedHashMapEntry<K, V> p = lhme.chainBackward;
+ LinkedHashMapEntry<K, V> n = lhme.chainForward;
+ LinkedHashMap<K, V> lhm = associatedMap;
if (p != null) {
p.chainForward = n;
if (n != null) {
@@ -211,23 +193,56 @@
lhm.tail = null;
}
}
- associatedMap.elementCount--;
+ currentEntry = null;
expectedModCount++;
}
}
- static final class LinkedHashMapEntrySet<KT, VT> extends HashMapEntrySet<KT, VT> {
+ private static class EntryIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<Map.Entry<K, V>> {
+
+ EntryIterator (LinkedHashMap<K, V> map) {
+ super(map);
+ }
+
+ public Map.Entry<K, V> next() {
+ makeNext();
+ return currentEntry;
+ }
+ }
+
+ private static class KeyIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<K> {
+
+ KeyIterator (LinkedHashMap<K, V> map) {
+ super(map);
+ }
+
+ public K next() {
+ makeNext();
+ return currentEntry.key;
+ }
+ }
+
+ private static class ValueIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<V> {
+
+ ValueIterator (LinkedHashMap<K, V> map) {
+ super(map);
+ }
+
+ public V next() {
+ makeNext();
+ return currentEntry.value;
+ }
+ }
+
+ static final class LinkedHashMapEntrySet<KT, VT> extends
+ HashMapEntrySet<KT, VT> {
public LinkedHashMapEntrySet(LinkedHashMap<KT, VT> lhm) {
super(lhm);
}
@Override
- public Iterator<Map.Entry<KT,VT>> iterator() {
- return new LinkedHashIterator<Map.Entry<KT,VT>,KT,VT>(new MapEntry.Type<Map.Entry<KT,VT>, KT, VT>() {
- public Map.Entry<KT,VT> get(MapEntry<KT,VT> entry) {
- return entry;
- }
- }, (LinkedHashMap<KT, VT>) hashMap());
+ public Iterator<Map.Entry<KT, VT>> iterator() {
+ return new EntryIterator<KT,VT>((LinkedHashMap<KT, VT>) hashMap());
}
}
@@ -246,11 +261,11 @@
chainBackward = null;
}
-
@Override
@SuppressWarnings("unchecked")
public Object clone() {
- LinkedHashMapEntry<K, V> entry = (LinkedHashMapEntry<K, V>) super.clone();
+ LinkedHashMapEntry<K, V> entry = (LinkedHashMapEntry<K, V>) super
+ .clone();
entry.chainBackward = chainBackward;
entry.chainForward = chainForward;
LinkedHashMapEntry<K, V> lnext = (LinkedHashMapEntry<K, V>) entry.next;
@@ -262,6 +277,33 @@
}
@Override
+ public boolean containsValue(Object value) {
+ LinkedHashMapEntry<K, V> entry = head;
+ if (null == value) {
+ while (null != entry) {
+ if (null == entry.value) {
+ return true;
+ }
+ entry = entry.chainForward;
+ }
+ } else {
+ while (null != entry) {
+ if (value.equals(entry.value)) {
+ return true;
+ }
+ entry = entry.chainForward;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Create a new element array
+ *
+ * @param s
+ * @return Reference to the element array
+ */
+ @Override
@SuppressWarnings("unchecked")
Entry<K, V>[] newElementArray(int s) {
return new LinkedHashMapEntry[s];
@@ -269,22 +311,21 @@
/**
* Returns the value of the mapping with the specified key.
- *
+ *
* @param key
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
- * @since Android 1.0
*/
@Override
public V get(Object key) {
LinkedHashMapEntry<K, V> m;
if (key == null) {
- m = (LinkedHashMapEntry<K, V>)findNullKeyEntry();
+ m = (LinkedHashMapEntry<K, V>) findNullKeyEntry();
} else {
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % elementData.length;
- m = (LinkedHashMapEntry<K, V>)findNonNullKeyEntry(key, index, hash);
+ m = (LinkedHashMapEntry<K, V>) findNonNullKeyEntry(key, index, hash);
}
if (m == null) {
return null;
@@ -321,7 +362,7 @@
return m;
}
- Entry<K,V> createHashedEntry(K key, int index, int hash) {
+ Entry<K, V> createHashedEntry(K key, int index, int hash) {
LinkedHashMapEntry<K, V> m = new LinkedHashMapEntry<K, V>(key, hash);
m.next = elementData[index];
elementData[index] = m;
@@ -329,22 +370,19 @@
return m;
}
- // BEGIN android-changed
- // copied from newer version of harmony
/**
* Maps the specified key to the specified value.
- *
+ *
* @param key
* the key.
* @param value
* the value.
* @return the value of any previous mapping with the specified key or
* {@code null} if there was no such mapping.
- * @since Android 1.0
*/
@Override
public V put(K key, V value) {
- V result = putImpl(key,value);
+ V result = putImpl(key, value);
if (removeEldestEntry(head)) {
remove(head.key);
@@ -352,38 +390,38 @@
return result;
}
-
- V putImpl(K key, V value){
+
+ V putImpl(K key, V value) {
LinkedHashMapEntry<K, V> m;
- if (elementCount == 0){
+ if (elementCount == 0) {
head = tail = null;
}
if (key == null) {
- m = (LinkedHashMapEntry<K, V>)findNullKeyEntry();
+ m = (LinkedHashMapEntry<K, V>) findNullKeyEntry();
if (m == null) {
modCount++;
- // Check if we need to remove the oldest entry
- // The check includes accessOrder since an accessOrder LinkedHashMap
- // does not record
- // the oldest member in 'head'.
+ // Check if we need to remove the oldest entry. The check
+ // includes accessOrder since an accessOrder LinkedHashMap does
+ // not record the oldest member in 'head'.
if (++elementCount > threshold) {
rehash();
}
- m = (LinkedHashMapEntry<K, V>) createHashedEntry(null, 0, 0);
+ m = (LinkedHashMapEntry<K, V>) createHashedEntry(null, 0, 0);
} else {
linkEntry(m);
}
} else {
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % elementData.length;
- m = (LinkedHashMapEntry<K, V>)findNonNullKeyEntry(key, index, hash);
+ m = (LinkedHashMapEntry<K, V>) findNonNullKeyEntry(key, index, hash);
if (m == null) {
modCount++;
if (++elementCount > threshold) {
rehash();
index = (hash & 0x7FFFFFFF) % elementData.length;
}
- m = (LinkedHashMapEntry<K, V>) createHashedEntry(key, index, hash);
+ m = (LinkedHashMapEntry<K, V>) createHashedEntry(key, index,
+ hash);
} else {
linkEntry(m);
}
@@ -393,7 +431,6 @@
m.value = value;
return result;
}
- // END android-changed
/*
* @param m
@@ -448,16 +485,14 @@
tail.chainForward = m;
tail = m;
}
-
}
/**
* Returns a set containing all of the mappings in this map. Each mapping is
* an instance of {@link Map.Entry}. As the set is backed by this map,
* changes in one will be reflected in the other.
- *
+ *
* @return a set of the mappings.
- * @since Android 1.0
*/
@Override
public Set<Map.Entry<K, V>> entrySet() {
@@ -468,9 +503,8 @@
* Returns a set of the keys contained in this map. The set is backed by
* this map so changes to one are reflected by the other. The set does not
* support adding.
- *
+ *
* @return a set of the keys.
- * @since Android 1.0
*/
@Override
public Set<K> keySet() {
@@ -502,11 +536,7 @@
@Override
public Iterator<K> iterator() {
- return new LinkedHashIterator<K,K,V>(new MapEntry.Type<K,K,V>() {
- public K get(MapEntry<K,V> entry) {
- return entry.key;
- }
- }, LinkedHashMap.this);
+ return new KeyIterator<K,V>(LinkedHashMap.this);
}
};
}
@@ -524,16 +554,13 @@
* "wrapper object" over the iterator of map's entrySet(). The size method
* wraps the map's size method and the contains method wraps the map's
* containsValue method.
- * </p>
* <p>
* The collection is created when this method is called for the first time
* and returned in response to all subsequent calls. This method may return
* different collections when multiple concurrent calls occur, since no
* synchronization is performed.
- * </p>
- *
+ *
* @return a collection of the values contained in this map.
- * @since Android 1.0
*/
@Override
public Collection<V> values() {
@@ -556,11 +583,7 @@
@Override
public Iterator<V> iterator() {
- return new LinkedHashIterator<V,K,V>(new MapEntry.Type<V,K,V>() {
- public V get(MapEntry<K,V> entry) {
- return entry.value;
- }
- }, LinkedHashMap.this);
+ return new ValueIterator<K,V>(LinkedHashMap.this);
}
};
}
@@ -569,12 +592,11 @@
/**
* Removes the mapping with the specified key from this map.
- *
+ *
* @param key
* the key of the mapping to remove.
* @return the value of the removed mapping or {@code null} if no mapping
* for the specified key was found.
- * @since Android 1.0
*/
@Override
public V remove(Object key) {
@@ -602,23 +624,21 @@
* eldest member of the map should be deleted before adding the new member.
* If this map was created with accessOrder = true, then the result of
* removeEldestEntry is assumed to be false.
- *
+ *
* @param eldest
* the entry to check if it should be removed.
* @return {@code true} if the eldest member should be removed.
- * @since Android 1.0
*/
- protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
+ protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return false;
}
// BEGIN android-changed
/**
* Removes all elements from this map, leaving it empty.
- *
+ *
* @see #isEmpty()
* @see #size()
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -631,25 +651,4 @@
head = tail = null;
}
// END android-changed
-
- // BEGIN android-removed
- // copied from newer version of harmony
- // /**
- // * Answers a new HashMap with the same mappings and size as this HashMap.
- // *
- // * @return a shallow copy of this HashMap
- // *
- // * @see java.lang.Cloneable
- // */
- // @Override
- // @SuppressWarnings("unchecked")
- // public Object clone() {
- // LinkedHashMap<K, V> map = (LinkedHashMap<K, V>) super.clone();
- // map.clear();
- // for (Map.Entry<K, V> entry : entrySet()) {
- // map.put(entry.getKey(), entry.getValue());
- // }
- // return map;
- // }
- // END android-removed
}
diff --git a/luni/src/main/java/java/util/LinkedHashSet.java b/luni/src/main/java/java/util/LinkedHashSet.java
index 943e01c..3add460 100644
--- a/luni/src/main/java/java/util/LinkedHashSet.java
+++ b/luni/src/main/java/java/util/LinkedHashSet.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.io.Serializable;
/**
@@ -30,18 +29,16 @@
* Like HashSet, LinkedHashSet is not thread safe, so access by multiple threads
* must be synchronized by an external mechanism such as
* {@link Collections#synchronizedSet(Set)}.
- *
- * @since Android 1.0
+ *
+ * @since 1.4
*/
public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable,
Serializable {
-
+
private static final long serialVersionUID = -2851667679971038690L;
/**
* Constructs a new empty instance of {@code LinkedHashSet}.
- *
- * @since Android 1.0
*/
public LinkedHashSet() {
super(new LinkedHashMap<E, HashSet<E>>());
@@ -53,7 +50,6 @@
*
* @param capacity
* the initial capacity of this {@code LinkedHashSet}.
- * @since Android 1.0
*/
public LinkedHashSet(int capacity) {
super(new LinkedHashMap<E, HashSet<E>>(capacity));
@@ -67,7 +63,6 @@
* the initial capacity.
* @param loadFactor
* the initial load factor.
- * @since Android 1.0
*/
public LinkedHashSet(int capacity, float loadFactor) {
super(new LinkedHashMap<E, HashSet<E>>(capacity, loadFactor));
@@ -79,7 +74,6 @@
*
* @param collection
* the collection of elements to add.
- * @since Android 1.0
*/
public LinkedHashSet(Collection<? extends E> collection) {
super(new LinkedHashMap<E, HashSet<E>>(collection.size() < 6 ? 11
diff --git a/luni/src/main/java/java/util/LinkedList.java b/luni/src/main/java/java/util/LinkedList.java
index 7cfefe6..64326e3 100644
--- a/luni/src/main/java/java/util/LinkedList.java
+++ b/luni/src/main/java/java/util/LinkedList.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -28,12 +27,12 @@
* LinkedList is an implementation of List, backed by a linked list. All
* optional operations (adding, removing and replacing) are supported. The
* elements can be any objects.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public class LinkedList<E> extends AbstractSequentialList<E> implements
List<E>, Queue<E>, Cloneable, Serializable {
-
+
private static final long serialVersionUID = 876323262645176354L;
transient int size = 0;
@@ -178,8 +177,6 @@
/**
* Constructs a new empty instance of {@code LinkedList}.
- *
- * @since Android 1.0
*/
public LinkedList() {
voidLink = new Link<E>(null, null, null);
@@ -192,10 +189,9 @@
* elements contained in the specified {@code collection}. The order of the
* elements in this new {@code LinkedList} will be determined by the
* iteration order of {@code collection}.
- *
+ *
* @param collection
* the collection of elements to add.
- * @since Android 1.0
*/
public LinkedList(Collection<? extends E> collection) {
this();
@@ -207,14 +203,13 @@
* specified location. The object is inserted before any previous element at
* the specified location. If the location is equal to the size of this
* {@code LinkedList}, the object is added at the end.
- *
+ *
* @param location
* the index at which to insert.
* @param object
* the object to add.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
- * @since Android 1.0
*/
@Override
public void add(int location, E object) {
@@ -242,11 +237,10 @@
/**
* Adds the specified object at the end of this {@code LinkedList}.
- *
+ *
* @param object
* the object to add.
* @return always true
- * @since Android 1.0
*/
@Override
public boolean add(E object) {
@@ -264,7 +258,7 @@
* Inserts the objects in the specified collection at the specified location
* in this {@code LinkedList}. The objects are added in the order they are
* returned from the collection's iterator.
- *
+ *
* @param location
* the index at which to insert.
* @param collection
@@ -277,7 +271,6 @@
* if an object cannot be added to this list.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || > size()}
- * @since Android 1.0
*/
@Override
public boolean addAll(int location, Collection<? extends E> collection) {
@@ -288,6 +281,9 @@
if (adding == 0) {
return false;
}
+ Collection<? extends E> elements = (collection == this) ?
+ new ArrayList<E>(collection) : collection;
+
Link<E> previous = voidLink;
if (location < (size / 2)) {
for (int i = 0; i < location; i++) {
@@ -299,7 +295,7 @@
}
}
Link<E> next = previous.next;
- for (E e : collection) {
+ for (E e : elements) {
Link<E> newLink = new Link<E>(e, previous, null);
previous.next = newLink;
previous = newLink;
@@ -311,15 +307,13 @@
return true;
}
-
/**
* Adds the objects in the specified Collection to this {@code LinkedList}.
- *
+ *
* @param collection
* the collection of objects.
* @return {@code true} if this {@code LinkedList} is modified,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean addAll(Collection<? extends E> collection) {
@@ -327,8 +321,11 @@
if (adding == 0) {
return false;
}
+ Collection<? extends E> elements = (collection == this) ?
+ new ArrayList<E>(collection) : collection;
+
Link<E> previous = voidLink.previous;
- for (E e : collection) {
+ for (E e : elements) {
Link<E> newLink = new Link<E>(e, previous, null);
previous.next = newLink;
previous = newLink;
@@ -342,10 +339,9 @@
/**
* Adds the specified object at the beginning of this {@code LinkedList}.
- *
+ *
* @param object
* the object to add.
- * @since Android 1.0
*/
public void addFirst(E object) {
Link<E> oldFirst = voidLink.next;
@@ -358,10 +354,9 @@
/**
* Adds the specified object at the end of this {@code LinkedList}.
- *
+ *
* @param object
* the object to add.
- * @since Android 1.0
*/
public void addLast(E object) {
Link<E> oldLast = voidLink.previous;
@@ -374,10 +369,9 @@
/**
* Removes all elements from this {@code LinkedList}, leaving it empty.
- *
+ *
* @see List#isEmpty
* @see #size
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -392,10 +386,9 @@
/**
* Returns a new {@code LinkedList} with the same elements and size as this
* {@code LinkedList}.
- *
+ *
* @return a shallow copy of this {@code LinkedList}.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
@Override
@@ -415,12 +408,11 @@
/**
* Searches this {@code LinkedList} for the specified object.
- *
+ *
* @param object
* the object to search for.
* @return {@code true} if {@code object} is an element of this
* {@code LinkedList}, {@code false} otherwise
- * @since Android 1.0
*/
@Override
public boolean contains(Object object) {
@@ -463,11 +455,10 @@
/**
* Returns the first element in this {@code LinkedList}.
- *
+ *
* @return the first element.
* @throws NoSuchElementException
* if this {@code LinkedList} is empty.
- * @since Android 1.0
*/
public E getFirst() {
Link<E> first = voidLink.next;
@@ -479,11 +470,10 @@
/**
* Returns the last element in this {@code LinkedList}.
- *
+ *
* @return the last element
* @throws NoSuchElementException
* if this {@code LinkedList} is empty
- * @since Android 1.0
*/
public E getLast() {
Link<E> last = voidLink.previous;
@@ -520,12 +510,11 @@
/**
* Searches this {@code LinkedList} for the specified object and returns the
* index of the last occurrence.
- *
+ *
* @param object
* the object to search for
* @return the index of the last occurrence of the object, or -1 if it was
* not found.
- * @since Android 1.0
*/
@Override
public int lastIndexOf(Object object) {
@@ -555,14 +544,13 @@
* Returns a ListIterator on the elements of this {@code LinkedList}. The
* elements are iterated in the same order that they occur in the
* {@code LinkedList}. The iteration starts at the specified location.
- *
+ *
* @param location
* the index at which to start the iteration
* @return a ListIterator on the elements of this {@code LinkedList}
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
* @see ListIterator
- * @since Android 1.0
*/
@Override
public ListIterator<E> listIterator(int location) {
@@ -571,13 +559,12 @@
/**
* Removes the object at the specified location from this {@code LinkedList}.
- *
+ *
* @param location
* the index of the object to remove
* @return the removed object
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
- * @since Android 1.0
*/
@Override
public E remove(int location) {
@@ -629,11 +616,10 @@
/**
* Removes the first object from this {@code LinkedList}.
- *
+ *
* @return the removed object.
* @throws NoSuchElementException
* if this {@code LinkedList} is empty.
- * @since Android 1.0
*/
public E removeFirst() {
Link<E> first = voidLink.next;
@@ -650,11 +636,10 @@
/**
* Removes the last object from this {@code LinkedList}.
- *
+ *
* @return the removed object.
* @throws NoSuchElementException
* if this {@code LinkedList} is empty.
- * @since Android 1.0
*/
public E removeLast() {
Link<E> last = voidLink.previous;
@@ -672,7 +657,7 @@
/**
* Replaces the element at the specified location in this {@code LinkedList}
* with the specified object.
- *
+ *
* @param location
* the index at which to put the specified object.
* @param object
@@ -684,7 +669,6 @@
* if an object cannot be added to this list.
* @throws IndexOutOfBoundsException
* if {@code location < 0 || >= size()}
- * @since Android 1.0
*/
@Override
public E set(int location, E object) {
@@ -708,15 +692,14 @@
/**
* Returns the number of elements in this {@code LinkedList}.
- *
+ *
* @return the number of elements in this {@code LinkedList}.
- * @since Android 1.0
*/
@Override
public int size() {
return size;
}
-
+
public boolean offer(E o) {
add(o);
return true;
@@ -742,9 +725,8 @@
/**
* Returns a new array containing all elements contained in this
* {@code LinkedList}.
- *
+ *
* @return an array of the elements from this {@code LinkedList}.
- * @since Android 1.0
*/
@Override
public Object[] toArray() {
@@ -765,14 +747,13 @@
* type is created. If the specified array is used and is larger than this
* {@code LinkedList}, the array element following the collection elements
* is set to null.
- *
+ *
* @param contents
* the array.
* @return an array of the elements from this {@code LinkedList}.
* @throws ArrayStoreException
* if the type of an element in this {@code LinkedList} cannot
* be stored in the type of the specified array.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -784,7 +765,7 @@
}
Link<E> link = voidLink.next;
while (link != voidLink) {
- contents[index++] = (T)link.data;
+ contents[index++] = (T) link.data;
link = link.next;
}
if (index < contents.length) {
@@ -810,7 +791,7 @@
voidLink = new Link<E>(null, null, null);
Link<E> link = voidLink;
for (int i = size; --i >= 0;) {
- Link<E> nextLink = new Link<E>((E)stream.readObject(), link, null);
+ Link<E> nextLink = new Link<E>((E) stream.readObject(), link, null);
link.next = nextLink;
link = nextLink;
}
diff --git a/luni/src/main/java/java/util/List.java b/luni/src/main/java/java/util/List.java
index d95b2d5..68e1ad9 100644
--- a/luni/src/main/java/java/util/List.java
+++ b/luni/src/main/java/java/util/List.java
@@ -23,8 +23,6 @@
* element in the {@code List} has an index. Each element can thus be accessed by its
* index, with the first index being zero. Normally, {@code List}s allow duplicate
* elements, as compared to Sets, where elements have to be unique.
- *
- * @since Android 1.0
*/
public interface List<E> extends Collection<E> {
/**
@@ -39,16 +37,15 @@
* the index at which to insert.
* @param object
* the object to add.
- * @exception UnsupportedOperationException
- * when adding to this {@code List} is not supported.
- * @exception ClassCastException
- * when the class of the object is inappropriate for this
+ * @throws UnsupportedOperationException
+ * if adding to this {@code List} is not supported.
+ * @throws ClassCastException
+ * if the class of the object is inappropriate for this
* {@code List}.
- * @exception IllegalArgumentException
- * when the object cannot be added to this {@code List}.
- * @exception IndexOutOfBoundsException
- * when {@code location < 0 || location > size()}
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if the object cannot be added to this {@code List}.
+ * @throws IndexOutOfBoundsException
+ * if {@code location < 0 || location > size()}
*/
public void add(int location, E object);
@@ -58,14 +55,13 @@
* @param object
* the object to add.
* @return always true.
- * @exception UnsupportedOperationException
- * when adding to this {@code List} is not supported.
- * @exception ClassCastException
- * when the class of the object is inappropriate for this
+ * @throws UnsupportedOperationException
+ * if adding to this {@code List} is not supported.
+ * @throws ClassCastException
+ * if the class of the object is inappropriate for this
* {@code List}.
- * @exception IllegalArgumentException
- * when the object cannot be added to this {@code List}.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if the object cannot be added to this {@code List}.
*/
public boolean add(E object);
@@ -80,16 +76,15 @@
* the collection of objects to be inserted.
* @return true if this {@code List} has been modified through the insertion, false
* otherwise (i.e. if the passed collection was empty).
- * @exception UnsupportedOperationException
- * when adding to this {@code List} is not supported.
- * @exception ClassCastException
- * when the class of an object is inappropriate for this
+ * @throws UnsupportedOperationException
+ * if adding to this {@code List} is not supported.
+ * @throws ClassCastException
+ * if the class of an object is inappropriate for this
* {@code List}.
- * @exception IllegalArgumentException
- * when an object cannot be added to this {@code List}.
- * @exception IndexOutOfBoundsException
- * when {@code location < 0 || > size()}
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if an object cannot be added to this {@code List}.
+ * @throws IndexOutOfBoundsException
+ * if {@code location < 0 || > size()}
*/
public boolean addAll(int location, Collection<? extends E> collection);
@@ -102,25 +97,23 @@
* the collection of objects.
* @return {@code true} if this {@code List} is modified, {@code false} otherwise
* (i.e. if the passed collection was empty).
- * @exception UnsupportedOperationException
- * when adding to this {@code List} is not supported.
- * @exception ClassCastException
- * when the class of an object is inappropriate for this
+ * @throws UnsupportedOperationException
+ * if adding to this {@code List} is not supported.
+ * @throws ClassCastException
+ * if the class of an object is inappropriate for this
* {@code List}.
- * @exception IllegalArgumentException
- * when an object cannot be added to this {@code List}.
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if an object cannot be added to this {@code List}.
*/
public boolean addAll(Collection<? extends E> collection);
/**
* Removes all elements from this {@code List}, leaving it empty.
*
- * @exception UnsupportedOperationException
- * when removing from this {@code List} is not supported.
+ * @throws UnsupportedOperationException
+ * if removing from this {@code List} is not supported.
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
public void clear();
@@ -131,7 +124,6 @@
* the object to search for.
* @return {@code true} if object is an element of this {@code List}, {@code false}
* otherwise
- * @since Android 1.0
*/
public boolean contains(Object object);
@@ -143,7 +135,6 @@
* the collection of objects
* @return {@code true} if all objects in the specified collection are
* elements of this {@code List}, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean containsAll(Collection<?> collection);
@@ -158,7 +149,6 @@
* @return boolean {@code true} if the object is the same as this object,
* and {@code false} if it is different from this object.
* @see #hashCode
- * @since Android 1.0
*/
public boolean equals(Object object);
@@ -168,9 +158,8 @@
* @param location
* the index of the element to return.
* @return the element at the specified location.
- * @exception IndexOutOfBoundsException
- * when {@code location < 0 || >= size()}
- * @since Android 1.0
+ * @throws IndexOutOfBoundsException
+ * if {@code location < 0 || >= size()}
*/
public E get(int location);
@@ -179,7 +168,6 @@
* element' hashcode and its position in the {@code List} into account.
*
* @return the hash code of the {@code List}.
- * @since Android 1.0
*/
public int hashCode();
@@ -191,7 +179,6 @@
* the object to search for.
* @return the index of the first occurrence of the object or -1 if the
* object was not found.
- * @since Android 1.0
*/
public int indexOf(Object object);
@@ -201,7 +188,6 @@
* @return {@code true} if this {@code List} has no elements, {@code false}
* otherwise.
* @see #size
- * @since Android 1.0
*/
public boolean isEmpty();
@@ -211,7 +197,6 @@
*
* @return an iterator on the elements of this {@code List}.
* @see Iterator
- * @since Android 1.0
*/
public Iterator<E> iterator();
@@ -223,7 +208,6 @@
* the object to search for.
* @return the index of the last occurrence of the object, or -1 if the
* object was not found.
- * @since Android 1.0
*/
public int lastIndexOf(Object object);
@@ -234,7 +218,6 @@
* @return a {@code List} iterator on the elements of this {@code List}
*
* @see ListIterator
- * @since Android 1.0
*/
public ListIterator<E> listIterator();
@@ -246,10 +229,9 @@
* @param location
* the index at which to start the iteration.
* @return a list iterator on the elements of this {@code List}.
- * @exception IndexOutOfBoundsException
- * when {@code location < 0 || location > size()}
+ * @throws IndexOutOfBoundsException
+ * if {@code location < 0 || location > size()}
* @see ListIterator
- * @since Android 1.0
*/
public ListIterator<E> listIterator(int location);
@@ -259,11 +241,10 @@
* @param location
* the index of the object to remove.
* @return the removed object.
- * @exception UnsupportedOperationException
- * when removing from this {@code List} is not supported.
- * @exception IndexOutOfBoundsException
- * when {@code location < 0 || >= size()}
- * @since Android 1.0
+ * @throws UnsupportedOperationException
+ * if removing from this {@code List} is not supported.
+ * @throws IndexOutOfBoundsException
+ * if {@code location < 0 || >= size()}
*/
public E remove(int location);
@@ -274,9 +255,8 @@
* the object to remove.
* @return true if this {@code List} was modified by this operation, false
* otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code List} is not supported.
- * @since Android 1.0
+ * @throws UnsupportedOperationException
+ * if removing from this {@code List} is not supported.
*/
public boolean remove(Object object);
@@ -287,9 +267,8 @@
* @param collection
* the collection of objects to remove.
* @return {@code true} if this {@code List} is modified, {@code false} otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code List} is not supported.
- * @since Android 1.0
+ * @throws UnsupportedOperationException
+ * if removing from this {@code List} is not supported.
*/
public boolean removeAll(Collection<?> collection);
@@ -300,9 +279,8 @@
* @param collection
* the collection of objects to retain.
* @return {@code true} if this {@code List} is modified, {@code false} otherwise.
- * @exception UnsupportedOperationException
- * when removing from this {@code List} is not supported.
- * @since Android 1.0
+ * @throws UnsupportedOperationException
+ * if removing from this {@code List} is not supported.
*/
public boolean retainAll(Collection<?> collection);
@@ -315,16 +293,15 @@
* @param object
* the object to insert.
* @return the previous element at the index.
- * @exception UnsupportedOperationException
- * when replacing elements in this {@code List} is not supported.
- * @exception ClassCastException
- * when the class of an object is inappropriate for this
+ * @throws UnsupportedOperationException
+ * if replacing elements in this {@code List} is not supported.
+ * @throws ClassCastException
+ * if the class of an object is inappropriate for this
* {@code List}.
- * @exception IllegalArgumentException
- * when an object cannot be added to this {@code List}.
- * @exception IndexOutOfBoundsException
- * when {@code location < 0 || >= size()}
- * @since Android 1.0
+ * @throws IllegalArgumentException
+ * if an object cannot be added to this {@code List}.
+ * @throws IndexOutOfBoundsException
+ * if {@code location < 0 || >= size()}
*/
public E set(int location, E object);
@@ -332,7 +309,6 @@
* Returns the number of elements in this {@code List}.
*
* @return the number of elements in this {@code List}.
- * @since Android 1.0
*/
public int size();
@@ -346,10 +322,9 @@
* @param end
* the index one past the end of the sublist.
* @return a list of a portion of this {@code List}.
- * @exception IndexOutOfBoundsException
- * when {@code start < 0, start > end} or {@code end >
+ * @throws IndexOutOfBoundsException
+ * if {@code start < 0, start > end} or {@code end >
* size()}
- * @since Android 1.0
*/
public List<E> subList(int start, int end);
@@ -357,7 +332,6 @@
* Returns an array containing all elements contained in this {@code List}.
*
* @return an array of the elements from this {@code List}.
- * @since Android 1.0
*/
public Object[] toArray();
@@ -371,10 +345,9 @@
* @param array
* the array.
* @return an array of the elements from this {@code List}.
- * @exception ArrayStoreException
- * when the type of an element in this {@code List} cannot be stored
+ * @throws ArrayStoreException
+ * if the type of an element in this {@code List} cannot be stored
* in the type of the specified array.
- * @since Android 1.0
*/
public <T> T[] toArray(T[] array);
}
diff --git a/luni/src/main/java/java/util/ListIterator.java b/luni/src/main/java/java/util/ListIterator.java
index 6ce94c3..1c62a22 100644
--- a/luni/src/main/java/java/util/ListIterator.java
+++ b/luni/src/main/java/java/util/ListIterator.java
@@ -21,8 +21,6 @@
/**
* An ListIterator is used to sequence over a List of objects. ListIterator can
* move backwards or forwards through the list.
- *
- * @since Android 1.0
*/
public interface ListIterator<E> extends Iterator<E> {
@@ -38,7 +36,6 @@
* if the class of the object is inappropriate for the list.
* @throws IllegalArgumentException
* if the object cannot be added to the list.
- * @since Android 1.0
*/
void add(E object);
@@ -47,7 +44,6 @@
*
* @return {@code true} if there are more elements, {@code false} otherwise.
* @see #next
- * @since Android 1.0
*/
public boolean hasNext();
@@ -57,7 +53,6 @@
* @return {@code true} if there are previous elements, {@code false}
* otherwise.
* @see #previous
- * @since Android 1.0
*/
public boolean hasPrevious();
@@ -68,7 +63,6 @@
* @throws NoSuchElementException
* if there are no more elements.
* @see #hasNext
- * @since Android 1.0
*/
public E next();
@@ -80,7 +74,6 @@
* @throws NoSuchElementException
* if there are no more elements.
* @see #next
- * @since Android 1.0
*/
public int nextIndex();
@@ -91,7 +84,6 @@
* @throws NoSuchElementException
* if there are no previous elements.
* @see #hasPrevious
- * @since Android 1.0
*/
public E previous();
@@ -103,7 +95,6 @@
* @throws NoSuchElementException
* if there are no previous elements.
* @see #previous
- * @since Android 1.0
*/
public int previousIndex();
@@ -117,7 +108,6 @@
* if {@code next} or {@code previous} have not been called, or
* {@code remove} or {@code add} have already been called after
* the last call to {@code next} or {@code previous}.
- * @since Android 1.0
*/
public void remove();
@@ -137,7 +127,6 @@
* if {@code next} or {@code previous} have not been called, or
* {@code remove} or {@code add} have already been called after
* the last call to {@code next} or {@code previous}.
- * @since Android 1.0
*/
void set(E object);
}
diff --git a/luni/src/main/java/java/util/ListResourceBundle.java b/luni/src/main/java/java/util/ListResourceBundle.java
index 20d64ac..6206ee6 100644
--- a/luni/src/main/java/java/util/ListResourceBundle.java
+++ b/luni/src/main/java/java/util/ListResourceBundle.java
@@ -17,22 +17,19 @@
package java.util;
-
/**
* {@code ListResourceBundle} is the abstract superclass of classes which provide
* resources by implementing the {@code getContents()} method to return
* the list of resources.
- *
+ *
* @see ResourceBundle
- * @since Android 1.0
+ * @since 1.1
*/
public abstract class ListResourceBundle extends ResourceBundle {
- Hashtable<String, Object> table;
+ HashMap<String, Object> table;
/**
* Constructs a new instance of this class.
- *
- * @since Android 1.0
*/
public ListResourceBundle() {
super();
@@ -43,73 +40,81 @@
* {@code ListResourceBundle}. Each element in the array is an array of two
* elements, the first is the resource key string and the second is the
* resource.
- *
+ *
* @return a {@code Object} array containing the resources.
- * @since Android 1.0
*/
protected abstract Object[][] getContents();
/**
* Returns the names of the resources contained in this {@code ListResourceBundle}.
- *
+ *
* @return an {@code Enumeration} of the resource names.
- * @since Android 1.0
*/
@Override
public Enumeration<String> getKeys() {
- if (table == null) {
- initializeTable();
- }
- if (parent == null) {
- return table.keys();
- }
- return new Enumeration<String>() {
- Enumeration<String> local = table.keys();
+ initializeTable();
+ if (parent != null) {
+ return new Enumeration<String>() {
+ Iterator<String> local = table.keySet().iterator();
- Enumeration<String> pEnum = parent.getKeys();
+ Enumeration<String> pEnum = parent.getKeys();
- String nextElement;
+ String nextElement;
- private boolean findNext() {
- if (nextElement != null) {
- return true;
- }
- while (pEnum.hasMoreElements()) {
- String next = pEnum.nextElement();
- if (!table.containsKey(next)) {
- nextElement = next;
+ private boolean findNext() {
+ if (nextElement != null) {
return true;
}
+ while (pEnum.hasMoreElements()) {
+ String next = pEnum.nextElement();
+ if (!table.containsKey(next)) {
+ nextElement = next;
+ return true;
+ }
+ }
+ return false;
}
- return false;
- }
- public boolean hasMoreElements() {
- if (local.hasMoreElements()) {
- return true;
+ public boolean hasMoreElements() {
+ if (local.hasNext()) {
+ return true;
+ }
+ return findNext();
}
- return findNext();
- }
- public String nextElement() {
- if (local.hasMoreElements()) {
- return local.nextElement();
+ public String nextElement() {
+ if (local.hasNext()) {
+ return local.next();
+ }
+ if (findNext()) {
+ String result = nextElement;
+ nextElement = null;
+ return result;
+ }
+ // Cause an exception
+ return pEnum.nextElement();
}
- if (findNext()) {
- String result = nextElement;
- nextElement = null;
- return result;
+ };
+ } else {
+ return new Enumeration<String>() {
+ Iterator<String> it = table.keySet().iterator();
+
+ public boolean hasMoreElements() {
+ return it.hasNext();
}
- // Cause an exception
- return pEnum.nextElement();
- }
- };
+
+ public String nextElement() {
+ return it.next();
+ }
+ };
+ }
}
@Override
public final Object handleGetObject(String key) {
- if (table == null) {
- initializeTable();
+ initializeTable();
+ if (key == null) {
+ throw new NullPointerException();
}
return table.get(key);
}
@@ -117,9 +122,12 @@
private synchronized void initializeTable() {
if (table == null) {
Object[][] contents = getContents();
- table = new Hashtable<String, Object>(contents.length / 3 * 4 + 3);
- for (int i = 0; i < contents.length; i++) {
- table.put((String)contents[i][0], contents[i][1]);
+ table = new HashMap<String, Object>(contents.length / 3 * 4 + 3);
+ for (Object[] content : contents) {
+ if (content[0] == null || content[1] == null) {
+ throw new NullPointerException();
+ }
+ table.put((String) content[0], content[1]);
}
}
}
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index bbf7239..b4558aa 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -17,7 +17,8 @@
package java.util;
-import java.io.File;
+// BEGIN android-changed
+// import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -25,19 +26,14 @@
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
+// import java.util.zip.ZipEntry;
+// import java.util.zip.ZipFile;
-// BEGIN android-removed
-//import org.apache.harmony.luni.internal.locale.Country;
-//import org.apache.harmony.luni.internal.locale.Language;
-// END android-removed
import org.apache.harmony.luni.util.PriviAction;
import org.apache.harmony.luni.util.Util;
-//BEGIN android-added
import com.ibm.icu4jni.util.Resources;
-// END android-added
+// END android-changed
/**
* {@code Locale} represents a language/country/variant combination. It is an identifier
@@ -45,15 +41,14 @@
* The language codes are two letter lowercase codes as defined by ISO-639. The
* country codes are three letter uppercase codes as defined by ISO-3166. The
* variant codes are unspecified.
- *
+ *
* @see ResourceBundle
- * @since Android 1.0
*/
public final class Locale implements Cloneable, Serializable {
-
+
private static final long serialVersionUID = 9149081749638150636L;
- private static Locale[] availableLocales;
+ private static volatile Locale[] availableLocales;
// Initialize a default which is used during static
// initialization of the default for the platform.
@@ -61,200 +56,159 @@
/**
* Locale constant for en_CA.
- *
- * @since Android 1.0
*/
public static final Locale CANADA = new Locale("en", "CA"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for fr_CA.
- *
- * @since Android 1.0
*/
public static final Locale CANADA_FRENCH = new Locale("fr", "CA"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for zh_CN.
- *
- * @since Android 1.0
*/
public static final Locale CHINA = new Locale("zh", "CN"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for zh.
- *
- * @since Android 1.0
*/
- public static final Locale CHINESE = new Locale("zh", ""); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale CHINESE = new Locale("zh", ""); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for en.
- *
- * @since Android 1.0
*/
public static final Locale ENGLISH = new Locale("en", ""); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for fr_FR.
- *
- * @since Android 1.0
*/
- public static final Locale FRANCE = new Locale("fr", "FR"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale FRANCE = new Locale("fr", "FR"); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for fr.
- *
- * @since Android 1.0
*/
- public static final Locale FRENCH = new Locale("fr", ""); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale FRENCH = new Locale("fr", ""); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for de.
- *
- * @since Android 1.0
*/
public static final Locale GERMAN = new Locale("de", ""); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for de_DE.
- *
- * @since Android 1.0
*/
public static final Locale GERMANY = new Locale("de", "DE"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for it.
- *
- * @since Android 1.0
*/
public static final Locale ITALIAN = new Locale("it", ""); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for it_IT.
- *
- * @since Android 1.0
*/
public static final Locale ITALY = new Locale("it", "IT"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for ja_JP.
- *
- * @since Android 1.0
*/
- public static final Locale JAPAN = new Locale("ja", "JP"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale JAPAN = new Locale("ja", "JP"); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for ja.
- *
- * @since Android 1.0
*/
- public static final Locale JAPANESE = new Locale("ja", ""); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale JAPANESE = new Locale("ja", ""); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for ko_KR.
- *
- * @since Android 1.0
*/
- public static final Locale KOREA = new Locale("ko", "KR"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale KOREA = new Locale("ko", "KR"); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for ko.
- *
- * @since Android 1.0
*/
- public static final Locale KOREAN = new Locale("ko", ""); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale KOREAN = new Locale("ko", ""); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for zh_CN.
- *
- * @since Android 1.0
*/
- public static final Locale PRC = new Locale("zh", "CN"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale PRC = new Locale("zh", "CN"); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for zh_CN.
- *
- * @since Android 1.0
*/
- public static final Locale SIMPLIFIED_CHINESE = new Locale("zh", "CN"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale SIMPLIFIED_CHINESE = new Locale("zh", "CN"); //$NON-NLS-1$//$NON-NLS-2$
/**
* Locale constant for zh_TW.
- *
- * @since Android 1.0
*/
public static final Locale TAIWAN = new Locale("zh", "TW"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for zh_TW.
- *
- * @since Android 1.0
*/
public static final Locale TRADITIONAL_CHINESE = new Locale("zh", "TW"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for en_GB.
- *
- * @since Android 1.0
*/
public static final Locale UK = new Locale("en", "GB"); //$NON-NLS-1$ //$NON-NLS-2$
/**
* Locale constant for en_US.
- *
- * @since Android 1.0
*/
- public static final Locale US = new Locale("en", "US"); //$NON-NLS-1$//$NON-NLS-2$
+ public static final Locale US = new Locale("en", "US"); //$NON-NLS-1$//$NON-NLS-2$
private static final PropertyPermission setLocalePermission = new PropertyPermission(
- "user.language", "write"); //$NON-NLS-1$//$NON-NLS-2$
+ "user.language", "write"); //$NON-NLS-1$//$NON-NLS-2$
static {
String language = AccessController
.doPrivileged(new PriviAction<String>("user.language", "en")); //$NON-NLS-1$ //$NON-NLS-2$
// BEGIN android-changed
- String region = AccessController
- .doPrivileged(new PriviAction<String>("user.region", "US")); //$NON-NLS-1$ //$NON-NLS-2$
+ String region = AccessController.doPrivileged(new PriviAction<String>(
+ "user.region", "US")); //$NON-NLS-1$ //$NON-NLS-2$
// END android-changed
- String variant = AccessController
- .doPrivileged(new PriviAction<String>("user.variant", "")); //$NON-NLS-1$ //$NON-NLS-2$
+ String variant = AccessController.doPrivileged(new PriviAction<String>(
+ "user.variant", "")); //$NON-NLS-1$ //$NON-NLS-2$
defaultLocale = new Locale(language, region, variant);
}
-
+
private transient String countryCode;
private transient String languageCode;
private transient String variantCode;
- /**
- * Constructs a default which is used during static initialization of the
- * default for the platform.
- */
- private Locale() {
- languageCode = "en"; //$NON-NLS-1$
- countryCode = "US"; //$NON-NLS-1$
- variantCode = ""; //$NON-NLS-1$
- }
+ // BEGIN android-removed
+ // private transient ULocale uLocale;
+ // END android-removed
+
+ /**
+ * Constructs a default which is used during static initialization of the
+ * default for the platform.
+ */
+ private Locale() {
+ languageCode = "en"; //$NON-NLS-1$
+ countryCode = "US"; //$NON-NLS-1$
+ variantCode = ""; //$NON-NLS-1$
+ }
/**
* Constructs a new {@code Locale} using the specified language.
- *
+ *
* @param language
* the language this {@code Locale} represents.
- *
- * @since Android 1.0
*/
public Locale(String language) {
- this(language, "", ""); //$NON-NLS-1$//$NON-NLS-2$
+ this(language, "", ""); //$NON-NLS-1$//$NON-NLS-2$
}
/**
* Constructs a new {@code Locale} using the specified language and country codes.
- *
+ *
* @param language
* the language this {@code Locale} represents.
* @param country
* the country this {@code Locale} represents.
- * @since Android 1.0
*/
public Locale(String language, String country) {
this(language, country, ""); //$NON-NLS-1$
@@ -263,7 +217,7 @@
/**
* Constructs a new {@code Locale} using the specified language, country, and
* variant codes.
- *
+ *
* @param language
* the language this {@code Locale} represents.
* @param country
@@ -273,13 +227,22 @@
* @throws NullPointerException
* if {@code language}, {@code country}, or
* {@code variant} is {@code null}.
- * @since Android 1.0
*/
public Locale(String language, String country, String variant) {
if (language == null || country == null || variant == null) {
throw new NullPointerException();
}
+ if(language.length() == 0 && country.length() == 0){
+ languageCode = "";
+ countryCode = "";
+ variantCode = variant;
+ return;
+ }
+ // BEGIN android-changed
+ // this.uLocale = new ULocale(language, country, variant);
+ // languageCode = uLocale.getLanguage();
languageCode = Util.toASCIILowerCase(language);
+ // END android-changed
// Map new language codes to the obsolete language
// codes so the correct resource bundles will be used.
if (languageCode.equals("he")) {//$NON-NLS-1$
@@ -291,18 +254,21 @@
}
// countryCode is defined in ASCII character set
+ // BEGIN android-changed
+ // countryCode = country.length()!=0?uLocale.getCountry():"";
countryCode = Util.toASCIIUpperCase(country);
+ // END android-changed
+ // Work around for be compatible with RI
variantCode = variant;
}
/**
* Returns a new {@code Locale} with the same language, country and variant codes as
* this {@code Locale}.
- *
+ *
* @return a shallow copy of this {@code Locale}.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -317,13 +283,12 @@
* Compares the specified object to this {@code Locale} and returns whether they are
* equal. The object must be an instance of {@code Locale} and have the same
* language, country and variant.
- *
+ *
* @param object
* the object to compare with this object.
* @return {@code true} if the specified object is equal to this {@code Locale},
* {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -347,13 +312,8 @@
// final String classPrefix = prefix.substring(last + 1, length);
// Set<String> result = new HashSet<String>();
// StringTokenizer paths = new StringTokenizer(System.getProperty(
- // // BEGIN android-removed
- // // "org.apache.harmony.boot.class.path", ""), System.getProperty( //$NON-NLS-1$ //$NON-NLS-2$
- // // END android-removed
- // // BEGIN android-added
- // "java.boot.class.path", ""), System.getProperty( //$NON-NLS-1$ //$NON-NLS-2$
- // // END android-added
- // "path.separator", ";")); //$NON-NLS-1$//$NON-NLS-2$
+ // "org.apache.harmony.boot.class.path", ""), System.getProperty( //$NON-NLS-1$ //$NON-NLS-2$
+ // "path.separator", ";")); //$NON-NLS-1$//$NON-NLS-2$
// while (paths.hasMoreTokens()) {
// String nextToken = paths.nextToken();
// File directory = new File(nextToken);
@@ -378,12 +338,13 @@
// String name = list[i];
// if (name.startsWith(classPrefix)
// && name.endsWith(".class")) { //$NON-NLS-1$
- // result.add(name.substring(0,
+ // result
+ // .add(name.substring(0,
// name.length() - 6));
// }
// }
// }
- //
+ //
// } else {
// // Handle ZIP/JAR files.
// try {
@@ -394,25 +355,26 @@
// String name = e.getName();
// if (name.startsWith(prefix)
// && name.endsWith(".class")) {//$NON-NLS-1$
- // result.add(name.substring(last+1, name.length() - 6));
+ // result.add(name.substring(last + 1, name
+ // .length() - 6));
// }
// }
// zip.close();
// } catch (IOException e) {
- // // Empty
+ // // Empty
// }
// }
// }
// }
// Locale[] locales = new Locale[result.size()];
// int i = 0;
- // for (String name: result) {
+ // for (String name : result) {
// int index = name.indexOf('_');
// int nextIndex = name.indexOf('_', index + 1);
// if (nextIndex == -1) {
- // locales[i++] = new Locale(name
- // .substring(index + 1, name.length()), ""); //$NON-NLS-1$
- // }else{
+ // locales[i++] = new Locale(name.substring(index + 1, name
+ // .length()), ""); //$NON-NLS-1$
+ // } else {
// String language = name.substring(index + 1, nextIndex);
// String variant;
// if ((index = name.indexOf('_', nextIndex + 1)) == -1) {
@@ -437,7 +399,7 @@
String s = locales[i];
int first = s.indexOf('_');
int second = s.indexOf('_', first + 1);
-
+
if (first == -1) {
// Language only
temp.add(new Locale(s));
@@ -454,37 +416,32 @@
}
// END android-added
- /**
+ /**
* Gets the list of installed {@code Locale}. At least a {@code Locale} that is equal to
* {@code Locale.US} must be contained in this array.
- *
+ *
* @return an array of {@code Locale}s.
- * @since Android 1.0
- */
- public static Locale[] getAvailableLocales() {
+ */
+ public static Locale[] getAvailableLocales() {
+ // BEGIN android-changed
+ // ULocale[] ulocales = ULocale.getAvailableLocales();
+ // Locale[] locales = new Locale[ulocales.length];
+ // for (int i = 0; i < locales.length; i++) {
+ // locales[i] = ulocales[i].toLocale();
+ // }
+ // return locales;
if (availableLocales == null) {
- // BEGIN android-removed
- // availableLocales = AccessController
- // .doPrivileged(new PrivilegedAction<Locale[]>() {
- // public Locale[] run() {
- // return find("org/apache/harmony/luni/internal/locale/Locale_"); //$NON-NLS-1$
- // }
- // });
- // END android-removed
-
- // BEGIN android-added
availableLocales = find();
- // END android-added
}
return availableLocales.clone();
- }
+ // END android-changed
+ }
/**
* Gets the country code for this {@code Locale} or an empty string of no country
* was set.
- *
+ *
* @return a country code.
- * @since Android 1.0
*/
public String getCountry() {
return countryCode;
@@ -492,9 +449,8 @@
/**
* Gets the default {@code Locale}.
- *
+ *
* @return the default {@code Locale}.
- * @since Android 1.0
*/
public static Locale getDefault() {
return defaultLocale;
@@ -504,9 +460,8 @@
* Gets the full country name in the default {@code Locale} for the country code of
* this {@code Locale}. If there is no matching country name, the country code is
* returned.
- *
+ *
* @return a country name.
- * @since Android 1.0
*/
public final String getDisplayCountry() {
return getDisplayCountry(getDefault());
@@ -516,22 +471,21 @@
* Gets the full country name in the specified {@code Locale} for the country code
* of this {@code Locale}. If there is no matching country name, the country code is
* returned.
- *
+ *
* @param locale
* the {@code Locale} for which the display name is retrieved.
* @return a country name.
- * @since Android 1.0
*/
- public String getDisplayCountry(Locale locale) {
+ public String getDisplayCountry(Locale locale) {
+ // BEGIN android-changed
+ // return ULocale.forLocale(this).getDisplayCountry(ULocale.forLocale(locale));
if (countryCode.length() == 0) {
return countryCode;
}
try {
// First try the specified locale
ResourceBundle bundle = getBundle("Country", locale); //$NON-NLS-1$
- // BEGIN android-changed
String result = bundle.getString(this.toString());
- // END android-changed
if (result != null) {
return result;
}
@@ -543,15 +497,15 @@
} catch (MissingResourceException e) {
return countryCode;
}
- }
+ // END android-changed
+ }
/**
* Gets the full language name in the default {@code Locale} for the language code
* of this {@code Locale}. If there is no matching language name, the language code
* is returned.
- *
+ *
* @return a language name.
- * @since Android 1.0
*/
public final String getDisplayLanguage() {
return getDisplayLanguage(getDefault());
@@ -561,22 +515,21 @@
* Gets the full language name in the specified {@code Locale} for the language code
* of this {@code Locale}. If there is no matching language name, the language code
* is returned.
- *
+ *
* @param locale
* the {@code Locale} for which the display name is retrieved.
* @return a language name.
- * @since Android 1.0
*/
- public String getDisplayLanguage(Locale locale) {
+ public String getDisplayLanguage(Locale locale) {
+ // BEGIN android-changed
+ // return ULocale.forLocale(this).getDisplayLanguage(ULocale.forLocale(locale));
if (languageCode.length() == 0) {
return languageCode;
}
try {
// First try the specified locale
ResourceBundle bundle = getBundle("Language", locale); //$NON-NLS-1$
- // BEGIN android-changed
String result = bundle.getString(this.toString());
- // END android-changed
if (result != null) {
return result;
}
@@ -588,14 +541,14 @@
} catch (MissingResourceException e) {
return languageCode;
}
- }
+ // END android-changed
+ }
/**
* Gets the full language, country, and variant names in the default {@code Locale}
* for the codes of this {@code Locale}.
- *
+ *
* @return a {@code Locale} name.
- * @since Android 1.0
*/
public final String getDisplayName() {
return getDisplayName(getDefault());
@@ -604,11 +557,10 @@
/**
* Gets the full language, country, and variant names in the specified
* Locale for the codes of this {@code Locale}.
- *
+ *
* @param locale
* the {@code Locale} for which the display name is retrieved.
* @return a {@code Locale} name.
- * @since Android 1.0
*/
public String getDisplayName(Locale locale) {
int count = 0;
@@ -643,9 +595,8 @@
* Gets the full variant name in the default {@code Locale} for the variant code of
* this {@code Locale}. If there is no matching variant name, the variant code is
* returned.
- *
+ *
* @return a variant name.
- * @since Android 1.0
*/
public final String getDisplayVariant() {
return getDisplayVariant(getDefault());
@@ -655,41 +606,17 @@
* Gets the full variant name in the specified {@code Locale} for the variant code
* of this {@code Locale}. If there is no matching variant name, the variant code is
* returned.
- *
+ *
* @param locale
* the {@code Locale} for which the display name is retrieved.
* @return a variant name.
- * @since Android 1.0
*/
- public String getDisplayVariant(Locale locale) {
+ public String getDisplayVariant(Locale locale) {
+ // BEGIN android-changed
+ // return ULocale.forLocale(this).getDisplayVariant(ULocale.forLocale(locale));
if (variantCode.length() == 0) {
return variantCode;
}
-// BEGIN android-removed
-// ResourceBundle bundle;
-// try {
-// bundle = getBundle("Variant", locale); //$NON-NLS-1$
-// } catch (MissingResourceException e) {
-// return variantCode.replace('_', ',');
-// }
-//
-// StringBuffer result = new StringBuffer();
-// StringTokenizer tokens = new StringTokenizer(variantCode, "_"); //$NON-NLS-1$
-// while (tokens.hasMoreTokens()) {
-// String code, variant = tokens.nextToken();
-// try {
-// code = bundle.getString(variant);
-// } catch (MissingResourceException e) {
-// code = variant;
-// }
-// result.append(code);
-// if (tokens.hasMoreTokens()) {
-// result.append(',');
-// }
-// }
-// return result.toString();
-// END android-removed
-// BEGIN android-added
try {
// First try the specified locale
ResourceBundle bundle = getBundle("Variant", locale); //$NON-NLS-1$
@@ -705,105 +632,78 @@
} catch (MissingResourceException e) {
return variantCode;
}
-// END android-added
- }
+ // END android-changed
+ }
/**
* Gets the three letter ISO country code which corresponds to the country
* code for this {@code Locale}.
- *
+ *
* @return a three letter ISO language code.
- * @exception MissingResourceException
- * when there is no matching three letter ISO country code.
- * @since Android 1.0
+ * @throws MissingResourceException
+ * if there is no matching three letter ISO country code.
*/
- public String getISO3Country() throws MissingResourceException {
+ public String getISO3Country() throws MissingResourceException {
+ // BEGIN android-changed
+ // return ULocale.forLocale(this).getISO3Country();
if (countryCode.length() == 0) {
return ""; //$NON-NLS-1$
}
ResourceBundle bundle = getBundle("ISO3Countries", this); //$NON-NLS-1$
- // BEGIN android-changed
return bundle.getString(this.toString());
// END android-changed
- }
+ }
/**
* Gets the three letter ISO language code which corresponds to the language
* code for this {@code Locale}.
- *
+ *
* @return a three letter ISO language code.
- * @exception MissingResourceException
- * when there is no matching three letter ISO language code.
- * @since Android 1.0
+ * @throws MissingResourceException
+ * if there is no matching three letter ISO language code.
*/
- public String getISO3Language() throws MissingResourceException {
+ public String getISO3Language() throws MissingResourceException {
+ // BEGIN android-changed
+ // return ULocale.forLocale(this).getISO3Language();
if (languageCode.length() == 0) {
return ""; //$NON-NLS-1$
}
ResourceBundle bundle = getBundle("ISO3Languages", this); //$NON-NLS-1$
- // BEGIN android-changed
return bundle.getString(this.toString());
// END android-changed
- }
+ }
/**
* Gets the list of two letter ISO country codes which can be used as the
* country code for a {@code Locale}.
- *
+ *
* @return an array of strings.
- * @since Android 1.0
*/
public static String[] getISOCountries() {
- // BEGIN android-removed
- // ListResourceBundle bundle = new Country();
- //
- // // To initialize the table
- // Enumeration<String> keys = bundle.getKeys();
- // int size = bundle.table.size();
- // String[] result = new String[size];
- // int index = 0;
- // while (keys.hasMoreElements()) {
- // String element = keys.nextElement();
- // result[index++] = element;
- // }
- // return result;
- // END android-removed
-
- // BEGIN android-added
+ // BEGIN android-changed
+ // return ULocale.getISOCountries();
return Resources.getISOCountries();
- // END android-added
+ // END android-changed
}
/**
* Gets the list of two letter ISO language codes which can be used as the
* language code for a {@code Locale}.
- *
+ *
* @return an array of strings.
- * @since Android 1.0
*/
- public static String[] getISOLanguages() {
- // BEGIN android-removed
- // ListResourceBundle bundle = new Language();
- // Enumeration<String> keys = bundle.getKeys(); // to initialize the table
- // String[] result = new String[bundle.table.size()];
- // int index = 0;
- // while (keys.hasMoreElements()) {
- // result[index++] = keys.nextElement();
- // }
- // return result;
- // END android-removed
-
- // BEGIN android-added
+ public static String[] getISOLanguages() {
+ // BEGIN android-changed
+ // return ULocale.getISOLanguages();
return Resources.getISOLanguages();
- // END android-added
- }
+ // END android-changed
+ }
/**
* Gets the language code for this {@code Locale} or the empty string of no language
* was set.
- *
+ *
* @return a language code.
- * @since Android 1.0
*/
public String getLanguage() {
return languageCode;
@@ -812,9 +712,8 @@
/**
* Gets the variant code for this {@code Locale} or an empty {@code String} of no variant
* was set.
- *
+ *
* @return a variant code.
- * @since Android 1.0
*/
public String getVariant() {
return variantCode;
@@ -823,10 +722,9 @@
/**
* Returns an integer hash code for the receiver. Objects which are equal
* return the same value for this method.
- *
+ *
* @return the receiver's hash.
* @see #equals
- * @since Android 1.0
*/
@Override
public synchronized int hashCode() {
@@ -836,13 +734,12 @@
/**
* Sets the default {@code Locale} to the specified {@code Locale}.
- *
+ *
* @param locale
* the new default {@code Locale}.
- * @exception SecurityException
+ * @throws SecurityException
* if there is a {@code SecurityManager} in place which does not allow this
* operation.
- * @since Android 1.0
*/
public synchronized static void setDefault(Locale locale) {
if (locale != null) {
@@ -864,11 +761,10 @@
* between the language and the variant. the variant alone canot be defined
* without a language and/or a country (in this case this method would
* return the empty string).
- *
+ *
* Examples: "en", "en_US", "_US", "en__POSIX", "en_US_POSIX"
- *
+ *
* @return the string representation of this {@code Locale}.
- * @since Android 1.0
*/
@Override
public final String toString() {
@@ -878,7 +774,7 @@
result.append('_');
result.append(countryCode);
}
- if (variantCode.length() > 0 && result.length() > 0 ) {
+ if (variantCode.length() > 0 && result.length() > 0) {
if (0 == countryCode.length()) {
result.append("__"); //$NON-NLS-1$
} else {
@@ -889,14 +785,16 @@
return result.toString();
}
+ // BEGIN android-added
static ResourceBundle getBundle(final String clName, final Locale locale) {
return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
- public ResourceBundle run() {
- return ResourceBundle.getBundle("org.apache.harmony.luni.internal.locale." //$NON-NLS-1$
- + clName, locale);
- }
- });
+ public ResourceBundle run() {
+ return ResourceBundle.getBundle("org.apache.harmony.luni.internal.locale." //$NON-NLS-1$
+ + clName, locale);
+ }
+ });
}
+ // END android-added
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("country", String.class), //$NON-NLS-1$
@@ -916,9 +814,8 @@
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
ObjectInputStream.GetField fields = stream.readFields();
- countryCode = (String) fields.get("country", ""); //$NON-NLS-1$//$NON-NLS-2$
- languageCode = (String) fields.get("language", ""); //$NON-NLS-1$//$NON-NLS-2$
- variantCode = (String) fields.get("variant", ""); //$NON-NLS-1$//$NON-NLS-2$
+ countryCode = (String) fields.get("country", ""); //$NON-NLS-1$//$NON-NLS-2$
+ languageCode = (String) fields.get("language", ""); //$NON-NLS-1$//$NON-NLS-2$
+ variantCode = (String) fields.get("variant", ""); //$NON-NLS-1$//$NON-NLS-2$
}
}
-
diff --git a/luni/src/main/java/java/util/Map.java b/luni/src/main/java/java/util/Map.java
index d8b1e62..7509d1a 100644
--- a/luni/src/main/java/java/util/Map.java
+++ b/luni/src/main/java/java/util/Map.java
@@ -23,19 +23,15 @@
* in which each key is mapped to a single value. The class of the objects
* used as keys is declared when the {@code Map} is declared, as is the
* class of the corresponding values.
- * <p>A {@code Map} provides helper methods to iterate through all of the
+ * <p>
+ * A {@code Map} provides helper methods to iterate through all of the
* keys contained in it, as well as various methods to access and update
* the key/value pairs.
- * </p>
- *
- * @since Android 1.0
*/
public interface Map<K,V> {
/**
* {@code Map.Entry} is a key/value mapping contained in a {@code Map}.
- *
- * @since Android 1.0
*/
public static interface Entry<K,V> {
/**
@@ -48,7 +44,6 @@
* @return {@code true} if the specified {@code Object} is equal to this
* {@code Map.Entry}, {@code false} otherwise.
* @see #hashCode()
- * @since Android 1.0
*/
public boolean equals(Object object);
@@ -56,7 +51,6 @@
* Returns the key.
*
* @return the key
- * @since Android 1.0
*/
public K getKey();
@@ -64,7 +58,6 @@
* Returns the value.
*
* @return the value
- * @since Android 1.0
*/
public V getValue();
@@ -74,7 +67,6 @@
*
* @return the receiver's hash code.
* @see #equals(Object)
- * @since Android 1.0
*/
public int hashCode();
@@ -85,7 +77,6 @@
* @param object
* the new value to set.
* @return object the replaced value of this entry.
- * @since Android 1.0
*/
public V setValue(V object);
};
@@ -97,7 +88,6 @@
* if removing elements from this {@code Map} is not supported.
* @see #isEmpty()
* @see #size()
- * @since Android 1.0
*/
public void clear();
@@ -108,7 +98,6 @@
* the key to search for.
* @return {@code true} if this map contains the specified key,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean containsKey(Object key);
@@ -119,7 +108,6 @@
* the value to search for.
* @return {@code true} if this map contains the specified value,
* {@code false} otherwise.
- * @since Android 1.0
*/
public boolean containsValue(Object value);
@@ -129,7 +117,6 @@
* changes in one will be reflected in the other.
*
* @return a set of the mappings
- * @since Android 1.0
*/
public Set<Map.Entry<K,V>> entrySet();
@@ -143,7 +130,6 @@
* {@code false} if it is different from this {@code Object}.
* @see #hashCode()
* @see #entrySet()
- * @since Android 1.0
*/
public boolean equals(Object object);
@@ -154,7 +140,6 @@
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
- * @since Android 1.0
*/
public V get(Object key);
@@ -164,7 +149,6 @@
*
* @return the receiver's hash.
* @see #equals(Object)
- * @since Android 1.0
*/
public int hashCode();
@@ -174,7 +158,6 @@
* @return {@code true} if this map has no elements, {@code false}
* otherwise.
* @see #size()
- * @since Android 1.0
*/
public boolean isEmpty();
@@ -184,7 +167,6 @@
* support adding.
*
* @return a set of the keys.
- * @since Android 1.0
*/
public Set<K> keySet();
@@ -207,7 +189,6 @@
* @throws NullPointerException
* if the key or value is {@code null} and this {@code Map} does
* not support {@code null} keys or values.
- * @since Android 1.0
*/
public V put(K key, V value);
@@ -226,7 +207,6 @@
* @throws NullPointerException
* if a key or value is {@code null} and this {@code Map} does not
* support {@code null} keys or values.
- * @since Android 1.0
*/
public void putAll(Map<? extends K,? extends V> map);
@@ -239,7 +219,6 @@
* for the specified key was found.
* @throws UnsupportedOperationException
* if removing from this {@code Map} is not supported.
- * @since Android 1.0
*/
public V remove(Object key);
@@ -247,7 +226,6 @@
* Returns the number of mappings in this {@code Map}.
*
* @return the number of mappings in this {@code Map}.
- * @since Android 1.0
*/
public int size();
@@ -263,16 +241,13 @@
* "wrapper object" over the iterator of this {@code Map}'s {@link #entrySet()}. The {@link AbstractCollection#size} method
* wraps this {@code Map}'s {@link #size} method and the {@link AbstractCollection#contains} method wraps this {@code Map}'s
* {@link #containsValue} method.
- * </p>
* <p>
* The collection is created when this method is called at first time and
* returned in response to all subsequent calls. This method may return
* different Collection when multiple calls to this method, since it has no
* synchronization performed.
- * </p>
*
* @return a collection of the values contained in this map.
- * @since Android 1.0
*/
public Collection<V> values();
}
diff --git a/luni/src/main/java/java/util/MapEntry.java b/luni/src/main/java/java/util/MapEntry.java
index a63f2fd..6a5bf0f 100644
--- a/luni/src/main/java/java/util/MapEntry.java
+++ b/luni/src/main/java/java/util/MapEntry.java
@@ -17,17 +17,16 @@
package java.util;
-
/**
* MapEntry is an internal class which provides an implementation of Map.Entry.
*/
-class MapEntry<K,V> implements Map.Entry<K,V>, Cloneable {
-
+class MapEntry<K, V> implements Map.Entry<K, V>, Cloneable {
+
K key;
V value;
- interface Type<RT,KT,VT> {
- RT get(MapEntry<KT,VT> entry);
+ interface Type<RT, KT, VT> {
+ RT get(MapEntry<KT, VT> entry);
}
MapEntry(K theKey) {
@@ -82,7 +81,7 @@
value = object;
return result;
}
-
+
@Override
public String toString() {
return key + "=" + value;
diff --git a/luni/src/main/java/java/util/MissingFormatArgumentException.java b/luni/src/main/java/java/util/MissingFormatArgumentException.java
index bcd240c..dfa0c73 100644
--- a/luni/src/main/java/java/util/MissingFormatArgumentException.java
+++ b/luni/src/main/java/java/util/MissingFormatArgumentException.java
@@ -24,7 +24,6 @@
* that refers to a missing argument.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class MissingFormatArgumentException extends IllegalFormatException {
private static final long serialVersionUID = 19190115L;
diff --git a/luni/src/main/java/java/util/MissingFormatWidthException.java b/luni/src/main/java/java/util/MissingFormatWidthException.java
index 19af7d7..8b4e1f8 100644
--- a/luni/src/main/java/java/util/MissingFormatWidthException.java
+++ b/luni/src/main/java/java/util/MissingFormatWidthException.java
@@ -21,7 +21,6 @@
* missing but is required.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class MissingFormatWidthException extends IllegalFormatException {
private static final long serialVersionUID = 15560123L;
diff --git a/luni/src/main/java/java/util/MissingResourceException.java b/luni/src/main/java/java/util/MissingResourceException.java
index c3a7efe..9a0cbbb 100644
--- a/luni/src/main/java/java/util/MissingResourceException.java
+++ b/luni/src/main/java/java/util/MissingResourceException.java
@@ -25,7 +25,6 @@
*
* @see ResourceBundle
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class MissingResourceException extends RuntimeException {
diff --git a/luni/src/main/java/java/util/Observable.java b/luni/src/main/java/java/util/Observable.java
index a4c0333..5ed4563 100644
--- a/luni/src/main/java/java/util/Observable.java
+++ b/luni/src/main/java/java/util/Observable.java
@@ -17,7 +17,6 @@
package java.util;
-
/**
* Observable is used to notify a group of Observer objects when a change
* occurs. On creation, the set of observers is empty. After a change occurred,
@@ -26,21 +25,17 @@
* Observers. The order of invocation is not specified. This implementation will
* call the Observers in the order they registered. Subclasses are completely
* free in what order they call the update methods.
- *
+ *
* @see Observer
- *
- * @since Android 1.0
*/
public class Observable {
-
- Vector<Observer> observers = new Vector<Observer>();
+
+ List<Observer> observers = new ArrayList<Observer>();
boolean changed = false;
/**
* Constructs a new {@code Observable} object.
- *
- * @since Android 1.0
*/
public Observable() {
super();
@@ -49,68 +44,62 @@
/**
* Adds the specified observer to the list of observers. If it is already
* registered, it is not added a second time.
- *
+ *
* @param observer
* the Observer to add.
- * @since Android 1.0
*/
- public synchronized void addObserver(Observer observer) {
+ public void addObserver(Observer observer) {
if (observer == null) {
throw new NullPointerException();
}
- if (!observers.contains(observer))
- observers.addElement(observer);
+ synchronized (this) {
+ if (!observers.contains(observer))
+ observers.add(observer);
+ }
}
/**
* Clears the changed flag for this {@code Observable}. After calling
* {@code clearChanged()}, {@code hasChanged()} will return {@code false}.
- *
- * @since Android 1.0
*/
- protected synchronized void clearChanged() {
+ protected void clearChanged() {
changed = false;
}
/**
* Returns the number of observers registered to this {@code Observable}.
- *
+ *
* @return the number of observers.
- * @since Android 1.0
*/
- public synchronized int countObservers() {
+ public int countObservers() {
return observers.size();
}
/**
* Removes the specified observer from the list of observers. Passing null
* won't do anything.
- *
+ *
* @param observer
* the observer to remove.
- * @since Android 1.0
*/
public synchronized void deleteObserver(Observer observer) {
- observers.removeElement(observer);
+ observers.remove(observer);
}
/**
* Removes all observers from the list of observers.
- *
- * @since Android 1.0
*/
public synchronized void deleteObservers() {
- observers.setSize(0);
+ observers.clear();
}
/**
* Returns the changed flag for this {@code Observable}.
- *
+ *
* @return {@code true} when the changed flag for this {@code Observable} is
* set, {@code false} otherwise.
- * @since Android 1.0
*/
- public synchronized boolean hasChanged() {
+ public boolean hasChanged() {
return changed;
}
@@ -120,9 +109,6 @@
* argument. Afterwards, calls {@code clearChanged()}.
* <p>
* Equivalent to calling {@code notifyObservers(null)}.
- * </p>
- *
- * @since Android 1.0
*/
public void notifyObservers() {
notifyObservers(null);
@@ -132,31 +118,34 @@
* If {@code hasChanged()} returns {@code true}, calls the {@code update()}
* method for every Observer in the list of observers using the specified
* argument. Afterwards calls {@code clearChanged()}.
- *
+ *
* @param data
* the argument passed to {@code update()}.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public void notifyObservers(Object data) {
- if (hasChanged()) {
- // Must clone the vector in case deleteObserver is called
- Vector<Observer> clone = (Vector<Observer>)observers.clone();
- int size = clone.size();
- for (int i = 0; i < size; i++) {
- clone.elementAt(i).update(this, data);
+ int size = 0;
+ Observer[] arrays = null;
+ synchronized (this) {
+ if (hasChanged()) {
+ clearChanged();
+ size = observers.size();
+ arrays = new Observer[size];
+ observers.toArray(arrays);
}
- clearChanged();
+ }
+ if (arrays != null) {
+ for (Observer observer : arrays) {
+ observer.update(this, data);
+ }
}
}
/**
* Sets the changed flag for this {@code Observable}. After calling
* {@code setChanged()}, {@code hasChanged()} will return {@code true}.
- *
- * @since Android 1.0
*/
- protected synchronized void setChanged() {
+ protected void setChanged() {
changed = true;
}
}
diff --git a/luni/src/main/java/java/util/Observer.java b/luni/src/main/java/java/util/Observer.java
index 2c8417b..c398e1b 100644
--- a/luni/src/main/java/java/util/Observer.java
+++ b/luni/src/main/java/java/util/Observer.java
@@ -23,7 +23,6 @@
* receive notification of updates on an {@code Observable} object.
*
* @see Observable
- * @since Android 1.0
*/
public interface Observer {
@@ -36,7 +35,6 @@
* the {@link Observable} object.
* @param data
* the data passed to {@link Observable#notifyObservers(Object)}.
- * @since Android 1.0
*/
void update(Observable observable, Object data);
}
diff --git a/luni/src/main/java/java/util/PriorityQueue.java b/luni/src/main/java/java/util/PriorityQueue.java
index 544c538..c17e7f9 100644
--- a/luni/src/main/java/java/util/PriorityQueue.java
+++ b/luni/src/main/java/java/util/PriorityQueue.java
@@ -31,8 +31,6 @@
* <p>
* A PriorityQueue is not synchronized. If multiple threads will have to access
* it concurrently, use the {@link java.util.concurrent.PriorityBlockingQueue}.
- *
- * @since Android 1.0
*/
public class PriorityQueue<E> extends AbstractQueue<E> implements Serializable {
@@ -53,8 +51,6 @@
/**
* Constructs a priority queue with an initial capacity of 11 and natural
* ordering.
- *
- * @since Android 1.0
*/
public PriorityQueue() {
this(DEFAULT_CAPACITY);
@@ -68,7 +64,6 @@
* the specified capacity.
* @throws IllegalArgumentException
* if the initialCapacity is less than 1.
- * @since Android 1.0
*/
public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
@@ -84,7 +79,6 @@
* will be used.
* @throws IllegalArgumentException
* if the initialCapacity is less than 1.
- * @since Android 1.0
*/
public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) {
if (initialCapacity < 1) {
@@ -107,7 +101,6 @@
* if any of the elements in the collection are not comparable.
* @throws NullPointerException
* if any of the elements in the collection are null.
- * @since Android 1.0
*/
public PriorityQueue(Collection<? extends E> c) {
if (c instanceof PriorityQueue) {
@@ -129,7 +122,6 @@
* @param c
* the priority queue whose elements will be added to the
* priority queue to be constructed.
- * @since Android 1.0
*/
public PriorityQueue(PriorityQueue<? extends E> c) {
getFromPriorityQueue(c);
@@ -144,7 +136,6 @@
* @param c
* the sorted set whose elements will be added to the priority
* queue to be constructed.
- * @since Android 1.0
*/
public PriorityQueue(SortedSet<? extends E> c) {
getFromSortedSet(c);
@@ -155,7 +146,6 @@
* in any specified ordering.
*
* @return the iterator of the priority queue.
- * @since Android 1.0
*/
@Override
public Iterator<E> iterator() {
@@ -167,7 +157,6 @@
* than the Integer.MAX, then it returns Integer.MAX.
*
* @return the size of the priority queue.
- * @since Android 1.0
*/
@Override
public int size() {
@@ -176,8 +165,6 @@
/**
* Removes all the elements of the priority queue.
- *
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -194,7 +181,8 @@
* @throws ClassCastException
* if the element cannot be compared with the elements in the
* priority queue using the ordering of the priority queue.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code o} is {@code null}.
*/
public boolean offer(E o) {
if (null == o) {
@@ -210,7 +198,6 @@
* Gets and removes the head of the queue.
*
* @return the head of the queue or null if the queue is empty.
- * @since Android 1.0
*/
public E poll() {
if (isEmpty()) {
@@ -225,7 +212,6 @@
* Gets but does not remove the head of the queue.
*
* @return the head of the queue or null if the queue is empty.
- * @since Android 1.0
*/
public E peek() {
if (isEmpty()) {
@@ -239,7 +225,6 @@
*
* @return the comparator of the priority queue or null if the natural
* ordering is used.
- * @since Android 1.0
*/
public Comparator<? super E> comparator() {
return comparator;
@@ -252,7 +237,6 @@
* the object to be removed.
* @return true if the object was in the priority queue, false if the object
* was not in the priority queue.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -282,7 +266,8 @@
* @throws ClassCastException
* if the element cannot be compared with the elements in the
* priority queue using the ordering of the priority queue.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code o} is {@code null}.
*/
@Override
public boolean add(E o) {
diff --git a/luni/src/main/java/java/util/Properties.java b/luni/src/main/java/java/util/Properties.java
index 15b74ee..b1fa938 100644
--- a/luni/src/main/java/java/util/Properties.java
+++ b/luni/src/main/java/java/util/Properties.java
@@ -17,9 +17,9 @@
package java.util;
-
import java.io.IOException;
import java.io.InputStream;
+import java.io.BufferedInputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
@@ -48,45 +48,37 @@
import org.w3c.dom.Text;
// END android-added
-// BEGIN android-added
-// copied from newer version of Haromny
import org.apache.harmony.luni.internal.nls.Messages;
-// END android-added
import org.apache.harmony.luni.util.PriviAction;
/**
- * A {@code Properties} object is a {@code Hashtable} where the keys and values
- * must be {@code String}s. Each property can have a default
+ * A {@code Properties} object is a {@code Hashtable} where the keys and values
+ * must be {@code String}s. Each property can have a default
* {@code Properties} list which specifies the default
* values to be used when a given key is not found in this {@code Properties}
* instance.
- *
+ *
* @see Hashtable
* @see java.lang.System#getProperties
- * @since Android 1.0
*/
-public class Properties extends Hashtable<Object,Object> {
-
+public class Properties extends Hashtable<Object, Object> {
+
private static final long serialVersionUID = 4112578634029874840L;
private transient DocumentBuilder builder = null;
- private static final String PROP_DTD_NAME
- = "http://java.sun.com/dtd/properties.dtd";
+ private static final String PROP_DTD_NAME = "http://java.sun.com/dtd/properties.dtd";
- private static final String PROP_DTD
- = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ private static final String PROP_DTD = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ " <!ELEMENT properties (comment?, entry*) >"
+ " <!ATTLIST properties version CDATA #FIXED \"1.0\" >"
+ " <!ELEMENT comment (#PCDATA) >"
+ " <!ELEMENT entry (#PCDATA) >"
+ " <!ATTLIST entry key CDATA #REQUIRED >";
-
+
/**
* The default values for keys not found in this {@code Properties}
* instance.
- *
- * @since Android 1.0
*/
protected Properties defaults;
@@ -95,8 +87,6 @@
/**
* Constructs a new {@code Properties} object.
- *
- * @since Android 1.0
*/
public Properties() {
super();
@@ -105,10 +95,9 @@
/**
* Constructs a new {@code Properties} object using the specified default
* {@code Properties}.
- *
+ *
* @param properties
* the default {@code Properties}.
- * @since Android 1.0
*/
public Properties(Properties properties) {
defaults = properties;
@@ -158,11 +147,10 @@
* Searches for the property with the specified name. If the property is not
* found, the default {@code Properties} are checked. If the property is not
* found in the default {@code Properties}, {@code null} is returned.
- *
+ *
* @param name
* the name of the property to find.
* @return the named property value, or {@code null} if it can't be found.
- * @since Android 1.0
*/
public String getProperty(String name) {
Object result = super.get(name);
@@ -178,13 +166,12 @@
* found, it looks in the default {@code Properties}. If the property is not
* found in the default {@code Properties}, it returns the specified
* default.
- *
+ *
* @param name
* the name of the property to find.
* @param defaultValue
* the default value.
* @return the named property value.
- * @since Android 1.0
*/
public String getProperty(String name, String defaultValue) {
Object result = super.get(name);
@@ -202,11 +189,10 @@
* Lists the mappings in this {@code Properties} to the specified
* {@code PrintStream} in a
* human readable form.
- *
+ *
* @param out
* the {@code PrintStream} to write the content to in human readable
* form.
- * @since Android 1.0
*/
public void list(PrintStream out) {
if (out == null) {
@@ -239,11 +225,10 @@
* Lists the mappings in this {@code Properties} to the specified
* {@code PrintWriter} in a
* human readable form.
- *
+ *
* @param writer
* the {@code PrintWriter} to write the content to in human
* readable form.
- * @since Android 1.0
*/
public void list(PrintWriter writer) {
if (writer == null) {
@@ -293,29 +278,40 @@
* <li>Following escape sequences are recognized: "\ ", "\\", "\r", "\n",
* "\!", "\#", "\t", "\b", "\f", and "\uXXXX" (unicode character).</li>
* </ul>
- *
+ *
* @param in
* the {@code InputStream}.
* @throws IOException
* if error occurs during reading from the {@code InputStream}.
- * @since Android 1.0
*/
+ @SuppressWarnings("fallthrough")
public synchronized void load(InputStream in) throws IOException {
+ if (in == null) {
+ throw new NullPointerException();
+ }
int mode = NONE, unicode = 0, count = 0;
char nextChar, buf[] = new char[40];
- int offset = 0, keyLength = -1;
+ int offset = 0, keyLength = -1, intVal;
boolean firstChar = true;
- byte[] inbuf = new byte[256];
- int inbufCount = 0, inbufPos = 0;
+ BufferedInputStream bis = new BufferedInputStream(in);
while (true) {
- if (inbufPos == inbufCount) {
- if ((inbufCount = in.read(inbuf)) == -1) {
- break;
+ intVal = bis.read();
+ if (intVal == -1) {
+ // if mode is UNICODE but has less than 4 hex digits, should
+ // throw an IllegalArgumentException
+ // luni.08=Invalid Unicode sequence: expected format \\uxxxx
+ if (mode == UNICODE && count < 4) {
+ throw new IllegalArgumentException(Messages.getString("luni.08")); //$NON-NLS-1$
}
- inbufPos = 0;
+ // if mode is SLASH and no data is read, should append '\u0000'
+ // to buf
+ if (mode == SLASH) {
+ buf[offset++] = '\u0000';
+ }
+ break;
}
- nextChar = (char) (inbuf[inbufPos++] & 0xff);
+ nextChar = (char) (intVal & 0xff);
if (offset == buf.length) {
char[] newBuf = new char[buf.length * 2];
@@ -324,8 +320,6 @@
}
if (mode == UNICODE) {
int digit = Character.digit(nextChar, 16);
- // BEGIN android-changed
- // copied from newer version of Harmony
if (digit >= 0) {
unicode = (unicode << 4) + digit;
if (++count < 4) {
@@ -333,9 +327,8 @@
}
} else if (count <= 4) {
// luni.09=Invalid Unicode sequence: illegal character
- throw new IllegalArgumentException(Messages.getString("luni.09"));
+ throw new IllegalArgumentException(Messages.getString("luni.09")); //$NON-NLS-1$
}
- // END android-changed
mode = NONE;
buf[offset++] = (char) unicode;
if (nextChar != '\n') {
@@ -377,16 +370,12 @@
case '!':
if (firstChar) {
while (true) {
- if (inbufPos == inbufCount) {
- if ((inbufCount = in.read(inbuf)) == -1) {
- inbufPos = -1;
- break;
- }
- inbufPos = 0;
+ intVal = bis.read();
+ if (intVal == -1) {
+ break;
}
- nextChar = (char) inbuf[inbufPos++]; // & 0xff
- // not
- // required
+ // & 0xff not required
+ nextChar = (char) intVal;
if (nextChar == '\r' || nextChar == '\n') {
break;
}
@@ -399,7 +388,7 @@
mode = IGNORE; // Ignore whitespace on the next line
continue;
}
- // fall into the next case
+ // fall into the next case
case '\r':
mode = NONE;
firstChar = true;
@@ -453,13 +442,9 @@
}
buf[offset++] = nextChar;
}
- // BEGIN android-added
- // copied from a newer version of Harmony
- if (mode == UNICODE && count <= 4) {
- // luni.08=Invalid Unicode sequence: expected format \\uxxxx
- throw new IllegalArgumentException(Messages.getString("luni.08"));
+ if (keyLength == -1 && offset > 0) {
+ keyLength = offset;
}
- // END android-added
if (keyLength >= 0) {
String temp = new String(buf, 0, offset);
put(temp.substring(0, keyLength), temp.substring(keyLength));
@@ -469,17 +454,18 @@
/**
* Returns all of the property names that this {@code Properties} object
* contains.
- *
+ *
* @return an {@code Enumeration} containing the names of all properties
* that this {@code Properties} object contains.
- * @since Android 1.0
*/
public Enumeration<?> propertyNames() {
if (defaults == null) {
return keys();
}
- Hashtable<Object, Object> set = new Hashtable<Object, Object>(defaults.size() + size());
+ Hashtable<Object, Object> set = new Hashtable<Object, Object>(defaults
+ .size()
+ + size());
Enumeration<?> keys = defaults.propertyNames();
while (keys.hasMoreElements()) {
set.put(keys.nextElement(), set);
@@ -496,15 +482,14 @@
* OutputStream}, putting the specified comment at the beginning. The output
* from this method is suitable for being read by the
* {@link #load(InputStream)} method.
- *
+ *
* @param out the {@code OutputStream} to write to.
* @param comment the comment to add at the beginning.
- * @exception ClassCastException when the key or value of a mapping is not a
+ * @throws ClassCastException if the key or value of a mapping is not a
* String.
* @deprecated This method ignores any {@code IOException} thrown while
* writing -- use {@link #store} instead for better exception
* handling.
- * @since Android 1.0
*/
@Deprecated
public void save(OutputStream out, String comment) {
@@ -517,13 +502,12 @@
/**
* Maps the specified key to the specified value. If the key already exists,
* the old value is replaced. The key and value cannot be {@code null}.
- *
+ *
* @param name
* the key.
* @param value
* the value.
* @return the old value mapped to the key, or {@code null}.
- * @since Android 1.0
*/
public Object setProperty(String name, String value) {
return put(name, value);
@@ -536,14 +520,13 @@
* OutputStream}, putting the specified comment at the beginning. The output
* from this method is suitable for being read by the
* {@link #load(InputStream)} method.
- *
+ *
* @param out the {@code OutputStream} to write to.
* @param comment the comment to put at the beginning.
* @throws IOException if an error occurs during the write to the {@code
* OutputStream}.
- * @exception ClassCastException when the key or value of a mapping is not a
+ * @throws ClassCastException if the key or value of a mapping is not a
* {@code String}.
- * @since Android 1.0
*/
public synchronized void store(OutputStream out, String comment)
throws IOException {
@@ -557,11 +540,11 @@
if (comment != null) {
writer.write("#"); //$NON-NLS-1$
writer.write(comment);
- writer.write(lineSeparator);
+ writer.write(lineSeparator);
}
writer.write("#"); //$NON-NLS-1$
writer.write(new Date().toString());
- writer.write(lineSeparator);
+ writer.write(lineSeparator);
for (Map.Entry<Object, Object> entry : entrySet()) {
String key = (String) entry.getKey();
@@ -579,39 +562,38 @@
* Loads the properties from an {@code InputStream} containing the
* properties in XML form. The XML document must begin with (and conform to)
* following DOCTYPE:
- *
+ *
* <pre>
* <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
* </pre>
- *
+ *
* Also the content of the XML data must satisfy the DTD but the xml is not
* validated against it. The DTD is not loaded from the SYSTEM ID. After
* this method returns the InputStream is not closed.
- *
+ *
* @param in the InputStream containing the XML document.
* @throws IOException in case an error occurs during a read operation.
* @throws InvalidPropertiesFormatException if the XML data is not a valid
* properties file.
- * @since Android 1.0
*/
- public synchronized void loadFromXML(InputStream in)
- throws IOException, InvalidPropertiesFormatException {
+ public synchronized void loadFromXML(InputStream in) throws IOException,
+ InvalidPropertiesFormatException {
if (in == null) {
throw new NullPointerException();
}
-
+
if (builder == null) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// BEGIN android-removed
// factory.setValidating(true);
// END android-removed
-
+
try {
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new Error(e);
}
-
+
builder.setErrorHandler(new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
throw e;
@@ -625,30 +607,30 @@
throw e;
}
});
-
+
builder.setEntityResolver(new EntityResolver() {
- public InputSource resolveEntity(String publicId, String systemId)
- throws SAXException, IOException {
+ public InputSource resolveEntity(String publicId,
+ String systemId) throws SAXException, IOException {
if (systemId.equals(PROP_DTD_NAME)) {
InputSource result = new InputSource(new StringReader(
PROP_DTD));
result.setSystemId(PROP_DTD_NAME);
return result;
}
- throw new SAXException(
- "Invalid DOCTYPE declaration: " + systemId);
+ throw new SAXException("Invalid DOCTYPE declaration: "
+ + systemId);
}
});
}
-
+
try {
Document doc = builder.parse(in);
- NodeList entries = doc.getElementsByTagName("entry");
+ NodeList entries = doc.getElementsByTagName("entry");
if (entries == null) {
return;
}
int entriesListLength = entries.getLength();
-
+
for (int i = 0; i < entriesListLength; i++) {
Element entry = (Element) entries.item(i);
String key = entry.getAttribute("key");
@@ -658,10 +640,10 @@
// BEGIN android-added
String value = getTextContent(entry);
// END android-added
-
+
/*
- * key != null & value != null
- * but key or(and) value can be empty String
+ * key != null & value != null but key or(and) value can be
+ * empty String
*/
put(key, value);
}
@@ -675,44 +657,41 @@
/**
* Writes all properties stored in this instance into the {@code
* OutputStream} in XML representation. The DOCTYPE is
- *
+ *
* <pre>
* <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
* </pre>
- *
+ *
* If the comment is null, no comment is added to the output. UTF-8 is used
* as the encoding. The {@code OutputStream} is not closed at the end. A
* call to this method is the same as a call to {@code storeToXML(os,
* comment, "UTF-8")}.
- *
+ *
* @param os the {@code OutputStream} to write to.
* @param comment the comment to add. If null, no comment is added.
* @throws IOException if an error occurs during writing to the output.
- * @since Android 1.0
*/
- public void storeToXML(OutputStream os, String comment)
- throws IOException {
- storeToXML(os, comment, "UTF-8");
+ public void storeToXML(OutputStream os, String comment) throws IOException {
+ storeToXML(os, comment, "UTF-8"); //$NON-NLS-1$
}
/**
* Writes all properties stored in this instance into the {@code
* OutputStream} in XML representation. The DOCTYPE is
- *
+ *
* <pre>
* <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
* </pre>
- *
+ *
* If the comment is null, no comment is added to the output. The parameter
* {@code encoding} defines which encoding should be used. The {@code
* OutputStream} is not closed at the end.
- *
+ *
* @param os the {@code OutputStream} to write to.
* @param comment the comment to add. If null, no comment is added.
* @param encoding the code identifying the encoding that should be used to
* write into the {@code OutputStream}.
* @throws IOException if an error occurs during writing to the output.
- * @since Android 1.0
*/
public synchronized void storeToXML(OutputStream os, String comment,
String encoding) throws IOException {
@@ -720,14 +699,14 @@
if (os == null || encoding == null) {
throw new NullPointerException();
}
-
+
/*
* We can write to XML file using encoding parameter but note that some
* aliases for encodings are not supported by the XML parser. Thus we
* have to know canonical name for encoding used to store data in XML
* since the XML parser must recognize encoding name used to store data.
*/
-
+
String encodingCanonicalName;
try {
encodingCanonicalName = Charset.forName(encoding).name();
@@ -741,18 +720,19 @@
encodingCanonicalName = "UTF-8";
}
- PrintStream printStream = new PrintStream(os, false, encodingCanonicalName);
-
+ PrintStream printStream = new PrintStream(os, false,
+ encodingCanonicalName);
+
printStream.print("<?xml version=\"1.0\" encoding=\"");
printStream.print(encodingCanonicalName);
printStream.println("\"?>");
-
+
printStream.print("<!DOCTYPE properties SYSTEM \"");
printStream.print(PROP_DTD_NAME);
printStream.println("\">");
-
+
printStream.println("<properties>");
-
+
if (comment != null) {
printStream.print("<comment>");
printStream.print(substitutePredefinedEntries(comment));
@@ -771,18 +751,16 @@
printStream.println("</properties>");
printStream.flush();
}
-
+
private String substitutePredefinedEntries(String s) {
-
+
/*
- * substitution for predefined character entities
- * to use them safely in XML
+ * substitution for predefined character entities to use them safely in
+ * XML
*/
- return s.replaceAll("&", "&")
- .replaceAll("<", "<")
- .replaceAll(">", ">")
- .replaceAll("\u0027", "'")
- .replaceAll("\"", """);
+ return s.replaceAll("&", "&").replaceAll("<", "<").replaceAll(
+ ">", ">").replaceAll("\u0027", "'").replaceAll("\"",
+ """);
}
// BEGIN android-added
diff --git a/luni/src/main/java/java/util/PropertyPermission.java b/luni/src/main/java/java/util/PropertyPermission.java
index cdbfe34..1cd7143 100644
--- a/luni/src/main/java/java/util/PropertyPermission.java
+++ b/luni/src/main/java/java/util/PropertyPermission.java
@@ -39,8 +39,6 @@
* <p>
* There are two possible permission action types: read and write. Possible
* actions are "read", "write", or "read,write"/"write,read".
- *
- * @since Android 1.0
*/
public final class PropertyPermission extends BasicPermission {
private static final long serialVersionUID = 885438825399942851L;
@@ -56,7 +54,6 @@
* the actions which are applicable to it. Possible actions are
* "read", "write", or "read,write"/"write,read". Anything else
* will result in an {@code IllegalArgumentException}.
- * @since Android 1.0
*/
public PropertyPermission(String name, String actions) {
super(name);
@@ -84,17 +81,16 @@
/**
* Compares the argument to the receiver, and returns true if they represent
* the <em>same</em> object using a class specific comparison. In this
- * case, the receiver must be a {@code PropertyPermission} for the same
+ * case, the receiver must be a {@code PropertyPermission} for the same
* property as the argument, and must have the same actions.
* If {@code o} is a permission that is not a {@code PropertyPermission},
- * this method may throw a {@code ClassCastException}.
- *
+ * this method may throw a {@code ClassCastException}.
+ *
* @param o
* the {@code Object} to compare with this {@code Object}.
* @return {@code true} if the {@code Object} is the same as this {@code Object},
* {@code false} if it is different from this {@code Object}.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object o) {
@@ -110,7 +106,6 @@
* either "read", "write", or "read,write".
*
* @return the actions associated with the receiver.
- * @since Android 1.0
*/
@Override
public String getActions() {
@@ -124,7 +119,6 @@
*
* @return the receiver's hash.
* @see #equals
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -138,7 +132,6 @@
* receiver, and {@code false} if it is not.
* @param permission
* the permission to check.
- * @since Android 1.0
*/
@Override
public boolean implies(Permission permission) {
@@ -155,7 +148,6 @@
*
* @return a new {@code PermissionCollection} or {@code null}.
* @see java.security.PermissionCollection
- * @since Android 1.0
*/
@Override
public PermissionCollection newPermissionCollection() {
diff --git a/luni/src/main/java/java/util/PropertyPermissionCollection.java b/luni/src/main/java/java/util/PropertyPermissionCollection.java
index 45e89d9..bf88534 100644
--- a/luni/src/main/java/java/util/PropertyPermissionCollection.java
+++ b/luni/src/main/java/java/util/PropertyPermissionCollection.java
@@ -26,8 +26,6 @@
/**
* A {@code PermissionCollection} for holding {@code PropertyPermission}s.
- *
- * @since Android 1.0
*/
class PropertyPermissionCollection extends PermissionCollection {
diff --git a/luni/src/main/java/java/util/PropertyResourceBundle.java b/luni/src/main/java/java/util/PropertyResourceBundle.java
index acc3263..835e892 100644
--- a/luni/src/main/java/java/util/PropertyResourceBundle.java
+++ b/luni/src/main/java/java/util/PropertyResourceBundle.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.io.IOException;
import java.io.InputStream;
@@ -28,9 +27,10 @@
*
* @see ResourceBundle
* @see Properties
- * @since Android 1.0
+ * @since 1.1
*/
public class PropertyResourceBundle extends ResourceBundle {
+
Properties resources;
/**
@@ -42,18 +42,23 @@
* @throws IOException
* if an error occurs during a read operation on the
* {@code InputStream}.
- * @since Android 1.0
*/
public PropertyResourceBundle(InputStream stream) throws IOException {
resources = new Properties();
resources.load(stream);
}
-
+
@SuppressWarnings("unchecked")
private Enumeration<String> getLocalKeys() {
- return (Enumeration<String>)resources.propertyNames();
+ return (Enumeration<String>) resources.propertyNames();
}
+ /**
+ * Returns the names of the resources contained in this
+ * PropertyResourceBundle.
+ *
+ * @return an Enumeration of the resource names
+ */
@Override
public Enumeration<String> getKeys() {
if (parent == null) {
@@ -102,6 +107,14 @@
};
}
+ /**
+ * Returns the named resource from this PropertyResourceBundle, or null if
+ * the resource is not found.
+ *
+ * @param key
+ * the name of the resource
+ * @return the resource object
+ */
@Override
public Object handleGetObject(String key) {
return resources.get(key);
diff --git a/luni/src/main/java/java/util/Queue.java b/luni/src/main/java/java/util/Queue.java
index 5035ce7..6ef776a 100644
--- a/luni/src/main/java/java/util/Queue.java
+++ b/luni/src/main/java/java/util/Queue.java
@@ -24,22 +24,17 @@
* However, a priority queue orders its elements according to a comparator
* specified or the elements' natural order. Furthermore, a stack orders its
* elements last-in-first out.
- * </p>
* <p>
* A typical queue does not allow {@code null} to be inserted as its element,
* while some implementations such as {@code LinkedList} allow it. But {@code
* null} should not be inserted even in these implementations, since the method
* {@code poll} returns {@code null} to indicate that there is no element left
* in the queue.
- * </p>
* <p>
* {@code Queue} does not provide blocking queue methods, which would block
* until the operation of the method is allowed. See the
* {@link java.util.concurrent.BlockingQueue} interface for information about
* blocking queue methods.
- * </p>
- *
- * @since Android 1.0
*/
public interface Queue<E> extends Collection<E> {
@@ -53,7 +48,6 @@
* the specified element to insert into the queue.
* @return {@code true} if the operation succeeds and {@code false} if it
* fails.
- * @since Android 1.0
*/
public boolean offer(E o);
@@ -63,7 +57,6 @@
*
* @return the element at the head of the queue or {@code null} if there is
* no element in the queue.
- * @since Android 1.0
*/
public E poll();
@@ -74,7 +67,6 @@
* @return the element at the head of the queue.
* @throws NoSuchElementException
* if there is no element in the queue.
- * @since Android 1.0
*/
public E remove();
@@ -83,7 +75,6 @@
*
* @return the element at the head of the queue or {@code null} if there is
* no element in the queue.
- * @since Android 1.0
*/
public E peek();
@@ -94,7 +85,6 @@
* @return the element at the head of the queue.
* @throws NoSuchElementException
* if there is no element in the queue.
- * @since Android 1.0
*/
public E element();
diff --git a/luni/src/main/java/java/util/Random.java b/luni/src/main/java/java/util/Random.java
index f92c3ee..be27258 100644
--- a/luni/src/main/java/java/util/Random.java
+++ b/luni/src/main/java/java/util/Random.java
@@ -26,44 +26,40 @@
*
* @see Properties
* @see PropertyResourceBundle
- * @since Android 1.0
*/
public class Random implements Serializable {
private static final long serialVersionUID = 3905348978240129619L;
- static final long multiplier = 0x5deece66dL;
+ private static final long multiplier = 0x5deece66dL;
/**
* The boolean value indicating if the second Gaussian number is available.
*
* @serial
*/
- boolean haveNextNextGaussian = false;
+ private boolean haveNextNextGaussian;
/**
- * It is associated with the internal state of this generator.
- *
- * @serial
+ * @serial It is associated with the internal state of this generator.
*/
- long seed;
+ private long seed;
/**
* The second Gaussian generated number.
*
* @serial
*/
- double nextNextGaussian = 0;
+ private double nextNextGaussian;
/**
* Construct a random generator with the current time of day in milliseconds
* as the initial state.
*
* @see #setSeed
- * @since Android 1.0
*/
public Random() {
- setSeed(System.currentTimeMillis());
+ setSeed(System.currentTimeMillis() + hashCode());
}
/**
@@ -74,7 +70,6 @@
* the seed that will determine the initial state of this random
* number generator.
* @see #setSeed
- * @since Android 1.0
*/
public Random(long seed) {
setSeed(seed);
@@ -89,7 +84,6 @@
* @param bits
* number of bits of the returned value.
* @return a pseudo-random generated int number.
- * @since Android 1.0
* @see #nextBytes
* @see #nextDouble
* @see #nextFloat
@@ -97,7 +91,6 @@
* @see #nextInt(int)
* @see #nextGaussian
* @see #nextLong
- * @since Android 1.0
*/
protected synchronized int next(int bits) {
seed = (seed * multiplier + 0xbL) & ((1L << 48) - 1);
@@ -109,7 +102,6 @@
* generated by this generator.
*
* @return a pseudo-random, uniformly distributed boolean value.
- * @since Android 1.0
*/
public boolean nextBoolean() {
return next(1) != 0;
@@ -122,7 +114,6 @@
* @param buf
* non-null array to contain the new random {@code byte}s.
* @see #next
- * @since Android 1.0
*/
public void nextBytes(byte[] buf) {
int rand = 0, count = 0, loop = 0;
@@ -144,7 +135,6 @@
*
* @return a random {@code double} in the range [0.0 - 1.0)
* @see #nextFloat
- * @since Android 1.0
*/
public double nextDouble() {
return ((((long) next(26) << 27) + next(27)) / (double) (1L << 53));
@@ -156,7 +146,6 @@
*
* @return float a random {@code float} number between [0.0 and 1.0)
* @see #nextDouble
- * @since Android 1.0
*/
public float nextFloat() {
return (next(24) / 16777216f);
@@ -172,7 +161,6 @@
*
* @return a random {@code double}
* @see #nextDouble
- * @since Android 1.0
*/
public synchronized double nextGaussian() {
if (haveNextNextGaussian) { // if X1 has been returned, return the
@@ -205,7 +193,6 @@
* @see java.lang.Integer#MIN_VALUE
* @see #next
* @see #nextLong
- * @since Android 1.0
*/
public int nextInt() {
return next(32);
@@ -218,7 +205,6 @@
* @param n
* the exclusive upper border of the range [0 - n).
* @return a random {@code int}.
- * @since Android 1.0
*/
public int nextInt(int n) {
if (n > 0) {
@@ -245,7 +231,6 @@
* @see #next
* @see #nextInt()
* @see #nextInt(int)
- * @since Android 1.0
*/
public long nextLong() {
return ((long) next(32) << 32) + next(32);
@@ -260,7 +245,6 @@
* @see #next
* @see #Random()
* @see #Random(long)
- * @since Android 1.0
*/
public synchronized void setSeed(long seed) {
this.seed = (seed ^ multiplier) & ((1L << 48) - 1);
diff --git a/luni/src/main/java/java/util/RandomAccess.java b/luni/src/main/java/java/util/RandomAccess.java
index a8a90de..7121bff 100644
--- a/luni/src/main/java/java/util/RandomAccess.java
+++ b/luni/src/main/java/java/util/RandomAccess.java
@@ -17,13 +17,10 @@
package java.util;
-
/**
* RandomAccess is implemented by {@code List} implementations that support fast
* (usually constant time) random access.
- *
- * @since Android 1.0
*/
public interface RandomAccess {
- /*empty*/
+ /* empty */
}
diff --git a/luni/src/main/java/java/util/ResourceBundle.java b/luni/src/main/java/java/util/ResourceBundle.java
index 1187358..218d3f3 100644
--- a/luni/src/main/java/java/util/ResourceBundle.java
+++ b/luni/src/main/java/java/util/ResourceBundle.java
@@ -27,6 +27,7 @@
import com.ibm.icu4jni.util.Resources;
import dalvik.system.VMStack;
// END android-changed
+import org.apache.harmony.luni.util.Msg;
/**
* {@code ResourceBundle} is an abstract class which is the superclass of classes which
@@ -35,7 +36,7 @@
* and when a resource is not found in a bundle, the parent bundle is searched for
* the resource. If the fallback mechanism reaches the base bundle and still
* can't find the resource it throws a {@code MissingResourceException}.
- *
+ *
* <ul>
* <li>All bundles for the same group of resources share a common base bundle.
* This base bundle acts as the root and is the last fallback in case none of
@@ -53,7 +54,7 @@
* current currency (Euro) and the {@code PREEURO} variant bundle would return the old
* currency (e.g. DM for Germany).</li>
* </ul>
- *
+ *
* <strong>Examples</strong>
* <ul>
* <li>BaseName (base bundle)
@@ -67,24 +68,22 @@
* <li>BaseName_fr_FR_PREEURO (bundle with France specific resources in french of
* the time before the Euro)
* </ul>
- *
+ *
* It's also possible to create variants for languages or countries. This can be
* done by just skipping the country or language abbreviation:
* BaseName_us__POSIX or BaseName__DE_PREEURO. But it's not allowed to
* circumvent both language and country: BaseName___VARIANT is illegal.
- *
+ *
* @see Properties
* @see PropertyResourceBundle
* @see ListResourceBundle
- * @since Android 1.0
+ * @since 1.1
*/
public abstract class ResourceBundle {
/**
* The parent of this {@code ResourceBundle} that is used if this bundle doesn't
* include the requested resource.
- *
- * @since Android 1.0
*/
protected ResourceBundle parent;
@@ -114,8 +113,6 @@
/**
* Constructs a new instance of this class.
- *
- * @since Android 1.0
*/
public ResourceBundle() {
/* empty */
@@ -124,13 +121,12 @@
/**
* Finds the named resource bundle for the default {@code Locale} and the caller's
* {@code ClassLoader}.
- *
+ *
* @param bundleName
* the name of the {@code ResourceBundle}.
* @return the requested {@code ResourceBundle}.
- * @exception MissingResourceException
+ * @throws MissingResourceException
* if the {@code ResourceBundle} cannot be found.
- * @since Android 1.0
*/
public static final ResourceBundle getBundle(String bundleName)
throws MissingResourceException {
@@ -143,15 +139,14 @@
/**
* Finds the named {@code ResourceBundle} for the specified {@code Locale} and the caller
* {@code ClassLoader}.
- *
+ *
* @param bundleName
* the name of the {@code ResourceBundle}.
* @param locale
* the {@code Locale}.
* @return the requested resource bundle.
- * @exception MissingResourceException
+ * @throws MissingResourceException
* if the resource bundle cannot be found.
- * @since Android 1.0
*/
public static final ResourceBundle getBundle(String bundleName,
Locale locale) {
@@ -163,17 +158,17 @@
/**
* Finds the named resource bundle for the specified {@code Locale} and {@code ClassLoader}.
- *
+ *
* The passed base name and {@code Locale} are used to create resource bundle names.
* The first name is created by concatenating the base name with the result
* of {@link Locale#toString()}. From this name all parent bundle names are
* derived. Then the same thing is done for the default {@code Locale}. This results
* in a list of possible bundle names.
- *
+ *
* <strong>Example</strong> For the basename "BaseName", the {@code Locale} of the
* German part of Switzerland (de_CH) and the default {@code Locale} en_US the list
* would look something like this:
- *
+ *
* <ol>
* <li>BaseName_de_CH</li>
* <li>BaseName_de</li>
@@ -181,11 +176,11 @@
* <li>Basename_en</li>
* <li>BaseName</li>
* </ol>
- *
+ *
* This list also shows the order in which the bundles will be searched for a requested
* resource in the German part of Switzerland (de_CH).
- *
- * As a first step, this method tries to instantiate
+ *
+ * As a first step, this method tries to instantiate
* a {@code ResourceBundle} with the names provided.
* If such a class can be instantiated and initialized, it is returned and
* all the parent bundles are instantiated too. If no such class can be
@@ -195,11 +190,11 @@
* by calling {@link ClassLoader#getResource(String)} it is used to
* initialize a {@link PropertyResourceBundle}. If this succeeds, it will
* also load the parents of this {@code ResourceBundle}.
- *
+ *
* For compatibility with older code, the bundle name isn't required to be
* a fully qualified class name. It's also possible to directly pass
* the path to a properties file (without a file extension).
- *
+ *
* @param bundleName
* the name of the {@code ResourceBundle}.
* @param locale
@@ -207,9 +202,8 @@
* @param loader
* the {@code ClassLoader} to use.
* @return the requested {@code ResourceBundle}.
- * @exception MissingResourceException
+ * @throws MissingResourceException
* if the {@code ResourceBundle} cannot be found.
- * @since Android 1.0
*/
public static ResourceBundle getBundle(String bundleName, Locale locale,
ClassLoader loader) throws MissingResourceException {
@@ -248,7 +242,7 @@
if ((bundle = handleGetBundle(bundleName, localeName, true, loader)) != null) {
return bundle;
}
- throw new MissingResourceException(null, bundleName + '_' + locale,
+ throw new MissingResourceException(Msg.getString("KA029", bundleName, locale), bundleName + '_' + locale, //$NON-NLS-1$
""); //$NON-NLS-1$
}
throw new NullPointerException();
@@ -256,9 +250,8 @@
/**
* Returns the names of the resources contained in this {@code ResourceBundle}.
- *
+ *
* @return an {@code Enumeration} of the resource names.
- * @since Android 1.0
*/
public abstract Enumeration<String> getKeys();
@@ -266,9 +259,8 @@
* Gets the {@code Locale} of this {@code ResourceBundle}. In case a bundle was not
* found for the requested {@code Locale}, this will return the actual {@code Locale} of
* this resource bundle that was found after doing a fallback.
- *
+ *
* @return the {@code Locale} of this {@code ResourceBundle}.
- * @since Android 1.0
*/
public Locale getLocale() {
return locale;
@@ -279,13 +271,12 @@
* cannot be found in this bundle, it falls back to the parent bundle (if
* it's not null) by calling the {@link #handleGetObject} method. If the resource still
* can't be found it throws a {@code MissingResourceException}.
- *
+ *
* @param key
* the name of the resource.
* @return the resource object.
- * @exception MissingResourceException
+ * @throws MissingResourceException
* if the resource is not found.
- * @since Android 1.0
*/
public final Object getObject(String key) {
ResourceBundle last, theParent = this;
@@ -297,21 +288,20 @@
last = theParent;
theParent = theParent.parent;
} while (theParent != null);
- throw new MissingResourceException(null, last.getClass().getName(), key);
+ throw new MissingResourceException(Msg.getString("KA029", last.getClass().getName(), key), last.getClass().getName(), key); //$NON-NLS-1$
}
/**
* Returns the named string resource from this {@code ResourceBundle}.
- *
+ *
* @param key
* the name of the resource.
* @return the resource string.
- * @exception MissingResourceException
+ * @throws MissingResourceException
* if the resource is not found.
- * @exception ClassCastException
+ * @throws ClassCastException
* if the resource found is not a string.
* @see #getObject(String)
- * @since Android 1.0
*/
public final String getString(String key) {
return (String) getObject(key);
@@ -319,16 +309,15 @@
/**
* Returns the named resource from this {@code ResourceBundle}.
- *
+ *
* @param key
* the name of the resource.
* @return the resource string array.
- * @exception MissingResourceException
+ * @throws MissingResourceException
* if the resource is not found.
- * @exception ClassCastException
+ * @throws ClassCastException
* if the resource found is not an array of strings.
* @see #getObject(String)
- * @since Android 1.0
*/
public final String[] getStringArray(String key) {
return (String[]) getObject(key);
@@ -343,7 +332,7 @@
synchronized (cache) {
loaderCache = cache.get(cacheKey);
if (loaderCache == null) {
- loaderCache = new Hashtable<String, ResourceBundle>(13);
+ loaderCache = new Hashtable<String, ResourceBundle>();
cache.put(cacheKey, loaderCache);
}
}
@@ -389,13 +378,9 @@
} catch (Exception e) {
}
- // BEGIN android-added
- // copied from newer version of Harmony
if (bundle != null) {
bundle.setLocale(locale);
- }
- // END android-added
- if (bundle == null) {
+ } else {
final String fileName = bundleName.replace('.', '/');
InputStream stream = AccessController
.doPrivileged(new PrivilegedAction<InputStream>() {
@@ -447,21 +432,19 @@
/**
* Returns the named resource from this {@code ResourceBundle}, or null if the
* resource is not found.
- *
+ *
* @param key
* the name of the resource.
* @return the resource object.
- * @since Android 1.0
*/
protected abstract Object handleGetObject(String key);
/**
* Sets the parent resource bundle of this {@code ResourceBundle}. The parent is
* searched for resources which are not found in this {@code ResourceBundle}.
- *
+ *
* @param bundle
* the parent {@code ResourceBundle}.
- * @since Android 1.0
*/
protected void setParent(ResourceBundle bundle) {
parent = bundle;
diff --git a/luni/src/main/java/java/util/Scanner.java b/luni/src/main/java/java/util/Scanner.java
index acacebb..dd5c024 100644
--- a/luni/src/main/java/java/util/Scanner.java
+++ b/luni/src/main/java/java/util/Scanner.java
@@ -44,7 +44,7 @@
* next* methods. If the token is not in a valid format, an
* {@code InputMismatchException} is thrown.
* <p>
- * For example: </p>
+ * For example:
* <pre>
* Scanner s = new Scanner("1A true");
* System.out.println(s.nextInt(16));
@@ -52,28 +52,25 @@
* </pre>
* <p>
* Yields the result: {@code 26 true}
- * </p>
* <p>A {@code Scanner} can also find or skip specific patterns without regard for the
* delimiter. All these methods and the various next* and hasNext* methods may
* block.
- * </p>
+ * <p>
* The {@code Scanner} class is not thread-safe.
- * @since Android 1.0
*/
public final class Scanner implements Iterator<String> {
- // Default delimiting pattern.
+ // Default delimiting pattern.
private static final Pattern DEFAULT_DELIMITER = Pattern
.compile("\\p{javaWhitespace}+"); //$NON-NLS-1$
-
+
// The boolean's pattern.
private static final Pattern BOOLEAN_PATTERN = Pattern.compile(
"true|false", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
-
-
+
// Pattern used to recognize line terminator.
private static final Pattern LINE_TERMINATOR;
-
+
// Pattern used to recognize multiple line terminators.
private static final Pattern MULTI_LINE_TERMINATOR;
@@ -81,24 +78,22 @@
private static final Pattern LINE_PATTERN;
static {
- String terminator = "\n|\r\n|\r|\u0085|\u2028|\u2029"; //$NON-NLS-1$
-
+ String terminator = "\n|\r\n|\r|\u0085|\u2028|\u2029"; //$NON-NLS-1$
+
LINE_TERMINATOR = Pattern.compile(terminator);
-
+
+ // BEGIN android-note
+ // consider plain old string concatenation for better performance
+ // END android-note
StringBuilder multiTerminator = new StringBuilder();
- MULTI_LINE_TERMINATOR = Pattern
- .compile(multiTerminator.append("(") //$NON-NLS-1$
- .append(terminator)
- .append(")+").toString()); //$NON-NLS-1$
+ MULTI_LINE_TERMINATOR = Pattern.compile(multiTerminator.append("(") //$NON-NLS-1$
+ .append(terminator).append(")+").toString()); //$NON-NLS-1$
StringBuilder line = new StringBuilder();
- LINE_PATTERN = Pattern
- .compile(line.append(".*(") //$NON-NLS-1$
- .append(terminator)
- .append(")|.+(") //$NON-NLS-1$
- .append(terminator)
- .append(")?").toString()); //$NON-NLS-1$
+ LINE_PATTERN = Pattern.compile(line.append(".*(") //$NON-NLS-1$
+ .append(terminator).append(")|.+(") //$NON-NLS-1$
+ .append(terminator).append(")?").toString()); //$NON-NLS-1$
}
-
+
// The pattern matches anything.
private static final Pattern ANY_PATTERN = Pattern.compile("(?s).*"); //$NON-NLS-1$
@@ -131,24 +126,24 @@
// The length of the buffer.
private int bufferLength = 0;
- // Record the status of this scanner. True if the scanner
+ // Record the status of this scanner. True if the scanner
// is closed.
private boolean closed = false;
private IOException lastIOException;
-
+
private boolean matchSuccessful = false;
-
+
private DecimalFormat decimalFormat;
-
+
// Records whether the underlying readable has more input.
private boolean inputExhausted = false;
-
+
private Object cacheHasNextValue = null;
-
+
private int cachehasNextIndex = -1;
-
- private enum DataType{
+
+ private enum DataType {
/*
* Stands for Integer
*/
@@ -162,12 +157,11 @@
/**
* Creates a {@code Scanner} with the specified {@code File} as input. The default charset
* is applied when reading the file.
- *
+ *
* @param src
* the file to be scanned.
* @throws FileNotFoundException
* if the specified file does not exist.
- * @since Android 1.0
*/
public Scanner(File src) throws FileNotFoundException {
this(src, Charset.defaultCharset().name());
@@ -176,7 +170,7 @@
/**
* Creates a {@code Scanner} with the specified {@code File} as input. The specified charset
* is applied when reading the file.
- *
+ *
* @param src
* the file to be scanned.
* @param charsetName
@@ -185,7 +179,6 @@
* if the specified file does not exist.
* @throws IllegalArgumentException
* if the specified coding does not exist.
- * @since Android 1.0
*/
public Scanner(File src, String charsetName) throws FileNotFoundException {
if (null == src) {
@@ -212,10 +205,9 @@
/**
* Creates a {@code Scanner} on the specified string.
- *
+ *
* @param src
* the string to be scanned.
- * @since Android 1.0
*/
public Scanner(String src) {
input = new StringReader(src);
@@ -225,10 +217,9 @@
/**
* Creates a {@code Scanner} on the specified {@code InputStream}. The default charset is
* applied when decoding the input.
- *
+ *
* @param src
* the {@code InputStream} to be scanned.
- * @since Android 1.0
*/
public Scanner(InputStream src) {
this(src, Charset.defaultCharset().name());
@@ -237,14 +228,13 @@
/**
* Creates a {@code Scanner} on the specified {@code InputStream}. The specified charset is
* applied when decoding the input.
- *
+ *
* @param src
* the {@code InputStream} to be scanned.
* @param charsetName
* the encoding type of the {@code InputStream}.
* @throws IllegalArgumentException
* if the specified character set is not found.
- * @since Android 1.0
*/
public Scanner(InputStream src, String charsetName) {
if (null == src) {
@@ -261,10 +251,9 @@
/**
* Creates a {@code Scanner} with the specified {@code Readable} as input.
- *
+ *
* @param src
* the {@code Readable} to be scanned.
- * @since Android 1.0
*/
public Scanner(Readable src) {
if (null == src) {
@@ -277,10 +266,9 @@
/**
* Creates a {@code Scanner} with the specified {@code ReadableByteChannel} as
* input. The default charset is applied when decoding the input.
- *
+ *
* @param src
* the {@code ReadableByteChannel} to be scanned.
- * @since Android 1.0
*/
public Scanner(ReadableByteChannel src) {
this(src, Charset.defaultCharset().name());
@@ -289,14 +277,13 @@
/**
* Creates a {@code Scanner} with the specified {@code ReadableByteChannel} as
* input. The specified charset is applied when decoding the input.
- *
+ *
* @param src
* the {@code ReadableByteChannel} to be scanned.
* @param charsetName
* the encoding type of the content.
* @throws IllegalArgumentException
* if the specified character set is not found.
- * @since Android 1.0
*/
public Scanner(ReadableByteChannel src, String charsetName) {
if (null == src) {
@@ -316,9 +303,8 @@
* {@code Closeable}. If the {@code Scanner} has been closed, this method will have
* no effect. Any scanning operation called after calling this method will throw
* an {@code IllegalStateException}.
- *
+ *
* @see Closeable
- * @since Android 1.0
*/
public void close() {
if (closed) {
@@ -336,9 +322,8 @@
/**
* Returns the delimiter {@code Pattern} in use by this {@code Scanner}.
- *
+ *
* @return the delimiter {@code Pattern} in use by this {@code Scanner}.
- * @since Android 1.0
*/
public Pattern delimiter() {
return delimiter;
@@ -351,14 +336,13 @@
* Otherwise, {@code null} will be returned and the {@code Scanner} will not advance.
* When waiting for input, the {@code Scanner} may be blocked. All the
* input may be cached if no line terminator exists in the buffer.
- *
+ *
* @param pattern
* the pattern to find in the input.
* @return the matched string or {@code null} if the pattern is not found
* before the next line terminator.
* @throws IllegalStateException
* if the {@code Scanner} is closed.
- * @since Android 1.0
*/
public String findInLine(Pattern pattern) {
checkClosed();
@@ -395,17 +379,32 @@
* bug is fixed.
*/
int oldLimit = buffer.limit();
- buffer.limit(horizonLineSeparator);
+ // Considering the look ahead feature, the line terminator should be involved as RI
+ buffer.limit(horizonLineSeparator + terminatorLength);
// ========== To deal with regex bug ====================
- matcher.region(findStartIndex, horizonLineSeparator);
+ // Considering the look ahead feature, the line terminator should be involved as RI
+ matcher.region(findStartIndex, horizonLineSeparator + terminatorLength);
if (matcher.find()) {
// The scanner advances past the input that matched
findStartIndex = matcher.end();
- // If the matched pattern is immediately followed by line terminator.
- if(horizonLineSeparator == matcher.end()) {
+ // If the matched pattern is immediately followed by line
+ // terminator.
+ if (horizonLineSeparator == matcher.end()) {
findStartIndex += terminatorLength;
}
+ // the line terminator itself should not be a part of
+ // the match result according to the Spec
+ if (horizonLineSeparator != bufferLength
+ && (horizonLineSeparator + terminatorLength == matcher
+ .end())) {
+ // ========== To deal with regex bug ====================
+ buffer.limit(oldLimit);
+ // ========== To deal with regex bug ====================
+
+ matchSuccessful = false;
+ return null;
+ }
matchSuccessful = true;
// ========== To deal with regex bug ====================
@@ -427,7 +426,7 @@
* Compiles the pattern string and tries to find a substing matching it in the input data. The
* delimiter will be ignored. This is the same as invoking
* {@code findInLine(Pattern.compile(pattern))}.
- *
+ *
* @param pattern
* a string used to construct a pattern which is in turn used to
* match a substring of the input data.
@@ -436,7 +435,6 @@
* @throws IllegalStateException
* if the {@code Scanner} is closed.
* @see #findInLine(Pattern)
- * @since Android 1.0
*/
public String findInLine(String pattern) {
return findInLine(Pattern.compile(pattern));
@@ -450,7 +448,7 @@
* advance. When waiting for input, the {@code Scanner} may be blocked.
* <p>
* The {@code Scanner}'s search will never go more than {@code horizon} code points from current
- * position. The position of {@code horizon} does have an effect on the result of the
+ * position. The position of {@code horizon} does have an effect on the result of the
* match. For example, when the input is "123" and current position is at zero,
* {@code findWithinHorizon(Pattern.compile("\\p{Digit}{3}"), 2)}
* will return {@code null}. While
@@ -459,10 +457,10 @@
* non-anchoring bound. (refer to
* {@link Matcher#useTransparentBounds(boolean)} and
* {@link Matcher#useAnchoringBounds(boolean)})
- * </p>
+ * <p>
* A {@code horizon} whose value is zero will be ignored and the whole input will be
* used for search. In this situation, all the input may be cached.
- *
+ *
* @param pattern
* the pattern used to scan.
* @param horizon
@@ -473,7 +471,6 @@
* if the {@code Scanner} is closed.
* @throws IllegalArgumentException
* if {@code horizon} is less than zero.
- * @since Android 1.0
*/
public String findWithinHorizon(Pattern pattern, int horizon) {
checkClosed();
@@ -538,7 +535,7 @@
* Tries to find the pattern in the input between the current position and the specified
* {@code horizon}. Delimiters are ignored. This call is the same as invoking
* {@code findWithinHorizon(Pattern.compile(pattern))}.
- *
+ *
* @param pattern
* the pattern used to scan.
* @param horizon
@@ -550,7 +547,6 @@
* @throws IllegalArgumentException
* if {@code horizon} is less than zero.
* @see #findWithinHorizon(Pattern, int)
- * @since Android 1.0
*/
public String findWithinHorizon(String pattern, int horizon) {
return findWithinHorizon(Pattern.compile(pattern), horizon);
@@ -559,12 +555,11 @@
/**
* Returns whether this {@code Scanner} has one or more tokens remaining to parse.
* This method will block if the data is still being read.
- *
+ *
* @return {@code true} if this {@code Scanner} has one or more tokens remaining,
* otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNext() {
return hasNext(ANY_PATTERN);
@@ -574,28 +569,28 @@
* Returns whether this {@code Scanner} has one or more tokens remaining to parse
* and the next token matches the given pattern. This method will block if the data is
* still being read.
- *
+ *
* @param pattern
* the pattern to check for.
* @return {@code true} if this {@code Scanner} has more tokens and the next token
* matches the pattern, {@code false} otherwise.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNext(Pattern pattern) {
checkClosed();
checkNull(pattern);
matchSuccessful = false;
saveCurrentStatus();
- //if the next token exists, set the match region, otherwise return false
+ // if the next token exists, set the match region, otherwise return
+ // false
if (!setTokenRegion()) {
recoverPreviousStatus();
return false;
}
matcher.usePattern(pattern);
boolean hasNext = false;
- //check whether next token matches the specified pattern
+ // check whether next token matches the specified pattern
if (matcher.matches()) {
cachehasNextIndex = findStartIndex;
matchSuccessful = true;
@@ -605,20 +600,18 @@
return hasNext;
}
-
/**
* Returns {@code true} if this {@code Scanner} has one or more tokens remaining to parse
* and the next token matches a pattern compiled from the given string. This method will
* block if the data is still being read. This call is equivalent to
* {@code hasNext(Pattern.compile(pattern))}.
- *
+ *
* @param pattern
* the string specifying the pattern to scan for
* @return {@code true} if the specified pattern matches this {@code Scanner}'s
* next token, {@code false} otherwise.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNext(String pattern) {
return hasNext(Pattern.compile(pattern));
@@ -627,12 +620,11 @@
/**
* Returns whether the next token can be translated into a valid
* {@code BigDecimal}.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code BigDecimal}, otherwise {@code false.}
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextBigDecimal() {
Pattern floatPattern = getFloatPattern();
@@ -653,12 +645,11 @@
/**
* Returns whether the next token can be translated into a valid
* {@code BigInteger} in the default radix.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code BigInteger}, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextBigInteger() {
return hasNextBigInteger(integerRadix);
@@ -667,7 +658,7 @@
/**
* Returns whether the next token can be translated into a valid
* {@code BigInteger} in the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into a
* {@code BigInteger}.
@@ -675,7 +666,6 @@
* {@code BigInteger}, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextBigInteger(int radix) {
Pattern integerPattern = getIntegerPattern(radix);
@@ -696,12 +686,11 @@
/**
* Returns whether the next token can be translated into a valid
* {@code boolean} value.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code boolean} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextBoolean() {
return hasNext(BOOLEAN_PATTERN);
@@ -710,12 +699,11 @@
/**
* Returns whether the next token can be translated into a valid
* {@code byte} value in the default radix.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code byte} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextByte() {
return hasNextByte(integerRadix);
@@ -724,7 +712,7 @@
/**
* Returns whether the next token can be translated into a valid
* {@code byte} value in the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into a {@code byte}
* value
@@ -732,7 +720,6 @@
* {@code byte} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextByte(int radix) {
Pattern integerPattern = getIntegerPattern(radix);
@@ -753,12 +740,11 @@
/**
* Returns whether the next token translated into a valid {@code double}
* value.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code double} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextDouble() {
Pattern floatPattern = getFloatPattern();
@@ -779,12 +765,11 @@
/**
* Returns whether the next token can be translated into a valid
* {@code float} value.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code float} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextFloat() {
Pattern floatPattern = getFloatPattern();
@@ -805,12 +790,11 @@
/**
* Returns whether the next token can be translated into a valid {@code int}
* value in the default radix.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code int} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed,
- * @since Android 1.0
*/
public boolean hasNextInt() {
return hasNextInt(integerRadix);
@@ -819,7 +803,7 @@
/**
* Returns whether the next token can be translated into a valid {@code int}
* value in the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into an {@code int}
* value.
@@ -828,7 +812,6 @@
* {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextInt(int radix) {
Pattern integerPattern = getIntegerPattern(radix);
@@ -849,12 +832,11 @@
/**
* Returns whether there is a line terminator in the input.
* This method may block.
- *
+ *
* @return {@code true} if there is a line terminator in the input,
* otherwise, {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} is closed.
- * @since Android 1.0
*/
public boolean hasNextLine() {
checkClosed();
@@ -886,12 +868,11 @@
/**
* Returns whether the next token can be translated into a valid
* {@code long} value in the default radix.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code long} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextLong() {
return hasNextLong(integerRadix);
@@ -900,7 +881,7 @@
/**
* Returns whether the next token can be translated into a valid
* {@code long} value in the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into a {@code long}
* value.
@@ -908,7 +889,6 @@
* {@code long} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextLong(int radix) {
Pattern integerPattern = getIntegerPattern(radix);
@@ -926,16 +906,14 @@
return isLongValue;
}
-
/**
* Returns whether the next token can be translated into a valid
* {@code short} value in the default radix.
- *
+ *
* @return {@code true} if the next token can be translated into a valid
* {@code short} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextShort() {
return hasNextShort(integerRadix);
@@ -944,7 +922,7 @@
/**
* Returns whether the next token can be translated into a valid
* {@code short} value in the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into a {@code short}
* value.
@@ -952,7 +930,6 @@
* {@code short} value, otherwise {@code false}.
* @throws IllegalStateException
* if the {@code Scanner} has been closed.
- * @since Android 1.0
*/
public boolean hasNextShort(int radix) {
Pattern integerPattern = getIntegerPattern(radix);
@@ -973,9 +950,8 @@
/**
* Returns the last {@code IOException} that was raised while reading from the underlying
* input.
- *
+ *
* @return the last thrown {@code IOException}, or {@code null} if none was thrown.
- * @since Android 1.0
*/
public IOException ioException() {
return lastIOException;
@@ -983,9 +959,8 @@
/**
* Return the {@code Locale} of this {@code Scanner}.
- *
+ *
* @return the {@code Locale} of this {@code Scanner}.
- * @since Android 1.0
*/
public Locale locale() {
return locale;
@@ -996,13 +971,11 @@
* <p>
* The next* and find* methods return the match result in the case of a
* successful match.
- * </p>
- *
+ *
* @return the match result of the last successful match operation
* @throws IllegalStateException
* if the match result is not available, of if the last match
* was not successful.
- * @since Android 1.0
*/
public MatchResult match() {
if (!matchSuccessful) {
@@ -1015,13 +988,12 @@
* Returns the next token. The token will be both prefixed and postfixed by
* the delimiter that is currently being used (or a string that matches the
* delimiter pattern). This method will block if input is being read.
- *
+ *
* @return the next complete token.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
* @throws NoSuchElementException
* if input has been exhausted.
- * @since Android 1.0
*/
public String next() {
return next(ANY_PATTERN);
@@ -1032,7 +1004,7 @@
* will be both prefixed and postfixed by the delimiter that is currently
* being used (or a string that matches the delimiter pattern). This method will block
* if input is being read.
- *
+ *
* @param pattern
* the specified pattern to scan.
* @return the next token.
@@ -1042,7 +1014,6 @@
* if input has been exhausted.
* @throws InputMismatchException
* if the next token does not match the pattern given.
- * @since Android 1.0
*/
public String next(Pattern pattern) {
checkClosed();
@@ -1070,7 +1041,7 @@
* being used (or a string that matches the delimiter pattern). This method will block
* if input is being read. Calling this methos is equivalent to
* {@code next(Pattern.compile(pattern))}.
- *
+ *
* @param pattern
* the string specifying the pattern to scan for.
* @return the next token.
@@ -1080,7 +1051,6 @@
* if input has been exhausted.
* @throws InputMismatchException
* if the next token does not match the pattern given.
- * @since Android 1.0
*/
public String next(String pattern) {
return next(Pattern.compile(pattern));
@@ -1095,7 +1065,7 @@
* negative sign (-) is added if the {@code Locale}-specific negative prefix or
* suffix was present. Finally the resulting string is passed to
* {@code BigDecimal(String) }.
- *
+ *
* @return the next token as a {@code BigDecimal}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1104,7 +1074,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code BigDecimal}.
- * @since Android 1.0
*/
public BigDecimal nextBigDecimal() {
checkClosed();
@@ -1131,7 +1100,7 @@
/**
* Returns the next token as a {@code BigInteger}. This method will block if input is
* being read. Equivalent to {@code nextBigInteger(DEFAULT_RADIX)}.
- *
+ *
* @return the next token as {@code BigInteger}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1140,7 +1109,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code BigInteger}.
- * @since Android 1.0
*/
public BigInteger nextBigInteger() {
return nextBigInteger(integerRadix);
@@ -1156,7 +1124,7 @@
* {@code Locale}-specific negative prefix or suffix was present. Finally the
* resulting String is passed to {@link BigInteger#BigInteger(String, int)}}
* with the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into a
* {@code BigInteger}.
@@ -1168,7 +1136,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code BigInteger}.
- * @since Android 1.0
*/
public BigInteger nextBigInteger(int radix) {
checkClosed();
@@ -1195,7 +1162,7 @@
/**
* Returns the next token as a {@code boolean}. This method will block if input is
* being read.
- *
+ *
* @return the next token as a {@code boolean}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1204,7 +1171,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code boolean} value.
- * @since Android 1.0
*/
public boolean nextBoolean() {
return Boolean.parseBoolean(next(BOOLEAN_PATTERN));
@@ -1213,7 +1179,7 @@
/**
* Returns the next token as a {@code byte}. This method will block if input is being
* read. Equivalent to {@code nextByte(DEFAULT_RADIX)}.
- *
+ *
* @return the next token as a {@code byte}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1222,7 +1188,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code byte} value.
- * @since Android 1.0
*/
public byte nextByte() {
return nextByte(integerRadix);
@@ -1238,7 +1203,7 @@
* {@code Locale}-specific negative prefix or suffix was present. Finally the
* resulting String is passed to {@link Byte#parseByte(String, int)}} with
* the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into {@code byte} value.
* @return the next token as a {@code byte}.
@@ -1249,7 +1214,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code byte} value.
- * @since Android 1.0
*/
@SuppressWarnings("boxing")
public byte nextByte(int radix) {
@@ -1285,7 +1249,7 @@
* {@link Double#parseDouble(String)}}. If the token matches the localized
* NaN or infinity strings, it is also passed to
* {@link Double#parseDouble(String)}}.
- *
+ *
* @return the next token as a {@code double}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1294,7 +1258,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code double} value.
- * @since Android 1.0
*/
@SuppressWarnings("boxing")
public double nextDouble() {
@@ -1330,7 +1293,7 @@
* {@link Float#parseFloat(String)}}.If the token matches the localized NaN
* or infinity strings, it is also passed to
* {@link Float#parseFloat(String)}}.
- *
+ *
* @return the next token as a {@code float}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1339,7 +1302,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code float} value.
- * @since Android 1.0
*/
@SuppressWarnings("boxing")
public float nextFloat() {
@@ -1367,7 +1329,7 @@
/**
* Returns the next token as an {@code int}. This method will block if input is being
* read. Equivalent to {@code nextInt(DEFAULT_RADIX)}.
- *
+ *
* @return the next token as an {@code int}
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1376,7 +1338,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code int} value.
- * @since Android 1.0
*/
public int nextInt() {
return nextInt(integerRadix);
@@ -1392,7 +1353,7 @@
* {@code Locale}-specific negative prefix or suffix was present. Finally the
* resulting String is passed to {@link Integer#parseInt(String, int)} with
* the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into an {@code int}
* value.
@@ -1404,7 +1365,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code int} value.
- * @since Android 1.0
*/
@SuppressWarnings("boxing")
public int nextInt(int radix) {
@@ -1416,7 +1376,7 @@
return (Integer) obj;
}
Pattern integerPattern = getIntegerPattern(radix);
- String intString=next(integerPattern);
+ String intString = next(integerPattern);
intString = removeLocaleInfo(intString, DataType.INT);
int intValue = 0;
try {
@@ -1435,13 +1395,12 @@
* searching, if no line terminator is found, then a large amount of input
* will be cached. If no line at all can be found, a {@code NoSuchElementException}
* will be thrown.
- *
+ *
* @return the skipped line.
* @throws IllegalStateException
* if the {@code Scanner} is closed.
* @throws NoSuchElementException
* if no line can be found, e.g. when input is an empty string.
- * @since Android 1.0
*/
public String nextLine() {
checkClosed();
@@ -1451,7 +1410,8 @@
String result = null;
while (true) {
if (matcher.find()) {
- if (inputExhausted || matcher.end() != bufferLength) {
+ if (inputExhausted || matcher.end() != bufferLength
+ || bufferLength < buffer.capacity()) {
matchSuccessful = true;
findStartIndex = matcher.end();
result = matcher.group();
@@ -1466,7 +1426,7 @@
if (!inputExhausted) {
readMore();
resetMatcher();
- }
+ }
}
// Find text without line terminator here.
if (null != result) {
@@ -1481,7 +1441,7 @@
/**
* Returns the next token as a {@code long}. This method will block if input is being
* read. Equivalent to {@code nextLong(DEFAULT_RADIX)}.
- *
+ *
* @return the next token as a {@code long}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1490,7 +1450,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code long} value.
- * @since Android 1.0
*/
public long nextLong() {
return nextLong(integerRadix);
@@ -1506,7 +1465,7 @@
* {@code Locale}-specific negative prefix or suffix was present. Finally the
* resulting String is passed to {@link Long#parseLong(String, int)}} with
* the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into a {@code long}
* value.
@@ -1518,7 +1477,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code long} value.
- * @since Android 1.0
*/
@SuppressWarnings("boxing")
public long nextLong(int radix) {
@@ -1546,7 +1504,7 @@
/**
* Returns the next token as a {@code short}. This method will block if input is being
* read. Equivalent to {@code nextShort(DEFAULT_RADIX)}.
- *
+ *
* @return the next token as a {@code short}.
* @throws IllegalStateException
* if this {@code Scanner} has been closed.
@@ -1555,7 +1513,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code short} value.
- * @since Android 1.0
*/
public short nextShort() {
return nextShort(integerRadix);
@@ -1571,7 +1528,7 @@
* {@code Locale}-specific negative prefix or suffix was present. Finally the
* resulting String is passed to {@link Short#parseShort(String, int)}}
* with the specified radix.
- *
+ *
* @param radix
* the radix used to translate the token into {@code short}
* value.
@@ -1583,7 +1540,6 @@
* @throws InputMismatchException
* if the next token can not be translated into a valid
* {@code short} value.
- * @since Android 1.0
*/
@SuppressWarnings("boxing")
public short nextShort(int radix) {
@@ -1610,9 +1566,8 @@
/**
* Return the radix of this {@code Scanner}.
- *
+ *
* @return the radix of this {@code Scanner}
- * @since Android 1.0
*/
public int radix() {
return integerRadix;
@@ -1624,8 +1579,8 @@
* skipped. If an anchored match of the specified pattern succeeds, the corresponding input
* will also be skipped. Otherwise, a {@code NoSuchElementException} will be thrown.
* Patterns that can match a lot of input may cause the {@code Scanner} to read
- * in a large amount of input.
- *
+ * in a large amount of input.
+ *
* @param pattern
* used to skip over input.
* @return the {@code Scanner} itself.
@@ -1633,7 +1588,6 @@
* if the {@code Scanner} is closed.
* @throws NoSuchElementException
* if the specified pattern match fails.
- * @since Android 1.0
*/
public Scanner skip(Pattern pattern) {
checkClosed();
@@ -1668,14 +1622,13 @@
* the constructed pattern to match input starting from the current position. The
* delimiter will be ignored. This call is the same as invoke
* {@code skip(Pattern.compile(pattern))}.
- *
+ *
* @param pattern
* the string used to construct a pattern which in turn is used to
* match input.
* @return the {@code Scanner} itself.
* @throws IllegalStateException
* if the {@code Scanner} is closed.
- * @since Android 1.0
*/
public Scanner skip(String pattern) {
return skip(Pattern.compile(pattern));
@@ -1684,9 +1637,8 @@
/**
* Returns a string representation of this {@code Scanner}. The information
* returned may be helpful for debugging. The format of the string is unspecified.
- *
+ *
* @return a string represendation of this {@code Scanner}.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -1702,11 +1654,10 @@
/**
* Sets the delimiting pattern of this {@code Scanner}.
- *
+ *
* @param pattern
* the delimiting pattern to use.
* @return this {@code Scanner}.
- * @since Android 1.0
*/
public Scanner useDelimiter(Pattern pattern) {
delimiter = pattern;
@@ -1716,11 +1667,10 @@
/**
* Sets the delimiting pattern of this {@code Scanner} with a pattern compiled from
* the supplied string value.
- *
+ *
* @param pattern
* a string from which a {@code Pattern} can be compiled.
* @return this {@code Scanner}.
- * @since Android 1.0
*/
public Scanner useDelimiter(String pattern) {
return useDelimiter(Pattern.compile(pattern));
@@ -1728,11 +1678,10 @@
/**
* Sets the {@code Locale} of this {@code Scanner} to a specified {@code Locale}.
- *
+ *
* @param l
* the specified {@code Locale} to use.
* @return this {@code Scanner}.
- * @since Android 1.0
*/
public Scanner useLocale(Locale l) {
if (null == l) {
@@ -1744,11 +1693,10 @@
/**
* Sets the radix of this {@code Scanner} to the specified radix.
- *
+ *
* @param radix
* the specified radix to use.
* @return this {@code Scanner}.
- * @since Android 1.0
*/
public Scanner useRadix(int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
@@ -1761,10 +1709,9 @@
/**
* Remove is not a supported operation on {@code Scanner}.
- *
+ *
* @throws UnsupportedOperationException
* if this method is invoked.
- * @since Android 1.0
*/
public void remove() {
throw new UnsupportedOperationException();
@@ -1778,7 +1725,7 @@
buffer.limit(0);
matcher = delimiter.matcher(buffer);
}
-
+
/*
* Check the {@code Scanner}'s state, if it is closed, IllegalStateException will be
* thrown.
@@ -1788,7 +1735,7 @@
throw new IllegalStateException();
}
}
-
+
/*
* Check the inputed pattern. If it is null, then a NullPointerException
* will be thrown out.
@@ -1824,7 +1771,7 @@
private void recoverPreviousStatus() {
findStartIndex = preStartIndex;
}
-
+
/*
* Get integer's pattern
*/
@@ -1834,12 +1781,12 @@
.getString("KA00e", radix)); //$NON-NLS-1$
}
decimalFormat = (DecimalFormat) NumberFormat.getInstance(locale);
-
- String allAvailableDigits="0123456789abcdefghijklmnopqrstuvwxyz"; //$NON-NLS-1$
- String ASCIIDigit=allAvailableDigits.substring(0, radix);
- String nonZeroASCIIDigit=allAvailableDigits.substring(1, radix);
- StringBuilder digit = new StringBuilder("((?i)[").append(ASCIIDigit) //$NON-NLS-1$
+ String allAvailableDigits = "0123456789abcdefghijklmnopqrstuvwxyz"; //$NON-NLS-1$
+ String ASCIIDigit = allAvailableDigits.substring(0, radix);
+ String nonZeroASCIIDigit = allAvailableDigits.substring(1, radix);
+
+ StringBuilder digit = new StringBuilder("((?i)[").append(ASCIIDigit) //$NON-NLS-1$
.append("]|\\p{javaDigit})"); //$NON-NLS-1$
StringBuilder nonZeroDigit = new StringBuilder("((?i)[").append( //$NON-NLS-1$
nonZeroASCIIDigit).append("]|([\\p{javaDigit}&&[^0]]))"); //$NON-NLS-1$
@@ -1912,16 +1859,16 @@
}
/*
- * Add the {@code Locale}-specific positive prefixes and suffixes to the pattern
+ * Add the locale specific positive prefixes and suffixes to the pattern
*/
private StringBuilder addPositiveSign(StringBuilder unSignNumeral) {
String positivePrefix = ""; //$NON-NLS-1$
String positiveSuffix = ""; //$NON-NLS-1$
if (!decimalFormat.getPositivePrefix().equals("")) { //$NON-NLS-1$
- positivePrefix = "\\Q" + decimalFormat.getPositivePrefix()+"\\E"; //$NON-NLS-1$ //$NON-NLS-2$
+ positivePrefix = "\\Q" + decimalFormat.getPositivePrefix() + "\\E"; //$NON-NLS-1$ //$NON-NLS-2$
}
if (!decimalFormat.getPositiveSuffix().equals("")) { //$NON-NLS-1$
- positiveSuffix = "\\Q" + decimalFormat.getPositiveSuffix()+"\\E"; //$NON-NLS-1$ //$NON-NLS-2$
+ positiveSuffix = "\\Q" + decimalFormat.getPositiveSuffix() + "\\E"; //$NON-NLS-1$ //$NON-NLS-2$
}
StringBuilder signedNumeral = new StringBuilder()
.append(positivePrefix).append(unSignNumeral).append(
@@ -1930,16 +1877,16 @@
}
/*
- * Add the {@code Locale} specific negative prefixes and suffixes to the pattern
+ * Add the locale specific negative prefixes and suffixes to the pattern
*/
private StringBuilder addNegativeSign(StringBuilder unSignNumeral) {
String negativePrefix = ""; //$NON-NLS-1$
String negativeSuffix = ""; //$NON-NLS-1$
if (!decimalFormat.getNegativePrefix().equals("")) { //$NON-NLS-1$
- negativePrefix = "\\Q" + decimalFormat.getNegativePrefix()+"\\E"; //$NON-NLS-1$//$NON-NLS-2$
+ negativePrefix = "\\Q" + decimalFormat.getNegativePrefix() + "\\E"; //$NON-NLS-1$//$NON-NLS-2$
}
if (!decimalFormat.getNegativeSuffix().equals("")) { //$NON-NLS-1$
- negativeSuffix = "\\Q" + decimalFormat.getNegativeSuffix()+"\\E"; //$NON-NLS-1$//$NON-NLS-2$
+ negativeSuffix = "\\Q" + decimalFormat.getNegativeSuffix() + "\\E"; //$NON-NLS-1$//$NON-NLS-2$
}
StringBuilder signedNumeral = new StringBuilder()
.append(negativePrefix).append(unSignNumeral).append(
@@ -1948,15 +1895,14 @@
}
/*
- * Remove {@code Locale} related information from float String
+ * Remove locale related information from float String
*/
private String removeLocaleInfoFromFloat(String floatString) {
// If the token is HexFloat
- if (-1 != floatString.indexOf('x')
- || -1 != floatString.indexOf('X')) {
+ if (-1 != floatString.indexOf('x') || -1 != floatString.indexOf('X')) {
return floatString;
}
-
+
int exponentIndex;
String decimalNumeralString;
String exponentString;
@@ -1968,11 +1914,11 @@
floatString.length());
decimalNumeralString = removeLocaleInfo(decimalNumeralString,
DataType.FLOAT);
- return decimalNumeralString + "e" + exponentString; //$NON-NLS-1$
+ return decimalNumeralString + "e" + exponentString; //$NON-NLS-1$
}
return removeLocaleInfo(floatString, DataType.FLOAT);
}
-
+
/*
* Remove the locale specific prefixes, group separators, and locale
* specific suffixes from input string
@@ -2001,12 +1947,12 @@
}
}
if (DataType.FLOAT == type) {
- if (tokenBuilder.toString().equals(decimalFormat.getDecimalFormatSymbols()
- .getNaN())) {
- result.append("NaN");//$NON-NLS-1$
- } else if (tokenBuilder.toString().equals(decimalFormat
- .getDecimalFormatSymbols().getInfinity())) {
- result.append("Infinity");//$NON-NLS-1$
+ if (tokenBuilder.toString().equals(
+ decimalFormat.getDecimalFormatSymbols().getNaN())) {
+ result.append("NaN");//$NON-NLS-1$
+ } else if (tokenBuilder.toString().equals(
+ decimalFormat.getDecimalFormatSymbols().getInfinity())) {
+ result.append("Infinity");//$NON-NLS-1$
} else {
for (int i = 0; i < tokenBuilder.length(); i++) {
if (-1 != Character.digit(tokenBuilder.charAt(i), 10)) {
@@ -2029,8 +1975,9 @@
}
return result.toString();
}
+
/*
- * remove positive and negative sign from the parameter stringBuilder, and
+ * Remove positive and negative sign from the parameter stringBuilder, and
* return whether the input string is negative
*/
private boolean removeLocaleSign(StringBuilder tokenBuilder) {
@@ -2106,7 +2053,7 @@
}
/*
- * Find prefixed delimiter
+ * Find prefix delimiter
*/
private int findPreDelimiter() {
int tokenStartIndex;
@@ -2166,7 +2113,7 @@
}
/*
- * Find postfixed delimiter
+ * Find postfix delimiter
*/
private int findPostDelimiter() {
int tokenEndIndex = 0;
@@ -2215,7 +2162,8 @@
}
} catch (IOException e) {
// Consider the scenario: readable puts 4 chars into
- // buffer and then an IOException is thrown out. In this case, buffer is
+ // buffer and then an IOException is thrown out. In this case,
+ // buffer is
// actually grown, but readable.read() will never return.
bufferLength = buffer.position();
/*
@@ -2226,7 +2174,6 @@
lastIOException = e;
}
-
buffer.flip();
buffer.position(oldPosition);
if (-1 == readCount) {
diff --git a/luni/src/main/java/java/util/Set.java b/luni/src/main/java/java/util/Set.java
index f52666d..109c8df 100644
--- a/luni/src/main/java/java/util/Set.java
+++ b/luni/src/main/java/java/util/Set.java
@@ -20,8 +20,8 @@
/**
* A {@code Set} is a data structure which does not allow duplicate elements.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
public interface Set<E> extends Collection<E> {
@@ -38,7 +38,6 @@
* when the class of the object is inappropriate for this set.
* @throws IllegalArgumentException
* when the object cannot be added to this set.
- * @since Android 1.0
*/
public boolean add(E object);
@@ -55,7 +54,6 @@
* when the class of an object is inappropriate for this set.
* @throws IllegalArgumentException
* when an object cannot be added to this set.
- * @since Android 1.0
*/
public boolean addAll(Collection<? extends E> collection);
@@ -66,7 +64,6 @@
* when removing from this set is not supported.
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
public void clear();
@@ -77,7 +74,6 @@
* the object to search for.
* @return {@code true} if object is an element of this set, {@code false}
* otherwise.
- * @since Android 1.0
*/
public boolean contains(Object object);
@@ -88,7 +84,6 @@
* the collection of objects.
* @return {@code true} if all objects in the specified collection are
* elements of this set, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean containsAll(Collection<?> collection);
@@ -103,7 +98,6 @@
* @return boolean {@code true} if the object is the same as this object,
* and {@code false} if it is different from this object.
* @see #hashCode
- * @since Android 1.0
*/
public boolean equals(Object object);
@@ -114,7 +108,6 @@
* @return the hash code of this set.
*
* @see #equals
- * @since Android 1.0
*/
public int hashCode();
@@ -124,7 +117,6 @@
* @return {@code true} if this set has no elements, {@code false}
* otherwise.
* @see #size
- * @since Android 1.0
*/
public boolean isEmpty();
@@ -134,7 +126,6 @@
*
* @return an iterator on the elements of this set.
* @see Iterator
- * @since Android 1.0
*/
public Iterator<E> iterator();
@@ -146,7 +137,6 @@
* @return {@code true} if this set was modified, {@code false} otherwise.
* @throws UnsupportedOperationException
* when removing from this set is not supported.
- * @since Android 1.0
*/
public boolean remove(Object object);
@@ -158,7 +148,6 @@
* @return {@code true} if this set was modified, {@code false} otherwise.
* @throws UnsupportedOperationException
* when removing from this set is not supported.
- * @since Android 1.0
*/
public boolean removeAll(Collection<?> collection);
@@ -171,7 +160,6 @@
* @return {@code true} if this set was modified, {@code false} otherwise.
* @throws UnsupportedOperationException
* when removing from this set is not supported.
- * @since Android 1.0
*/
public boolean retainAll(Collection<?> collection);
@@ -179,7 +167,6 @@
* Returns the number of elements in this set.
*
* @return the number of elements in this set.
- * @since Android 1.0
*/
public int size();
@@ -187,7 +174,6 @@
* Returns an array containing all elements contained in this set.
*
* @return an array of the elements from this set.
- * @since Android 1.0
*/
public Object[] toArray();
@@ -205,7 +191,6 @@
* when the type of an element in this set cannot be stored in
* the type of the specified array.
* @see Collection#toArray(Object[])
- * @since Android 1.0
*/
public <T> T[] toArray(T[] array);
}
diff --git a/luni/src/main/java/java/util/SimpleTimeZone.java b/luni/src/main/java/java/util/SimpleTimeZone.java
index 18d076f..702b6ef 100644
--- a/luni/src/main/java/java/util/SimpleTimeZone.java
+++ b/luni/src/main/java/java/util/SimpleTimeZone.java
@@ -14,12 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
-*******************************************************************************
-* Copyright (C) 1996-2008, International Business Machines Corporation and *
-* others. All Rights Reserved. *
-*******************************************************************************
-*/
+
+// BEGIN android-note
+// This implementation is based on an old version of Apache Harmony. The current
+// Harmony uses ICU4J, which makes it much simpler. We should consider updating
+// this implementation to leverage ICU4JNI.
+// END android-note
package java.util;
@@ -27,33 +27,41 @@
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
+// BEGIN android-removed
+// import java.security.AccessController;
+// import java.security.PrivilegedAction;
+// END android-removed
import org.apache.harmony.luni.util.Msg;
-// BEGIN android-note
-// The class javadoc and some of the method descriptions are copied from ICU4J
-// source files. Changes have been made to the copied descriptions.
-// The icu license header was added to this file.
-// END android-note
/**
* {@code SimpleTimeZone} is a concrete subclass of {@code TimeZone}
* that represents a time zone for use with a Gregorian calendar. This class
* does not handle historical changes.
- * <P>
+ * <p>
* Use a negative value for {@code dayOfWeekInMonth} to indicate that
* {@code SimpleTimeZone} should count from the end of the month
* backwards. For example, Daylight Savings Time ends at the last
* (dayOfWeekInMonth = -1) Sunday in October, at 2 AM in standard time.
- *
+ *
* @see Calendar
* @see GregorianCalendar
* @see TimeZone
- * @since Android 1.0
*/
public class SimpleTimeZone extends TimeZone {
-
+
private static final long serialVersionUID = -403250971215465050L;
+ // BEGIN android-removed
+ // private static com.ibm.icu.util.TimeZone getICUTimeZone(final String name){
+ // return AccessController.doPrivileged(new PrivilegedAction<com.ibm.icu.util.TimeZone>(){
+ // public com.ibm.icu.util.TimeZone run() {
+ // return com.ibm.icu.util.TimeZone.getTimeZone(name);
+ // }
+ // });
+ // }
+ // END android-removed
+
private int rawOffset;
private int startYear, startMonth, startDay, startDayOfWeek, startTime;
@@ -67,8 +75,6 @@
/**
* The constant for representing a start or end time in GMT time mode.
- *
- * @since Android 1.0
*/
public static final int UTC_TIME = 2;
@@ -76,8 +82,6 @@
* The constant for representing a start or end time in standard local time mode,
* based on timezone's raw offset from GMT; does not include Daylight
* savings.
- *
- * @since Android 1.0
*/
public static final int STANDARD_TIME = 1;
@@ -85,8 +89,6 @@
* The constant for representing a start or end time in local wall clock time
* mode, based on timezone's adjusted offset from GMT; includes
* Daylight savings.
- *
- * @since Android 1.0
*/
public static final int WALL_TIME = 0;
@@ -96,22 +98,37 @@
private int dstSavings = 3600000;
+ // BEGIN android-removed
+ // private final transient com.ibm.icu.util.TimeZone icuTZ;
+ //
+ // private final transient boolean isSimple;
+ // END android-removed
+
/**
* Constructs a {@code SimpleTimeZone} with the given base time zone offset from GMT
* and time zone ID. Timezone IDs can be obtained from
* {@code TimeZone.getAvailableIDs}. Normally you should use {@code TimeZone.getDefault} to
* construct a {@code TimeZone}.
- *
+ *
* @param offset
* the given base time zone offset to GMT.
* @param name
* the time zone ID which is obtained from
* {@code TimeZone.getAvailableIDs}.
- * @since Android 1.0
*/
- public SimpleTimeZone(int offset, String name) {
+ public SimpleTimeZone(int offset, final String name) {
setID(name);
rawOffset = offset;
+ // BEGIN android-removed
+ // icuTZ = getICUTimeZone(name);
+ // if (icuTZ instanceof com.ibm.icu.util.SimpleTimeZone) {
+ // isSimple = true;
+ // icuTZ.setRawOffset(offset);
+ // } else {
+ // isSimple = false;
+ // }
+ // useDaylight = icuTZ.useDaylightTime();
+ // END android-removed
}
/**
@@ -146,8 +163,8 @@
* The above examples refer to the {@code startMonth}, {@code startDay}, and {@code startDayOfWeek};
* the same applies for the {@code endMonth}, {@code endDay}, and {@code endDayOfWeek}.
* <p>
- * The daylight savings time difference is set to the default value: one hour.
- *
+ * The daylight savings time difference is set to the default value: one hour.
+ *
* @param offset
* the given base time zone offset to GMT.
* @param name
@@ -182,7 +199,6 @@
* @throws IllegalArgumentException
* if the month, day, dayOfWeek, or time parameters are out of
* range for the start or end rule.
- * @since Android 1.0
*/
public SimpleTimeZone(int offset, String name, int startMonth,
int startDay, int startDayOfWeek, int startTime, int endMonth,
@@ -193,9 +209,9 @@
/**
* Constructs a {@code SimpleTimeZone} with the given base time zone offset from GMT,
- * time zone ID, times to start and end the daylight savings time, and
- * the daylight savings time difference in milliseconds
- *
+ * time zone ID, times to start and end the daylight savings time, and
+ * the daylight savings time difference in milliseconds.
+ *
* @param offset
* the given base time zone offset to GMT.
* @param name
@@ -212,7 +228,7 @@
* description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example.
* @param startTime
* The daylight savings starting time in local wall time, which
- * is standard time in this case. Please see the description of
+ * is standard time in this case. Please see the description of
* {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example.
* @param endMonth
* the daylight savings ending month. Month is 0-based. eg, 0 for
@@ -221,7 +237,7 @@
* the daylight savings ending day-of-week-in-month. Please see
* the description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example.
* @param endDayOfWeek
- * the daylight savings ending day-of-week. Please see the description of
+ * the daylight savings ending day-of-week. Please see the description of
* {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example.
* @param endTime
* the daylight savings ending time in local wall time, which is
@@ -229,31 +245,50 @@
* for an example.
* @param daylightSavings
* the daylight savings time difference in milliseconds.
- * @exception IllegalArgumentException
- * the month, day, dayOfWeek, or time parameters are out of
+ * @throws IllegalArgumentException
+ * if the month, day, dayOfWeek, or time parameters are out of
* range for the start or end rule.
- * @since Android 1.0
*/
public SimpleTimeZone(int offset, String name, int startMonth,
int startDay, int startDayOfWeek, int startTime, int endMonth,
int endDay, int endDayOfWeek, int endTime, int daylightSavings) {
+ // BEGIN android-changed
+ // icuTZ = getICUTimeZone(name);
+ // if (icuTZ instanceof com.ibm.icu.util.SimpleTimeZone) {
+ // isSimple = true;
+ // com.ibm.icu.util.SimpleTimeZone tz = (com.ibm.icu.util.SimpleTimeZone)icuTZ;
+ // tz.setRawOffset(offset);
+ // tz.setStartRule(startMonth, startDay, startDayOfWeek, startTime);
+ // tz.setEndRule(endMonth, endDay, endDayOfWeek, endTime);
+ // tz.setDSTSavings(daylightSavings);
+ // } else {
+ // isSimple = false;
+ // }
+ // setID(name);
+ // rawOffset = offset;
this(offset, name);
+ // END android-changed
if (daylightSavings <= 0) {
- throw new IllegalArgumentException(Msg.getString("K00e9", daylightSavings)); //$NON-NLS-1$
+ throw new IllegalArgumentException(Msg.getString(
+ "K00e9", daylightSavings)); //$NON-NLS-1$
}
dstSavings = daylightSavings;
setStartRule(startMonth, startDay, startDayOfWeek, startTime);
setEndRule(endMonth, endDay, endDayOfWeek, endTime);
+
+ // BEGIN android-removed
+ // useDaylight = daylightSavings > 0 || icuTZ.useDaylightTime();
+ // END android-removed
}
/**
* Construct a {@code SimpleTimeZone} with the given base time zone offset from GMT,
- * time zone ID, times to start and end the daylight savings time including a
+ * time zone ID, times to start and end the daylight savings time including a
* mode specifier, the daylight savings time difference in milliseconds.
* The mode specifies either {@link #WALL_TIME}, {@link #STANDARD_TIME}, or
* {@link #UTC_TIME}.
- *
+ *
* @param offset
* the given base time zone offset to GMT.
* @param name
@@ -269,21 +304,21 @@
* the daylight savings starting day-of-week. Please see the
* description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example.
* @param startTime
- * the time of day in milliseconds on which daylight savings
+ * the time of day in milliseconds on which daylight savings
* time starts, based on the {@code startTimeMode}.
* @param startTimeMode
* the mode (UTC, standard, or wall time) of the start time
* value.
- * @param endDay
- * the day of the week on which daylight savings time ends.
+ * @param endDay
+ * the day of the week on which daylight savings time ends.
* @param endMonth
* the daylight savings ending month. The month indexing is 0-based. eg, 0 for
* January.
* @param endDayOfWeek
- * the daylight savings ending day-of-week. Please see the description of
+ * the daylight savings ending day-of-week. Please see the description of
* {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example.
* @param endTime
- * the time of day in milliseconds on which daylight savings
+ * the time of day in milliseconds on which daylight savings
* time ends, based on the {@code endTimeMode}.
* @param endTimeMode
* the mode (UTC, standard, or wall time) of the end time value.
@@ -292,7 +327,6 @@
* @throws IllegalArgumentException
* if the month, day, dayOfWeek, or time parameters are out of
* range for the start or end rule.
- * @since Android 1.0
*/
public SimpleTimeZone(int offset, String name, int startMonth,
int startDay, int startDayOfWeek, int startTime, int startTimeMode,
@@ -308,10 +342,9 @@
/**
* Returns a new {@code SimpleTimeZone} with the same ID, {@code rawOffset} and daylight
* savings time rules as this SimpleTimeZone.
- *
+ *
* @return a shallow copy of this {@code SimpleTimeZone}.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -326,13 +359,12 @@
* Compares the specified object to this {@code SimpleTimeZone} and returns whether they
* are equal. The object must be an instance of {@code SimpleTimeZone} and have the
* same internal data.
- *
+ *
* @param object
* the object to compare with this object.
* @return {@code true} if the specified object is equal to this
* {@code SimpleTimeZone}, {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -372,6 +404,8 @@
checkDay(month, day);
}
+ // BEGIN android-changed
+ // return icuTZ.getOffset(era, year, month, day, dayOfWeek, time);
if (!useDaylightTime() || era != GregorianCalendar.AD
|| year < startYear) {
return rawOffset;
@@ -389,38 +423,39 @@
int ruleDay = 0, daysInMonth, firstDayOfMonth = mod7(dayOfWeek - day);
if (month == startMonth) {
switch (startMode) {
- case DOM_MODE:
- ruleDay = startDay;
- break;
- case DOW_IN_MONTH_MODE:
- if (startDay >= 0) {
- ruleDay = mod7(startDayOfWeek - firstDayOfMonth) + 1
- + (startDay - 1) * 7;
- } else {
- daysInMonth = GregorianCalendar.DaysInMonth[startMonth];
- if (startMonth == Calendar.FEBRUARY && isLeapYear(year)) {
- daysInMonth += 1;
+ case DOM_MODE:
+ ruleDay = startDay;
+ break;
+ case DOW_IN_MONTH_MODE:
+ if (startDay >= 0) {
+ ruleDay = mod7(startDayOfWeek - firstDayOfMonth) + 1
+ + (startDay - 1) * 7;
+ } else {
+ daysInMonth = GregorianCalendar.DaysInMonth[startMonth];
+ if (startMonth == Calendar.FEBRUARY && isLeapYear(
+ year)) {
+ daysInMonth += 1;
+ }
+ ruleDay = daysInMonth
+ + 1
+ + mod7(startDayOfWeek
+ - (firstDayOfMonth + daysInMonth))
+ + startDay * 7;
}
- ruleDay = daysInMonth
- + 1
+ break;
+ case DOW_GE_DOM_MODE:
+ ruleDay = startDay
+ mod7(startDayOfWeek
- - (firstDayOfMonth + daysInMonth))
- + startDay * 7;
- }
- break;
- case DOW_GE_DOM_MODE:
- ruleDay = startDay
- + mod7(startDayOfWeek
- - (firstDayOfMonth + startDay - 1));
- break;
- case DOW_LE_DOM_MODE:
- ruleDay = startDay
- + mod7(startDayOfWeek
- - (firstDayOfMonth + startDay - 1));
- if (ruleDay != startDay) {
- ruleDay -= 7;
- }
- break;
+ - (firstDayOfMonth + startDay - 1));
+ break;
+ case DOW_LE_DOM_MODE:
+ ruleDay = startDay
+ + mod7(startDayOfWeek
+ - (firstDayOfMonth + startDay - 1));
+ if (ruleDay != startDay) {
+ ruleDay -= 7;
+ }
+ break;
}
if (ruleDay > day || ruleDay == day && time < startTime) {
return rawOffset;
@@ -431,36 +466,38 @@
int nextMonth = (month + 1) % 12;
if (month == endMonth || (ruleTime < 0 && nextMonth == endMonth)) {
switch (endMode) {
- case DOM_MODE:
- ruleDay = endDay;
- break;
- case DOW_IN_MONTH_MODE:
- if (endDay >= 0) {
- ruleDay = mod7(endDayOfWeek - firstDayOfMonth) + 1
- + (endDay - 1) * 7;
- } else {
- daysInMonth = GregorianCalendar.DaysInMonth[endMonth];
- if (endMonth == Calendar.FEBRUARY && isLeapYear(year)) {
- daysInMonth++;
+ case DOM_MODE:
+ ruleDay = endDay;
+ break;
+ case DOW_IN_MONTH_MODE:
+ if (endDay >= 0) {
+ ruleDay = mod7(endDayOfWeek - firstDayOfMonth) + 1
+ + (endDay - 1) * 7;
+ } else {
+ daysInMonth = GregorianCalendar.DaysInMonth[endMonth];
+ if (endMonth == Calendar.FEBRUARY && isLeapYear(year)) {
+ daysInMonth++;
+ }
+ ruleDay = daysInMonth
+ + 1
+ + mod7(endDayOfWeek
+ - (firstDayOfMonth + daysInMonth)) + endDay
+ * 7;
}
- ruleDay = daysInMonth
- + 1
- + mod7(endDayOfWeek
- - (firstDayOfMonth + daysInMonth)) + endDay
- * 7;
- }
- break;
- case DOW_GE_DOM_MODE:
- ruleDay = endDay
- + mod7(endDayOfWeek - (firstDayOfMonth + endDay - 1));
- break;
- case DOW_LE_DOM_MODE:
- ruleDay = endDay
- + mod7(endDayOfWeek - (firstDayOfMonth + endDay - 1));
- if (ruleDay != endDay) {
- ruleDay -= 7;
- }
- break;
+ break;
+ case DOW_GE_DOM_MODE:
+ ruleDay = endDay
+ + mod7(
+ endDayOfWeek - (firstDayOfMonth + endDay - 1));
+ break;
+ case DOW_LE_DOM_MODE:
+ ruleDay = endDay
+ + mod7(
+ endDayOfWeek - (firstDayOfMonth + endDay - 1));
+ if (ruleDay != endDay) {
+ ruleDay -= 7;
+ }
+ break;
}
int ruleMonth = endMonth;
@@ -488,10 +525,13 @@
}
}
return rawOffset + dstSavings;
+ // END android-changed
}
@Override
public int getOffset(long time) {
+ // BEGIN android-changed
+ // return icuTZ.getOffset(time);
if (!useDaylightTime()) {
return rawOffset;
}
@@ -499,6 +539,7 @@
daylightSavings = new GregorianCalendar(this);
}
return daylightSavings.getOffset(time + rawOffset);
+ // END android-changed
}
@Override
@@ -509,10 +550,9 @@
/**
* Returns an integer hash code for the receiver. Objects which are equal
* return the same value for this method.
- *
+ *
* @return the receiver's hash.
* @see #equals
- * @since Android 1.0
*/
@Override
public synchronized int hashCode() {
@@ -548,6 +588,8 @@
@Override
public boolean inDaylightTime(Date time) {
+ // BEGIN android-changed
+ // return icuTZ.inDaylightTime(time);
// check for null pointer
long millis = time.getTime();
if (!useDaylightTime()) {
@@ -557,6 +599,7 @@
daylightSavings = new GregorianCalendar(this);
}
return daylightSavings.getOffset(millis + rawOffset) != rawOffset;
+ // END android-changed
}
private boolean isLeapYear(int year) {
@@ -566,17 +609,18 @@
return year % 4 == 0;
}
+ // BEGIN android-added
private int mod7(int num1) {
int rem = num1 % 7;
return (num1 < 0 && rem < 0) ? 7 + rem : rem;
}
+ // END android-added
/**
* Sets the daylight savings offset in milliseconds for this {@code SimpleTimeZone}.
- *
+ *
* @param milliseconds
* the daylight savings offset in milliseconds.
- * @since Android 1.0
*/
public void setDSTSavings(int milliseconds) {
if (milliseconds > 0) {
@@ -591,7 +635,8 @@
throw new IllegalArgumentException(Msg.getString("K00e5", month)); //$NON-NLS-1$
}
if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) {
- throw new IllegalArgumentException(Msg.getString("K00e7", dayOfWeek)); //$NON-NLS-1$
+ throw new IllegalArgumentException(Msg
+ .getString("K00e7", dayOfWeek)); //$NON-NLS-1$
}
if (time < 0 || time >= 24 * 3600000) {
throw new IllegalArgumentException(Msg.getString("K00e8", time)); //$NON-NLS-1$
@@ -626,7 +671,8 @@
checkDay(endMonth, endDay);
} else {
if (endDay < -5 || endDay > 5) {
- throw new IllegalArgumentException(Msg.getString("K00f8", endDay)); //$NON-NLS-1$
+ throw new IllegalArgumentException(Msg.getString(
+ "K00f8", endDay)); //$NON-NLS-1$
}
}
}
@@ -637,7 +683,7 @@
/**
* Sets the rule which specifies the end of daylight savings time.
- *
+ *
* @param month
* the {@code Calendar} month in which daylight savings time ends.
* @param dayOfMonth
@@ -646,7 +692,6 @@
* @param time
* the time of day in milliseconds standard time on which
* daylight savings time ends.
- * @since Android 1.0
*/
public void setEndRule(int month, int dayOfMonth, int time) {
endMonth = month;
@@ -654,11 +699,17 @@
endDayOfWeek = 0; // Initialize this value for hasSameRules()
endTime = time;
setEndMode();
+ // BEGIN android-removed
+ // if (isSimple) {
+ // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month,
+ // dayOfMonth, time);
+ // }
+ // END android-removed
}
/**
* Sets the rule which specifies the end of daylight savings time.
- *
+ *
* @param month
* the {@code Calendar} month in which daylight savings time ends.
* @param day
@@ -670,7 +721,6 @@
* @param time
* the time of day in milliseconds standard time on which
* daylight savings time ends.
- * @since Android 1.0
*/
public void setEndRule(int month, int day, int dayOfWeek, int time) {
endMonth = month;
@@ -678,11 +728,17 @@
endDayOfWeek = dayOfWeek;
endTime = time;
setEndMode();
+ // BEGIN android-removed
+ // if (isSimple) {
+ // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month, day,
+ // dayOfWeek, time);
+ // }
+ // END android-removed
}
/**
* Sets the rule which specifies the end of daylight savings time.
- *
+ *
* @param month
* the {@code Calendar} month in which daylight savings time ends.
* @param day
@@ -695,7 +751,6 @@
* ends.
* @param after
* selects the day after or before the day of month.
- * @since Android 1.0
*/
public void setEndRule(int month, int day, int dayOfWeek, int time,
boolean after) {
@@ -704,18 +759,26 @@
endDayOfWeek = -dayOfWeek;
endTime = time;
setEndMode();
+ // BEGIN android-removed
+ // if (isSimple) {
+ // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month, day,
+ // dayOfWeek, time, after);
+ // }
+ // END android-removed
}
/**
* Sets the offset for standard time from GMT for this {@code SimpleTimeZone}.
- *
+ *
* @param offset
* the offset from GMT of standard time in milliseconds.
- * @since Android 1.0
*/
@Override
public void setRawOffset(int offset) {
rawOffset = offset;
+ // BEGIN android-removed
+ // icuTZ.setRawOffset(offset);
+ // END android-removed
}
private void setStartMode() {
@@ -740,7 +803,8 @@
checkDay(startMonth, startDay);
} else {
if (startDay < -5 || startDay > 5) {
- throw new IllegalArgumentException(Msg.getString("K00f8", startDay)); //$NON-NLS-1$
+ throw new IllegalArgumentException(Msg.getString(
+ "K00f8", startDay)); //$NON-NLS-1$
}
}
}
@@ -751,7 +815,7 @@
/**
* Sets the rule which specifies the start of daylight savings time.
- *
+ *
* @param month
* the {@code Calendar} month in which daylight savings time starts.
* @param dayOfMonth
@@ -760,7 +824,6 @@
* @param time
* the time of day in milliseconds on which daylight savings time
* starts.
- * @since Android 1.0
*/
public void setStartRule(int month, int dayOfMonth, int time) {
startMonth = month;
@@ -768,11 +831,17 @@
startDayOfWeek = 0; // Initialize this value for hasSameRules()
startTime = time;
setStartMode();
+ // BEGIN android-removed
+ // if (isSimple) {
+ // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(month,
+ // dayOfMonth, time);
+ // }
+ // END android-removed
}
/**
* Sets the rule which specifies the start of daylight savings time.
- *
+ *
* @param month
* the {@code Calendar} month in which daylight savings time starts.
* @param day
@@ -784,7 +853,6 @@
* @param time
* the time of day in milliseconds on which daylight savings time
* starts.
- * @since Android 1.0
*/
public void setStartRule(int month, int day, int dayOfWeek, int time) {
startMonth = month;
@@ -792,11 +860,17 @@
startDayOfWeek = dayOfWeek;
startTime = time;
setStartMode();
+ // BEGIN android-removed
+ // if (isSimple) {
+ // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(month, day,
+ // dayOfWeek, time);
+ // }
+ // END android-removed
}
/**
* Sets the rule which specifies the start of daylight savings time.
- *
+ *
* @param month
* the {@code Calendar} month in which daylight savings time starts.
* @param day
@@ -809,7 +883,6 @@
* starts.
* @param after
* selects the day after or before the day of month.
- * @since Android 1.0
*/
public void setStartRule(int month, int day, int dayOfWeek, int time,
boolean after) {
@@ -818,15 +891,20 @@
startDayOfWeek = -dayOfWeek;
startTime = time;
setStartMode();
+ // BEGIN android-removed
+ // if (isSimple) {
+ // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(month, day,
+ // dayOfWeek, time, after);
+ // }
+ // END android-removed
}
/**
* Sets the starting year for daylight savings time in this {@code SimpleTimeZone}.
* Years before this start year will always be in standard time.
- *
+ *
* @param year
* the starting year.
- * @since Android 1.0
*/
public void setStartYear(int year) {
startYear = year;
@@ -835,9 +913,8 @@
/**
* Returns the string representation of this {@code SimpleTimeZone}.
- *
+ *
* @return the string representation of this {@code SimpleTimeZone}.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -864,7 +941,7 @@
+ endMode + ",endMonth=" + endMonth + ",endDay=" + endDay //$NON-NLS-1$ //$NON-NLS-2$
+ ",endDayOfWeek=" //$NON-NLS-1$
+ (useDaylight && (endMode != DOM_MODE) ? endDayOfWeek + 1 : 0)
- + ",endTime=" + endTime + "]"; //$NON-NLS-1$//$NON-NLS-2$
+ + ",endTime=" + endTime + "]"; //$NON-NLS-1$//$NON-NLS-2$
}
@Override
diff --git a/luni/src/main/java/java/util/SortedMap.java b/luni/src/main/java/java/util/SortedMap.java
index 10b2647..2fb25fd 100644
--- a/luni/src/main/java/java/util/SortedMap.java
+++ b/luni/src/main/java/java/util/SortedMap.java
@@ -21,8 +21,6 @@
/**
* A map that has its keys ordered. The sorting is according to either the
* natural ordering of its keys or the ordering given by a specified comparator.
- *
- * @since Android 1.0
*/
public interface SortedMap<K,V> extends Map<K,V> {
@@ -30,7 +28,6 @@
* Returns the comparator used to compare keys in this sorted map.
*
* @return the comparator or {@code null} if the natural order is used.
- * @since Android 1.0
*/
public Comparator<? super K> comparator();
@@ -38,9 +35,8 @@
* Returns the first key in this sorted map.
*
* @return the first key in this sorted map.
- * @exception NoSuchElementException
+ * @throws NoSuchElementException
* if this sorted map is empty.
- * @since Android 1.0
*/
public K firstKey();
@@ -51,8 +47,7 @@
* <p>
* Note: The returned map will not allow an insertion of a key outside the
* specified range.
- * </p>
- *
+ *
* @param endKey
* the high boundary of the range specified.
* @return a sorted map where the keys are less than {@code endKey}.
@@ -65,7 +60,6 @@
* @throws IllegalArgumentException
* if this map is itself a sorted map over a range of another
* map and the specified key is outside of its range.
- * @since Android 1.0
*/
public SortedMap<K,V> headMap(K endKey);
@@ -73,9 +67,8 @@
* Returns the last key in this sorted map.
*
* @return the last key in this sorted map.
- * @exception NoSuchElementException
+ * @throws NoSuchElementException
* if this sorted map is empty.
- * @since Android 1.0
*/
public K lastKey();
@@ -87,8 +80,7 @@
* <p>
* Note: The returned map will not allow an insertion of a key outside the
* specified range.
- * </p>
- *
+ *
* @param startKey
* the low boundary of the range (inclusive).
* @param endKey
@@ -104,7 +96,6 @@
* if the start key is greater than the end key, or if this map
* is itself a sorted map over a range of another sorted map and
* the specified range is outside of its range.
- * @since Android 1.0
*/
public SortedMap<K,V> subMap(K startKey, K endKey);
@@ -115,7 +106,6 @@
* <p>
* Note: The returned map will not allow an insertion of a key outside the
* specified range.
- * </p>
*
* @param startKey
* the low boundary of the range specified.
@@ -130,7 +120,6 @@
* @throws IllegalArgumentException
* if this map itself a sorted map over a range of another map
* and the specified key is outside of its range.
- * @since Android 1.0
*/
public SortedMap<K,V> tailMap(K startKey);
}
diff --git a/luni/src/main/java/java/util/SortedSet.java b/luni/src/main/java/java/util/SortedSet.java
index 24fa017..d387540 100644
--- a/luni/src/main/java/java/util/SortedSet.java
+++ b/luni/src/main/java/java/util/SortedSet.java
@@ -27,7 +27,6 @@
*
* @see Comparator
* @see Comparable
- * @since Android 1.0
*/
public interface SortedSet<E> extends Set<E> {
@@ -35,7 +34,6 @@
* Returns the comparator used to compare elements in this {@code SortedSet}.
*
* @return a comparator or null if the natural ordering is used.
- * @since Android 1.0
*/
public Comparator<? super E> comparator();
@@ -46,7 +44,6 @@
* @return the first element.
* @throws NoSuchElementException
* when this {@code SortedSet} is empty.
- * @since Android 1.0
*/
public E first();
@@ -65,7 +62,6 @@
* @throws NullPointerException
* when the end element is null and this {@code SortedSet} does
* not support null elements.
- * @since Android 1.0
*/
public SortedSet<E> headSet(E end);
@@ -76,7 +72,6 @@
* @return the last element.
* @throws NoSuchElementException
* when this {@code SortedSet} is empty.
- * @since Android 1.0
*/
public E last();
@@ -101,7 +96,6 @@
* {@code SortedSet} does not support null elements.
* @throws IllegalArgumentException
* when the start element is greater than the end element.
- * @since Android 1.0
*/
public SortedSet<E> subSet(E start, E end);
@@ -120,7 +114,6 @@
* @throws NullPointerException
* when the start element is null and this {@code SortedSet}
* does not support null elements.
- * @since Android 1.0
*/
public SortedSet<E> tailSet(E start);
}
diff --git a/luni/src/main/java/java/util/Stack.java b/luni/src/main/java/java/util/Stack.java
index 8ecb765..1572a08 100644
--- a/luni/src/main/java/java/util/Stack.java
+++ b/luni/src/main/java/java/util/Stack.java
@@ -17,22 +17,17 @@
package java.util;
-
/**
* {@code Stack} is a Last-In/First-Out(LIFO) data structure which represents a
* stack of objects. It enables users to pop to and push from the stack,
* including null objects. There is no limit to the size of the stack.
- *
- * @since Android 1.0
*/
public class Stack<E> extends Vector<E> {
-
+
private static final long serialVersionUID = 1224463164541339165L;
/**
* Constructs a stack with the default size of {@code Vector}.
- *
- * @since Android 1.0
*/
public Stack() {
super();
@@ -40,9 +35,8 @@
/**
* Returns whether the stack is empty or not.
- *
+ *
* @return {@code true} if the stack is empty, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean empty() {
return elementCount == 0;
@@ -50,16 +44,16 @@
/**
* Returns the element at the top of the stack without removing it.
- *
+ *
* @return the element at the top of the stack.
* @throws EmptyStackException
* if the stack is empty.
* @see #pop
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
public synchronized E peek() {
try {
- return (E)elementData[elementCount - 1];
+ return (E) elementData[elementCount - 1];
} catch (IndexOutOfBoundsException e) {
throw new EmptyStackException();
}
@@ -67,36 +61,35 @@
/**
* Returns the element at the top of the stack and removes it.
- *
+ *
* @return the element at the top of the stack.
* @throws EmptyStackException
* if the stack is empty.
* @see #peek
* @see #push
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
public synchronized E pop() {
- try {
- int index = elementCount - 1;
- E obj = (E)elementData[index];
- removeElementAt(index);
- return obj;
- } catch (IndexOutOfBoundsException e) {
+ if (elementCount == 0) {
throw new EmptyStackException();
}
+ final int index = --elementCount;
+ final E obj = (E) elementData[index];
+ elementData[index] = null;
+ modCount++;
+ return obj;
}
/**
* Pushes the specified object onto the top of the stack.
- *
+ *
* @param object
* The object to be added on top of the stack.
* @return the object argument.
* @see #peek
* @see #pop
- * @since Android 1.0
*/
- public synchronized E push(E object) {
+ public E push(E object) {
addElement(object);
return object;
}
@@ -104,17 +97,28 @@
/**
* Returns the index of the first occurrence of the object, starting from
* the top of the stack.
- *
+ *
* @return the index of the first occurrence of the object, assuming that
* the topmost object on the stack has a distance of one.
* @param o
* the object to be searched.
- * @since Android 1.0
*/
public synchronized int search(Object o) {
- int index = lastIndexOf(o);
- if (index >= 0)
- return (elementCount - index);
+ final Object[] dumpArray = elementData;
+ final int size = elementCount;
+ if (o != null) {
+ for (int i = size - 1; i >= 0; i--) {
+ if (o.equals(dumpArray[i])) {
+ return size - i;
+ }
+ }
+ } else {
+ for (int i = size - 1; i >= 0; i--) {
+ if (dumpArray[i] == null) {
+ return size - i;
+ }
+ }
+ }
return -1;
}
}
diff --git a/luni/src/main/java/java/util/StringTokenizer.java b/luni/src/main/java/java/util/StringTokenizer.java
index 3bbeefa..2800283 100644
--- a/luni/src/main/java/java/util/StringTokenizer.java
+++ b/luni/src/main/java/java/util/StringTokenizer.java
@@ -14,32 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
-*******************************************************************************
-* Copyright (C) 1996-2006, International Business Machines Corporation and *
-* others. All Rights Reserved. *
-*******************************************************************************
-*/
package java.util;
-
-// BEGIN android-note
-// The class javadoc and some of the method descriptions are copied from ICU4J
-// source files. Changes have been made to the copied descriptions.
-// The icu license header was added to this file.
-// END android-note
/**
- * <p>
* The {@code StringTokenizer} class allows an application to break a string
* into tokens by performing code point comparison. The {@code StringTokenizer}
* methods do not distinguish among identifiers, numbers, and quoted strings,
* nor do they recognize and skip comments.
- * </p>
* <p>
* The set of delimiters (the codepoints that separate tokens) may be specified
* either at creation time or on a per-token basis.
- * </p>
* <p>
* An instance of {@code StringTokenizer} behaves in one of three ways,
* depending on whether it was created with the {@code returnDelimiters} flag
@@ -55,45 +40,40 @@
* <p>
* A token is thus either one delimiter code point, or a maximal sequence of
* consecutive code points that are not delimiters.
- * </p>
* <p>
* A {@code StringTokenizer} object internally maintains a current position
* within the string to be tokenized. Some operations advance this current
* position past the code point processed.
- * </p>
* <p>
* A token is returned by taking a substring of the string that was used to
* create the {@code StringTokenizer} object.
- * </p>
* <p>
* Here's an example of the use of the default delimiter {@code StringTokenizer}
* : <blockquote>
- *
+ *
* <pre>
* StringTokenizer st = new StringTokenizer("this is a test");
* while (st.hasMoreTokens()) {
* println(st.nextToken());
* }
* </pre>
- *
+ *
* </blockquote>
- * </p>
* <p>
* This prints the following output: <blockquote>
- *
+ *
* <pre>
* this
* is
* a
* test
* </pre>
- *
+ *
* </blockquote>
- * </p>
* <p>
* Here's an example of how to use a {@code StringTokenizer} with a user
* specified delimiter: <blockquote>
- *
+ *
* <pre>
* StringTokenizer st = new StringTokenizer(
* "this is a test with supplementary characters \ud800\ud800\udc00\udc00",
@@ -102,12 +82,11 @@
* println(st.nextToken());
* }
* </pre>
- *
+ *
* </blockquote>
- * </p>
* <p>
* This prints the following output: <blockquote>
- *
+ *
* <pre>
* this
* is
@@ -119,14 +98,11 @@
* \ud800
* \udc00
* </pre>
- *
+ *
* </blockquote>
- * </p>
- *
- * @since Android 1.0
*/
public class StringTokenizer implements Enumeration<Object> {
-
+
private String string;
private String delimiters;
@@ -139,10 +115,9 @@
* Constructs a new {@code StringTokenizer} for the parameter string using
* whitespace as the delimiter. The {@code returnDelimiters} flag is set to
* {@code false}.
- *
+ *
* @param string
* the string to be tokenized.
- * @since Android 1.0
*/
public StringTokenizer(String string) {
this(string, " \t\n\r\f", false); //$NON-NLS-1$
@@ -154,12 +129,11 @@
* {@code false}. If {@code delimiters} is {@code null}, this constructor
* doesn't throw an {@code Exception}, but later calls to some methods might
* throw a {@code NullPointerException}.
- *
+ *
* @param string
* the string to be tokenized.
* @param delimiters
* the delimiters to use.
- * @since Android 1.0
*/
public StringTokenizer(String string, String delimiters) {
this(string, delimiters, false);
@@ -171,14 +145,13 @@
* parameter {@code returnDelimiters} is {@code true}. If {@code delimiters}
* is null this constructor doesn't throw an {@code Exception}, but later
* calls to some methods might throw a {@code NullPointerException}.
- *
+ *
* @param string
* the string to be tokenized.
* @param delimiters
* the delimiters to use.
* @param returnDelimiters
* {@code true} to return each delimiter as a token.
- * @since Android 1.0
*/
public StringTokenizer(String string, String delimiters,
boolean returnDelimiters) {
@@ -193,10 +166,9 @@
/**
* Returns the number of unprocessed tokens remaining in the string.
- *
+ *
* @return number of tokens that can be retreived before an {@code
* Exception} will result from a call to {@code nextToken()}.
- * @since Android 1.0
*/
public int countTokens() {
int count = 0;
@@ -221,9 +193,8 @@
/**
* Returns {@code true} if unprocessed tokens remain. This method is
* implemented in order to satisfy the {@code Enumeration} interface.
- *
+ *
* @return {@code true} if unprocessed tokens remain.
- * @since Android 1.0
*/
public boolean hasMoreElements() {
return hasMoreTokens();
@@ -231,11 +202,13 @@
/**
* Returns {@code true} if unprocessed tokens remain.
- *
+ *
* @return {@code true} if unprocessed tokens remain.
- * @since Android 1.0
*/
public boolean hasMoreTokens() {
+ if (delimiters == null) {
+ throw new NullPointerException();
+ }
int length = string.length();
if (position < length) {
if (returnDelimiters)
@@ -253,11 +226,10 @@
/**
* Returns the next token in the string as an {@code Object}. This method is
* implemented in order to satisfy the {@code Enumeration} interface.
- *
+ *
* @return next token in the string as an {@code Object}
- * @exception NoSuchElementException
+ * @throws NoSuchElementException
* if no tokens remain.
- * @since Android 1.0
*/
public Object nextElement() {
return nextToken();
@@ -265,13 +237,15 @@
/**
* Returns the next token in the string as a {@code String}.
- *
+ *
* @return next token in the string as a {@code String}.
- * @exception NoSuchElementException
+ * @throws NoSuchElementException
* if no tokens remain.
- * @since Android 1.0
*/
public String nextToken() {
+ if (delimiters == null) {
+ throw new NullPointerException();
+ }
int i = position;
int length = string.length();
@@ -301,20 +275,14 @@
/**
* Returns the next token in the string as a {@code String}. The delimiters
* used are changed to the specified delimiters.
- *
+ *
* @param delims
* the new delimiters to use.
* @return next token in the string as a {@code String}.
- * @exception NoSuchElementException
+ * @throws NoSuchElementException
* if no tokens remain.
- * @since Android 1.0
*/
public String nextToken(String delims) {
- // BEGIN android-added
- if (delims == null) {
- throw new NullPointerException();
- }
- // END android-added
this.delimiters = delims;
return nextToken();
}
diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java
index c9709ce..b0bcc6b 100644
--- a/luni/src/main/java/java/util/TimeZone.java
+++ b/luni/src/main/java/java/util/TimeZone.java
@@ -14,35 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
-*******************************************************************************
-* Copyright (C) 1996-2008, International Business Machines Corporation and *
-* others. All Rights Reserved. *
-*******************************************************************************
-*/
-
-// BEGIN android-note
-// The class javadoc and some of the method descriptions are copied from ICU4J
-// source files. Changes have been made to the copied descriptions.
-// The icu license header was added to this file.
-// END android-note
package java.util;
-
import java.io.Serializable;
-// BEGIN android-removed
-// import java.security.AccessController;
-// import java.text.DateFormatSymbols;
-//
-// import org.apache.harmony.luni.util.PriviAction;
-// END android-removed
// BEGIN android-added
import org.apache.harmony.luni.internal.util.ZoneInfo;
import org.apache.harmony.luni.internal.util.ZoneInfoDB;
import com.ibm.icu4jni.util.Resources;
// END android-added
+
/**
* {@code TimeZone} represents a time zone offset, taking into account
* daylight savings.
@@ -57,21 +39,21 @@
* along with a time zone ID. For instance, the time zone ID for the U.S.
* Pacific Time zone is "America/Los_Angeles". So, you can get a U.S. Pacific
* Time {@code TimeZone} object with the following: <blockquote>
- *
+ *
* <pre>
* TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
* </pre>
- *
+ *
* </blockquote> You can use the {@code getAvailableIDs} method to iterate
* through all the supported time zone IDs. You can then choose a supported ID
* to get a {@code TimeZone}. If the time zone you want is not
* represented by one of the supported IDs, then you can create a custom time
* zone ID with the following syntax: <blockquote>
- *
+ *
* <pre>
* GMT[+|-]hh[[:]mm]
* </pre>
- *
+ *
* </blockquote> For example, you might specify GMT+14:00 as a custom time zone
* ID. The {@code TimeZone} that is returned when you specify a custom
* time zone ID does not include daylight savings time.
@@ -83,33 +65,26 @@
* "China Standard Time"), and the Java platform can then only recognize one of
* them.
* <p>
- * Please note the type returned by factory methods, i.e.
- * {@code getDefault()} and {@code getTimeZone(String)}, is
- * implementation dependent, so it may introduce serialization
- * incompatibility issues between different implementations. Android returns
- * instances of {@link SimpleTimeZone} so that the bytes serialized by Android
- * can be deserialized successfully on other implementations, but the reverse
- * compatibility cannot be guaranteed.
- *
+ * Please note the type returned by factory methods, i.e. {@code getDefault()}
+ * and {@code getTimeZone(String)}, is implementation dependent, so it may
+ * introduce serialization incompatibility issues between different
+ * implementations. Android returns instances of {@link SimpleTimeZone} so that
+ * the bytes serialized by Android can be deserialized successfully on other
+ * implementations, but the reverse compatibility cannot be guaranteed.
+ *
* @see GregorianCalendar
* @see SimpleTimeZone
- * @since Android 1.0
*/
-
public abstract class TimeZone implements Serializable, Cloneable {
private static final long serialVersionUID = 3581463369166924961L;
/**
* The SHORT display name style.
- *
- * @since Android 1.0
*/
public static final int SHORT = 0;
/**
* The LONG display name style.
- *
- * @since Android 1.0
*/
public static final int LONG = 1;
@@ -124,41 +99,49 @@
private String ID;
// BEGIN android-removed
+ // private com.ibm.icu.util.TimeZone icuTimeZone = null;
+ //
// private static void initializeAvailable() {
// TimeZone[] zones = TimeZones.getTimeZones();
- // AvailableZones = new HashMap<String, TimeZone>((zones.length + 1) * 4 / 3);
+ // AvailableZones = new HashMap<String, TimeZone>(
+ // (zones.length + 1) * 4 / 3);
// AvailableZones.put(GMT.getID(), GMT);
// for (int i = 0; i < zones.length; i++) {
// AvailableZones.put(zones[i].getID(), zones[i]);
// }
+ //}
+ //
+ // private static boolean isAvailableIDInICU(String name) {
+ // String[] availableIDs = com.ibm.icu.util.TimeZone.getAvailableIDs();
+ // for (int i = 0; i < availableIDs.length; i++) {
+ // if (availableIDs[i].equals(name)) {
+ // return true;
+ // }
+ // }
+ // return false;
+ // }
+ //
+ // private static void appendAvailableZones(String name) {
+ // com.ibm.icu.util.TimeZone icuTZ = com.ibm.icu.util.TimeZone
+ // .getTimeZone(name);
+ // int raw = icuTZ.getRawOffset();
+ // TimeZone zone = new SimpleTimeZone(raw, name);
+ // AvailableZones.put(name, zone);
// }
// END android-removed
/**
* Constructs a new instance of this class.
- *
- * @since Android 1.0
*/
public TimeZone() {
}
- private void appendNumber(StringBuffer buffer, int count, int value) {
- String string = Integer.toString(value);
- if (count > string.length()) {
- for (int i = 0; i < count - string.length(); i++) {
- buffer.append('0');
- }
- }
- buffer.append(string);
- }
-
/**
* Returns a new {@code TimeZone} with the same ID, {@code rawOffset} and daylight savings
* time rules as this {@code TimeZone}.
- *
+ *
* @return a shallow copy of this {@code TimeZone}.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
public Object clone() {
@@ -173,49 +156,34 @@
/**
* Gets the available time zone IDs. Any one of these IDs can be passed to
* {@code get()} to create the corresponding {@code TimeZone} instance.
- *
+ *
* @return an array of time zone ID strings.
- * @since Android 1.0
*/
public static synchronized String[] getAvailableIDs() {
- // BEGIN android-removed
- // if (AvailableZones == null) {
- // initializeAvailable();
- // }
- // int length = AvailableZones.size();
- // String[] answer = new String[length];
- // Iterator<String> keys = AvailableZones.keySet().iterator();
- // for (int i = 0; i < length; i++) {
- // answer[i] = keys.next();
- // }
- // return answer;
- // END android-removed
-
- // BEGIN android-added
+ // BEGIN android-changed
+ // return com.ibm.icu.util.TimeZone.getAvailableIDs();
return ZoneInfoDB.getAvailableIDs();
- // END android-added
+ // END android-changed
}
/**
* Gets the available time zone IDs which match the specified offset from
* GMT. Any one of these IDs can be passed to {@code get()} to create the corresponding
* {@code TimeZone} instance.
- *
+ *
* @param offset
* the offset from GMT in milliseconds.
* @return an array of time zone ID strings.
- * @since Android 1.0
*/
public static synchronized String[] getAvailableIDs(int offset) {
- // BEGIN android-removed
- // if (AvailableZones == null) {
- // initializeAvailable();
- // }
- // int count = 0, length = AvailableZones.size();
+ // BEGIN android-changed
+ // String[] availableIDs = com.ibm.icu.util.TimeZone.getAvailableIDs();
+ // int count = 0;
+ // int length = availableIDs.length;
// String[] all = new String[length];
- // Iterator<TimeZone> zones = AvailableZones.values().iterator();
// for (int i = 0; i < length; i++) {
- // TimeZone tz = zones.next();
+ // com.ibm.icu.util.TimeZone tz = com.ibm.icu.util.TimeZone
+ // .getTimeZone(availableIDs[i]);
// if (tz.getRawOffset() == offset) {
// all[count++] = tz.getID();
// }
@@ -223,23 +191,21 @@
// String[] answer = new String[count];
// System.arraycopy(all, 0, answer, 0, count);
// return answer;
- // END android-removed
-
- // BEGIN android-added
return ZoneInfoDB.getAvailableIDs(offset);
- // END android-added
-
+ // END android-changed
}
/**
* Gets the default time zone.
- *
+ *
* @return the default time zone.
- * @since Android 1.0
*/
public static synchronized TimeZone getDefault() {
if (Default == null) {
+ // BEGIN android-changed
+ // setDefault(null);
Default = ZoneInfoDB.getDefault();
+ // END android-changed
}
return (TimeZone) Default.clone();
}
@@ -248,9 +214,8 @@
* Gets the LONG name for this {@code TimeZone} for the default {@code Locale} in standard
* time. If the name is not available, the result is in the format
* {@code GMT[+-]hh:mm}.
- *
+ *
* @return the {@code TimeZone} name.
- * @since Android 1.0
*/
public final String getDisplayName() {
return getDisplayName(false, LONG, Locale.getDefault());
@@ -260,11 +225,10 @@
* Gets the LONG name for this {@code TimeZone} for the specified {@code Locale} in standard
* time. If the name is not available, the result is in the format
* {@code GMT[+-]hh:mm}.
- *
+ *
* @param locale
* the {@code Locale}.
* @return the {@code TimeZone} name.
- * @since Android 1.0
*/
public final String getDisplayName(Locale locale) {
return getDisplayName(false, LONG, locale);
@@ -274,14 +238,13 @@
* Gets the specified style of name ({@code LONG} or {@code SHORT}) for this {@code TimeZone} for
* the default {@code Locale} in either standard or daylight time as specified. If
* the name is not available, the result is in the format {@code GMT[+-]hh:mm}.
- *
+ *
* @param daylightTime
* {@code true} for daylight time, {@code false} for standard
* time.
* @param style
- * Either {@code LONG} or {@code SHORT}.
+ * either {@code LONG} or {@code SHORT}.
* @return the {@code TimeZone} name.
- * @since Android 1.0
*/
public final String getDisplayName(boolean daylightTime, int style) {
return getDisplayName(daylightTime, style, Locale.getDefault());
@@ -291,39 +254,31 @@
* Gets the specified style of name ({@code LONG} or {@code SHORT}) for this {@code TimeZone} for
* the specified {@code Locale} in either standard or daylight time as specified. If
* the name is not available, the result is in the format {@code GMT[+-]hh:mm}.
- *
+ *
* @param daylightTime
* {@code true} for daylight time, {@code false} for standard
* time.
* @param style
- * Either LONG or SHORT.
+ * either LONG or SHORT.
* @param locale
- * Either {@code LONG} or {@code SHORT}.
+ * either {@code LONG} or {@code SHORT}.
* @return the {@code TimeZone} name.
- * @since Android 1.0
*/
public String getDisplayName(boolean daylightTime, int style, Locale locale) {
+ // BEGIN android-changed
+ // if(icuTimeZone == null || !ID.equals(icuTimeZone.getID())){
+ // icuTimeZone = com.ibm.icu.util.TimeZone.getTimeZone(ID);
+ // }
+ // return icuTimeZone.getDisplayName(
+ // daylightTime, style, locale);
if (style == SHORT || style == LONG) {
boolean useDaylight = daylightTime && useDaylightTime();
- // BEGIN android-removed
- // DateFormatSymbols data = new DateFormatSymbols(locale);
- // String id = getID();
- // String[][] zones = data.getZoneStrings();
- // for (int i = 0; i < zones.length; i++) {
- // if (id.equals(zones[i][0])) {
- // return style == SHORT ? zones[i][useDaylight ? 4 : 2]
- // : zones[i][useDaylight ? 3 : 1];
- // }
- // }
- // BEGIN android-removed
-
- // BEGIN android-added
+
String result = Resources.getDisplayTimeZone(getID(), daylightTime, style, locale.toString());
if (result != null) {
return result;
}
- // END android-added
-
+
int offset = getRawOffset();
if (useDaylight && this instanceof SimpleTimeZone) {
offset += ((SimpleTimeZone) this).getDSTSavings();
@@ -343,13 +298,25 @@
return buffer.toString();
}
throw new IllegalArgumentException();
+ // END android-changed
}
+ // BEGIN android-added
+ private void appendNumber(StringBuffer buffer, int count, int value) {
+ String string = Integer.toString(value);
+ if (count > string.length()) {
+ for (int i = 0; i < count - string.length(); i++) {
+ buffer.append('0');
+ }
+ }
+ buffer.append(string);
+ }
+ // END android-added
+
/**
* Gets the ID of this {@code TimeZone}.
- *
+ *
* @return the time zone ID string.
- * @since Android 1.0
*/
public String getID() {
return ID;
@@ -364,10 +331,9 @@
* Subclasses may override to return daylight savings values other than 1
* hour.
* <p>
- *
+ *
* @return the daylight savings offset in milliseconds if this {@code TimeZone}
* observes daylight savings, zero otherwise.
- * @since Android 1.0
*/
public int getDSTSavings() {
if (useDaylightTime()) {
@@ -380,11 +346,10 @@
* Gets the offset from GMT of this {@code TimeZone} for the specified date. The
* offset includes daylight savings time if the specified date is within the
* daylight savings time period.
- *
+ *
* @param time
* the date in milliseconds since January 1, 1970 00:00:00 GMT
* @return the offset from GMT in milliseconds.
- * @since Android 1.0
*/
public int getOffset(long time) {
if (inDaylightTime(new Date(time))) {
@@ -397,7 +362,7 @@
* Gets the offset from GMT of this {@code TimeZone} for the specified date and
* time. The offset includes daylight savings time if the specified date and
* time are within the daylight savings time period.
- *
+ *
* @param era
* the {@code GregorianCalendar} era, either {@code GregorianCalendar.BC} or
* {@code GregorianCalendar.AD}.
@@ -412,39 +377,38 @@
* @param time
* the time of day in milliseconds.
* @return the offset from GMT in milliseconds.
- * @since Android 1.0
*/
abstract public int getOffset(int era, int year, int month, int day,
int dayOfWeek, int time);
/**
* Gets the offset for standard time from GMT for this {@code TimeZone}.
- *
+ *
* @return the offset from GMT in milliseconds.
- * @since Android 1.0
*/
abstract public int getRawOffset();
/**
* Gets the {@code TimeZone} with the specified ID.
- *
+ *
* @param name
* a time zone string ID.
* @return the {@code TimeZone} with the specified ID or null if no {@code TimeZone} with
* the specified ID exists.
- * @since Android 1.0
*/
public static synchronized TimeZone getTimeZone(String name) {
- // BEGIN android-removed
+ // BEGIN android-changed
// if (AvailableZones == null) {
// initializeAvailable();
// }
+ //
// TimeZone zone = AvailableZones.get(name);
- // END android-removed
-
- // BEGIN android-added
+ // if(zone == null && isAvailableIDInICU(name)){
+ // appendAvailableZones(name);
+ // zone = AvailableZones.get(name);
+ // }
TimeZone zone = ZoneInfo.getTimeZone(name);
- // END android-added
+ // END android-changed
if (zone == null) {
if (name.startsWith("GMT") && name.length() > 3) {
char sign = name.charAt(3);
@@ -513,12 +477,11 @@
/**
* Returns whether the specified {@code TimeZone} has the same raw offset as this
* {@code TimeZone}.
- *
+ *
* @param zone
* a {@code TimeZone}.
* @return {@code true} when the {@code TimeZone} have the same raw offset, {@code false}
* otherwise.
- * @since Android 1.0
*/
public boolean hasSameRules(TimeZone zone) {
if (zone == null) {
@@ -530,12 +493,11 @@
/**
* Returns whether the specified {@code Date} is in the daylight savings time period for
* this {@code TimeZone}.
- *
+ *
* @param time
* a {@code Date}.
* @return {@code true} when the {@code Date} is in the daylight savings time period, {@code false}
* otherwise.
- * @since Android 1.0
*/
abstract public boolean inDaylightTime(Date time);
@@ -555,34 +517,30 @@
* time {@link #getDefault} is called, the default time zone will be
* determined. This behavior is slightly different than the canonical
* description of this method, but it follows the spirit of it.
- *
+ *
* @param timezone
* a {@code TimeZone} object.
- * @since Android 1.0
*/
public static synchronized void setDefault(TimeZone timezone) {
// BEGIN android-removed
// if (timezone != null) {
+ // setICUDefaultTimeZone(timezone);
// Default = timezone;
// return;
// }
- // END android-removed
-
- // BEGIN android-added
- Default = timezone;
-
- // TODO Not sure if this is spec-compliant. Shouldn't be persistent.
- ZoneInfoDB.setDefault(timezone);
- // END android-added
-
- // BEGIN android-removed
+ //
// String zone = AccessController.doPrivileged(new PriviAction<String>(
- // "user.timezone"));
+ // "user.timezone"));
+ //
+ // // sometimes DRLVM incorrectly adds "\n" to the end of timezone ID
+ // if (zone != null && zone.contains("\n")) {
+ // zone = zone.substring(0, zone.indexOf("\n"));
+ // }
//
// // if property user.timezone is not set, we call the native method
// // getCustomTimeZone
- // if (zone == null) {
- // int[] tzinfo = new int[10];
+ // if (zone == null || zone.length() == 0) {
+ // int[] tzinfo = new int[10];
// boolean[] isCustomTimeZone = new boolean[1];
//
// String zoneId = getCustomTimeZone(tzinfo, isCustomTimeZone);
@@ -609,15 +567,45 @@
// // if property user.timezone is set in command line (with -D option)
// Default = getTimeZone(zone);
// }
+ // setICUDefaultTimeZone(Default);
// END android-removed
+
+ // BEGIN android-added
+ Default = timezone;
+
+ // TODO Not sure if this is spec-compliant. Shouldn't be persistent.
+ ZoneInfoDB.setDefault(timezone);
+ // END android-added
}
+ // BEGIN android-removed
+ // private static void setICUDefaultTimeZone(TimeZone timezone) {
+ // final com.ibm.icu.util.TimeZone icuTZ = com.ibm.icu.util.TimeZone
+ // .getTimeZone(timezone.getID());
+ //
+ // AccessController
+ // .doPrivileged(new PrivilegedAction<java.lang.reflect.Field>() {
+ // public java.lang.reflect.Field run() {
+ // java.lang.reflect.Field field = null;
+ // try {
+ // field = com.ibm.icu.util.TimeZone.class
+ // .getDeclaredField("defaultZone");
+ // field.setAccessible(true);
+ // field.set("defaultZone", icuTZ);
+ // } catch (Exception e) {
+ // return null;
+ // }
+ // return field;
+ // }
+ // });
+ // }
+ // END android-removed
+
/**
* Sets the ID of this {@code TimeZone}.
- *
+ *
* @param name
* a string which is the time zone ID.
- * @since Android 1.0
*/
public void setID(String name) {
if (name == null) {
@@ -628,44 +616,40 @@
/**
* Sets the offset for standard time from GMT for this {@code TimeZone}.
- *
+ *
* @param offset
* the offset from GMT in milliseconds.
- * @since Android 1.0
*/
abstract public void setRawOffset(int offset);
/**
* Returns whether this {@code TimeZone} has a daylight savings time period.
- *
+ *
* @return {@code true} if this {@code TimeZone} has a daylight savings time period, {@code false}
* otherwise.
- * @since Android 1.0
*/
abstract public boolean useDaylightTime();
- // BEGIN android-removed
- // /**
- // * Gets the name and the details of the user-selected TimeZone on the
- // * device.
- // *
- // * @param tzinfo
- // * int array of 10 elements to be filled with the TimeZone
- // * information. Once filled, the contents of the array are
- // * formatted as follows: tzinfo[0] -> the timezone offset;
- // * tzinfo[1] -> the dst adjustment; tzinfo[2] -> the dst start
- // * hour; tzinfo[3] -> the dst start day of week; tzinfo[4] -> the
- // * dst start week of month; tzinfo[5] -> the dst start month;
- // * tzinfo[6] -> the dst end hour; tzinfo[7] -> the dst end day of
- // * week; tzinfo[8] -> the dst end week of month; tzinfo[9] -> the
- // * dst end month;
- // * @param isCustomTimeZone
- // * boolean array of size 1 that indicates if a timezone
- // * match is found
- // * @return the name of the TimeZone or null if error occurs in native
- // * method.
- // */
- // private static native String getCustomTimeZone(int[] tzinfo,
- // boolean[] isCustomTimeZone);
- // END android-removed
+ /**
+ * Gets the name and the details of the user-selected TimeZone on the
+ * device.
+ *
+ * @param tzinfo
+ * int array of 10 elements to be filled with the TimeZone
+ * information. Once filled, the contents of the array are
+ * formatted as follows: tzinfo[0] -> the timezone offset;
+ * tzinfo[1] -> the dst adjustment; tzinfo[2] -> the dst start
+ * hour; tzinfo[3] -> the dst start day of week; tzinfo[4] -> the
+ * dst start week of month; tzinfo[5] -> the dst start month;
+ * tzinfo[6] -> the dst end hour; tzinfo[7] -> the dst end day of
+ * week; tzinfo[8] -> the dst end week of month; tzinfo[9] -> the
+ * dst end month;
+ * @param isCustomTimeZone
+ * boolean array of size 1 that indicates if a timezone match is
+ * found
+ * @return the name of the TimeZone or null if error occurs in native
+ * method.
+ */
+ private static native String getCustomTimeZone(int[] tzinfo,
+ boolean[] isCustomTimeZone);
}
diff --git a/luni/src/main/java/java/util/Timer.java b/luni/src/main/java/java/util/Timer.java
index ccff929..48970be 100644
--- a/luni/src/main/java/java/util/Timer.java
+++ b/luni/src/main/java/java/util/Timer.java
@@ -29,145 +29,143 @@
* excessive amount of time to run it may impact the time at which subsequent
* tasks may run.
* <p>
- *
+ *
* The {@code TimerTask} does not offer any guarantees about the real-time nature of
* scheduling tasks as its underlying implementation relies on the
* {@code Object.wait(long)} method.
- * </p>
* <p>
* Multiple threads can share a single {@code Timer} without the need for their own
- * synchronization.</p>
+ * synchronization.
* <p>
- * A {@code Timer} can be set to schedule tasks either at a fixed rate or
- * with a fixed period. Fixed-period execution is the default.</p>
+ * A {@code Timer} can be set to schedule tasks either at a fixed rate or
+ * with a fixed period. Fixed-period execution is the default.
* <p>
- * The difference between fixed-rate and fixed-period execution
- * is the following: With fixed-rate execution, the start time of each
+ * The difference between fixed-rate and fixed-period execution
+ * is the following: With fixed-rate execution, the start time of each
* successive run of the task is scheduled in absolute terms without regard for when the previous
- * task run actually took place. This can result in a series of bunched-up runs
- * (one launched immediately after another) if busy resources or other
+ * task run actually took place. This can result in a series of bunched-up runs
+ * (one launched immediately after another) if busy resources or other
* system delays prevent the {@code Timer} from firing for an extended time.
- * With fixed-period execution, each successive run of the
- * task is scheduled relative to the start time of the previous run of the
- * task, so two runs of the task are never fired closer together in time than
- * the specified {@code period}.</p>
- * </p>
- *
+ * With fixed-period execution, each successive run of the
+ * task is scheduled relative to the start time of the previous run of the
+ * task, so two runs of the task are never fired closer together in time than
+ * the specified {@code period}.
+ *
* @see TimerTask
* @see java.lang.Object#wait(long)
- * @since Android 1.0
*/
public class Timer {
private static final class TimerImpl extends Thread {
- private static final class TimerNode {
- TimerNode parent, left, right;
+ private static final class TimerHeap {
+ private int DEFAULT_HEAP_SIZE = 256;
- TimerTask task;
+ private TimerTask[] timers = new TimerTask[DEFAULT_HEAP_SIZE];
- public TimerNode(TimerTask value) {
- this.task = value;
+ private int size = 0;
+
+ private int deletedCancelledNumber = 0;
+
+ public TimerTask minimum() {
+ return timers[0];
}
- public void deleteIfCancelled(TimerTree tasks) {
- /*
- * All changes in the tree structure during deleting this node
- * affect only the structure of the subtree having this node as
- * its root
- */
- if (left != null) {
- left.deleteIfCancelled(tasks);
- }
- if (right != null) {
- right.deleteIfCancelled(tasks);
- }
- if (task.cancelled) {
- tasks.delete(this);
- tasks.deletedCancelledNumber++;
- }
- }
- }
-
- private static final class TimerTree {
-
- int deletedCancelledNumber;
-
- TimerNode root;
-
- boolean isEmpty() {
- return root == null;
+ public boolean isEmpty() {
+ return size == 0;
}
- void insert(TimerNode z) {
- TimerNode y = null, x = root;
- while (x != null) {
- y = x;
- if (z.task.getWhen() < x.task.getWhen()) {
- x = x.left;
- } else {
- x = x.right;
+ public void insert(TimerTask task) {
+ if (timers.length == size) {
+ TimerTask[] appendedTimers = new TimerTask[size * 2];
+ System.arraycopy(timers, 0, appendedTimers, 0, size);
+ timers = appendedTimers;
+ }
+ timers[size++] = task;
+ upHeap();
+ }
+
+ public void delete(int pos) {
+ // posible to delete any position of the heap
+ if (pos >= 0 && pos < size) {
+ timers[pos] = timers[--size];
+ timers[size] = null;
+ downHeap(pos);
+ }
+ }
+
+ private void upHeap() {
+ int current = size - 1;
+ int parent = (current - 1) / 2;
+
+ while (timers[current].when < timers[parent].when) {
+ // swap the two
+ TimerTask tmp = timers[current];
+ timers[current] = timers[parent];
+ timers[parent] = tmp;
+
+ // update pos and current
+ current = parent;
+ parent = (current - 1) / 2;
+ }
+ }
+
+ private void downHeap(int pos) {
+ int current = pos;
+ int child = 2 * current + 1;
+
+ while (child < size && size > 0) {
+ // compare the children if they exist
+ if (child + 1 < size
+ && timers[child + 1].when < timers[child].when) {
+ child++;
+ }
+
+ // compare selected child with parent
+ if (timers[current].when < timers[child].when) {
+ break;
+ }
+
+ // swap the two
+ TimerTask tmp = timers[current];
+ timers[current] = timers[child];
+ timers[child] = tmp;
+
+ // update pos and current
+ current = child;
+ child = 2 * current + 1;
+ }
+ }
+
+ public void reset() {
+ timers = new TimerTask[DEFAULT_HEAP_SIZE];
+ size = 0;
+ }
+
+ public void adjustMinimum() {
+ downHeap(0);
+ }
+
+ public void deleteIfCancelled() {
+ for (int i = 0; i < size; i++) {
+ if (timers[i].cancelled) {
+ deletedCancelledNumber++;
+ delete(i);
+ // re-try this point
+ i--;
}
}
- z.parent = y;
- if (y == null) {
- root = z;
- } else if (z.task.getWhen() < y.task.getWhen()) {
- y.left = z;
- } else {
- y.right = z;
- }
}
- void delete(TimerNode z) {
- TimerNode y = null, x = null;
- if (z.left == null || z.right == null) {
- y = z;
- } else {
- y = successor(z);
+ private int getTask(TimerTask task) {
+ for (int i = 0; i < timers.length; i++) {
+ if (timers[i] == task) {
+ return i;
+ }
}
- if (y.left != null) {
- x = y.left;
- } else {
- x = y.right;
- }
- if (x != null) {
- x.parent = y.parent;
- }
- if (y.parent == null) {
- root = x;
- } else if (y == y.parent.left) {
- y.parent.left = x;
- } else {
- y.parent.right = x;
- }
- if (y != z) {
- z.task = y.task;
- }
+ return -1;
}
- private TimerNode successor(TimerNode x) {
- if (x.right != null) {
- return minimum(x.right);
- }
- TimerNode y = x.parent;
- while (y != null && x == y.right) {
- x = y;
- y = y.parent;
- }
- return y;
- }
-
- private TimerNode minimum(TimerNode x) {
- while (x.left != null) {
- x = x.left;
- }
- return x;
- }
-
- TimerNode minimum() {
- return minimum(root);
- }
}
/**
@@ -185,11 +183,11 @@
* Vector consists of scheduled events, sorted according to
* {@code when} field of TaskScheduled object.
*/
- private TimerTree tasks = new TimerTree();
+ private TimerHeap tasks = new TimerHeap();
/**
* Starts a new timer.
- *
+ *
* @param isDaemon
*/
TimerImpl(boolean isDaemon) {
@@ -230,13 +228,12 @@
long currentTime = System.currentTimeMillis();
- TimerNode taskNode = tasks.minimum();
- task = taskNode.task;
+ task = tasks.minimum();
long timeToSleep;
synchronized (task.lock) {
if (task.cancelled) {
- tasks.delete(taskNode);
+ tasks.delete(0);
continue;
}
@@ -257,8 +254,12 @@
// no sleep is necessary before launching the task
synchronized (task.lock) {
+ int pos = 0;
+ if (tasks.minimum().when != task.when) {
+ pos = tasks.getTask(task);
+ }
if (task.cancelled) {
- tasks.delete(taskNode);
+ tasks.delete(tasks.getTask(task));
continue;
}
@@ -266,7 +267,7 @@
task.setScheduledTime(task.when);
// remove task from queue
- tasks.delete(taskNode);
+ tasks.delete(pos);
// set when the next task should be launched
if (task.period >= 0) {
@@ -299,7 +300,7 @@
private void insertTask(TimerTask newTask) {
// callers are synchronized
- tasks.insert(new TimerNode(newTask));
+ tasks.insert(newTask);
this.notify();
}
@@ -308,7 +309,7 @@
*/
public synchronized void cancel() {
cancelled = true;
- tasks = new TimerTree();
+ tasks.reset();
this.notify();
}
@@ -318,7 +319,7 @@
}
// callers are synchronized
tasks.deletedCancelledNumber = 0;
- tasks.root.deleteIfCancelled(tasks);
+ tasks.deleteIfCancelled();
return tasks.deletedCancelledNumber;
}
@@ -329,71 +330,72 @@
// Used to finalize thread
@SuppressWarnings("unused")
- private Object finalizer = new Object() { // $NON-LOCK-1$
- @Override
- protected void finalize() {
- synchronized (impl) {
- impl.finished = true;
- impl.notify();
- }
- }
- };
+ private final Object finalizer;
/**
* Creates a new {@code Timer} which may be specified to be run as a daemon thread.
- *
+ *
* @param isDaemon
* {@code true} if the {@code Timer}'s thread should be a daemon thread.
- * @since Android 1.0
*/
public Timer(boolean isDaemon) {
// BEGIN android-changed
impl = new TimerImpl("java.util.Timer", isDaemon);
// END android-changed
+ finalizer = newFinalizer();
}
/**
* Creates a new non-daemon {@code Timer}.
- *
- * @since Android 1.0
*/
public Timer() {
// BEGIN android-changed
impl = new TimerImpl("java.util.Timer", false);
// END android-changed
+ finalizer = newFinalizer();
}
/**
* Creates a new named {@code Timer} which may be specified to be run as a
* daemon thread.
- *
+ *
* @param name
* the name of the {@code Timer}.
* @param isDaemon
* true if {@code Timer}'s thread should be a daemon thread.
- * @since Android 1.0
*/
public Timer(String name, boolean isDaemon) {
impl = new TimerImpl(name, isDaemon);
+ finalizer = newFinalizer();
}
/**
* Creates a new named {@code Timer} which does not run as a daemon thread.
- *
+ *
* @param name
* the name of the Timer.
- * @since Android 1.0
*/
public Timer(String name) {
impl = new TimerImpl(name, false);
+ finalizer = newFinalizer();
+ }
+
+ private Object newFinalizer() {
+ return new Object() { // $NON-LOCK-1$
+ @Override
+ protected void finalize() {
+ synchronized (impl) {
+ impl.finished = true;
+ impl.notify();
+ }
+ }
+ };
}
/**
* Cancels the {@code Timer} and removes any scheduled tasks. If there is a
* currently running task it is not affected. No more tasks may be scheduled
* on this {@code Timer}. Subsequent calls do nothing.
- *
- * @since Android 1.0
*/
public void cancel() {
impl.cancel();
@@ -401,12 +403,11 @@
/**
* Removes all canceled tasks from the task queue. If there are no
- * other references on the tasks, then after this call they are free
+ * other references on the tasks, then after this call they are free
* to be garbage collected.
- *
+ *
* @return the number of canceled tasks that were removed from the task
* queue.
- * @since Android 1.0
*/
public int purge() {
synchronized (impl) {
@@ -417,17 +418,16 @@
/**
* Schedule a task for single execution. If {@code when} is less than the
* current time, it will be scheduled to be executed as soon as possible.
- *
+ *
* @param task
* the task to schedule.
* @param when
* time of execution.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code when.getTime() < 0}.
- * @exception IllegalStateException
+ * @throws IllegalStateException
* if the {@code Timer} has been canceled, or if the task has been
* scheduled or canceled.
- * @since Android 1.0
*/
public void schedule(TimerTask task, Date when) {
if (when.getTime() < 0) {
@@ -439,17 +439,16 @@
/**
* Schedule a task for single execution after a specified delay.
- *
+ *
* @param task
* the task to schedule.
* @param delay
* amount of time before execution.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code delay < 0}.
- * @exception IllegalStateException
+ * @throws IllegalStateException
* if the {@code Timer} has been canceled, or if the task has been
* scheduled or canceled.
- * @since Android 1.0
*/
public void schedule(TimerTask task, long delay) {
if (delay < 0) {
@@ -460,19 +459,18 @@
/**
* Schedule a task for repeated fixed-delay execution after a specific delay.
- *
+ *
* @param task
* the task to schedule.
* @param delay
* amount of time before first execution.
* @param period
* amount of time between subsequent executions.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code delay < 0} or {@code period < 0}.
- * @exception IllegalStateException
+ * @throws IllegalStateException
* if the {@code Timer} has been canceled, or if the task has been
* scheduled or canceled.
- * @since Android 1.0
*/
public void schedule(TimerTask task, long delay, long period) {
if (delay < 0 || period <= 0) {
@@ -484,19 +482,18 @@
/**
* Schedule a task for repeated fixed-delay execution after a specific time
* has been reached.
- *
+ *
* @param task
* the task to schedule.
* @param when
* time of first execution.
* @param period
* amount of time between subsequent executions.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code when.getTime() < 0} or {@code period < 0}.
- * @exception IllegalStateException
+ * @throws IllegalStateException
* if the {@code Timer} has been canceled, or if the task has been
* scheduled or canceled.
- * @since Android 1.0
*/
public void schedule(TimerTask task, Date when, long period) {
if (period <= 0 || when.getTime() < 0) {
@@ -509,19 +506,18 @@
/**
* Schedule a task for repeated fixed-rate execution after a specific delay
* has passed.
- *
+ *
* @param task
* the task to schedule.
* @param delay
* amount of time before first execution.
* @param period
* amount of time between subsequent executions.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code delay < 0} or {@code period < 0}.
- * @exception IllegalStateException
+ * @throws IllegalStateException
* if the {@code Timer} has been canceled, or if the task has been
* scheduled or canceled.
- * @since Android 1.0
*/
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (delay < 0 || period <= 0) {
@@ -533,19 +529,18 @@
/**
* Schedule a task for repeated fixed-rate execution after a specific time
* has been reached.
- *
+ *
* @param task
* the task to schedule.
* @param when
* time of first execution.
* @param period
* amount of time between subsequent executions.
- * @exception IllegalArgumentException
+ * @throws IllegalArgumentException
* if {@code when.getTime() < 0} or {@code period < 0}.
- * @exception IllegalStateException
+ * @throws IllegalStateException
* if the {@code Timer} has been canceled, or if the task has been
* scheduled or canceled.
- * @since Android 1.0
*/
public void scheduleAtFixedRate(TimerTask task, Date when, long period) {
if (period <= 0 || when.getTime() < 0) {
@@ -555,13 +550,8 @@
scheduleImpl(task, delay < 0 ? 0 : delay, period, true);
}
- /**
+ /*
* Schedule a task.
- *
- * @param task
- * @param delay
- * @param period
- * @param fixed
*/
private void scheduleImpl(TimerTask task, long delay, long period,
boolean fixed) {
diff --git a/luni/src/main/java/java/util/TimerTask.java b/luni/src/main/java/java/util/TimerTask.java
index 384746f..319ed58 100644
--- a/luni/src/main/java/java/util/TimerTask.java
+++ b/luni/src/main/java/java/util/TimerTask.java
@@ -23,7 +23,6 @@
*
* @see Timer
* @see java.lang.Object#wait(long)
- * @since Android 1.0
*/
public abstract class TimerTask implements Runnable {
/* Lock object for synchronization. It's also used by Timer class. */
@@ -77,8 +76,6 @@
/**
* Creates a new {@code TimerTask}.
- *
- * @since Android 1.0
*/
protected TimerTask() {
super();
@@ -91,7 +88,6 @@
*
* @return {@code true} if the call prevented a scheduled execution
* from taking place, {@code false} otherwise.
- * @since Android 1.0
*/
public boolean cancel() {
synchronized (lock) {
@@ -107,7 +103,6 @@
* have not yet run return an undefined value.
*
* @return the most recent execution time.
- * @since Android 1.0
*/
public long scheduledExecutionTime() {
synchronized (lock) {
@@ -118,8 +113,6 @@
/**
* The task to run should be specified in the implementation of the {@code run()}
* method.
- *
- * @since Android 1.0
*/
public abstract void run();
diff --git a/luni/src/main/java/java/util/TooManyListenersException.java b/luni/src/main/java/java/util/TooManyListenersException.java
index 32b2133..8c044c0 100644
--- a/luni/src/main/java/java/util/TooManyListenersException.java
+++ b/luni/src/main/java/java/util/TooManyListenersException.java
@@ -22,8 +22,6 @@
* A {@code TooManyListenersException} is thrown when an attempt is made to add
* more than one listener to an event source which only supports a single
* listener. It is also thrown when the same listener is added more than once.
- *
- * @since Android 1.0
*/
public class TooManyListenersException extends Exception {
diff --git a/luni/src/main/java/java/util/TreeMap.java b/luni/src/main/java/java/util/TreeMap.java
index e3dc5a7..b97821f 100644
--- a/luni/src/main/java/java/util/TreeMap.java
+++ b/luni/src/main/java/java/util/TreeMap.java
@@ -27,43 +27,124 @@
* and removing) are supported. The values can be any objects. The keys can be
* any objects which are comparable to each other either using their natural
* order or a specified Comparator.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
-public class TreeMap<K, V> extends AbstractMap<K, V> implements SortedMap<K, V>, Cloneable,
- Serializable {
+public class TreeMap <K, V> extends AbstractMap<K, V> implements SortedMap<K, V>,
+ Cloneable, Serializable {
private static final long serialVersionUID = 919286545866124006L;
transient int size;
- transient Entry<K, V> root;
-
private Comparator<? super K> comparator;
transient int modCount;
transient Set<Map.Entry<K, V>> entrySet;
- /**
- * Entry is an internal class which is used to hold the entries of a
- * TreeMap.
- */
- static class Entry<K, V> extends MapEntry<K, V> {
- Entry<K, V> parent, left, right;
+ transient Node<K, V> root;
+
+class MapEntry implements Map.Entry<K, V>, Cloneable {
+
+ final int offset;
+ final Node<K, V> node;
+ final K key;
+
+ MapEntry(Node<K, V> node, int offset) {
+ this.node = node;
+ this.offset = offset;
+ key = node.keys[offset];
+ }
+ @Override
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object instanceof Map.Entry) {
+ Map.Entry<?, ?> entry = (Map.Entry<?, ?>) object;
+ V value = getValue();
+ return (key == null ? entry.getKey() == null : key.equals(entry
+ .getKey()))
+ && (value == null ? entry.getValue() == null : value
+ .equals(entry.getValue()));
+ }
+ return false;
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ if (node.keys[offset] == key) {
+ return node.values[offset];
+ }
+ if (containsKey(key)) {
+ return get(key);
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public int hashCode() {
+ V value = getValue();
+ return (key == null ? 0 : key.hashCode())
+ ^ (value == null ? 0 : value.hashCode());
+ }
+
+ public V setValue(V object) {
+ if (node.keys[offset] == key) {
+ V res = node.values[offset];
+ node.values[offset] = object;
+ return res;
+ }
+ if (containsKey(key)) {
+ return put(key, object);
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public String toString() {
+ return key + "=" + getValue();
+ }
+ }
+
+ static class Node <K,V> implements Cloneable {
+ static final int NODE_SIZE = 64;
+ Node<K, V> prev, next;
+ Node<K, V> parent, left, right;
+ V[] values;
+ K[] keys;
+ int left_idx = 0;
+ int right_idx = -1;
+ int size = 0;
boolean color;
- Entry(K key) {
- super(key);
- }
-
- Entry(K key, V value) {
- super(key, value);
+ public Node() {
+ keys = (K[]) new Object[NODE_SIZE];
+ values = (V[]) new Object[NODE_SIZE];
}
@SuppressWarnings("unchecked")
- Entry<K, V> clone(Entry<K, V> parent) {
- Entry<K, V> clone = (Entry<K, V>) super.clone();
+ Node<K, V> clone(Node<K, V> parent) throws CloneNotSupportedException {
+ Node<K, V> clone = (Node<K, V>) super.clone();
+ clone.keys = (K[]) new Object[NODE_SIZE];
+ clone.values = (V[]) new Object[NODE_SIZE];
+ System.arraycopy(keys, 0, clone.keys, 0, keys.length);
+ System.arraycopy(values, 0, clone.values, 0, values.length);
+ clone.left_idx = left_idx;
+ clone.right_idx = right_idx;
clone.parent = parent;
if (left != null) {
clone.left = left.clone(clone);
@@ -71,45 +152,45 @@
if (right != null) {
clone.right = right.clone(clone);
}
+ clone.prev = null;
+ clone.next = null;
return clone;
}
}
-
+
@SuppressWarnings("unchecked")
- private static <T> Comparable<T> toComparable(T obj) {
- return (Comparable<T>)obj;
+ private static <T> Comparable<T> toComparable(T obj) {
+ return (Comparable) obj;
}
- private static class AbstractMapIterator <K,V> {
+ static class AbstractMapIterator <K,V> {
TreeMap<K, V> backingMap;
int expectedModCount;
- TreeMap.Entry<K, V> node;
- TreeMap.Entry<K, V> lastNode;
+ Node<K, V> node;
+ Node<K, V> lastNode;
+ int offset;
+ int lastOffset;
- AbstractMapIterator(TreeMap<K, V> map, Entry<K, V> startNode) {
+ AbstractMapIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
backingMap = map;
expectedModCount = map.modCount;
node = startNode;
+ offset = startOffset;
+ }
+
+ AbstractMapIterator(TreeMap<K, V> map, Node<K, V> startNode) {
+ this(map, startNode, startNode != null ?
+ startNode.right_idx - startNode.left_idx : 0);
+ }
+
+ AbstractMapIterator(TreeMap<K, V> map) {
+ this(map, minimum(map.root));
}
public boolean hasNext() {
return node != null;
}
- final public void remove() {
- if (expectedModCount == backingMap.modCount) {
- if (lastNode != null) {
- backingMap.rbDelete(lastNode);
- lastNode = null;
- expectedModCount++;
- } else {
- throw new IllegalStateException();
- }
- } else {
- throw new ConcurrentModificationException();
- }
- }
-
final void makeNext() {
if (expectedModCount != backingMap.modCount) {
throw new ConcurrentModificationException();
@@ -117,564 +198,777 @@
throw new NoSuchElementException();
}
lastNode = node;
- node = TreeMap.successor(node);
+ lastOffset = offset;
+ if (offset != 0) {
+ offset--;
+ } else {
+ node = node.next;
+ if (node != null) {
+ offset = node.right_idx - node.left_idx;
+ }
}
}
- private static class UnboundedEntryIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<Map.Entry<K, V>> {
-
- UnboundedEntryIterator(TreeMap<K, V> map, Entry<K, V> startNode) {
- super(map, startNode);
- }
-
- UnboundedEntryIterator(TreeMap<K, V> map) {
- super(map, map.root == null ? null : TreeMap.minimum(map.root));
- }
-
- public Map.Entry<K, V> next() {
- makeNext();
- return lastNode;
+ final public void remove() {
+ if (expectedModCount == backingMap.modCount) {
+ if (lastNode != null) {
+ int idx = lastNode.right_idx - lastOffset;
+ backingMap.removeFromIterator(lastNode, idx);
+ lastNode = null;
+ expectedModCount++;
+ } else {
+ throw new IllegalStateException();
+ }
+ } else {
+ throw new ConcurrentModificationException();
}
}
+ }
- static class UnboundedKeyIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<K> {
- public UnboundedKeyIterator(TreeMap<K, V> treeMap, Entry<K, V> entry) {
- super(treeMap, entry);
- }
+ static class UnboundedEntryIterator <K, V> extends AbstractMapIterator<K, V>
+ implements Iterator<Map.Entry<K, V>> {
- public UnboundedKeyIterator(TreeMap<K, V> map) {
- super(map, map.root == null ? null : TreeMap.minimum(map.root));
- }
-
- public K next() {
- makeNext();
- return lastNode.key;
- }
+ UnboundedEntryIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
+ super(map, startNode, startOffset);
}
- static class UnboundedValueIterator <K, V> extends AbstractMapIterator<K, V> implements Iterator<V> {
-
- public UnboundedValueIterator(TreeMap<K, V> treeMap, Entry<K, V> startNode) {
- super(treeMap, startNode);
- }
-
- public UnboundedValueIterator(TreeMap<K, V> map) {
- super(map, map.root == null ? null : TreeMap.minimum(map.root));
- }
-
- public V next() {
- makeNext();
- return lastNode.value;
- }
+ UnboundedEntryIterator(TreeMap<K, V> map) {
+ super(map);
}
- private static class ComparatorBoundedIterator<K, V> extends AbstractMapIterator<K, V> {
- private final K endKey;
+ public Map.Entry<K, V> next() {
+ makeNext();
+ int idx = lastNode.right_idx - lastOffset;
+ return backingMap.new MapEntry(lastNode, idx);
+ }
+ }
- private final Comparator<? super K> cmp;
+ static class UnboundedKeyIterator <K, V> extends AbstractMapIterator<K, V>
+ implements Iterator<K> {
- ComparatorBoundedIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
- super(map, startNode);
+ UnboundedKeyIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
+ super(map, startNode, startOffset);
+ }
+
+ UnboundedKeyIterator(TreeMap<K, V> map) {
+ super(map);
+ }
+
+ public K next() {
+ makeNext();
+ return lastNode.keys[lastNode.right_idx - lastOffset];
+ }
+ }
+
+ static class UnboundedValueIterator <K, V> extends AbstractMapIterator<K, V>
+ implements Iterator<V> {
+
+ UnboundedValueIterator(TreeMap<K, V> map, Node<K, V> startNode, int startOffset) {
+ super(map, startNode, startOffset);
+ }
+
+ UnboundedValueIterator(TreeMap<K, V> map) {
+ super(map);
+ }
+
+ public V next() {
+ makeNext();
+ return lastNode.values[lastNode.right_idx - lastOffset];
+ }
+ }
+
+ static class BoundedMapIterator <K, V> extends AbstractMapIterator<K, V> {
+
+ Node<K, V> finalNode;
+ int finalOffset;
+
+ BoundedMapIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
+ Node<K, V> finalNode, int finalOffset) {
+ super(map, finalNode==null? null : startNode, startOffset);
+ this.finalNode = finalNode;
+ this.finalOffset = finalOffset;
+ }
+
+ BoundedMapIterator(Node<K, V> startNode, TreeMap<K, V> map,
+ Node<K, V> finalNode, int finalOffset) {
+ this(startNode, startNode != null ?
+ startNode.right_idx - startNode.left_idx : 0,
+ map, finalNode, finalOffset);
+ }
+
+ BoundedMapIterator(Node<K, V> startNode, int startOffset,
+ TreeMap<K, V> map, Node<K, V> finalNode) {
+ this(startNode, startOffset, map, finalNode,
+ finalNode.right_idx - finalNode.left_idx);
+ }
+
+ void makeBoundedNext() {
+ makeNext();
+ if (lastNode == finalNode && lastOffset == finalOffset) {
+ node = null;
+ }
+ }
+ }
+
+ static class BoundedEntryIterator <K, V> extends BoundedMapIterator<K, V>
+ implements Iterator<Map.Entry<K, V>> {
+
+ public BoundedEntryIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
+ Node<K, V> finalNode, int finalOffset) {
+ super(startNode, startOffset, map, finalNode, finalOffset);
+ }
+
+ public Map.Entry<K, V> next() {
+ makeBoundedNext();
+ int idx = lastNode.right_idx - lastOffset;
+ return backingMap.new MapEntry(lastNode, idx);
+ }
+ }
+
+ static class BoundedKeyIterator <K, V> extends BoundedMapIterator<K, V>
+ implements Iterator<K> {
+
+ public BoundedKeyIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
+ Node<K, V> finalNode, int finalOffset) {
+ super(startNode, startOffset, map, finalNode, finalOffset);
+ }
+
+ public K next() {
+ makeBoundedNext();
+ return lastNode.keys[lastNode.right_idx - lastOffset];
+ }
+ }
+
+ static class BoundedValueIterator <K, V> extends BoundedMapIterator<K, V>
+ implements Iterator<V> {
+
+ public BoundedValueIterator(Node<K, V> startNode, int startOffset, TreeMap<K, V> map,
+ Node<K, V> finalNode, int finalOffset) {
+ super(startNode, startOffset, map, finalNode, finalOffset);
+ }
+
+ public V next() {
+ makeBoundedNext();
+ return lastNode.values[lastNode.right_idx - lastOffset];
+ }
+ }
+
+ static final class SubMap <K,V> extends AbstractMap<K, V>
+ implements SortedMap<K, V>, Serializable {
+ private static final long serialVersionUID = -6520786458950516097L;
+
+ private TreeMap<K, V> backingMap;
+
+ boolean hasStart, hasEnd;
+ K startKey, endKey;
+ transient Set<Map.Entry<K, V>> entrySet = null;
+ transient int firstKeyModCount = -1;
+ transient int lastKeyModCount = -1;
+ transient Node<K, V> firstKeyNode;
+ transient int firstKeyIndex;
+ transient Node<K, V> lastKeyNode;
+ transient int lastKeyIndex;
+
+ SubMap(K start, TreeMap<K, V> map) {
+ backingMap = map;
+ hasStart = true;
+ startKey = start;
+ }
+
+ SubMap(K start, TreeMap<K, V> map, K end) {
+ backingMap = map;
+ hasStart = hasEnd = true;
+ startKey = start;
endKey = end;
- cmp = map.comparator();
}
- final void cleanNext() {
- if (node != null && cmp.compare(endKey, node.key) <= 0) {
- node = null;
+ SubMap(TreeMap<K, V> map, K end) {
+ backingMap = map;
+ hasEnd = true;
+ endKey = end;
+ }
+
+ private void checkRange(K key) {
+ Comparator<? super K> cmp = backingMap.comparator;
+ if (cmp == null) {
+ Comparable<K> object = toComparable(key);
+ if (hasStart && object.compareTo(startKey) < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (hasEnd && object.compareTo(endKey) > 0) {
+ throw new IllegalArgumentException();
+ }
+ } else {
+ if (hasStart
+ && backingMap.comparator().compare(key, startKey) < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (hasEnd && backingMap.comparator().compare(key, endKey) > 0) {
+ throw new IllegalArgumentException();
+ }
}
}
+ private boolean isInRange(K key) {
+ Comparator<? super K> cmp = backingMap.comparator;
+ if (cmp == null) {
+ Comparable<K> object = toComparable(key);
+ if (hasStart && object.compareTo(startKey) < 0) {
+ return false;
+ }
+ if (hasEnd && object.compareTo(endKey) >= 0) {
+ return false;
+ }
+ } else {
+ if (hasStart && cmp.compare(key, startKey) < 0) {
+ return false;
+ }
+ if (hasEnd && cmp.compare(key, endKey) >= 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean checkUpperBound(K key) {
+ if (hasEnd) {
+ Comparator<? super K> cmp = backingMap.comparator;
+ if (cmp == null) {
+ return (toComparable(key).compareTo(endKey) < 0);
+ }
+ return (cmp.compare(key, endKey) < 0);
+ }
+ return true;
+ }
+
+ private boolean checkLowerBound(K key) {
+ if (hasStart) {
+ Comparator<? super K> cmp = backingMap.comparator;
+ if (cmp == null) {
+ return (toComparable(key).compareTo(startKey) >= 0);
+ }
+ return (cmp.compare(key, startKey) >= 0);
+ }
+ return true;
+ }
+
+ public Comparator<? super K> comparator() {
+ return backingMap.comparator();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean containsKey(Object key) {
+ if (isInRange((K) key)) {
+ return backingMap.containsKey(key);
+ }
+ return false;
+ }
+
@Override
- public boolean hasNext() {
- return (node != null && endKey != null) && (cmp.compare(node.key, endKey) < 0);
- }
- }
-
- private static class ComparatorBoundedEntryIterator<K, V> extends
- ComparatorBoundedIterator<K, V> implements Iterator<Map.Entry<K, V>> {
-
- ComparatorBoundedEntryIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
- super(map, startNode, end);
- }
-
- public Map.Entry<K, V> next() {
- makeNext();
- cleanNext();
- return lastNode;
- }
- }
-
- private static class ComparatorBoundedKeyIterator<K, V> extends
- ComparatorBoundedIterator<K, V> implements Iterator<K> {
-
- ComparatorBoundedKeyIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
- super(map, startNode, end);
- }
-
- public K next() {
- makeNext();
- cleanNext();
- return lastNode.key;
- }
- }
-
- private static class ComparatorBoundedValueIterator<K, V> extends
- ComparatorBoundedIterator<K, V> implements Iterator<V> {
-
- ComparatorBoundedValueIterator(TreeMap<K, V> map, Entry<K, V> startNode, K end) {
- super(map, startNode, end);
- }
-
- public V next() {
- makeNext();
- cleanNext();
- return lastNode.value;
- }
- }
-
- private static class ComparableBoundedIterator<K, V> extends AbstractMapIterator<K, V> {
- private final Comparable<K> endKey;
-
- public ComparableBoundedIterator(TreeMap<K, V> treeMap, Entry<K, V> entry,
- Comparable<K> endKey) {
- super(treeMap, entry);
- this.endKey = endKey;
- }
-
- final void cleanNext() {
- if ((node != null) && (endKey.compareTo(node.key) <= 0)) {
- node = null;
- }
+ public void clear() {
+ keySet().clear();
}
@Override
- public boolean hasNext() {
- return (node != null) && (endKey.compareTo(node.key) > 0);
- }
- }
-
- private static class ComparableBoundedEntryIterator<K, V> extends
- ComparableBoundedIterator<K, V> implements Iterator<Map.Entry<K, V>> {
-
- ComparableBoundedEntryIterator(TreeMap<K, V> map, Entry<K, V> startNode,
- Comparable<K> end) {
- super(map, startNode, end);
- }
-
- public Map.Entry<K, V> next() {
- makeNext();
- cleanNext();
- return lastNode;
- }
-
- }
-
- private static class ComparableBoundedKeyIterator<K, V> extends
- ComparableBoundedIterator<K, V> implements Iterator<K> {
-
- ComparableBoundedKeyIterator(TreeMap<K, V> map, Entry<K, V> startNode, Comparable<K> end) {
- super(map, startNode, end);
- }
-
- public K next() {
- makeNext();
- cleanNext();
- return lastNode.key;
- }
- }
-
- private static class ComparableBoundedValueIterator<K, V> extends
- ComparableBoundedIterator<K, V> implements Iterator<V> {
-
- ComparableBoundedValueIterator(TreeMap<K, V> map, Entry<K, V> startNode,
- Comparable<K> end) {
- super(map, startNode, end);
- }
-
- public V next() {
- makeNext();
- cleanNext();
- return lastNode.value;
- }
- }
-
- static final class SubMap<K,V> extends AbstractMap<K,V> implements SortedMap<K,V>, Serializable {
- private static final long serialVersionUID = -6520786458950516097L;
-
- private TreeMap<K,V> backingMap;
-
- boolean hasStart, hasEnd;
-
- K startKey, endKey;
-
- transient Set<Map.Entry<K,V>> entrySet = null;
-
- SubMap(K start, TreeMap<K,V> map) {
- backingMap = map;
- hasStart = true;
- startKey = start;
- }
-
- SubMap(K start, TreeMap<K,V> map, K end) {
- backingMap = map;
- hasStart = hasEnd = true;
- startKey = start;
- endKey = end;
- }
-
- SubMap(TreeMap<K,V> map, K end) {
- backingMap = map;
- hasEnd = true;
- endKey = end;
- }
-
- private void checkRange(K key) {
- Comparator<? super K> cmp = backingMap.comparator;
- if (cmp == null) {
- Comparable<K> object = toComparable(key);
- if (hasStart && object.compareTo(startKey) < 0) {
- throw new IllegalArgumentException();
+ public boolean containsValue(Object value) {
+ Iterator<V> it = values().iterator();
+ if (value != null) {
+ while (it.hasNext()) {
+ if (value.equals(it.next())) {
+ return true;
}
- if (hasEnd && object.compareTo(endKey) > 0) {
- throw new IllegalArgumentException();
+ }
+ } else {
+ while (it.hasNext()) {
+ if (it.next() == null) {
+ return true;
}
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ if (entrySet == null) {
+ entrySet = new SubMapEntrySet<K, V>(this);
+ }
+ return entrySet;
+ }
+
+ private void setFirstKey() {
+ if (firstKeyModCount == backingMap.modCount) {
+ return;
+ }
+ Comparable<K> object = backingMap.comparator == null ?
+ toComparable((K) startKey) : null;
+ K key = (K) startKey;
+ Node<K, V> node = backingMap.root;
+ Node<K, V> foundNode = null;
+ int foundIndex = -1;
+ TOP_LOOP:
+ while (node != null) {
+ K[] keys = node.keys;
+ int left_idx = node.left_idx;
+ int result = backingMap.cmp(object, key, keys[left_idx]);
+ if (result < 0) {
+ foundNode = node;
+ foundIndex = left_idx;
+ node = node.left;
+ } else if (result == 0) {
+ foundNode = node;
+ foundIndex = left_idx;
+ break;
} else {
- if (hasStart
- && backingMap.comparator().compare(key, startKey) < 0) {
- throw new IllegalArgumentException();
+ int right_idx = node.right_idx;
+ if (left_idx != right_idx) {
+ result = backingMap.cmp(object, key, keys[right_idx]);
}
- if (hasEnd && backingMap.comparator().compare(key, endKey) > 0) {
- throw new IllegalArgumentException();
+ if (result > 0) {
+ node = node.right;
+ } else if (result == 0) {
+ foundNode = node;
+ foundIndex = right_idx;
+ break;
+ } else { /*search in node*/
+ foundNode = node;
+ foundIndex = right_idx;
+ int low = left_idx + 1, mid = 0, high = right_idx - 1;
+ while (low <= high) {
+ mid = (low + high) >> 1;
+ result = backingMap.cmp(object, key, keys[mid]);
+ if (result > 0) {
+ low = mid + 1;
+ } else if (result == 0) {
+ foundNode = node;
+ foundIndex = mid;
+ break TOP_LOOP;
+ } else {
+ foundNode = node;
+ foundIndex = mid;
+ high = mid - 1;
+ }
+ }
+ break TOP_LOOP;
}
}
}
-
- private boolean isInRange(K key) {
- Comparator<? super K> cmp = backingMap.comparator;
- if (cmp == null) {
- Comparable<K> object = toComparable(key);
- if (hasStart && object.compareTo(startKey) < 0) {
- return false;
- }
- if (hasEnd && object.compareTo(endKey) >= 0) {
- return false;
- }
- } else {
- if (hasStart && cmp.compare(key, startKey) < 0) {
- return false;
- }
- if (hasEnd && cmp.compare(key, endKey) >= 0) {
- return false;
- }
- }
- return true;
+ if (foundNode != null && !checkUpperBound(foundNode.keys[foundIndex])) {
+ foundNode = null;
}
+ firstKeyNode = foundNode;
+ firstKeyIndex = foundIndex;
+ firstKeyModCount = backingMap.modCount;
+ }
- private boolean checkUpperBound(K key) {
- if (hasEnd) {
- Comparator<? super K> cmp = backingMap.comparator;
- if (cmp == null) {
- return (toComparable(key).compareTo(endKey) < 0);
- }
- return (cmp.compare(key, endKey) < 0);
- }
- return true;
- }
-
- private boolean checkLowerBound(K key) {
- if (hasStart) {
- Comparator<? super K> cmp = backingMap.comparator;
- if (cmp == null) {
- return (toComparable(key).compareTo(startKey) >= 0);
- }
- return (cmp.compare(key, startKey) >= 0);
- }
- return true;
- }
-
- public Comparator<? super K> comparator() {
- return backingMap.comparator();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public boolean containsKey(Object key) {
- if (isInRange((K)key)) {
- return backingMap.containsKey(key);
- }
- return false;
- }
-
- @Override
- public Set<Map.Entry<K,V>> entrySet() {
- if(entrySet==null) {
- entrySet = new SubMapEntrySet<K,V>(this);
- }
- return entrySet;
- }
-
- public K firstKey() {
- TreeMap.Entry<K,V> node = firstEntry();
- if (node != null ) {
- return node.key;
- }
- throw new NoSuchElementException();
- }
-
- TreeMap.Entry<K,V> firstEntry() {
+ public K firstKey() {
+ if (backingMap.size > 0) {
if (!hasStart) {
- TreeMap.Entry<K,V> root = backingMap.root;
- return (root == null) ? null : minimum(backingMap.root);
- }
- TreeMap.Entry<K,V> node = backingMap.findAfter(startKey);
- if (node != null && checkUpperBound(node.key)) {
- return node;
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public V get(Object key) {
- if (isInRange((K)key)) {
- return backingMap.get(key);
- }
- return null;
- }
-
- public SortedMap<K,V> headMap(K endKey) {
- checkRange(endKey);
- if (hasStart) {
- return new SubMap<K,V>(startKey, backingMap, endKey);
- }
- return new SubMap<K,V>(backingMap, endKey);
- }
-
- @Override
- public boolean isEmpty() {
- if (hasStart) {
- TreeMap.Entry<K,V> node = backingMap.findAfter(startKey);
- return node == null || !checkUpperBound(node.key);
- }
- return backingMap.findBefore(endKey) == null;
- }
-
- @Override
- public Set<K> keySet() {
- if (keySet == null) {
- keySet = new SubMapKeySet<K,V>(this);
- }
- return keySet;
- }
-
- public K lastKey() {
- if (!hasEnd) {
- return backingMap.lastKey();
- }
- TreeMap.Entry<K,V> node = backingMap.findBefore(endKey);
- if (node != null && checkLowerBound(node.key)) {
- return node.key;
- }
- throw new NoSuchElementException();
- }
-
- @Override
- public V put(K key, V value) {
- if (isInRange(key)) {
- return backingMap.put(key, value);
- }
- throw new IllegalArgumentException();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public V remove(Object key) {
- if (isInRange((K)key)) {
- return backingMap.remove(key);
- }
- return null;
- }
-
- public SortedMap<K,V> subMap(K startKey, K endKey) {
- checkRange(startKey);
- checkRange(endKey);
- Comparator<? super K> c = backingMap.comparator();
- if (c == null) {
- if (toComparable(startKey).compareTo(endKey) <= 0) {
- return new SubMap<K,V>(startKey, backingMap, endKey);
+ Node<K, V> node = minimum(backingMap.root);
+ if (node != null && checkUpperBound(node.keys[node.left_idx])) {
+ return node.keys[node.left_idx];
}
} else {
- if (c.compare(startKey, endKey) <= 0) {
- return new SubMap<K,V>(startKey, backingMap, endKey);
+ setFirstKey();
+ if (firstKeyNode != null) {
+ return firstKeyNode.keys[firstKeyIndex];
}
}
- throw new IllegalArgumentException();
}
+ throw new NoSuchElementException();
+ }
- public SortedMap<K,V> tailMap(K startKey) {
- checkRange(startKey);
- if (hasEnd) {
- return new SubMap<K,V>(startKey, backingMap, endKey);
- }
- return new SubMap<K,V>(startKey, backingMap);
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public V get(Object key) {
+ if (isInRange((K) key)) {
+ return backingMap.get(key);
}
+ return null;
+ }
- @Override
- public Collection<V> values() {
- if(valuesCollection==null) {
- valuesCollection = new SubMapValuesCollection<K,V>(this);
- }
- return valuesCollection;
+ public SortedMap<K, V> headMap(K endKey) {
+ checkRange(endKey);
+ if (hasStart) {
+ return new SubMap<K, V>(startKey, backingMap, endKey);
+ }
+ return new SubMap<K, V>(backingMap, endKey);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ if (hasStart) {
+ setFirstKey();
+ return firstKeyNode == null;
+ } else {
+ setLastKey();
+ return lastKeyNode == null;
}
}
- static class SubMapEntrySet<K,V> extends AbstractSet<Map.Entry<K,V>> implements Set<Map.Entry<K,V>> {
- SubMap<K,V> subMap;
-
- SubMapEntrySet(SubMap<K,V> map) {
- subMap = map;
+ @Override
+ public Set<K> keySet() {
+ if (keySet == null) {
+ keySet = new SubMapKeySet<K, V>(this);
}
-
- @Override
- public boolean isEmpty() {
- return subMap.isEmpty();
- }
-
- @Override
- public Iterator<Map.Entry<K,V>> iterator() {
- TreeMap.Entry<K,V> startNode = subMap.firstEntry();
- if (subMap.hasEnd) {
- Comparator<? super K> cmp = subMap.comparator();
- if (cmp == null) {
- return new ComparableBoundedEntryIterator<K,V>(subMap.backingMap, startNode, toComparable(subMap.endKey));
- }
- return new ComparatorBoundedEntryIterator<K,V>(subMap.backingMap, startNode, subMap.endKey);
- }
- return new UnboundedEntryIterator<K,V>(subMap.backingMap, startNode);
- }
-
- @Override
- public int size() {
- int size = 0;
- Iterator<Map.Entry<K,V>> it = iterator();
- while (it.hasNext()) {
- size++;
- it.next();
- }
- return size;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public boolean contains(Object object) {
- if (object instanceof Map.Entry) {
- Map.Entry<K,V> entry = (Map.Entry<K,V>) object;
- K key = entry.getKey();
- if (subMap.isInRange(key)) {
- V v1 = subMap.get(key), v2 = entry.getValue();
- return v1 == null ? v2 == null : v1.equals(v2);
- }
- }
- return false;
- }
-
+ return keySet;
}
- static class SubMapKeySet<K,V> extends AbstractSet<K> implements Set<K> {
- SubMap<K,V> subMap;
-
- SubMapKeySet(SubMap<K,V> map) {
- subMap = map;
+ private void setLastKey() {
+ if (lastKeyModCount == backingMap.modCount) {
+ return;
}
-
- @Override
- public boolean contains(Object object) {
- return subMap.containsKey(object);
- }
-
- @Override
- public boolean isEmpty() {
- return subMap.isEmpty();
- }
-
- @Override
- public int size() {
- int size = 0;
- Iterator<K> it = iterator();
- while (it.hasNext()) {
- size++;
- it.next();
- }
- return size;
- }
-
- @Override
- public Iterator<K> iterator() {
- TreeMap.Entry<K,V> startNode = subMap.firstEntry();
- if (subMap.hasEnd) {
- Comparator<? super K> cmp = subMap.comparator();
- if (cmp == null) {
- return new ComparableBoundedKeyIterator<K,V>(subMap.backingMap, startNode, toComparable(subMap.endKey));
+ Comparable<K> object = backingMap.comparator == null ?
+ toComparable((K) endKey) : null;
+ K key = (K) endKey;
+ Node<K, V> node = backingMap.root;
+ Node<K, V> foundNode = null;
+ int foundIndex = -1;
+ TOP_LOOP:
+ while (node != null) {
+ K[] keys = node.keys;
+ int left_idx = node.left_idx;
+ int result = backingMap.cmp(object, key, keys[left_idx]);
+ if (result <= 0) {
+ node = node.left;
+ } else {
+ int right_idx = node.right_idx;
+ if (left_idx != right_idx) {
+ result = backingMap.cmp(object, key, keys[right_idx]);
}
- return new ComparatorBoundedKeyIterator<K,V>(subMap.backingMap, startNode, subMap.endKey);
+ if (result > 0) {
+ foundNode = node;
+ foundIndex = right_idx;
+ node = node.right;
+ } else if (result == 0) {
+ if (node.left_idx == node.right_idx) {
+ foundNode = node.prev;
+ if (foundNode != null) {
+ foundIndex = foundNode.right_idx - 1;
+ }
+ } else {
+ foundNode = node;
+ foundIndex = right_idx - 1;
+ }
+ break;
+ } else { /*search in node*/
+ foundNode = node;
+ foundIndex = left_idx;
+ int low = left_idx + 1, mid = 0, high = right_idx - 1;
+ while (low <= high) {
+ mid = (low + high) >> 1;
+ result = backingMap.cmp(object, key, keys[mid]);
+ if (result > 0) {
+ foundNode = node;
+ foundIndex = mid;
+ low = mid + 1;
+ } else if (result == 0) {
+ foundNode = node;
+ foundIndex = mid - 1;
+ break TOP_LOOP;
+ } else {
+ high = mid - 1;
+ }
+ }
+ break TOP_LOOP;
+ }
}
- return new UnboundedKeyIterator<K,V>(subMap.backingMap, startNode);
}
+ if (foundNode != null && !checkLowerBound(foundNode.keys[foundIndex])) {
+ foundNode = null;
+ }
+ lastKeyNode = foundNode;
+ lastKeyIndex = foundIndex;
+ lastKeyModCount = backingMap.modCount;
}
- static class SubMapValuesCollection<K,V> extends AbstractCollection<V> {
- SubMap<K,V> subMap;
-
- public SubMapValuesCollection(SubMap<K,V> subMap) {
- this.subMap = subMap;
- }
-
- @Override
- public boolean isEmpty() {
- return subMap.isEmpty();
- }
-
- @Override
- public Iterator<V> iterator() {
- TreeMap.Entry<K,V> startNode = subMap.firstEntry();
- if (subMap.hasEnd) {
- Comparator<? super K> cmp = subMap.comparator();
- if (cmp == null) {
- return new ComparableBoundedValueIterator<K,V>(subMap.backingMap, startNode, toComparable(subMap.endKey));
+ public K lastKey() {
+ if (backingMap.size > 0) {
+ if (!hasEnd) {
+ Node<K, V> node = maximum(backingMap.root);
+ if (node != null && checkLowerBound(node.keys[node.right_idx])) {
+ return node.keys[node.right_idx];
}
- return new ComparatorBoundedValueIterator<K,V>(subMap.backingMap, startNode, subMap.endKey);
+ } else {
+ setLastKey();
+ if (lastKeyNode != null) {
+ return lastKeyNode.keys[lastKeyIndex];
+ }
}
- return new UnboundedValueIterator<K,V>(subMap.backingMap, startNode);
}
-
- @Override
- public int size() {
- int cnt = 0;
- for (Iterator<V> it = iterator(); it.hasNext();) {
- it.next();
- cnt++;
- }
- return cnt;
- }
+ throw new NoSuchElementException();
}
+
+ @Override
+ public V put(K key, V value) {
+ if (isInRange(key)) {
+ return backingMap.put(key, value);
+ }
+ throw new IllegalArgumentException();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public V remove(Object key) {
+ if (isInRange((K) key)) {
+ return backingMap.remove(key);
+ }
+ return null;
+ }
+
+ public SortedMap<K, V> subMap(K startKey, K endKey) {
+ checkRange(startKey);
+ checkRange(endKey);
+ Comparator<? super K> c = backingMap.comparator();
+ if (c == null) {
+ if (toComparable(startKey).compareTo(endKey) <= 0) {
+ return new SubMap<K, V>(startKey, backingMap, endKey);
+ }
+ } else {
+ if (c.compare(startKey, endKey) <= 0) {
+ return new SubMap<K, V>(startKey, backingMap, endKey);
+ }
+ }
+ throw new IllegalArgumentException();
+ }
+
+ public SortedMap<K, V> tailMap(K startKey) {
+ checkRange(startKey);
+ if (hasEnd) {
+ return new SubMap<K, V>(startKey, backingMap, endKey);
+ }
+ return new SubMap<K, V>(startKey, backingMap);
+ }
+
+ @Override
+ public Collection<V> values() {
+ if (valuesCollection == null) {
+ valuesCollection = new SubMapValuesCollection<K, V>(this);
+ }
+ return valuesCollection;
+ }
+
+ public int size() {
+ Node<K, V> from, to;
+ int fromIndex, toIndex;
+ if (hasStart) {
+ setFirstKey();
+ from = firstKeyNode;
+ fromIndex = firstKeyIndex;
+ } else {
+ from = minimum(backingMap.root);
+ fromIndex = from == null ? 0 : from.left_idx;
+ }
+ if (from == null) {
+ return 0;
+ }
+ if (hasEnd) {
+ setLastKey();
+ to = lastKeyNode;
+ toIndex = lastKeyIndex;
+ } else {
+ to = maximum(backingMap.root);
+ toIndex = to == null ? 0 : to.right_idx;
+ }
+ if (to == null) {
+ return 0;
+ }
+ if (from == to) {
+ return toIndex - fromIndex + 1;
+ }
+ int sum = 0;
+ while (from != to) {
+ sum += (from.right_idx - fromIndex + 1);
+ from = from.next;
+ fromIndex = from.left_idx;
+ }
+ return sum + toIndex - fromIndex + 1;
+ }
+
+ private void readObject(ObjectInputStream stream) throws IOException,
+ ClassNotFoundException {
+ stream.defaultReadObject();
+ firstKeyModCount = -1;
+ lastKeyModCount = -1;
+ }
+ }
+
+ static class SubMapEntrySet <K,V> extends AbstractSet<Map.Entry<K, V>>
+ implements Set<Map.Entry<K, V>> {
+ SubMap<K, V> subMap;
+
+ SubMapEntrySet(SubMap<K, V> map) {
+ subMap = map;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return subMap.isEmpty();
+ }
+
+ public Iterator<Map.Entry<K, V>> iterator() {
+ Node<K, V> from;
+ int fromIndex;
+ if (subMap.hasStart) {
+ subMap.setFirstKey();
+ from = subMap.firstKeyNode;
+ fromIndex = subMap.firstKeyIndex;
+ } else {
+ from = minimum(subMap.backingMap.root);
+ fromIndex = from != null ? from.left_idx : 0;
+ }
+ if (!subMap.hasEnd) {
+ return new UnboundedEntryIterator<K, V>(subMap.backingMap, from, from == null ? 0 : from.right_idx - fromIndex);
+ }
+ subMap.setLastKey();
+ Node<K, V> to = subMap.lastKeyNode;
+ int toIndex = subMap.lastKeyIndex;
+ return new BoundedEntryIterator<K, V>(from, from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to, to == null ? 0 : to.right_idx - toIndex);
+ }
+
+ @Override
+ public int size() {
+ return subMap.size();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean contains(Object object) {
+ if (object instanceof Map.Entry) {
+ Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
+ K key = entry.getKey();
+ if (subMap.isInRange(key)) {
+ V v1 = subMap.get(key), v2 = entry.getValue();
+ return v1 == null ? ( v2 == null && subMap.containsKey(key) ) : v1.equals(v2);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ if (contains(object)) {
+ Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
+ K key = entry.getKey();
+ subMap.remove(key);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ static class SubMapKeySet <K,V> extends AbstractSet<K> implements Set<K> {
+ SubMap<K, V> subMap;
+
+ SubMapKeySet(SubMap<K, V> map) {
+ subMap = map;
+ }
+
+ @Override
+ public boolean contains(Object object) {
+ return subMap.containsKey(object);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return subMap.isEmpty();
+ }
+
+ @Override
+ public int size() {
+ return subMap.size();
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ if (subMap.containsKey(object)) {
+ subMap.remove(object);
+ return true;
+ }
+ return false;
+ }
+
+ public Iterator<K> iterator() {
+ Node<K, V> from;
+ int fromIndex;
+ if (subMap.hasStart) {
+ subMap.setFirstKey();
+ from = subMap.firstKeyNode;
+ fromIndex = subMap.firstKeyIndex;
+ } else {
+ from = minimum(subMap.backingMap.root);
+ fromIndex = from != null ? from.left_idx : 0;
+ }
+ if (!subMap.hasEnd) {
+ return new UnboundedKeyIterator<K, V>(subMap.backingMap, from,
+ from == null ? 0 : from.right_idx - fromIndex);
+ }
+ subMap.setLastKey();
+ Node<K, V> to = subMap.lastKeyNode;
+ int toIndex = subMap.lastKeyIndex;
+ return new BoundedKeyIterator<K, V>(from,
+ from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to,
+ to == null ? 0 : to.right_idx - toIndex);
+ }
+ }
+
+ static class SubMapValuesCollection <K,V> extends AbstractCollection<V> {
+ SubMap<K, V> subMap;
+
+ public SubMapValuesCollection(SubMap<K, V> subMap) {
+ this.subMap = subMap;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return subMap.isEmpty();
+ }
+
+ @Override
+ public Iterator<V> iterator() {
+ Node<K, V> from;
+ int fromIndex;
+ if (subMap.hasStart) {
+ subMap.setFirstKey();
+ from = subMap.firstKeyNode;
+ fromIndex = subMap.firstKeyIndex;
+ } else {
+ from = minimum(subMap.backingMap.root);
+ fromIndex = from != null ? from.left_idx : 0;
+ }
+ if (!subMap.hasEnd) {
+ return new UnboundedValueIterator<K, V>(subMap.backingMap, from,
+ from == null ? 0 : from.right_idx - fromIndex);
+ }
+ subMap.setLastKey();
+ Node<K, V> to = subMap.lastKeyNode;
+ int toIndex = subMap.lastKeyIndex;
+ return new BoundedValueIterator<K, V>(from,
+ from == null ? 0 : from.right_idx - fromIndex, subMap.backingMap, to,
+ to == null ? 0 : to.right_idx - toIndex);
+ }
+
+ @Override
+ public int size() {
+ return subMap.size();
+ }
+ }
+
/**
* Constructs a new empty {@code TreeMap} instance.
- *
- * @since Android 1.0
*/
public TreeMap() {
- super();
}
/**
* Constructs a new empty {@code TreeMap} instance with the specified
* comparator.
- *
+ *
* @param comparator
* the comparator to compare keys with.
- * @since Android 1.0
*/
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
@@ -683,50 +977,753 @@
/**
* Constructs a new {@code TreeMap} instance containing the mappings from
* the specified map and using natural ordering.
- *
+ *
* @param map
* the mappings to add.
* @throws ClassCastException
* if a key in the specified map does not implement the
* Comparable interface, or if the keys in the map cannot be
* compared.
- * @since Android 1.0
*/
- public TreeMap(Map<? extends K,? extends V> map) {
- this();
+ public TreeMap(Map<? extends K, ? extends V> map) {
putAll(map);
}
/**
* Constructs a new {@code TreeMap} instance containing the mappings from
* the specified SortedMap and using the same comparator.
- *
+ *
* @param map
* the mappings to add.
- * @since Android 1.0
*/
- public TreeMap(SortedMap<K,? extends V> map) {
+ public TreeMap(SortedMap<K, ? extends V> map) {
this(map.comparator());
+ Node<K, V> lastNode = null;
Iterator<? extends Map.Entry<K, ? extends V>> it = map.entrySet().iterator();
- if (it.hasNext()) {
+ while (it.hasNext()) {
Map.Entry<K, ? extends V> entry = it.next();
- Entry<K, V> last = new Entry<K, V>(entry.getKey(), entry.getValue());
- root = last;
- size = 1;
- while (it.hasNext()) {
- entry = it.next();
- Entry<K, V> x = new Entry<K, V>(entry.getKey(), entry.getValue());
- x.parent = last;
- last.right = x;
- size++;
- balance(x);
- last = x;
- }
+ lastNode = addToLast(lastNode, entry.getKey(), entry.getValue());
}
}
- void balance(Entry<K, V> x) {
- Entry<K, V> y;
+ Node<K, V> addToLast(Node<K, V> last, K key, V value) {
+ if (last == null) {
+ root = last = createNode(key, value);
+ size = 1;
+ } else if (last.size == Node.NODE_SIZE) {
+ Node<K, V> newNode = createNode(key, value);
+ attachToRight(last, newNode);
+ balance(newNode);
+ size++;
+ last = newNode;
+ } else {
+ appendFromRight(last, key, value);
+ size++;
+ }
+ return last;
+ }
+
+ /**
+ * Removes all mappings from this TreeMap, leaving it empty.
+ *
+ * @see Map#isEmpty()
+ * @see #size()
+ */
+ @Override
+ public void clear() {
+ root = null;
+ size = 0;
+ modCount++;
+ }
+
+ /**
+ * Returns a new {@code TreeMap} with the same mappings, size and comparator
+ * as this instance.
+ *
+ * @return a shallow copy of this instance.
+ * @see java.lang.Cloneable
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object clone() {
+ try {
+ TreeMap<K, V> clone = (TreeMap<K, V>) super.clone();
+ clone.entrySet = null;
+ if (root != null) {
+ clone.root = root.clone(null);
+ // restore prev/next chain
+ Node<K, V> node = minimum(clone.root);
+ while (true) {
+ Node<K, V> nxt = successor(node);
+ if (nxt == null) {
+ break;
+ }
+ nxt.prev = node;
+ node.next = nxt;
+ node = nxt;
+ }
+ }
+ return clone;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ static private <K, V> Node<K, V> successor(Node<K, V> x) {
+ if (x.right != null) {
+ return minimum(x.right);
+ }
+ Node<K, V> y = x.parent;
+ while (y != null && x == y.right) {
+ x = y;
+ y = y.parent;
+ }
+ return y;
+ }
+
+ /**
+ * Returns the comparator used to compare elements in this map.
+ *
+ * @return the comparator or {@code null} if the natural ordering is used.
+ */
+ public Comparator<? super K> comparator() {
+ return comparator;
+ }
+
+ /**
+ * Returns whether this map contains the specified key.
+ *
+ * @param key
+ * the key to search for.
+ * @return {@code true} if this map contains the specified key,
+ * {@code false} otherwise.
+ * @throws ClassCastException
+ * if the specified key cannot be compared with the keys in this
+ * map.
+ * @throws NullPointerException
+ * if the specified key is {@code null} and the comparator
+ * cannot handle {@code null} keys.
+ */
+ @Override
+ public boolean containsKey(Object key) {
+ Comparable<K> object = comparator == null ? toComparable((K) key) : null;
+ K keyK = (K) key;
+ Node<K, V> node = root;
+ while (node != null) {
+ K[] keys = node.keys;
+ int left_idx = node.left_idx;
+ int result = cmp(object, keyK, keys[left_idx]);
+ if (result < 0) {
+ node = node.left;
+ } else if (result == 0) {
+ return true;
+ } else {
+ int right_idx = node.right_idx;
+ if (left_idx != right_idx) {
+ result = cmp(object, keyK, keys[right_idx]);
+ }
+ if (result > 0) {
+ node = node.right;
+ } else if (result == 0) {
+ return true;
+ } else { /*search in node*/
+ int low = left_idx + 1, mid = 0, high = right_idx - 1;
+ while (low <= high) {
+ mid = (low + high) >> 1;
+ result = cmp(object, keyK, keys[mid]);
+ if (result > 0) {
+ low = mid + 1;
+ } else if (result == 0) {
+ return true;
+ } else {
+ high = mid - 1;
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether this map contains the specified value.
+ *
+ * @param value
+ * the value to search for.
+ * @return {@code true} if this map contains the specified value,
+ * {@code false} otherwise.
+ */
+ @Override
+ public boolean containsValue(Object value) {
+ if (root == null) {
+ return false;
+ }
+ Node<K, V> node = minimum(root);
+ if (value != null) {
+ while (node != null) {
+ int to = node.right_idx;
+ V[] values = node.values;
+ for (int i = node.left_idx; i <= to; i++) {
+ if (value.equals(values[i])) {
+ return true;
+ }
+ }
+ node = node.next;
+ }
+ } else {
+ while (node != null) {
+ int to = node.right_idx;
+ V[] values = node.values;
+ for (int i = node.left_idx; i <= to; i++) {
+ if (values[i] == null) {
+ return true;
+ }
+ }
+ node = node.next;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns a set containing all of the mappings in this map. Each mapping is
+ * an instance of {@link Map.Entry}. As the set is backed by this map,
+ * changes in one will be reflected in the other. It does not support adding
+ * operations.
+ *
+ * @return a set of the mappings.
+ */
+ @Override
+ public Set<Map.Entry<K, V>> entrySet() {
+ if (entrySet == null) {
+ entrySet = new AbstractSet<Map.Entry<K, V>>() {
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public void clear() {
+ TreeMap.this.clear();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public boolean contains(Object object) {
+ if (object instanceof Map.Entry) {
+ Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
+ K key = entry.getKey();
+ Object v1 = TreeMap.this.get(key), v2 = entry.getValue();
+ return v1 == null ? ( v2 == null && TreeMap.this.containsKey(key) ) : v1.equals(v2);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ if (contains(object)) {
+ Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
+ K key = entry.getKey();
+ TreeMap.this.remove(key);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Iterator<Map.Entry<K, V>> iterator() {
+ return new UnboundedEntryIterator<K, V>(TreeMap.this);
+ }
+ };
+ }
+ return entrySet;
+ }
+
+ /**
+ * Returns the first key in this map.
+ *
+ * @return the first key in this map.
+ * @throws NoSuchElementException
+ * if this map is empty.
+ */
+ public K firstKey() {
+ if (root != null) {
+ Node<K, V> node = minimum(root);
+ return node.keys[node.left_idx];
+ }
+ throw new NoSuchElementException();
+ }
+
+
+ /**
+ * Returns the value of the mapping with the specified key.
+ *
+ * @param key
+ * the key.
+ * @return the value of the mapping with the specified key.
+ * @throws ClassCastException
+ * if the key cannot be compared with the keys in this map.
+ * @throws NullPointerException
+ * if the key is {@code null} and the comparator cannot handle
+ * {@code null}.
+ */
+ @Override
+ public V get(Object key) {
+ Comparable<K> object = comparator == null ? toComparable((K) key) : null;
+ K keyK = (K) key;
+ Node<K, V> node = root;
+ while (node != null) {
+ K[] keys = node.keys;
+ int left_idx = node.left_idx;
+ int result = cmp(object, keyK, keys[left_idx]);
+ if (result < 0) {
+ node = node.left;
+ } else if (result == 0) {
+ return node.values[left_idx];
+ } else {
+ int right_idx = node.right_idx;
+ if (left_idx != right_idx) {
+ result = cmp(object, keyK, keys[right_idx]);
+ }
+ if (result > 0) {
+ node = node.right;
+ } else if (result == 0) {
+ return node.values[right_idx];
+ } else { /*search in node*/
+ int low = left_idx + 1, mid = 0, high = right_idx - 1;
+ while (low <= high) {
+ mid = (low + high) >> 1;
+ result = cmp(object, keyK, keys[mid]);
+ if (result > 0) {
+ low = mid + 1;
+ } else if (result == 0) {
+ return node.values[mid];
+ } else {
+ high = mid - 1;
+ }
+ }
+ return null;
+ }
+ }
+ }
+ return null;
+ }
+
+ private int cmp(Comparable<K> object, K key1, K key2) {
+ return object != null ?
+ object.compareTo(key2) : comparator.compare(key1, key2);
+ }
+
+ /**
+ * Returns a sorted map over a range of this sorted map with all keys that
+ * are less than the specified {@code endKey}. Changes to the returned
+ * sorted map are reflected in this sorted map and vice versa.
+ * <p>
+ * Note: The returned map will not allow an insertion of a key outside the
+ * specified range.
+ *
+ * @param endKey
+ * the high boundary of the range specified.
+ * @return a sorted map where the keys are less than {@code endKey}.
+ * @throws ClassCastException
+ * if the specified key cannot be compared with the keys in this
+ * map.
+ * @throws NullPointerException
+ * if the specified key is {@code null} and the comparator
+ * cannot handle {@code null} keys.
+ * @throws IllegalArgumentException
+ * if this map is itself a sorted map over a range of another
+ * map and the specified key is outside of its range.
+ */
+ public SortedMap<K, V> headMap(K endKey) {
+ // Check for errors
+ if (comparator == null) {
+ toComparable(endKey).compareTo(endKey);
+ } else {
+ comparator.compare(endKey, endKey);
+ }
+ return new SubMap<K, V>(this, endKey);
+ }
+
+ /**
+ * Returns a set of the keys contained in this map. The set is backed by
+ * this map so changes to one are reflected by the other. The set does not
+ * support adding.
+ *
+ * @return a set of the keys.
+ */
+ @Override
+ public Set<K> keySet() {
+ if (keySet == null) {
+ keySet = new AbstractSet<K>() {
+ @Override
+ public boolean contains(Object object) {
+ return TreeMap.this.containsKey(object);
+ }
+
+ @Override
+ public int size() {
+ return TreeMap.this.size;
+ }
+
+ @Override
+ public void clear() {
+ TreeMap.this.clear();
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ if (contains(object)) {
+ TreeMap.this.remove(object);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public Iterator<K> iterator() {
+ return new UnboundedKeyIterator<K, V>(TreeMap.this);
+ }
+ };
+ }
+ return keySet;
+ }
+
+ /**
+ * Returns the last key in this map.
+ *
+ * @return the last key in this map.
+ * @throws NoSuchElementException
+ * if this map is empty.
+ */
+ public K lastKey() {
+ if (root != null) {
+ Node<K, V> node = maximum(root);
+ return node.keys[node.right_idx];
+ }
+ throw new NoSuchElementException();
+ }
+
+ static <K,V> Node<K, V> minimum(Node<K, V> x) {
+ if (x == null) {
+ return null;
+ }
+ while (x.left != null) {
+ x = x.left;
+ }
+ return x;
+ }
+
+ static <K,V> Node<K, V> maximum(Node<K, V> x) {
+ if (x == null) {
+ return null;
+ }
+ while (x.right != null) {
+ x = x.right;
+ }
+ return x;
+ }
+
+ /**
+ * Maps the specified key to the specified value.
+ *
+ * @param key
+ * the key.
+ * @param value
+ * the value.
+ * @return the value of any previous mapping with the specified key or
+ * {@code null} if there was no mapping.
+ * @throws ClassCastException
+ * if the specified key cannot be compared with the keys in this
+ * map.
+ * @throws NullPointerException
+ * if the specified key is {@code null} and the comparator
+ * cannot handle {@code null} keys.
+ */
+ @Override
+ public V put(K key, V value) {
+ if (root == null) {
+ root = createNode(key, value);
+ size = 1;
+ modCount++;
+ return null;
+ }
+ Comparable<K> object = comparator == null ? toComparable((K) key) : null;
+ K keyK = (K) key;
+ Node<K, V> node = root;
+ Node<K, V> prevNode = null;
+ int result = 0;
+ while (node != null) {
+ prevNode = node;
+ K[] keys = node.keys;
+ int left_idx = node.left_idx;
+ result = cmp(object, keyK, keys[left_idx]);
+ if (result < 0) {
+ node = node.left;
+ } else if (result == 0) {
+ V res = node.values[left_idx];
+ node.values[left_idx] = value;
+ return res;
+ } else {
+ int right_idx = node.right_idx;
+ if (left_idx != right_idx) {
+ result = cmp(object, keyK, keys[right_idx]);
+ }
+ if (result > 0) {
+ node = node.right;
+ } else if (result == 0) {
+ V res = node.values[right_idx];
+ node.values[right_idx] = value;
+ return res;
+ } else { /*search in node*/
+ int low = left_idx + 1, mid = 0, high = right_idx - 1;
+ while (low <= high) {
+ mid = (low + high) >> 1;
+ result = cmp(object, keyK, keys[mid]);
+ if (result > 0) {
+ low = mid + 1;
+ } else if (result == 0) {
+ V res = node.values[mid];
+ node.values[mid] = value;
+ return res;
+ } else {
+ high = mid - 1;
+ }
+ }
+ result = low;
+ break;
+ }
+ }
+ } /* while */
+/*
+ if(node == null) {
+ if(prevNode==null) {
+ - case of empty Tree
+ } else {
+ result < 0 - prevNode.left==null - attach here
+ result > 0 - prevNode.right==null - attach here
+ }
+ } else {
+ insert into node.
+ result - index where it should be inserted.
+ }
+ */
+ size++;
+ modCount++;
+ if (node == null) {
+ if (prevNode == null) {
+ // case of empty Tree
+ root = createNode(key, value);
+ } else if (prevNode.size < Node.NODE_SIZE) {
+ // there is a place for insert
+ if (result < 0) {
+ appendFromLeft(prevNode, key, value);
+ } else {
+ appendFromRight(prevNode, key, value);
+ }
+ } else {
+ // create and link
+ Node<K, V> newNode = createNode(key, value);
+ if (result < 0) {
+ attachToLeft(prevNode, newNode);
+ } else {
+ attachToRight(prevNode, newNode);
+ }
+ balance(newNode);
+ }
+ } else {
+ // insert into node.
+ // result - index where it should be inserted.
+ if (node.size < Node.NODE_SIZE) { // insert and ok
+ int left_idx = node.left_idx;
+ int right_idx = node.right_idx;
+ if (left_idx == 0 || ((right_idx != Node.NODE_SIZE - 1) && (right_idx - result <= result - left_idx))) {
+ int right_idxPlus1 = right_idx + 1;
+ System.arraycopy(node.keys, result, node.keys, result + 1, right_idxPlus1 - result);
+ System.arraycopy(node.values, result, node.values, result + 1, right_idxPlus1 - result);
+ node.right_idx = right_idxPlus1;
+ node.keys[result] = key;
+ node.values[result] = value;
+ } else {
+ int left_idxMinus1 = left_idx - 1;
+ System.arraycopy(node.keys, left_idx, node.keys, left_idxMinus1, result - left_idx);
+ System.arraycopy(node.values, left_idx, node.values, left_idxMinus1, result - left_idx);
+ node.left_idx = left_idxMinus1;
+ node.keys[result - 1] = key;
+ node.values[result - 1] = value;
+ }
+ node.size++;
+ } else {
+ // there are no place here
+ // insert and push old pair
+ Node<K, V> previous = node.prev;
+ Node<K, V> nextNode = node.next;
+ boolean removeFromStart;
+ boolean attachFromLeft = false;
+ Node<K, V> attachHere = null;
+ if (previous == null) {
+ if (nextNode != null && nextNode.size < Node.NODE_SIZE) {
+ // move last pair to next
+ removeFromStart = false;
+ } else {
+ // next node doesn't exist or full
+ // left==null
+ // drop first pair to new node from left
+ removeFromStart = true;
+ attachFromLeft = true;
+ attachHere = node;
+ }
+ } else if (nextNode == null) {
+ if (previous.size < Node.NODE_SIZE) {
+ // move first pair to prev
+ removeFromStart = true;
+ } else {
+ // right == null;
+ // drop last pair to new node from right
+ removeFromStart = false;
+ attachFromLeft = false;
+ attachHere = node;
+ }
+ } else {
+ if (previous.size < Node.NODE_SIZE) {
+ if (nextNode.size < Node.NODE_SIZE) {
+ // choose prev or next for moving
+ removeFromStart = previous.size < nextNode.size;
+ } else {
+ // move first pair to prev
+ removeFromStart = true;
+ }
+ } else {
+ if (nextNode.size < Node.NODE_SIZE) {
+ // move last pair to next
+ removeFromStart = false;
+ } else {
+ // prev & next are full
+ // if node.right!=null then node.next.left==null
+ // if node.left!=null then node.prev.right==null
+ if (node.right == null) {
+ attachHere = node;
+ attachFromLeft = false;
+ removeFromStart = false;
+ } else {
+ attachHere = nextNode;
+ attachFromLeft = true;
+ removeFromStart = false;
+ }
+ }
+ }
+ }
+ K movedKey;
+ V movedValue;
+ if (removeFromStart) {
+ // node.left_idx == 0
+ movedKey = node.keys[0];
+ movedValue = node.values[0];
+ int resMunus1 = result - 1;
+ System.arraycopy(node.keys, 1, node.keys, 0, resMunus1);
+ System.arraycopy(node.values, 1, node.values, 0, resMunus1);
+ node.keys [resMunus1] = key;
+ node.values[resMunus1] = value;
+ } else {
+ // node.right_idx == Node.NODE_SIZE - 1
+ movedKey = node.keys[Node.NODE_SIZE - 1];
+ movedValue = node.values[Node.NODE_SIZE - 1];
+ System.arraycopy(node.keys, result, node.keys, result + 1, Node.NODE_SIZE - 1 - result);
+ System.arraycopy(node.values, result, node.values, result + 1, Node.NODE_SIZE - 1 - result);
+ node.keys[result] = key;
+ node.values[result] = value;
+ }
+ if (attachHere == null) {
+ if (removeFromStart) {
+ appendFromRight(previous, movedKey, movedValue);
+ } else {
+ appendFromLeft(nextNode, movedKey, movedValue);
+ }
+ } else {
+ Node<K, V> newNode = createNode(movedKey, movedValue);
+ if (attachFromLeft) {
+ attachToLeft(attachHere, newNode);
+ } else {
+ attachToRight(attachHere, newNode);
+ }
+ balance(newNode);
+ }
+ }
+ }
+ return null;
+ }
+
+ private void appendFromLeft(Node<K, V> node, K keyObj, V value) {
+ if (node.left_idx == 0) {
+ int new_right = node.right_idx + 1;
+ System.arraycopy(node.keys, 0, node.keys, 1, new_right);
+ System.arraycopy(node.values, 0, node.values, 1, new_right);
+ node.right_idx = new_right;
+ } else {
+ node.left_idx--;
+ }
+ node.size++;
+ node.keys[node.left_idx] = keyObj;
+ node.values[node.left_idx] = value;
+ }
+
+ private void attachToLeft(Node<K, V> node, Node<K, V> newNode) {
+ newNode.parent = node;
+ // node.left==null - attach here
+ node.left = newNode;
+ Node<K, V> predecessor = node.prev;
+ newNode.prev = predecessor;
+ newNode.next = node;
+ if (predecessor != null) {
+ predecessor.next = newNode;
+ }
+ node.prev = newNode;
+ }
+
+ /* add pair into node; existence free room in the node should be checked
+ * before call
+ */
+ private void appendFromRight(Node<K, V> node, K keyObj, V value) {
+ if (node.right_idx == Node.NODE_SIZE - 1) {
+ int left_idx = node.left_idx;
+ int left_idxMinus1 = left_idx - 1;
+ System.arraycopy(node.keys, left_idx, node.keys, left_idxMinus1, Node.NODE_SIZE - left_idx);
+ System.arraycopy(node.values, left_idx, node.values, left_idxMinus1, Node.NODE_SIZE - left_idx);
+ node.left_idx = left_idxMinus1;
+ } else {
+ node.right_idx++;
+ }
+ node.size++;
+ node.keys[node.right_idx] = keyObj;
+ node.values[node.right_idx] = value;
+ }
+
+ private void attachToRight(Node<K, V> node, Node<K, V> newNode) {
+ newNode.parent = node;
+ // - node.right==null - attach here
+ node.right = newNode;
+ newNode.prev = node;
+ Node<K, V> successor = node.next;
+ newNode.next = successor;
+ if (successor != null) {
+ successor.prev = newNode;
+ }
+ node.next = newNode;
+ }
+
+ private Node<K, V> createNode(K keyObj, V value) {
+ Node<K, V> node = new Node<K, V>();
+ node.keys[0] = keyObj;
+ node.values[0] = value;
+ node.left_idx = 0;
+ node.right_idx = 0;
+ node.size = 1;
+ return node;
+ }
+
+ void balance(Node<K, V> x) {
+ Node<K, V> y;
x.color = true;
while (x != root && x.parent.color) {
if (x.parent == x.parent.parent.left) {
@@ -766,226 +1763,421 @@
root.color = false;
}
+ private void rightRotate(Node<K, V> x) {
+ Node<K, V> y = x.left;
+ x.left = y.right;
+ if (y.right != null) {
+ y.right.parent = x;
+ }
+ y.parent = x.parent;
+ if (x.parent == null) {
+ root = y;
+ } else {
+ if (x == x.parent.right) {
+ x.parent.right = y;
+ } else {
+ x.parent.left = y;
+ }
+ }
+ y.right = x;
+ x.parent = y;
+ }
+
+
+ private void leftRotate(Node<K, V> x) {
+ Node<K, V> y = x.right;
+ x.right = y.left;
+ if (y.left != null) {
+ y.left.parent = x;
+ }
+ y.parent = x.parent;
+ if (x.parent == null) {
+ root = y;
+ } else {
+ if (x == x.parent.left) {
+ x.parent.left = y;
+ } else {
+ x.parent.right = y;
+ }
+ }
+ y.left = x;
+ x.parent = y;
+ }
+
+
/**
- * Removes all mappings from this TreeMap, leaving it empty.
- *
- * @see Map#isEmpty()
- * @see #size()
- * @since Android 1.0
+ * Copies all the mappings in the given map to this map. These mappings will
+ * replace all mappings that this map had for any of the keys currently in
+ * the given map.
+ *
+ * @param map
+ * the map to copy mappings from.
+ * @throws ClassCastException
+ * if a key in the specified map cannot be compared with the
+ * keys in this map.
+ * @throws NullPointerException
+ * if a key in the specified map is {@code null} and the
+ * comparator cannot handle {@code null} keys.
*/
@Override
- public void clear() {
- root = null;
- size = 0;
- modCount++;
+ public void putAll(Map<? extends K, ? extends V> map) {
+ super.putAll(map);
}
/**
- * Returns a new {@code TreeMap} with the same mappings, size and comparator
- * as this instance.
- *
- * @return a shallow copy of this instance.
- * @see java.lang.Cloneable
- * @since Android 1.0
+ * Removes the mapping with the specified key from this map.
+ *
+ * @param key
+ * the key of the mapping to remove.
+ * @return the value of the removed mapping or {@code null} if no mapping
+ * for the specified key was found.
+ * @throws ClassCastException
+ * if the specified key cannot be compared with the keys in this
+ * map.
+ * @throws NullPointerException
+ * if the specified key is {@code null} and the comparator
+ * cannot handle {@code null} keys.
*/
- @SuppressWarnings("unchecked")
@Override
- public Object clone() {
- try {
- TreeMap<K, V> clone = (TreeMap<K, V>) super.clone();
- clone.entrySet = null;
- if (root != null) {
- clone.root = root.clone(null);
- }
- return clone;
- } catch (CloneNotSupportedException e) {
+ public V remove(Object key) {
+ if (size == 0) {
return null;
}
- }
-
- /**
- * Returns the comparator used to compare elements in this map.
- *
- * @return the comparator or {@code null} if the natural ordering is used.
- * @since Android 1.0
- */
- public Comparator<? super K> comparator() {
- return comparator;
- }
-
- /**
- * Returns whether this map contains the specified key.
- *
- * @param key
- * the key to search for.
- * @return {@code true} if this map contains the specified key,
- * {@code false} otherwise.
- * @since Android 1.0
- */
- @Override
- public boolean containsKey(Object key) {
- return find(key) != null;
- }
-
- /**
- * Returns whether this map contains the specified value.
- *
- * @param value
- * the value to search for.
- * @return {@code true} if this map contains the specified value,
- * {@code false} otherwise.
- * @since Android 1.0
- */
- @Override
- public boolean containsValue(Object value) {
- if (root != null) {
- return containsValue(root, value);
- }
- return false;
- }
-
- private boolean containsValue(Entry<K, V> node, Object value) {
- if (value == null ? node.value == null : value.equals(node.value)) {
- return true;
- }
- if (node.left != null) {
- if (containsValue(node.left, value)) {
- return true;
- }
- }
- if (node.right != null) {
- if (containsValue(node.right, value)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns a set containing all of the mappings in this map. Each mapping is
- * an instance of {@link Map.Entry}. As the set is backed by this map,
- * changes in one will be reflected in the other. It does not support adding
- * operations.
- *
- * @return a set of the mappings.
- * @since Android 1.0
- */
- @Override
- public Set<Map.Entry<K, V>> entrySet() {
- if (entrySet == null) {
- entrySet = new AbstractSet<Map.Entry<K, V>>() {
- @Override
- public int size() {
- return size;
+ Comparable<K> object = comparator == null ? toComparable((K) key) : null;
+ K keyK = (K) key;
+ Node<K, V> node = root;
+ while (node != null) {
+ K[] keys = node.keys;
+ int left_idx = node.left_idx;
+ int result = cmp(object, keyK, keys[left_idx]);
+ if (result < 0) {
+ node = node.left;
+ } else if (result == 0) {
+ V value = node.values[left_idx];
+ removeLeftmost(node);
+ return value;
+ } else {
+ int right_idx = node.right_idx;
+ if (left_idx != right_idx) {
+ result = cmp(object, keyK, keys[right_idx]);
}
-
- @Override
- public void clear() {
- TreeMap.this.clear();
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public boolean contains(Object object) {
- if (object instanceof Map.Entry) {
- Map.Entry<K, V> entry = (Map.Entry<K, V>) object;
- Object v1 = get(entry.getKey()), v2 = entry.getValue();
- return v1 == null ? v2 == null : v1.equals(v2);
+ if (result > 0) {
+ node = node.right;
+ } else if (result == 0) {
+ V value = node.values[right_idx];
+ removeRightmost(node);
+ return value;
+ } else { /*search in node*/
+ int low = left_idx + 1, mid = 0, high = right_idx - 1;
+ while (low <= high) {
+ mid = (low + high) >> 1;
+ result = cmp(object, keyK, keys[mid]);
+ if (result > 0) {
+ low = mid + 1;
+ } else if (result == 0) {
+ V value = node.values[mid];
+ removeMiddleElement(node, mid);
+ return value;
+ } else {
+ high = mid - 1;
+ }
}
- return false;
+ return null;
}
-
- @Override
- public Iterator<Map.Entry<K, V>> iterator() {
- return new UnboundedEntryIterator<K, V>(TreeMap.this);
- }
- };
- }
- return entrySet;
- }
-
- @SuppressWarnings("unchecked")
- private Entry<K, V> find(Object keyObj) {
- int result;
- K key = (K)keyObj;
- Comparable<K> object = null;
- if (comparator == null) {
- object = toComparable(key);
- }
- Entry<K, V> x = root;
- while (x != null) {
- result = object != null ? object.compareTo(x.key) : comparator
- .compare(key, x.key);
- if (result == 0) {
- return x;
}
- x = result < 0 ? x.left : x.right;
}
return null;
}
- @SuppressWarnings("unchecked")
- Entry<K, V> findAfter(Object keyObj) {
- K key = (K)keyObj;
- int result;
- Comparable<K> object = null;
- if (comparator == null) {
- object = toComparable(key);
- }
- Entry<K, V> x = root, last = null;
- while (x != null) {
- result = object != null ? object.compareTo(x.key) : comparator
- .compare(key, x.key);
- if (result == 0) {
- return x;
+ void removeLeftmost(Node<K, V> node) {
+ int index = node.left_idx;
+ if (node.size == 1) {
+ deleteNode(node);
+ } else if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) {
+ // move all to prev node and kill it
+ Node<K, V> prev = node.prev;
+ int size = node.right_idx - index;
+ System.arraycopy(node.keys, index + 1, prev.keys, prev.right_idx + 1, size);
+ System.arraycopy(node.values, index + 1, prev.values, prev.right_idx + 1, size);
+ prev.right_idx += size;
+ prev.size += size;
+ deleteNode(node);
+ } else if (node.next != null && (node.next.left_idx) > node.size) {
+ // move all to next node and kill it
+ Node<K, V> next = node.next;
+ int size = node.right_idx - index;
+ int next_new_left = next.left_idx - size;
+ next.left_idx = next_new_left;
+ System.arraycopy(node.keys, index + 1, next.keys, next_new_left, size);
+ System.arraycopy(node.values, index + 1, next.values, next_new_left, size);
+ next.size += size;
+ deleteNode(node);
+ } else {
+ node.keys[index] = null;
+ node.values[index] = null;
+ node.left_idx++;
+ node.size--;
+ Node<K, V> prev = node.prev;
+ if (prev != null && prev.size == 1) {
+ node.size++;
+ node.left_idx--;
+ node.keys [node.left_idx] = prev.keys [prev.left_idx];
+ node.values[node.left_idx] = prev.values[prev.left_idx];
+ deleteNode(prev);
}
- if (result < 0) {
- last = x;
- x = x.left;
+ }
+ modCount++;
+ size--;
+ }
+
+ void removeRightmost(Node<K, V> node) {
+ int index = node.right_idx;
+ if (node.size == 1) {
+ deleteNode(node);
+ } else if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) {
+ // move all to prev node and kill it
+ Node<K, V> prev = node.prev;
+ int left_idx = node.left_idx;
+ int size = index - left_idx;
+ System.arraycopy(node.keys, left_idx, prev.keys, prev.right_idx + 1, size);
+ System.arraycopy(node.values, left_idx, prev.values, prev.right_idx + 1, size);
+ prev.right_idx += size;
+ prev.size += size;
+ deleteNode(node);
+ } else if (node.next != null && (node.next.left_idx) > node.size) {
+ // move all to next node and kill it
+ Node<K, V> next = node.next;
+ int left_idx = node.left_idx;
+ int size = index - left_idx;
+ int next_new_left = next.left_idx - size;
+ next.left_idx = next_new_left;
+ System.arraycopy(node.keys, left_idx, next.keys, next_new_left, size);
+ System.arraycopy(node.values, left_idx, next.values, next_new_left, size);
+ next.size += size;
+ deleteNode(node);
+ } else {
+ node.keys[index] = null;
+ node.values[index] = null;
+ node.right_idx--;
+ node.size--;
+ Node<K, V> next = node.next;
+ if (next != null && next.size == 1) {
+ node.size++;
+ node.right_idx++;
+ node.keys[node.right_idx] = next.keys[next.left_idx];
+ node.values[node.right_idx] = next.values[next.left_idx];
+ deleteNode(next);
+ }
+ }
+ modCount++;
+ size--;
+ }
+
+ void removeMiddleElement(Node<K, V> node, int index) {
+ // this function is called iff index if some middle element;
+ // so node.left_idx < index < node.right_idx
+ // condition above assume that node.size > 1
+ if (node.prev != null && (Node.NODE_SIZE - 1 - node.prev.right_idx) > node.size) {
+ // move all to prev node and kill it
+ Node<K, V> prev = node.prev;
+ int left_idx = node.left_idx;
+ int size = index - left_idx;
+ System.arraycopy(node.keys, left_idx, prev.keys, prev.right_idx + 1, size);
+ System.arraycopy(node.values, left_idx, prev.values, prev.right_idx + 1, size);
+ prev.right_idx += size;
+ size = node.right_idx - index;
+ System.arraycopy(node.keys, index + 1, prev.keys, prev.right_idx + 1, size);
+ System.arraycopy(node.values, index + 1, prev.values, prev.right_idx + 1, size);
+ prev.right_idx += size;
+ prev.size += (node.size - 1);
+ deleteNode(node);
+ } else if (node.next != null && (node.next.left_idx) > node.size) {
+ // move all to next node and kill it
+ Node<K, V> next = node.next;
+ int left_idx = node.left_idx;
+ int next_new_left = next.left_idx - node.size + 1;
+ next.left_idx = next_new_left;
+ int size = index - left_idx;
+ System.arraycopy(node.keys, left_idx, next.keys, next_new_left, size);
+ System.arraycopy(node.values, left_idx, next.values, next_new_left, size);
+ next_new_left += size;
+ size = node.right_idx - index;
+ System.arraycopy(node.keys, index + 1, next.keys, next_new_left, size);
+ System.arraycopy(node.values, index + 1, next.values, next_new_left, size);
+ next.size += (node.size - 1);
+ deleteNode(node);
+ } else {
+ int moveFromRight = node.right_idx - index;
+ int left_idx = node.left_idx;
+ int moveFromLeft = index - left_idx ;
+ if (moveFromRight <= moveFromLeft) {
+ System.arraycopy(node.keys, index + 1, node.keys, index, moveFromRight);
+ System.arraycopy(node.values, index + 1, node.values, index, moveFromRight);
+ Node<K, V> next = node.next;
+ if (next != null && next.size == 1) {
+ node.keys [node.right_idx] = next.keys [next.left_idx];
+ node.values[node.right_idx] = next.values[next.left_idx];
+ deleteNode(next);
+ } else {
+ node.keys [node.right_idx] = null;
+ node.values[node.right_idx] = null;
+ node.right_idx--;
+ node.size--;
+ }
} else {
- x = x.right;
+ System.arraycopy(node.keys, left_idx , node.keys, left_idx + 1, moveFromLeft);
+ System.arraycopy(node.values, left_idx , node.values, left_idx + 1, moveFromLeft);
+ Node<K, V> prev = node.prev;
+ if (prev != null && prev.size == 1) {
+ node.keys [left_idx ] = prev.keys [prev.left_idx];
+ node.values[left_idx ] = prev.values[prev.left_idx];
+ deleteNode(prev);
+ } else {
+ node.keys [left_idx ] = null;
+ node.values[left_idx ] = null;
+ node.left_idx++;
+ node.size--;
+ }
}
}
- return last;
+ modCount++;
+ size--;
}
- Entry<K, V> findBefore(K key) {
- int result;
- Comparable<K> object = null;
- if (comparator == null) {
- object = toComparable(key);
- }
- Entry<K, V> x = root, last = null;
- while (x != null) {
- result = object != null ? object.compareTo(x.key) : comparator
- .compare(key, x.key);
- if (result <= 0) {
- x = x.left;
+ void removeFromIterator(Node<K, V> node, int index) {
+ if (node.size == 1) {
+ // it is safe to delete the whole node here.
+ // iterator already moved to the next node;
+ deleteNode(node);
+ } else {
+ int left_idx = node.left_idx;
+ if (index == left_idx) {
+ Node<K, V> prev = node.prev;
+ if (prev != null && prev.size == 1) {
+ node.keys [left_idx] = prev.keys [prev.left_idx];
+ node.values[left_idx] = prev.values[prev.left_idx];
+ deleteNode(prev);
+ } else {
+ node.keys [left_idx] = null;
+ node.values[left_idx] = null;
+ node.left_idx++;
+ node.size--;
+ }
+ } else if (index == node.right_idx) {
+ node.keys [index] = null;
+ node.values[index] = null;
+ node.right_idx--;
+ node.size--;
} else {
- last = x;
- x = x.right;
+ int moveFromRight = node.right_idx - index;
+ int moveFromLeft = index - left_idx;
+ if (moveFromRight <= moveFromLeft) {
+ System.arraycopy(node.keys, index + 1, node.keys, index, moveFromRight );
+ System.arraycopy(node.values, index + 1, node.values, index, moveFromRight );
+ node.keys [node.right_idx] = null;
+ node.values[node.right_idx] = null;
+ node.right_idx--;
+ node.size--;
+ } else {
+ System.arraycopy(node.keys, left_idx, node.keys, left_idx+ 1, moveFromLeft);
+ System.arraycopy(node.values, left_idx, node.values, left_idx+ 1, moveFromLeft);
+ node.keys [left_idx] = null;
+ node.values[left_idx] = null;
+ node.left_idx++;
+ node.size--;
+ }
}
}
- return last;
+ modCount++;
+ size--;
}
- /**
- * Returns the first key in this map.
- *
- * @return the first key in this map.
- * @exception NoSuchElementException
- * if this sorted map is empty.
- * @since Android 1.0
- */
- public K firstKey() {
- if (root != null) {
- return minimum(root).key;
+ private void deleteNode(Node<K, V> node) {
+ if (node.right == null) {
+ if (node.left != null) {
+ attachToParent(node, node.left);
+ } else {
+ attachNullToParent(node);
+ }
+ fixNextChain(node);
+ } else if(node.left == null) { // node.right != null
+ attachToParent(node, node.right);
+ fixNextChain(node);
+ } else {
+ // Here node.left!=nul && node.right!=null
+ // node.next should replace node in tree
+ // node.next!=null by tree logic.
+ // node.next.left==null by tree logic.
+ // node.next.right may be null or non-null
+ Node<K, V> toMoveUp = node.next;
+ fixNextChain(node);
+ if(toMoveUp.right==null){
+ attachNullToParent(toMoveUp);
+ } else {
+ attachToParent(toMoveUp, toMoveUp.right);
+ }
+ // Here toMoveUp is ready to replace node
+ toMoveUp.left = node.left;
+ if (node.left != null) {
+ node.left.parent = toMoveUp;
+ }
+ toMoveUp.right = node.right;
+ if (node.right != null) {
+ node.right.parent = toMoveUp;
+ }
+ attachToParentNoFixup(node,toMoveUp);
+ toMoveUp.color = node.color;
}
- throw new NoSuchElementException();
}
- private void fixup(Entry<K, V> x) {
- Entry<K, V> w;
+ private void attachToParentNoFixup(Node<K, V> toDelete, Node<K, V> toConnect) {
+ // assert toConnect!=null
+ Node<K,V> parent = toDelete.parent;
+ toConnect.parent = parent;
+ if (parent == null) {
+ root = toConnect;
+ } else if (toDelete == parent.left) {
+ parent.left = toConnect;
+ } else {
+ parent.right = toConnect;
+ }
+ }
+
+ private void attachToParent(Node<K, V> toDelete, Node<K, V> toConnect) {
+ // assert toConnect!=null
+ attachToParentNoFixup(toDelete,toConnect);
+ if (!toDelete.color) {
+ fixup(toConnect);
+ }
+ }
+
+ private void attachNullToParent(Node<K, V> toDelete) {
+ Node<K, V> parent = toDelete.parent;
+ if (parent == null) {
+ root = null;
+ } else {
+ if (toDelete == parent.left) {
+ parent.left = null;
+ } else {
+ parent.right = null;
+ }
+ if (!toDelete.color) {
+ fixup(parent);
+ }
+ }
+ }
+
+ private void fixNextChain(Node<K, V> node) {
+ if (node.prev != null) {
+ node.prev.next = node.next;
+ }
+ if (node.next != null) {
+ node.next.prev = node.prev;
+ }
+ }
+
+ private void fixup(Node<K, V> x) {
+ Node<K, V> w;
while (x != root && !x.color) {
if (x == x.parent.left) {
w = x.parent.right;
@@ -1004,7 +2196,7 @@
}
}
if ((w.left == null || !w.left.color)
- && (w.right == null || !w.right.color)) {
+ && (w.right == null || !w.right.color)) {
w.color = true;
x = x.parent;
} else {
@@ -1037,7 +2229,7 @@
}
}
if ((w.left == null || !w.left.color)
- && (w.right == null || !w.right.color)) {
+ && (w.right == null || !w.right.color)) {
w.color = true;
x = x.parent;
} else {
@@ -1058,321 +2250,11 @@
x.color = false;
}
- /**
- * Returns the value of the mapping with the specified key.
- *
- * @param key
- * the key.
- * @return the value of the mapping with the specified key.
- * @throws ClassCastException
- * if the key cannot be compared with the keys in this map.
- * @throws NullPointerException
- * if the key is {@code null} and the comparator cannot handle
- * {@code null}.
- * @since Android 1.0
- */
- @Override
- public V get(Object key) {
- Entry<K, V> node = find(key);
- if (node != null) {
- return node.value;
- }
- return null;
- }
-
- /**
- * Returns a sorted map over a range of this sorted map with all keys that
- * are less than the specified {@code endKey}. Changes to the returned
- * sorted map are reflected in this sorted map and vice versa.
- * <p>
- * Note: The returned map will not allow an insertion of a key outside the
- * specified range.
- * </p>
- *
- * @param endKey
- * the high boundary of the range specified.
- * @return a sorted map where the keys are less than {@code endKey}.
- * @throws ClassCastException
- * if the specified key cannot be compared with the keys in this
- * map.
- * @throws NullPointerException
- * if the specified key is {@code null} and the comparator
- * cannot handle {@code null} keys.
- * @throws IllegalArgumentException
- * if this map is itself a sorted map over a range of another
- * map and the specified key is outside of its range.
- * @since Android 1.0
- */
- public SortedMap<K, V> headMap(K endKey) {
- // Check for errors
- if (comparator == null) {
- toComparable(endKey).compareTo(endKey);
- } else {
- comparator.compare(endKey, endKey);
- }
- return new SubMap<K, V>(this, endKey);
- }
-
- /**
- * Returns a set of the keys contained in this map. The set is backed by
- * this map so changes to one are reflected by the other. The set does not
- * support adding.
- *
- * @return a set of the keys.
- * @since Android 1.0
- */
- @Override
- public Set<K> keySet() {
- if (keySet == null) {
- keySet = new AbstractSet<K>() {
- @Override
- public boolean contains(Object object) {
- return containsKey(object);
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public void clear() {
- TreeMap.this.clear();
- }
-
- @Override
- public Iterator<K> iterator() {
- return new UnboundedKeyIterator<K,V> (TreeMap.this);
- }
- };
- }
- return keySet;
- }
-
- /**
- * Returns the last key in this map.
- *
- * @return the last key in this map.
- * @throws NoSuchElementException
- * if this map is empty.
- * @since Android 1.0
- */
- public K lastKey() {
- if (root != null) {
- return maximum(root).key;
- }
- throw new NoSuchElementException();
- }
-
- private void leftRotate(Entry<K, V> x) {
- Entry<K, V> y = x.right;
- x.right = y.left;
- if (y.left != null) {
- y.left.parent = x;
- }
- y.parent = x.parent;
- if (x.parent == null) {
- root = y;
- } else {
- if (x == x.parent.left) {
- x.parent.left = y;
- } else {
- x.parent.right = y;
- }
- }
- y.left = x;
- x.parent = y;
- }
-
- static <K, V> Entry<K, V> maximum(Entry<K, V> x) {
- while (x.right != null) {
- x = x.right;
- }
- return x;
- }
-
- static <K, V> Entry<K, V> minimum(Entry<K, V> x) {
- while (x.left != null) {
- x = x.left;
- }
- return x;
- }
-
- static <K, V> Entry<K, V> predecessor(Entry<K, V> x) {
- if (x.left != null) {
- return maximum(x.left);
- }
- Entry<K, V> y = x.parent;
- while (y != null && x == y.left) {
- x = y;
- y = y.parent;
- }
- return y;
- }
-
- /**
- * Maps the specified key to the specified value.
- *
- * @param key
- * the key.
- * @param value
- * the value.
- * @return the value of any previous mapping with the specified key or
- * {@code null} if there was no mapping.
- * @throws ClassCastException
- * if the specified key cannot be compared with the keys in this
- * map.
- * @throws NullPointerException
- * if the specified key is {@code null} and the comparator
- * cannot handle {@code null} keys.
- * @since Android 1.0
- */
- @Override
- public V put(K key, V value) {
- MapEntry<K, V> entry = rbInsert(key);
- V result = entry.value;
- entry.value = value;
- return result;
- }
-
- /**
- * Copies all the mappings in the given map to this map. These mappings will
- * replace all mappings that this map had for any of the keys currently in
- * the given map.
- *
- * @param map
- * the map to copy mappings from.
- * @throws ClassCastException
- * if a key in the specified map cannot be compared with the
- * keys in this map.
- * @throws NullPointerException
- * if a key in the specified map is {@code null} and the
- * comparator cannot handle {@code null} keys.
- * @since Android 1.0
- */
- @Override
- public void putAll(Map<? extends K, ? extends V> map) {
- super.putAll(map);
- }
-
- void rbDelete(Entry<K, V> z) {
- Entry<K, V> y = z.left == null || z.right == null ? z : successor(z);
- Entry<K, V> x = y.left != null ? y.left : y.right;
- if (x != null) {
- x.parent = y.parent;
- }
- if (y.parent == null) {
- root = x;
- } else if (y == y.parent.left) {
- y.parent.left = x;
- } else {
- y.parent.right = x;
- }
- modCount++;
- if (y != z) {
- z.key = y.key;
- z.value = y.value;
- }
- if (!y.color && root != null) {
- if (x == null) {
- fixup(y.parent);
- } else {
- fixup(x);
- }
- }
- size--;
- }
-
- private Entry<K, V> rbInsert(K object) {
- int result = 0;
- Entry<K, V> y = null;
- if (size != 0) {
- Comparable<K> key = null;
- if (comparator == null) {
- key = toComparable(object);
- }
- Entry<K, V> x = root;
- while (x != null) {
- y = x;
- result = key != null ? key.compareTo(x.key) : comparator
- .compare(object, x.key);
- if (result == 0) {
- return x;
- }
- x = result < 0 ? x.left : x.right;
- }
- }
-
- size++;
- modCount++;
- Entry<K, V> z = new Entry<K, V>(object);
- if (y == null) {
- return root = z;
- }
- z.parent = y;
- if (result < 0) {
- y.left = z;
- } else {
- y.right = z;
- }
- balance(z);
- return z;
- }
-
- /**
- * Removes the mapping with the specified key from this map.
- *
- * @param key
- * the key of the mapping to remove.
- * @return the value of the removed mapping or {@code null} if no mapping
- * for the specified key was found.
- * @throws ClassCastException
- * if the specified key cannot be compared with the keys in this
- * map.
- * @throws NullPointerException
- * if the specified key is {@code null} and the comparator
- * cannot handle {@code null} keys.
- * @since Android 1.0
- */
- @Override
- public V remove(Object key) {
- if (size == 0) {
- return null;
- }
- Entry<K, V> node = find(key);
- if (node == null) {
- return null;
- }
- V result = node.value;
- rbDelete(node);
- return result;
- }
-
- private void rightRotate(Entry<K, V> x) {
- Entry<K, V> y = x.left;
- x.left = y.right;
- if (y.right != null) {
- y.right.parent = x;
- }
- y.parent = x.parent;
- if (x.parent == null) {
- root = y;
- } else {
- if (x == x.parent.right) {
- x.parent.right = y;
- } else {
- x.parent.left = y;
- }
- }
- y.right = x;
- x.parent = y;
- }
/**
* Returns the number of mappings in this map.
- *
+ *
* @return the number of mappings in this map.
- * @since Android 1.0
*/
@Override
public int size() {
@@ -1387,8 +2269,7 @@
* <p>
* Note: The returned map will not allow an insertion of a key outside the
* specified range.
- * </p>
- *
+ *
* @param startKey
* the low boundary of the range (inclusive).
* @param endKey
@@ -1404,7 +2285,6 @@
* if the start key is greater than the end key, or if this map
* is itself a sorted map over a range of another sorted map and
* the specified range is outside of its range.
- * @since Android 1.0
*/
public SortedMap<K, V> subMap(K startKey, K endKey) {
if (comparator == null) {
@@ -1419,18 +2299,6 @@
throw new IllegalArgumentException();
}
- static <K, V> Entry<K, V> successor(Entry<K, V> x) {
- if (x.right != null) {
- return minimum(x.right);
- }
- Entry<K, V> y = x.parent;
- while (y != null && x == y.right) {
- x = y;
- y = y.parent;
- }
- return y;
- }
-
/**
* Returns a sorted map over a range of this sorted map with all keys that
* are greater than or equal to the specified {@code startKey}. Changes to
@@ -1438,8 +2306,7 @@
* <p>
* Note: The returned map will not allow an insertion of a key outside the
* specified range.
- * </p>
- *
+ *
* @param startKey
* the low boundary of the range specified.
* @return a sorted map where the keys are greater or equal to
@@ -1453,7 +2320,6 @@
* @throws IllegalArgumentException
* if this map itself a sorted map over a range of another map
* and the specified key is outside of its range.
- * @since Android 1.0
*/
public SortedMap<K, V> tailMap(K startKey) {
// Check for errors
@@ -1476,16 +2342,13 @@
* "wrapper object" over the iterator of map's entrySet(). The {@code size}
* method wraps the map's size method and the {@code contains} method wraps
* the map's containsValue method.
- * </p>
* <p>
* The collection is created when this method is called for the first time
* and returned in response to all subsequent calls. This method may return
* different collections when multiple concurrent calls occur, since no
* synchronization is performed.
- * </p>
- *
+ *
* @return a collection of the values contained in this map.
- * @since Android 1.0
*/
@Override
public Collection<V> values() {
@@ -1508,7 +2371,7 @@
@Override
public Iterator<V> iterator() {
- return new UnboundedValueIterator<K,V> (TreeMap.this);
+ return new UnboundedValueIterator<K, V>(TreeMap.this);
}
};
}
@@ -1519,32 +2382,26 @@
stream.defaultWriteObject();
stream.writeInt(size);
if (size > 0) {
- Entry<K, V> node = minimum(root);
+ Node<K, V> node = minimum(root);
while (node != null) {
- stream.writeObject(node.key);
- stream.writeObject(node.value);
- node = successor(node);
+ int to = node.right_idx;
+ for (int i = node.left_idx; i <= to; i++) {
+ stream.writeObject(node.keys[i]);
+ stream.writeObject(node.values[i]);
+ }
+ node = node.next;
}
}
}
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream stream) throws IOException,
- ClassNotFoundException {
+ ClassNotFoundException {
stream.defaultReadObject();
- size = stream.readInt();
- Entry<K, V> last = null;
- for (int i = size; --i >= 0;) {
- Entry<K, V> node = new Entry<K, V>((K)stream.readObject());
- node.value = (V)stream.readObject();
- if (last == null) {
- root = node;
- } else {
- node.parent = last;
- last.right = node;
- balance(node);
- }
- last = node;
+ int size = stream.readInt();
+ Node<K, V> lastNode = null;
+ for (int i = 0; i < size; i++) {
+ lastNode = addToLast(lastNode, (K) stream.readObject(), (V) stream.readObject());
}
}
}
diff --git a/luni/src/main/java/java/util/TreeSet.java b/luni/src/main/java/java/util/TreeSet.java
index bfd572f..375b9c8 100644
--- a/luni/src/main/java/java/util/TreeSet.java
+++ b/luni/src/main/java/java/util/TreeSet.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
@@ -28,25 +27,23 @@
* and removing) are supported. The elements can be any objects which are
* comparable to each other either using their natural order or a specified
* Comparator.
- *
- * @since Android 1.0
+ *
+ * @since 1.2
*/
-public class TreeSet<E> extends AbstractSet<E> implements SortedSet<E>, Cloneable,
- Serializable {
-
+public class TreeSet<E> extends AbstractSet<E> implements SortedSet<E>,
+ Cloneable, Serializable {
+
private static final long serialVersionUID = -2479143000061671589L;
private transient SortedMap<E, E> backingMap;
- private TreeSet(SortedMap<E,E> map) {
+ private TreeSet(SortedMap<E, E> map) {
this.backingMap = map;
}
/**
* Constructs a new empty instance of {@code TreeSet} which uses natural
* ordering.
- *
- * @since Android 1.0
*/
public TreeSet() {
backingMap = new TreeMap<E, E>();
@@ -55,14 +52,13 @@
/**
* Constructs a new instance of {@code TreeSet} which uses natural ordering
* and containing the unique elements in the specified collection.
- *
+ *
* @param collection
* the collection of elements to add.
* @throws ClassCastException
* when an element in the collection does not implement the
* Comparable interface, or the elements in the collection
* cannot be compared.
- * @since Android 1.0
*/
public TreeSet(Collection<? extends E> collection) {
this();
@@ -72,10 +68,9 @@
/**
* Constructs a new empty instance of {@code TreeSet} which uses the
* specified comparator.
- *
+ *
* @param comparator
* the comparator to use.
- * @since Android 1.0
*/
public TreeSet(Comparator<? super E> comparator) {
backingMap = new TreeMap<E, E>(comparator);
@@ -84,10 +79,9 @@
/**
* Constructs a new instance of {@code TreeSet} containing the elements of
* the specified SortedSet and using the same Comparator.
- *
+ *
* @param set
* the SortedSet of elements to add.
- * @since Android 1.0
*/
public TreeSet(SortedSet<E> set) {
this(set.comparator());
@@ -99,7 +93,7 @@
/**
* Adds the specified object to this {@code TreeSet}.
- *
+ *
* @param object
* the object to add.
* @return {@code true} when this {@code TreeSet} did not already contain
@@ -110,7 +104,6 @@
* @throws NullPointerException
* when the object is null and the comparator cannot handle
* null.
- * @since Android 1.0
*/
@Override
public boolean add(E object) {
@@ -119,7 +112,7 @@
/**
* Adds the objects in the specified collection to this {@code TreeSet}.
- *
+ *
* @param collection
* the collection of objects to add.
* @return {@code true} if this {@code TreeSet} was modified, {@code false}
@@ -130,7 +123,6 @@
* @throws NullPointerException
* when an object in the collection is null and the comparator
* cannot handle null.
- * @since Android 1.0
*/
@Override
public boolean addAll(Collection<? extends E> collection) {
@@ -139,10 +131,9 @@
/**
* Removes all elements from this {@code TreeSet}, leaving it empty.
- *
+ *
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -152,10 +143,9 @@
/**
* Returns a new {@code TreeSet} with the same elements, size and comparator
* as this {@code TreeSet}.
- *
+ *
* @return a shallow copy of this {@code TreeSet}.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
@Override
@@ -163,7 +153,8 @@
try {
TreeSet<E> clone = (TreeSet<E>) super.clone();
if (backingMap instanceof TreeMap) {
- clone.backingMap = (SortedMap<E, E>) ((TreeMap<E, E>) backingMap).clone();
+ clone.backingMap = (SortedMap<E, E>) ((TreeMap<E, E>) backingMap)
+ .clone();
} else {
clone.backingMap = new TreeMap<E, E>(backingMap);
}
@@ -175,9 +166,8 @@
/**
* Returns the comparator used to compare elements in this {@code TreeSet}.
- *
+ *
* @return a Comparator or null if the natural ordering is used
- * @since Android 1.0
*/
public Comparator<? super E> comparator() {
return backingMap.comparator();
@@ -185,7 +175,7 @@
/**
* Searches this {@code TreeSet} for the specified object.
- *
+ *
* @param object
* the object to search for.
* @return {@code true} if {@code object} is an element of this
@@ -196,7 +186,6 @@
* @throws NullPointerException
* when the object is null and the comparator cannot handle
* null.
- * @since Android 1.0
*/
@Override
public boolean contains(Object object) {
@@ -205,11 +194,10 @@
/**
* Returns the first element in this {@code TreeSet}.
- *
+ *
* @return the first element.
* @throws NoSuchElementException
* when this {@code TreeSet} is empty.
- * @since Android 1.0
*/
public E first() {
return backingMap.firstKey();
@@ -220,7 +208,7 @@
* which contains elements which are all less than the end element. The
* returned SortedSet is backed by this {@code TreeSet} so changes to one
* are reflected by the other.
- *
+ *
* @param end
* the end element.
* @return a subset where the elements are less than {@code end}
@@ -230,7 +218,6 @@
* @throws NullPointerException
* when the end object is null and the comparator cannot handle
* null.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public SortedSet<E> headSet(E end) {
@@ -246,10 +233,9 @@
/**
* Returns true if this {@code TreeSet} has no element, otherwise false.
- *
+ *
* @return true if this {@code TreeSet} has no element.
* @see #size
- * @since Android 1.0
*/
@Override
public boolean isEmpty() {
@@ -258,10 +244,9 @@
/**
* Returns an Iterator on the elements of this {@code TreeSet}.
- *
+ *
* @return an Iterator on the elements of this {@code TreeSet}.
* @see Iterator
- * @since Android 1.0
*/
@Override
public Iterator<E> iterator() {
@@ -271,11 +256,10 @@
/**
* Returns the last element in this {@code TreeSet}. The last element is
* the highest element.
- *
+ *
* @return the last element.
* @throws NoSuchElementException
* when this {@code TreeSet} is empty.
- * @since Android 1.0
*/
public E last() {
return backingMap.lastKey();
@@ -283,7 +267,7 @@
/**
* Removes an occurrence of the specified object from this {@code TreeSet}.
- *
+ *
* @param object
* the object to remove.
* @return {@code true} if this {@code TreeSet} was modified, {@code false}
@@ -294,7 +278,6 @@
* @throws NullPointerException
* when the object is null and the comparator cannot handle
* null.
- * @since Android 1.0
*/
@Override
public boolean remove(Object object) {
@@ -303,9 +286,8 @@
/**
* Returns the number of elements in this {@code TreeSet}.
- *
+ *
* @return the number of elements in this {@code TreeSet}.
- * @since Android 1.0
*/
@Override
public int size() {
@@ -317,7 +299,7 @@
* which contains elements greater or equal to the start element but less
* than the end element. The returned SortedSet is backed by this
* {@code TreeSet} so changes to one are reflected by the other.
- *
+ *
* @param start
* the start element.
* @param end
@@ -330,7 +312,6 @@
* @throws NullPointerException
* when the start or end object is null and the comparator
* cannot handle null.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public SortedSet<E> subSet(E start, E end) {
@@ -352,7 +333,7 @@
* which contains elements greater or equal to the start element. The
* returned SortedSet is backed by this {@code TreeSet} so changes to one
* are reflected by the other.
- *
+ *
* @param start
* the start element.
* @return a subset where the elements are greater or equal to {@code start}
@@ -362,7 +343,6 @@
* @throws NullPointerException
* when the start object is null and the comparator cannot
* handle null.
- * @since Android 1.0
*/
@SuppressWarnings("unchecked")
public SortedSet<E> tailSet(E start) {
@@ -391,23 +371,16 @@
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream stream) throws IOException,
- ClassNotFoundException {
+ ClassNotFoundException {
stream.defaultReadObject();
- TreeMap<E, E> map = new TreeMap<E, E>((Comparator<? super E>) stream.readObject());
+ TreeMap<E, E> map = new TreeMap<E, E>((Comparator<? super E>) stream
+ .readObject());
int size = stream.readInt();
if (size > 0) {
- E key = (E)stream.readObject();
- TreeMap.Entry<E,E> last = new TreeMap.Entry<E,E>(key,key);
- map.root = last;
- map.size = 1;
- for (int i=1; i<size; i++) {
- key = (E)stream.readObject();
- TreeMap.Entry<E,E> x = new TreeMap.Entry<E,E>(key,key);
- x.parent = last;
- last.right = x;
- map.size++;
- map.balance(x);
- last = x;
+ TreeMap.Node<E,E> lastNode = null;
+ for(int i=0; i<size; i++) {
+ E elem = (E)stream.readObject();
+ lastNode = map.addToLast(lastNode,elem,elem);
}
}
backingMap = map;
diff --git a/luni/src/main/java/java/util/UUID.java b/luni/src/main/java/java/util/UUID.java
index a5ab702..081e900 100644
--- a/luni/src/main/java/java/util/UUID.java
+++ b/luni/src/main/java/java/util/UUID.java
@@ -27,19 +27,16 @@
import org.apache.harmony.luni.util.Msg;
/**
- * <p>
* UUID is an immutable representation of a 128-bit universally unique
* identifier (UUID).
- * </p>
* <p>
* There are multiple, variant layouts of UUIDs, but this class is based upon
* variant 2 of <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>, the
* Leach-Salz variant. This class can be used to model alternate variants, but
* most of the methods will be unsupported in those cases; see each method for
* details.
- * </p>
- *
- * @since Android 1.0
+ *
+ * @since 1.5
*/
public final class UUID implements Serializable, Comparable<UUID> {
@@ -60,13 +57,11 @@
/**
* <p>
* Constructs an instance with the specified bits.
- * </p>
- *
+ *
* @param mostSigBits
* The 64 most significant bits of the UUID.
* @param leastSigBits
* The 64 least significant bits of the UUID.
- * @since Android 1.0
*/
public UUID(long mostSigBits, long leastSigBits) {
super();
@@ -79,7 +74,6 @@
* <p>
* Sets up the transient fields of this instance based on the current values
* of the {@code mostSigBits} and {@code leastSigBits} fields.
- * </p>
*/
private void init() {
// setup hash field
@@ -123,10 +117,8 @@
* <p>
* Generates a variant 2, version 4 (randomly generated number) UUID as per
* <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- * </p>
- *
+ *
* @return an UUID instance.
- * @since Android 1.0
*/
public static UUID randomUUID() {
byte[] data;
@@ -135,9 +127,8 @@
if (rng == null) {
rng = new SecureRandom();
}
- rng.nextBytes(data = new byte[16]);
}
-
+ rng.nextBytes(data = new byte[16]);
long msb = (data[0] & 0xFFL) << 56;
msb |= (data[1] & 0xFFL) << 48;
msb |= (data[2] & 0xFFL) << 40;
@@ -164,12 +155,10 @@
* <p>
* Generates a variant 2, version 3 (name-based, MD5-hashed) UUID as per <a
* href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- * </p>
- *
+ *
* @param name
* the name used as byte array to create an UUID.
* @return an UUID instance.
- * @since Android 1.0
*/
public static UUID nameUUIDFromBytes(byte[] name) {
if (name == null) {
@@ -209,57 +198,57 @@
/**
* <p>
* Parses a UUID string with the format defined by {@link #toString()}.
- * </p>
- *
+ *
* @param uuid
* the UUID string to parse.
* @return an UUID instance.
+ * @throws NullPointerException
+ * if {@code uuid} is {@code null}.
* @throws IllegalArgumentException
* if {@code uuid} is not formatted correctly.
- * @since Android 1.0
*/
public static UUID fromString(String uuid) {
if (uuid == null) {
throw new NullPointerException();
}
-
+
int[] position = new int[5];
int lastPosition = 1;
int startPosition = 0;
-
+
int i = 0;
- for (; i < position.length && lastPosition > 0; i++) {
+ for (; i < position.length && lastPosition > 0; i++) {
position[i] = uuid.indexOf("-", startPosition); //$NON-NLS-1$
lastPosition = position[i];
startPosition = position[i] + 1;
}
// should have and only can have four "-" in UUID
- if(i != position.length || lastPosition != -1)
- {
+ if (i != position.length || lastPosition != -1) {
throw new IllegalArgumentException(Msg.getString("KA014") + uuid); //$NON-NLS-1$
}
long m1 = Long.parseLong(uuid.substring(0, position[0]), 16);
- long m2 = Long.parseLong(uuid.substring(position[0]+ 1, position[1]), 16);
- long m3 = Long.parseLong(uuid.substring(position[1] + 1, position[2]), 16);
+ long m2 = Long.parseLong(uuid.substring(position[0] + 1, position[1]),
+ 16);
+ long m3 = Long.parseLong(uuid.substring(position[1] + 1, position[2]),
+ 16);
- long lsb1 = Long.parseLong(uuid.substring(position[2] + 1, position[3]), 16);
- long lsb2 = Long.parseLong(uuid.substring(position[3]+ 1), 16);
+ long lsb1 = Long.parseLong(
+ uuid.substring(position[2] + 1, position[3]), 16);
+ long lsb2 = Long.parseLong(uuid.substring(position[3] + 1), 16);
long msb = (m1 << 32) | (m2 << 16) | m3;
long lsb = (lsb1 << 48) | lsb2;
-
+
return new UUID(msb, lsb);
}
/**
* <p>
* The 64 least significant bits of the UUID.
- * </p>
- *
+ *
* @return the 64 least significant bits.
- * @since Android 1.0
*/
public long getLeastSignificantBits() {
return leastSigBits;
@@ -268,10 +257,8 @@
/**
* <p>
* The 64 most significant bits of the UUID.
- * </p>
- *
+ *
* @return the 64 most significant bits.
- * @since Android 1.0
*/
public long getMostSignificantBits() {
return mostSigBits;
@@ -282,7 +269,6 @@
* The version of the variant 2 UUID as per <a
* href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>. If the variant
* is not 2, then the version will be 0.
- * </p>
* <ul>
* <li>1 - Time-based UUID</li>
* <li>2 - DCE Security UUID</li>
@@ -290,9 +276,8 @@
* <li>4 - Randomly generated UUID ({@link #randomUUID()})</li>
* <li>5 - Name-based with SHA-1 hashing UUID</li>
* </ul>
- *
+ *
* @return an {@code int} value.
- * @since Android 1.0
*/
public int version() {
return version;
@@ -302,16 +287,14 @@
* <p>
* The variant of the UUID as per <a
* href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- * </p>
* <ul>
* <li>0 - Reserved for NCS compatibility</li>
* <li>2 - RFC 4122/Leach-Salz</li>
* <li>6 - Reserved for Microsoft Corporation compatibility</li>
* <li>7 - Reserved for future use</li>
* </ul>
- *
+ *
* @return an {@code int} value.
- * @since Android 1.0
*/
public int variant() {
return variant;
@@ -321,12 +304,10 @@
* <p>
* The timestamp value of the version 1, variant 2 UUID as per <a
* href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- * </p>
- *
+ *
* @return a {@code long} value.
* @throws UnsupportedOperationException
* if {@link #version()} is not 1.
- * @since Android 1.0
*/
public long timestamp() {
if (version != 1) {
@@ -339,12 +320,10 @@
* <p>
* The clock sequence value of the version 1, variant 2 UUID as per <a
* href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- * </p>
- *
+ *
* @return a {@code long} value.
* @throws UnsupportedOperationException
* if {@link #version()} is not 1.
- * @since Android 1.0
*/
public int clockSequence() {
if (version != 1) {
@@ -357,12 +336,10 @@
* <p>
* The node value of the version 1, variant 2 UUID as per <a
* href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- * </p>
- *
+ *
* @return a {@code long} value.
* @throws UnsupportedOperationException
* if {@link #version()} is not 1.
- * @since Android 1.0
*/
public long node() {
if (version != 1) {
@@ -376,13 +353,11 @@
* Compares this UUID to the specified UUID. The natural ordering of UUIDs
* is based upon the value of the bits from most significant to least
* significant.
- * </p>
- *
+ *
* @param uuid
* the UUID to compare to.
* @return a value of -1, 0 or 1 if this UUID is less than, equal to or
* greater than {@code uuid}.
- * @since Android 1.0
*/
public int compareTo(UUID uuid) {
if (uuid == this) {
@@ -409,13 +384,11 @@
* Compares this UUID to another object for equality. If {@code object}
* is not {@code null}, is a UUID instance, and all bits are equal, then
* {@code true} is returned.
- * </p>
- *
+ *
* @param object
* the {@code Object} to compare to.
* @return {@code true} if this UUID is equal to {@code object}
* or {@code false} if not.
- * @since Android 1.0
*/
@Override
public boolean equals(Object object) {
@@ -441,10 +414,8 @@
* <p>
* Returns a hash value for this UUID that is consistent with the
* {@link #equals(Object)} method.
- * </p>
- *
+ *
* @return an {@code int} value.
- * @since Android 1.0
*/
@Override
public int hashCode() {
@@ -455,8 +426,7 @@
* <p>
* Returns a string representation of this UUID in the following format, as
* per <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
- * </p>
- *
+ *
* <pre>
* UUID = time-low "-" time-mid "-"
* time-high-and-version "-"
@@ -474,9 +444,8 @@
* "a" / "b" / "c" / "d" / "e" / "f" /
* "A" / "B" / "C" / "D" / "E" / "F"
* </pre>
- *
+ *
* @return a String instance.
- * @since Android 1.0
*/
@Override
public String toString() {
@@ -507,8 +476,7 @@
/**
* <p>
* Resets the transient fields to match the behavior of the constructor.
- * </p>
- *
+ *
* @param in
* the {@code InputStream} to read from.
* @throws IOException
diff --git a/luni/src/main/java/java/util/UnknownFormatConversionException.java b/luni/src/main/java/java/util/UnknownFormatConversionException.java
index 19b9b6d..8bb9441 100644
--- a/luni/src/main/java/java/util/UnknownFormatConversionException.java
+++ b/luni/src/main/java/java/util/UnknownFormatConversionException.java
@@ -22,7 +22,6 @@
* conversion is unknown.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class UnknownFormatConversionException extends IllegalFormatException {
private static final long serialVersionUID = 19060418L;
diff --git a/luni/src/main/java/java/util/UnknownFormatFlagsException.java b/luni/src/main/java/java/util/UnknownFormatFlagsException.java
index 837328a..2a1b075 100644
--- a/luni/src/main/java/java/util/UnknownFormatFlagsException.java
+++ b/luni/src/main/java/java/util/UnknownFormatFlagsException.java
@@ -23,7 +23,6 @@
* an unknown flag.
*
* @see java.lang.RuntimeException
- * @since Android 1.0
*/
public class UnknownFormatFlagsException extends IllegalFormatException {
diff --git a/luni/src/main/java/java/util/Vector.java b/luni/src/main/java/java/util/Vector.java
index 7a5c775..8634c13 100644
--- a/luni/src/main/java/java/util/Vector.java
+++ b/luni/src/main/java/java/util/Vector.java
@@ -17,7 +17,6 @@
package java.util;
-
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
@@ -36,26 +35,21 @@
* The capacity of a vector may be specified when the vector is created. If the
* capacity of the vector is exceeded, the capacity is increased (doubled by
* default).
- *
+ *
* @see java.lang.StringBuffer
- * @since Android 1.0
*/
-public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess,
- Cloneable, Serializable {
-
+public class Vector<E> extends AbstractList<E> implements List<E>,
+ RandomAccess, Cloneable, Serializable {
+
private static final long serialVersionUID = -2767605614048989439L;
/**
* The number of elements or the size of the vector.
- *
- * @since Android 1.0
*/
protected int elementCount;
/**
* The elements of the vector.
- *
- * @since Android 1.0
*/
protected Object[] elementData;
@@ -63,8 +57,6 @@
* How many elements should be added to the vector when it is detected that
* it needs to grow to accommodate extra entries. If this value is zero or
* negative the size will be doubled if an increase is needed.
- *
- * @since Android 1.0
*/
protected int capacityIncrement;
@@ -72,8 +64,6 @@
/**
* Constructs a new vector using the default capacity.
- *
- * @since Android 1.0
*/
public Vector() {
this(DEFAULT_SIZE, 0);
@@ -81,12 +71,11 @@
/**
* Constructs a new vector using the specified capacity.
- *
+ *
* @param capacity
* the initial capacity of the new vector.
* @throws IllegalArgumentException
* if {@code capacity} is negative.
- * @since Android 1.0
*/
public Vector(int capacity) {
this(capacity, 0);
@@ -95,22 +84,20 @@
/**
* Constructs a new vector using the specified capacity and capacity
* increment.
- *
+ *
* @param capacity
* the initial capacity of the new vector.
* @param capacityIncrement
* the amount to increase the capacity when this vector is full.
* @throws IllegalArgumentException
* if {@code capacity} is negative.
- * @since Android 1.0
*/
public Vector(int capacity, int capacityIncrement) {
- elementCount = 0;
- try {
- elementData = newElementArray(capacity);
- } catch (NegativeArraySizeException e) {
+ if (capacity < 0) {
throw new IllegalArgumentException();
}
+ elementData = newElementArray(capacity);
+ elementCount = 0;
this.capacityIncrement = capacityIncrement;
}
@@ -118,10 +105,9 @@
* Constructs a new instance of {@code Vector} containing the elements in
* {@code collection}. The order of the elements in the new {@code Vector}
* is dependent on the iteration order of the seed collection.
- *
+ *
* @param collection
* the collection of elements to add.
- * @since Android 1.0
*/
public Vector(Collection<? extends E> collection) {
this(collection.size(), 0);
@@ -130,10 +116,10 @@
elementData[elementCount++] = it.next();
}
}
-
+
@SuppressWarnings("unchecked")
private E[] newElementArray(int size) {
- return (E[])new Object[size];
+ return (E[]) new Object[size];
}
/**
@@ -141,16 +127,15 @@
* object is inserted before any element with the same or a higher index
* increasing their index by 1. If the location is equal to the size of this
* vector, the object is added at the end.
- *
+ *
* @param location
* the index at which to insert the element.
* @param object
* the object to insert in this vector.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0 || location > size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0 || location > size()}.
* @see #addElement
* @see #size
- * @since Android 1.0
*/
@Override
public void add(int location, E object) {
@@ -159,15 +144,18 @@
/**
* Adds the specified object at the end of this vector.
- *
+ *
* @param object
* the object to add to the vector.
* @return {@code true}
- * @since Android 1.0
*/
@Override
- public boolean add(E object) {
- addElement(object);
+ public synchronized boolean add(E object) {
+ if (elementCount == elementData.length) {
+ growByOne();
+ }
+ elementData[elementCount++] = object;
+ modCount++;
return true;
}
@@ -177,18 +165,18 @@
* returned from the Collection iterator. The elements with an index equal
* or higher than {@code location} have their index increased by the size of
* the added collection.
- *
+ *
* @param location
* the location to insert the objects.
* @param collection
* the collection of objects.
* @return {@code true} if this vector is modified, {@code false} otherwise.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0} or {@code location > size()}.
- * @since Android 1.0
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0} or {@code location > size()}.
*/
@Override
- public synchronized boolean addAll(int location, Collection<? extends E> collection) {
+ public synchronized boolean addAll(int location,
+ Collection<? extends E> collection) {
if (0 <= location && location <= elementCount) {
int size = collection.size();
if (size == 0) {
@@ -216,11 +204,10 @@
/**
* Adds the objects in the specified collection to the end of this vector.
- *
+ *
* @param collection
* the collection of objects.
* @return {@code true} if this vector is modified, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public synchronized boolean addAll(Collection<? extends E> collection) {
@@ -229,10 +216,9 @@
/**
* Adds the specified object at the end of this vector.
- *
+ *
* @param object
* the object to add to the vector.
- * @since Android 1.0
*/
public synchronized void addElement(E object) {
if (elementCount == elementData.length) {
@@ -244,11 +230,10 @@
/**
* Returns the number of elements this vector can hold without growing.
- *
+ *
* @return the capacity of this vector.
* @see #ensureCapacity
* @see #size
- * @since Android 1.0
*/
public synchronized int capacity() {
return elementData.length;
@@ -256,10 +241,9 @@
/**
* Removes all elements from this vector, leaving it empty.
- *
+ *
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -269,10 +253,9 @@
/**
* Returns a new vector with the same elements, size, capacity and capacity
* increment as this vector.
- *
+ *
* @return a shallow copy of this vector.
* @see java.lang.Cloneable
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -288,7 +271,7 @@
/**
* Searches this vector for the specified object.
- *
+ *
* @param object
* the object to look for in this vector.
* @return {@code true} if object is an element of this vector,
@@ -296,7 +279,6 @@
* @see #indexOf(Object)
* @see #indexOf(Object, int)
* @see java.lang.Object#equals
- * @since Android 1.0
*/
@Override
public boolean contains(Object object) {
@@ -305,12 +287,11 @@
/**
* Searches this vector for all objects in the specified collection.
- *
+ *
* @param collection
* the collection of objects.
* @return {@code true} if all objects in the specified collection are
* elements of this vector, {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public synchronized boolean containsAll(Collection<?> collection) {
@@ -320,14 +301,13 @@
/**
* Attempts to copy elements contained by this {@code Vector} into the
* corresponding elements of the supplied {@code Object} array.
- *
+ *
* @param elements
* the {@code Object} array into which the elements of this
* vector are copied.
* @throws IndexOutOfBoundsException
* if {@code elements} is not big enough.
* @see #clone
- * @since Android 1.0
*/
public synchronized void copyInto(Object[] elements) {
System.arraycopy(elementData, 0, elements, 0, elementCount);
@@ -335,18 +315,18 @@
/**
* Returns the element at the specified location in this vector.
- *
+ *
* @param location
* the index of the element to return in this vector.
* @return the element at the specified location.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0 || location >= size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0 || location >= size()}.
* @see #size
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
public synchronized E elementAt(int location) {
if (location < elementCount) {
- return (E)elementData[location];
+ return (E) elementData[location];
}
throw new ArrayIndexOutOfBoundsException(location);
}
@@ -354,26 +334,24 @@
/**
* Returns an enumeration on the elements of this vector. The results of the
* enumeration may be affected if the contents of this vector is modified.
- *
+ *
* @return an enumeration of the elements of this vector.
* @see #elementAt
* @see Enumeration
- * @since Android 1.0
*/
public Enumeration<E> elements() {
return new Enumeration<E>() {
int pos = 0;
public boolean hasMoreElements() {
- synchronized (Vector.this) {
- return pos < elementCount;
- }
+ return pos < elementCount;
}
+ @SuppressWarnings("unchecked")
public E nextElement() {
synchronized (Vector.this) {
if (pos < elementCount) {
- return (E)elementData[pos++];
+ return (E) elementData[pos++];
}
}
throw new NoSuchElementException();
@@ -384,12 +362,11 @@
/**
* Ensures that this vector can hold the specified number of elements
* without growing.
- *
+ *
* @param minimumCapacity
* the minimum number of elements that this vector will hold
* before growing.
* @see #capacity
- * @since Android 1.0
*/
public synchronized void ensureCapacity(int minimumCapacity) {
if (elementData.length < minimumCapacity) {
@@ -404,13 +381,12 @@
* Compares the specified object to this vector and returns if they are
* equal. The object must be a List which contains the same objects in the
* same order.
- *
+ *
* @param object
* the object to compare with this object
* @return {@code true} if the specified object is equal to this vector,
* {@code false} otherwise.
* @see #hashCode
- * @since Android 1.0
*/
@Override
public synchronized boolean equals(Object object) {
@@ -418,8 +394,8 @@
return true;
}
if (object instanceof List) {
- List<?> list = (List) object;
- if (list.size() != size()) {
+ List<?> list = (List<?>) object;
+ if (list.size() != elementCount) {
return false;
}
@@ -438,35 +414,34 @@
/**
* Returns the first element in this vector.
- *
+ *
* @return the element at the first position.
- * @exception NoSuchElementException
- * when this vector is empty.
+ * @throws NoSuchElementException
+ * if this vector is empty.
* @see #elementAt
* @see #lastElement
* @see #size
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
public synchronized E firstElement() {
if (elementCount > 0) {
- return (E)elementData[0];
+ return (E) elementData[0];
}
throw new NoSuchElementException();
}
/**
* Returns the element at the specified location in this vector.
- *
+ *
* @param location
* the index of the element to return in this vector.
* @return the element at the specified location.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0 || location >= size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0 || location >= size()}.
* @see #size
- * @since Android 1.0
*/
@Override
- public synchronized E get(int location) {
+ public E get(int location) {
return elementAt(location);
}
@@ -474,7 +449,7 @@
E[] newData = newElementArray(newCapacity);
// Assumes elementCount is <= newCapacity
assert elementCount <= newCapacity;
- System.arraycopy(elementData, 0, newData, 0, elementCount);
+ System.arraycopy(elementData, 0, newData, 0, elementCount);
elementData = newData;
}
@@ -519,10 +494,9 @@
/**
* Returns an integer hash code for the receiver. Objects which are equal
* return the same value for this method.
- *
+ *
* @return the receiver's hash.
* @see #equals
- * @since Android 1.0
*/
@Override
public synchronized int hashCode() {
@@ -538,7 +512,7 @@
* Searches in this vector for the index of the specified object. The search
* for the object starts at the beginning and moves towards the end of this
* vector.
- *
+ *
* @param object
* the object to find in this vector.
* @return the index in this vector of the specified element, -1 if the
@@ -546,7 +520,6 @@
* @see #contains
* @see #lastIndexOf(Object)
* @see #lastIndexOf(Object, int)
- * @since Android 1.0
*/
@Override
public int indexOf(Object object) {
@@ -557,19 +530,18 @@
* Searches in this vector for the index of the specified object. The search
* for the object starts at the specified location and moves towards the end
* of this vector.
- *
+ *
* @param object
* the object to find in this vector.
* @param location
* the index at which to start searching.
* @return the index in this vector of the specified element, -1 if the
* element isn't found.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0}.
* @see #contains
* @see #lastIndexOf(Object)
* @see #lastIndexOf(Object, int)
- * @since Android 1.0
*/
public synchronized int indexOf(Object object, int location) {
if (object != null) {
@@ -594,16 +566,15 @@
* location. All elements with an index equal or greater than
* {@code location} have their index increased by 1. If the location is
* equal to the size of this vector, the object is added at the end.
- *
+ *
* @param object
* the object to insert in this vector.
* @param location
* the index at which to insert the element.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0 || location > size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0 || location > size()}.
* @see #addElement
* @see #size
- * @since Android 1.0
*/
public synchronized void insertElementAt(E object, int location) {
if (0 <= location && location <= elementCount) {
@@ -625,11 +596,10 @@
/**
* Returns if this vector has no elements, a size of zero.
- *
+ *
* @return {@code true} if this vector has no elements, {@code false}
* otherwise.
* @see #size
- * @since Android 1.0
*/
@Override
public synchronized boolean isEmpty() {
@@ -638,18 +608,18 @@
/**
* Returns the last element in this vector.
- *
+ *
* @return the element at the last position.
- * @exception NoSuchElementException
- * when this vector is empty.
+ * @throws NoSuchElementException
+ * if this vector is empty.
* @see #elementAt
* @see #firstElement
* @see #size
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
public synchronized E lastElement() {
try {
- return (E)elementData[elementCount - 1];
+ return (E) elementData[elementCount - 1];
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
@@ -659,7 +629,7 @@
* Searches in this vector for the index of the specified object. The search
* for the object starts at the end and moves towards the start of this
* vector.
- *
+ *
* @param object
* the object to find in this vector.
* @return the index in this vector of the specified element, -1 if the
@@ -667,7 +637,6 @@
* @see #contains
* @see #indexOf(Object)
* @see #indexOf(Object, int)
- * @since Android 1.0
*/
@Override
public synchronized int lastIndexOf(Object object) {
@@ -678,19 +647,18 @@
* Searches in this vector for the index of the specified object. The search
* for the object starts at the specified location and moves towards the
* start of this vector.
- *
+ *
* @param object
* the object to find in this vector.
* @param location
* the index at which to start searching.
* @return the index in this vector of the specified element, -1 if the
* element isn't found.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location >= size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location >= size()}.
* @see #contains
* @see #indexOf(Object)
* @see #indexOf(Object, int)
- * @since Android 1.0
*/
public synchronized int lastIndexOf(Object object, int location) {
if (location < elementCount) {
@@ -716,18 +684,18 @@
* Removes the object at the specified location from this vector. All
* elements with an index bigger than {@code location} have their index
* decreased by 1.
- *
+ *
* @param location
* the index of the object to remove.
* @return the removed object.
- * @exception IndexOutOfBoundsException
- * when {@code location < 0 || location >= size()}.
- * @since Android 1.0
+ * @throws IndexOutOfBoundsException
+ * if {@code location < 0 || location >= size()}.
*/
+ @SuppressWarnings("unchecked")
@Override
public synchronized E remove(int location) {
if (location < elementCount) {
- E result = (E)elementData[location];
+ E result = (E) elementData[location];
elementCount--;
int size = elementCount - location;
if (size > 0) {
@@ -746,7 +714,7 @@
* towards the end, of the specified object from this vector. All elements
* with an index bigger than the element that gets removed have their index
* decreased by 1.
- *
+ *
* @param object
* the object to remove from this vector.
* @return {@code true} if the specified object was found, {@code false}
@@ -754,7 +722,6 @@
* @see #removeAllElements
* @see #removeElementAt
* @see #size
- * @since Android 1.0
*/
@Override
public boolean remove(Object object) {
@@ -764,13 +731,12 @@
/**
* Removes all occurrences in this vector of each object in the specified
* Collection.
- *
+ *
* @param collection
* the collection of objects to remove.
* @return {@code true} if this vector is modified, {@code false} otherwise.
* @see #remove(Object)
* @see #contains(Object)
- * @since Android 1.0
*/
@Override
public synchronized boolean removeAll(Collection<?> collection) {
@@ -780,13 +746,14 @@
/**
* Removes all elements from this vector, leaving the size zero and the
* capacity unchanged.
- *
+ *
* @see #isEmpty
* @see #size
- * @since Android 1.0
*/
public synchronized void removeAllElements() {
- Arrays.fill(elementData, 0, elementCount, null);
+ for (int i = 0; i < elementCount; i++) {
+ elementData[i] = null;
+ }
modCount++;
elementCount = 0;
}
@@ -796,7 +763,7 @@
* towards the end, of the specified object from this vector. All elements
* with an index bigger than the element that gets removed have their index
* decreased by 1.
- *
+ *
* @param object
* the object to remove from this vector.
* @return {@code true} if the specified object was found, {@code false}
@@ -804,7 +771,6 @@
* @see #removeAllElements
* @see #removeElementAt
* @see #size
- * @since Android 1.0
*/
public synchronized boolean removeElement(Object object) {
int index;
@@ -819,15 +785,14 @@
* Removes the element found at index position {@code location} from
* this {@code Vector}. All elements with an index bigger than
* {@code location} have their index decreased by 1.
- *
+ *
* @param location
* the index of the element to remove.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0 || location >= size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0 || location >= size()}.
* @see #removeElement
* @see #removeAllElements
* @see #size
- * @since Android 1.0
*/
public synchronized void removeElementAt(int location) {
if (0 <= location && location < elementCount) {
@@ -848,19 +813,18 @@
* Removes the objects in the specified range from the start to the, but not
* including, end index. All elements with an index bigger than or equal to
* {@code end} have their index decreased by {@code end - start}.
- *
+ *
* @param start
* the index at which to start removing.
* @param end
* the index one past the end of the range to remove.
- * @exception IndexOutOfBoundsException
- * when {@code start < 0, start > end} or
+ * @throws IndexOutOfBoundsException
+ * if {@code start < 0, start > end} or
* {@code end > size()}.
- * @since Android 1.0
*/
@Override
protected void removeRange(int start, int end) {
- if (start >= 0 && start <= end && end <= size()) {
+ if (start >= 0 && start <= end && end <= elementCount) {
if (start == end) {
return;
}
@@ -883,12 +847,11 @@
/**
* Removes all objects from this vector that are not contained in the
* specified collection.
- *
+ *
* @param collection
* the collection of objects to retain.
* @return {@code true} if this vector is modified, {@code false} otherwise.
* @see #remove(Object)
- * @since Android 1.0
*/
@Override
public synchronized boolean retainAll(Collection<?> collection) {
@@ -898,21 +861,21 @@
/**
* Replaces the element at the specified location in this vector with the
* specified object.
- *
+ *
* @param location
* the index at which to put the specified object.
* @param object
* the object to add to this vector.
* @return the previous element at the location.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0 || location >= size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0 || location >= size()}.
* @see #size
- * @since Android 1.0
*/
+ @SuppressWarnings("unchecked")
@Override
public synchronized E set(int location, E object) {
if (location < elementCount) {
- E result = (E)elementData[location];
+ E result = (E) elementData[location];
elementData[location] = object;
return result;
}
@@ -922,15 +885,14 @@
/**
* Replaces the element at the specified location in this vector with the
* specified object.
- *
+ *
* @param object
* the object to add to this vector.
* @param location
* the index at which to put the specified object.
- * @exception ArrayIndexOutOfBoundsException
- * when {@code location < 0 || location >= size()}.
+ * @throws ArrayIndexOutOfBoundsException
+ * if {@code location < 0 || location >= size()}.
* @see #size
- * @since Android 1.0
*/
public synchronized void setElementAt(E object, int location) {
if (location < elementCount) {
@@ -945,11 +907,10 @@
* than length elements in this vector, the elements at end are lost. If
* there are less than length elements in the vector, the additional
* elements contain null.
- *
+ *
* @param length
* the new size of this vector.
* @see #size
- * @since Android 1.0
*/
public synchronized void setSize(int length) {
if (length == elementCount) {
@@ -965,11 +926,10 @@
/**
* Returns the number of elements in this vector.
- *
+ *
* @return the number of elements in this vector.
* @see #elementCount
* @see #lastElement
- * @since Android 1.0
*/
@Override
public synchronized int size() {
@@ -980,29 +940,27 @@
* Returns a List of the specified portion of this vector from the start
* index to one less than the end index. The returned List is backed by this
* vector so changes to one are reflected by the other.
- *
+ *
* @param start
* the index at which to start the sublist.
* @param end
* the index one past the end of the sublist.
* @return a List of a portion of this vector.
- * @exception IndexOutOfBoundsException
- * when {@code start < 0} or {@code end > size()}.
- * @exception IllegalArgumentException
- * when {@code start > end}.
- * @since Android 1.0
+ * @throws IndexOutOfBoundsException
+ * if {@code start < 0} or {@code end > size()}.
+ * @throws IllegalArgumentException
+ * if {@code start > end}.
*/
@Override
public synchronized List<E> subList(int start, int end) {
- return new Collections.SynchronizedRandomAccessList<E>(
- super.subList(start, end), this);
+ return new Collections.SynchronizedRandomAccessList<E>(super.subList(
+ start, end), this);
}
/**
* Returns a new array containing all elements contained in this vector.
- *
+ *
* @return an array of the elements from this vector.
- * @since Android 1.0
*/
@Override
public synchronized Object[] toArray() {
@@ -1017,14 +975,13 @@
* is used, otherwise an array of the same type is created. If the specified
* array is used and is larger than this vector, the array element following
* the collection elements is set to null.
- *
+ *
* @param contents
* the array to fill.
* @return an array of the elements from this vector.
- * @exception ArrayStoreException
- * when the type of an element in this vector cannot be
+ * @throws ArrayStoreException
+ * if the type of an element in this vector cannot be
* stored in the type of the specified array.
- * @since Android 1.0
*/
@Override
@SuppressWarnings("unchecked")
@@ -1042,29 +999,28 @@
/**
* Returns the string representation of this vector.
- *
+ *
* @return the string representation of this vector.
* @see #elements
- * @since Android 1.0
*/
@Override
public synchronized String toString() {
if (elementCount == 0) {
- return "[]";
+ return "[]"; //$NON-NLS-1$
}
int length = elementCount - 1;
- StringBuffer buffer = new StringBuffer(size() * 16);
+ StringBuffer buffer = new StringBuffer(elementCount * 16);
buffer.append('[');
for (int i = 0; i < length; i++) {
if (elementData[i] == this) {
- buffer.append("(this Collection)");
+ buffer.append("(this Collection)"); //$NON-NLS-1$
} else {
buffer.append(elementData[i]);
}
- buffer.append(", ");
+ buffer.append(", "); //$NON-NLS-1$
}
if (elementData[length] == this) {
- buffer.append("(this Collection)");
+ buffer.append("(this Collection)"); //$NON-NLS-1$
} else {
buffer.append(elementData[length]);
}
@@ -1074,11 +1030,10 @@
/**
* Sets the capacity of this vector to be the same as the size.
- *
+ *
* @see #capacity
* @see #ensureCapacity
* @see #size
- * @since Android 1.0
*/
public synchronized void trimToSize() {
if (elementData.length != elementCount) {
diff --git a/luni/src/main/java/java/util/WeakHashMap.java b/luni/src/main/java/java/util/WeakHashMap.java
index e0228e2..01e15af 100644
--- a/luni/src/main/java/java/util/WeakHashMap.java
+++ b/luni/src/main/java/java/util/WeakHashMap.java
@@ -26,10 +26,10 @@
* optional operations (adding and removing) are supported. Keys and values can
* be any objects. Note that the garbage collector acts similar to a second
* thread on this collection, possibly removing keys.
- *
+ *
+ * @since 1.2
* @see HashMap
* @see WeakReference
- * @since Android 1.0
*/
public class WeakHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {
@@ -127,7 +127,7 @@
}
public boolean hasNext() {
- if (nextEntry != null) {
+ if (nextEntry != null && (nextKey != null || nextEntry.isNull)) {
return true;
}
while (true) {
@@ -183,8 +183,6 @@
/**
* Constructs a new empty {@code WeakHashMap} instance.
- *
- * @since Android 1.0
*/
public WeakHashMap() {
this(DEFAULT_SIZE);
@@ -193,12 +191,11 @@
/**
* Constructs a new {@code WeakHashMap} instance with the specified
* capacity.
- *
+ *
* @param capacity
* the initial capacity of this map.
* @throws IllegalArgumentException
* if the capacity is less than zero.
- * @since Android 1.0
*/
public WeakHashMap(int capacity) {
if (capacity >= 0) {
@@ -215,7 +212,7 @@
/**
* Constructs a new {@code WeakHashMap} instance with the specified capacity
* and load factor.
- *
+ *
* @param capacity
* the initial capacity of this map.
* @param loadFactor
@@ -223,7 +220,6 @@
* @throws IllegalArgumentException
* if the capacity is less than zero or the load factor is less
* or equal to zero.
- * @since Android 1.0
*/
public WeakHashMap(int capacity, float loadFactor) {
if (capacity >= 0 && loadFactor > 0) {
@@ -240,10 +236,9 @@
/**
* Constructs a new {@code WeakHashMap} instance containing the mappings
* from the specified map.
- *
+ *
* @param map
* the mappings to add.
- * @since Android 1.0
*/
public WeakHashMap(Map<? extends K, ? extends V> map) {
this(map.size() < 6 ? 11 : map.size() * 2);
@@ -252,10 +247,9 @@
/**
* Removes all mappings from this map, leaving it empty.
- *
+ *
* @see #isEmpty()
* @see #size()
- * @since Android 1.0
*/
@Override
public void clear() {
@@ -275,12 +269,11 @@
/**
* Returns whether this map contains the specified key.
- *
+ *
* @param key
* the key to search for.
* @return {@code true} if this map contains the specified key,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsKey(Object key) {
@@ -292,9 +285,8 @@
* an instance of {@link Map.Entry}. As the set is backed by this map,
* changes in one will be reflected in the other. It does not support adding
* operations.
- *
+ *
* @return a set of the mappings.
- * @since Android 1.0
*/
@Override
public Set<Map.Entry<K, V>> entrySet() {
@@ -351,9 +343,8 @@
* Returns a set of the keys contained in this map. The set is backed by
* this map so changes to one are reflected by the other. The set does not
* support adding.
- *
+ *
* @return a set of the keys.
- * @since Android 1.0
*/
@Override
public Set<K> keySet() {
@@ -392,6 +383,26 @@
}
});
}
+
+ @Override
+ public Object[] toArray() {
+ Collection<K> coll = new ArrayList<K>(size());
+
+ for (Iterator<K> iter = iterator(); iter.hasNext();) {
+ coll.add(iter.next());
+ }
+ return coll.toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] contents) {
+ Collection<K> coll = new ArrayList<K>(size());
+
+ for (Iterator<K> iter = iterator(); iter.hasNext();) {
+ coll.add(iter.next());
+ }
+ return coll.toArray(contents);
+ }
};
}
return keySet;
@@ -408,16 +419,13 @@
* "wrapper object" over the iterator of map's entrySet(). The size method
* wraps the map's size method and the contains method wraps the map's
* containsValue method.
- * </p>
* <p>
* The collection is created when this method is called at first time and
* returned in response to all subsequent calls. This method may return
* different Collection when multiple calls to this method, since it has no
* synchronization performed.
- * </p>
- *
+ *
* @return a collection of the values contained in this map.
- * @since Android 1.0
*/
@Override
public Collection<V> values() {
@@ -454,12 +462,11 @@
/**
* Returns the value of the mapping with the specified key.
- *
+ *
* @param key
* the key.
* @return the value of the mapping with the specified key, or {@code null}
* if no mapping for the specified key is found.
- * @since Android 1.0
*/
@Override
public V get(Object key) {
@@ -510,12 +517,11 @@
/**
* Returns whether this map contains the specified value.
- *
+ *
* @param value
* the value to search for.
* @return {@code true} if this map contains the specified value,
* {@code false} otherwise.
- * @since Android 1.0
*/
@Override
public boolean containsValue(Object value) {
@@ -549,9 +555,8 @@
/**
* Returns the number of elements in this map.
- *
+ *
* @return the number of elements in this map.
- * @since Android 1.0
*/
@Override
public boolean isEmpty() {
@@ -590,14 +595,13 @@
/**
* Maps the specified key to the specified value.
- *
+ *
* @param key
* the key.
* @param value
* the value.
* @return the value of any previous mapping with the specified key or
* {@code null} if there was no mapping.
- * @since Android 1.0
*/
@Override
public V put(K key, V value) {
@@ -658,10 +662,11 @@
* Copies all the mappings in the given map to this map. These mappings will
* replace all mappings that this map had for any of the keys currently in
* the given map.
- *
+ *
* @param map
* the map to copy mappings from.
- * @since Android 1.0
+ * @throws NullPointerException
+ * if {@code map} is {@code null}.
*/
@Override
public void putAll(Map<? extends K, ? extends V> map) {
@@ -670,12 +675,11 @@
/**
* Removes the mapping with the specified key from this map.
- *
+ *
* @param key
* the key of the mapping to remove.
* @return the value of the removed mapping or {@code null} if no mapping
* for the specified key was found.
- * @since Android 1.0
*/
@Override
public V remove(Object key) {
@@ -711,9 +715,8 @@
/**
* Returns the number of elements in this map.
- *
+ *
* @return the number of elements in this map.
- * @since Android 1.0
*/
@Override
public int size() {
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/MimeTable.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/MimeTable.java
index e288f1a..be6da05 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/MimeTable.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/MimeTable.java
@@ -51,7 +51,7 @@
}
/**
- * Contructs a MIME table using the default values defined in this class.
+ * Constructs a MIME table using the default values defined in this class.
*
* It then augments this table by reading pairs of extensions and
* corresponding content types from the file "content-types.properties",
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java
index 07357be..7f738d3 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/FileURLConnection.java
@@ -59,16 +59,9 @@
public FileURLConnection(URL url) {
super(url);
fileName = url.getFile();
- if (url.getRef() != null) {
- fileName += "#" + url.getRef(); //$NON-NLS-1$
- }
if (fileName == null) {
fileName = ""; //$NON-NLS-1$
}
- String host = url.getHost();
- if (host != null && host.length() > 0) {
- fileName = "//" + host + fileName; //$NON-NLS-1$
- }
fileName = Util.decode(fileName, false);
}
@@ -131,13 +124,23 @@
return MimeTable.UNKNOWN;
}
if (isDir) {
- return "text/html"; //$NON-NLS-1$
+ return "text/plain"; //$NON-NLS-1$
}
String result = guessContentTypeFromName(url.getFile());
- if (result == null) {
- return MimeTable.UNKNOWN;
+ if (result != null) {
+ return result;
}
- return result;
+
+ try {
+ result = guessContentTypeFromStream(is);
+ } catch (IOException e) {
+ // Ignore
+ }
+ if (result != null) {
+ return result;
+ }
+
+ return MimeTable.UNKNOWN;
}
/**
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/Handler.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/Handler.java
index 909e611..1b5bfb9 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/Handler.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/file/Handler.java
@@ -41,15 +41,15 @@
*
*/
@Override
- public URLConnection openConnection(URL url) {
- return new FileURLConnection(url);
+ public URLConnection openConnection(URL url) throws IOException {
+ return openConnection(url, null);
}
/**
* The behaviour of this method is the same as openConnection(URL).
* <code>proxy</code> is not used in FileURLConnection.
*
- * @param u
+ * @param url
* the URL which the connection is pointing to
* @param proxy
* Proxy
@@ -58,18 +58,28 @@
* @throws IOException
* if this handler fails to establish a connection.
* @throws IllegalArgumentException
- * if any argument is null or of an invalid type.
+ * if the url argument is null.
* @throws UnsupportedOperationException
* if the protocol handler doesn't support this method.
*/
@Override
public URLConnection openConnection(URL url, Proxy proxy)
throws IOException {
- if (null == url || null == proxy) {
+ if (null == url) {
// K034b=url and proxy can not be null
throw new IllegalArgumentException(Msg.getString("K034b")); //$NON-NLS-1$
}
- return new FileURLConnection(url);
+
+ String host = url.getHost();
+ if (host == null || host.length() == 0
+ || host.equalsIgnoreCase("localhost")) { //$NON-NLS-1$
+ return new FileURLConnection(url);
+ }
+
+ // If a hostname is specified try to get the resource using FTP
+ URL ftpURL = new URL("ftp", host, url.getFile()); //$NON-NLS-1$
+ return (proxy == null) ? ftpURL.openConnection() : ftpURL
+ .openConnection(proxy);
}
/**
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java
index 2d4ab0d..016d5a7 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java
@@ -183,22 +183,24 @@
ProxySelector selector = ProxySelector.getDefault();
Iterator<Proxy> iter = proxyList.iterator();
boolean connectOK = false;
+ String failureReason = ""; //$NON-NLS-1$
while (iter.hasNext() && !connectOK) {
currentProxy = iter.next();
try {
connectInternal();
connectOK = true;
} catch (IOException ioe) {
+ failureReason = ioe.getLocalizedMessage();
// If connect failed, callback "connectFailed"
// should be invoked.
if (null != selector && Proxy.NO_PROXY != currentProxy) {
- selector
- .connectFailed(uri, currentProxy.address(), ioe);
+ selector.connectFailed(uri, currentProxy.address(), ioe);
}
}
}
if (!connectOK) {
- throw new IOException(Msg.getString("K0097")); //$NON-NLS-1$
+ // K0097=Unable to connect to server\: {0}
+ throw new IOException(Msg.getString("K0097", failureReason)); //$NON-NLS-1$
}
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
index 1f7589d..24be092 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/Header.java
@@ -118,7 +118,7 @@
/**
* Set a field with the specified value. If the field is not found, it is
* added. If the field is found, the existing value(s) are overwritten.
- *
+ *
* @param key
* @param value
*/
@@ -148,8 +148,10 @@
* Provides an unmodifiable map with all String header names mapped to their
* String values. The map keys are Strings and the values are unmodifiable
* Lists of Strings.
- *
+ *
* @return an unmodifiable map of the headers
+ *
+ * @since 1.4
*/
public Map<String, List<String>> getFieldMap() {
Map<String, List<String>> result = new HashMap<String, List<String>>(
@@ -164,7 +166,7 @@
/**
* Returns the element at <code>pos</code>, null if no such element
* exist.
- *
+ *
* @return java.lang.String the value of the key
* @param pos
* int the position to look for
@@ -179,8 +181,8 @@
/**
* Returns the key of this header at <code>pos</code>, null if there are
* fewer keys in the header
- *
- *
+ *
+ *
* @return the key the desired position
* @param pos
* the position to look for
@@ -193,11 +195,12 @@
}
/**
- * Returns the value corresponding to the specified key, null if no such key
- * exists.
- *
+ * Returns the value corresponding to the specified key.
+ *
* @param key
- * @return
+ * the key to look up.
+ * @return Answers the value for the given key, or <code>null</code> if no
+ * such key exists.
*/
public String get(String key) {
LinkedList<String> result = keyTable.get(key.toLowerCase());
@@ -209,8 +212,8 @@
/**
* Returns the number of keys stored in this header
- *
- * @return
+ *
+ * @return the number of keys.
*/
public int length() {
return props.size() / 2;
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java
index 6a26365..55d762d 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConfiguration.java
@@ -14,12 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-// BEGIN android-note
-// This class was copied from a newer version of harmony
-// to improve reusability of URLConnections
-// END android-note
-
package org.apache.harmony.luni.internal.net.www.protocol.http;
import java.net.InetSocketAddress;
@@ -141,4 +135,4 @@
return uri.hashCode();
}
-}
+}
\ No newline at end of file
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
index f7c8d96..4c51bdc 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnection.java
@@ -14,12 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-// BEGIN android-note
-// This class was copied from a newer version of harmony
-// to improve reusability of URLConnections
-// END android-note
-
package org.apache.harmony.luni.internal.net.www.protocol.http;
import java.io.IOException;
@@ -42,6 +36,7 @@
* various utility methods to access that connection.
*/
public class HttpConnection {
+
private boolean usingSecureSocket = false;
private Socket socket;
@@ -233,7 +228,7 @@
* Returns whether this connection is eligible to be recycled. This
* is like {@link #isStale} except that it doesn't try to actually
* perform any I/O.
- *
+ *
* @return <code>true</code> if the connection is eligible to be
* recycled
*/
@@ -272,4 +267,5 @@
return null;
}
}
-}
+
+}
\ No newline at end of file
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionManager.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionManager.java
index 9a90612..61d7cbe 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionManager.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpConnectionManager.java
@@ -14,12 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-// BEGIN android-note
-// This class was copied from a newer version of harmony
-// to improve reusability of URLConnections
-// END android-note
-
package org.apache.harmony.luni.internal.net.www.protocol.http;
import java.io.IOException;
@@ -179,4 +173,4 @@
pool.clear();
}
-}
+}
\ No newline at end of file
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
index 6f5a2be..505c6b2 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java
@@ -15,11 +15,6 @@
* limitations under the License.
*/
-// BEGIN android-note
-// This class and some helper classes where copied from a newer version of harmony
-// to improve reusability of URLConnections
-// END android-note
-
package org.apache.harmony.luni.internal.net.www.protocol.http;
import java.io.ByteArrayOutputStream;
@@ -185,7 +180,7 @@
return is.skip(n);
}
-
+
public int available() throws IOException {
if (closed) {
throwClosed();
@@ -222,9 +217,9 @@
private void throwClosed() throws IOException {
throw new IOException("stream closed");
}
- }
+ }
// END android-added
-
+
private class LimitedInputStream extends InputStream {
int bytesRemaining;
@@ -523,7 +518,7 @@
* size minus chunk head (which writes chunk data size in HEX and
* "\r\n") size. For example, a string "abcd" use chunk whose size is 5
* must be written to socket as "2\r\nab","2\r\ncd" ...
- *
+ *
*/
private int calculateChunkDataLength() {
/*
@@ -691,7 +686,7 @@
/**
* Creates an instance of the <code>HttpURLConnection</code> using default
* port 80.
- *
+ *
* @param url
* URL The URL this connection is connecting
*/
@@ -701,7 +696,7 @@
/**
* Creates an instance of the <code>HttpURLConnection</code>
- *
+ *
* @param url
* URL The URL this connection is connecting
* @param port
@@ -711,7 +706,7 @@
super(url);
defaultPort = port;
reqHeader = (Header) defaultReqHeader.clone();
-
+
try {
uri = url.toURI();
} catch (URISyntaxException e) {
@@ -727,7 +722,7 @@
/**
* Creates an instance of the <code>HttpURLConnection</code>
- *
+ *
* @param url
* URL The URL this connection is connecting
* @param port
@@ -742,12 +737,12 @@
/**
* Establishes the connection to the remote HTTP server
- *
+ *
* Any methods that requires a valid connection to the resource will call
* this method implicitly. After the connection is established,
* <code>connected</code> is set to true.
- *
- *
+ *
+ *
* @see #connected
* @see java.io.IOException
* @see URLStreamHandler
@@ -762,9 +757,9 @@
}
// BEGIN android-changed
// url.toURI(); throws an URISyntaxException if the url contains
- // illegal characters in e.g. the query.
- // Since the query is not needed for proxy selection, we just create an
- // URI that only contains the necessary information.
+ // illegal characters in e.g. the query.
+ // Since the query is not needed for proxy selection, we just create an
+ // URI that only contains the necessary information.
try {
uri = new URI(url.getProtocol(),
null,
@@ -817,7 +812,7 @@
}
/**
- * Returns connected socket to be used for this HTTP connection.
+ * Returns connected socket to be used for this HTTP connection.
*/
protected HttpConnection getHTTPConnection(Proxy proxy) throws IOException {
HttpConnection connection;
@@ -832,7 +827,7 @@
/**
* Sets up the data streams used to send request[s] and read response[s].
- *
+ *
* @param connection
* HttpConnection to be used
*/
@@ -882,8 +877,8 @@
/**
* Closes the connection with the HTTP server
- *
- *
+ *
+ *
* @see URLConnection#connect()
*/
@Override
@@ -940,7 +935,7 @@
* <p>
* If the content type is not what stated above,
* <code>FileNotFoundException</code> is thrown.
- *
+ *
* @return InputStream the error input stream returned by the server.
*/
@Override
@@ -978,14 +973,14 @@
/**
* Returns the value of the field corresponding to the <code>key</code>
* Returns <code>null</code> if there is no such field.
- *
+ *
* If there are multiple fields with that key, the last field value is
* returned.
- *
+ *
* @return java.lang.String The value of the header field
* @param key
* java.lang.String the name of the header field
- *
+ *
* @see #getHeaderField(int)
* @see #getHeaderFieldKey
*/
@@ -1019,8 +1014,10 @@
* Provides an unmodifiable map of the connection header values. The map
* keys are the String header field names. Each map value is a list of the
* header field values associated with that key name.
- *
+ *
* @return the mapping of header field names to values
+ *
+ * @since 1.4
*/
@Override
public Map<String, List<String>> getHeaderFields() {
@@ -1172,7 +1169,7 @@
/**
* Returns a line read from the input stream. Does not include the \n
- *
+ *
* @return The line that was read.
*/
String readln() throws IOException {
@@ -1215,7 +1212,7 @@
* Sends the request header to the remote HTTP server Not all of them are
* guaranteed to have any effect on the content the server will return,
* depending on if the server supports that field.
- *
+ *
* Examples : Accept: text/*, text/html, text/html;level=1, Accept-Charset:
* iso-8859-5, unicode-1-1;q=0.8
*/
@@ -1327,6 +1324,45 @@
} else {
output.append("1\r\n"); //$NON-NLS-1$
}
+ // add user-specified request headers if any
+ boolean hasContentLength = false;
+ for (int i = 0; i < reqHeader.length(); i++) {
+ String key = reqHeader.getKey(i);
+ if (key != null) {
+ String lKey = key.toLowerCase();
+ if ((os != null && !os.isChunked())
+ || (!lKey.equals("transfer-encoding") && !lKey //$NON-NLS-1$
+ .equals("content-length"))) { //$NON-NLS-1$
+ output.append(key);
+ String value = reqHeader.get(i);
+ /*
+ * duplicates are allowed under certain conditions see
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
+ */
+ if (lKey.equals("content-length")) { //$NON-NLS-1$
+ hasContentLength = true;
+ /*
+ * if both setFixedLengthStreamingMode and
+ * content-length are set, use fixedContentLength first
+ */
+ if(fixedContentLength >= 0){
+ value = String.valueOf(fixedContentLength);
+ }
+ }
+ if (value != null) {
+ output.append(": "); //$NON-NLS-1$
+ output.append(value);
+ }
+ output.append("\r\n"); //$NON-NLS-1$
+ }
+ }
+ }
+ if (fixedContentLength >= 0 && !hasContentLength) {
+ output.append("content-length: "); //$NON-NLS-1$
+ output.append(String.valueOf(fixedContentLength));
+ output.append("\r\n"); //$NON-NLS-1$
+ }
+
if (reqHeader.get("User-Agent") == null) { //$NON-NLS-1$
output.append("User-Agent: "); //$NON-NLS-1$
String agent = getSystemProperty("http.agent"); //$NON-NLS-1$
@@ -1348,6 +1384,9 @@
}
output.append("\r\n"); //$NON-NLS-1$
}
+ if (reqHeader.get("Accept") == null) { //$NON-NLS-1$
+ output.append("Accept: *; */*\r\n"); //$NON-NLS-1$
+ }
if (httpVersion > 0 && reqHeader.get("Connection") == null) { //$NON-NLS-1$
output.append("Connection: Keep-Alive\r\n"); //$NON-NLS-1$
}
@@ -1367,43 +1406,6 @@
output.append("Transfer-Encoding: chunked\r\n"); //$NON-NLS-1$
}
}
-
- boolean hasContentLength = false;
- // then the user-specified request headers, if any
- for (int i = 0; i < reqHeader.length(); i++) {
- String key = reqHeader.getKey(i);
- if (key != null) {
- String lKey = key.toLowerCase();
- if ((os != null && !os.isChunked())
- || (!lKey.equals("transfer-encoding") && !lKey //$NON-NLS-1$
- .equals("content-length"))) { //$NON-NLS-1$
- output.append(key);
- output.append(": "); //$NON-NLS-1$
- /*
- * duplicates are allowed under certain conditions see
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
- */
- if (lKey.equals("content-length")) { //$NON-NLS-1$
- hasContentLength = true;
- /*
- * if both setFixedLengthStreamingMode and
- * content-length are set, use fixedContentLength first
- */
- output.append((fixedContentLength >= 0) ? String
- .valueOf(fixedContentLength)
- : reqHeader.get(i));
- } else {
- output.append(reqHeader.get(i));
- }
- output.append("\r\n"); //$NON-NLS-1$
- }
- }
- }
- if (fixedContentLength >= 0 && !hasContentLength) {
- output.append("content-length: "); //$NON-NLS-1$
- output.append(String.valueOf(fixedContentLength));
- output.append("\r\n"); //$NON-NLS-1$
- }
// end the headers
output.append("\r\n"); //$NON-NLS-1$
return output.toString().getBytes("ISO8859_1"); //$NON-NLS-1$
@@ -1412,7 +1414,7 @@
/**
* Sets the default request header fields to be sent to the remote server.
* This does not affect the current URL Connection, only newly created ones.
- *
+ *
* @param field
* java.lang.String The name of the field to be changed
* @param value
@@ -1427,11 +1429,11 @@
* <code>setIfModifiedSince()</code> Since this HTTP impl supports
* IfModifiedSince as one of the header field, the request header is updated
* with the new value.
- *
- *
+ *
+ *
* @param newValue
* the number of millisecond since epoch
- *
+ *
* @throws IllegalStateException
* if already connected.
*/
@@ -1655,7 +1657,7 @@
/**
* Returns the authorization credentials on the base of provided
* authorization challenge
- *
+ *
* @param challenge
* @return authorization credentials
* @throws IOException
@@ -1707,4 +1709,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnection.java
index 31c1198..4d0aff7 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/https/HttpsURLConnection.java
@@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.harmony.luni.internal.net.www.protocol.https;
import java.io.IOException;
@@ -22,10 +21,6 @@
import java.io.OutputStream;
import java.net.ProtocolException;
import java.net.Proxy;
-// BEGIN andorid-removed
-// copied from newer version of harmony
-// import java.net.Socket;
-// END android-removed
import java.net.URL;
import java.security.Permission;
import java.security.Principal;
@@ -390,10 +385,7 @@
responseMessage, responseCode));
}
// if there are some remaining data in the stream - read it out
- // BEGIN andorid-changed
- // copied from newer version of harmony
InputStream is = connection.getInputStream();
- // END android-changed
while (is.available() != 0) {
is.read();
}
@@ -403,11 +395,8 @@
super.connect();
}
if (!makingSSLTunnel) {
- // BEGIN andorid-changed
- // copied from newer version of harmony
sslSocket = connection.getSecureSocket(getSSLSocketFactory(), getHostnameVerifier());
setUpTransportIO(connection);
- // END android-changed
}
}
@@ -430,23 +419,5 @@
return super.requestString();
}
- // BEGIN android-removed
- // /**
- // * Create the secure socket over the connected socket and verify remote
- // * hostname.
- // */
- // private Socket wrapConnection(Socket socket) throws IOException {
- // String hostname = url.getHost();
- // // create the wrapper over connected socket
- // sslSocket = (SSLSocket) getSSLSocketFactory().createSocket(socket,
- // hostname, url.getPort(), true);
- // sslSocket.setUseClientMode(true);
- // sslSocket.startHandshake();
- // if (!getHostnameVerifier().verify(hostname, sslSocket.getSession())) {
- // throw new IOException(Messages.getString("luni.02", hostname)); //$NON-NLS-1$
- // }
- // return sslSocket;
- // }
- // END android-removed
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java
index da34969..d299913 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java
@@ -36,8 +36,9 @@
* @param u
* java.net.URL The URL to which the connection is pointing to
*
- * @thows IOException thrown if an IO error occurs when this method tries to
- * establish connection.
+ * @throws IOException
+ * thrown if an IO error occurs when this method tries to
+ * establish connection.
*/
@Override
protected URLConnection openConnection(URL u) throws IOException {
@@ -75,7 +76,8 @@
file = file.substring(0, file.indexOf('!') + 1) + spec;
} else {
int idx = file.indexOf('!');
- String tmpFile = file.substring(idx + 1, file.lastIndexOf('/') + 1) + spec;
+ String tmpFile = file.substring(idx + 1, file.lastIndexOf('/') + 1)
+ + spec;
tmpFile = URLUtil.canonicalizePath(tmpFile);
file = file.substring(0, idx + 1) + tmpFile;
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java
index 5f4896a..56c1f3c 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java
@@ -23,8 +23,6 @@
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
import java.net.ContentHandler;
import java.net.ContentHandlerFactory;
import java.net.MalformedURLException;
@@ -32,120 +30,38 @@
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.TreeSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;
-// BEGIN android-removed
-// import org.apache.harmony.kernel.vm.VM;
-// END android-removed
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.Util;
/**
* This subclass extends <code>URLConnection</code>.
* <p>
- *
+ *
* This class is responsible for connecting and retrieving resources from a Jar
* file which can be anywhere that can be refered to by an URL.
*/
public class JarURLConnection extends java.net.JarURLConnection {
- static Hashtable<String, CacheEntry<? extends JarFile>> jarCache = new Hashtable<String, CacheEntry<?>>();
+ static HashMap<URL, JarFile> jarCache = new HashMap<URL, JarFile>();
- InputStream jarInput;
+ private URL jarFileURL;
+
+ private InputStream jarInput;
private JarFile jarFile;
private JarEntry jarEntry;
-
+
private boolean closed;
- ReferenceQueue<JarFile> cacheQueue = new ReferenceQueue<JarFile>();
-
- static TreeSet<LRUKey> lru = new TreeSet<LRUKey>(
- new LRUComparator<LRUKey>());
-
- static int Limit;
-
- static {
- Limit = AccessController.doPrivileged(new PrivilegedAction<Integer>() {
- public Integer run() {
- return Integer.getInteger("jar.cacheSize", 500); //$NON-NLS-1$
- }
- });
- // BEGIN android-removed
- // TODO this needs to be implemented once this is available.
- // VM.closeJars();
- // END android-removed
- }
-
- static final class CacheEntry<T extends JarFile> extends WeakReference<T> {
- Object key;
-
- CacheEntry(T jar, String key, ReferenceQueue<JarFile> queue) {
- super(jar, queue);
- this.key = key;
- }
- }
-
- static final class LRUKey {
- JarFile jar;
-
- long ts;
-
- LRUKey(JarFile file, long time) {
- jar = file;
- ts = time;
- }
-
- /**
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- return (obj instanceof LRUKey) &&
- (jar == ((LRUKey) obj).jar);
- }
-
- @Override
- public int hashCode() {
- return jar.hashCode();
- }
- }
-
- static final class LRUComparator<T> implements Comparator<LRUKey> {
-
- LRUComparator() {
- }
-
- /**
- * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
- */
- public int compare(LRUKey o1, LRUKey o2) {
- if ((o1).ts > (o2).ts) {
- return 1;
- }
- return (o1).ts == (o2).ts ? 0 : -1;
- }
-
- /**
- * @param o1
- * an object to compare
- * @param o2
- * an object to compare
- * @return <code>true</code> if the objects are equal,
- * <code>false</code> otherwise.
- */
- public boolean equals(Object o1, Object o2) {
- return o1.equals(o2);
- }
- }
/**
* @param url
@@ -153,8 +69,10 @@
* @throws MalformedURLException
* if the URL is malformed
*/
- public JarURLConnection(java.net.URL url) throws MalformedURLException {
+ public JarURLConnection(java.net.URL url) throws MalformedURLException, IOException {
super(url);
+ jarFileURL = getJarFileURL();
+ jarFileURLConnection = jarFileURL.openConnection();
}
/**
@@ -162,77 +80,76 @@
*/
@Override
public void connect() throws IOException {
- jarFileURLConnection = getJarFileURL().openConnection();
- findJarFile(); // ensure the file can be found
- findJarEntry(); // ensure the entry, if any, can be found
- connected = true;
+ if (!connected) {
+ findJarFile(); // ensure the file can be found
+ findJarEntry(); // ensure the entry, if any, can be found
+ connected = true;
+ }
}
/**
* Returns the Jar file refered by this <code>URLConnection</code>
- *
+ *
* @return the JAR file referenced by this connection
- *
+ *
* @throws IOException
* thrown if an IO error occurs while connecting to the
* resource.
*/
@Override
public JarFile getJarFile() throws IOException {
- if (!connected) {
- connect();
- }
+ connect();
return jarFile;
}
/**
* Returns the Jar file refered by this <code>URLConnection</code>
- *
+ *
* @throws IOException
* if an IO error occurs while connecting to the resource.
*/
private void findJarFile() throws IOException {
- URL jarFileURL = getJarFileURL();
- if (jarFileURL.getProtocol().equals("file")) { //$NON-NLS-1$
- String fileName = jarFileURL.getFile();
- if(!new File(Util.decode(fileName,false)).exists()){
- // KA026=JAR entry {0} not found in {1}
- throw new FileNotFoundException(Msg.getString("KA026", //$NON-NLS-1$
- getEntryName(), fileName));
+ JarFile jar = null;
+ if (getUseCaches()) {
+ synchronized(jarCache){
+ jarFile = jarCache.get(jarFileURL);
}
- String host = jarFileURL.getHost();
- if (host != null && host.length() > 0) {
- fileName = "//" + host + fileName; //$NON-NLS-1$
- }
- jarFile = openJarFile(fileName, fileName, false);
- return;
- }
-
- final String externalForm = jarFileURLConnection.getURL()
- .toExternalForm();
- jarFile = AccessController
- .doPrivileged(new PrivilegedAction<JarFile>() {
- public JarFile run() {
- try {
- return openJarFile(null, externalForm, false);
- } catch (IOException e) {
- return null;
- }
+ if (jarFile == null) {
+ jar = openJarFile();
+ synchronized(jarCache){
+ jarFile = jarCache.get(jarFileURL);
+ if (jarFile == null){
+ jarCache.put(jarFileURL, jar);
+ jarFile = jar;
+ }else{
+ jar.close();
}
- });
- if (jarFile != null) {
- return;
+ }
+ }
+ }else{
+ jarFile = openJarFile();
}
- // Build a temp jar file
- final InputStream is = jarFileURLConnection.getInputStream();
- try {
- jarFile = AccessController
+ if (jarFile == null) {
+ throw new IOException();
+ }
+ }
+
+ JarFile openJarFile() throws IOException {
+ JarFile jar = null;
+ if (jarFileURL.getProtocol().equals("file")) { //$NON-NLS-1$
+ jar = new JarFile(new File(Util.decode(jarFileURL.getFile(), false)),
+ true, ZipFile.OPEN_READ);
+ } else{
+ final InputStream is = jarFileURL.openConnection().getInputStream();
+ try {
+ jar = AccessController
.doPrivileged(new PrivilegedAction<JarFile>() {
public JarFile run() {
try {
File tempJar = File.createTempFile("hyjar_", //$NON-NLS-1$
".tmp", null); //$NON-NLS-1$
+ tempJar.deleteOnExit();
FileOutputStream fos = new FileOutputStream(
tempJar);
byte[] buf = new byte[4096];
@@ -241,79 +158,33 @@
fos.write(buf, 0, nbytes);
}
fos.close();
- String path = tempJar.getPath();
- return openJarFile(path, externalForm, true);
+ return new JarFile(tempJar,
+ true, ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
} catch (IOException e) {
return null;
}
}
});
- } finally {
- is.close();
- }
- if (jarFile == null) {
- throw new IOException();
- }
- }
-
- JarFile openJarFile(String fileString, String key, boolean temp)
- throws IOException {
-
- JarFile jar = null;
- if (useCaches) {
- CacheEntry<? extends JarFile> entry;
- while ((entry = (CacheEntry<? extends JarFile>) cacheQueue.poll()) != null) {
- jarCache.remove(entry.key);
+ } finally {
+ if (is != null) is.close();
}
- entry = jarCache.get(key);
- if (entry != null) {
- jar = entry.get();
- }
- if (jar == null && fileString != null) {
- int flags = ZipFile.OPEN_READ
- + (temp ? ZipFile.OPEN_DELETE : 0);
- jar = new JarFile(new File(Util.decode(fileString, false)),
- true, flags);
- jarCache
- .put(key, new CacheEntry<JarFile>(jar, key, cacheQueue));
- } else {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkPermission(getPermission());
- }
- if (temp) {
- lru.remove(new LRUKey(jar, 0));
- }
- }
- } else if (fileString != null) {
- int flags = ZipFile.OPEN_READ + (temp ? ZipFile.OPEN_DELETE : 0);
- jar = new JarFile(new File(Util.decode(fileString, false)), true,
- flags);
}
- if (temp) {
- lru.add(new LRUKey(jar, new Date().getTime()));
- if (lru.size() > Limit) {
- lru.remove(lru.first());
- }
- }
return jar;
}
/**
* Returns the JarEntry of the entry referenced by this
* <code>URLConnection</code>.
- *
+ *
* @return java.util.jar.JarEntry the JarEntry referenced
- *
+ *
* @throws IOException
* if an IO error occurs while getting the entry
*/
@Override
public JarEntry getJarEntry() throws IOException {
- if (!connected) {
- connect();
- }
+ connect();
return jarEntry;
}
@@ -334,20 +205,19 @@
/**
* Creates an input stream for reading from this URL Connection.
- *
+ *
* @return the input stream
- *
+ *
* @throws IOException
* if an IO error occurs while connecting to the resource.
*/
@Override
public InputStream getInputStream() throws IOException {
+
if (closed) {
throw new IllegalStateException(Msg.getString("KA027"));
}
- if (!connected) {
- connect();
- }
+ connect();
if (jarInput != null) {
return jarInput;
}
@@ -359,39 +229,56 @@
}
/**
- * Returns the content type of the resource. Test cases reveal that only if
- * the URL is refering to a Jar file, that this method returns a non-null
- * value - x-java/jar.
- *
+ * Returns the content type of the resource.
+ * For jar file itself "x-java/jar" should be returned,
+ * for jar entries the content type of the entry should be returned.
+ * Returns non-null results ("content/unknown" for unknown types).
+ *
* @return the content type
*/
@Override
public String getContentType() {
- // it could also return "x-java/jar" which jdk returns but here, we get
- // it from the URLConnection
- try {
- if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
- return getJarFileURL().openConnection().getContentType();
+ if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
+ // the type for jar file itself is always "x-java/jar"
+ return "x-java/jar"; //$NON-NLS-1$
+ } else {
+ String cType = null;
+ String entryName = getEntryName();
+
+ if (entryName != null) {
+ // if there is an Jar Entry, get the content type from the name
+ cType = guessContentTypeFromName(entryName);
+ } else {
+ try {
+ connect();
+ cType = jarFileURLConnection.getContentType();
+ } catch (IOException ioe) {
+ // Ignore
+ }
}
- } catch (IOException ioe) {
- // Ignore
+ if (cType == null) {
+ cType = "content/unknown"; //$NON-NLS-1$
+ }
+ return cType;
}
- // if there is an Jar Entry, get the content type from the name
- return guessContentTypeFromName(url.getFile());
}
/**
* Returns the content length of the resource. Test cases reveal that if the
* URL is refering to a Jar file, this method returns a content-length
- * returned by URLConnection. If not, it will return -1.
- *
+ * returned by URLConnection. For jar entry it should return it's size.
+ * Otherwise, it will return -1.
+ *
* @return the content length
*/
@Override
public int getContentLength() {
try {
- if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
- return getJarFileURL().openConnection().getContentLength();
+ connect();
+ if (jarEntry == null) {
+ return jarFileURLConnection.getContentLength();
+ } else {
+ return (int) getJarEntry().getSize();
}
} catch (IOException e) {
//Ignored
@@ -404,12 +291,12 @@
* URLConnection is pointing to a Jar File (no Jar Entry), this method will
* return a <code>JarFile</code> If there is a Jar Entry, it will return
* the object corresponding to the Jar entry content type.
- *
+ *
* @return a non-null object
- *
+ *
* @throws IOException
* if an IO error occured
- *
+ *
* @see ContentHandler
* @see ContentHandlerFactory
* @see java.io.IOException
@@ -417,9 +304,7 @@
*/
@Override
public Object getContent() throws IOException {
- if (!connected) {
- connect();
- }
+ connect();
// if there is no Jar Entry, return a JarFile
if (jarEntry == null) {
return jarFile;
@@ -431,37 +316,57 @@
* Returns the permission, in this case the subclass, FilePermission object
* which represents the permission necessary for this URLConnection to
* establish the connection.
- *
+ *
* @return the permission required for this URLConnection.
- *
+ *
* @throws IOException
* thrown when an IO exception occurs while creating the
* permission.
*/
+
@Override
public Permission getPermission() throws IOException {
- if (jarFileURLConnection != null) {
- return jarFileURLConnection.getPermission();
- }
- return getJarFileURL().openConnection().getPermission();
+ return jarFileURLConnection.getPermission();
+ }
+
+ @Override
+ public boolean getUseCaches() {
+ return jarFileURLConnection.getUseCaches();
+ }
+
+ @Override
+ public void setUseCaches(boolean usecaches) {
+ jarFileURLConnection.setUseCaches(usecaches);
+ }
+
+ @Override
+ public boolean getDefaultUseCaches() {
+ return jarFileURLConnection.getDefaultUseCaches();
+ }
+
+ @Override
+ public void setDefaultUseCaches(boolean defaultusecaches) {
+ jarFileURLConnection.setDefaultUseCaches(defaultusecaches);
}
/**
* Closes the cached files.
*/
public static void closeCachedFiles() {
- Enumeration<CacheEntry<? extends JarFile>> elemEnum = jarCache
- .elements();
- while (elemEnum.hasMoreElements()) {
- try {
- ZipFile zip = elemEnum.nextElement().get();
- if (zip != null) {
- zip.close();
+ Set<Map.Entry<URL, JarFile>> s = jarCache.entrySet();
+ synchronized(jarCache){
+ Iterator<Map.Entry<URL, JarFile>> i = s.iterator();
+ while(i.hasNext()){
+ try {
+ ZipFile zip = i.next().getValue();
+ if (zip != null) {
+ zip.close();
+ }
+ } catch (IOException e) {
+ // Ignored
}
- } catch (IOException e) {
- // Ignored
}
- }
+ }
}
private class JarURLConnectionInputStream extends FilterInputStream {
@@ -478,7 +383,7 @@
@Override
public void close() throws IOException {
super.close();
- if (!useCaches) {
+ if (!getUseCaches()) {
closed = true;
jarFile.close();
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties b/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
index fe392b7..2ee09f7 100644
--- a/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/nls/messages.properties
@@ -21,8 +21,6 @@
luni.04=this Map
luni.05=Attempt to insert {0} element into collection with element type {1}
luni.06=The string argument is null
-# // BEGIN android-added
-# // copied from newer version of harmony
+luni.07=The stream is corrupted
luni.08=Invalid Unicode sequence: expected format \\uxxxx
luni.09=Invalid Unicode sequence: illegal character
-# // END android-added
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyCharArrayCache.java b/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyCharArrayCache.java
deleted file mode 100644
index a359b8b..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyCharArrayCache.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.reflect;
-
-class ProxyCharArrayCache {
- static boolean equals(char[] first, char[] second) {
- if (first == second) {
- return true;
- }
- if (first == null || second == null) {
- return false;
- }
- if (first.length != second.length) {
- return false;
- }
-
- for (int i = first.length; --i >= 0;) {
- if (first[i] != second[i]) {
- return false;
- }
- }
- return true;
- }
-
- // to avoid using Enumerations, walk the individual tables skipping nulls
- private char[] keyTable[];
-
- private int valueTable[];
-
- // number of elements in the table
- private int elementSize;
-
- private int threshold;
-
- ProxyCharArrayCache(int initialCapacity) {
- if (initialCapacity < 13) {
- initialCapacity = 13;
- }
- this.elementSize = 0;
- this.threshold = (int) (initialCapacity * 0.66f);
- this.keyTable = new char[initialCapacity][];
- this.valueTable = new int[initialCapacity];
- }
-
- int get(char[] key) {
- int index = hashCodeChar(key);
- while (keyTable[index] != null) {
- if (equals(keyTable[index], key)) {
- return valueTable[index];
- }
- index = (index + 1) % keyTable.length;
- }
- return -1;
- }
-
- private int hashCodeChar(char[] val) {
- int length = val.length;
- int hash = 0;
- int n = 2; // number of characters skipped
- for (int i = 0; i < length; i += n) {
- hash += val[i];
- }
- return (hash & 0x7FFFFFFF) % keyTable.length;
- }
-
- int put(char[] key, int value) {
- int index = hashCodeChar(key);
- while (keyTable[index] != null) {
- if (equals(keyTable[index], key)) {
- return valueTable[index] = value;
- }
- index = (index + 1) % keyTable.length;
- }
- keyTable[index] = key;
- valueTable[index] = value;
-
- // assumes the threshold is never equal to the size of the table
- if (++elementSize > threshold) {
- rehash();
- }
- return value;
- }
-
- private void rehash() {
- ProxyCharArrayCache newHashtable = new ProxyCharArrayCache(
- keyTable.length * 2);
- for (int i = keyTable.length; --i >= 0;) {
- if (keyTable[i] != null) {
- newHashtable.put(keyTable[i], valueTable[i]);
- }
- }
-
- this.keyTable = newHashtable.keyTable;
- this.valueTable = newHashtable.valueTable;
- this.threshold = newHashtable.threshold;
- }
-
- int size() {
- return elementSize;
- }
-
- @Override
- public String toString() {
- int max = size();
- StringBuilder buf = new StringBuilder();
- buf.append("{"); //$NON-NLS-1$
- for (int i = 0; i < max; ++i) {
- if (keyTable[i] != null) {
- buf.append(keyTable[i]).append("->").append(valueTable[i]); //$NON-NLS-1$
- }
- if (i < max) {
- buf.append(", "); //$NON-NLS-1$
- }
- }
- buf.append("}"); //$NON-NLS-1$
- return buf.toString();
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyClassFile.java b/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyClassFile.java
deleted file mode 100644
index 43fa5a3..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyClassFile.java
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.reflect;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.util.ArrayList;
-import java.util.HashSet;
-
-public final class ProxyClassFile implements ProxyConstants {
-
- private static final int INITIAL_CONTENTS_SIZE = 1000;
-
- private static final int INITIAL_HEADER_SIZE = 500;
-
- private static final int INCREMENT_SIZE = 250;
-
- private static Method ObjectEqualsMethod;
-
- private static Method ObjectHashCodeMethod;
-
- private static Method ObjectToStringMethod;
-
- private static Method ClassForNameMethod;
-
- private static Method ClassGetMethod;
-
- private static Method HandlerInvokeMethod;
-
- private static Constructor<?> ProxyConstructor;
-
- private static Constructor<?> UndeclaredThrowableExceptionConstructor;
-
- private static Field ProxyHandlerField;
-
- public static byte[] generateBytes(String typeName, Class[] interfaces) {
- ProxyClassFile classFile = new ProxyClassFile(typeName, interfaces);
- classFile.addFields();
- classFile.findMethods(interfaces);
- classFile.addMethods();
- classFile.addAttributes();
- return classFile.getBytes();
- }
-
- static char[] getConstantPoolName(Class<?> c) {
- if (c.isArray()) {
- // Array classes are named/ with their signature
- return c.getName().replace('.', '/').toCharArray();
- }
-
- if (c.isPrimitive()) {
- // Special cases for each base type.
- if (c == void.class) {
- return new char[] { 'V' };
- }
- if (c == int.class) {
- return new char[] { 'I' };
- }
- if (c == boolean.class) {
- return new char[] { 'Z' };
- }
- if (c == byte.class) {
- return new char[] { 'B' };
- }
- if (c == char.class) {
- return new char[] { 'C' };
- }
- if (c == short.class) {
- return new char[] { 'S' };
- }
- if (c == long.class) {
- return new char[] { 'J' };
- }
- if (c == float.class) {
- return new char[] { 'F' };
- }
- if (c == double.class) {
- return new char[] { 'D' };
- }
- }
- return ("L" + c.getName().replace('.', '/') + ";").toCharArray();
- }
-
- static char[] getConstantPoolName(Constructor<?> method) /* (ILjava/lang/Thread;)V */{
- Class[] parameters = method.getParameterTypes();
- StringBuffer buffer = new StringBuffer(parameters.length + 1 * 20);
- buffer.append('(');
- for (Class<?> element : parameters) {
- buffer.append(getConstantPoolName(element));
- }
- buffer.append(')');
- buffer.append(getConstantPoolName(void.class));
- return buffer.toString().toCharArray();
- }
-
- static char[] getConstantPoolName(Method method) /* (ILjava/lang/Thread;)Ljava/lang/Object; */{
- Class[] parameters = method.getParameterTypes();
- StringBuffer buffer = new StringBuffer(parameters.length + 1 * 20);
- buffer.append('(');
- for (Class<?> element : parameters) {
- buffer.append(getConstantPoolName(element));
- }
- buffer.append(')');
- buffer.append(getConstantPoolName(method.getReturnType()));
- return buffer.toString().toCharArray();
- }
-
- private ProxyConstantPool constantPool;
-
- // the header contains all the bytes till the end of the constant pool
- byte[] header;
-
- int headerOffset;
-
- // that collection contains all the remaining bytes of the .class file
- private byte[] contents;
-
- private int contentsOffset;
-
- private int constantPoolOffset;
-
- private ProxyMethod[] proxyMethods;
-
- ProxyClassFile(String typeName, Class[] interfaces) {
- super();
- header = new byte[INITIAL_HEADER_SIZE];
- // generate the magic numbers inside the header
- header[headerOffset++] = (byte) (0xCAFEBABEL >> 24);
- header[headerOffset++] = (byte) (0xCAFEBABEL >> 16);
- header[headerOffset++] = (byte) (0xCAFEBABEL >> 8);
- header[headerOffset++] = (byte) (0xCAFEBABEL >> 0);
- // Compatible with JDK 1.2
- header[headerOffset++] = 0;
- header[headerOffset++] = 0;
- header[headerOffset++] = 0;
- header[headerOffset++] = 46;
- constantPoolOffset = headerOffset;
- headerOffset += 2;
- constantPool = new ProxyConstantPool(this);
- contents = new byte[INITIAL_CONTENTS_SIZE];
- // now we continue to generate the bytes inside the contents array
- int accessFlags = AccPublic | AccFinal | AccSuper;
- contents[contentsOffset++] = (byte) (accessFlags >> 8);
- contents[contentsOffset++] = (byte) accessFlags;
- int classNameIndex = constantPool.typeIndex(typeName);
- contents[contentsOffset++] = (byte) (classNameIndex >> 8);
- contents[contentsOffset++] = (byte) classNameIndex;
- int superclassNameIndex = constantPool
- .typeIndex("java/lang/reflect/Proxy");
- contents[contentsOffset++] = (byte) (superclassNameIndex >> 8);
- contents[contentsOffset++] = (byte) superclassNameIndex;
- int interfacesCount = interfaces.length;
- contents[contentsOffset++] = (byte) (interfacesCount >> 8);
- contents[contentsOffset++] = (byte) interfacesCount;
- for (int i = 0; i < interfacesCount; i++) {
- int interfaceIndex = constantPool
- .typeIndex(interfaces[i].getName());
- contents[contentsOffset++] = (byte) (interfaceIndex >> 8);
- contents[contentsOffset++] = (byte) interfaceIndex;
- }
- }
-
- private void addAttributes() {
- writeUnsignedShort(0); // classFile does not have attributes of its own
-
- // resynchronize all offsets of the classfile
- header = constantPool.poolContent;
- headerOffset = constantPool.currentOffset;
- int constantPoolCount = constantPool.currentIndex;
- header[constantPoolOffset++] = (byte) (constantPoolCount >> 8);
- header[constantPoolOffset] = (byte) constantPoolCount;
- }
-
- private void addFields() {
- writeUnsignedShort(0); // we have no fields
- }
-
- private void addMethods() {
- int methodCount = proxyMethods.length;
- writeUnsignedShort(methodCount + 1);
-
- // save constructor
- writeUnsignedShort(AccPublic);
- writeUnsignedShort(constantPool.literalIndex(Init));
- if (ProxyConstructor == null) {
- try {
- ProxyConstructor = Proxy.class
- .getDeclaredConstructor(new Class[] { InvocationHandler.class });
- } catch (NoSuchMethodException e) {
- throw new InternalError();
- }
- }
- writeUnsignedShort(constantPool
- .literalIndex(getConstantPoolName(ProxyConstructor)));
- writeUnsignedShort(1); // store just the code attribute
- writeUnsignedShort(constantPool.literalIndex(CodeName));
- // save attribute_length(4), max_stack(2), max_locals(2), code_length(4)
- int codeLength = 6;
- writeUnsignedWord(12 + codeLength); // max_stack(2), max_locals(2),
- // code_length(4), 2 zero shorts
- writeUnsignedShort(2);
- writeUnsignedShort(2);
- writeUnsignedWord(codeLength);
- writeUnsignedByte(OPC_aload_0);
- writeUnsignedByte(OPC_aload_1);
- writeUnsignedByte(OPC_invokespecial);
- writeUnsignedShort(constantPool.literalIndex(ProxyConstructor));
- writeUnsignedByte(OPC_return);
- writeUnsignedShort(0); // no exceptions table
- writeUnsignedShort(0); // there are no attributes for the code
- // attribute
-
- for (int i = 0; i < methodCount; i++) {
- ProxyMethod pMethod = proxyMethods[i];
- Method method = pMethod.method;
- writeUnsignedShort(AccPublic | AccFinal);
- writeUnsignedShort(constantPool.literalIndex(method.getName()
- .toCharArray()));
- writeUnsignedShort(constantPool
- .literalIndex(getConstantPoolName(method)));
- Class[] thrownsExceptions = pMethod.commonExceptions;
- int eLength = thrownsExceptions.length;
- if (eLength > 0) {
- writeUnsignedShort(2); // store the exception & code attributes
- // The method has a throw clause. So we need to add an exception
- // attribute
- writeUnsignedShort(constantPool.literalIndex(ExceptionsName));
- // The attribute length = length * 2 + 2 in case of a exception
- // attribute
- writeUnsignedWord(eLength * 2 + 2);
- writeUnsignedShort(eLength);
- for (int e = 0; e < eLength; e++) {
- writeUnsignedShort(constantPool
- .typeIndex(thrownsExceptions[e].getName()));
- }
- } else {
- writeUnsignedShort(1); // store just the code attribute
- }
- generateCodeAttribute(pMethod);
- }
- }
-
- private void findMethods(Class[] interfaces) {
- /*
- * find all methods defined by the interfaces (including inherited
- * interfaces) plus hashCode, equals & toString from Object build an
- * array with the methods... no duplicates - check up to the array size
- * when the interface's first method was added
- */
- if (ObjectEqualsMethod == null) {
- try {
- ObjectEqualsMethod = Object.class.getMethod("equals",
- new Class[] { Object.class });
- ObjectHashCodeMethod = Object.class.getMethod("hashCode",
- new Class[0]);
- ObjectToStringMethod = Object.class.getMethod("toString",
- new Class[0]);
- } catch (NoSuchMethodException ex) {
- throw new InternalError();
- }
- }
-
- ArrayList<ProxyMethod> allMethods = new ArrayList<ProxyMethod>(25);
- allMethods.add(new ProxyMethod(ObjectEqualsMethod));
- allMethods.add(new ProxyMethod(ObjectHashCodeMethod));
- allMethods.add(new ProxyMethod(ObjectToStringMethod));
-
- HashSet<Class<?>> interfacesSeen = new HashSet<Class<?>>();
- for (Class<?> element : interfaces) {
- findMethods(element, allMethods, interfacesSeen);
- }
-
- proxyMethods = new ProxyMethod[allMethods.size()];
- allMethods.toArray(proxyMethods);
- }
-
- private void findMethods(Class<?> nextInterface,
- ArrayList<ProxyMethod> allMethods, HashSet<Class<?>> interfacesSeen) {
- /*
- * add the nextInterface's methods to allMethods if an equivalent method
- * already exists then return types must be identical... don't replace
- * it
- */
- if (interfacesSeen.contains(nextInterface)) {
- return; // already walked it
- }
- interfacesSeen.add(nextInterface);
-
- int existingMethodCount = allMethods.size();
- Method[] methods = nextInterface.getMethods();
- nextMethod: for (Method method : methods) {
- for (int j = 0; j < existingMethodCount; j++) {
- if (allMethods.get(j).matchMethod(method)) {
- continue nextMethod;
- }
- }
- allMethods.add(new ProxyMethod(method));
- }
-
- Class<?>[] superInterfaces = nextInterface.getInterfaces();
- for (Class<?> element : superInterfaces) {
- // recursion should be minimal
- findMethods(element, allMethods, interfacesSeen);
- }
- }
-
- private void generateCodeAttribute(ProxyMethod pMethod) {
- int codeAttributeOffset = contentsOffset;
- int contentsLength = contents.length;
- if (contentsOffset + 20 + 100 >= contentsLength) {
- System.arraycopy(contents, 0, (contents = new byte[contentsLength
- + INCREMENT_SIZE]), 0, contentsLength);
- }
- writeUnsignedShort(constantPool.literalIndex(CodeName));
- // leave space for attribute_length(4), max_stack(2), max_locals(2),
- // code_length(4)
- contentsOffset += 12;
-
- /*
- * to push the args for the call to invoke push the receiver field h 0
- * aload0 1 getfield 33 java.lang.reflect.Proxy.h
- * Ljava.lang.reflect.InvocationHandler; push the receiver as the first
- * arg 4 aload0 push the method push the array of args call invoke 89
- * invokeinterface 67
- * java.lang.reflect.InvocationHandler.invoke(Ljava.lang.Object;Ljava.lang.reflect.Method;[Ljava.lang.Object;)Ljava.lang.Object;
- * cast return result catch & convert exceptions if necessary
- */
-
- int codeStartOffset = contentsOffset;
- writeUnsignedByte(OPC_aload_0);
- writeUnsignedByte(OPC_getfield);
- if (ProxyHandlerField == null) {
- try {
- ProxyHandlerField = Proxy.class.getDeclaredField("h");
- } catch (NoSuchFieldException e) {
- throw new InternalError();
- }
- }
- writeUnsignedShort(constantPool.literalIndex(ProxyHandlerField));
- writeUnsignedByte(OPC_aload_0);
- Method method = pMethod.method;
- Class[] argTypes = method.getParameterTypes();
- genCallGetMethod(method.getDeclaringClass(), method.getName(), argTypes);
- int maxLocals = genInvokeArgs(argTypes);
- writeUnsignedByte(OPC_invokeinterface);
- if (HandlerInvokeMethod == null) {
- try {
- HandlerInvokeMethod = InvocationHandler.class.getMethod(
- "invoke", new Class[] { Object.class, Method.class,
- Object[].class });
- } catch (NoSuchMethodException e) {
- throw new InternalError();
- }
- }
- writeUnsignedShort(constantPool.literalIndex(HandlerInvokeMethod));
- writeUnsignedByte(4); // invoke has 3 args
- writeUnsignedByte(0); // 4th operand must be 0
- genCastReturnType(method.getReturnType());
- int codeLength = contentsOffset - codeStartOffset;
-
- Class[] checkedExceptions = pMethod.getCheckedExceptions();
- int checkedLength = checkedExceptions.length;
- if (checkedLength > 0) {
- int codeEndIndex = contentsOffset - codeStartOffset;
- writeUnsignedByte(OPC_athrow); // re-throw the caught exception
-
- genStoreArg(maxLocals);
- writeUnsignedByte(OPC_new);
- writeUnsignedShort(constantPool
- .typeIndex("java/lang/reflect/UndeclaredThrowableException"));
- writeUnsignedByte(OPC_dup);
- genLoadArg(maxLocals);
- maxLocals++; // now expecting the exception
- writeUnsignedByte(OPC_invokespecial);
- if (UndeclaredThrowableExceptionConstructor == null) {
- try {
- UndeclaredThrowableExceptionConstructor = UndeclaredThrowableException.class
- .getConstructor(new Class[] { Throwable.class });
- } catch (NoSuchMethodException e) {
- throw new InternalError();
- }
- }
- writeUnsignedShort(constantPool
- .literalIndex(UndeclaredThrowableExceptionConstructor));
- writeUnsignedByte(OPC_athrow);
-
- codeLength = contentsOffset - codeStartOffset;
-
- // write the exception table
- writeUnsignedShort(checkedLength + 1);
- for (int i = 0; i < checkedLength; i++) {
- writeUnsignedShort(0);
- writeUnsignedShort(codeEndIndex);
- writeUnsignedShort(codeEndIndex);
- writeUnsignedShort(constantPool.typeIndex(checkedExceptions[i]
- .getName()));
- }
- writeUnsignedShort(0);
- writeUnsignedShort(codeEndIndex);
- writeUnsignedShort(codeEndIndex + 1); // starts after the first
- // throw
- writeUnsignedShort(constantPool.typeIndex("java/lang/Throwable"));
- } else {
- writeUnsignedShort(0); // no exceptions table
- }
- // there are no attributes for the code attribute
- writeUnsignedShort(0);
-
- /*
- * Complete the creation of the code attribute by setting the
- * attribute_length, max_stack max_locals, code_length & exception table
- * codeAttributeOffset is the position inside contents byte array before
- * we started to write That means that to write the attribute_length you
- * need to offset by 2 the value of codeAttributeOffset to get the right
- * position, 6 for the max_stack etc...
- */
- int codeAttributeLength = contentsOffset - (codeAttributeOffset + 6);
- contents[codeAttributeOffset + 2] = (byte) (codeAttributeLength >> 24);
- contents[codeAttributeOffset + 3] = (byte) (codeAttributeLength >> 16);
- contents[codeAttributeOffset + 4] = (byte) (codeAttributeLength >> 8);
- contents[codeAttributeOffset + 5] = (byte) codeAttributeLength;
-
- int maxStack = maxLocals + 10; // larger than the exact amount
- contents[codeAttributeOffset + 6] = (byte) (maxStack >> 8);
- contents[codeAttributeOffset + 7] = (byte) maxStack;
- contents[codeAttributeOffset + 8] = (byte) (maxLocals >> 8);
- contents[codeAttributeOffset + 9] = (byte) maxLocals;
- contents[codeAttributeOffset + 10] = (byte) (codeLength >> 24);
- contents[codeAttributeOffset + 11] = (byte) (codeLength >> 16);
- contents[codeAttributeOffset + 12] = (byte) (codeLength >> 8);
- contents[codeAttributeOffset + 13] = (byte) codeLength;
- }
-
- /**
- * Perform call to Class.getMethod(String, Class[]) receiver 13 ldc 37
- * (java.lang.String) "java.lang.Object" 15 invokestatic 43
- * java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class; selector 37
- * ldc 55 (java.lang.String) "equals" plus method args 39 iconst0 40
- * anewarray 39 java.lang.Class or 39 iconst1 40 anewarray 39
- * java.lang.Class 43 dup 44 iconst0 53 ldc 37 (java.lang.String)
- * "java.lang.Object" 55 invokestatic 43
- * java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class; 77 aastore
- * or 39 iconst2 40 anewarray 39 java.lang.Class 43 dup 44 iconst0 45
- * getstatic 102 java.lang.Integer.TYPE Ljava.lang.Class; 48 aastore 49 dup
- * 50 iconst1 51 getstatic 104 java.lang.Boolean.TYPE Ljava.lang.Class; 54
- * aastore then 78 invokevirtual 59
- * java.lang.Class.getMethod(Ljava.lang.String;[Ljava.lang.Class;)Ljava.lang.reflect.Method;
- */
- private void genCallGetMethod(Class<?> receiverType, String selector,
- Class[] argTypes) {
- genCallClassForName(receiverType.getName());
- writeLdc(selector);
- int length = argTypes.length;
- writeIntConstant(length);
- writeUnsignedByte(OPC_anewarray);
- writeUnsignedShort(constantPool.typeIndex("java/lang/Class"));
- for (int i = 0; i < length; i++) {
- writeUnsignedByte(OPC_dup);
- writeIntConstant(i);
- Class<?> type = argTypes[i];
- if (type.isPrimitive()) {
- writeUnsignedByte(OPC_getstatic);
- writeUnsignedShort(constantPool.literalIndex(typeField(type)));
- } else {
- genCallClassForName(type.getName());
- }
- writeUnsignedByte(OPC_aastore);
- }
- writeUnsignedByte(OPC_invokevirtual);
- if (ClassGetMethod == null) {
- try {
- ClassGetMethod = Class.class.getMethod("getMethod",
- new Class[] { String.class, Class[].class });
- } catch (NoSuchMethodException e) {
- throw new InternalError();
- }
- }
- writeUnsignedShort(constantPool.literalIndex(ClassGetMethod));
- }
-
- /**
- * Add argument array for call to InvocationHandler.invoke
- *
- * 46 aconstnull or 81 iconst1 82 anewarray 61 java.lang.Object 85 dup 86
- * iconst0 87 aload1 88 aastore or 58 iconst2 59 anewarray 61
- * java.lang.Object 62 dup 63 iconst0 64 new 84 java.lang.Integer 67 dup 68
- * iload1 69 invokespecial 107 java.lang.Integer.<init>(I)V 72 aastore 73
- * dup 74 iconst1 75 new 69 java.lang.Boolean 78 dup 79 iload2 80
- * invokespecial 110 java.lang.Boolean.<init>(Z)V 83 aastore
- */
- private int genInvokeArgs(Class[] argTypes) {
- int argByteOffset = 1; // remember h is at position 0
- int length = argTypes.length;
- if (length == 0) {
- writeUnsignedByte(OPC_aconst_null);
- } else {
- writeIntConstant(length);
- writeUnsignedByte(OPC_anewarray);
- writeUnsignedShort(constantPool.typeIndex("java/lang/Object"));
- for (int i = 0; i < length; i++) {
- writeUnsignedByte(OPC_dup);
- writeIntConstant(i);
- argByteOffset = genInvokeArg(argTypes[i], argByteOffset);
- writeUnsignedByte(OPC_aastore);
- }
- }
- return argByteOffset;
- }
-
- private int genInvokeArg(Class<?> type, int argByteOffset) {
- // offset represents maxLocals in bytes
- if (type.isPrimitive()) {
- writeUnsignedByte(OPC_new);
- writeUnsignedShort(constantPool.typeIndex(typeWrapperName(type)));
- writeUnsignedByte(OPC_dup);
- if (argByteOffset > 255) {
- writeUnsignedByte(OPC_wide);
- }
- if (type == long.class) {
- switch (argByteOffset) {
- case 0:
- writeUnsignedByte(OPC_lload_0);
- break;
- case 1:
- writeUnsignedByte(OPC_lload_1);
- break;
- case 2:
- writeUnsignedByte(OPC_lload_2);
- break;
- case 3:
- writeUnsignedByte(OPC_lload_3);
- break;
- default:
- writeUnsignedByte(OPC_lload);
- if (argByteOffset > 255) {
- writeUnsignedShort(argByteOffset);
- } else {
- writeUnsignedByte(argByteOffset);
- }
- }
- argByteOffset += 2;
- } else if (type == float.class) {
- switch (argByteOffset) {
- case 0:
- writeUnsignedByte(OPC_fload_0);
- break;
- case 1:
- writeUnsignedByte(OPC_fload_1);
- break;
- case 2:
- writeUnsignedByte(OPC_fload_2);
- break;
- case 3:
- writeUnsignedByte(OPC_fload_3);
- break;
- default:
- writeUnsignedByte(OPC_fload);
- if (argByteOffset > 255) {
- writeUnsignedShort(argByteOffset);
- } else {
- writeUnsignedByte(argByteOffset);
- }
- }
- argByteOffset++;
- } else if (type == double.class) {
- switch (argByteOffset) {
- case 0:
- writeUnsignedByte(OPC_dload_0);
- break;
- case 1:
- writeUnsignedByte(OPC_dload_1);
- break;
- case 2:
- writeUnsignedByte(OPC_dload_2);
- break;
- case 3:
- writeUnsignedByte(OPC_dload_3);
- break;
- default:
- writeUnsignedByte(OPC_dload);
- if (argByteOffset > 255) {
- writeUnsignedShort(argByteOffset);
- } else {
- writeUnsignedByte(argByteOffset);
- }
- }
- argByteOffset += 2;
- } else { // handles int, short, byte, boolean & char
- switch (argByteOffset) {
- case 0:
- writeUnsignedByte(OPC_iload_0);
- break;
- case 1:
- writeUnsignedByte(OPC_iload_1);
- break;
- case 2:
- writeUnsignedByte(OPC_iload_2);
- break;
- case 3:
- writeUnsignedByte(OPC_iload_3);
- break;
- default:
- writeUnsignedByte(OPC_iload);
- if (argByteOffset > 255) {
- writeUnsignedShort(argByteOffset);
- } else {
- writeUnsignedByte(argByteOffset);
- }
- }
- argByteOffset++;
- }
- writeUnsignedByte(OPC_invokespecial);
- writeUnsignedShort(constantPool.literalIndex(typeInitMethod(type)));
- } else {
- genLoadArg(argByteOffset);
- argByteOffset++;
- }
- return argByteOffset;
- }
-
- /**
- * 94 checkcast 69 java.lang.Boolean 97 invokevirtual 73
- * java.lang.Boolean.booleanValue()Z 100 ireturn or 52 checkcast 91
- * java.lang.String 55 areturn
- */
- private void genCastReturnType(Class<?> type) {
- if (type.isPrimitive()) {
- if (type == void.class) {
- writeUnsignedByte(OPC_pop);
- writeUnsignedByte(OPC_return);
- } else {
- writeUnsignedByte(OPC_checkcast);
- writeUnsignedShort(constantPool
- .typeIndex(typeWrapperName(type)));
- writeUnsignedByte(OPC_invokevirtual);
- writeUnsignedShort(constantPool
- .literalIndex(typeAccessMethod(type)));
- if (type == long.class) {
- writeUnsignedByte(OPC_lreturn);
- } else if (type == float.class) {
- writeUnsignedByte(OPC_freturn);
- } else if (type == double.class) {
- writeUnsignedByte(OPC_dreturn);
- } else { // handles int, short, byte, boolean & char
- writeUnsignedByte(OPC_ireturn);
- }
- }
- } else {
- writeUnsignedByte(OPC_checkcast);
- writeUnsignedShort(constantPool.typeIndex(type.getName()));
- writeUnsignedByte(OPC_areturn);
- }
- }
-
- private void genCallClassForName(String typeName) {
- writeLdc(typeName);
- writeUnsignedByte(OPC_invokestatic);
- if (ClassForNameMethod == null) {
- try {
- ClassForNameMethod = Class.class.getMethod("forName",
- new Class[] { String.class });
- } catch (NoSuchMethodException e) {
- throw new InternalError();
- }
- }
- writeUnsignedShort(constantPool.literalIndex(ClassForNameMethod));
- }
-
- private void genLoadArg(int argByteOffset) {
- if (argByteOffset > 255) {
- writeUnsignedByte(OPC_wide);
- writeUnsignedByte(OPC_aload);
- writeUnsignedShort(argByteOffset);
- } else {
- switch (argByteOffset) {
- case 0:
- writeUnsignedByte(OPC_aload_0);
- break;
- case 1:
- writeUnsignedByte(OPC_aload_1);
- break;
- case 2:
- writeUnsignedByte(OPC_aload_2);
- break;
- case 3:
- writeUnsignedByte(OPC_aload_3);
- break;
- default:
- writeUnsignedByte(OPC_aload);
- writeUnsignedByte(argByteOffset);
- }
- }
- }
-
- private void genStoreArg(int argByteOffset) {
- if (argByteOffset > 255) {
- writeUnsignedByte(OPC_wide);
- writeUnsignedByte(OPC_astore);
- writeUnsignedShort(argByteOffset);
- } else {
- switch (argByteOffset) {
- case 0:
- writeUnsignedByte(OPC_astore_0);
- break;
- case 1:
- writeUnsignedByte(OPC_astore_1);
- break;
- case 2:
- writeUnsignedByte(OPC_astore_2);
- break;
- case 3:
- writeUnsignedByte(OPC_astore_3);
- break;
- default:
- writeUnsignedByte(OPC_astore);
- writeUnsignedByte(argByteOffset);
- }
- }
- }
-
- private byte[] getBytes() {
- byte[] fullContents = new byte[headerOffset + contentsOffset];
- System.arraycopy(header, 0, fullContents, 0, headerOffset);
- System.arraycopy(contents, 0, fullContents, headerOffset,
- contentsOffset);
- return fullContents;
- }
-
- private Method typeAccessMethod(Class<?> baseType) {
- try {
- if (baseType == int.class) {
- return Integer.class.getMethod("intValue", (Class[]) null);
- }
- if (baseType == short.class) {
- return Short.class.getMethod("shortValue", (Class[]) null);
- }
- if (baseType == byte.class) {
- return Byte.class.getMethod("byteValue", (Class[]) null);
- }
- if (baseType == boolean.class) {
- return Boolean.class.getMethod("booleanValue", (Class[]) null);
- }
- if (baseType == char.class) {
- return Character.class.getMethod("charValue", (Class[]) null);
- }
- if (baseType == long.class) {
- return Long.class.getMethod("longValue", (Class[]) null);
- }
- if (baseType == float.class) {
- return Float.class.getMethod("floatValue", (Class[]) null);
- }
- if (baseType == double.class) {
- return Double.class.getMethod("doubleValue", (Class[]) null);
- }
- } catch (NoSuchMethodException e) {
- throw new InternalError();
- }
- return null;
- }
-
- private Field typeField(Class<?> baseType) {
- try {
- if (baseType == int.class) {
- return Integer.class.getField("TYPE");
- }
- if (baseType == short.class) {
- return Short.class.getField("TYPE");
- }
- if (baseType == byte.class) {
- return Byte.class.getField("TYPE");
- }
- if (baseType == boolean.class) {
- return Boolean.class.getField("TYPE");
- }
- if (baseType == char.class) {
- return Character.class.getField("TYPE");
- }
- if (baseType == long.class) {
- return Long.class.getField("TYPE");
- }
- if (baseType == float.class) {
- return Float.class.getField("TYPE");
- }
- if (baseType == double.class) {
- return Double.class.getField("TYPE");
- }
- } catch (NoSuchFieldException e) {
- throw new InternalError();
- }
- return null;
- }
-
- private Constructor<?> typeInitMethod(Class<?> baseType) {
- try {
- if (baseType == int.class) {
- return Integer.class.getConstructor(new Class[] { int.class });
- }
- if (baseType == short.class) {
- return Short.class.getConstructor(new Class[] { short.class });
- }
- if (baseType == byte.class) {
- return Byte.class.getConstructor(new Class[] { byte.class });
- }
- if (baseType == boolean.class) {
- return Boolean.class
- .getConstructor(new Class[] { boolean.class });
- }
- if (baseType == char.class) {
- return Character.class
- .getConstructor(new Class[] { char.class });
- }
- if (baseType == long.class) {
- return Long.class.getConstructor(new Class[] { long.class });
- }
- if (baseType == float.class) {
- return Float.class.getConstructor(new Class[] { float.class });
- }
- if (baseType == double.class) {
- return Double.class
- .getConstructor(new Class[] { double.class });
- }
- } catch (NoSuchMethodException e) {
- throw new InternalError();
- }
- return null;
- }
-
- private String typeWrapperName(Class<?> baseType) {
- if (baseType == int.class) {
- return "java/lang/Integer";
- }
- if (baseType == short.class) {
- return "java/lang/Short";
- }
- if (baseType == byte.class) {
- return "java/lang/Byte";
- }
- if (baseType == boolean.class) {
- return "java/lang/Boolean";
- }
- if (baseType == char.class) {
- return "java/lang/Character";
- }
- if (baseType == long.class) {
- return "java/lang/Long";
- }
- if (baseType == float.class) {
- return "java/lang/Float";
- }
- if (baseType == double.class) {
- return "java/lang/Double";
- }
- return null;
- }
-
- private void writeIntConstant(int b) {
- switch (b) {
- case 0:
- writeUnsignedByte(OPC_iconst_0);
- break;
- case 1:
- writeUnsignedByte(OPC_iconst_1);
- break;
- case 2:
- writeUnsignedByte(OPC_iconst_2);
- break;
- case 3:
- writeUnsignedByte(OPC_iconst_3);
- break;
- case 4:
- writeUnsignedByte(OPC_iconst_4);
- break;
- case 5:
- writeUnsignedByte(OPC_iconst_5);
- break;
- default:
- writeUnsignedByte(OPC_bipush);
- writeUnsignedByte(b);
- }
- }
-
- private void writeLdc(String constant) {
- int index = constantPool.literalIndexForLdc(constant.toCharArray());
- if (index <= 0) {
- throw new InternalError();
- }
- if (index > 255) {
- writeUnsignedByte(OPC_ldc_w);
- writeUnsignedShort(index);
- } else {
- writeUnsignedByte(OPC_ldc);
- writeUnsignedByte(index);
- }
- }
-
- private void writeUnsignedByte(int b) {
- try {
- contents[contentsOffset++] = (byte) b;
- } catch (IndexOutOfBoundsException e) {
- int actualLength = contents.length;
- System.arraycopy(contents, 0, (contents = new byte[actualLength
- + INCREMENT_SIZE]), 0, actualLength);
- contents[contentsOffset - 1] = (byte) b;
- }
- }
-
- private void writeUnsignedShort(int b) {
- writeUnsignedByte(b >>> 8);
- writeUnsignedByte(b);
- }
-
- private void writeUnsignedWord(int b) {
- writeUnsignedByte(b >>> 24);
- writeUnsignedByte(b >>> 16);
- writeUnsignedByte(b >>> 8);
- writeUnsignedByte(b);
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyConstantPool.java b/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyConstantPool.java
deleted file mode 100644
index 3789730..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyConstantPool.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.reflect;
-
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
-class ProxyConstantPool implements ProxyConstants {
- public static final int UTF8_INITIAL_SIZE = 50;
-
- public static final int STRING_INITIAL_SIZE = 21;
-
- public static final int FIELD_INITIAL_SIZE = 7;
-
- public static final int METHOD_INITIAL_SIZE = 21;
-
- public static final int INTERFACE_INITIAL_SIZE = 21;
-
- public static final int CLASS_INITIAL_SIZE = 21;
-
- public static final int NAMEANDTYPE_INITIAL_SIZE = 21;
-
- public static final int CONSTANTPOOL_INITIAL_SIZE = 500;
-
- public static final int CONSTANTPOOL_GROW_SIZE = 1000;
-
- ProxyCharArrayCache UTF8Cache;
-
- ProxyCharArrayCache stringCache;
-
- ProxyCharArrayCache classNameCache;
-
- ProxyObjectCache fieldCache;
-
- ProxyObjectCache methodCache;
-
- ProxyObjectCache interfaceMethodCache;
-
- ProxyNameAndTypeCache nameAndTypeCache;
-
- byte[] poolContent;
-
- int currentIndex;
-
- int currentOffset;
-
- ProxyConstantPool(ProxyClassFile classFile) {
- UTF8Cache = new ProxyCharArrayCache(UTF8_INITIAL_SIZE);
- stringCache = new ProxyCharArrayCache(STRING_INITIAL_SIZE);
- classNameCache = new ProxyCharArrayCache(CLASS_INITIAL_SIZE);
- fieldCache = new ProxyObjectCache(FIELD_INITIAL_SIZE);
- methodCache = new ProxyObjectCache(METHOD_INITIAL_SIZE);
- interfaceMethodCache = new ProxyObjectCache(INTERFACE_INITIAL_SIZE);
- nameAndTypeCache = new ProxyNameAndTypeCache(NAMEANDTYPE_INITIAL_SIZE);
- poolContent = classFile.header;
- currentOffset = classFile.headerOffset;
- currentIndex = 1;
- }
-
- int literalIndex(char[] utf8Constant) {
- int index;
- if ((index = UTF8Cache.get(utf8Constant)) < 0) {
- writeU1(Utf8Tag);
- int savedCurrentOffset = currentOffset;
- if (currentOffset + 2 >= poolContent.length) {
- int length = poolContent.length;
- System.arraycopy(poolContent, 0, (poolContent = new byte[length
- + CONSTANTPOOL_GROW_SIZE]), 0, length);
- }
- currentOffset += 2;
- int length = 0;
- for (int i = 0; i < utf8Constant.length; i++) {
- char current = utf8Constant[i];
- if ((current >= 0x0001) && (current <= 0x007F)) {
- // we only need one byte: ASCII table
- writeU1(current);
- length++;
- } else if (current > 0x07FF) {
- // we need 3 bytes
- length += 3;
- writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 = 1110
- // 0000
- writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 = 1000
- // 0000
- writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
- } else {
- // we can be 0 or between 0x0080 and 0x07FF
- // In that case we only need 2 bytes
- length += 2;
- writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 = 1100
- // 0000
- writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
- }
- }
- if (length >= 65535) {
- currentOffset = savedCurrentOffset - 1;
- return -1;
- }
- index = UTF8Cache.put(utf8Constant, currentIndex++);
- // Now we know the length that we have to write in the constant pool
- // we use savedCurrentOffset to do that
- poolContent[savedCurrentOffset] = (byte) (length >> 8);
- poolContent[savedCurrentOffset + 1] = (byte) length;
- }
- return index;
- }
-
- int literalIndex(Field aField) {
- int index;
- if ((index = fieldCache.get(aField)) < 0) {
- int classIndex = typeIndex(aField.getDeclaringClass().getName());
- int nameAndTypeIndex = literalIndexForNameAndType(
- literalIndex(aField.getName().toCharArray()),
- literalIndex(ProxyClassFile.getConstantPoolName(aField
- .getType())));
- index = fieldCache.put(aField, currentIndex++);
- writeU1(FieldRefTag);
- writeU2(classIndex);
- writeU2(nameAndTypeIndex);
- }
- return index;
- }
-
- int literalIndex(Constructor<?> aMethod) {
- int index;
- if ((index = methodCache.get(aMethod)) < 0) {
- int classIndex = typeIndex(aMethod.getDeclaringClass().getName());
- int nameAndTypeIndex = literalIndexForNameAndType(
- literalIndex(Init), literalIndex(ProxyClassFile
- .getConstantPoolName(aMethod)));
- index = methodCache.put(aMethod, currentIndex++);
- writeU1(MethodRefTag);
- writeU2(classIndex);
- writeU2(nameAndTypeIndex);
- }
- return index;
- }
-
- int literalIndex(Method aMethod) {
- int index;
- if (aMethod.getDeclaringClass().isInterface()) {
- if ((index = interfaceMethodCache.get(aMethod)) < 0) {
- int classIndex = typeIndex(aMethod.getDeclaringClass()
- .getName());
- int nameAndTypeIndex = literalIndexForNameAndType(
- literalIndex(aMethod.getName().toCharArray()),
- literalIndex(ProxyClassFile
- .getConstantPoolName(aMethod)));
- index = interfaceMethodCache.put(aMethod, currentIndex++);
- writeU1(InterfaceMethodRefTag);
- writeU2(classIndex);
- writeU2(nameAndTypeIndex);
- }
- } else if ((index = methodCache.get(aMethod)) < 0) {
- int classIndex = typeIndex(aMethod.getDeclaringClass().getName());
- int nameAndTypeIndex = literalIndexForNameAndType(
- literalIndex(aMethod.getName().toCharArray()),
- literalIndex(ProxyClassFile.getConstantPoolName(aMethod)));
- index = methodCache.put(aMethod, currentIndex++);
- writeU1(MethodRefTag);
- writeU2(classIndex);
- writeU2(nameAndTypeIndex);
- }
- return index;
- }
-
- int literalIndex(String stringConstant) {
- int index;
- char[] stringCharArray = stringConstant.toCharArray();
- if ((index = stringCache.get(stringCharArray)) < 0) {
- int stringIndex = literalIndex(stringCharArray);
- index = stringCache.put(stringCharArray, currentIndex++);
- writeU1(StringTag);
- writeU2(stringIndex);
- }
- return index;
- }
-
- int literalIndexForLdc(char[] stringCharArray) {
- int index;
- if ((index = stringCache.get(stringCharArray)) < 0) {
- int stringIndex;
- if ((stringIndex = UTF8Cache.get(stringCharArray)) < 0) {
- writeU1(Utf8Tag);
- int savedCurrentOffset = currentOffset;
- if (currentOffset + 2 >= poolContent.length) {
- int length = poolContent.length;
- System.arraycopy(poolContent, 0,
- (poolContent = new byte[length
- + CONSTANTPOOL_GROW_SIZE]), 0, length);
- }
- currentOffset += 2;
- int length = 0;
- for (int i = 0; i < stringCharArray.length; i++) {
- char current = stringCharArray[i];
- if ((current >= 0x0001) && (current <= 0x007F)) {
- // we only need one byte: ASCII table
- writeU1(current);
- length++;
- } else if (current > 0x07FF) {
- // we need 3 bytes
- length += 3;
- writeU1(0xE0 | ((current >> 12) & 0x0F)); // 0xE0 =
- // 1110 0000
- writeU1(0x80 | ((current >> 6) & 0x3F)); // 0x80 =
- // 1000 0000
- writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
- } else {
- // we can be 0 or between 0x0080 and 0x07FF
- // In that case we only need 2 bytes
- length += 2;
- writeU1(0xC0 | ((current >> 6) & 0x1F)); // 0xC0 =
- // 1100 0000
- writeU1(0x80 | (current & 0x3F)); // 0x80 = 1000 0000
- }
- }
- if (length >= 65535) {
- currentOffset = savedCurrentOffset - 1;
- return -1;
- }
- stringIndex = UTF8Cache.put(stringCharArray, currentIndex++);
- // Now we know the length that we have to write in the constant
- // pool
- // we use savedCurrentOffset to do that
- if (length > 65535)
- return 0;
- poolContent[savedCurrentOffset] = (byte) (length >> 8);
- poolContent[savedCurrentOffset + 1] = (byte) length;
- }
- index = stringCache.put(stringCharArray, currentIndex++);
- writeU1(StringTag);
- writeU2(stringIndex);
- }
- return index;
- }
-
- private int literalIndexForNameAndType(int nameIndex, int typeIndex) {
- int index;
- int[] key = new int[] { nameIndex, typeIndex };
- if ((index = nameAndTypeCache.get(key)) == -1) {
- index = nameAndTypeCache.put(key, currentIndex++);
- writeU1(NameAndTypeTag);
- writeU2(nameIndex);
- writeU2(typeIndex);
- }
- return index;
- }
-
- int typeIndex(String typeName) {
- int index;
- if (typeName.indexOf('.') != -1)
- typeName = typeName.replace('.', '/');
- char[] charArray = typeName.toCharArray();
- if ((index = classNameCache.get(charArray)) < 0) {
- int nameIndex = literalIndex(charArray);
- index = classNameCache.put(charArray, currentIndex++);
- writeU1(ClassTag);
- writeU2(nameIndex);
- }
- return index;
- }
-
- private final void writeU1(int value) {
- try {
- poolContent[currentOffset++] = (byte) value;
- } catch (IndexOutOfBoundsException e) {
- // currentOffset has been ++ already (see the -1)
- int length = poolContent.length;
- System.arraycopy(poolContent, 0, (poolContent = new byte[length
- + CONSTANTPOOL_GROW_SIZE]), 0, length);
- poolContent[currentOffset - 1] = (byte) value;
- }
- }
-
- private final void writeU2(int value) {
- try {
- poolContent[currentOffset++] = (byte) (value >> 8);
- } catch (IndexOutOfBoundsException e) {
- // currentOffset has been ++ already (see the -1)
- int length = poolContent.length;
- System.arraycopy(poolContent, 0, (poolContent = new byte[length
- + CONSTANTPOOL_GROW_SIZE]), 0, length);
- poolContent[currentOffset - 1] = (byte) (value >> 8);
- }
- try {
- poolContent[currentOffset++] = (byte) value;
- } catch (IndexOutOfBoundsException e) {
- // currentOffset has been ++ already (see the -1)
- int length = poolContent.length;
- System.arraycopy(poolContent, 0, (poolContent = new byte[length
- + CONSTANTPOOL_GROW_SIZE]), 0, length);
- poolContent[currentOffset - 1] = (byte) value;
- }
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyConstants.java b/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyConstants.java
deleted file mode 100644
index 93db394..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyConstants.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.reflect;
-
-
-interface ProxyConstants {
- final char[] CodeName = new char[] { 'C', 'o', 'd', 'e' };
-
- final char[] ExceptionsName = new char[] { 'E', 'x', 'c', 'e', 'p', 't',
- 'i', 'o', 'n', 's' };
-
- final char[] Init = new char[] { '<', 'i', 'n', 'i', 't', '>' };
-
- final int AccPublic = 0x0001;
-
- final int AccPrivate = 0x0002;
-
- final int AccProtected = 0x0004;
-
- final int AccStatic = 0x0008;
-
- final int AccFinal = 0x0010;
-
- final int AccSuper = 0x0020;
-
- final int Utf8Tag = 1;
-
- final int IntegerTag = 3;
-
- final int FloatTag = 4;
-
- final int LongTag = 5;
-
- final int DoubleTag = 6;
-
- final int ClassTag = 7;
-
- final int StringTag = 8;
-
- final int FieldRefTag = 9;
-
- final int MethodRefTag = 10;
-
- final int InterfaceMethodRefTag = 11;
-
- final int NameAndTypeTag = 12;
-
- final int OPC_nop = 0;
-
- final int OPC_aconst_null = 1;
-
- final int OPC_iconst_m1 = 2;
-
- final int OPC_iconst_0 = 3;
-
- final int OPC_iconst_1 = 4;
-
- final int OPC_iconst_2 = 5;
-
- final int OPC_iconst_3 = 6;
-
- final int OPC_iconst_4 = 7;
-
- final int OPC_iconst_5 = 8;
-
- final int OPC_lconst_0 = 9;
-
- final int OPC_lconst_1 = 10;
-
- final int OPC_fconst_0 = 11;
-
- final int OPC_fconst_1 = 12;
-
- final int OPC_fconst_2 = 13;
-
- final int OPC_dconst_0 = 14;
-
- final int OPC_dconst_1 = 15;
-
- final int OPC_bipush = 16;
-
- final int OPC_sipush = 17;
-
- final int OPC_ldc = 18;
-
- final int OPC_ldc_w = 19;
-
- final int OPC_ldc2_w = 20;
-
- final int OPC_iload = 21;
-
- final int OPC_lload = 22;
-
- final int OPC_fload = 23;
-
- final int OPC_dload = 24;
-
- final int OPC_aload = 25;
-
- final int OPC_iload_0 = 26;
-
- final int OPC_iload_1 = 27;
-
- final int OPC_iload_2 = 28;
-
- final int OPC_iload_3 = 29;
-
- final int OPC_lload_0 = 30;
-
- final int OPC_lload_1 = 31;
-
- final int OPC_lload_2 = 32;
-
- final int OPC_lload_3 = 33;
-
- final int OPC_fload_0 = 34;
-
- final int OPC_fload_1 = 35;
-
- final int OPC_fload_2 = 36;
-
- final int OPC_fload_3 = 37;
-
- final int OPC_dload_0 = 38;
-
- final int OPC_dload_1 = 39;
-
- final int OPC_dload_2 = 40;
-
- final int OPC_dload_3 = 41;
-
- final int OPC_aload_0 = 42;
-
- final int OPC_aload_1 = 43;
-
- final int OPC_aload_2 = 44;
-
- final int OPC_aload_3 = 45;
-
- final int OPC_iaload = 46;
-
- final int OPC_laload = 47;
-
- final int OPC_faload = 48;
-
- final int OPC_daload = 49;
-
- final int OPC_aaload = 50;
-
- final int OPC_baload = 51;
-
- final int OPC_caload = 52;
-
- final int OPC_saload = 53;
-
- final int OPC_istore = 54;
-
- final int OPC_lstore = 55;
-
- final int OPC_fstore = 56;
-
- final int OPC_dstore = 57;
-
- final int OPC_astore = 58;
-
- final int OPC_istore_0 = 59;
-
- final int OPC_istore_1 = 60;
-
- final int OPC_istore_2 = 61;
-
- final int OPC_istore_3 = 62;
-
- final int OPC_lstore_0 = 63;
-
- final int OPC_lstore_1 = 64;
-
- final int OPC_lstore_2 = 65;
-
- final int OPC_lstore_3 = 66;
-
- final int OPC_fstore_0 = 67;
-
- final int OPC_fstore_1 = 68;
-
- final int OPC_fstore_2 = 69;
-
- final int OPC_fstore_3 = 70;
-
- final int OPC_dstore_0 = 71;
-
- final int OPC_dstore_1 = 72;
-
- final int OPC_dstore_2 = 73;
-
- final int OPC_dstore_3 = 74;
-
- final int OPC_astore_0 = 75;
-
- final int OPC_astore_1 = 76;
-
- final int OPC_astore_2 = 77;
-
- final int OPC_astore_3 = 78;
-
- final int OPC_iastore = 79;
-
- final int OPC_lastore = 80;
-
- final int OPC_fastore = 81;
-
- final int OPC_dastore = 82;
-
- final int OPC_aastore = 83;
-
- final int OPC_bastore = 84;
-
- final int OPC_castore = 85;
-
- final int OPC_sastore = 86;
-
- final int OPC_pop = 87;
-
- final int OPC_pop2 = 88;
-
- final int OPC_dup = 89;
-
- final int OPC_dup_x1 = 90;
-
- final int OPC_dup_x2 = 91;
-
- final int OPC_dup2 = 92;
-
- final int OPC_dup2_x1 = 93;
-
- final int OPC_dup2_x2 = 94;
-
- final int OPC_swap = 95;
-
- final int OPC_iadd = 96;
-
- final int OPC_ladd = 97;
-
- final int OPC_fadd = 98;
-
- final int OPC_dadd = 99;
-
- final int OPC_isub = 100;
-
- final int OPC_lsub = 101;
-
- final int OPC_fsub = 102;
-
- final int OPC_dsub = 103;
-
- final int OPC_imul = 104;
-
- final int OPC_lmul = 105;
-
- final int OPC_fmul = 106;
-
- final int OPC_dmul = 107;
-
- final int OPC_idiv = 108;
-
- final int OPC_ldiv = 109;
-
- final int OPC_fdiv = 110;
-
- final int OPC_ddiv = 111;
-
- final int OPC_irem = 112;
-
- final int OPC_lrem = 113;
-
- final int OPC_frem = 114;
-
- final int OPC_drem = 115;
-
- final int OPC_ineg = 116;
-
- final int OPC_lneg = 117;
-
- final int OPC_fneg = 118;
-
- final int OPC_dneg = 119;
-
- final int OPC_ishl = 120;
-
- final int OPC_lshl = 121;
-
- final int OPC_ishr = 122;
-
- final int OPC_lshr = 123;
-
- final int OPC_iushr = 124;
-
- final int OPC_lushr = 125;
-
- final int OPC_iand = 126;
-
- final int OPC_land = 127;
-
- final int OPC_ior = 128;
-
- final int OPC_lor = 129;
-
- final int OPC_ixor = 130;
-
- final int OPC_lxor = 131;
-
- final int OPC_iinc = 132;
-
- final int OPC_i2l = 133;
-
- final int OPC_i2f = 134;
-
- final int OPC_i2d = 135;
-
- final int OPC_l2i = 136;
-
- final int OPC_l2f = 137;
-
- final int OPC_l2d = 138;
-
- final int OPC_f2i = 139;
-
- final int OPC_f2l = 140;
-
- final int OPC_f2d = 141;
-
- final int OPC_d2i = 142;
-
- final int OPC_d2l = 143;
-
- final int OPC_d2f = 144;
-
- final int OPC_i2b = 145;
-
- final int OPC_i2c = 146;
-
- final int OPC_i2s = 147;
-
- final int OPC_lcmp = 148;
-
- final int OPC_fcmpl = 149;
-
- final int OPC_fcmpg = 150;
-
- final int OPC_dcmpl = 151;
-
- final int OPC_dcmpg = 152;
-
- final int OPC_ifeq = 153;
-
- final int OPC_ifne = 154;
-
- final int OPC_iflt = 155;
-
- final int OPC_ifge = 156;
-
- final int OPC_ifgt = 157;
-
- final int OPC_ifle = 158;
-
- final int OPC_if_icmpeq = 159;
-
- final int OPC_if_icmpne = 160;
-
- final int OPC_if_icmplt = 161;
-
- final int OPC_if_icmpge = 162;
-
- final int OPC_if_icmpgt = 163;
-
- final int OPC_if_icmple = 164;
-
- final int OPC_if_acmpeq = 165;
-
- final int OPC_if_acmpne = 166;
-
- final int OPC_goto = 167;
-
- final int OPC_jsr = 168;
-
- final int OPC_ret = 169;
-
- final int OPC_tableswitch = 170;
-
- final int OPC_lookupswitch = 171;
-
- final int OPC_ireturn = 172;
-
- final int OPC_lreturn = 173;
-
- final int OPC_freturn = 174;
-
- final int OPC_dreturn = 175;
-
- final int OPC_areturn = 176;
-
- final int OPC_return = 177;
-
- final int OPC_getstatic = 178;
-
- final int OPC_putstatic = 179;
-
- final int OPC_getfield = 180;
-
- final int OPC_putfield = 181;
-
- final int OPC_invokevirtual = 182;
-
- final int OPC_invokespecial = 183;
-
- final int OPC_invokestatic = 184;
-
- final int OPC_invokeinterface = 185;
-
- final int OPC_new = 187;
-
- final int OPC_newarray = 188;
-
- final int OPC_anewarray = 189;
-
- final int OPC_arraylength = 190;
-
- final int OPC_athrow = 191;
-
- final int OPC_checkcast = 192;
-
- final int OPC_instanceof = 193;
-
- final int OPC_monitorenter = 194;
-
- final int OPC_monitorexit = 195;
-
- final int OPC_wide = 196;
-
- final int OPC_multianewarray = 197;
-
- final int OPC_ifnull = 198;
-
- final int OPC_ifnonnull = 199;
-
- final int OPC_goto_w = 200;
-
- final int OPC_jsr_w = 201;
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyMethod.java b/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyMethod.java
deleted file mode 100644
index cd112b5..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyMethod.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.reflect;
-
-import java.lang.reflect.Method;
-
-import org.apache.harmony.luni.util.Msg;
-
-class ProxyMethod {
- Method method;
-
- Class[] commonExceptions;
-
- ProxyMethod(Method method) {
- this.method = method;
- this.commonExceptions = method.getExceptionTypes();
- }
-
- Class[] getCheckedExceptions() {
- Class[] newExceptions = commonExceptions.clone();
- int cLength = newExceptions.length;
- for (int c = 0, cL = cLength; c < cL; c++) {
- Class<?> ex = newExceptions[c];
- if (Throwable.class == ex) {
- // if Throwable is included then treat as if no exceptions are
- // checked
- return new Class[0];
- }
- if (Error.class.isAssignableFrom(ex) || RuntimeException.class.isAssignableFrom(ex)) {
- newExceptions[c] = null;
- cLength--;
- }
- }
-
- // All errors & runtime exceptions are passed back without being wrapped
- Class[] result = new Class[cLength + 2];
- int index = 0;
- result[index++] = Error.class;
- result[index++] = RuntimeException.class;
- for (Class<?> ex : newExceptions) {
- if (ex != null) {
- result[index++] = ex;
- }
- }
- return result;
- }
-
- boolean matchMethod(Method otherMethod) {
- if (!method.getName().equals(otherMethod.getName())) {
- return false;
- }
-
- Class[] params1 = method.getParameterTypes();
- Class[] params2 = otherMethod.getParameterTypes();
- int p = params1.length;
- if (p != params2.length) {
- return false;
- }
- while (--p >= 0) {
- if (params1[p] != params2[p]) {
- return false;
- }
- }
-
- Class<?> thisMethodReturnType = method.getReturnType();
- Class<?> otherMethodReturnType = otherMethod.getReturnType();
- if (!thisMethodReturnType.isAssignableFrom(otherMethodReturnType)) {
- if (otherMethodReturnType.isAssignableFrom(thisMethodReturnType)) {
- // substitute returnType of method with that of otherMethod
- method = otherMethod;
- } else {
- throw new IllegalArgumentException(Msg.getString("K00f2",
- method.getName()));
- }
- }
-
- if (commonExceptions.length != 0) {
- Class[] otherExceptions = otherMethod.getExceptionTypes();
- if (otherExceptions.length == 0) {
- commonExceptions = otherExceptions;
- } else {
- int cLength = commonExceptions.length;
- nextException: for (int c = 0, cL = cLength, oL = otherExceptions.length; c < cL; c++) {
- Class<?> cException = commonExceptions[c];
- for (int o = 0; o < oL; o++) {
- Class<?> oException = otherExceptions[o];
- if (cException == oException) {
- continue nextException;
- }
- if (oException.isAssignableFrom(cException)) {
- continue nextException; // cException is a subclass
- }
- if (cException.isAssignableFrom(oException)) {
- // oException is a subclass, keep it instead
- commonExceptions[c] = cException = oException;
- continue nextException;
- }
- }
- commonExceptions[c] = null;
- cLength--;
- }
- if (cLength != commonExceptions.length) {
- Class[] newExceptions = new Class[cLength];
- for (int i = 0, j = 0, length = commonExceptions.length; i < length; i++) {
- Class<?> ex = commonExceptions[i];
- if (ex != null) {
- newExceptions[j++] = ex;
- }
- }
- commonExceptions = newExceptions;
- }
- }
- }
- return true;
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyNameAndTypeCache.java b/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyNameAndTypeCache.java
deleted file mode 100644
index 09eb23e..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyNameAndTypeCache.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.reflect;
-
-class ProxyNameAndTypeCache {
- int[][] keyTable;
-
- int[] valueTable;
-
- int elementSize;
-
- int threshold;
-
- ProxyNameAndTypeCache(int initialCapacity) {
- if (initialCapacity < 13) {
- initialCapacity = 13;
- }
- this.elementSize = 0;
- this.threshold = (int) (initialCapacity * 0.66f);
- this.keyTable = new int[initialCapacity][];
- this.valueTable = new int[initialCapacity];
- }
-
- int get(int[] key) {
- int index = hashCode(key);
- while (keyTable[index] != null) {
- if (keyTable[index][0] == key[0] && keyTable[index][1] == key[1]) {
- return valueTable[index];
- }
- index = (index + 1) % keyTable.length;
- }
- return -1;
- }
-
- int hashCode(int[] key) {
- return (key[0] + key[1]) % keyTable.length;
- }
-
- int put(int[] key, int value) {
- int index = hashCode(key);
- while (keyTable[index] != null) {
- if (keyTable[index][0] == key[0] && keyTable[index][1] == key[1]) {
- return valueTable[index] = value;
- }
- index = (index + 1) % keyTable.length;
- }
- keyTable[index] = key;
- valueTable[index] = value;
-
- // assumes the threshold is never equal to the size of the table
- if (++elementSize > threshold) {
- rehash();
- }
- return value;
- }
-
- private void rehash() {
- ProxyNameAndTypeCache newHashtable = new ProxyNameAndTypeCache(keyTable.length * 2);
- for (int i = keyTable.length; --i >= 0;) {
- if (keyTable[i] != null) {
- newHashtable.put(keyTable[i], valueTable[i]);
- }
- }
-
- this.keyTable = newHashtable.keyTable;
- this.valueTable = newHashtable.valueTable;
- this.threshold = newHashtable.threshold;
- }
-
- int size() {
- return elementSize;
- }
-
- @Override
- public String toString() {
- int max = size();
- StringBuilder buf = new StringBuilder();
- buf.append("{");
- for (int i = 0; i < max; ++i) {
- if (keyTable[i] != null) {
- buf.append(keyTable[i]).append("->").append(valueTable[i]);
- }
- if (i < max) {
- buf.append(", ");
- }
- }
- buf.append("}");
- return buf.toString();
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyObjectCache.java b/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyObjectCache.java
deleted file mode 100644
index b3089c5..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/internal/reflect/ProxyObjectCache.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.internal.reflect;
-
-class ProxyObjectCache {
- Object keyTable[];
-
- int valueTable[];
-
- int elementSize;
-
- int threshold;
-
- ProxyObjectCache(int initialCapacity) {
- if (initialCapacity < 13) {
- initialCapacity = 13;
- }
- this.elementSize = 0;
- this.threshold = (int) (initialCapacity * 0.66f);
- this.keyTable = new Object[initialCapacity];
- this.valueTable = new int[initialCapacity];
- }
-
- int get(Object key) {
- int index = hashCode(key);
- while (keyTable[index] != null) {
- if (keyTable[index].equals(key)) {
- return valueTable[index];
- }
- index = (index + 1) % keyTable.length;
- }
- return -1;
- }
-
- int hashCode(Object key) {
- return (key.hashCode() & 0x7FFFFFFF) % keyTable.length;
- }
-
- int put(Object key, int value) {
- int index = hashCode(key);
- while (keyTable[index] != null) {
- if (keyTable[index].equals(key)) {
- return valueTable[index] = value;
- }
- index = (index + 1) % keyTable.length;
- }
- keyTable[index] = key;
- valueTable[index] = value;
-
- // assumes the threshold is never equal to the size of the table
- if (++elementSize > threshold) {
- rehash();
- }
- return value;
- }
-
- private void rehash() {
- ProxyObjectCache newHashtable = new ProxyObjectCache(
- keyTable.length * 2);
- for (int i = keyTable.length; --i >= 0;) {
- if (keyTable[i] != null) {
- newHashtable.put(keyTable[i], valueTable[i]);
- }
- }
-
- this.keyTable = newHashtable.keyTable;
- this.valueTable = newHashtable.valueTable;
- this.threshold = newHashtable.threshold;
- }
-
- int size() {
- return elementSize;
- }
-
- @Override
- public String toString() {
- int max = size();
- StringBuilder buf = new StringBuilder();
- buf.append("{"); //$NON-NLS-1$
- for (int i = 0; i < max; ++i) {
- if (keyTable[i] != null) {
- buf.append(keyTable[i]).append("->").append(valueTable[i]); //$NON-NLS-1$
- }
- if (i < max) {
- buf.append(", "); //$NON-NLS-1$
- }
- }
- buf.append("}"); //$NON-NLS-1$
- return buf.toString();
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
index 230df13..ac0c877 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
@@ -42,7 +42,7 @@
* support security checks. Alternative types of DatagramSocketImpl's may be
* used by setting the <code>impl.prefix</code> system property.
*/
-class PlainDatagramSocketImpl extends DatagramSocketImpl {
+public class PlainDatagramSocketImpl extends DatagramSocketImpl {
static final int MULTICAST_IF = 1;
@@ -70,7 +70,8 @@
*/
static final int REUSEADDR_AND_REUSEPORT = 10001;
- private boolean bindToDevice;
+ // Ignored in native code
+ private boolean bindToDevice = false;
private byte[] ipaddress = { 0, 0, 0, 0 };
@@ -116,7 +117,7 @@
public void bind(int port, InetAddress addr) throws SocketException {
String prop = AccessController.doPrivileged(new PriviAction<String>("bindToDevice")); //$NON-NLS-1$
boolean useBindToDevice = prop != null && prop.toLowerCase().equals("true"); //$NON-NLS-1$
- bindToDevice = netImpl.bind2(fd, port, useBindToDevice, addr);
+ netImpl.bind(fd, addr, port);
if (0 != port) {
localPort = port;
} else {
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainMulticastSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainMulticastSocketImpl.java
deleted file mode 100644
index 7f5ac50..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainMulticastSocketImpl.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.net;
-
-import java.net.SocketException;
-
-import org.apache.harmony.luni.platform.Platform;
-
-/**
- * This class was added so we can create sockets with options that are needed
- * for server sockets. It just overrides create so that we call new natives
- * which only set the options required for server sockets. In order to preserve
- * behaviour of older versions the create PlainSocketImpl was left as is and
- * this new class was added. For newer versions an instance of this class is
- * used, for earlier versions the original PlainSocketImpl is used.
- */
-class PlainMulticastSocketImpl extends PlainDatagramSocketImpl {
-
- @Override
- public void create() throws SocketException {
- Platform.getNetworkSystem().createMulticastSocket(fd, NetUtil.preferIPv4Stack());
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainServerSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainServerSocketImpl.java
index de6cb8f..4343ffb 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainServerSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainServerSocketImpl.java
@@ -24,14 +24,10 @@
import org.apache.harmony.luni.net.PlainSocketImpl;
/**
- * This class was added so we can create sockets with options that are needed
- * for server sockets. It just overrides create so that we call new natives
- * which only set the options required for server sockets. In order to preserve
- * behaviour of older versions the create PlainSocketImpl was left as is and
- * this new class was added. For newer versions an instance of this class is
- * used, for earlier versions the original PlainSocketImpl is used.
+ * This class overrides create to call natives that set the options required
+ * for server sockets.
*/
-class PlainServerSocketImpl extends PlainSocketImpl {
+public class PlainServerSocketImpl extends PlainSocketImpl {
public PlainServerSocketImpl() {
super();
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
index 4fb8b91..9a3ae6e 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl.java
@@ -43,7 +43,7 @@
/**
* A concrete connected-socket implementation.
*/
-class PlainSocketImpl extends SocketImpl {
+public class PlainSocketImpl extends SocketImpl {
// Const copy from socket
@@ -89,6 +89,27 @@
fd = new FileDescriptor();
}
+ public PlainSocketImpl(FileDescriptor fd) {
+ super();
+ this.fd = fd;
+ }
+
+ /**
+ * creates an instance with specified proxy.
+ */
+ public PlainSocketImpl(Proxy proxy) {
+ this();
+ this.proxy = proxy;
+ }
+
+ public PlainSocketImpl(FileDescriptor fd, int localport, InetAddress addr, int port) {
+ super();
+ this.fd = fd;
+ this.localport = localport;
+ this.address = addr;
+ this.port = port;
+ }
+
@Override
protected void accept(SocketImpl newImpl) throws IOException {
if (NetUtil.usingSocks(proxy)) {
@@ -160,7 +181,7 @@
@Override
protected void bind(InetAddress anAddr, int aPort) throws IOException {
- netImpl.bind(fd, aPort, anAddr);
+ netImpl.bind(fd, anAddr, aPort);
// PlainSocketImpl2.socketBindImpl2(fd, aPort, anAddr);
address = anAddr;
if (0 != aPort) {
@@ -201,7 +222,7 @@
/**
* Connects this socket to the specified remote host address/port.
- *
+ *
* @param anAddr
* the remote host address to connect to
* @param aPort
@@ -211,13 +232,10 @@
* @throws IOException
* if an error occurs while connecting
*/
- // BEGIN android-changed
- // copied from a newer harmony revision
private void connect(InetAddress anAddr, int aPort, int timeout)
throws IOException {
- InetAddress normalAddr = anAddr.isAnyLocalAddress() ? InetAddress
- .getLocalHost() : anAddr;
+ InetAddress normalAddr = anAddr.isAnyLocalAddress() ? InetAddress.getLocalHost() : anAddr;
try {
if (streaming) {
if (NetUtil.usingSocks(proxy)) {
@@ -231,7 +249,7 @@
}
}
} else {
- netImpl.connectDatagram(fd, aPort, trafficClass, normalAddr);
+ netImpl.connectDatagram(fd, aPort, trafficClass, normalAddr);
}
} catch (ConnectException e) {
throw new ConnectException(anAddr + ":" + aPort + " - "
@@ -240,16 +258,12 @@
super.address = normalAddr;
super.port = aPort;
}
- // END android-changed
@Override
protected void create(boolean streaming) throws IOException {
this.streaming = streaming;
if (streaming) {
- // BEGIN android-changed
- // call createSocket instead of createStreamSocket
- netImpl.createSocket(fd, NetUtil.preferIPv4Stack());
- // END android-changed
+ netImpl.createStreamSocket(fd, NetUtil.preferIPv4Stack());
} else {
netImpl.createDatagramSocket(fd, NetUtil.preferIPv4Stack());
}
@@ -546,16 +560,19 @@
if (shutdownInput) {
return -1;
}
- try {
- int read = netImpl.receiveStream(fd, buffer, offset, count,
- receiveTimeout);
- if (read == -1) {
- shutdownInput = true;
- }
- return read;
- } catch (InterruptedIOException e) {
- throw new SocketTimeoutException(e.getMessage());
+ // BEGIN android-changed
+ // call receiveStream() instead of read()
+ int read = netImpl.receiveStream(fd, buffer, offset, count, receiveTimeout);
+ // END android-changed
+ // Return of zero bytes for a blocking socket means a timeout occurred
+ if (read == 0) {
+ throw new SocketTimeoutException();
}
+ // Return of -1 indicates the peer was closed
+ if (read == -1) {
+ shutdownInput = true;
+ }
+ return read;
}
int write(byte[] buffer, int offset, int count) throws IOException {
@@ -563,6 +580,9 @@
return netImpl.sendDatagram2(fd, buffer, offset, count, port,
address);
}
+ // BEGIN android-changed
+ // call sendStream() instead of write()
return netImpl.sendStream(fd, buffer, offset, count);
+ // END android-changed
}
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl2.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl2.java
deleted file mode 100644
index 160de7c..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainSocketImpl2.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.net;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Proxy;
-
-/**
- * This class was added so we can create sockets without options that were
- * needed for server sockets. It just overrides create so that we call new
- * natives which only set the options required for plain sockets. In order to
- * preserve behaviour of older versions the create PlainSocketImpl was left as
- * is and this new class was added. For newer versions an instance of this class
- * is used, for earlier versions the original PlainSocketImpl is used.
- */
-class PlainSocketImpl2 extends PlainSocketImpl {
-
- public PlainSocketImpl2(FileDescriptor fd, int localport, InetAddress addr, int port) {
- super();
- super.fd = fd;
- super.localport = localport;
- super.address = addr;
- super.port = port;
- }
-
- public PlainSocketImpl2() {
- super();
- }
-
- /**
- * creates an instance with specified proxy.
- */
- public PlainSocketImpl2(Proxy proxy) {
- super();
- this.proxy = proxy;
- }
-
- @Override
- protected void create(boolean isStreaming) throws IOException {
- streaming = isStreaming;
- if (isStreaming) {
- netImpl.createSocket(fd, NetUtil.preferIPv4Stack());
- } else {
- netImpl.createDatagramSocket(fd, NetUtil.preferIPv4Stack());
- }
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/SocketImplProvider.java b/luni/src/main/java/org/apache/harmony/luni/net/SocketImplProvider.java
deleted file mode 100644
index e8e7dc3..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/net/SocketImplProvider.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.harmony.luni.net;
-
-import java.io.FileDescriptor;
-import java.net.DatagramSocketImpl;
-import java.net.InetAddress;
-import java.net.Proxy;
-import java.net.SocketImpl;
-
-public class SocketImplProvider {
-
- public static SocketImpl getSocketImpl() {
- return new PlainSocketImpl2();
- }
-
- /**
- * gets a SocketImpl with specified proxy.
- */
- public static SocketImpl getSocketImpl(Proxy proxy) {
- return new PlainSocketImpl2(proxy);
- }
-
- public static SocketImpl getSocketImpl(FileDescriptor fd, int localport, InetAddress addr,
- int port) {
- return new PlainSocketImpl2(fd, localport, addr, port);
- }
-
- public static SocketImpl getServerSocketImpl() {
- return new PlainServerSocketImpl();
- }
-
- public static SocketImpl getServerSocketImpl(FileDescriptor fd) {
- return new PlainServerSocketImpl(fd);
- }
-
- public static DatagramSocketImpl getDatagramSocketImpl() {
- return new PlainDatagramSocketImpl();
- }
-
- public static DatagramSocketImpl getMulticastSocketImpl() {
- return new PlainMulticastSocketImpl();
- }
-
- public static DatagramSocketImpl getDatagramSocketImpl(FileDescriptor fd, int localPort) {
- return new PlainDatagramSocketImpl(fd, localPort);
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/AbstractMemorySpy.java b/luni/src/main/java/org/apache/harmony/luni/platform/AbstractMemorySpy.java
index 130454f..5462cf0 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/AbstractMemorySpy.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/AbstractMemorySpy.java
@@ -30,84 +30,82 @@
*/
abstract class AbstractMemorySpy implements IMemorySpy {
- // TODO: figure out how to prevent this being a synchronization bottleneck
- protected Map<PlatformAddress,AddressWrapper> memoryInUse = new HashMap<PlatformAddress, AddressWrapper>(); // Shadow to Wrapper
+ // TODO: figure out how to prevent this being a synchronization bottleneck
+ protected Map<PlatformAddress,AddressWrapper> memoryInUse = new HashMap<PlatformAddress, AddressWrapper>(); // Shadow to Wrapper
- protected Map<Reference,PlatformAddress> refToShadow = new HashMap<Reference, PlatformAddress>(); // Reference to Shadow
+ protected Map<Reference,PlatformAddress> refToShadow = new HashMap<Reference, PlatformAddress>(); // Reference to Shadow
- protected ReferenceQueue<Object> notifyQueue = new ReferenceQueue<Object>();
+ protected ReferenceQueue<Object> notifyQueue = new ReferenceQueue<Object>();
- final class AddressWrapper {
- final PlatformAddress shadow;
+ final class AddressWrapper {
+ final PlatformAddress shadow;
- final PhantomReference<PlatformAddress> wrAddress;
+ final PhantomReference<PlatformAddress> wrAddress;
- volatile boolean autoFree = false;
+ volatile boolean autoFree = false;
- AddressWrapper(PlatformAddress address) {
- super();
- this.shadow = address.duplicate();
- this.wrAddress = new PhantomReference<PlatformAddress>(address, notifyQueue);
- }
- }
+ AddressWrapper(PlatformAddress address) {
+ super();
+ this.shadow = address.duplicate();
+ this.wrAddress = new PhantomReference<PlatformAddress>(address, notifyQueue);
+ }
+ }
- public AbstractMemorySpy() {
- super();
- }
+ public AbstractMemorySpy() {
+ super();
+ }
- public void alloc(PlatformAddress address) {
- AddressWrapper wrapper = new AddressWrapper(address);
- synchronized (this) {
- memoryInUse.put(wrapper.shadow, wrapper);
- refToShadow.put(wrapper.wrAddress, wrapper.shadow);
- }
- }
+ public void alloc(PlatformAddress address) {
+ AddressWrapper wrapper = new AddressWrapper(address);
+ synchronized (this) {
+ memoryInUse.put(wrapper.shadow, wrapper);
+ refToShadow.put(wrapper.wrAddress, wrapper.shadow);
+ }
+ }
- public boolean free(PlatformAddress address) {
- AddressWrapper wrapper;
- synchronized (this) {
- wrapper = memoryInUse.remove(address);
+ public boolean free(PlatformAddress address) {
+ AddressWrapper wrapper;
+ synchronized (this) {
+ wrapper = memoryInUse.remove(address);
// BEGIN android-added
if (wrapper != null) {
refToShadow.remove(wrapper.wrAddress);
}
// END android-added
- }
- if (wrapper == null) {
- // Attempt to free memory we didn't alloc
- System.err
- .println("Memory Spy! Fixed attempt to free memory that was not allocated " + address); //$NON-NLS-1$
- }
- return wrapper != null;
- }
+ }
+ if (wrapper == null) {
+ // Attempt to free memory we didn't alloc
+ System.err
+ .println("Memory Spy! Fixed attempt to free memory that was not allocated " + address); //$NON-NLS-1$
+ }
+ return wrapper != null;
+ }
- public void rangeCheck(PlatformAddress address, int offset, int length)
- throws IndexOutOfBoundsException {
- // Do nothing
- }
+ public void rangeCheck(PlatformAddress address, int offset, int length)
+ throws IndexOutOfBoundsException {
+ // Do nothing
+ }
- /*
- * (non-Javadoc)
- *
- * @see org.apache.harmony.luni.platform.struct.IMemorySpy#autoFree(org.apache.harmony.luni.platform.struct.PlatformAddress)
- */
- public void autoFree(PlatformAddress address) {
- AddressWrapper wrapper;
- synchronized (this) {
- wrapper = memoryInUse.get(address);
- }
- if (wrapper != null) {
- wrapper.autoFree = true;
- }
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.apache.harmony.luni.platform.struct.IMemorySpy#autoFree(org.apache.harmony.luni.platform.struct.PlatformAddress)
+ */
+ public void autoFree(PlatformAddress address) {
+ AddressWrapper wrapper;
+ synchronized (this) {
+ wrapper = memoryInUse.get(address);
+ }
+ if (wrapper != null) {
+ wrapper.autoFree = true;
+ }
+ }
- protected void orphanedMemory(Reference ref) {
- AddressWrapper wrapper;
- // BEGIN android-changed
- // copied from newer version of harmony
- synchronized (this) {
- PlatformAddress shadow = refToShadow.remove(ref);
- wrapper = memoryInUse.get(shadow);
+ protected void orphanedMemory(Reference ref) {
+ AddressWrapper wrapper;
+ synchronized (this) {
+ PlatformAddress shadow = refToShadow.remove(ref);
+ wrapper = memoryInUse.get(shadow);
if (wrapper != null) {
// There is a leak if we were not auto-freeing this memory.
if (!wrapper.autoFree) {
@@ -116,8 +114,7 @@
}
wrapper.shadow.free();
}
- }
+ }
ref.clear();
- // END android-changed
- }
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/AdapterManager.java b/luni/src/main/java/org/apache/harmony/luni/platform/AdapterManager.java
deleted file mode 100644
index 2380fbc..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/platform/AdapterManager.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.platform;
-
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Adapter Manager
- *
- */
-final class AdapterManager implements IAdapterManager {
-
- /*
- * key is adaptable type, and value is list of adapter factories for that
- * type.
- */
- private final HashMap<Class, List<IAdapterFactory>> factories = new HashMap<Class, List<IAdapterFactory>>();
-
- public Object getAdapter(IAdaptable adaptable, Class adapterType) {
- List factoryList = factories.get(adapterType);
- if (factoryList != null) {
- for (Iterator factoryItr = factoryList.iterator(); factoryItr
- .hasNext();) {
- IAdapterFactory factory = (IAdapterFactory) factoryItr.next();
- Object adapter = factory.getAdapter(adaptable, adapterType);
- if (adapter != null) {
- return adapter;
- }
- }
- }
- return null;
- }
-
- public boolean hasAdapter(IAdaptable adaptable, Class adapterType) {
- return null == getAdapter(adaptable, adapterType);
- }
-
- public void registerAdapters(IAdapterFactory factory, Class adaptable) {
- List<IAdapterFactory> factoryList = factories.get(adaptable);
- if (factoryList == null) {
- factoryList = new ArrayList<IAdapterFactory>();
- factories.put(adaptable, factoryList);
- }
- factoryList.add(factory);
- }
-
- public void unregisterAdapters(IAdapterFactory factory, Class adaptable) {
- List factoryList = factories.get(adaptable);
- if (factoryList != null) {
- factoryList.remove(factory);
- }
- }
-
- public void unregisterAdapters(IAdapterFactory factory) {
- for (Iterator<Class> knownAdaptablesItr = factories.keySet().iterator(); knownAdaptablesItr
- .hasNext();) {
- Class adaptable = knownAdaptablesItr.next();
- unregisterAdapters(factory, adaptable);
- }
- }
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IAdaptable.java b/luni/src/main/java/org/apache/harmony/luni/platform/IAdaptable.java
deleted file mode 100644
index e4c72ea..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IAdaptable.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.platform;
-
-
-/**
- * The interface to extensible objects.
- * <p>
- * Classes can implement this interface (a single method) to provide interfaces
- * that are not API -- each interface type has to be handled in the
- * implementation of <code>getAdapter(Class)</code>. This is a good way to
- * extend the class without breaking existing API.
- * </p>
- * <p>
- * In addition, classes can be augmented by interfaces that are defined by other
- * classes (which requires the <code>getAdapter(Class)</code> to be
- * implemented by a factory.
- *
- */
-public interface IAdaptable {
-
- /**
- * Returns the adapter corresponding to the given class.
- * <p>
- * The adapter is typically obtained using the class literal, like this:
- *
- * <pre>
- * ...
- * IAdaptable = (IAdaptable) foo;
- * IMyInterface bar = (IMyInterface)foo.getAdapter(IMyInterface.class);
- * bar.doMyThing();
- * ...
- * </pre>
- *
- * @param adapter
- * the type of adapter requested
- * @return the adapter
- */
- public Object getAdapter(Class adapter);
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IAdapterFactory.java b/luni/src/main/java/org/apache/harmony/luni/platform/IAdapterFactory.java
deleted file mode 100644
index 49fcd15..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IAdapterFactory.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.platform;
-
-
-/**
- * IAdapterFactory
- *
- */
-public interface IAdapterFactory {
-
- /**
- * Answer the adapter of the given type for the given object.
- *
- * @param adaptableObject
- * the object that implements IAdaptable.
- * @param adapterType
- * the type of adapter to return.
- * @return the adapter of the requested type.
- */
- public Object getAdapter(IAdaptable adaptableObject, Class adapterType);
-
- /**
- * Returns the adapters that this factory provides.
- *
- * @return the list of adapters as an array of classes.
- */
- public Class[] getAdapterList();
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IAdapterManager.java b/luni/src/main/java/org/apache/harmony/luni/platform/IAdapterManager.java
deleted file mode 100644
index 886dda7..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IAdapterManager.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.platform;
-
-
-/**
- * IAdapterManager
- *
- */
-public interface IAdapterManager {
- public Object getAdapter(IAdaptable adaptable, Class adapterType);
-
- public boolean hasAdapter(IAdaptable adaptable, Class adapterType);
-
- public void registerAdapters(IAdapterFactory factory, Class adaptable);
-
- public void unregisterAdapters(IAdapterFactory factory);
-
- public void unregisterAdapters(IAdapterFactory factory, Class adaptable);
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
index fb2ff9d..7613f0e 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/IFileSystem.java
@@ -29,7 +29,7 @@
* TODO Type description
*
*/
-public interface IFileSystem extends ISystemComponent {
+public interface IFileSystem {
public final int SHARED_LOCK_TYPE = 1;
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
index 9f70515..eae5261 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
@@ -29,17 +29,12 @@
import java.net.SocketImpl;
import java.net.UnknownHostException;
import java.nio.channels.Channel;
-import java.nio.channels.SelectableChannel;
/*
* The interface for network methods.
*/
public interface INetworkSystem {
- // -----------------------------------------------
- // Class Const
- // -----------------------------------------------
-
/*
* Socket connect Step start
*/
@@ -50,34 +45,24 @@
*/
public final int SOCKET_CONNECT_STEP_CHECK = 1;
- // -----------------------------------------------
- // Methods
- // -----------------------------------------------
-
/*
* socket accept
*/
public void accept(FileDescriptor fdServer, SocketImpl newSocket,
FileDescriptor fdnewSocket, int timeout) throws IOException;
- public void bind(FileDescriptor aFD, int port, InetAddress inetAddress)
+ public void bind(FileDescriptor aFD, InetAddress inetAddress, int port)
throws SocketException;
- public boolean bind2(FileDescriptor aFD, int port, boolean bindToDevice,
- InetAddress inetAddress) throws SocketException;
-
- public void createSocket(FileDescriptor fd, boolean preferIPv4Stack)
- throws IOException;
-
public int read(FileDescriptor aFD, byte[] data, int offset, int count,
int timeout) throws IOException;
-
+
public int readDirect(FileDescriptor aFD, int address, int offset, int count,
int timeout) throws IOException;
public int write(FileDescriptor fd, byte[] data, int offset, int count)
throws IOException;
-
+
public int writeDirect(FileDescriptor fd, int address, int offset, int count)
throws IOException;
@@ -96,7 +81,7 @@
public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
int length, int port, boolean bindToDevice, int trafficClass,
InetAddress inetAddress) throws IOException;
-
+
public int sendDatagramDirect(FileDescriptor fd, int address, int offset,
int length, int port, boolean bindToDevice, int trafficClass,
InetAddress inetAddress) throws IOException;
@@ -104,7 +89,7 @@
public int receiveDatagram(FileDescriptor aFD, DatagramPacket packet,
byte[] data, int offset, int length, int receiveTimeout,
boolean peek) throws IOException;
-
+
public int receiveDatagramDirect(FileDescriptor aFD, DatagramPacket packet,
int address, int offset, int length, int receiveTimeout,
boolean peek) throws IOException;
@@ -112,17 +97,17 @@
public int recvConnectedDatagram(FileDescriptor aFD, DatagramPacket packet,
byte[] data, int offset, int length, int receiveTimeout,
boolean peek) throws IOException;
-
+
public int recvConnectedDatagramDirect(FileDescriptor aFD,
DatagramPacket packet, int address, int offset, int length,
int receiveTimeout, boolean peek) throws IOException;
-
+
public int peekDatagram(FileDescriptor aFD, InetAddress sender,
int receiveTimeout) throws IOException;
public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
int offset, int length, boolean bindToDevice) throws IOException;
-
+
public int sendConnectedDatagramDirect(FileDescriptor fd, int address,
int offset, int length, boolean bindToDevice) throws IOException;
@@ -134,17 +119,17 @@
public void connectDatagram(FileDescriptor aFD, int port, int trafficClass,
InetAddress inetAddress) throws SocketException;
- public void createMulticastSocket(FileDescriptor aFD,
- boolean preferIPv4Stack) throws SocketException;
-
- public void createServerStreamSocket(FileDescriptor aFD,
- boolean preferIPv4Stack) throws SocketException;
-
+ /**
+ * @deprecated Use {@link #read(FileDescriptor, byte[], int, int, int)}
+ */
+ @Deprecated
public int receiveStream(FileDescriptor aFD, byte[] data, int offset,
int count, int timeout) throws IOException;
+ // BEGIN android-added
public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
throws IOException;
+ // END android-added
public void shutdownInput(FileDescriptor descriptor) throws IOException;
@@ -160,11 +145,14 @@
// public void acceptStreamSocket(FileDescriptor fdServer,
// SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
// throws IOException;
- //
- // public void createStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
- // throws SocketException;
// END android-removed
+ public void createServerStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
+ throws SocketException;
+
+ public void createStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
+ throws SocketException;
+
public void listenStreamSocket(FileDescriptor aFD, int backlog)
throws SocketException;
@@ -184,7 +172,7 @@
/*
* Query the IP stack for the local port to which this socket is bound.
- *
+ *
* @param aFD the socket descriptor @param preferIPv6Addresses address
* preference for nodes that support both IPv4 and IPv6 @return int the
* local port to which the socket is bound
@@ -194,10 +182,10 @@
/*
* Query the IP stack for the nominated socket option.
- *
+ *
* @param aFD the socket descriptor @param opt the socket option type
* @return the nominated socket option value
- *
+ *
* @throws SocketException if the option is invalid
*/
public Object getSocketOption(FileDescriptor aFD, int opt)
@@ -205,10 +193,10 @@
/*
* Set the nominated socket option in the IP stack.
- *
+ *
* @param aFD the socket descriptor @param opt the option selector @param
* optVal the nominated option value
- *
+ *
* @throws SocketException if the option is invalid or cannot be set
*/
public void setSocketOption(FileDescriptor aFD, int opt, Object optVal)
@@ -218,7 +206,7 @@
/*
* Close the socket in the IP stack.
- *
+ *
* @param aFD the socket descriptor
*/
public void socketClose(FileDescriptor aFD) throws IOException;
@@ -233,8 +221,8 @@
// BEGIN android-removed
// public boolean isReachableByICMP(InetAddress dest,InetAddress source,int ttl,int timeout);
// END android-removed
-
+
public Channel inheritedChannel();
-
+
public void oneTimeInitialization(boolean jcl_supports_ipv6);
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/ISystemComponent.java b/luni/src/main/java/org/apache/harmony/luni/platform/ISystemComponent.java
deleted file mode 100644
index 29cf555..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/platform/ISystemComponent.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.platform;
-
-
-/**
- * ISystemComponent
- *
- */
-public interface ISystemComponent extends IAdaptable {
- /*empty*/
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSComponent.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSComponent.java
deleted file mode 100644
index b5f14f2..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSComponent.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.platform;
-
-
-//BEGIN android-changed
-import dalvik.system.VMStack;
-// END android-changed
-
-/**
- * OSComponent
- *
- */
-class OSComponent implements IAdaptable {
-
- /**
- *
- */
- public OSComponent() {
- super();
- // BEGIN android-changed
- if (VMStack.getCallingClassLoader() != null) {
- throw new SecurityException();
- }
- // END android-changed
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.harmony.luni.platform.IAdaptable#getAdapter(java.lang.Class)
- */
- public Object getAdapter(Class adapter) {
- return Platform.getAdapterManager().getAdapter(this, adapter);
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSComponentFactory.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSComponentFactory.java
deleted file mode 100644
index a883ee0..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSComponentFactory.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.platform;
-
-
-/**
- * OSComponentFactory
- *
- */
-class OSComponentFactory {
-
- /**
- * @return OSFileSystem
- */
- public static IFileSystem getFileSystem() {
- // Auto-generated method stub
- return new OSFileSystem();
- }
-
- /**
- * @return OSMemory
- */
- public static IMemorySystem getMemorySystem() {
- // Auto-generated method stub
- return new OSMemory();
- }
-
- /**
- * @return OSNetwork
- */
- public static INetworkSystem getNetworkSystem() {
- return OSNetworkSystem.getOSNetworkSystem();
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
index 2759d6b..20cf7cb 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java
@@ -27,14 +27,17 @@
/**
* This is the portable implementation of the file system interface.
- *
+ *
*/
-class OSFileSystem extends OSComponent implements IFileSystem {
+class OSFileSystem implements IFileSystem {
- /**
- *
- */
- public OSFileSystem() {
+ private static final OSFileSystem singleton = new OSFileSystem();
+
+ public static OSFileSystem getOSFileSystem() {
+ return singleton;
+ }
+
+ private OSFileSystem() {
super();
}
@@ -153,6 +156,14 @@
}
long bytesRead = readImpl(fileDescriptor, bytes, offset, length);
if (bytesRead < -1) {
+ /*
+ * TODO: bytesRead is never less than -1 so this code
+ * does nothing?
+ * The native code throws an exception in only one case
+ * so perhaps this should be 'bytesRead < 0' to handle
+ * any other cases. But the other cases have been
+ * ignored until now so fixing this could break things
+ */
throw new IOException();
}
return bytesRead;
@@ -203,7 +214,7 @@
/*
* (non-Javadoc)
- *
+ *
* @see org.apache.harmony.luni.platform.IFileSystem#close(long)
*/
public void close(int fileDescriptor) throws IOException {
@@ -238,7 +249,8 @@
public long transfer(int fileHandler, FileDescriptor socketDescriptor,
long offset, long count) throws IOException {
long result = transferImpl(fileHandler, socketDescriptor, offset, count);
- if (result < 0) throw new IOException();
+ if (result < 0)
+ throw new IOException();
return result;
}
@@ -268,7 +280,7 @@
}
private native long ttyReadImpl(byte[] bytes, int offset, int length);
-
+
// BEGIN android-added
public native int ioctlAvailable(int fileDescriptor) throws IOException;
// END android-added
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java
index e3e7c46..0061d2a 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSMemory.java
@@ -43,7 +43,7 @@
* above.
* </p>
*/
-final class OSMemory extends OSComponent implements IMemorySystem {
+final class OSMemory implements IMemorySystem {
/**
* Defines the size, in bytes, of a native pointer type for the underlying
@@ -74,142 +74,150 @@
}
/**
- * This class is not designed to be publically instantiated.
- *
+ * This class is not designed to be publicly instantiated.
+ *
* @see #getOSMemory()
*/
- OSMemory() {
+ private OSMemory() {
super();
}
- // BEGIN android-note
- // changed to private
- // END android-note
/**
* Returns whether the byte order of this machine is little endian or not..
- *
- * @return <code>false</code> for Big Endian, and
- * <code>true</code. for Little Endian.
+ *
+ * @return <code>false</code> for Big Endian, and
+ * <code>true</code. for Little Endian.
*/
+ // BEGIN android-changed
+ /*public*/
private static native boolean isLittleEndianImpl();
+ // END android-changed
public boolean isLittleEndian() {
return isLittleEndianImpl();
}
- /**
- * Returns the natural byte order for this machine.
- *
- * @return the native byte order for the current platform.
- */
- public Endianness getNativeOrder() {
- return NATIVE_ORDER;
- }
+ /**
+ * Returns the natural byte order for this machine.
+ *
+ * @return the native byte order for the current platform.
+ */
+ public Endianness getNativeOrder() {
+ return NATIVE_ORDER;
+ }
- /**
- * Returns the size of a native pointer type for the underlying platform.
- *
- * @return the size of a pointer, in bytes.
- */
- private static native int getPointerSizeImpl();
+ /**
+ * Returns the size of a native pointer type for the underlying platform.
+ *
+ * @return the size of a pointer, in bytes.
+ */
+ private static native int getPointerSizeImpl();
- public int getPointerSize() {
- return POINTER_SIZE;
- }
+ public int getPointerSize() {
+ return POINTER_SIZE;
+ }
/**
* Allocates and returns a pointer to space for a memory block of
* <code>length</code> bytes. The space is uninitialized and may be larger
* than the number of bytes requested; however, the guaranteed usable memory
* block is exactly <code>length</code> bytes int.
- *
- * @param length
- * number of bytes requested.
+ *
+ * @param length
+ * number of bytes requested.
* @return the address of the start of the memory block.
- * @throws OutOfMemoryError
- * if the request cannot be satisfied.
+ * @throws OutOfMemoryError
+ * if the request cannot be satisfied.
*/
+ // BEGIN android-changed
+ // public long malloc(long length) throws OutOfMemoryError
+ // {
+ // OSResourcesMonitor.ensurePhysicalMemoryCapacity();
+ // return mallocNative(length);
+ // }
+ // private native long mallocNative(long length) throws OutOfMemoryError;
public native int malloc(int length) throws OutOfMemoryError;
+ // END android-changed
/**
* Deallocates space for a memory block that was previously allocated by a
* call to {@link #malloc(int) malloc(int)}. The number of bytes freed is
* identical to the number of bytes acquired when the memory block was
- * allocated. If <code>address</code> is zero the method does nothing.
- * <p>
+ * allocated. If <code>address</code> is zero the method does nothing.
+ * <p>
* Freeing a pointer to a memory block that was not allocated by
- * <code>malloc()</code> has unspecified effect.
- * </p>
- *
- * @param address
- * the address of the memory block to deallocate.
+ * <code>malloc()</code> has unspecified effect.
+ * </p>
+ *
+ * @param address
+ * the address of the memory block to deallocate.
*/
public native void free(int address);
/**
* Places <code>value</code> into first <code>length</code> bytes of the
- * memory block starting at <code>address</code>.
- * <p>
- * The behavior is unspecified if
- * <code>(address ... address + length)</code> is not wholly within the
- * range that was previously allocated using <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the address of the first memory location.
- * @param value
- * the byte value to set at each location.
- * @param length
- * the number of byte-length locations to set.
+ * memory block starting at <code>address</code>.
+ * <p>
+ * The behavior is unspecified if
+ * <code>(address ... address + length)</code> is not wholly within the
+ * range that was previously allocated using <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the address of the first memory location.
+ * @param value
+ * the byte value to set at each location.
+ * @param length
+ * the number of byte-length locations to set.
*/
public native void memset(int address, byte value, long length);
/**
* Copies <code>length</code> bytes from <code>srcAddress</code> to
- * <code>destAddress</code>. Where any part of the source memory block
- * and the destination memory block overlap <code>memmove()</code> ensures
- * that the original source bytes in the overlapping region are copied
- * before being overwritten.
- * <p>
- * The behavior is unspecified if
- * <code>(srcAddress ... srcAddress + length)</code> and
- * <code>(destAddress ... destAddress + length)</code> are not both wholly
- * within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param destAddress
- * the address of the destination memory block.
- * @param srcAddress
- * the address of the source memory block.
- * @param length
- * the number of bytes to move.
+ * <code>destAddress</code>. Where any part of the source memory block
+ * and the destination memory block overlap <code>memmove()</code> ensures
+ * that the original source bytes in the overlapping region are copied
+ * before being overwritten.
+ * <p>
+ * The behavior is unspecified if
+ * <code>(srcAddress ... srcAddress + length)</code> and
+ * <code>(destAddress ... destAddress + length)</code> are not both wholly
+ * within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param destAddress
+ * the address of the destination memory block.
+ * @param srcAddress
+ * the address of the source memory block.
+ * @param length
+ * the number of bytes to move.
*/
public native void memmove(int destAddress, int srcAddress, long length);
/**
* Copies <code>length</code> bytes from the memory block at
- * <code>address</code> into the byte array <code>bytes</code> starting
- * at element <code>offset</code> within the byte array.
- * <p>
- * The behavior of this method is undefined if the range
- * <code>(address ... address + length)</code> is not within a memory
+ * <code>address</code> into the byte array <code>bytes</code> starting
+ * at element <code>offset</code> within the byte array.
+ * <p>
+ * The behavior of this method is undefined if the range
+ * <code>(address ... address + length)</code> is not within a memory
* block that was allocated using {@link #malloc(int) malloc(int)}.
- * </p>
- *
- * @param address
- * the address of the OS memory block from which to copy bytes.
- * @param bytes
- * the byte array into which to copy the bytes.
- * @param offset
- * the index of the first element in <code>bytes</code> that
- * will be overwritten.
- * @param length
- * the total number of bytes to copy into the byte array.
- * @throws NullPointerException
- * if <code>bytes</code> is <code>null</code>.
- * @throws IndexOutOfBoundsException
- * if <code>offset + length > bytes.length</code>.
+ * </p>
+ *
+ * @param address
+ * the address of the OS memory block from which to copy bytes.
+ * @param bytes
+ * the byte array into which to copy the bytes.
+ * @param offset
+ * the index of the first element in <code>bytes</code> that
+ * will be overwritten.
+ * @param length
+ * the total number of bytes to copy into the byte array.
+ * @throws NullPointerException
+ * if <code>bytes</code> is <code>null</code>.
+ * @throws IndexOutOfBoundsException
+ * if <code>offset + length > bytes.length</code>.
*/
public native void getByteArray(int address, byte[] bytes, int offset,
int length) throws NullPointerException, IndexOutOfBoundsException;
@@ -217,32 +225,32 @@
/**
* Copies <code>length</code> bytes from the byte array <code>bytes</code>
* into the memory block at <code>address</code>, starting at element
- * <code>offset</code> within the byte array.
- * <p>
- * The behavior of this method is undefined if the range
- * <code>(address ... address + length)</code> is not within a memory
+ * <code>offset</code> within the byte array.
+ * <p>
+ * The behavior of this method is undefined if the range
+ * <code>(address ... address + length)</code> is not within a memory
* block that was allocated using {@link #malloc(int) malloc(int)}.
- * </p>
- *
- * @param address
- * the address of the OS memory block into which to copy the
- * bytes.
- * @param bytes
- * the byte array from which to copy the bytes.
- * @param offset
- * the index of the first element in <code>bytes</code> that
- * will be read.
- * @param length
- * the total number of bytes to copy from <code>bytes</code>
- * into the memory block.
- * @throws NullPointerException
- * if <code>bytes</code> is <code>null</code>.
- * @throws IndexOutOfBoundsException
- * if <code>offset + length > bytes.length</code>.
+ * </p>
+ *
+ * @param address
+ * the address of the OS memory block into which to copy the
+ * bytes.
+ * @param bytes
+ * the byte array from which to copy the bytes.
+ * @param offset
+ * the index of the first element in <code>bytes</code> that
+ * will be read.
+ * @param length
+ * the total number of bytes to copy from <code>bytes</code>
+ * into the memory block.
+ * @throws NullPointerException
+ * if <code>bytes</code> is <code>null</code>.
+ * @throws IndexOutOfBoundsException
+ * if <code>offset + length > bytes.length</code>.
*/
public native void setByteArray(int address, byte[] bytes, int offset,
int length) throws NullPointerException, IndexOutOfBoundsException;
-
+
// BEGIN android-added
/**
* Copies <code>length</code> shorts from the short array <code>shorts</code>
@@ -253,7 +261,7 @@
* <code>(address ... address + 2*length)</code> is not within a memory
* block that was allocated using {@link #malloc(int) malloc(int)}.
* </p>
- *
+ *
* @param address
* the address of the OS memory block into which to copy the
* shorts.
@@ -285,7 +293,7 @@
* <code>(address ... address + 2*length)</code> is not within a memory
* block that was allocated using {@link #malloc(int) malloc(int)}.
* </p>
- *
+ *
* @param address
* the address of the OS memory block into which to copy the
* ints.
@@ -312,43 +320,43 @@
// Primitive get & set methods
/**
- * Gets the value of the single byte at the given address.
- * <p>
- * The behavior is unspecified if <code>address</code> is not in the range
- * that was previously allocated using <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the byte.
+ * Gets the value of the single byte at the given address.
+ * <p>
+ * The behavior is unspecified if <code>address</code> is not in the range
+ * that was previously allocated using <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the byte.
* @return the byte value.
*/
public native byte getByte(int address);
/**
- * Sets the given single byte value at the given address.
- * <p>
- * The behavior is unspecified if <code>address</code> is not in the range
- * that was previously allocated using <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the address at which to set the byte value.
- * @param value
- * the value to set.
+ * Sets the given single byte value at the given address.
+ * <p>
+ * The behavior is unspecified if <code>address</code> is not in the range
+ * that was previously allocated using <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the address at which to set the byte value.
+ * @param value
+ * the value to set.
*/
public native void setByte(int address, byte value);
/**
* Gets the value of the signed two-byte integer stored in platform byte
- * order at the given address.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 2)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the two-byte value.
+ * order at the given address.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 2)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the two-byte value.
* @return the value of the two-byte integer as a Java <code>short</code>.
*/
public native short getShort(int address);
@@ -360,17 +368,17 @@
/**
* Sets the value of the signed two-byte integer at the given address in
- * platform byte order.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 2)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the two-byte value.
- * @param value
- * the value of the two-byte integer as a Java <code>short</code>.
+ * platform byte order.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 2)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the two-byte value.
+ * @param value
+ * the value of the two-byte integer as a Java <code>short</code>.
*/
public native void setShort(int address, short value);
@@ -384,15 +392,15 @@
/**
* Gets the value of the signed four-byte integer stored in platform
- * byte-order at the given address.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 4)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the four-byte value.
+ * byte-order at the given address.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 4)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the four-byte value.
* @return the value of the four-byte integer as a Java <code>int</code>.
*/
public native int getInt(int address);
@@ -404,17 +412,17 @@
/**
* Sets the value of the signed four-byte integer at the given address in
- * platform byte order.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 4)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the four-byte value.
- * @param value
- * the value of the four-byte integer as a Java <code>int</code>.
+ * platform byte order.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 4)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the four-byte value.
+ * @param value
+ * the value of the four-byte integer as a Java <code>int</code>.
*/
public native void setInt(int address, int value);
@@ -428,15 +436,15 @@
/**
* Gets the value of the signed eight-byte integer stored in platform byte
- * order at the given address.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 8)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the eight-byte value.
+ * order at the given address.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 8)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the eight-byte value.
* @return the value of the eight-byte integer as a Java <code>long</code>.
*/
public native long getLong(int address);
@@ -448,17 +456,17 @@
/**
* Sets the value of the signed eight-byte integer at the given address in
- * the platform byte order.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 8)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the eight-byte value.
- * @param value
- * the value of the eight-byte integer as a Java
+ * the platform byte order.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 8)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the eight-byte value.
+ * @param value
+ * the value of the eight-byte integer as a Java
* <code>long</code>.
*/
public native void setLong(int address, long value);
@@ -473,15 +481,15 @@
/**
* Gets the value of the IEEE754-format four-byte float stored in platform
- * byte order at the given address.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 4)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the eight-byte value.
+ * byte order at the given address.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 4)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the eight-byte value.
* @return the value of the four-byte float as a Java <code>float</code>.
*/
public native float getFloat(int address);
@@ -496,17 +504,17 @@
/**
* Sets the value of the IEEE754-format four-byte float stored in platform
- * byte order at the given address.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 4)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the eight-byte value.
- * @param value
- * the value of the four-byte float as a Java <code>float</code>.
+ * byte order at the given address.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 4)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the eight-byte value.
+ * @param value
+ * the value of the four-byte float as a Java <code>float</code>.
*/
public native void setFloat(int address, float value);
@@ -521,15 +529,15 @@
/**
* Gets the value of the IEEE754-format eight-byte float stored in platform
- * byte order at the given address.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 8)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the eight-byte value.
+ * byte order at the given address.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 8)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the eight-byte value.
* @return the value of the eight-byte float as a Java <code>double</code>.
*/
public native double getDouble(int address);
@@ -544,17 +552,17 @@
/**
* Sets the value of the IEEE754-format eight-byte float store in platform
- * byte order at the given address.
- * <p>
- * The behavior is unspecified if <code>(address ... address + 8)</code>
- * is not wholly within the range that was previously allocated using
- * <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the eight-byte value.
- * @param value
- * the value of the eight-byte float as a Java
+ * byte order at the given address.
+ * <p>
+ * The behavior is unspecified if <code>(address ... address + 8)</code>
+ * is not wholly within the range that was previously allocated using
+ * <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the eight-byte value.
+ * @param value
+ * the value of the eight-byte float as a Java
* <code>double</code>.
*/
public native void setDouble(int address, double value);
@@ -569,44 +577,44 @@
}
/**
- * Gets the value of the platform pointer at the given address.
- * <p>
- * The length of the platform pointer is defined by
- * <code>POINTER_SIZE</code>.
- * </p>
- * The behavior is unspecified if
- * <code>(address ... address + POINTER_SIZE)</code> is not wholly within
- * the range that was previously allocated using <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the platform pointer.
+ * Gets the value of the platform pointer at the given address.
+ * <p>
+ * The length of the platform pointer is defined by
+ * <code>POINTER_SIZE</code>.
+ * </p>
+ * The behavior is unspecified if
+ * <code>(address ... address + POINTER_SIZE)</code> is not wholly within
+ * the range that was previously allocated using <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the platform pointer.
* @return the value of the platform pointer as a Java <code>int</code>.
*/
public native int getAddress(int address);
/**
- * Sets the value of the platform pointer at the given address.
- * <p>
- * The length of the platform pointer is defined by
- * <code>POINTER_SIZE</code>. This method only sets
- * <code>POINTER_SIZE</code> bytes at the given address.
- * </p>
- * The behavior is unspecified if
- * <code>(address ... address + POINTER_SIZE)</code> is not wholly within
- * the range that was previously allocated using <code>malloc()</code>.
- * </p>
- *
- * @param address
- * the platform address of the start of the platform pointer.
- * @param value
+ * Sets the value of the platform pointer at the given address.
+ * <p>
+ * The length of the platform pointer is defined by
+ * <code>POINTER_SIZE</code>. This method only sets
+ * <code>POINTER_SIZE</code> bytes at the given address.
+ * </p>
+ * The behavior is unspecified if
+ * <code>(address ... address + POINTER_SIZE)</code> is not wholly within
+ * the range that was previously allocated using <code>malloc()</code>.
+ * </p>
+ *
+ * @param address
+ * the platform address of the start of the platform pointer.
+ * @param value
* the value of the platform pointer as a Java <code>int</code>.
*/
public native void setAddress(int address, int value);
/*
- * Memory mapped file
- */
+ * Memory mapped file
+ */
private native int mmapImpl(int fileDescriptor, long alignment,
long size, int mapMode);
@@ -632,39 +640,48 @@
private native int loadImpl(int l, long size);
public boolean isLoaded(int addr, long size) {
- return size == 0 ? true : isLoadedImpl(addr, size);
- }
+ return size == 0 ? true : isLoadedImpl(addr, size);
+ }
private native boolean isLoadedImpl(int l, long size);
public void flush(int addr, long size) {
- flushImpl(addr, size);
- }
+ flushImpl(addr, size);
+ }
private native int flushImpl(int l, long size);
- /*
- * Helper methods to change byte order.
- */
- private short swap(short value) {
- int topEnd = value << 8;
- int btmEnd = (value >> 8) & 0xFF;
- return (short) (topEnd | btmEnd);
- }
+ /*
+ * Helper methods to change byte order.
+ */
+ private short swap(short value) {
+ // BEGIN android-note
+ // is Integer.reverseBytes() >>> 16 be faster?
+ // END android-note
+ int topEnd = value << 8;
+ int btmEnd = (value >> 8) & 0xFF;
+ return (short) (topEnd | btmEnd);
+ }
- private int swap(int value) {
- short left = (short) (value >> 16);
- short right = (short) value;
- int topEnd = swap(right) << 16;
- int btmEnd = swap(left) & 0xFFFF;
- return topEnd | btmEnd;
- }
+ private int swap(int value) {
+ // BEGIN android-note
+ // is Integer.reverseBytes() be faster?
+ // END android-note
+ short left = (short) (value >> 16);
+ short right = (short) value;
+ int topEnd = swap(right) << 16;
+ int btmEnd = swap(left) & 0xFFFF;
+ return topEnd | btmEnd;
+ }
- private long swap(long value) {
- int left = (int) (value >> 32);
- int right = (int) value;
- long topEnd = ((long) swap(right)) << 32;
- long btmEnd = swap(left) & 0xFFFFFFFFL;
- return topEnd | btmEnd;
- }
+ private long swap(long value) {
+ // BEGIN android-note
+ // is Long.reverseBytes() be faster?
+ // END android-note
+ int left = (int) (value >> 32);
+ int right = (int) value;
+ long topEnd = ((long) swap(right)) << 32;
+ long btmEnd = swap(left) & 0xFFFFFFFFL;
+ return topEnd | btmEnd;
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
index c153428..0c9ac8a 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
@@ -16,7 +16,10 @@
*/
// BEGIN android-note
-// address length was changed from long to int for performance reasons.
+// Address length was changed from long to int for performance reasons.
+// Harmony implements INetworkSystem's methods with native methods; Android
+// implements them with Java that call through to native wrappers.
+// TODO: change the native code to eliminate the wrappers
// END android-note
package org.apache.harmony.luni.platform;
@@ -32,123 +35,33 @@
// BEGIN android-removed
// import java.nio.channels.SelectableChannel;
// END android-removed
-/*
- *
- * This Class is used for native code wrap, the implement class of
- * INetworkSystem.
- *
+
+/**
+ * This wraps native code that implements the INetworkSystem interface.
*/
final class OSNetworkSystem implements INetworkSystem {
- // ----------------------------------------------------
- // Class Variables
- // ----------------------------------------------------
-
private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
+ private static final int ERRORCODE_SOCKET_INTERRUPTED = -208;
- private static OSNetworkSystem ref = new OSNetworkSystem();
-
private static final int INETADDR_REACHABLE = 0;
-
+
private static boolean isNetworkInited = false;
-
- // ----------------------------------------------------
- // Class Constructor
- // ----------------------------------------------------
+ private static OSNetworkSystem singleton = new OSNetworkSystem();
- // can not be instantiated.
- private OSNetworkSystem() {
- super();
- }
-
- /*
- * @return a static ref of this class
+ /**
+ * Answers the unique instance of the OSNetworkSystem.
+ *
+ * @return the network system interface instance
*/
public static OSNetworkSystem getOSNetworkSystem() {
- return ref;
+ return singleton;
}
- // Useing when cache set/get is OK
- // public static native void oneTimeInitializationDatagram(
- // boolean jcl_IPv6_support);
- //
- // public static native void oneTimeInitializationSocket(
- // boolean jcl_IPv6_support);
-
- // --------------------------------------------------
- // java codes that wrap native codes
- // --------------------------------------------------
-
- public void createSocket(FileDescriptor fd, boolean preferIPv4Stack)
- throws IOException {
- createSocketImpl(fd, preferIPv4Stack);
- }
-
- public void createDatagramSocket(FileDescriptor fd, boolean preferIPv4Stack)
- throws SocketException {
- createDatagramSocketImpl(fd, preferIPv4Stack);
- }
-
- public int read(FileDescriptor aFD, byte[] data, int offset, int count,
- int timeout) throws IOException {
- return readSocketImpl(aFD, data, offset, count, timeout);
- }
-
- public int readDirect(FileDescriptor aFD, int address, int offset, int count,
- int timeout) throws IOException {
- return readSocketDirectImpl(aFD, address, offset, count, timeout);
- }
-
- public int write(FileDescriptor aFD, byte[] data, int offset, int count)
- throws IOException {
- return writeSocketImpl(aFD, data, offset, count);
- }
-
- public int writeDirect(FileDescriptor aFD, int address, int offset,
- int count) throws IOException {
- return writeSocketDirectImpl(aFD, address, offset, count);
- }
-
- public void setNonBlocking(FileDescriptor aFD, boolean block)
- throws IOException {
- setNonBlockingImpl(aFD, block);
- }
-
- public void connectDatagram(FileDescriptor aFD, int port, int trafficClass,
- InetAddress inetAddress) throws SocketException {
- connectDatagramImpl2(aFD, port, trafficClass, inetAddress);
- }
-
- public int connect(FileDescriptor aFD, int trafficClass,
- InetAddress inetAddress, int port) throws IOException{
- return connectSocketImpl(aFD, trafficClass, inetAddress, port);
- }
-
- // BEGIN android-changed
- public int connectWithTimeout(FileDescriptor aFD, int timeout,
- int trafficClass, InetAddress inetAddress, int port, int step,
- byte[] context) throws IOException{
- return connectWithTimeoutSocketImpl(aFD, timeout, trafficClass,
- inetAddress, port, step, context);
- }
- // END android-changed
-
- public void connectStreamWithTimeoutSocket(FileDescriptor aFD, int aport,
- int timeout, int trafficClass, InetAddress inetAddress)
- throws IOException {
- connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
- inetAddress);
- }
-
- public void bind(FileDescriptor aFD, int port, InetAddress inetAddress)
- throws SocketException {
- socketBindImpl(aFD, port, inetAddress);
- }
-
- public boolean bind2(FileDescriptor aFD, int port, boolean bindToDevice,
- InetAddress inetAddress) throws SocketException {
- return socketBindImpl2(aFD, port, bindToDevice, inetAddress);
+ // Can not be instantiated.
+ private OSNetworkSystem() {
+ super();
}
public void accept(FileDescriptor fdServer, SocketImpl newSocket,
@@ -156,110 +69,9 @@
acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
}
- public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
- int length, int port, boolean bindToDevice, int trafficClass,
- InetAddress inetAddress) throws IOException {
- return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
- trafficClass, inetAddress);
- }
-
- public int sendDatagramDirect(FileDescriptor fd, int address, int offset,
- int length, int port, boolean bindToDevice, int trafficClass,
- InetAddress inetAddress) throws IOException {
- return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
- trafficClass, inetAddress);
- }
-
- public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
- int length, int port, InetAddress inetAddress) throws IOException {
- return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
- }
-
- public int receiveDatagram(FileDescriptor aFD, DatagramPacket packet,
- byte[] data, int offset, int length, int receiveTimeout,
- boolean peek) throws IOException {
- return receiveDatagramImpl(aFD, packet, data, offset, length,
- receiveTimeout, peek);
- }
-
- public int receiveDatagramDirect(FileDescriptor aFD, DatagramPacket packet,
- int address, int offset, int length, int receiveTimeout,
- boolean peek) throws IOException {
- return receiveDatagramDirectImpl(aFD, packet, address, offset, length,
- receiveTimeout, peek);
- }
-
- public int recvConnectedDatagram(FileDescriptor aFD, DatagramPacket packet,
- byte[] data, int offset, int length, int receiveTimeout,
- boolean peek) throws IOException {
- return recvConnectedDatagramImpl(aFD, packet, data, offset, length,
- receiveTimeout, peek);
- }
-
- public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
- int offset, int length, int receiveTimeout, boolean peek)
- throws IOException {
- return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
- }
-
- public int peekDatagram(FileDescriptor aFD, InetAddress sender,
- int receiveTimeout) throws IOException {
- return peekDatagramImpl(aFD, sender, receiveTimeout);
- }
-
- public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
- int offset, int length, boolean bindToDevice) throws IOException {
- return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
- }
-
- public int sendConnectedDatagramDirect(FileDescriptor fd, int address,
- int offset, int length, boolean bindToDevice) throws IOException {
- return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
- }
-
- public void disconnectDatagram(FileDescriptor aFD) throws SocketException {
- disconnectDatagramImpl(aFD);
- }
-
- public void createMulticastSocket(FileDescriptor aFD,
- boolean preferIPv4Stack) throws SocketException {
- createMulticastSocketImpl(aFD, preferIPv4Stack);
- }
-
- public void createServerStreamSocket(FileDescriptor aFD,
- boolean preferIPv4Stack) throws SocketException {
- createServerStreamSocketImpl(aFD, preferIPv4Stack);
- }
-
- public int receiveStream(FileDescriptor aFD, byte[] data, int offset,
- int count, int timeout) throws IOException {
- return receiveStreamImpl(aFD, data, offset, count, timeout);
- }
-
- public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
- throws IOException {
- return sendStreamImpl(fd, data, offset, count);
- }
-
- public void shutdownInput(FileDescriptor descriptor) throws IOException {
- shutdownInputImpl(descriptor);
- }
-
- public void shutdownOutput(FileDescriptor descriptor) throws IOException {
- shutdownOutputImpl(descriptor);
- }
-
- public boolean supportsUrgentData(FileDescriptor fd) {
- return supportsUrgentDataImpl(fd);
- }
-
- public void sendUrgentData(FileDescriptor fd, byte value) {
- sendUrgentDataImpl(fd, value);
- }
-
- public int availableStream(FileDescriptor aFD) throws SocketException {
- return availableStreamImpl(aFD);
- }
+ static native void acceptSocketImpl(FileDescriptor fdServer,
+ SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
+ throws IOException;
// BEGIN android-removed
// public void acceptStreamSocket(FileDescriptor fdServer,
@@ -267,41 +79,479 @@
// throws IOException {
// acceptStreamSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
// }
- //
- // public void createStreamSocket(FileDescriptor aFD, boolean preferIPv4Stack)
- // throws SocketException {
- // createStreamSocketImpl(aFD, preferIPv4Stack);
+
+ // static native void acceptStreamSocketImpl(FileDescriptor fdServer,
+ // SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
+ // throws IOException;
+ // END android-removed
+
+ public int availableStream(FileDescriptor fd) throws SocketException {
+ return availableStreamImpl(fd);
+ }
+
+ static native int availableStreamImpl(FileDescriptor aFD) throws SocketException;
+
+ /**
+ * Associates a local address with a socket.
+ *
+ * @param fd
+ * the socket descriptor
+ * @param port
+ * the port number
+ * @param inetAddress
+ * address to bind
+ * @throws SocketException
+ * thrown if bind operation fails
+ */
+ public void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException {
+ socketBindImpl(fd, port, inetAddress);
+ }
+
+ static native void socketBindImpl(FileDescriptor aFD, int port, InetAddress inetAddress) throws SocketException;
+
+ public int connect(FileDescriptor fd, int trafficClass,
+ InetAddress inetAddress, int port) throws IOException{
+ return connectSocketImpl(fd, trafficClass, inetAddress, port);
+ }
+
+ static native int connectSocketImpl(FileDescriptor aFD,
+ int trafficClass, InetAddress inetAddress, int port);
+
+ public void connectDatagram(FileDescriptor fd, int port,
+ int trafficClass, InetAddress inetAddress) throws SocketException {
+ connectDatagramImpl2(fd, port, trafficClass, inetAddress);
+ }
+
+ static native void connectDatagramImpl2(FileDescriptor aFD, int port,
+ int trafficClass, InetAddress inetAddress) throws SocketException;
+
+ public void connectStreamWithTimeoutSocket(FileDescriptor aFD,
+ int aport, int timeout, int trafficClass, InetAddress inetAddress)
+ throws IOException {
+ connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
+ inetAddress);
+ }
+
+ static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
+ int aport, int timeout, int trafficClass, InetAddress inetAddress)
+ throws IOException;
+
+ // BEGIN android-changed
+ // changed context from Long to byte[]
+ public int connectWithTimeout(FileDescriptor fd, int timeout,
+ int trafficClass, InetAddress inetAddress, int port, int step,
+ byte[] context) throws IOException {
+ return connectWithTimeoutSocketImpl(fd, timeout, trafficClass,
+ inetAddress, port, step, context);
+ }
+
+ static native int connectWithTimeoutSocketImpl(FileDescriptor aFD,
+ int timeout, int trafficClass, InetAddress hostname, int port, int step,
+ byte[] context);
+ // END android-changed
+
+ public void createDatagramSocket(FileDescriptor fd,
+ boolean preferIPv4Stack) throws SocketException {
+ createDatagramSocketImpl(fd, preferIPv4Stack);
+ }
+
+ /*
+ * Allocate a datagram socket in the IP stack. The socket is associated with
+ * the <code>aFD</code>.
+ *
+ * @param aFD the FileDescriptor to associate with the socket @param
+ * preferIPv4Stack IP stack preference if underlying platform is V4/V6
+ * @exception SocketException upon an allocation error
+ */
+ static native void createDatagramSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ public void createServerStreamSocket(FileDescriptor fd,
+ boolean preferIPv4Stack) throws SocketException {
+ createServerStreamSocketImpl(fd, preferIPv4Stack);
+ }
+
+ /*
+ * Answer the result of attempting to create a server stream socket in the
+ * IP stack. Any special options required for server sockets will be set by
+ * this method.
+ *
+ * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
+ * @exception SocketException if an error occurs while creating the socket
+ */
+ static native void createServerStreamSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ public void createStreamSocket(FileDescriptor fd,
+ boolean preferIPv4Stack) throws SocketException {
+ createStreamSocketImpl(fd, preferIPv4Stack);
+ }
+
+ static native void createStreamSocketImpl(FileDescriptor aFD,
+ boolean preferIPv4Stack) throws SocketException;
+
+ /**
+ * Disconnect the socket to a port and address
+ *a
+ * @param fd
+ * the FileDescriptor associated with the socket
+ *
+ * @throws SocketException
+ * if the disconnect fails
+ */
+ public void disconnectDatagram(FileDescriptor fd)
+ throws SocketException {
+ disconnectDatagramImpl(fd);
+ }
+
+ static native void disconnectDatagramImpl(FileDescriptor aFD)
+ throws SocketException;
+
+ public InetAddress getHostByAddr(byte[] addr)
+ throws UnknownHostException {
+ return getHostByAddrImpl(addr);
+ }
+ static native InetAddress getHostByAddrImpl(byte[] addr)
+ throws UnknownHostException;
+
+ public InetAddress getHostByName(String addr,
+ boolean preferIPv6Addresses) throws UnknownHostException {
+ return getHostByNameImpl(addr, preferIPv6Addresses);
+ }
+
+ static native InetAddress getHostByNameImpl(String addr,
+ boolean preferIPv6Addresses) throws UnknownHostException;
+
+ public int getSocketFlags() {
+ return getSocketFlagsImpl();
+ }
+
+ static native int getSocketFlagsImpl();
+
+ public InetAddress getSocketLocalAddress(FileDescriptor fd,
+ boolean preferIPv6Addresses) {
+ return getSocketLocalAddressImpl(fd, preferIPv6Addresses);
+ }
+ static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD,
+ boolean preferIPv6Addresses);
+
+ /**
+ * Query the IP stack for the local port to which this socket is bound.
+ *
+ * @param aFD
+ * the socket descriptor
+ * @param preferIPv6Addresses
+ * address preference for nodes that support both IPv4 and IPv6
+ * @return the local port to which the socket is bound
+ */
+ public int getSocketLocalPort(FileDescriptor aFD,
+ boolean preferIPv6Addresses) {
+ return getSocketLocalPortImpl(aFD, preferIPv6Addresses);
+ }
+
+ static native int getSocketLocalPortImpl(FileDescriptor aFD,
+ boolean preferIPv6Addresses);
+
+ /**
+ * Query the IP stack for the nominated socket option.
+ *
+ * @param fd
+ * the socket descriptor
+ * @param opt
+ * the socket option type
+ * @return the nominated socket option value
+ * @throws SocketException
+ * if the option is invalid
+ */
+ public Object getSocketOption(FileDescriptor fd, int opt)
+ throws SocketException {
+ return getSocketOptionImpl(fd, opt);
+ }
+
+ static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
+ throws SocketException;
+
+ public Channel inheritedChannel() {
+ return inheritedChannelImpl();
+ }
+
+ native Channel inheritedChannelImpl();
+
+ // BEGIN android-removed
+ // public boolean isReachableByICMP(final InetAddress dest,
+ // InetAddress source, final int ttl, final int timeout) {
+ // return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
+ // timeout);
// }
+
+ // native int isReachableByICMPImpl(InetAddress addr,
+ // InetAddress local, int ttl, int timeout);
// END android-removed
public void listenStreamSocket(FileDescriptor aFD, int backlog)
throws SocketException {
listenStreamSocketImpl(aFD, backlog);
}
-
- // BEGIN android-removed
- // public boolean isReachableByICMP(final InetAddress dest,
- // InetAddress source, final int ttl, final int timeout) {
- // return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
- // timeout);
- // }
- // END android-removed
- /*
- *
- * @param
- * readChannels all channels interested in read and accept
- * @param
- * writeChannels all channels interested in write and connect
- * @param timeout
- * timeout in millis @return a set of channels that are ready for operation
- * @throws
- * SocketException @return int array, each int approve one of the * channel if OK
+ static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
+ throws SocketException;
+
+ public void oneTimeInitialization(boolean jcl_supports_ipv6) {
+ if (!isNetworkInited) {
+ oneTimeInitializationImpl(jcl_supports_ipv6);
+ isNetworkInited = true;
+ }
+ }
+
+ native void oneTimeInitializationImpl (boolean jcl_supports_ipv6);
+
+ /**
+ * Peek on the socket, update <code>sender</code> address and answer the
+ * sender port.
+ *
+ * @param fd
+ * the socket FileDescriptor
+ * @param sender
+ * an InetAddress, to be updated with the sender's address
+ * @param receiveTimeout
+ * the maximum length of time the socket should block, reading
+ * @return the sender port
+ *
+ * @throws IOException
+ * upon an read error or timeout
*/
+ public int peekDatagram(FileDescriptor fd, InetAddress sender,
+ int receiveTimeout) throws IOException {
+ return peekDatagramImpl(fd, sender, receiveTimeout);
+ }
- public int[] select(FileDescriptor[] readFDs,
- FileDescriptor[] writeFDs, long timeout)
- throws SocketException {
+ static native int peekDatagramImpl(FileDescriptor aFD,
+ InetAddress sender, int receiveTimeout) throws IOException;
+
+ /**
+ * Read available bytes from the given file descriptor into a byte array.
+ *
+ * The read has an optional timeout parameter, which if non-zero is the
+ * length of time that the read will wait on a select call to see if any
+ * bytes are available for reading. If the timeout expires the method
+ * returns zero to indicate no bytes were read.
+ *
+ * @param fd
+ * the socket file descriptor to read
+ * @param data
+ * the byte array in which to store the results
+ * @param offset
+ * the offset into the byte array in which to start reading the
+ * results
+ * @param count
+ * the maximum number of bytes to read
+ * @param timeout
+ * the length of time to wait for the bytes, in milliseconds; or
+ * zero to indicate no timeout applied. When there is no timeout
+ * applied the read may block based upon socket options.
+ * @return number of bytes read, or zero if there were no bytes available
+ * before the timeout occurred, or -1 to indicate the socket is
+ * closed
+ * @throws IOException
+ * if an underlying socket exception occurred
+ */
+ public int read(FileDescriptor fd, byte[] data, int offset, int count,
+ int timeout) throws IOException {
+ return readSocketImpl(fd, data, offset, count, timeout);
+ }
+
+ static native int readSocketImpl(FileDescriptor aFD, byte[] data,
+ int offset, int count, int timeout) throws IOException;
+
+ /**
+ * Read available bytes from the given file descriptor into OS memory at a
+ * given address.
+ *
+ * @param fd
+ * the socket file descriptor to read
+ * @param address
+ * the address of the memory in which to store the results
+ * @param count
+ * the maximum number of bytes to read
+ * @param timeout
+ * the length of time to wait for the bytes, in milliseconds
+ * @return number of bytes read, or zero if there were no bytes available
+ * before the timeout occurred, or -1 to indicate the socket is
+ * closed
+ * @throws IOException
+ * if an underlying socket exception occurred
+ */
+ public int readDirect(FileDescriptor fd, int address, int offset, int count,
+ int timeout) throws IOException {
+ return readSocketDirectImpl(fd, address, offset, count, timeout);
+ }
+
+ static native int readSocketDirectImpl(FileDescriptor aFD, int address, int offset, int count,
+ int timeout) throws IOException;
+
+ /**
+ * Receive data on the socket into the specified buffer. The packet fields
+ * <code>data</code> & <code>length</code> are passed in addition to
+ * <code>packet</code> to eliminate the JNI field access calls.
+ *
+ * @param fd
+ * the socket FileDescriptor
+ * @param packet
+ * the DatagramPacket to receive into
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param receiveTimeout
+ * the maximum length of time the socket should block, reading
+ * @param peek
+ * indicates to peek at the data
+ * @return number of data received
+ * @throws IOException
+ * upon an read error or timeout
+ */
+ public int receiveDatagram(FileDescriptor fd, DatagramPacket packet,
+ byte[] data, int offset, int length, int receiveTimeout,
+ boolean peek) throws IOException {
+ return receiveDatagramImpl(fd, packet, data, offset, length,
+ receiveTimeout, peek);
+ }
+
+ static native int receiveDatagramImpl(FileDescriptor aFD,
+ DatagramPacket packet, byte[] data, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ public int receiveDatagramDirect(FileDescriptor fd,
+ DatagramPacket packet, int address, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException {
+ return receiveDatagramDirectImpl(fd, packet, address, offset, length,
+ receiveTimeout, peek);
+ }
+
+ static native int receiveDatagramDirectImpl(FileDescriptor aFD,
+ DatagramPacket packet, int address, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ /**
+ * Receive at most <code>count</code> bytes into the buffer
+ * <code>data</code> at the <code>offset</code> on the socket.
+ *
+ * @param aFD
+ * the socket FileDescriptor
+ * @param data
+ * the receive buffer
+ * @param offset
+ * the offset into the buffer
+ * @param count
+ * the max number of bytes to receive
+ * @param timeout
+ * the max time the read operation should block waiting for data
+ * @return the actual number of bytes read
+ * @throws IOException
+ * @throws SocketException
+ * if an error occurs while reading
+ * @deprecated use {@link #read(FileDescriptor, byte[], int, int, int)}
+ */
+ public int receiveStream(FileDescriptor aFD, byte[] data,
+ int offset, int count, int timeout) throws IOException {
+ return receiveStreamImpl(aFD, data, offset, count, timeout);
+ }
+
+ static native int receiveStreamImpl(FileDescriptor aFD, byte[] data,
+ int offset, int count, int timeout) throws IOException;
+
+ // BEGIN android-added
+ /**
+ * Send <code>count</code> bytes from the buffer <code>data</code> at
+ * the <code>offset</code>, on the socket.
+ *
+ * @param fd
+ *
+ * @param data the send buffer @param offset the offset into the buffer
+ * @param count the number of bytes to receive @return int the actual number
+ * of bytes sent @throws IOException @exception SocketException if an error
+ * occurs while writing
+ */
+ public int sendStream(FileDescriptor fd, byte[] data, int offset, int count)
+ throws IOException {
+ return sendStreamImpl(fd, data, offset, count);
+ }
+
+ static native int sendStreamImpl(FileDescriptor fd, byte[] data,
+ int offset, int count) throws IOException;
+ // END android-added
+
+ /**
+ * Recieve data on the connected socket into the specified buffer. The
+ * packet fields <code>data</code> and <code>length</code> are passed in
+ * addition to <code>packet</code> to eliminate the JNI field access calls.
+ *
+ * @param fd
+ * the socket FileDescriptor
+ * @param packet
+ * the DatagramPacket to receive into
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param receiveTimeout
+ * the maximum length of time the socket should block, reading
+ * @param peek
+ * indicates to peek at the data
+ * @return number of data received
+ * @throws IOException
+ * upon an read error or timeout
+ */
+ public int recvConnectedDatagram(FileDescriptor fd,
+ DatagramPacket packet, byte[] data, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException {
+ return recvConnectedDatagramImpl(fd, packet, data, offset, length,
+ receiveTimeout, peek);
+ }
+
+ static native int recvConnectedDatagramImpl(FileDescriptor aFD,
+ DatagramPacket packet, byte[] data, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
+ int offset, int length, int receiveTimeout, boolean peek)
+ throws IOException {
+ return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
+ }
+
+ static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
+ DatagramPacket packet, int address, int offset, int length,
+ int receiveTimeout, boolean peek) throws IOException;
+
+ /**
+ * Select the given file descriptors for read and write operations.
+ *
+ * The file descriptors passed in as readFDs will be selected for read-ready
+ * operations, and those in the writeFDs will be selected for write-ready
+ * operations. A file descriptor can appear in either or both array, and
+ * must not be <code>null</code>. If the file descriptor is closed during
+ * the select the behavior depends upon the underlying OS.
+ *
+ * Upon return the result is a single array of length
+ * <code>readFDs.length</code> + <code>writeFDs.length</code> laid out as
+ * the result of the select operation on the corresponding file descriptors.
+ *
+ * @param readFDs
+ * all sockets interested in read and accept
+ * @param writeFDs
+ * all sockets interested in write and connect
+ * @param timeout
+ * timeout in milliseconds
+ * @returns each element describes the corresponding state of the descriptor
+ * in the read and write arrays.
+ * @throws SocketException
+ */
+ public int[] select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
+ long timeout) throws SocketException {
int countRead = readFDs.length;
int countWrite = writeFDs.length;
int result = 0;
@@ -310,6 +560,8 @@
}
int[] flags = new int[countRead + countWrite];
+ assert validateFDs(readFDs, writeFDs) : "Invalid file descriptor arrays"; //$NON-NLS-1$
+
// handle timeout in native
result = selectImpl(readFDs, writeFDs, countRead, countWrite, flags,
timeout);
@@ -317,430 +569,245 @@
if (0 <= result) {
return flags;
}
- if (ERRORCODE_SOCKET_TIMEOUT == result) {
+ if (ERRORCODE_SOCKET_TIMEOUT == result ||
+ ERRORCODE_SOCKET_INTERRUPTED == result) {
return new int[0];
}
throw new SocketException();
-
}
- public InetAddress getSocketLocalAddress(FileDescriptor aFD,
- boolean preferIPv6Addresses) {
- return getSocketLocalAddressImpl(aFD, preferIPv6Addresses);
- }
-
- /*
- * Query the IP stack for the local port to which this socket is bound.
- *
- * @param aFD the socket descriptor @param preferIPv6Addresses address
- * preference for nodes that support both IPv4 and IPv6 @return int the
- * local port to which the socket is bound
- */
- public int getSocketLocalPort(FileDescriptor aFD,
- boolean preferIPv6Addresses) {
- return getSocketLocalPortImpl(aFD, preferIPv6Addresses);
- }
-
- /*
- * Query the IP stack for the nominated socket option.
- *
- * @param aFD the socket descriptor @param opt the socket option type
- * @return the nominated socket option value
- *
- * @throws SocketException if the option is invalid
- */
- public Object getSocketOption(FileDescriptor aFD, int opt)
- throws SocketException {
- return getSocketOptionImpl(aFD, opt);
- }
-
- /*
- * Set the nominated socket option in the IP stack.
- *
- * @param aFD the socket descriptor @param opt the option selector @param
- * optVal the nominated option value
- *
- * @throws SocketException if the option is invalid or cannot be set
- */
- public void setSocketOption(FileDescriptor aFD, int opt, Object optVal)
- throws SocketException {
- setSocketOptionImpl(aFD, opt, optVal);
- }
-
- public int getSocketFlags() {
- return getSocketFlagsImpl();
- }
-
- /*
- * Close the socket in the IP stack.
- *
- * @param aFD the socket descriptor
- */
- public void socketClose(FileDescriptor aFD) throws IOException {
- socketCloseImpl(aFD);
- }
-
- public InetAddress getHostByAddr(byte[] addr) throws UnknownHostException {
- return getHostByAddrImpl(addr);
- }
-
- public InetAddress getHostByName(String addr, boolean preferIPv6Addresses)
- throws UnknownHostException {
- return getHostByNameImpl(addr, preferIPv6Addresses);
- }
-
- public void setInetAddress(InetAddress sender, byte[] address) {
- setInetAddressImpl(sender, address);
- }
-
- // ---------------------------------------------------
- // Native Codes
- // ---------------------------------------------------
-
- static native void createSocketImpl(FileDescriptor fd,
- boolean preferIPv4Stack);
-
- /*
- * Allocate a datagram socket in the IP stack. The socket is associated with
- * the <code>aFD</code>.
- *
- * @param aFD the FileDescriptor to associate with the socket @param
- * preferIPv4Stack IP stack preference if underlying platform is V4/V6
- * @exception SocketException upon an allocation error
- */
- static native void createDatagramSocketImpl(FileDescriptor aFD,
- boolean preferIPv4Stack) throws SocketException;
-
- static native int readSocketImpl(FileDescriptor aFD, byte[] data,
- int offset, int count, int timeout) throws IOException;
-
- static native int readSocketDirectImpl(FileDescriptor aFD, int address,
- int offset, int count, int timeout) throws IOException;
-
- static native int writeSocketImpl(FileDescriptor fd, byte[] data,
- int offset, int count) throws IOException;
-
- static native int writeSocketDirectImpl(FileDescriptor fd, int address,
- int offset, int count) throws IOException;
-
- static native void setNonBlockingImpl(FileDescriptor aFD,
- boolean block);
-
- static native int connectSocketImpl(FileDescriptor aFD,
- int trafficClass, InetAddress inetAddress, int port);
-
- // BEGIN android-changed
- static native int connectWithTimeoutSocketImpl(
- FileDescriptor aFD, int timeout, int trafficClass,
- InetAddress hostname, int port, int step, byte[] context);
- // END android-changed
-
- static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
- int aport, int timeout, int trafficClass, InetAddress inetAddress)
- throws IOException;
-
- static native void socketBindImpl(FileDescriptor aFD, int port,
- InetAddress inetAddress) throws SocketException;
-
- static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
- throws SocketException;
-
- static native int availableStreamImpl(FileDescriptor aFD)
- throws SocketException;
-
- static native void acceptSocketImpl(FileDescriptor fdServer,
- SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
- throws IOException;
-
- static native boolean supportsUrgentDataImpl(FileDescriptor fd);
-
- static native void sendUrgentDataImpl(FileDescriptor fd, byte value);
-
- /*
- * Connect the socket to a port and address
- *
- * @param aFD the FileDescriptor to associate with the socket @param port
- * the port to connect to @param trafficClass the traffic Class to be used
- * then the connection is made @param inetAddress address to connect to.
- *
- * @exception SocketException if the connect fails
- */
- static native void connectDatagramImpl2(FileDescriptor aFD,
- int port, int trafficClass, InetAddress inetAddress)
- throws SocketException;
-
- /*
- * Disconnect the socket to a port and address
- *
- * @param aFD the FileDescriptor to associate with the socket
- *
- * @exception SocketException if the disconnect fails
- */
- static native void disconnectDatagramImpl(FileDescriptor aFD)
- throws SocketException;
-
- /*
- * Allocate a datagram socket in the IP stack. The socket is associated with
- * the <code>aFD</code>.
- *
- * @param aFD the FileDescriptor to associate with the socket @param
- * preferIPv4Stack IP stack preference if underlying platform is V4/V6
- * @exception SocketException upon an allocation error
- */
-
- /*
- * Bind the socket to the port/localhost in the IP stack.
- *
- * @param aFD the socket descriptor @param port the option selector @param
- * bindToDevice bind the socket to the specified interface @param
- * inetAddress address to connect to. @return if bind successful @exception
- * SocketException thrown if bind operation fails
- */
- static native boolean socketBindImpl2(FileDescriptor aFD,
- int port, boolean bindToDevice, InetAddress inetAddress)
- throws SocketException;
-
- /*
- * Peek on the socket, update <code>sender</code> address and answer the
- * sender port.
- *
- * @param aFD the socket FileDescriptor @param sender an InetAddress, to be
- * updated with the sender's address @param receiveTimeout the maximum
- * length of time the socket should block, reading @return int the sender
- * port
- *
- * @exception IOException upon an read error or timeout
- */
- static native int peekDatagramImpl(FileDescriptor aFD,
- InetAddress sender, int receiveTimeout) throws IOException;
-
- /*
- * Recieve data on the socket into the specified buffer. The packet fields
- * <code>data</code> & <code>length</code> are passed in addition to
- * <code>packet</code> to eliminate the JNI field access calls.
- *
- * @param aFD the socket FileDescriptor @param packet the DatagramPacket to
- * receive into @param data the data buffer of the packet @param offset the
- * offset in the data buffer @param length the length of the data buffer in
- * the packet @param receiveTimeout the maximum length of time the socket
- * should block, reading @param peek indicates to peek at the data @return
- * number of data received @exception IOException upon an read error or
- * timeout
- */
- static native int receiveDatagramImpl(FileDescriptor aFD,
- DatagramPacket packet, byte[] data, int offset, int length,
- int receiveTimeout, boolean peek) throws IOException;
-
- static native int receiveDatagramDirectImpl(FileDescriptor aFD,
- DatagramPacket packet, int address, int offset, int length,
- int receiveTimeout, boolean peek) throws IOException;
-
- /*
- * Recieve data on the connected socket into the specified buffer. The
- * packet fields <code>data</code> & <code>length</code> are passed in
- * addition to <code>packet</code> to eliminate the JNI field access
- * calls.
- *
- * @param aFD the socket FileDescriptor @param packet the DatagramPacket to
- * receive into @param data the data buffer of the packet @param offset the
- * offset in the data buffer @param length the length of the data buffer in
- * the packet @param receiveTimeout the maximum length of time the socket
- * should block, reading @param peek indicates to peek at the data @return
- * number of data received @exception IOException upon an read error or
- * timeout
- */
- static native int recvConnectedDatagramImpl(FileDescriptor aFD,
- DatagramPacket packet, byte[] data, int offset, int length,
- int receiveTimeout, boolean peek) throws IOException;
-
- static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
- DatagramPacket packet, int address, int offset, int length,
- int receiveTimeout, boolean peek) throws IOException;
-
- /*
- * Send the <code>data</code> to the nominated target <code>address</code>
- * and <code>port</code>. These values are derived from the
- * DatagramPacket to reduce the field calls within JNI.
- *
- * @param fd the socket FileDescriptor @param data the data buffer of the
- * packet @param offset the offset in the data buffer @param length the
- * length of the data buffer in the packet @param port the target host port
- * @param bindToDevice if bind to device @param trafficClass the traffic
- * class to be used when the datagram is sent @param inetAddress address to
- * connect to. @return number of data send
- *
- * @exception IOException upon an read error or timeout
- */
- static native int sendDatagramImpl(FileDescriptor fd,
- byte[] data, int offset, int length, int port,
- boolean bindToDevice, int trafficClass, InetAddress inetAddress)
- throws IOException;
-
- static native int sendDatagramDirectImpl(FileDescriptor fd,
- int address, int offset, int length, int port,
- boolean bindToDevice, int trafficClass, InetAddress inetAddress)
- throws IOException;
-
- /*
- * Send the <code>data</code> to the address and port to which the was
- * connnected and <code>port</code>.
- *
- * @param fd the socket FileDescriptor @param data the data buffer of the
- * packet @param offset the offset in the data buffer @param length the
- * length of the data buffer in the packet @param bindToDevice not used,
- * current kept in case needed as was the case for sendDatagramImpl @return
- * number of data send @exception IOException upon an read error or timeout
- */
- static native int sendConnectedDatagramImpl(FileDescriptor fd,
- byte[] data, int offset, int length, boolean bindToDevice)
- throws IOException;
-
- static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
- int address, int offset, int length, boolean bindToDevice)
- throws IOException;
-
- /*
- * Answer the result of attempting to create a server stream socket in the
- * IP stack. Any special options required for server sockets will be set by
- * this method.
- *
- * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
- * @exception SocketException if an error occurs while creating the socket
- */
- static native void createServerStreamSocketImpl(FileDescriptor aFD,
- boolean preferIPv4Stack) throws SocketException;
-
- /*
- * Answer the result of attempting to create a multicast socket in the IP
- * stack. Any special options required for server sockets will be set by
- * this method.
- *
- * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
- * @exception SocketException if an error occurs while creating the socket
- */
- static native void createMulticastSocketImpl(FileDescriptor aFD,
- boolean preferIPv4Stack) throws SocketException;
-
- /*
- * Recieve at most <code>count</code> bytes into the buffer <code>data</code>
- * at the <code>offset</code> on the socket.
- *
- * @param aFD the socket FileDescriptor @param data the receive buffer
- * @param offset the offset into the buffer @param count the max number of
- * bytes to receive @param timeout the max time the read operation should
- * block waiting for data @return int the actual number of bytes read
- * @throws IOException @exception SocketException if an error occurs while
- * reading
- */
- static native int receiveStreamImpl(FileDescriptor aFD, byte[] data,
- int offset, int count, int timeout) throws IOException;
-
- /*
- * Send <code>count</code> bytes from the buffer <code>data</code> at
- * the <code>offset</code>, on the socket.
- *
- * @param fd
- *
- * @param data the send buffer @param offset the offset into the buffer
- * @param count the number of bytes to receive @return int the actual number
- * of bytes sent @throws IOException @exception SocketException if an error
- * occurs while writing
- */
- static native int sendStreamImpl(FileDescriptor fd, byte[] data,
- int offset, int count) throws IOException;
-
- private native void shutdownInputImpl(FileDescriptor descriptor)
- throws IOException;
-
- private native void shutdownOutputImpl(FileDescriptor descriptor)
- throws IOException;
-
- // BEGIN android-removed
- // static native void acceptStreamSocketImpl(FileDescriptor fdServer,
- // SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
- // throws IOException;
- //
- // static native void createStreamSocketImpl(FileDescriptor aFD,
- // boolean preferIPv4Stack) throws SocketException;
- // END android-removed
-
- static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
- int offset, int length, int port, InetAddress inetAddress)
- throws IOException;
-
static native int selectImpl(FileDescriptor[] readfd,
FileDescriptor[] writefd, int cread, int cwirte, int[] flags,
long timeout);
- static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD,
- boolean preferIPv6Addresses);
-
- /*
- * Query the IP stack for the local port to which this socket is bound.
- *
- * @param aFD the socket descriptor @param preferIPv6Addresses address
- * preference for nodes that support both IPv4 and IPv6 @return int the
- * local port to which the socket is bound
+ /**
+ * Send the <code>data</code> to the address and port to which the was
+ * connected and <code>port</code>.
+ *
+ * @param fd
+ * the socket FileDescriptor
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param bindToDevice
+ * not used, current kept in case needed as was the case for
+ * sendDatagramImpl
+ * @return number of data send
+ * @throws IOException
+ * upon an read error or timeout
*/
- static native int getSocketLocalPortImpl(FileDescriptor aFD,
- boolean preferIPv6Addresses);
+ public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
+ int offset, int length, boolean bindToDevice) throws IOException {
+ return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
+ }
- /*
- * Query the IP stack for the nominated socket option.
- *
- * @param aFD the socket descriptor @param opt the socket option type
- * @return the nominated socket option value
- *
- * @throws SocketException if the option is invalid
+ static native int sendConnectedDatagramImpl(FileDescriptor fd,
+ byte[] data, int offset, int length, boolean bindToDevice)
+ throws IOException;
+
+ public int sendConnectedDatagramDirect(FileDescriptor fd,
+ int address, int offset, int length, boolean bindToDevice)
+ throws IOException {
+ return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
+ }
+ static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
+ int address, int offset, int length, boolean bindToDevice)
+ throws IOException;
+
+ /**
+ * Send the <code>data</code> to the nominated target <code>address</code>
+ * and <code>port</code>. These values are derived from the DatagramPacket
+ * to reduce the field calls within JNI.
+ *
+ * @param fd
+ * the socket FileDescriptor
+ * @param data
+ * the data buffer of the packet
+ * @param offset
+ * the offset in the data buffer
+ * @param length
+ * the length of the data buffer in the packet
+ * @param port
+ * the target host port
+ * @param bindToDevice
+ * if bind to device
+ * @param trafficClass
+ * the traffic class to be used when the datagram is sent
+ * @param inetAddress
+ * address to connect to.
+ * @return number of data send
+ *
+ * @throws IOException
+ * upon an read error or timeout
*/
- static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
- throws SocketException;
+ public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
+ int length, int port, boolean bindToDevice, int trafficClass,
+ InetAddress inetAddress) throws IOException {
+ return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
+ trafficClass, inetAddress);
+ }
- /*
- * Set the nominated socket option in the IP stack.
- *
- * @param aFD the socket descriptor @param opt the option selector @param
- * optVal the nominated option value
- *
- * @throws SocketException if the option is invalid or cannot be set
- */
- static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
- Object optVal) throws SocketException;
+ static native int sendDatagramImpl(FileDescriptor fd, byte[] data, int offset,
+ int length, int port, boolean bindToDevice, int trafficClass,
+ InetAddress inetAddress) throws IOException;
- static native int getSocketFlagsImpl();
+ public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
+ int length, int port, InetAddress inetAddress) throws IOException {
+ return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
+ }
- /*
- * Close the socket in the IP stack.
- *
- * @param aFD the socket descriptor
- */
- static native void socketCloseImpl(FileDescriptor aFD);
+ static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
+ int offset, int length, int port, InetAddress inetAddress) throws IOException;
- static native InetAddress getHostByAddrImpl(byte[] addr)
- throws UnknownHostException;
- static native InetAddress getHostByNameImpl(String addr,
- boolean preferIPv6Addresses) throws UnknownHostException;
+ public int sendDatagramDirect(FileDescriptor fd, int address,
+ int offset, int length, int port, boolean bindToDevice,
+ int trafficClass, InetAddress inetAddress) throws IOException {
+ return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
+ trafficClass, inetAddress);
+ }
+
+ static native int sendDatagramDirectImpl(FileDescriptor fd, int address,
+ int offset, int length, int port, boolean bindToDevice,
+ int trafficClass, InetAddress inetAddress) throws IOException;
+
+ public void sendUrgentData(FileDescriptor fd, byte value) {
+ sendUrgentDataImpl(fd, value);
+ }
+
+ static native void sendUrgentDataImpl(FileDescriptor fd, byte value);
+
+ public void setInetAddress(InetAddress sender, byte[] address) {
+ setInetAddressImpl(sender, address);
+ }
native void setInetAddressImpl(InetAddress sender, byte[] address);
- // BEGIN android-removed
- // native int isReachableByICMPImpl(InetAddress addr, InetAddress local,
- // int ttl, int timeout);
- // END android-removed
-
- native Channel inheritedChannelImpl();
+ public void setNonBlocking(FileDescriptor fd, boolean block)
+ throws IOException {
+ setNonBlockingImpl(fd, block);
+ }
- public Channel inheritedChannel() {
- return inheritedChannelImpl();
+ static native void setNonBlockingImpl(FileDescriptor aFD, boolean block);
+
+ /**
+ * Set the nominated socket option in the IP stack.
+ *
+ * @param aFD
+ * the socket descriptor @param opt the option selector @param
+ * optVal the nominated option value
+ *
+ * @throws SocketException
+ * if the option is invalid or cannot be set
+ */
+ public void setSocketOption(FileDescriptor aFD, int opt,
+ Object optVal) throws SocketException {
+ setSocketOptionImpl(aFD, opt, optVal);
}
-
- public void oneTimeInitialization(boolean jcl_supports_ipv6){
- if (!isNetworkInited){
- oneTimeInitializationImpl(jcl_supports_ipv6);
- isNetworkInited = true;
- }
+
+ static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
+ Object optVal) throws SocketException;
+
+ public void shutdownInput(FileDescriptor descriptor) throws IOException {
+ shutdownInputImpl(descriptor);
}
-
- native void oneTimeInitializationImpl (boolean jcl_supports_ipv6);
+
+ private native void shutdownInputImpl(FileDescriptor descriptor)
+ throws IOException;
+
+ public void shutdownOutput(FileDescriptor fd) throws IOException {
+ shutdownOutputImpl(fd);
+ }
+
+ private native void shutdownOutputImpl(FileDescriptor descriptor)
+ throws IOException;
+ /**
+ * Close the socket in the IP stack.
+ *
+ * @param fd
+ * the socket descriptor
+ */
+ public void socketClose(FileDescriptor fd) throws IOException {
+ socketCloseImpl(fd);
+ }
+
+ static native void socketCloseImpl(FileDescriptor fD);
+
+ public boolean supportsUrgentData(FileDescriptor fd) {
+ return supportsUrgentDataImpl(fd);
+ }
+
+ static native boolean supportsUrgentDataImpl(FileDescriptor fd);
+
+ /*
+ * Used to check if the file descriptor arrays are valid before passing them
+ * into the select native call.
+ */
+ private boolean validateFDs(FileDescriptor[] readFDs,
+ FileDescriptor[] writeFDs) {
+ for (FileDescriptor fd : readFDs) {
+ // Also checks fd not null
+ if (!fd.valid()) {
+ return false;
+ }
+ }
+ for (FileDescriptor fd : writeFDs) {
+ if (!fd.valid()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Write bytes from a byte array to a socket.
+ *
+ * @param fd
+ * the socket on which to write the bytes
+ * @param data
+ * the array containing the bytes to be written
+ * @param offset
+ * the offset in the byte array from which to take the bytes
+ * @param count
+ * the maximum number of bytes to be written. Callers are trusted
+ * not to send values of length+count that are larger than
+ * data.length
+ * @return the actual number of bytes written, which will be between zero
+ * and count
+ * @throws IOException
+ * if there is an underlying socket problem
+ */
+ public int write(FileDescriptor fd, byte[] data, int offset, int count)
+ throws IOException {
+ return writeSocketImpl(fd, data, offset, count);
+ }
+
+ static native int writeSocketImpl(FileDescriptor fd, byte[] data, int offset,
+ int count) throws IOException;
+
+
+ /**
+ * Write bytes from the given address to a socket.
+ *
+ * @param fd
+ * the socket on which to write the bytes
+ * @param address
+ * the start address of the bytes to be written
+ * @param count
+ * the maximum number of bytes to be written
+ * @return the actual number of bytes written, which will be between zero
+ * and count
+ * @throws IOException
+ * if there is an underlying socket problem
+ */
+ public int writeDirect(FileDescriptor fd, int address, int offset, int count)
+ throws IOException {
+ return writeSocketDirectImpl(fd, address, offset, count);
+ }
+
+ static native int writeSocketDirectImpl(FileDescriptor fd, int address, int offset, int count)
+ throws IOException;
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/Platform.java b/luni/src/main/java/org/apache/harmony/luni/platform/Platform.java
index 68d2515..ab71a00 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/Platform.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/Platform.java
@@ -21,25 +21,33 @@
// END android-changed
/**
- * Platform
- *
+ * The Platform class gives access to the low-level underlying capabilities of
+ * the operating system.
+ *
+ * The platform is structured into operations on the process heap memory,
+ * network subsystem, and file system through different OS components.
+ *
+ * OS components are 'dangerous' in that they pass through the calls and
+ * arguments to the OS with very little checking, and as such may cause fatal
+ * exceptions in the runtime. Access to the OS components is restricted to
+ * trusted code running on the system classpath.
+ *
+ * @see IFileSystem
+ * @see INetworkSystem
+ * @see IMemorySystem
*/
public class Platform {
- static final IAdapterManager ADAPTER_MANAGER = new AdapterManager();
+ static final IFileSystem FILE_SYSTEM = OSFileSystem.getOSFileSystem();
- static final IFileSystem FILE_SYSTEM = OSComponentFactory.getFileSystem();
+ static final IMemorySystem MEMORY_SYSTEM = OSMemory.getOSMemory();
- static final IMemorySystem MEMORY_SYSTEM = OSComponentFactory
- .getMemorySystem();
+ static final INetworkSystem NETWORK_SYSTEM = OSNetworkSystem.getOSNetworkSystem();
- static final INetworkSystem NETWORK_SYSTEM = OSComponentFactory
- .getNetworkSystem();
-
- public static IAdapterManager getAdapterManager() {
- return ADAPTER_MANAGER;
- }
-
+ /**
+ * Checks to ensure that whoever is asking for the OS component is running
+ * on the system classpath.
+ */
private static final void accessCheck() {
// BEGIN android-changed
if (VMStack.getCallingClassLoader() != null) {
@@ -48,16 +56,31 @@
// END android-changed
}
+ /**
+ * Answers the instance that interacts directly with the OS file system.
+ *
+ * @return a low-level file system interface.
+ */
public static IFileSystem getFileSystem() {
accessCheck();
return FILE_SYSTEM;
}
+ /**
+ * Answers the instance that interacts directly with the OS memory system.
+ *
+ * @return a low-level memory system interface.
+ */
public static IMemorySystem getMemorySystem() {
accessCheck();
return MEMORY_SYSTEM;
}
+ /**
+ * Answers the instance that interacts directly with the OS network system.
+ *
+ * @return a low-level network system interface.
+ */
public static INetworkSystem getNetworkSystem() {
accessCheck();
return NETWORK_SYSTEM;
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/RuntimeMemorySpy.java b/luni/src/main/java/org/apache/harmony/luni/platform/RuntimeMemorySpy.java
index e897506..3692819 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/RuntimeMemorySpy.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/RuntimeMemorySpy.java
@@ -20,17 +20,18 @@
final class RuntimeMemorySpy extends AbstractMemorySpy {
- public RuntimeMemorySpy() {
- super();
- }
+ public RuntimeMemorySpy() {
+ super();
+ }
- public void alloc(PlatformAddress address) {
+ public void alloc(PlatformAddress address) {
+ // Pay a tax on the allocation to see if there are any frees pending.
+ Reference ref = notifyQueue.poll(); // non-blocking check
+ while (ref != null) {
+ orphanedMemory(ref);
+ ref = notifyQueue.poll();
+ }
+
super.alloc(address);
- // Pay a tax on the allocation to see if there are any frees pending.
- Reference ref = notifyQueue.poll(); // non-blocking check
- while (ref != null) {
- orphanedMemory(ref);
- ref = notifyQueue.poll();
- }
- }
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/DeleteOnExit.java b/luni/src/main/java/org/apache/harmony/luni/util/DeleteOnExit.java
new file mode 100644
index 0000000..ac3275e
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/luni/util/DeleteOnExit.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.luni.util;
+
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+
+// BEGIN android-changed
+/**
+ * Implements the actual DeleteOnExit mechanism. Is registered as a shutdown
+ * hook in the Runtime, once it is actually being used.
+ */
+public class DeleteOnExit extends Thread {
+
+ /**
+ * Our singleton instance.
+ */
+ private static DeleteOnExit instance;
+
+ /**
+ * Our list of files scheduled for deletion.
+ */
+ private ArrayList<String> files = new ArrayList<String>();
+
+ /**
+ * Returns our singleton instance, creating it if necessary.
+ */
+ public static synchronized DeleteOnExit getInstance() {
+ if (instance == null) {
+ instance = new DeleteOnExit();
+ Runtime.getRuntime().addShutdownHook(instance);
+ }
+
+ return instance;
+ }
+
+ /**
+ * Schedules a file for deletion.
+ *
+ * @param filename The file to delete.
+ */
+ public void addFile(String filename) {
+ synchronized(files) {
+ if (!files.contains(filename)) {
+ files.add(filename);
+ }
+ }
+ }
+
+ /**
+ * Does the actual work. Note we (a) first sort the files lexicographically
+ * and then (b) delete them in reverse order. This is to make sure files
+ * get deleted before their parent directories.
+ */
+ @Override
+ public void run() {
+ Collections.sort(files);
+ for (int i = files.size() - 1; i >= 0; i--) {
+ new File(files.get(i)).delete();
+ }
+ }
+}
+// END android-changed
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/ExposedByteArrayInputStream.java b/luni/src/main/java/org/apache/harmony/luni/util/ExposedByteArrayInputStream.java
new file mode 100644
index 0000000..0ff073c
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/luni/util/ExposedByteArrayInputStream.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.harmony.luni.util;
+
+import java.io.ByteArrayInputStream;
+
+/**
+ * The extension of <code>ByteArrayInputStream</code> which exposes an
+ * underlying buffer.
+ */
+public class ExposedByteArrayInputStream extends ByteArrayInputStream {
+
+ /**
+ * @see java.io.ByteArrayInputStream(byte[])
+ */
+ public ExposedByteArrayInputStream(byte buf[]) {
+ super(buf);
+ }
+
+ /**
+ * @see java.io.ByteArrayInputStream(byte[], int, int)
+ */
+ public ExposedByteArrayInputStream(byte buf[], int offset, int length) {
+ super(buf, offset, length);
+ }
+
+ /**
+ * Reads the whole stream and returns the stream snapshot.
+ */
+ public synchronized byte[] expose() {
+ if (pos == 0 && count == buf.length) {
+ skip(count);
+ return buf;
+ }
+
+ final int available = available();
+ final byte[] buffer = new byte[available];
+ System.arraycopy(buf, pos, buffer, 0, available);
+ skip(available);
+ return buffer;
+ }
+}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
index bc1688f..c740ae9 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
+++ b/luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties
@@ -61,8 +61,8 @@
K0046=Local port declared out of range
K0047=buffer is null
K0048=Invalid action specified\: {0}
-K0049=MinPort is greater than MaxPort
-K004a=Invalid port number specified
+K0049=MinPort is greater than MaxPort\: {0}
+K004a=Invalid port number specified\: {0}
K004b=Attempt to set factory more than once.
K004c=Package is sealed
K004d=Does not support writing to the input stream
@@ -288,6 +288,7 @@
K034d=method has not been implemented yet
K034e=Build rules empty
K0351=format is null
+K0352=package is sealed
KA000=Line too long
KA001=Argument must not be null
KA002=Unshared read of back reference
@@ -322,3 +323,5 @@
KA025=Method has not been implemented
KA026=JAR entry {0} not found in {1}
KA027=Inputstream of the JarURLConnection has been closed
+KA028=Cannot set protocol version when stream in use
+KA029=Can't find resource for bundle {0}, key {1}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java b/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java
index 820de0f..642d309 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java
@@ -17,8 +17,6 @@
package org.apache.harmony.luni.util;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* Used to parse a string and return either a single or double precision
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/HexStringParser.java b/luni/src/main/java/org/apache/harmony/luni/util/HexStringParser.java
index 93bd9da..8072165 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/HexStringParser.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/HexStringParser.java
@@ -304,13 +304,13 @@
private int getOffset(String strIntegerPart, String strDecimalPart) {
strIntegerPart = strIntegerPart.replaceFirst("^0+", ""); //$NON-NLS-1$ //$NON-NLS-2$
- //If the Interger part is a nonzero number.
+ //If the Integer part is a nonzero number.
if (strIntegerPart.length() != 0) {
String leadingNumber = strIntegerPart.substring(0, 1);
return (strIntegerPart.length() - 1) * 4 + countBitsLength(Long.parseLong(leadingNumber,HEX_RADIX)) - 1;
}
- //If the Interger part is a zero number.
+ //If the Integer part is a zero number.
int i;
for (i = 0; i < strDecimalPart.length() && strDecimalPart.charAt(i) == '0'; i++);
if (i == strDecimalPart.length()) {
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/HistoricalNamesUtil.java b/luni/src/main/java/org/apache/harmony/luni/util/HistoricalNamesUtil.java
new file mode 100644
index 0000000..f32f976
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/luni/util/HistoricalNamesUtil.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.luni.util;
+
+import java.util.HashMap;
+
+public class HistoricalNamesUtil {
+ private static HashMap<String, String> historicalNames = new HashMap<String, String>();
+
+ static {
+ historicalNames.put("Big5-HKSCS", "Big5_HKSCS");
+ historicalNames.put("EUC-JP", "EUC_JP");
+ historicalNames.put("EUC-KR", "EUC_KR");
+ historicalNames.put("GB2312", "EUC_CN");
+ historicalNames.put("IBM-Thai", "Cp838");
+ historicalNames.put("IBM00858", "Cp858");
+ historicalNames.put("IBM01140", "Cp1140");
+ historicalNames.put("IBM01141", "Cp1141");
+ historicalNames.put("IBM01142", "Cp1142");
+ historicalNames.put("IBM01143", "Cp1143");
+ historicalNames.put("IBM01144", "Cp1144");
+ historicalNames.put("IBM01145", "Cp1145");
+ historicalNames.put("IBM01146", "Cp1146");
+ historicalNames.put("IBM01147", "Cp1147");
+ historicalNames.put("IBM01148", "Cp1148");
+ historicalNames.put("IBM01149", "Cp1149");
+ historicalNames.put("IBM037", "Cp037");
+ historicalNames.put("IBM1026", "Cp1026");
+ historicalNames.put("IBM1047", "Cp1047");
+ historicalNames.put("IBM273", "Cp273");
+ historicalNames.put("IBM277", "Cp277");
+ historicalNames.put("IBM278", "Cp278");
+ historicalNames.put("IBM280", "Cp280");
+ historicalNames.put("IBM284", "Cp284");
+ historicalNames.put("IBM285", "Cp285");
+ historicalNames.put("IBM297", "Cp297");
+ historicalNames.put("IBM420", "Cp420");
+ historicalNames.put("IBM424", "Cp424");
+ historicalNames.put("IBM437", "Cp437");
+ historicalNames.put("IBM500", "Cp500");
+ historicalNames.put("IBM775", "Cp775");
+ historicalNames.put("IBM850", "Cp850");
+ historicalNames.put("IBM852", "Cp852");
+ historicalNames.put("IBM855", "Cp855");
+ historicalNames.put("IBM857", "Cp857");
+ historicalNames.put("IBM860", "Cp860");
+ historicalNames.put("IBM861", "Cp861");
+ historicalNames.put("IBM862", "Cp862");
+ historicalNames.put("IBM863", "Cp863");
+ historicalNames.put("IBM864", "Cp864");
+ historicalNames.put("IBM865", "Cp865");
+ historicalNames.put("IBM866", "Cp866");
+ historicalNames.put("IBM868", "Cp868");
+ historicalNames.put("IBM869", "Cp869");
+ historicalNames.put("IBM870", "Cp870");
+ historicalNames.put("IBM871", "Cp871");
+ historicalNames.put("IBM918", "Cp918");
+ historicalNames.put("ISO-2022-CN", "ISO2022CN");
+ historicalNames.put("ISO-2022-JP", "ISO2022JP");
+ historicalNames.put("ISO-2022-KR", "ISO2022KR");
+ historicalNames.put("ISO-8859-1", "ISO8859_1");
+ historicalNames.put("ISO-8859-13", "ISO8859_13");
+ historicalNames.put("ISO-8859-15", "ISO8859_15");
+ historicalNames.put("ISO-8859-2", "ISO8859_2");
+ historicalNames.put("ISO-8859-3", "ISO8859_3");
+ historicalNames.put("ISO-8859-4", "ISO8859_4");
+ historicalNames.put("ISO-8859-5", "ISO8859_5");
+ historicalNames.put("ISO-8859-6", "ISO8859_6");
+ historicalNames.put("ISO-8859-7", "ISO8859_7");
+ historicalNames.put("ISO-8859-8", "ISO8859_8");
+ historicalNames.put("ISO-8859-9", "ISO8859_9");
+ historicalNames.put("KOI8-R", "KOI8_R");
+ historicalNames.put("Shift_JIS", "SJIS");
+ historicalNames.put("TIS-620", "TIS620");
+ historicalNames.put("US-ASCII", "ASCII");
+ historicalNames.put("UTF-16BE", "UnicodeBigUnmarked");
+ historicalNames.put("UTF-16LE", "UnicodeLittleUnmarked");
+ historicalNames.put("UTF-8", "UTF8");
+ historicalNames.put("windows-1250", "Cp1250");
+ historicalNames.put("windows-1251", "Cp1251");
+ historicalNames.put("windows-1252", "Cp1252");
+ historicalNames.put("windows-1253", "Cp1253");
+ historicalNames.put("windows-1254", "Cp1254");
+ historicalNames.put("windows-1255", "Cp1255");
+ historicalNames.put("windows-1256", "Cp1256");
+ historicalNames.put("windows-1257", "Cp1257");
+ historicalNames.put("windows-1258", "Cp1258");
+ historicalNames.put("windows-31j", "MS932");
+ historicalNames.put("x-Big5-Solaris", "Big5_Solaris");
+ historicalNames.put("x-euc-jp-linux", "EUC_JP_LINUX");
+ historicalNames.put("x-EUC-TW", "EUC_TW");
+ historicalNames.put("x-eucJP-Open", "EUC_JP_Solaris");
+ historicalNames.put("x-IBM1006", "Cp1006");
+ historicalNames.put("x-IBM1025", "Cp1025");
+ historicalNames.put("x-IBM1046", "Cp1046");
+ historicalNames.put("x-IBM1097", "Cp1097");
+ historicalNames.put("x-IBM1098", "Cp1098");
+ historicalNames.put("x-IBM1112", "Cp1112");
+ historicalNames.put("x-IBM1122", "Cp1122");
+ historicalNames.put("x-IBM1123", "Cp1123");
+ historicalNames.put("x-IBM1124", "Cp1124");
+ historicalNames.put("x-IBM1381", "Cp1381");
+ historicalNames.put("x-IBM1383", "Cp1383");
+ historicalNames.put("x-IBM33722", "Cp33722");
+ historicalNames.put("x-IBM737", "Cp737");
+ historicalNames.put("x-IBM856", "Cp856");
+ historicalNames.put("x-IBM874", "Cp874");
+ historicalNames.put("x-IBM875", "Cp875");
+ historicalNames.put("x-IBM921", "Cp921");
+ historicalNames.put("x-IBM922", "Cp922");
+ historicalNames.put("x-IBM930", "Cp930");
+ historicalNames.put("x-IBM933", "Cp933");
+ historicalNames.put("x-IBM935", "Cp935");
+ historicalNames.put("x-IBM937", "Cp937");
+ historicalNames.put("x-IBM939", "Cp939");
+ historicalNames.put("x-IBM942", "Cp942");
+ historicalNames.put("x-IBM942C", "Cp942C");
+ historicalNames.put("x-IBM943", "Cp943");
+ historicalNames.put("x-IBM943C", "Cp943C");
+ historicalNames.put("x-IBM948", "Cp948");
+ historicalNames.put("x-IBM949", "Cp949");
+ historicalNames.put("x-IBM949C", "Cp949C");
+ historicalNames.put("x-IBM950", "Cp950");
+ historicalNames.put("x-IBM964", "Cp964");
+ historicalNames.put("x-IBM970", "Cp970");
+ historicalNames.put("x-ISCII91", "ISCII91");
+ historicalNames.put("x-ISO-2022-CN-CNS", "ISO2022CN");
+ historicalNames.put("x-ISO-2022-CN-GB", "ISO2022CN");
+ historicalNames.put("x-JISAutoDetect", "JISAutoDetect");
+ historicalNames.put("x-MacArabic", "MacArabic");
+ historicalNames.put("x-MacCentralEurope", "MacCentralEurope");
+ historicalNames.put("x-MacCroatian", "MacCroatian");
+ historicalNames.put("x-MacCyrillic", "MacCyrillic");
+ historicalNames.put("x-MacDingbat", "MacDingbat");
+ historicalNames.put("x-MacGreek", "MacGreek");
+ historicalNames.put("x-MacHebrew", "MacHebrew");
+ historicalNames.put("x-MacIceland", "MacIceland");
+ historicalNames.put("x-MacRoman", "MacRoman");
+ historicalNames.put("x-MacRomania", "MacRomania");
+ historicalNames.put("x-MacSymbol", "MacSymbol");
+ historicalNames.put("x-MacThai", "MacThai");
+ historicalNames.put("x-MacTurkish", "MacTurkish");
+ historicalNames.put("x-MacUkraine", "MacUkraine");
+ historicalNames.put("x-MS950-HKSCS", "MS950_HKSCS");
+ historicalNames.put("x-mswin-936", "MS936");
+ historicalNames.put("x-PCK", "PCK");
+ historicalNames.put("x-windows-874", "MS874");
+ historicalNames.put("x-windows-949", "MS949");
+ historicalNames.put("x-windows-950", "MS950");
+ }
+
+ public static String getHistoricalName(String name) {
+ return (!historicalNames.containsKey(name) ? name : historicalNames
+ .get(name));
+ }
+}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java b/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
index 8c8257b..d8b261d 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
@@ -24,28 +24,28 @@
*/
public class Inet6Util {
- /**
- * Creates an byte[] based on an ipAddressString. No error handling is
- * performed here.
- */
- public static byte[] createByteArrayFromIPAddressString(
- String ipAddressString) {
+ /**
+ * Creates an byte[] based on an ipAddressString. No error handling is
+ * performed here.
+ */
+ public static byte[] createByteArrayFromIPAddressString(
+ String ipAddressString) {
- if (isValidIPV4Address(ipAddressString)) {
+ if (isValidIPV4Address(ipAddressString)) {
StringTokenizer tokenizer = new StringTokenizer(ipAddressString, ".");
- String token = "";
- int tempInt = 0;
- byte[] byteAddress = new byte[4];
- for (int i = 0; i < 4; i++) {
- token = tokenizer.nextToken();
- tempInt = Integer.parseInt(token);
- byteAddress[i] = (byte) tempInt;
- }
+ String token = "";
+ int tempInt = 0;
+ byte[] byteAddress = new byte[4];
+ for (int i = 0; i < 4; i++) {
+ token = tokenizer.nextToken();
+ tempInt = Integer.parseInt(token);
+ byteAddress[i] = (byte) tempInt;
+ }
- return byteAddress;
- }
-
- if (ipAddressString.charAt(0) == '[') {
+ return byteAddress;
+ }
+
+ if (ipAddressString.charAt(0) == '[') {
ipAddressString = ipAddressString.substring(1, ipAddressString.length() - 1);
}
@@ -63,105 +63,105 @@
* or decimal list. In the case where we hit a :: we will save the index
* of the hexStrings so we can add zeros in to fill out the string
*/
- while (tokenizer.hasMoreTokens()) {
- prevToken = token;
- token = tokenizer.nextToken();
+ while (tokenizer.hasMoreTokens()) {
+ prevToken = token;
+ token = tokenizer.nextToken();
- if (token.equals(":")) {
- if (prevToken.equals(":")) {
- doubleColonIndex = hexStrings.size();
- } else if (!prevToken.equals("")) {
- hexStrings.add(prevToken);
- }
- } else if (token.equals(".")) {
- decStrings.add(prevToken);
- }
- }
+ if (token.equals(":")) {
+ if (prevToken.equals(":")) {
+ doubleColonIndex = hexStrings.size();
+ } else if (!prevToken.equals("")) {
+ hexStrings.add(prevToken);
+ }
+ } else if (token.equals(".")) {
+ decStrings.add(prevToken);
+ }
+ }
- if (prevToken.equals(":")) {
- if (token.equals(":")) {
- doubleColonIndex = hexStrings.size();
- } else {
- hexStrings.add(token);
- }
- } else if (prevToken.equals(".")) {
- decStrings.add(token);
- }
+ if (prevToken.equals(":")) {
+ if (token.equals(":")) {
+ doubleColonIndex = hexStrings.size();
+ } else {
+ hexStrings.add(token);
+ }
+ } else if (prevToken.equals(".")) {
+ decStrings.add(token);
+ }
- // figure out how many hexStrings we should have
- // also check if it is a IPv4 address
- int hexStringsLength = 8;
+ // figure out how many hexStrings we should have
+ // also check if it is a IPv4 address
+ int hexStringsLength = 8;
- // If we have an IPv4 address tagged on at the end, subtract
- // 4 bytes, or 2 hex words from the total
- if (decStrings.size() > 0) {
- hexStringsLength -= 2;
- }
+ // If we have an IPv4 address tagged on at the end, subtract
+ // 4 bytes, or 2 hex words from the total
+ if (decStrings.size() > 0) {
+ hexStringsLength -= 2;
+ }
- // if we hit a double Colon add the appropriate hex strings
- if (doubleColonIndex != -1) {
- int numberToInsert = hexStringsLength - hexStrings.size();
- for (int i = 0; i < numberToInsert; i++) {
- hexStrings.add(doubleColonIndex, "0");
- }
- }
+ // if we hit a double Colon add the appropriate hex strings
+ if (doubleColonIndex != -1) {
+ int numberToInsert = hexStringsLength - hexStrings.size();
+ for (int i = 0; i < numberToInsert; i++) {
+ hexStrings.add(doubleColonIndex, "0");
+ }
+ }
- byte ipByteArray[] = new byte[16];
+ byte ipByteArray[] = new byte[16];
- // Finally convert these strings to bytes...
- for (int i = 0; i < hexStrings.size(); i++) {
- convertToBytes(hexStrings.get(i), ipByteArray, i * 2);
- }
+ // Finally convert these strings to bytes...
+ for (int i = 0; i < hexStrings.size(); i++) {
+ convertToBytes(hexStrings.get(i), ipByteArray, i * 2);
+ }
- // Now if there are any decimal values, we know where they go...
- for (int i = 0; i < decStrings.size(); i++) {
+ // Now if there are any decimal values, we know where they go...
+ for (int i = 0; i < decStrings.size(); i++) {
ipByteArray[i + 12] = (byte) (Integer.parseInt(decStrings.get(i)) & 255);
}
- // now check to see if this guy is actually and IPv4 address
- // an ipV4 address is ::FFFF:d.d.d.d
- boolean ipV4 = true;
- for (int i = 0; i < 10; i++) {
- if (ipByteArray[i] != 0) {
- ipV4 = false;
- break;
- }
- }
+ // now check to see if this guy is actually and IPv4 address
+ // an ipV4 address is ::FFFF:d.d.d.d
+ boolean ipV4 = true;
+ for (int i = 0; i < 10; i++) {
+ if (ipByteArray[i] != 0) {
+ ipV4 = false;
+ break;
+ }
+ }
- if (ipByteArray[10] != -1 || ipByteArray[11] != -1) {
- ipV4 = false;
- }
+ if (ipByteArray[10] != -1 || ipByteArray[11] != -1) {
+ ipV4 = false;
+ }
- if (ipV4) {
- byte ipv4ByteArray[] = new byte[4];
- for (int i = 0; i < 4; i++) {
- ipv4ByteArray[i] = ipByteArray[i + 12];
- }
- return ipv4ByteArray;
- }
-
- return ipByteArray;
+ if (ipV4) {
+ byte ipv4ByteArray[] = new byte[4];
+ for (int i = 0; i < 4; i++) {
+ ipv4ByteArray[i] = ipByteArray[i + 12];
+ }
+ return ipv4ByteArray;
+ }
- }
+ return ipByteArray;
+
+ }
// BEGIN android-changed
static char[] hexCharacters = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f'};
// END android-changed
- public static String createIPAddrStringFromByteArray(byte ipByteArray[]) {
- if (ipByteArray.length == 4) {
- return addressToString(bytesToInt(ipByteArray, 0));
- }
+ public static String createIPAddrStringFromByteArray(byte ipByteArray[]) {
+ if (ipByteArray.length == 4) {
+ return addressToString(bytesToInt(ipByteArray, 0));
+ }
- if (ipByteArray.length == 16) {
- if (isIPv4MappedAddress(ipByteArray)) {
- byte ipv4ByteArray[] = new byte[4];
- for (int i = 0; i < 4; i++) {
- ipv4ByteArray[i] = ipByteArray[i + 12];
- }
- return addressToString(bytesToInt(ipv4ByteArray, 0));
- }
+ if (ipByteArray.length == 16) {
+ if (isIPv4MappedAddress(ipByteArray)) {
+ byte ipv4ByteArray[] = new byte[4];
+ for (int i = 0; i < 4; i++) {
+ ipv4ByteArray[i] = ipByteArray[i + 12];
+ }
+ return addressToString(bytesToInt(ipv4ByteArray, 0));
+ }
StringBuilder buffer = new StringBuilder();
// BEGIN android-changed
for (int i = 0; i < 8; i++) { // ipByteArray.length / 2
@@ -189,131 +189,129 @@
}
// END android-changed
return buffer.toString();
- }
- return null;
- }
+ }
+ return null;
+ }
- /** Converts a 4 character hex word into a 2 byte word equivalent */
- public static void convertToBytes(String hexWord, byte ipByteArray[],
- int byteIndex) {
+ /** Converts a 4 character hex word into a 2 byte word equivalent */
+ public static void convertToBytes(String hexWord, byte ipByteArray[],
+ int byteIndex) {
- int hexWordLength = hexWord.length();
- int hexWordIndex = 0;
- ipByteArray[byteIndex] = 0;
- ipByteArray[byteIndex + 1] = 0;
- int charValue;
+ int hexWordLength = hexWord.length();
+ int hexWordIndex = 0;
+ ipByteArray[byteIndex] = 0;
+ ipByteArray[byteIndex + 1] = 0;
+ int charValue;
- // high order 4 bits of first byte
- if (hexWordLength > 3) {
- charValue = getIntValue(hexWord.charAt(hexWordIndex++));
- ipByteArray[byteIndex] = (byte) (ipByteArray[byteIndex] | (charValue << 4));
- }
+ // high order 4 bits of first byte
+ if (hexWordLength > 3) {
+ charValue = getIntValue(hexWord.charAt(hexWordIndex++));
+ ipByteArray[byteIndex] = (byte) (ipByteArray[byteIndex] | (charValue << 4));
+ }
- // low order 4 bits of the first byte
- if (hexWordLength > 2) {
- charValue = getIntValue(hexWord.charAt(hexWordIndex++));
- ipByteArray[byteIndex] = (byte) (ipByteArray[byteIndex] | charValue);
- }
+ // low order 4 bits of the first byte
+ if (hexWordLength > 2) {
+ charValue = getIntValue(hexWord.charAt(hexWordIndex++));
+ ipByteArray[byteIndex] = (byte) (ipByteArray[byteIndex] | charValue);
+ }
- // high order 4 bits of second byte
- if (hexWordLength > 1) {
- charValue = getIntValue(hexWord.charAt(hexWordIndex++));
- ipByteArray[byteIndex + 1] = (byte) (ipByteArray[byteIndex + 1] | (charValue << 4));
- }
+ // high order 4 bits of second byte
+ if (hexWordLength > 1) {
+ charValue = getIntValue(hexWord.charAt(hexWordIndex++));
+ ipByteArray[byteIndex + 1] = (byte) (ipByteArray[byteIndex + 1] | (charValue << 4));
+ }
- // low order 4 bits of the first byte
- charValue = getIntValue(hexWord.charAt(hexWordIndex));
- ipByteArray[byteIndex + 1] = (byte) (ipByteArray[byteIndex + 1] | charValue & 15);
- }
+ // low order 4 bits of the first byte
+ charValue = getIntValue(hexWord.charAt(hexWordIndex));
+ ipByteArray[byteIndex + 1] = (byte) (ipByteArray[byteIndex + 1] | charValue & 15);
+ }
- static int getIntValue(char c) {
+ static int getIntValue(char c) {
- switch (c) {
- case '0':
- return 0;
- case '1':
- return 1;
- case '2':
- return 2;
- case '3':
- return 3;
- case '4':
- return 4;
- case '5':
- return 5;
- case '6':
- return 6;
- case '7':
- return 7;
- case '8':
- return 8;
- case '9':
- return 9;
- }
+ switch (c) {
+ case '0':
+ return 0;
+ case '1':
+ return 1;
+ case '2':
+ return 2;
+ case '3':
+ return 3;
+ case '4':
+ return 4;
+ case '5':
+ return 5;
+ case '6':
+ return 6;
+ case '7':
+ return 7;
+ case '8':
+ return 8;
+ case '9':
+ return 9;
+ }
- c = Character.toLowerCase(c);
- switch (c) {
- case 'a':
- return 10;
- case 'b':
- return 11;
- case 'c':
- return 12;
- case 'd':
- return 13;
- case 'e':
- return 14;
- case 'f':
- return 15;
- }
- return 0;
- }
+ c = Character.toLowerCase(c);
+ switch (c) {
+ case 'a':
+ return 10;
+ case 'b':
+ return 11;
+ case 'c':
+ return 12;
+ case 'd':
+ return 13;
+ case 'e':
+ return 14;
+ case 'f':
+ return 15;
+ }
+ return 0;
+ }
- private static boolean isIPv4MappedAddress(byte ipAddress[]) {
+ private static boolean isIPv4MappedAddress(byte ipAddress[]) {
- // Check if the address matches ::FFFF:d.d.d.d
- // The first 10 bytes are 0. The next to are -1 (FF).
- // The last 4 bytes are varied.
- for (int i = 0; i < 10; i++) {
- if (ipAddress[i] != 0) {
- return false;
- }
- }
+ // Check if the address matches ::FFFF:d.d.d.d
+ // The first 10 bytes are 0. The next to are -1 (FF).
+ // The last 4 bytes are varied.
+ for (int i = 0; i < 10; i++) {
+ if (ipAddress[i] != 0) {
+ return false;
+ }
+ }
- if (ipAddress[10] != -1 || ipAddress[11] != -1) {
- return false;
- }
+ if (ipAddress[10] != -1 || ipAddress[11] != -1) {
+ return false;
+ }
- return true;
+ return true;
- }
+ }
- /**
- * Takes the byte array and creates an integer out of four bytes starting at
- * start as the high-order byte. This method makes no checks on the validity
- * of the parameters.
- */
- public static int bytesToInt(byte bytes[], int start) {
- // First mask the byte with 255, as when a negative
- // signed byte converts to an integer, it has bits
- // on in the first 3 bytes, we are only concerned
- // about the right-most 8 bits.
- // Then shift the rightmost byte to align with its
- // position in the integer.
- int value = ((bytes[start + 3] & 255))
- | ((bytes[start + 2] & 255) << 8)
- | ((bytes[start + 1] & 255) << 16)
- | ((bytes[start] & 255) << 24);
- return value;
- }
+ /**
+ * Takes the byte array and creates an integer out of four bytes starting at
+ * start as the high-order byte. This method makes no checks on the validity
+ * of the parameters.
+ */
+ public static int bytesToInt(byte bytes[], int start) {
+ // First mask the byte with 255, as when a negative
+ // signed byte converts to an integer, it has bits
+ // on in the first 3 bytes, we are only concerned
+ // about the right-most 8 bits.
+ // Then shift the rightmost byte to align with its
+ // position in the integer.
+ int value = ((bytes[start + 3] & 255))
+ | ((bytes[start + 2] & 255) << 8)
+ | ((bytes[start + 1] & 255) << 16)
+ | ((bytes[start] & 255) << 24);
+ return value;
+ }
- public static String addressToString(int value) {
- return ((value >> 24) & 0xff) + "." + ((value >> 16) & 0xff) + "."
- + ((value >> 8) & 0xff) + "." + (value & 0xff);
- }
+ public static String addressToString(int value) {
+ return ((value >> 24) & 0xff) + "." + ((value >> 16) & 0xff) + "."
+ + ((value >> 8) & 0xff) + "." + (value & 0xff);
+ }
- // BEGIN android-added
- // copied from a newer version of harmony
public static boolean isIP6AddressInFullForm(String ipAddress) {
if (isValidIP6Address(ipAddress)) {
int doubleColonIndex = ipAddress.indexOf("::");
@@ -325,215 +323,214 @@
}
return false;
}
- // END android-added
- public static boolean isValidIP6Address(String ipAddress) {
- int length = ipAddress.length();
- boolean doubleColon = false;
- int numberOfColons = 0;
- int numberOfPeriods = 0;
- int numberOfPercent = 0;
- String word = "";
- char c = 0;
- char prevChar = 0;
- int offset = 0; // offset for [] IP addresses
+ public static boolean isValidIP6Address(String ipAddress) {
+ int length = ipAddress.length();
+ boolean doubleColon = false;
+ int numberOfColons = 0;
+ int numberOfPeriods = 0;
+ int numberOfPercent = 0;
+ String word = "";
+ char c = 0;
+ char prevChar = 0;
+ int offset = 0; // offset for [] IP addresses
- if (length < 2) {
+ if (length < 2) {
return false;
}
- for (int i = 0; i < length; i++) {
- prevChar = c;
- c = ipAddress.charAt(i);
- switch (c) {
+ for (int i = 0; i < length; i++) {
+ prevChar = c;
+ c = ipAddress.charAt(i);
+ switch (c) {
- // case for an open bracket [x:x:x:...x]
- case '[':
- if (i != 0) {
+ // case for an open bracket [x:x:x:...x]
+ case '[':
+ if (i != 0) {
return false; // must be first character
}
- if (ipAddress.charAt(length - 1) != ']') {
+ if (ipAddress.charAt(length - 1) != ']') {
return false; // must have a close ]
}
- offset = 1;
- if (length < 4) {
+ offset = 1;
+ if (length < 4) {
return false;
}
- break;
+ break;
- // case for a closed bracket at end of IP [x:x:x:...x]
- case ']':
- if (i != length - 1) {
+ // case for a closed bracket at end of IP [x:x:x:...x]
+ case ']':
+ if (i != length - 1) {
return false; // must be last character
}
- if (ipAddress.charAt(0) != '[') {
+ if (ipAddress.charAt(0) != '[') {
return false; // must have a open [
}
- break;
+ break;
- // case for the last 32-bits represented as IPv4 x:x:x:x:x:x:d.d.d.d
- case '.':
- numberOfPeriods++;
- if (numberOfPeriods > 3) {
+ // case for the last 32-bits represented as IPv4 x:x:x:x:x:x:d.d.d.d
+ case '.':
+ numberOfPeriods++;
+ if (numberOfPeriods > 3) {
return false;
}
- if (!isValidIP4Word(word)) {
+ if (!isValidIP4Word(word)) {
return false;
}
- if (numberOfColons != 6 && !doubleColon) {
+ if (numberOfColons != 6 && !doubleColon) {
return false;
}
- // a special case ::1:2:3:4:5:d.d.d.d allows 7 colons with an
- // IPv4 ending, otherwise 7 :'s is bad
- if (numberOfColons == 7 && ipAddress.charAt(0 + offset) != ':'
- && ipAddress.charAt(1 + offset) != ':') {
+ // a special case ::1:2:3:4:5:d.d.d.d allows 7 colons with an
+ // IPv4 ending, otherwise 7 :'s is bad
+ if (numberOfColons == 7 && ipAddress.charAt(0 + offset) != ':'
+ && ipAddress.charAt(1 + offset) != ':') {
return false;
}
- word = "";
- break;
+ word = "";
+ break;
- case ':':
- numberOfColons++;
- if (numberOfColons > 7) {
+ case ':':
+ numberOfColons++;
+ if (numberOfColons > 7) {
return false;
}
- if (numberOfPeriods > 0) {
+ if (numberOfPeriods > 0) {
return false;
}
- if (prevChar == ':') {
- if (doubleColon) {
+ if (prevChar == ':') {
+ if (doubleColon) {
return false;
}
- doubleColon = true;
- }
- word = "";
- break;
- case '%':
- if (numberOfColons == 0) {
+ doubleColon = true;
+ }
+ word = "";
+ break;
+ case '%':
+ if (numberOfColons == 0) {
return false;
}
- numberOfPercent++;
+ numberOfPercent++;
- // validate that the stuff after the % is valid
- if ((i + 1) >= length) {
- // in this case the percent is there but no number is
- // available
- return false;
- }
- try {
- Integer.parseInt(ipAddress.substring(i + 1));
- } catch (NumberFormatException e) {
- // right now we just support an integer after the % so if
- // this is not
- // what is there then return
- return false;
- }
- break;
+ // validate that the stuff after the % is valid
+ if ((i + 1) >= length) {
+ // in this case the percent is there but no number is
+ // available
+ return false;
+ }
+ try {
+ Integer.parseInt(ipAddress.substring(i + 1));
+ } catch (NumberFormatException e) {
+ // right now we just support an integer after the % so if
+ // this is not
+ // what is there then return
+ return false;
+ }
+ break;
- default:
- if (numberOfPercent == 0) {
- if (word.length() > 3) {
+ default:
+ if (numberOfPercent == 0) {
+ if (word.length() > 3) {
return false;
}
- if (!isValidHexChar(c)) {
+ if (!isValidHexChar(c)) {
return false;
}
- }
- word += c;
- }
- }
+ }
+ word += c;
+ }
+ }
- // Check if we have an IPv4 ending
- if (numberOfPeriods > 0) {
- if (numberOfPeriods != 3 || !isValidIP4Word(word)) {
+ // Check if we have an IPv4 ending
+ if (numberOfPeriods > 0) {
+ if (numberOfPeriods != 3 || !isValidIP4Word(word)) {
return false;
}
- } else {
- // If we're at then end and we haven't had 7 colons then there is a
- // problem unless we encountered a doubleColon
- if (numberOfColons != 7 && !doubleColon) {
+ } else {
+ // If we're at then end and we haven't had 7 colons then there is a
+ // problem unless we encountered a doubleColon
+ if (numberOfColons != 7 && !doubleColon) {
+ return false;
+ }
+
+ // If we have an empty word at the end, it means we ended in either
+ // a : or a .
+ // If we did not end in :: then this is invalid
+ if (numberOfPercent == 0) {
+ if (word == "" && ipAddress.charAt(length - 1 - offset) == ':'
+ && ipAddress.charAt(length - 2 - offset) != ':') {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isValidIP4Word(String word) {
+ char c;
+ if (word.length() < 1 || word.length() > 3) {
+ return false;
+ }
+ for (int i = 0; i < word.length(); i++) {
+ c = word.charAt(i);
+ if (!(c >= '0' && c <= '9')) {
+ return false;
+ }
+ }
+ if (Integer.parseInt(word) > 255) {
+ return false;
+ }
+ return true;
+ }
+
+ static boolean isValidHexChar(char c) {
+
+ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
+ || (c >= 'a' && c <= 'f');
+ }
+
+ /**
+ * Takes a string and parses it to see if it is a valid IPV4 address.
+ *
+ * @return true, if the string represents an IPV4 address in dotted
+ * notation, false otherwise
+ */
+ public static boolean isValidIPV4Address(String value) {
+ // BEGIN android-changed
+ // general test
+ if (!value.matches("\\p{Digit}+(\\.\\p{Digit}+)*")) {
return false;
}
- // If we have an empty word at the end, it means we ended in either
- // a : or a .
- // If we did not end in :: then this is invalid
- if (numberOfPercent == 0) {
- if (word == "" && ipAddress.charAt(length - 1 - offset) == ':'
- && ipAddress.charAt(length - 2 - offset) != ':') {
- return false;
- }
- }
- }
-
- return true;
- }
-
- public static boolean isValidIP4Word(String word) {
- char c;
- if (word.length() < 1 || word.length() > 3) {
- return false;
- }
- for (int i = 0; i < word.length(); i++) {
- c = word.charAt(i);
- if (!(c >= '0' && c <= '9')) {
+ String[] parts = value.split("\\.");
+ int length = parts.length;
+ if (length < 1 || length > 4) {
return false;
}
- }
- if (Integer.parseInt(word) > 255) {
- return false;
- }
- return true;
- }
- static boolean isValidHexChar(char c) {
-
- return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')
- || (c >= 'a' && c <= 'f');
- }
-
- /**
- * Takes a string and parses it to see if it is a valid IPV4 address.
- *
- * @return true, if the string represents an IPV4 address in dotted
- * notation, false otherwise
- */
- public static boolean isValidIPV4Address(String value) {
- // BEGIN android-changed
- // general test
- if (!value.matches("\\p{Digit}+(\\.\\p{Digit}+)*")) {
- return false;
- }
-
- String[] parts = value.split("\\.");
- int length = parts.length;
- if (length < 1 || length > 4) {
- return false;
- }
-
- if (length == 1) {
- // One part decimal numeric address
- long longValue = Long.parseLong(parts[0]);
- return longValue <= 0xFFFFFFFFL;
- } else {
- // Test each part for inclusion in the correct range
- for (int i = 0; i < length; i++) {
- // For two part addresses, the second part expresses
- // a 24-bit quantity; for three part addresses, the third
- // part expresses a 16-bit quantity.
- int max = 0xff;
- if ((length == 2) && (i == 1)) {
- max = 0xffffff;
- } else if ((length == 3) && (i == 2)) {
- max = 0xffff;
+ if (length == 1) {
+ // One part decimal numeric address
+ long longValue = Long.parseLong(parts[0]);
+ return longValue <= 0xFFFFFFFFL;
+ } else {
+ // Test each part for inclusion in the correct range
+ for (int i = 0; i < length; i++) {
+ // For two part addresses, the second part expresses
+ // a 24-bit quantity; for three part addresses, the third
+ // part expresses a 16-bit quantity.
+ int max = 0xff;
+ if ((length == 2) && (i == 1)) {
+ max = 0xffffff;
+ } else if ((length == 3) && (i == 2)) {
+ max = 0xffff;
+ }
+ if (Integer.parseInt(parts[i]) > max) {
+ return false;
+ }
}
- if (Integer.parseInt(parts[i]) > max) {
- return false;
- }
+ return true;
}
- return true;
- }
- // END android-changed
- }
+ // END android-changed
+ }
}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/InputStreamExposer.java b/luni/src/main/java/org/apache/harmony/luni/util/InputStreamExposer.java
index d7c2ab8..51a2d28 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/InputStreamExposer.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/InputStreamExposer.java
@@ -106,6 +106,7 @@
// if (is instanceof ExposedByteArrayInputStream) {
// return ((ExposedByteArrayInputStream) is).expose();
// }
+ // END android-changed
if (is.getClass().equals(ByteArrayInputStream.class)) {
return expose((ByteArrayInputStream) is);
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/Sorter.java b/luni/src/main/java/org/apache/harmony/luni/util/Sorter.java
deleted file mode 100644
index 1a994b2..0000000
--- a/luni/src/main/java/org/apache/harmony/luni/util/Sorter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.harmony.luni.util;
-
-import java.util.Arrays;
-
-/**
- * Helper class with methods for sorting arrays.
- * @deprecated Use {@link Comparator} and {@link Arrays.sort()}
- */
-@Deprecated
-public final class Sorter {
- public interface Comparator<T> extends java.util.Comparator<T> {
- }
-
- /**
- * Sorts the array of objects using the default sorting algorithm.
- *
- * @param objs
- * array of objects to be sorted
- * @param comp
- * A Comparator to be used to sort the elements
- *
- */
- public static <T> void sort(T[] objs, Comparator<T> comp) {
- Arrays.sort(objs, comp);
- }
-
-}
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/TwoKeyHashMap.java b/luni/src/main/java/org/apache/harmony/luni/util/TwoKeyHashMap.java
index 26e8d01..655d156 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/TwoKeyHashMap.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/TwoKeyHashMap.java
@@ -29,7 +29,7 @@
import java.util.Set;
/**
- *
+ *
* Reductive hash with two keys
*
*/
@@ -37,13 +37,13 @@
static final float DEFAULT_LOAD_FACTOR = 0.75f;
static final int DEFAULT_INITIAL_SIZE = 16;
-
+
private Set<Map.Entry<String, V>> entrySet;
private Collection<V> values;
private int size;
private int arrSize;
private int modCount;
-
+
private Entry<E, K, V>[] arr;
private float loadFactor;
@@ -55,9 +55,10 @@
public TwoKeyHashMap() {
this(DEFAULT_INITIAL_SIZE, DEFAULT_LOAD_FACTOR);
}
-
+
/**
* Constructs an empty HashMap
+ *
* @param initialCapacity
*/
public TwoKeyHashMap(int initialCapacity) {
@@ -65,16 +66,19 @@
}
/**
- * Constructs an empty HashMap
+ * Constructs an empty HashMap
+ *
* @param initialCapacity
* @param initialLoadFactor
*/
+ @SuppressWarnings("unchecked")
public TwoKeyHashMap(int initialCapacity, float initialLoadFactor) {
- if (initialCapacity < 0) {
+ if (initialCapacity < 0) {
throw new IllegalArgumentException("initialCapacity should be >= 0");
}
if (initialLoadFactor <= 0) {
- throw new IllegalArgumentException("initialLoadFactor should be > 0");
+ throw new IllegalArgumentException(
+ "initialLoadFactor should be > 0");
}
loadFactor = initialLoadFactor;
if (initialCapacity == Integer.MAX_VALUE) {
@@ -84,9 +88,9 @@
threshold = (int) (arrSize * loadFactor);
arr = new Entry[arrSize + 1];
}
-
+
/**
- * Returns a collection view of the values
+ * Returns a collection view of the values
*/
public Collection<V> values() {
if (values == null) {
@@ -94,9 +98,9 @@
}
return values;
}
-
+
/**
- * Returns a collection view of the mappings
+ * Returns a collection view of the mappings
*/
public Set<Map.Entry<String, V>> entrySet() {
if (entrySet == null) {
@@ -104,7 +108,7 @@
}
return entrySet;
}
-
+
/**
* Clears the map
*/
@@ -116,6 +120,7 @@
/**
* Removes the mapping for the keys
+ *
* @param key1
* @param key2
* @return
@@ -124,9 +129,10 @@
Entry<E, K, V> e = removeEntry(key1, key2);
return null != e ? e.value : null;
}
-
+
/**
* Associates the specified value with the specified keys in this map
+ *
* @param key1
* @param key2
* @param value
@@ -152,7 +158,8 @@
Entry<E, K, V> e = arr[index];
while (e != null) {
- if (hash == e.hash && key1.equals(e.getKey1()) && key2.equals(e.getKey2())) {
+ if (hash == e.hash && key1.equals(e.getKey1())
+ && key2.equals(e.getKey2())) {
V oldValue = e.value;
e.value = value;
return oldValue;
@@ -172,8 +179,9 @@
/**
* Rehash the map
- *
+ *
*/
+ @SuppressWarnings("unchecked")
void rehash() {
int newArrSize = (arrSize + 1) * 2 + 1;
if (newArrSize < 0) {
@@ -206,10 +214,12 @@
}
/**
- * Returns true if this map contains a mapping for the specified keys
- * @param key1
- * @param key2
- * @return
+ * Answers whether this map contains a mapping for the specified keys.
+ *
+ * @param key1 first key
+ * @param key2 second key
+ * @return true if this map contains a mapping for the specified keys, and
+ * false otherwise.
*/
public boolean containsKey(Object key1, Object key2) {
return findEntry(key1, key2) != null;
@@ -217,6 +227,7 @@
/**
* Return the value by keys
+ *
* @param key1
* @param key2
* @return
@@ -237,14 +248,15 @@
}
/**
- * Returns the number of mappings
+ * Returns the number of mappings
*/
public int size() {
return size;
}
-
+
/**
- * Creates new entry
+ * Creates new entry
+ *
* @param hashCode
* @param key1
* @param key2
@@ -252,13 +264,14 @@
* @param next
* @return
*/
- Entry<E, K, V> createEntry(int hashCode, E key1, K key2,
- V value, Entry<E, K, V> next) {
+ Entry<E, K, V> createEntry(int hashCode, E key1, K key2, V value,
+ Entry<E, K, V> next) {
return new Entry<E, K, V>(hashCode, key1, key2, value, next);
}
/**
* Creates entries iterator
+ *
* @return
*/
Iterator<Map.Entry<String, V>> createEntrySetIterator() {
@@ -267,18 +280,18 @@
/**
* Creates values iterator
+ *
* @return
*/
Iterator<V> createValueCollectionIterator() {
return new ValueIteratorImpl();
}
-
/**
* Entry implementation for the TwoKeyHashMap class
*
*/
- public static class Entry<E, K, V> implements Map.Entry<String, V> {
+ public static class Entry<E, K, V> implements Map.Entry<String, V> {
int hash;
E key1;
K key2;
@@ -292,7 +305,7 @@
this.value = value;
this.next = next;
}
-
+
public String getKey() {
return key1.toString() + key2.toString();
}
@@ -300,7 +313,7 @@
public E getKey1() {
return key1;
}
-
+
public K getKey2() {
return key2;
}
@@ -324,12 +337,11 @@
Object getKey1 = e.getKey1();
Object getKey2 = e.getKey2();
Object getValue = e.getValue();
- if ((key1 == null && getKey1 != null) ||
- (key2 == null && getKey2 != null) ||
- (value == null && getValue != null) ||
- !key1.equals(e.getKey1()) ||
- !key2.equals(e.getKey2()) ||
- !value.equals(getValue)) {
+ if ((key1 == null && getKey1 != null)
+ || (key2 == null && getKey2 != null)
+ || (value == null && getValue != null)
+ || !key1.equals(e.getKey1()) || !key2.equals(e.getKey2())
+ || !value.equals(getValue)) {
return false;
}
return true;
@@ -340,9 +352,9 @@
int hash2 = (key2 == null ? 0 : key2.hashCode());
return (hash1 + hash2) ^ (value == null ? 0 : value.hashCode());
}
-
+
}
-
+
class EntrySetImpl extends AbstractSet<Map.Entry<String, V>> {
public int size() {
return size;
@@ -375,7 +387,7 @@
if (!(obj instanceof Entry)) {
return false;
}
- return removeEntry(((Entry) obj).getKey1(), ((Entry)obj).getKey2()) != null;
+ return removeEntry(((Entry) obj).getKey1(), ((Entry) obj).getKey2()) != null;
}
public Iterator<Map.Entry<String, V>> iterator() {
@@ -425,14 +437,14 @@
found = false;
returned_index = curr;
returned_entry = curr_entry;
- return (Map.Entry<String, V>)curr_entry;
+ return (Map.Entry<String, V>) curr_entry;
}
public void remove() {
if (returned_index == -1) {
throw new IllegalStateException();
}
-
+
if (modCount != startModCount) {
throw new ConcurrentModificationException();
}
@@ -454,7 +466,7 @@
returned_index = -1;
}
}
-
+
private final Entry<E, K, V> findEntry(Object key1, Object key2) {
if (key1 == null && key2 == null) {
return arr[arrSize];
@@ -465,14 +477,15 @@
Entry<E, K, V> e = arr[index];
while (e != null) {
- if (hash == e.hash && key1.equals(e.getKey1()) && key2.equals(e.getKey2())) {
+ if (hash == e.hash && key1.equals(e.getKey1())
+ && key2.equals(e.getKey2())) {
return e;
}
e = e.next;
}
return null;
}
-
+
// Removes entry
private final Entry<E, K, V> removeEntry(Object key1, Object key2) {
if (key1 == null && key2 == null) {
@@ -493,7 +506,8 @@
Entry<E, K, V> e = arr[index];
Entry<E, K, V> prev = e;
while (e != null) {
- if (hash == e.hash && key1.equals(e.getKey1()) && key2.equals(e.getKey2())) {
+ if (hash == e.hash && key1.equals(e.getKey1())
+ && key2.equals(e.getKey2())) {
if (prev == e) {
arr[index] = e.next;
} else {
@@ -529,12 +543,12 @@
public Iterator<V> iterator() {
return createValueCollectionIterator();
}
-
+
public boolean contains(Object obj) {
return containsValue(obj);
}
}
-
+
class ValueIteratorImpl implements Iterator<V> {
private EntryIteratorImpl itr;
diff --git a/luni/src/main/java/org/apache/harmony/luni/util/Util.java b/luni/src/main/java/org/apache/harmony/luni/util/Util.java
index bfb0149..0688e7d 100644
--- a/luni/src/main/java/org/apache/harmony/luni/util/Util.java
+++ b/luni/src/main/java/org/apache/harmony/luni/util/Util.java
@@ -41,13 +41,19 @@
if (encoding != null) {
try {
"".getBytes(encoding);
- } catch (java.io.UnsupportedEncodingException e) {
+ } catch (Throwable t) {
encoding = null;
}
}
defaultEncoding = encoding;
}
+ /**
+ * Get bytes from String using default encoding; default encoding can
+ * be changed via "os.encoding" property
+ * @param name input String
+ * @return byte array
+ */
public static byte[] getBytes(String name) {
if (defaultEncoding != null) {
try {
@@ -58,6 +64,20 @@
return name.getBytes();
}
+ /**
+ * Get bytes from String with UTF8 encoding
+ * @param name
+ * input String
+ * @return byte array
+ */
+ public static byte[] getUTF8Bytes(String name) {
+ try {
+ return name.getBytes("UTF-8");
+ } catch (java.io.UnsupportedEncodingException e) {
+ return getBytes(name);
+ }
+ }
+
public static String toString(byte[] bytes) {
if (defaultEncoding != null) {
try {
@@ -68,6 +88,10 @@
return new String(bytes, 0, bytes.length);
}
+ public static String toUTF8String(byte[] bytes) {
+ return toUTF8String(bytes, 0, bytes.length);
+ }
+
public static String toString(byte[] bytes, int offset, int length) {
if (defaultEncoding != null) {
try {
@@ -78,10 +102,18 @@
return new String(bytes, offset, length);
}
+ public static String toUTF8String(byte[] bytes, int offset, int length) {
+ try {
+ return new String(bytes, offset, length, "UTF-8");
+ } catch (java.io.UnsupportedEncodingException e) {
+ return toString(bytes, offset, length);
+ }
+ }
+
/**
* Returns the millisecond value of the date and time parsed from the
* specified String. Many date/time formats are recognized
- *
+ *
* @param string
* the String to parse
* @return the millisecond value parsed from the String
@@ -236,7 +268,7 @@
* '%' and two following hex digit characters are converted to the
* equivalent byte value. All other characters are passed through
* unmodified. e.g. "ABC %24%25" -> "ABC $%"
- *
+ *
* @param s
* java.lang.String The encoded string.
* @return java.lang.String The decoded version.
@@ -273,7 +305,7 @@
}
return result.toString();
}
-
+
public static String toASCIILowerCase(String s) {
int len = s.length();
StringBuilder buffer = new StringBuilder(len);
@@ -287,7 +319,7 @@
}
return buffer.toString();
}
-
+
public static String toASCIIUpperCase(String s) {
int len = s.length();
StringBuilder buffer = new StringBuilder(len);
diff --git a/luni/src/main/native/cbigint.c b/luni/src/main/native/cbigint.c
index 0f65ca0..77ee0f8 100644
--- a/luni/src/main/native/cbigint.c
+++ b/luni/src/main/native/cbigint.c
@@ -18,7 +18,7 @@
#include <string.h>
#include "cbigint.h"
-#if defined(LINUX) || defined(FREEBSD)
+#if defined(LINUX) || defined(FREEBSD) || defined(ZOS)
#define USE_LL
#endif
@@ -691,7 +691,7 @@
*/
/* Replace the current implementaion which performs a
* "multiplication" by 10 e number of times with an actual
- * mulitplication. 10e19 is the largest exponent to the power of ten
+ * multiplication. 10e19 is the largest exponent to the power of ten
* that will fit in a 64-bit integer, and 10e9 is the largest exponent to
* the power of ten that will fit in a 64-bit integer. Not sure where the
* break-even point is between an actual multiplication and a
diff --git a/luni/src/main/native/java_io_FileDescriptor.c b/luni/src/main/native/java_io_FileDescriptor.c
index a5ec8b7..897e688 100644
--- a/luni/src/main/native/java_io_FileDescriptor.c
+++ b/luni/src/main/native/java_io_FileDescriptor.c
@@ -103,20 +103,6 @@
}
}
-/*
- * public native boolean valid()
- */
-static jboolean fd_valid(JNIEnv* env, jobject obj) {
- int fd = getFd(env, obj);
- struct stat sb;
-
- if(fstat(fd, &sb) == 0) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
-}
-
/* checks to see if class is inited and inits if needed, returning -1
* on fail and 0 on success
*/
@@ -205,8 +191,7 @@
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "oneTimeInitialization", "()V", nativeClassInit },
- { "syncImpl", "()V", fd_sync },
- { "valid", "()Z", fd_valid }
+ { "syncImpl", "()V", fd_sync }
};
int register_java_io_FileDescriptor(JNIEnv* env) {
return jniRegisterNativeMethods(env, "java/io/FileDescriptor",
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index e105f5c..cce822a 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -1654,7 +1654,7 @@
}
-static void osNetworkSystem_createSocketImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_createStreamSocketImpl(JNIEnv* env, jclass clazz,
jobject fileDescriptor, jboolean preferIPv4Stack) {
// LOGD("ENTER createSocketImpl");
createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
@@ -2340,35 +2340,6 @@
}
}
-static jboolean osNetworkSystem_socketBindImpl2(JNIEnv* env, jclass clazz,
- jobject fileDescriptor, jint port, jboolean bindToDevice,
- jobject inetAddress) {
- // LOGD("ENTER socketBindImpl2");
-
- struct sockaddr_storage sockaddress;
- int ret;
- int handle;
-
- ret = inetAddressToSocketAddress(env, inetAddress, port, &sockaddress);
- if (ret < 0) // Exception has already been thrown.
- return 0;
-
- handle = jniGetFDFromFileDescriptor(env, fileDescriptor);
- if (handle == 0 || handle == -1) {
- throwSocketException(env, SOCKERR_BADDESC);
- return 0;
- }
-
- ret = doBind(handle, &sockaddress);
- if (ret < 0) {
- int err = convertError(errno);
- jniThrowException(env, "java/net/BindException", netLookupErrorString(err));
- return 0;
- }
-
- return 0;
-}
-
static jint osNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz,
jobject fd, jobject sender, jint receiveTimeout) {
// LOGD("ENTER peekDatagramImpl");
@@ -2639,19 +2610,6 @@
setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
}
-static void osNetworkSystem_createMulticastSocketImpl(JNIEnv* env,
- jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) {
- // LOGD("ENTER createMulticastSocketImpl");
-
- int handle = createSocketFileDescriptor(env, fileDescriptor, SOCK_DGRAM);
- if (handle < 0)
- return;
-
- int value = 1;
- // setsockopt(handle, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(jbyte));
- setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
-}
-
/*
* @param timeout in milliseconds. If zero, block until data received
*/
@@ -3847,7 +3805,7 @@
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "oneTimeInitializationImpl", "(Z)V", (void*) osNetworkSystem_oneTimeInitializationImpl },
- { "createSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createSocketImpl },
+ { "createStreamSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createStreamSocketImpl },
{ "createDatagramSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createDatagramSocketImpl },
{ "readSocketImpl", "(Ljava/io/FileDescriptor;[BIII)I", (void*) osNetworkSystem_readSocketImpl },
{ "readSocketDirectImpl", "(Ljava/io/FileDescriptor;IIII)I", (void*) osNetworkSystem_readSocketDirectImpl },
@@ -3865,7 +3823,6 @@
{ "sendUrgentDataImpl", "(Ljava/io/FileDescriptor;B)V", (void*) osNetworkSystem_sendUrgentDataImpl },
{ "connectDatagramImpl2", "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;)V", (void*) osNetworkSystem_connectDatagramImpl2 },
{ "disconnectDatagramImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_disconnectDatagramImpl },
- { "socketBindImpl2", "(Ljava/io/FileDescriptor;IZLjava/net/InetAddress;)Z", (void*) osNetworkSystem_socketBindImpl2 },
{ "peekDatagramImpl", "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)I", (void*) osNetworkSystem_peekDatagramImpl },
{ "receiveDatagramImpl", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I", (void*) osNetworkSystem_receiveDatagramImpl },
{ "receiveDatagramDirectImpl", "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I", (void*) osNetworkSystem_receiveDatagramDirectImpl },
@@ -3876,7 +3833,6 @@
{ "sendConnectedDatagramImpl", "(Ljava/io/FileDescriptor;[BIIZ)I", (void*) osNetworkSystem_sendConnectedDatagramImpl },
{ "sendConnectedDatagramDirectImpl", "(Ljava/io/FileDescriptor;IIIZ)I", (void*) osNetworkSystem_sendConnectedDatagramDirectImpl },
{ "createServerStreamSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createServerStreamSocketImpl },
- { "createMulticastSocketImpl", "(Ljava/io/FileDescriptor;Z)V", (void*) osNetworkSystem_createMulticastSocketImpl },
{ "receiveStreamImpl", "(Ljava/io/FileDescriptor;[BIII)I", (void*) osNetworkSystem_receiveStreamImpl },
{ "sendStreamImpl", "(Ljava/io/FileDescriptor;[BII)I", (void*) osNetworkSystem_sendStreamImpl },
{ "shutdownInputImpl", "(Ljava/io/FileDescriptor;)V", (void*) osNetworkSystem_shutdownInputImpl },
diff --git a/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c b/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
index d8a1e68..e92b776 100644
--- a/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
+++ b/luni/src/main/native/org_apache_harmony_luni_util_fltparse.c
@@ -22,7 +22,7 @@
#include "commonDblParce.h"
#include "cbigint.h"
-#if defined(LINUX)
+#if defined(LINUX) || defined(FREEBSD) || defined(ZOS)
#define USE_LL
#endif
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
index ed81162..84cddf2 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileTest.java
@@ -45,8 +45,9 @@
File file = new File(root, "/dir/file");
assertEquals("Assert 1: wrong path result ", path.getPath(), file
.getPath());
- assertTrue("Assert 1.1: path not absolute ", new File("\\\\\\a\b").isAbsolute());
-
+ assertFalse("Assert 1.1: path absolute ", new File("\\\\\\a\b").isAbsolute());
+ assertTrue("Assert 1.1: path absolute ", new File("///a/b").isAbsolute());
+
// Test data used in a few places below
String dirName = System.getProperty("java.io.tmpdir");
String fileName = "input.tst";
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java
index 14ca1ad..3097fbe 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ClassTest.java
@@ -838,6 +838,8 @@
args = {}
)
public void test_getClassLoader() {
+ // this fails if ClassTest.class was loaded by the regular classloader,
+ // but passes if it was loaded by the boot class loader.
assertEquals(ExtendTestClass.class.getClassLoader(),
PublicTestClass.class.getClassLoader());
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java
index 2b03e5a..b1ad88a 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/FloatTest.java
@@ -1091,8 +1091,6 @@
fail("Expected Float.valueOf(null) to throw NPE.");
} catch (NullPointerException ex) {
// expected
- } catch (Exception ex) {
- fail("Expected Float.valueOf(null) to throw NPE not " + ex.getClass().getName());
}
try {
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IntegerTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IntegerTest.java
index 9151068..ea71009 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IntegerTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/IntegerTest.java
@@ -169,6 +169,56 @@
exception = true;
}
assertTrue("Failed to throw exception for 9999999999", exception);
+
+ try {
+ Integer.decode("-");
+ fail("Expected exception for -");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("0x");
+ fail("Expected exception for 0x");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("#");
+ fail("Expected exception for #");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("x123");
+ fail("Expected exception for x123");
+ } catch (NumberFormatException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode(null);
+ fail("Expected exception for null");
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ try {
+ Integer.decode("");
+ fail("Expected exception for empty string");
+ } catch (NumberFormatException ex) {
+ // Expected
+ }
+
+ try {
+ Integer.decode(" ");
+ fail("Expected exception for single space");
+ } catch (NumberFormatException ex) {
+ // Expected
+ }
+
}
/**
@@ -591,6 +641,15 @@
-Integer.MAX_VALUE));
assertEquals("Returned incorrect octal string", "-2147483648", Integer.toString(
Integer.MIN_VALUE));
+
+ // Test for HARMONY-6068
+ assertEquals("Returned incorrect octal String", "-1000", Integer.toString(-1000));
+ assertEquals("Returned incorrect octal String", "1000", Integer.toString(1000));
+ assertEquals("Returned incorrect octal String", "0", Integer.toString(0));
+ assertEquals("Returned incorrect octal String", "708", Integer.toString(708));
+ assertEquals("Returned incorrect octal String", "-100", Integer.toString(-100));
+ assertEquals("Returned incorrect octal String", "-1000000008", Integer.toString(-1000000008));
+ assertEquals("Returned incorrect octal String", "2000000008", Integer.toString(2000000008));
}
/**
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ObjectTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ObjectTest.java
index e2b72be..758428e 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ObjectTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ObjectTest.java
@@ -23,6 +23,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.BrokenTest;
+import dalvik.annotation.SideEffect;
@TestTargetClass(Object.class)
public class ObjectTest extends junit.framework.TestCase {
@@ -79,6 +80,7 @@
method = "finalize",
args = {}
)
+ @SideEffect("Causes OutOfMemoryError to test finalization")
public void test_finalize() {
isCalled = false;
class TestObject extends Object {
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ProcessBuilderTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ProcessBuilderTest.java
index 93561bf..d35f50b 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ProcessBuilderTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ProcessBuilderTest.java
@@ -228,6 +228,16 @@
Process process = pb.start();
InputStream in = process.getInputStream();
InputStream err = process.getErrorStream();
+
+ while (true) {
+ try {
+ process.waitFor();
+ break;
+ } catch (InterruptedException e) {
+ // Ignored
+ }
+ }
+
byte[] buf = new byte[1024];
if (in.available() > 0) {
assertTrue(in.read(buf) > 0);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadLocalTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadLocalTest.java
index bcb94c7..48fddfe 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadLocalTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/lang/ThreadLocalTest.java
@@ -37,11 +37,7 @@
args = {}
)
public void test_Constructor() {
- try {
- new ThreadLocal<Object>();
- } catch (Exception e) {
- fail("unexpected exception: " + e.toString());
- }
+ new ThreadLocal<Object>();
}
/**
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java
index d00968f..bdbfbd4 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/ContentHandlerFactoryTest.java
@@ -67,8 +67,7 @@
assertTrue(isCreateContentHandlerCalled);
assertTrue(isGetContentCalled);
} catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
-
+ throw new RuntimeException(e);
}
isGetContentCalled = false;
@@ -77,8 +76,7 @@
con.getContent(new Class[] {});
assertTrue(isGetContentCalled);
} catch (Exception e) {
- fail("Exception during test : " + e.getMessage());
-
+ throw new RuntimeException(e);
}
try {
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
index c803d3b..bcd73d8 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
@@ -1069,8 +1069,6 @@
method = "getHeaderFieldDate",
args = {java.lang.String.class, long.class}
)
- @KnownFailure("getHeaderFieldDate on Content-Length throws an exception."
- + " The RI just returns the default value")
public void test_getHeaderFieldDateLjava_lang_StringJ() {
Support_TestWebData params = Support_TestWebData.testParams[0];
@@ -1612,7 +1610,6 @@
method = "guessContentTypeFromStream",
args = {java.io.InputStream.class}
)
- @KnownFailure("'<?xml' recognised as text/html instead of application/xml")
public void test_guessContentTypeFromStreamLjava_io_InputStream()
throws IOException {
assertContentTypeEquals("ASCII", "text/html", "<html>");
diff --git a/luni/src/test/java/tests/api/java/io/FileTest.java b/luni/src/test/java/tests/api/java/io/FileTest.java
index b35e85f..9f32fef 100644
--- a/luni/src/test/java/tests/api/java/io/FileTest.java
+++ b/luni/src/test/java/tests/api/java/io/FileTest.java
@@ -217,8 +217,6 @@
method = "File",
args = {java.lang.String.class, java.lang.String.class}
)
- @AndroidOnly("Test 3 incorrectly fails on the RI; Android is more " +
- "better at resolving path names.")
public void test_ConstructorLjava_lang_StringLjava_lang_String_112270() {
File ref1 = new File("/dir1/file1");
@@ -230,10 +228,10 @@
ref1.getPath()));
File file3 = new File("\\", "\\dir1\\file1");
assertTrue("wrong result 3: " + file3, file3.getPath().equals(
- ref1.getPath()));
+ "\\/\\dir1\\file1"));
File file4 = new File("\\", "\\\\dir1\\file1");
assertTrue("wrong result 4: " + file4, file4.getPath().equals(
- ref1.getPath()));
+ "\\/\\\\dir1\\file1"));
File ref2 = new File("/lib/content-types.properties");
File file5 = new File("/", "lib/content-types.properties");
@@ -250,8 +248,6 @@
method = "File",
args = {java.io.File.class, java.lang.String.class}
)
- @AndroidOnly("Test 3 incorrectly fails on the RI; Android is more " +
- "better at resolving path names.")
public void test_ConstructorLjava_io_FileLjava_lang_String_112270() {
File ref1 = new File("/dir1/file1");
@@ -264,10 +260,10 @@
ref1.getPath()));
File file3 = new File(root, "\\dir1\\file1");
assertTrue("wrong result 3: " + file3, file3.getPath().equals(
- ref1.getPath()));
+ "/\\dir1\\file1"));
File file4 = new File(root, "\\\\dir1\\file1");
assertTrue("wrong result 4: " + file4, file4.getPath().equals(
- ref1.getPath()));
+ "/\\\\dir1\\file1"));
File ref2 = new File("/lib/content-types.properties");
File file5 = new File(root, "lib/content-types.properties");
@@ -693,6 +689,8 @@
args = {}
)
public void test_delete() {
+ // this test passes in the emulator, but it fails on the device
+
// Test for method boolean java.io.File.delete()
try {
File dir = new File(System.getProperty("java.io.tmpdir"), platformId
diff --git a/luni/src/test/java/tests/api/java/io/OutputStreamWriterTest.java b/luni/src/test/java/tests/api/java/io/OutputStreamWriterTest.java
index 3f5fc68..783478a 100644
--- a/luni/src/test/java/tests/api/java/io/OutputStreamWriterTest.java
+++ b/luni/src/test/java/tests/api/java/io/OutputStreamWriterTest.java
@@ -30,6 +30,7 @@
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
+import java.util.Arrays;
import tests.support.Support_OutputStream;
@@ -483,6 +484,99 @@
}
}
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {char[].class}
+ )
+ public void test_write_US_ASCII() throws Exception {
+ testEncodeCharset("US-ASCII", 128);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {char[].class}
+ )
+ public void test_write_ISO_8859_1() throws Exception {
+ testEncodeCharset("ISO-8859-1", 256);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {char[].class}
+ )
+ public void test_write_UTF_16BE() throws Exception {
+ testEncodeCharset("UTF-16BE", 0xd800);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {char[].class}
+ )
+ public void test_write_UTF_16LE() throws Exception {
+ testEncodeCharset("UTF-16LE", 0xd800);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {char[].class}
+ )
+ public void test_write_UTF_16() throws Exception {
+ testEncodeCharset("UTF-16", 0xd800);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "",
+ method = "write",
+ args = {char[].class}
+ )
+ public void test_write_UTF_8() throws Exception {
+ testEncodeCharset("UTF-8", 0xd800);
+ }
+
+ private void testEncodeCharset(String charset, int maxChar) throws Exception {
+ char[] chars = new char[maxChar];
+ for (int i = 0; i < maxChar; i++) {
+ chars[i] = (char) i;
+ }
+
+ // to byte array
+ ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ OutputStreamWriter charsOut = new OutputStreamWriter(bytesOut, charset);
+ charsOut.write(chars);
+ charsOut.flush();
+
+ // decode from byte array, one character at a time
+ ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesOut.toByteArray());
+ InputStreamReader charsIn = new InputStreamReader(bytesIn, charset);
+ for (int i = 0; i < maxChar; i++) {
+ assertEquals(i, charsIn.read());
+ }
+ assertEquals(-1, charsIn.read());
+
+ // decode from byte array, using byte buffers
+ bytesIn = new ByteArrayInputStream(bytesOut.toByteArray());
+ charsIn = new InputStreamReader(bytesIn, charset);
+ char[] decoded = new char[maxChar];
+ for (int r = 0; r < maxChar; ) {
+ r += charsIn.read(decoded, r, maxChar - r);
+ }
+ assertEquals(-1, charsIn.read());
+ for (int i = 0; i < maxChar; i++) {
+ assertEquals(i, decoded[i]);
+ }
+ }
+
/**
* @tests java.io.OutputStreamWriter#getEncoding()
*/
diff --git a/luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java b/luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java
index 4c67241..d890f38 100644
--- a/luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java
+++ b/luni/src/test/java/tests/api/java/lang/ref/SoftReferenceTest.java
@@ -21,6 +21,7 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.BrokenTest;
+import dalvik.annotation.SideEffect;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
@@ -107,6 +108,7 @@
method = "get",
args = {}
)
+ @SideEffect("Causes OutOfMemoryError to test finalization")
public void test_get_SoftReference() {
class TestObject {
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java
index 31dfaa5..8919652 100644
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java
+++ b/luni/src/test/java/tests/api/java/lang/reflect/GenericReflectionCornerCases.java
@@ -169,8 +169,6 @@
)
})
@SuppressWarnings("unchecked")
- @KnownFailure("Class MultipleBoundedWildcardUnEquality can not be found, "
- + "maybe the wrong class loader is used to get the raw type?")
public void testMultipleBoundedWildcardUnEquality() throws Exception {
Class<? extends MultipleBoundedWildcardUnEquality> clazz = MultipleBoundedWildcardUnEquality.class;
@@ -240,8 +238,6 @@
)
})
@SuppressWarnings("unchecked")
- @KnownFailure("Class MultipleBoundedWildcardEquality can not be found, "
- + "maybe the wrong class loader is used to get the raw type?")
public void testMultipleBoundedWildcard() throws Exception {
Class<? extends MultipleBoundedWildcardEquality> clazz = MultipleBoundedWildcardEquality.class;
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java b/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java
index c9255b2..7db5dbe 100644
--- a/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java
+++ b/luni/src/test/java/tests/api/java/lang/reflect/GenericTypesTest.java
@@ -201,8 +201,6 @@
args = {}
)
@SuppressWarnings("unchecked")
- @KnownFailure("Class GenericType can not be found, "
- + "maybe the wrong class loader is used to get the raw type?")
public void testSimpleInheritance() throws Exception {
Class<? extends SimpleInheritance> clazz = SimpleInheritance.class;
TypeVariable<Class> subTypeVariable = getTypeParameter(clazz);
diff --git a/luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java b/luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java
index eaff7c8..bf3698e 100644
--- a/luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java
+++ b/luni/src/test/java/tests/api/java/lang/reflect/ParameterizedTypeTest.java
@@ -55,8 +55,6 @@
args = {}
)
})
- @KnownFailure("Class A can not be found, "
- + "maybe the wrong class loader is used to get the raw type?")
public void testStringParameterizedSuperClass() {
Class<? extends B> clazz = B.class;
Type genericSuperclass = clazz.getGenericSuperclass();
@@ -93,8 +91,6 @@
args = {}
)
})
- @KnownFailure("Class C can not be found, "
- + "maybe the wrong class loader is used to get the raw type?")
public void testTypeParameterizedSuperClass() {
Class<? extends D> clazz = D.class;
Type genericSuperclass = clazz.getGenericSuperclass();
diff --git a/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
index f6957e2..13141f8 100644
--- a/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
+++ b/luni/src/test/java/tests/api/java/net/MulticastSocketTest.java
@@ -36,6 +36,9 @@
import java.net.UnknownHostException;
import java.security.Permission;
import java.util.Enumeration;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
import tests.support.Support_NetworkInterface;
import tests.support.Support_PortManager;
@@ -64,23 +67,24 @@
public MulticastSocket ms;
- boolean running = true;
+ volatile boolean running = true;
- volatile public byte[] rbuf = new byte[512];
-
- volatile DatagramPacket rdp = null;
+ private final BlockingQueue<DatagramPacket> queue
+ = new ArrayBlockingQueue<DatagramPacket>(1);
public void run() {
try {
while (running) {
try {
+ byte[] rbuf = new byte[512];
+ rbuf[0] = -1;
+ DatagramPacket rdp = new DatagramPacket(rbuf, rbuf.length);
ms.receive(rdp);
+ queue.put(rdp);
} catch (java.io.InterruptedIOException e) {
- Thread.yield();
+ } catch (InterruptedException e) {
}
- ;
}
- ;
} catch (java.io.IOException e) {
System.out.println("Multicast server failed: " + e);
} finally {
@@ -93,15 +97,8 @@
ms.leaveGroup(aGroup);
}
- public void stopServer() {
- running = false;
- }
-
public MulticastServer(InetAddress anAddress, int aPort)
throws java.io.IOException {
- rbuf = new byte[512];
- rbuf[0] = -1;
- rdp = new DatagramPacket(rbuf, rbuf.length);
ms = new MulticastSocket(aPort);
ms.setSoTimeout(2000);
ms.joinGroup(anAddress);
@@ -109,13 +106,20 @@
public MulticastServer(SocketAddress anAddress, int aPort,
NetworkInterface netInterface) throws java.io.IOException {
- rbuf = new byte[512];
- rbuf[0] = -1;
- rdp = new DatagramPacket(rbuf, rbuf.length);
ms = new MulticastSocket(aPort);
ms.setSoTimeout(2000);
ms.joinGroup(anAddress, netInterface);
}
+
+ public DatagramPacket receive() throws InterruptedException {
+ return queue.poll(1000, TimeUnit.MILLISECONDS);
+ }
+
+ public void stopServer() throws InterruptedException {
+ running = false;
+ interrupt();
+ join();
+ }
}
/**
@@ -458,7 +462,7 @@
method = "joinGroup",
args = {java.net.InetAddress.class}
)
- public void test_joinGroupLjava_net_InetAddress() {
+ public void test_joinGroupLjava_net_InetAddress() throws InterruptedException {
// Test for method void
// java.net.MulticastSocket.joinGroup(java.net.InetAddress)
String msg = null;
@@ -476,8 +480,7 @@
.length(), group, groupPort);
mss.joinGroup(group);
mss.send(sdp, (byte) 10);
- Thread.sleep(1000);
-
+
SecurityManager sm = new SecurityManager() {
public void checkPermission(Permission perm) {
@@ -514,8 +517,10 @@
} catch (Exception e) {
fail("Exception during joinGroup test: " + e.toString());
}
- assertTrue("Group member did not recv data: ", new String(server.rdp
- .getData(), 0, server.rdp.getLength()).equals(msg));
+ DatagramPacket rdb = server.receive();
+
+ assertEquals("Group member did not recv data: ", msg,
+ new String(rdb.getData(), 0, rdb.getLength()));
}
@@ -609,11 +614,11 @@
.length(), group, serverPort);
mss.setTimeToLive(2);
mss.send(sdp);
- Thread.sleep(1000);
+ DatagramPacket rdp = server.receive();
+
// now vaildate that we received the data as expected
- assertTrue("Group member did not recv data: ", new String(
- server.rdp.getData(), 0, server.rdp.getLength())
- .equals(msg));
+ assertEquals("Group member did not recv data: ", msg,
+ new String(rdp.getData(), 0, rdp.getLength()));
server.stopServer();
// now validate that we handled the case were we join a
@@ -634,11 +639,9 @@
sdp = new DatagramPacket(msg.getBytes(), msg.length(), group2,
serverPort);
mss.send(sdp);
- Thread.sleep(1000);
- assertFalse(
- "Group member received data when sent on different group: ",
- new String(server.rdp.getData(), 0, server.rdp.getLength())
- .equals(msg));
+ rdp = server.receive();
+ assertNull("Group member received data when sent on different group",
+ rdp);
server.stopServer();
// if there is more than one network interface then check that
@@ -718,20 +721,20 @@
sdp = new DatagramPacket(msg.getBytes(), msg.length(),
group, serverPort);
mss.send(sdp);
- Thread.sleep(1000);
+ rdp = server.receive();
+
if (thisInterface.equals(sendingInterface)) {
- assertTrue(
+ assertEquals(
"Group member did not recv data when " +
- "bound on specific interface: ",
- new String(server.rdp.getData(), 0,
- server.rdp.getLength()).equals(msg));
+ "bound on specific interface: ", msg,
+ new String(rdp.getData(), 0, rdp.getLength()));
} else {
assertFalse(
"Group member received data on other " +
"interface when only asked for it on one " +
"interface: ",
- new String(server.rdp.getData(), 0,
- server.rdp.getLength()).equals(msg));
+ new String(rdp.getData(), 0,
+ rdp.getLength()).equals(msg));
}
server.stopServer();
@@ -943,7 +946,7 @@
method = "send",
args = {java.net.DatagramPacket.class, byte.class}
)
- public void test_sendLjava_net_DatagramPacketB() {
+ public void test_sendLjava_net_DatagramPacketB() throws InterruptedException {
// Test for method void
// java.net.MulticastSocket.send(java.net.DatagramPacket, byte)
@@ -1016,11 +1019,10 @@
} catch(IOException ioe) {
//expected
}
-
- byte[] data = server.rdp.getData();
- int length = server.rdp.getLength();
- assertTrue("Failed to send data. Received " + length, new String(data,
- 0, length).equals(msg));
+
+ DatagramPacket rdp = server.receive();
+ assertEquals("Failed to send data. Received " + rdp.getLength(), msg,
+ new String(rdp.getData(), 0, rdp.getLength()));
}
/**
@@ -1163,24 +1165,13 @@
DatagramPacket sdp = new DatagramPacket(theBytes,
theBytes.length, group, serverPort);
mss.send(sdp);
- Thread.sleep(1000);
- String receivedMessage = new String(server.rdp
- .getData(), 0, server.rdp.getLength());
- assertTrue(
- "Group member did not recv data when send on " +
- "a specific interface: ",
- receivedMessage.equals(msg));
- assertTrue(
- "Datagram was not received from expected " +
- "interface expected["
- + thisInterface
- + "] got ["
- + NetworkInterface
- .getByInetAddress(server.rdp
- .getAddress()) + "]",
- NetworkInterface.getByInetAddress(
- server.rdp.getAddress()).equals(
- thisInterface));
+ DatagramPacket rdp = server.receive();
+
+ String receivedMessage = new String(rdp.getData(), 0, rdp.getLength());
+ assertEquals("Group member did not recv data when send on "
+ + "a specific interface: ", msg, receivedMessage);
+ assertEquals("Datagram was not received as expected.",
+ thisInterface, NetworkInterface.getByInetAddress(rdp.getAddress()));
// stop the server
server.stopServer();
@@ -1598,7 +1589,7 @@
* Tears down the fixture, for example, close a network connection. This
* method is called after a test is executed.
*/
- protected void tearDown() {
+ protected void tearDown() throws InterruptedException {
if (t != null)
t.interrupt();
diff --git a/luni/src/test/java/tests/api/java/net/UnknownServiceExceptionTest.java b/luni/src/test/java/tests/api/java/net/UnknownServiceExceptionTest.java
index 9fc287c..463532f 100644
--- a/luni/src/test/java/tests/api/java/net/UnknownServiceExceptionTest.java
+++ b/luni/src/test/java/tests/api/java/net/UnknownServiceExceptionTest.java
@@ -40,7 +40,7 @@
public void test_Constructor() {
// Test for method java.net.UnknownServiceException()
try {
- new URL("file://moo.txt").openConnection().getOutputStream();
+ new URL("file:///moo.txt").openConnection().getOutputStream();
} catch (UnknownServiceException e) {
// correct
return;
diff --git a/luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java b/luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java
index 169afe3..e2c47b8 100644
--- a/luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java
+++ b/luni/src/test/java/tests/api/java/util/AbstractSequentialListTest.java
@@ -85,7 +85,7 @@
}
public boolean hasNext() {
- return false;
+ return true;
}
public boolean hasPrevious() {
diff --git a/luni/src/test/java/tests/api/java/util/BitSetTest.java b/luni/src/test/java/tests/api/java/util/BitSetTest.java
index c0e6f2a..34ec49a 100644
--- a/luni/src/test/java/tests/api/java/util/BitSetTest.java
+++ b/luni/src/test/java/tests/api/java/util/BitSetTest.java
@@ -252,7 +252,7 @@
initialSize = bs.size();
bs.set(0, initialSize);
bs.clear(7, 64);
- assertEquals("Failed to grow BitSet", 128, bs.size());
+ assertEquals("Failed to grow BitSet", 64, bs.size());
for (int i = 0; i < 7; i++)
assertTrue("Shouldn't have cleared bit " + i, bs.get(i));
for (int i = 7; i < 64; i++)
@@ -624,7 +624,7 @@
// pos1 and pos2 is in the same bitset element, boundary testing
bs = new BitSet(16);
bs.set(7, 64);
- assertEquals("Failed to grow BitSet", 128, bs.size());
+ assertEquals("Failed to grow BitSet", 64, bs.size());
for (int i = 0; i < 7; i++)
assertTrue("Shouldn't have set bit " + i, !bs.get(i));
for (int i = 7; i < 64; i++)
@@ -858,7 +858,7 @@
bs.set(7);
bs.set(10);
bs.flip(7, 64);
- assertEquals("Failed to grow BitSet", 128, bs.size());
+ assertEquals("Failed to grow BitSet", 64, bs.size());
for (int i = 0; i < 7; i++)
assertTrue("Shouldn't have flipped bit " + i, !bs.get(i));
assertTrue("Failed to flip bit 7", !bs.get(7));
diff --git a/luni/src/test/java/tests/api/java/util/FormatterTest.java b/luni/src/test/java/tests/api/java/util/FormatterTest.java
index 636f1bd..b2030c9 100644
--- a/luni/src/test/java/tests/api/java/util/FormatterTest.java
+++ b/luni/src/test/java/tests/api/java/util/FormatterTest.java
@@ -4705,7 +4705,7 @@
bw.close();
readOnly = File.createTempFile("readonly", null);
- readOnly.setReadOnly();
+ assertTrue(readOnly.setReadOnly());
secret = File.createTempFile("secret", null);
diff --git a/luni/src/test/java/tests/api/java/util/TreeMapTest.java b/luni/src/test/java/tests/api/java/util/TreeMapTest.java
index 7ea4c9e..0e7f6a1 100644
--- a/luni/src/test/java/tests/api/java/util/TreeMapTest.java
+++ b/luni/src/test/java/tests/api/java/util/TreeMapTest.java
@@ -83,6 +83,9 @@
if (null == o1) {
return -1;
}
+ if (null == o2) {
+ return 1;
+ }
return o1.compareTo(o2);
}
}
@@ -844,8 +847,6 @@
method = "equals",
args = {java.lang.Object.class}
)
- @KnownFailure("equals(Onject o) method throws java.lang.ClassCastException " +
- "for TreeMap objects with different key objects.")
public void test_equals() throws Exception {
// comparing TreeMaps with different object types
Map m1 = new TreeMap();
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
index ddd56e5..ac8f77b 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/DatagramChannelImpl.java
@@ -15,14 +15,13 @@
* limitations under the License.
*/
-/*
- * Android Notice
- * In this class the address length was changed from long to int.
- * This is due to performance optimizations for the device.
- */
-
package org.apache.harmony.nio.internal;
+// BEGIN android-note
+// Copied from a newer version of Harmony.
+// In this class the address length was changed from long to int.
+// END android-note
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -43,7 +42,7 @@
import java.nio.channels.spi.SelectorProvider;
import org.apache.harmony.luni.net.NetUtil;
-import org.apache.harmony.luni.net.SocketImplProvider;
+import org.apache.harmony.luni.net.PlainDatagramSocketImpl;
import org.apache.harmony.luni.platform.FileDescriptorHandler;
import org.apache.harmony.luni.platform.INetworkSystem;
import org.apache.harmony.luni.platform.Platform;
@@ -52,15 +51,10 @@
/*
* The default implementation class of java.nio.channels.DatagramChannel.
- *
*/
class DatagramChannelImpl extends DatagramChannel implements
FileDescriptorHandler {
- // -------------------------------------------------------------------
- // Class variables
- // -------------------------------------------------------------------
-
// The singleton to do the native network operation.
private static final INetworkSystem networkSystem = Platform
.getNetworkSystem();
@@ -72,10 +66,6 @@
private static final byte[] stubArray = new byte[0];
- // -------------------------------------------------------------------
- // Instance variables
- // -------------------------------------------------------------------
-
// The fd to interact with native code
private FileDescriptor fd;
@@ -94,19 +84,17 @@
// whether the socket is bound
boolean isBound = false;
- private final Object readLock = new Object();
+ private static class ReadLock {}
+ private final Object readLock = new ReadLock();
- private final Object writeLock = new Object();
+ private static class WriteLock {}
+ private final Object writeLock = new WriteLock();
// used to store the trafficClass value which is simply returned
// as the value that was set. We also need it to pass it to methods
// that specify an address packets are going to be sent to
private int trafficClass = 0;
- // -------------------------------------------------------------------
- // Constructor
- // -------------------------------------------------------------------
-
/*
* Constructor
*/
@@ -120,16 +108,13 @@
/*
* for native call
*/
- private DatagramChannelImpl(){
+ @SuppressWarnings("unused")
+ private DatagramChannelImpl() {
super(SelectorProvider.provider());
fd = new FileDescriptor();
connectAddress = new InetSocketAddress(0);
}
- // -------------------------------------------------------------------
- // Methods for getting internal DatagramSocket.
- // -------------------------------------------------------------------
-
/*
* Getting the internal DatagramSocket If we have not the socket, we create
* a new one.
@@ -137,8 +122,8 @@
@Override
synchronized public DatagramSocket socket() {
if (null == socket) {
- socket = new DatagramSocketAdapter(SocketImplProvider
- .getDatagramSocketImpl(fd, localPort), this);
+ socket = new DatagramSocketAdapter(
+ new PlainDatagramSocketImpl(fd, localPort), this);
}
return socket;
}
@@ -155,12 +140,7 @@
.preferIPv6Addresses());
}
- // -------------------------------------------------------------------
- // Methods for connect and disconnect
- // -------------------------------------------------------------------
-
- /*
- *
+ /**
* @see java.nio.channels.DatagramChannel#isConnected()
*/
@Override
@@ -168,8 +148,7 @@
return connected;
}
- /*
- *
+ /**
* @see java.nio.channels.DatagramChannel#connect(java.net.SocketAddress)
*/
@Override
@@ -214,8 +193,7 @@
return this;
}
- /*
- *
+ /**
* @see java.nio.channels.DatagramChannel#disconnect()
*/
@Override
@@ -232,12 +210,7 @@
return this;
}
- // -------------------------------------------------------------------
- // Methods for send and receive
- // -------------------------------------------------------------------
-
- /*
- *
+ /**
* @see java.nio.channels.DatagramChannel#receive(java.nio.ByteBuffer)
*/
@Override
@@ -284,14 +257,15 @@
.position()
+ target.arrayOffset(), target.remaining());
} else {
- receivePacket = new DatagramPacket(new byte[target.remaining()], target.remaining());
+ receivePacket = new DatagramPacket(new byte[target.remaining()],
+ target.remaining());
}
do {
if (isConnected()) {
- received = networkSystem.recvConnectedDatagram(fd, receivePacket,
- receivePacket.getData(), receivePacket.getOffset(),
- receivePacket.getLength(), isBlocking() ? 0
- : DEFAULT_TIMEOUT, false);
+ received = networkSystem.recvConnectedDatagram(fd,
+ receivePacket, receivePacket.getData(), receivePacket
+ .getOffset(), receivePacket.getLength(),
+ isBlocking() ? 0 : DEFAULT_TIMEOUT, false);
} else {
received = networkSystem.receiveDatagram(fd, receivePacket,
receivePacket.getData(), receivePacket.getOffset(),
@@ -327,24 +301,23 @@
return retAddr;
}
- private SocketAddress receiveDirectImpl(ByteBuffer target, boolean loop) throws IOException
- {
- SocketAddress retAddr = null;
- DatagramPacket receivePacket = new DatagramPacket(
- stubArray, 0);
+ private SocketAddress receiveDirectImpl(ByteBuffer target, boolean loop)
+ throws IOException {
+ SocketAddress retAddr = null;
+ DatagramPacket receivePacket = new DatagramPacket(stubArray, 0);
int oldposition = target.position();
int received = 0;
do {
int address = AddressUtil.getDirectBufferAddress(target);
if (isConnected()) {
- received = networkSystem.recvConnectedDatagramDirect(fd, receivePacket,
- address, target.position(),
- target.remaining(), isBlocking() ? 0
+ received = networkSystem.recvConnectedDatagramDirect(fd,
+ receivePacket, address, target.position(), target
+ .remaining(), isBlocking() ? 0
: DEFAULT_TIMEOUT, false);
} else {
- received = networkSystem.receiveDatagramDirect(fd, receivePacket,
- address, target.position(),
- target.remaining(), isBlocking() ? 0
+ received = networkSystem.receiveDatagramDirect(fd,
+ receivePacket, address, target.position(), target
+ .remaining(), isBlocking() ? 0
: DEFAULT_TIMEOUT, false);
}
@@ -352,15 +325,14 @@
SecurityManager sm = System.getSecurityManager();
if (!isConnected() && null != sm) {
try {
- sm.checkAccept(receivePacket.getAddress()
- .getHostAddress(), receivePacket.getPort());
+ sm.checkAccept(receivePacket.getAddress().getHostAddress(),
+ receivePacket.getPort());
} catch (SecurityException e) {
// do discard the datagram packet
receivePacket = null;
}
}
- if (null != receivePacket
- && null != receivePacket.getAddress()) {
+ if (null != receivePacket && null != receivePacket.getAddress()) {
// copy the data of received packet
if (received > 0) {
target.position(oldposition + received);
@@ -372,7 +344,7 @@
return retAddr;
}
- /*
+ /**
* @see java.nio.channels.DatagramChannel#send(java.nio.ByteBuffer,
* java.net.SocketAddress)
*/
@@ -445,12 +417,7 @@
}
}
- // -------------------------------------------------------------------
- // Methods for read and write.
- // -------------------------------------------------------------------
-
- /*
- *
+ /**
* @see java.nio.channels.DatagramChannel#read(java.nio.ByteBuffer)
*/
@Override
@@ -467,10 +434,10 @@
return 0;
}
- int readCount = 0;
+ int readCount = 0;
if (target.isDirect() || target.hasArray()) {
readCount = readImpl(target);
- if(readCount > 0){
+ if (readCount > 0) {
target.position(target.position() + readCount);
}
@@ -478,15 +445,14 @@
byte[] readArray = new byte[target.remaining()];
ByteBuffer readBuffer = ByteBuffer.wrap(readArray);
readCount = readImpl(readBuffer);
- if(readCount > 0){
+ if (readCount > 0) {
target.put(readArray, 0, readCount);
}
}
return readCount;
}
- /*
- *
+ /**
* @see java.nio.channels.DatagramChannel#read(java.nio.ByteBuffer[], int,
* int)
*/
@@ -530,7 +496,7 @@
* read from channel, and store the result in the target.
*/
private int readImpl(ByteBuffer readBuffer) throws IOException {
- synchronized(readLock){
+ synchronized (readLock) {
int readCount = 0;
try {
begin();
@@ -542,8 +508,9 @@
if (readBuffer.isDirect()) {
int address = AddressUtil.getDirectBufferAddress(readBuffer);
if (isConnected()) {
- readCount = networkSystem.recvConnectedDatagramDirect(fd,
- null, address, start, length, timeout, false);
+ readCount = networkSystem.recvConnectedDatagramDirect(
+ fd, null, address, start, length, timeout,
+ false);
} else {
readCount = networkSystem.receiveDatagramDirect(fd,
null, address, start, length, timeout, false);
@@ -553,11 +520,11 @@
byte[] target = readBuffer.array();
start += readBuffer.arrayOffset();
if (isConnected()) {
- readCount = networkSystem.recvConnectedDatagram(fd, null,
- target, start, length, timeout, false);
+ readCount = networkSystem.recvConnectedDatagram(fd,
+ null, target, start, length, timeout, false);
} else {
- readCount = networkSystem.receiveDatagram(fd, null, target,
- start, length, timeout, false);
+ readCount = networkSystem.receiveDatagram(fd, null,
+ target, start, length, timeout, false);
}
}
return readCount;
@@ -570,7 +537,7 @@
}
}
- /*
+ /**
* @see java.nio.channels.DatagramChannel#write(java.nio.ByteBuffer)
*/
@Override
@@ -602,7 +569,7 @@
return result;
}
- /*
+ /**
* @see java.nio.channels.DatagramChannel#write(java.nio.ByteBuffer[], int,
* int)
*/
@@ -621,7 +588,7 @@
return 0;
}
ByteBuffer writeBuf = ByteBuffer.allocate(count);
- for (int val = offset; val < length+offset; val++) {
+ for (int val = offset; val < length + offset; val++) {
ByteBuffer source = sources[val];
int oldPosition = source.position();
writeBuf.put(source);
@@ -642,10 +609,10 @@
}
/*
- * write the source. return the count of bytes written.
+ * Write the source. Return the count of bytes written.
*/
private int writeImpl(ByteBuffer buf) throws IOException {
- synchronized(writeLock){
+ synchronized (writeLock) {
int result = 0;
try {
begin();
@@ -654,13 +621,13 @@
if (buf.isDirect()) {
int address = AddressUtil.getDirectBufferAddress(buf);
- result = networkSystem.sendConnectedDatagramDirect(fd, address,
- start, length, isBound);
+ result = networkSystem.sendConnectedDatagramDirect(fd,
+ address, start, length, isBound);
} else {
// buf is assured to have array.
start += buf.arrayOffset();
- result = networkSystem.sendConnectedDatagram(fd, buf.array(),
- start, length, isBound);
+ result = networkSystem.sendConnectedDatagram(fd, buf
+ .array(), start, length, isBound);
}
return result;
} catch (SocketException e) {
@@ -677,12 +644,8 @@
}
}
- // -------------------------------------------------------------------
- // Protected Inherited methods
- // -------------------------------------------------------------------
-
/*
- * do really closing action here
+ * Do really closing action here.
*/
@Override
synchronized protected void implCloseSelectableChannel() throws IOException {
@@ -694,8 +657,7 @@
}
}
- /*
- *
+ /**
* @see java.nio.channels.spi.AbstractSelectableChannel#implConfigureBlocking(boolean)
*/
@Override
@@ -707,12 +669,8 @@
// decided by isBlocking() method.
}
- // -------------------------------------------------------------------
- // Share methods for checking.
- // -------------------------------------------------------------------
-
/*
- * status check, must be open.
+ * Status check, must be open.
*/
private void checkOpen() throws IOException {
if (!isOpen()) {
@@ -721,7 +679,7 @@
}
/*
- * status check, must be open and connected, for read and write.
+ * Status check, must be open and connected, for read and write.
*/
private void checkOpenConnected() throws IOException {
checkOpen();
@@ -731,7 +689,7 @@
}
/*
- * buffer check, must not null
+ * Buffer check, must not null
*/
private void checkNotNull(ByteBuffer source) {
if (null == source) {
@@ -740,7 +698,7 @@
}
/*
- * buffer check, must not null and not read only buffer, for read and
+ * Buffer check, must not null and not read only buffer, for read and
* receive.
*/
private void checkWritable(ByteBuffer target) {
@@ -750,12 +708,8 @@
}
}
- // -------------------------------------------------------------------
- // Adapter classes for internal socket.
- // -------------------------------------------------------------------
-
/*
- * get the fd for internal use.
+ * Get the fd for internal use.
*/
public FileDescriptor getFD() {
return fd;
@@ -781,7 +735,7 @@
private DatagramChannelImpl channelImpl;
/*
- * init the datagramSocketImpl and datagramChannelImpl
+ * Constructor initialize the datagramSocketImpl and datagramChannelImpl
*/
DatagramSocketAdapter(DatagramSocketImpl socketimpl,
DatagramChannelImpl channelImpl) {
@@ -790,14 +744,14 @@
}
/*
- * get the internal datagramChannelImpl
+ * Get the internal datagramChannelImpl
*/
@Override
public DatagramChannel getChannel() {
return channelImpl;
}
- /*
+ /**
* @see java.net.DatagramSocket#isBound()
*/
@Override
@@ -805,7 +759,7 @@
return channelImpl.isBound;
}
- /*
+ /**
* @see java.net.DatagramSocket#isConnected()
*/
@Override
@@ -813,7 +767,7 @@
return channelImpl.isConnected();
}
- /*
+ /**
* @see java.net.DatagramSocket#getInetAddress()
*/
@Override
@@ -824,7 +778,7 @@
return channelImpl.connectAddress.getAddress();
}
- /*
+ /**
* @see java.net.DatagramSocket#getLocalAddress()
*/
@Override
@@ -832,7 +786,7 @@
return channelImpl.getLocalAddress();
}
- /*
+ /**
* @see java.net.DatagramSocket#getPort()
*/
@Override
@@ -843,7 +797,7 @@
return channelImpl.connectAddress.getPort();
}
- /*
+ /**
* @see java.net.DatagramSocket#bind(java.net.SocketAddress)
*/
@Override
@@ -855,7 +809,7 @@
channelImpl.isBound = true;
}
- /*
+ /**
* @see java.net.DatagramSocket#receive(java.net.DatagramPacket)
*/
@Override
@@ -866,7 +820,7 @@
super.receive(packet);
}
- /*
+ /**
* @see java.net.DatagramSocket#send(java.net.DatagramPacket)
*/
@Override
@@ -877,7 +831,7 @@
super.send(packet);
}
- /*
+ /**
* @see java.net.DatagramSocket#close()
*/
@Override
@@ -894,7 +848,7 @@
}
}
- /*
+ /**
* @see java.net.DatagramSocket#disconnect()
*/
@Override
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
index 3bc368f..dbef656 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
@@ -17,6 +17,10 @@
package org.apache.harmony.nio.internal;
+// BEGIN android-note
+// Copied from a newer version of Harmony.
+// END android-note
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.ServerSocket;
@@ -27,13 +31,12 @@
import java.nio.channels.ClosedChannelException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.NotYetBoundException;
-import java.nio.channels.SelectableChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import org.apache.harmony.luni.net.NetUtil;
-import org.apache.harmony.luni.net.SocketImplProvider;
+import org.apache.harmony.luni.net.PlainServerSocketImpl;
import org.apache.harmony.luni.platform.FileDescriptorHandler;
import org.apache.harmony.luni.platform.Platform;
@@ -43,10 +46,6 @@
public class ServerSocketChannelImpl extends ServerSocketChannel implements
FileDescriptorHandler {
- // ----------------------------------------------------
- // Class variables
- // ----------------------------------------------------
-
// status un-init, not initialized.
private static final int SERVER_STATUS_UNINIT = -1;
@@ -56,10 +55,6 @@
// status closed.
private static final int SERVER_STATUS_CLOSED = 1;
- // -------------------------------------------------------------------
- // Instance variables
- // -------------------------------------------------------------------
-
// The fd to interact with native code
private final FileDescriptor fd;
@@ -74,13 +69,9 @@
boolean isBound = false;
// lock for accept
- private class AcceptLock {}
+ private static class AcceptLock {}
private final Object acceptLock = new AcceptLock();
- // ----------------------------------------------------
- // Constructor
- // ----------------------------------------------------
-
/*
* Constructor
*/
@@ -88,26 +79,23 @@
super(sp);
status = SERVER_STATUS_OPEN;
fd = new FileDescriptor();
- Platform.getNetworkSystem().createServerStreamSocket(fd,
+ Platform.getNetworkSystem().createStreamSocket(fd,
NetUtil.preferIPv4Stack());
- impl = SocketImplProvider.getServerSocketImpl(fd);
+ impl = new PlainServerSocketImpl(fd);
socket = new ServerSocketAdapter(impl, this);
}
// for native call
+ @SuppressWarnings("unused")
private ServerSocketChannelImpl() throws IOException {
super(SelectorProvider.provider());
status = SERVER_STATUS_OPEN;
fd = new FileDescriptor();
- impl = SocketImplProvider.getServerSocketImpl(fd);
+ impl = new PlainServerSocketImpl(fd);
socket = new ServerSocketAdapter(impl, this);
isBound = false;
}
- // ----------------------------------------------------
- // Methods
- // ----------------------------------------------------
-
/*
* Getting the internal Socket If we have not the socket, we create a new
* one.
@@ -128,7 +116,7 @@
throw new NotYetBoundException();
}
- SocketChannel sockChannel = SocketChannel.open();
+ SocketChannel sockChannel = new SocketChannelImpl(SelectorProvider.provider(), false);
Socket socketGot = sockChannel.socket();
try {
@@ -168,10 +156,6 @@
return sockChannel;
}
- // -------------------------------------------------------------------
- // Protected inherited methods
- // -------------------------------------------------------------------
-
/*
* @see java.nio.channels.spi.AbstractSelectableChannel#implConfigureBlocking
*
@@ -202,10 +186,6 @@
return fd;
}
- // ----------------------------------------------------
- // Adapter classes.
- // ----------------------------------------------------
-
/*
* The adapter class of ServerSocket.
*/
@@ -264,10 +244,7 @@
synchronized (this) {
super.implAccept(aSocket);
sockChannel.setConnected();
- // BEGIN android-added
- // copied from a newer version of harmony
sockChannel.setBound(true);
- // END android-added
}
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
index 8e6c52f..1affb21 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/SocketChannelImpl.java
@@ -17,6 +17,11 @@
package org.apache.harmony.nio.internal;
+// BEGIN android-note
+// Copied from a newer version of Harmony.
+// In this class the address length was changed from long to int.
+// END android-note
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
@@ -42,25 +47,20 @@
import java.nio.channels.UnsupportedAddressTypeException;
import java.nio.channels.spi.SelectorProvider;
-import org.apache.harmony.luni.net.SocketImplProvider;
+import org.apache.harmony.luni.net.PlainSocketImpl;
import org.apache.harmony.luni.platform.FileDescriptorHandler;
import org.apache.harmony.luni.platform.INetworkSystem;
import org.apache.harmony.luni.platform.Platform;
import org.apache.harmony.luni.util.ErrorCodeException;
+import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.nio.AddressUtil;
import org.apache.harmony.nio.internal.nls.Messages;
/*
- *
* The default implementation class of java.nio.channels.SocketChannel.
- *
*/
class SocketChannelImpl extends SocketChannel implements FileDescriptorHandler {
- // -------------------------------------------------------------------
- // Class variables
- // -------------------------------------------------------------------
-
private static final int EOF = -1;
private static final int ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK = -211;
@@ -68,41 +68,37 @@
// The singleton to do the native network operation.
static final INetworkSystem networkSystem = Platform.getNetworkSystem();
- // status un-init, not initialized.
+ // Status un-init, not initialized.
static final int SOCKET_STATUS_UNINIT = EOF;
- // status before connect.
+ // Status before connect.
static final int SOCKET_STATUS_UNCONNECTED = 0;
- // status connection pending
+ // Status connection pending.
static final int SOCKET_STATUS_PENDING = 1;
- // status after connection success
+ // Status after connection success.
static final int SOCKET_STATUS_CONNECTED = 2;
- // status closed.
+ // Status closed.
static final int SOCKET_STATUS_CLOSED = 3;
- // timeout used for non-block mode.
+ // Timeout used for non-block mode.
private static final int TIMEOUT_NONBLOCK = 0;
- // timeout used for block mode.
+ // Timeout used for block mode.
private static final int TIMEOUT_BLOCK = EOF;
- // step used for connect
+ // Step used for connect.
private static final int HY_SOCK_STEP_START = 0;
- // step used for finishConnect
+ // Step used for finishConnect.
private static final int HY_PORT_SOCKET_STEP_CHECK = 1;
- // connect success
+ // Connect success.
private static final int CONNECT_SUCCESS = 0;
- // -------------------------------------------------------------------
- // Instance Variables
- // -------------------------------------------------------------------
-
- // The fd to interact with native code
+ // The descriptor to interact with native code.
FileDescriptor fd;
// Our internal Socket.
@@ -111,24 +107,23 @@
// The address to be connected.
InetSocketAddress connectAddress = null;
- // Local address of the this socket (package private for adapter)
+ // Local address of the this socket (package private for adapter).
InetAddress localAddress = null;
- // local port
+ // Local port number.
int localPort;
// At first, uninitialized.
int status = SOCKET_STATUS_UNINIT;
- // BEGIN android-changed
- // copied from a newer version of harmony
- // whether the socket is bound
+ // Whether the socket is bound.
volatile boolean isBound = false;
- // END adroid-changed
- private final Object readLock = new Object();
+ private static class ReadLock {}
+ private final Object readLock = new ReadLock();
- private final Object writeLock = new Object();
+ private static class WriteLock {}
+ private final Object writeLock = new WriteLock();
// BEGIN android-changed
// this content is a struct used in connect_withtimeout().
@@ -136,30 +131,37 @@
private byte[] connectContext = new byte[392];
// END android-changed
- // used to store the trafficClass value which is simply returned
+ // Used to store the trafficClass value which is simply returned
// as the value that was set. We also need it to pass it to methods
- // that specify an address packets are going to be sent to
+ // that specify an address packets are going to be sent to.
private int trafficClass = 0;
- // -------------------------------------------------------------------
- // Constructor
- // -------------------------------------------------------------------
-
/*
- * Constructor
+ * Constructor for creating a connected socket channel.
*/
public SocketChannelImpl(SelectorProvider selectorProvider)
throws IOException {
+ this(selectorProvider, true);
+ }
+
+ /*
+ * Constructor for creating an optionally connected socket channel.
+ */
+ public SocketChannelImpl(SelectorProvider selectorProvider, boolean connect)
+ throws IOException {
super(selectorProvider);
fd = new FileDescriptor();
status = SOCKET_STATUS_UNCONNECTED;
- networkSystem.createSocket(fd, true);
+ if (connect) {
+ networkSystem.createStreamSocket(fd, true);
+ }
}
/*
- * for native call
+ * For native call.
*/
- private SocketChannelImpl(){
+ @SuppressWarnings("unused")
+ private SocketChannelImpl() {
super(SelectorProvider.provider());
fd = new FileDescriptor();
connectAddress = new InetSocketAddress(0);
@@ -186,10 +188,6 @@
status = SOCKET_STATUS_UNCONNECTED;
}
- // -------------------------------------------------------------------
- // Methods for getting internal Socket.
- // -------------------------------------------------------------------
-
/*
* Getting the internal Socket If we have not the socket, we create a new
* one.
@@ -204,8 +202,8 @@
addr = connectAddress.getAddress();
port = connectAddress.getPort();
}
- socket = new SocketAdapter(SocketImplProvider.getSocketImpl(fd,
- localPort, addr, port), this);
+ socket = new SocketAdapter(
+ new PlainSocketImpl(fd, localPort, addr, port), this);
} catch (SocketException e) {
return null;
}
@@ -213,11 +211,7 @@
return socket;
}
- // -------------------------------------------------------------------
- // Methods for connect and finishConnect
- // -------------------------------------------------------------------
-
- /*
+ /**
* @see java.nio.channels.SocketChannel#isConnected()
*/
@Override
@@ -226,20 +220,17 @@
}
/*
- * status setting used by other class.
+ * Status setting used by other class.
*/
synchronized void setConnected() {
status = SOCKET_STATUS_CONNECTED;
}
- // BEGIN android-added
- // copied from a newer version of harmony
void setBound(boolean flag) {
isBound = flag;
}
- // END android-added
- /*
+ /**
* @see java.nio.channels.SocketChannel#isConnectionPending()
*/
@Override
@@ -247,7 +238,7 @@
return status == SOCKET_STATUS_PENDING;
}
- /*
+ /**
* @see java.nio.channels.SocketChannel#connect(java.net.SocketAddress)
*/
@Override
@@ -257,9 +248,15 @@
// check the address
InetSocketAddress inetSocketAddress = validateAddress(socketAddress);
+ InetAddress normalAddr = inetSocketAddress.getAddress();
+
+ // When connecting, map ANY address to Localhost
+ if (normalAddr.isAnyLocalAddress()) {
+ normalAddr = InetAddress.getLocalHost();
+ }
int port = inetSocketAddress.getPort();
- String hostName = inetSocketAddress.getAddress().getHostName();
+ String hostName = normalAddr.getHostName();
// security check
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
@@ -271,23 +268,12 @@
boolean finished = false;
try {
- if (!isBound) {
- // bind
- networkSystem.bind2(fd, 0, true, InetAddress
- .getByAddress(new byte[] { 0, 0, 0, 0 }));
- isBound = true;
- }
-
if (isBlocking()) {
begin();
- result = networkSystem.connect(fd, trafficClass,
- inetSocketAddress.getAddress(), inetSocketAddress
- .getPort());
-
+ result = networkSystem.connect(fd, trafficClass, normalAddr, port);
} else {
result = networkSystem.connectWithTimeout(fd, 0, trafficClass,
- inetSocketAddress.getAddress(), inetSocketAddress
- .getPort(), HY_SOCK_STEP_START, connectContext);
+ normalAddr, port, HY_SOCK_STEP_START, connectContext);
// set back to nonblocking to work around with a bug in portlib
if (!this.isBlocking()) {
networkSystem.setNonBlocking(fd, true);
@@ -328,7 +314,7 @@
return finished;
}
- /*
+ /**
* @see java.nio.channels.SocketChannel#finishConnect()
*/
@Override
@@ -372,14 +358,13 @@
synchronized (this) {
status = (finished ? SOCKET_STATUS_CONNECTED : status);
isBound = finished;
+ // TPE: Workaround for bug that turns socket back to blocking
+ if (!isBlocking()) implConfigureBlocking(false);
}
return finished;
}
- // -------------------------------------------------------------------
- // Methods for read and write
- // -------------------------------------------------------------------
- /*
+ /**
* @see java.nio.channels.SocketChannel#read(java.nio.ByteBuffer)
*/
@Override
@@ -411,7 +396,7 @@
return readCount;
}
- /*
+ /**
* @see java.nio.channels.SocketChannel#read(java.nio.ByteBuffer[], int,
* int)
*/
@@ -449,16 +434,17 @@
private boolean isIndexValid(ByteBuffer[] targets, int offset, int length) {
return (length >= 0) && (offset >= 0)
- && ((long)length + (long)offset <= targets.length);
+ && ((long) length + (long) offset <= targets.length);
}
- /*
- * read from channel, and store the result in the target.
+ /**
+ * Read from channel, and store the result in the target.
*
- * @param target output parameter
+ * @param target
+ * output parameter
*/
private int readImpl(ByteBuffer target) throws IOException {
- synchronized(readLock){
+ synchronized (readLock) {
int readCount = 0;
try {
if (isBlocking()) {
@@ -467,10 +453,13 @@
int offset = target.position();
int length = target.remaining();
if (target.isDirect()) {
+ // BEGIN android-changed
+ // changed address from long to int; split address and offset paramters
int address = AddressUtil.getDirectBufferAddress(target);
readCount = networkSystem.readDirect(fd, address, offset,
length, (isBlocking() ? TIMEOUT_BLOCK
: TIMEOUT_NONBLOCK));
+ // END android-changed
} else {
// target is assured to have array.
byte[] array = target.array();
@@ -487,8 +476,7 @@
}
}
- /*
- *
+ /**
* @see java.nio.channels.SocketChannel#write(java.nio.ByteBuffer)
*/
@Override
@@ -503,7 +491,7 @@
return writeImpl(source);
}
- /*
+ /**
* @see java.nio.channels.SocketChannel#write(java.nio.ByteBuffer[], int,
* int)
*/
@@ -520,7 +508,7 @@
return 0;
}
ByteBuffer writeBuf = ByteBuffer.allocate(count);
- for (int val = offset; val < length+offset; val++) {
+ for (int val = offset; val < length + offset; val++) {
ByteBuffer source = sources[val];
int oldPosition = source.position();
writeBuf.put(source);
@@ -550,10 +538,10 @@
}
/*
- * write the source. return the count of bytes written.
+ * Write the source. return the count of bytes written.
*/
private int writeImpl(ByteBuffer source) throws IOException {
- synchronized(writeLock){
+ synchronized (writeLock) {
if (!source.hasRemaining()) {
return 0;
}
@@ -565,9 +553,12 @@
begin();
}
if (source.isDirect()) {
+ // BEGIN android-changed
+ // changed address from long to int; split address and pos parameters
int address = AddressUtil.getDirectBufferAddress(source);
- writeCount = networkSystem
- .writeDirect(fd, address, pos, length);
+ writeCount = networkSystem.writeDirect(fd, address, pos,
+ length);
+ // END android-changed
} else if (source.hasArray()) {
pos += source.arrayOffset();
writeCount = networkSystem.write(fd, source.array(), pos,
@@ -595,12 +586,8 @@
}
}
- // -------------------------------------------------------------------
- // Shared methods
- // -------------------------------------------------------------------
-
/*
- * status check, open and "connected", when read and write.
+ * Status check, open and "connected", when read and write.
*/
synchronized private void checkOpenConnected()
throws ClosedChannelException {
@@ -613,7 +600,7 @@
}
/*
- * status check, open and "unconnected", before connection.
+ * Status check, open and "unconnected", before connection.
*/
synchronized private void checkUnconnected() throws IOException {
if (!isOpen()) {
@@ -628,7 +615,7 @@
}
/*
- * shared by this class and DatagramChannelImpl, to do the address transfer
+ * Shared by this class and DatagramChannelImpl, to do the address transfer
* and check.
*/
static InetSocketAddress validateAddress(SocketAddress socketAddress) {
@@ -646,7 +633,7 @@
}
/*
- * get local address
+ * Get local address.
*/
public InetAddress getLocalAddress() throws UnknownHostException {
byte[] any_bytes = { 0, 0, 0, 0 };
@@ -656,11 +643,8 @@
return localAddress;
}
- // -------------------------------------------------------------------
- // Protected inherited methods
- // -------------------------------------------------------------------
/*
- * do really closing action here
+ * Do really closing action here.
*/
@Override
synchronized protected void implCloseSelectableChannel() throws IOException {
@@ -674,7 +658,7 @@
}
}
- /*
+ /**
* @see java.nio.channels.spi.AbstractSelectableChannel#implConfigureBlocking(boolean)
*/
@Override
@@ -685,30 +669,21 @@
}
/*
- * get the fd
+ * Get the fd.
*/
public FileDescriptor getFD() {
return fd;
}
- // -------------------------------------------------------------------
- // Adapter classes for internal socket.
- // -------------------------------------------------------------------
-
+ /*
+ * Adapter classes for internal socket.
+ */
private static class SocketAdapter extends Socket {
- // ----------------------------------------------------
- // Class Variables
- // ----------------------------------------------------
-
SocketChannelImpl channel;
SocketImpl socketImpl;
- // ----------------------------------------------------
- // Methods
- // ----------------------------------------------------
-
SocketAdapter(SocketImpl socketimpl, SocketChannelImpl channel)
throws SocketException {
super(socketimpl);
@@ -716,8 +691,7 @@
this.channel = channel;
}
- /*
- *
+ /**
* @see java.net.Socket#getChannel()
*/
@Override
@@ -725,8 +699,7 @@
return channel;
}
- /*
- *
+ /**
* @see java.net.Socket#isBound()
*/
@Override
@@ -734,8 +707,7 @@
return channel.isBound;
}
- /*
- *
+ /**
* @see java.net.Socket#isConnected()
*/
@Override
@@ -743,8 +715,7 @@
return channel.isConnected();
}
- /*
- *
+ /**
* @see java.net.Socket#getLocalAddress()
*/
@Override
@@ -756,8 +727,7 @@
}
}
- /*
- *
+ /**
* @see java.net.Socket#connect(java.net.SocketAddress, int)
*/
@Override
@@ -778,8 +748,7 @@
}
}
- /*
- *
+ /**
* @see java.net.Socket#bind(java.net.SocketAddress)
*/
@Override
@@ -798,8 +767,7 @@
}
- /*
- *
+ /**
* @see java.net.Socket#close()
*/
@Override
@@ -849,8 +817,7 @@
.intValue();
}
- /*
- *
+ /**
* @see java.net.Socket#getKeepAlive()
*/
@Override
@@ -860,8 +827,7 @@
.booleanValue();
}
- /*
- *
+ /**
* @see java.net.Socket#getOOBInline()
*/
@Override
@@ -871,8 +837,7 @@
.booleanValue();
}
- /*
- *
+ /**
* @see java.net.Socket#getSoLinger()
*/
@Override
@@ -882,7 +847,7 @@
.intValue();
}
- /*
+ /**
* @see java.net.Socket#getTcpNoDelay()
*/
@Override
@@ -892,7 +857,82 @@
.booleanValue();
}
- /*
+ @Override
+ public void setKeepAlive(boolean value) throws SocketException {
+ checkOpen();
+ socketImpl.setOption(SocketOptions.SO_KEEPALIVE, value ? Boolean.TRUE
+ : Boolean.FALSE);
+ }
+
+ @Override
+ public void setOOBInline(boolean oobinline) throws SocketException {
+ checkOpen();
+ socketImpl.setOption(SocketOptions.SO_OOBINLINE, oobinline ? Boolean.TRUE
+ : Boolean.FALSE);
+ }
+
+ @Override
+ public synchronized void setReceiveBufferSize(int size)
+ throws SocketException {
+ checkOpen();
+ if (size < 1) {
+ throw new IllegalArgumentException(Msg.getString("K0035")); //$NON-NLS-1$
+ }
+ socketImpl
+ .setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
+ }
+
+ @Override
+ public void setReuseAddress(boolean reuse) throws SocketException {
+ checkOpen();
+ socketImpl.setOption(SocketOptions.SO_REUSEADDR, reuse ? Boolean.TRUE
+ : Boolean.FALSE);
+ }
+
+ @Override
+ public synchronized void setSendBufferSize(int size) throws SocketException {
+ checkOpen();
+ if (size < 1) {
+ throw new IllegalArgumentException(Msg.getString("K0035")); //$NON-NLS-1$
+ }
+ socketImpl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
+ }
+
+ @Override
+ public void setSoLinger(boolean on, int timeout) throws SocketException {
+ checkOpen();
+ if (on && timeout < 0) {
+ throw new IllegalArgumentException(Msg.getString("K0045")); //$NON-NLS-1$
+ }
+ int val = on ? (65535 < timeout ? 65535 : timeout) : -1;
+ socketImpl.setOption(SocketOptions.SO_LINGER, Integer.valueOf(val));
+ }
+
+ @Override
+ public synchronized void setSoTimeout(int timeout) throws SocketException {
+ checkOpen();
+ if (timeout < 0) {
+ throw new IllegalArgumentException(Msg.getString("K0036")); //$NON-NLS-1$
+ }
+ socketImpl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
+ }
+
+ @Override
+ public void setTcpNoDelay(boolean on) throws SocketException {
+ checkOpen();
+ socketImpl.setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
+ }
+
+ @Override
+ public void setTrafficClass(int value) throws SocketException {
+ checkOpen();
+ if (value < 0 || value > 255) {
+ throw new IllegalArgumentException();
+ }
+ socketImpl.setOption(SocketOptions.IP_TOS, Integer.valueOf(value));
+ }
+
+ /**
* @see java.net.Socket#getOutputStream()
*/
@Override
@@ -912,8 +952,7 @@
return new SocketChannelOutputStream(channel);
}
- /*
- *
+ /**
* @see java.net.Socket#getInputStream()
*/
@Override
@@ -934,7 +973,7 @@
}
/*
- * Checks whether the channel is open
+ * Checks whether the channel is open.
*/
private void checkOpen() throws SocketException {
if (isClosed()) {
@@ -944,7 +983,7 @@
}
/*
- * used for net and nio exchange
+ * Used for net and nio exchange.
*/
public SocketImpl getImpl() {
return socketImpl;
@@ -964,7 +1003,7 @@
}
/*
- * Closes this stream and channel
+ * Closes this stream and channel.
*
* @exception IOException thrown if an error occurs during the close
*/
@@ -973,7 +1012,7 @@
channel.close();
}
- /*
+ /**
* @see java.io.OutputStream#write(byte[], int, int)
*/
@Override
@@ -989,7 +1028,7 @@
channel.write(buf);
}
- /*
+ /**
* @see java.io.OutputStream#write(int)
*/
@Override
@@ -1023,7 +1062,7 @@
channel.close();
}
- /*
+ /**
* @see java.io.InputStream#read()
*/
@Override
@@ -1038,7 +1077,7 @@
// END android-changed
}
- /*
+ /**
* @see java.io.InputStream#read(byte[], int, int)
*/
@Override
diff --git a/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
index 6bcdaef..903c689 100644
--- a/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
+++ b/nio_char/src/test/java/tests/api/java/nio/charset/CharsetProviderTest.java
@@ -266,8 +266,6 @@
method = "charsetForName",
args = {String.class}
)
- @KnownFailure("Android throws Error in case of insufficient privileges, " +
- "RI throws SecurityException")
public void testIsSupported_InsufficientPrivilege() throws Exception {
SecurityManager oldMan = System.getSecurityManager();
System.setSecurityManager(new MockSecurityManager());
@@ -301,8 +299,6 @@
method = "charsetForName",
args = {String.class}
)
- @KnownFailure("Android throws Error in case of insufficient privileges, " +
- "RI throws SecurityException")
public void testForName_InsufficientPrivilege() throws Exception {
SecurityManager oldMan = System.getSecurityManager();
System.setSecurityManager(new MockSecurityManager());
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
index dc2ec2e..0c61e75 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/FilePreferencesImplTest.java
@@ -32,15 +32,25 @@
@TestTargetClass(java.util.prefs.Preferences.class)
public class FilePreferencesImplTest extends TestCase {
- public FilePreferencesImplTest() {
- super();
+ String oldUserHome = System.getProperty("user.home");
+ String oldJavaHome = System.getProperty("java.home");
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ System.setProperty("user.home", System.getProperty("java.io.tmpdir"));
+ System.setProperty("java.home", System.getProperty("java.io.tmpdir"));
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
}
-
- @Override
- protected void setUp(){
- }
- @Override
- protected void tearDown(){
+
+ protected void tearDown() throws Exception {
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
+ System.setProperty("user.home", oldUserHome);
+ System.setProperty("java.home", oldJavaHome);
+
+ super.tearDown();
}
@TestTargets({
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java
index 3260a04..eab3b14 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/NodeChangeEventTest.java
@@ -39,6 +39,27 @@
NodeChangeEvent event;
+ String oldUserHome = System.getProperty("user.home");
+ String oldJavaHome = System.getProperty("java.home");
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ System.setProperty("user.home", System.getProperty("java.io.tmpdir"));
+ System.setProperty("java.home", System.getProperty("java.io.tmpdir"));
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
+ }
+
+ protected void tearDown() throws Exception {
+ Preferences.systemRoot().clear();
+ Preferences.userRoot().clear();
+ System.setProperty("user.home", oldUserHome);
+ System.setProperty("java.home", oldJavaHome);
+
+ super.tearDown();
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
diff --git a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
index 9d526d6..0ebf6bb 100644
--- a/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
+++ b/prefs/src/test/java/org/apache/harmony/prefs/tests/java/util/prefs/PreferencesTest.java
@@ -45,8 +45,8 @@
@TestTargetClass(Preferences.class)
public class PreferencesTest extends TestCase {
- private String oldJavaHome;
- private String oldUserHome;
+ String oldUserHome = System.getProperty("user.home");
+ String oldJavaHome = System.getProperty("java.home");
MockSecurityManager manager = new MockSecurityManager();
@@ -81,6 +81,8 @@
.getBytes("UTF-8"));
stream = new MockInputStream(in);
+ System.setProperty("user.home", System.getProperty("java.io.tmpdir"));
+ System.setProperty("java.home", System.getProperty("java.io.tmpdir"));
Preferences.systemRoot().clear();
Preferences.userRoot().clear();
@@ -107,6 +109,8 @@
Preferences.systemRoot().clear();
Preferences.userRoot().clear();
+ System.setProperty("user.home", oldUserHome);
+ System.setProperty("java.home", oldJavaHome);
}
@TestTargetNew(
diff --git a/run-core-tests b/run-core-tests
index 62b3c51..70ab320 100755
--- a/run-core-tests
+++ b/run-core-tests
@@ -26,5 +26,5 @@
chmod 777 $tmp
exec dalvikvm -Duser.language=en -Duser.region=US -Djava.io.tmpdir=$tmp \
- -Xbootclasspath:$BOOTCLASSPATH:/system/framework/core-tests.jar \
+ -classpath /system/framework/core-tests.jar \
-Xmx64M com.google.coretests.Main "$@"