summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2009-08-10 18:43:30 -0700
committerJesse Wilson <jessewilson@google.com>2009-08-11 16:49:12 -0700
commita389b4a499f40379b0b204d7ba1c2057663d95c0 (patch)
tree616ccda43a8209b476e273b86fa533acafb3d33e
parent1d4289187a7179c14d0b336ff37e48dcf915c307 (diff)
downloadlibcore-a389b4a499f40379b0b204d7ba1c2057663d95c0.zip
libcore-a389b4a499f40379b0b204d7ba1c2057663d95c0.tar.gz
libcore-a389b4a499f40379b0b204d7ba1c2057663d95c0.tar.bz2
Update Luni to Harmony r802921.
Notable changes: - replaced StringBuffer with StringBuilder in several places - fixed a problem with BufferedInputStream's newline characters (EBCDIC) - cleanup Timer's finalizer helper object - new cache for the canonical path of a file - fixed concurrency issue with ArrayList - floating point parsing now trims length for very small numbers - encoding specified "UTF-8" when converting some byte[]s to strings (JarURLConnection, Util, OSFileSystem) - Harmony now implements floor and ceil in Java. We continue to use native code.
-rw-r--r--luni/src/main/java/java/io/BufferedReader.java38
-rw-r--r--luni/src/main/java/java/io/DataInputStream.java2
-rw-r--r--luni/src/main/java/java/io/File.java11
-rw-r--r--luni/src/main/java/java/io/PipedInputStream.java16
-rw-r--r--luni/src/main/java/java/io/PushbackInputStream.java6
-rw-r--r--luni/src/main/java/java/io/StreamTokenizer.java4
-rw-r--r--luni/src/main/java/java/lang/AbstractStringBuilder.java2
-rw-r--r--luni/src/main/java/java/lang/Math.java301
-rw-r--r--luni/src/main/java/java/lang/String.java183
-rw-r--r--luni/src/main/java/java/lang/reflect/Modifier.java4
-rw-r--r--luni/src/main/java/java/net/ServerSocket.java2
-rw-r--r--luni/src/main/java/java/net/SocketImpl.java2
-rw-r--r--luni/src/main/java/java/net/SocketPermission.java4
-rw-r--r--luni/src/main/java/java/net/URI.java16
-rw-r--r--luni/src/main/java/java/net/URIEncoderDecoder.java6
-rw-r--r--luni/src/main/java/java/net/URLClassLoader.java10
-rw-r--r--luni/src/main/java/java/net/URLConnection.java2
-rw-r--r--luni/src/main/java/java/net/URLEncoder.java2
-rw-r--r--luni/src/main/java/java/net/URLStreamHandler.java8
-rw-r--r--luni/src/main/java/java/util/AbstractList.java5
-rw-r--r--luni/src/main/java/java/util/ArrayList.java25
-rw-r--r--luni/src/main/java/java/util/BitSet.java2
-rw-r--r--luni/src/main/java/java/util/Calendar.java2
-rw-r--r--luni/src/main/java/java/util/Date.java2
-rw-r--r--luni/src/main/java/java/util/HashMap.java4
-rw-r--r--luni/src/main/java/java/util/Hashtable.java11
-rw-r--r--luni/src/main/java/java/util/IdentityHashMap.java12
-rw-r--r--luni/src/main/java/java/util/Locale.java2
-rw-r--r--luni/src/main/java/java/util/Properties.java6
-rw-r--r--luni/src/main/java/java/util/TimeZone.java2
-rw-r--r--luni/src/main/java/java/util/Timer.java122
-rw-r--r--luni/src/main/java/java/util/Vector.java2
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/internal/io/FileCanonPathCache.java136
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/ftp/FtpURLConnection.java2
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnection.java2
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/Handler.java2
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/jar/JarURLConnection.java6
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java57
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/platform/OSFileSystem.java10
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java4
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/util/ExternalMessages.properties1
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/util/FloatingPointParser.java527
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/util/Util.java438
-rw-r--r--luni/src/main/native/cbigint.c6
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java1
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileCanonPathCacheTest.java120
46 files changed, 1273 insertions, 855 deletions
diff --git a/luni/src/main/java/java/io/BufferedReader.java b/luni/src/main/java/java/io/BufferedReader.java
index 875840c..77f1975 100644
--- a/luni/src/main/java/java/io/BufferedReader.java
+++ b/luni/src/main/java/java/io/BufferedReader.java
@@ -30,13 +30,13 @@ import java.util.logging.Logger;
* 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(&quot;file.java&quot;));
* </pre>
- *
+ *
* @see BufferedWriter
* @since 1.1
*/
@@ -57,7 +57,7 @@ public class BufferedReader extends Reader {
/**
* Constructs a new BufferedReader on the Reader {@code in}. The
* buffer gets the default size (8 KB).
- *
+ *
* @param in
* the Reader that is buffered.
*/
@@ -85,7 +85,7 @@ public class BufferedReader extends Reader {
/**
* 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
@@ -106,7 +106,7 @@ public class BufferedReader extends Reader {
* 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.
*/
@@ -154,7 +154,7 @@ public class BufferedReader extends Reader {
/**
* Indicates whether or not this reader is closed.
- *
+ *
* @return {@code true} if this reader is closed, {@code false}
* otherwise.
*/
@@ -167,7 +167,7 @@ public class BufferedReader extends Reader {
* 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.
@@ -195,7 +195,7 @@ public class BufferedReader extends Reader {
/**
* 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()
@@ -240,7 +240,7 @@ public class BufferedReader extends Reader {
* 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
@@ -329,9 +329,8 @@ public class BufferedReader extends Reader {
* 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. In EBCDIC systems, a new line can also
- * be represented by the {@code &#92;u0085} (NEL) character.
- *
+ * not include the newline sequence.
+ *
* @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
@@ -351,7 +350,7 @@ public class BufferedReader extends Reader {
// BEGIN android-note
// a switch statement may be more efficient
// END android-note
- if ((ch > '\r') && (ch != '\u0085')) {
+ if (ch > '\r') {
continue;
}
if (ch == '\n') {
@@ -366,11 +365,6 @@ public class BufferedReader extends Reader {
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;
}
}
@@ -398,7 +392,7 @@ public class BufferedReader extends Reader {
// use a local variable for buf[charPos] and a switch statement
// END android-note
if (eol == '\0') {
- if ((buf[charPos] == '\n' || buf[charPos] == '\r') || (buf[charPos] == '\u0085')) {
+ if ((buf[charPos] == '\n' || buf[charPos] == '\r')) {
eol = buf[charPos];
}
} else if (eol == '\r' && (buf[charPos] == '\n')) {
@@ -407,7 +401,7 @@ public class BufferedReader extends Reader {
}
pos = charPos + 1;
return result.toString();
- } else if (eol != '\0') {
+ } else {
if (charPos > pos) {
result.append(buf, pos, charPos - pos - 1);
}
@@ -451,7 +445,7 @@ public class BufferedReader extends Reader {
* 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)
@@ -475,7 +469,7 @@ public class BufferedReader extends Reader {
* {@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.
diff --git a/luni/src/main/java/java/io/DataInputStream.java b/luni/src/main/java/java/io/DataInputStream.java
index 42e38a2..cb21986 100644
--- a/luni/src/main/java/java/io/DataInputStream.java
+++ b/luni/src/main/java/java/io/DataInputStream.java
@@ -303,7 +303,7 @@ public class DataInputStream extends FilterInputStream implements DataInput {
*/
@Deprecated
public final String readLine() throws IOException {
- StringBuffer line = new StringBuffer(80); // Typical line length
+ StringBuilder line = new StringBuilder(80); // Typical line length
boolean foundTerminator = false;
while (true) {
int nextByte = in.read();
diff --git a/luni/src/main/java/java/io/File.java b/luni/src/main/java/java/io/File.java
index e34ab18..c802995 100644
--- a/luni/src/main/java/java/io/File.java
+++ b/luni/src/main/java/java/io/File.java
@@ -25,6 +25,7 @@ import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
+import org.apache.harmony.luni.internal.io.FileCanonPathCache;
import org.apache.harmony.luni.util.DeleteOnExit;
import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.PriviAction;
@@ -495,6 +496,12 @@ public class File implements Serializable, Comparable<File> {
*/
public String getCanonicalPath() throws IOException {
byte[] result = properPath(false);
+ String absPath = Util.toUTF8String(result);
+ String canonPath = FileCanonPathCache.get(absPath);
+
+ if (canonPath != null) {
+ return canonPath;
+ }
if(separatorChar == '/') {
// resolve the full path first
result = resolveLink(result, result.length, false);
@@ -566,7 +573,9 @@ public class File implements Serializable, Comparable<File> {
newResult[newLength] = 0;
newResult = getCanonImpl(newResult);
newLength = newResult.length;
- return Util.toUTF8String(newResult, 0, newLength);
+ canonPath = Util.toUTF8String(newResult, 0, newLength);
+ FileCanonPathCache.put(absPath, canonPath);
+ return canonPath;
}
/*
diff --git a/luni/src/main/java/java/io/PipedInputStream.java b/luni/src/main/java/java/io/PipedInputStream.java
index d06143d..83987ec 100644
--- a/luni/src/main/java/java/io/PipedInputStream.java
+++ b/luni/src/main/java/java/io/PipedInputStream.java
@@ -150,11 +150,18 @@ public class PipedInputStream extends InputStream {
@Override
public synchronized int read() throws IOException {
if (!isConnected) {
+ // K0074=Not connected
throw new IOException(Msg.getString("K0074")); //$NON-NLS-1$
}
if (buffer == null) {
+ // K0075=InputStream is closed
throw new IOException(Msg.getString("K0075")); //$NON-NLS-1$
}
+
+ if (lastWriter != null && !lastWriter.isAlive() && (in < 0)) {
+ // KA030=Write end dead
+ throw new IOException(Msg.getString("KA030")); //$NON-NLS-1$
+ }
/**
* Set the last thread to be reading on this PipedInputStream. If
* lastReader dies while someone is waiting to write an IOException of
@@ -169,6 +176,7 @@ public class PipedInputStream extends InputStream {
return -1;
}
if ((attempts-- <= 0) && lastWriter != null && !lastWriter.isAlive()) {
+ // K0076=Pipe broken
throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
}
// Notify callers of receive()
@@ -244,13 +252,20 @@ public class PipedInputStream extends InputStream {
}
if (!isConnected) {
+ // K0074=Not connected
throw new IOException(Msg.getString("K0074")); //$NON-NLS-1$
}
if (buffer == null) {
+ // K0075=InputStream is closed
throw new IOException(Msg.getString("K0075")); //$NON-NLS-1$
}
+ if (lastWriter != null && !lastWriter.isAlive() && (in < 0)) {
+ // KA030=Write end dead
+ throw new IOException(Msg.getString("KA030")); //$NON-NLS-1$
+ }
+
/**
* Set the last thread to be reading on this PipedInputStream. If
* lastReader dies while someone is waiting to write an IOException of
@@ -265,6 +280,7 @@ public class PipedInputStream extends InputStream {
return -1;
}
if ((attempts-- <= 0) && lastWriter != null && !lastWriter.isAlive()) {
+ // K0076=Pipe broken
throw new IOException(Msg.getString("K0076")); //$NON-NLS-1$
}
// Notify callers of receive()
diff --git a/luni/src/main/java/java/io/PushbackInputStream.java b/luni/src/main/java/java/io/PushbackInputStream.java
index 1784012..4600fa2 100644
--- a/luni/src/main/java/java/io/PushbackInputStream.java
+++ b/luni/src/main/java/java/io/PushbackInputStream.java
@@ -314,9 +314,11 @@ public class PushbackInputStream extends FilterInputStream {
}
// END android-changed
- for (int i = offset + length - 1; i >= offset; i--) {
- unread(buffer[i]);
+ if (buf == null) {
+ throw new IOException();
}
+ System.arraycopy(buffer, offset, buf, pos - length, length);
+ pos = pos - length;
}
/**
diff --git a/luni/src/main/java/java/io/StreamTokenizer.java b/luni/src/main/java/java/io/StreamTokenizer.java
index d39e5a8..c87a053 100644
--- a/luni/src/main/java/java/io/StreamTokenizer.java
+++ b/luni/src/main/java/java/io/StreamTokenizer.java
@@ -336,7 +336,7 @@ public class StreamTokenizer {
}
// Check for words
if ((currentType & TOKEN_WORD) != 0) {
- StringBuffer word = new StringBuffer(20);
+ StringBuilder word = new StringBuilder(20);
while (true) {
word.append((char) currentChar);
currentChar = read();
@@ -353,7 +353,7 @@ public class StreamTokenizer {
// Check for quoted character
if (currentType == TOKEN_QUOTE) {
int matchQuote = currentChar;
- StringBuffer quoteString = new StringBuffer();
+ StringBuilder quoteString = new StringBuilder();
int peekOne = read();
while (peekOne >= 0 && peekOne != matchQuote && peekOne != '\r'
&& peekOne != '\n') {
diff --git a/luni/src/main/java/java/lang/AbstractStringBuilder.java b/luni/src/main/java/java/lang/AbstractStringBuilder.java
index 06f8c50..c481e11 100644
--- a/luni/src/main/java/java/lang/AbstractStringBuilder.java
+++ b/luni/src/main/java/java/lang/AbstractStringBuilder.java
@@ -231,7 +231,7 @@ abstract class AbstractStringBuilder {
}
if (end > start) {
int length = count - end;
- if (length > 0) {
+ if (length >= 0) {
if (!shared) {
System.arraycopy(value, end, value, start, length);
} else {
diff --git a/luni/src/main/java/java/lang/Math.java b/luni/src/main/java/java/lang/Math.java
index 998856a..d06e6e4 100644
--- a/luni/src/main/java/java/lang/Math.java
+++ b/luni/src/main/java/java/lang/Math.java
@@ -17,7 +17,6 @@
package java.lang;
-
/**
* Class Math provides basic math constants and operations such as trigonometric
* functions, hyperbolic functions, exponential, logarithms, etc.
@@ -53,16 +52,16 @@ public final class Math {
* <li>{@code abs(-infinity) = +infinity}</li>
* <li>{@code abs(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose absolute value has to be computed.
* @return the absolute value of the argument.
*/
- 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.
@@ -74,45 +73,45 @@ public final class Math {
* <li>{@code abs(-infinity) = +infinity}</li>
* <li>{@code abs(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param f
* the value whose absolute value has to be computed.
* @return the argument if it is positive, otherwise the negation of the
* argument.
*/
- 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.
*/
- 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.
*/
- 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
@@ -125,12 +124,12 @@ public final class Math {
* <li>{@code acos((anything < -1) = NaN}</li>
* <li>{@code acos(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value to compute arc cosine of.
* @return the arc cosine of the argument.
*/
- 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
@@ -143,12 +142,12 @@ public final class Math {
* <li>{@code asin((anything < -1)) = NaN}</li>
* <li>{@code asin(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose arc sine has to be computed.
* @return the arc sine of the argument.
*/
- 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
@@ -163,7 +162,7 @@ public final class Math {
* <li>{@code atan(-infinity) = -pi/2}</li>
* <li>{@code atan(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose arc tangent has to be computed.
* @return the arc tangent of the argument.
@@ -171,10 +170,10 @@ public final class Math {
public static native double atan(double d);
/**
- * Returns the closest double approximation of the arc tangent of
- * {@code y/x} within the range {@code [-pi..pi]}. This is the angle of the
- * polar representation of the rectangular coordinates (x,y). The returned
- * result is within 2 ulps (units in the last place) of the real result.
+ * Returns the closest double approximation of the arc tangent of {@code
+ * y/x} within the range {@code [-pi..pi]}. This is the angle of the polar
+ * representation of the rectangular coordinates (x,y). The returned result
+ * is within 2 ulps (units in the last place) of the real result.
* <p>
* Special cases:
* <ul>
@@ -196,12 +195,12 @@ public final class Math {
* <li>{@code atan2(-infinity, +infinity ) = -pi/4}</li>
* <li>{@code atan2(+infinity, -infinity ) = +3pi/4}</li>
* <li>{@code atan2(-infinity, -infinity ) = -3pi/4}</li>
- * <li>{@code atan2(+infinity, (anything but,0, NaN, and infinity))}
- * {@code =} {@code +pi/2}</li>
- * <li>{@code atan2(-infinity, (anything but,0, NaN, and infinity))}
- * {@code =} {@code -pi/2}</li>
+ * <li>{@code atan2(+infinity, (anything but,0, NaN, and infinity))} {@code
+ * =} {@code +pi/2}</li>
+ * <li>{@code atan2(-infinity, (anything but,0, NaN, and infinity))} {@code
+ * =} {@code -pi/2}</li>
* </ul>
- *
+ *
* @param y
* the numerator of the value whose atan has to be computed.
* @param x
@@ -222,7 +221,7 @@ public final class Math {
* <li>{@code cbrt(-infinity) = -infinity}</li>
* <li>{@code cbrt(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose cube root has to be computed.
* @return the cube root of the argument.
@@ -230,8 +229,8 @@ public final class Math {
public static native double cbrt(double d);
/**
- * Returns the double conversion of the most negative (closest to
- * negative infinity) integer value which is greater than the argument.
+ * Returns the double conversion of the most negative (closest to negative
+ * infinity) integer value which is greater than the argument.
* <p>
* Special cases:
* <ul>
@@ -242,14 +241,16 @@ public final class Math {
* <li>{@code ceil(-infinity) = -infinity}</li>
* <li>{@code ceil(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose closest integer value has to be computed.
* @return the ceiling of the argument.
*/
+ // BEGIN android-changed
public static native double ceil(double d);
+ // END android-changed
- /**
+ /**
* 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.
@@ -260,7 +261,7 @@ public final class Math {
* <li>{@code cos(-infinity) = NaN}</li>
* <li>{@code cos(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the angle whose cosine has to be computed, in radians.
* @return the cosine of the argument.
@@ -278,7 +279,7 @@ public final class Math {
* <li>{@code cosh(-infinity) = +infinity}</li>
* <li>{@code cosh(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose hyperbolic cosine has to be computed.
* @return the hyperbolic cosine of the argument.
@@ -296,7 +297,7 @@ public final class Math {
* <li>{@code exp(-infinity) = +0.0}</li>
* <li>{@code exp(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose exponential has to be computed.
* @return the exponential of the argument.
@@ -304,9 +305,9 @@ public final class Math {
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
- * much more accurate to use {@code expm1(d)+1} than {@code exp(d)} (due to
+ * 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 much more
+ * accurate to use {@code expm1(d)+1} than {@code exp(d)} (due to
* cancellation of significant digits). The returned result is within 1 ulp
* (unit in the last place) of the real result.
* <p>
@@ -321,12 +322,12 @@ public final class Math {
* <li>{@code expm1(-infinity) = -1.0}</li>
* <li>{@code expm1(NaN) = NaN}</li>
* </ul>
- *
+ *
* @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.
+ * 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.
*/
public static native double expm1(double d);
@@ -342,19 +343,21 @@ public final class Math {
* <li>{@code floor(-infinity) = -infinity}</li>
* <li>{@code floor(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose closest integer value has to be computed.
* @return the floor of the argument.
*/
+ // BEGIN android-changed
public static native double floor(double d);
+ // END android-changed
/**
- * 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. If one parameter remains
- * constant, the result should be semi-monotonic.
+ * 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. If one parameter remains constant,
+ * the result should be semi-monotonic.
* <p>
* Special cases:
* <ul>
@@ -364,7 +367,7 @@ public final class Math {
* <li>{@code hypot((anything including NaN), -infinity) = +infinity}</li>
* <li>{@code hypot(NaN, NaN) = NaN}</li>
* </ul>
- *
+ *
* @param x
* a double number.
* @param y
@@ -393,7 +396,7 @@ public final class Math {
* <li>{@code IEEEremainder(x, -infinity) = x } where x is anything but
* +/-infinity</li>
* </ul>
- *
+ *
* @param x
* the numerator of the operation.
* @param y
@@ -416,7 +419,7 @@ public final class Math {
* <li>{@code log(-infinity) = NaN}</li>
* <li>{@code log(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose log has to be computed.
* @return the natural logarithm of the argument.
@@ -437,7 +440,7 @@ public final class Math {
* <li>{@code log10(-infinity) = NaN}</li>
* <li>{@code log10(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose base 10 log has to be computed.
* @return the natural logarithm of the argument.
@@ -461,7 +464,7 @@ public final class Math {
* <li>{@code log1p(-infinity) = NaN}</li>
* <li>{@code log1p(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value to compute the {@code ln(1+d)} of.
* @return the natural logarithm of the sum of the argument and 1.
@@ -479,16 +482,14 @@ public final class Math {
* <li>{@code max(+0.0, -0.0) = +0.0}</li>
* <li>{@code max(-0.0, +0.0) = +0.0}</li>
* </ul>
- *
+ *
* @param d1
* the first argument.
* @param d2
* the second argument.
* @return the larger of {@code d1} and {@code d2}.
*/
- public static double max(double d1, double d2) {
- // BEGIN android-changed
- // copied from a newer version of Harmony
+ public static double max(double d1, double d2) {
if (d1 > d2) {
return d1;
}
@@ -505,8 +506,7 @@ public final class Math {
return d2;
}
return 0.0d;
- // END android-changed
- }
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
@@ -519,16 +519,14 @@ public final class Math {
* <li>{@code max(+0.0, -0.0) = +0.0}</li>
* <li>{@code max(-0.0, +0.0) = +0.0}</li>
* </ul>
- *
+ *
* @param f1
* the first argument.
* @param f2
* the second argument.
* @return the larger of {@code f1} and {@code f2}.
*/
- public static float max(float f1, float f2) {
- // BEGIN android-changed
- // copied from a newer version of Harmony
+ public static float max(float f1, float f2) {
if (f1 > f2) {
return f1;
}
@@ -545,36 +543,35 @@ public final class Math {
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}.
*/
- 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}.
*/
- 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
@@ -587,16 +584,14 @@ public final class Math {
* <li>{@code min(+0.0, -0.0) = -0.0}</li>
* <li>{@code min(-0.0, +0.0) = -0.0}</li>
* </ul>
- *
+ *
* @param d1
* the first argument.
* @param d2
* the second argument.
* @return the smaller of {@code d1} and {@code d2}.
*/
- public static double min(double d1, double d2) {
- // BEGIN android-changed
- // copied from a newer version of Harmony
+ public static double min(double d1, double d2) {
if (d1 > d2) {
return d2;
}
@@ -613,8 +608,7 @@ public final class Math {
return -0.0d;
}
return d2;
- // END android-changed
- }
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
@@ -627,16 +621,14 @@ public final class Math {
* <li>{@code min(+0.0, -0.0) = -0.0}</li>
* <li>{@code min(-0.0, +0.0) = -0.0}</li>
* </ul>
- *
+ *
* @param f1
* the first argument.
* @param f2
* the second argument.
* @return the smaller of {@code f1} and {@code f2}.
*/
- public static float min(float f1, float f2) {
- // BEGIN android-changed
- // copied from a newer version of Harmony
+ public static float min(float f1, float f2) {
if (f1 > f2) {
return f2;
}
@@ -653,40 +645,39 @@ public final class Math {
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}.
*/
- 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}.
*/
- 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
- * {@code x} to the power of {@code y}.
+ * Returns the closest double approximation of the result of raising {@code
+ * x} to the power of {@code y}.
* <p>
* Special cases:
* <ul>
@@ -710,11 +701,11 @@ public final class Math {
* <li>{@code pow(+infinity, (+anything except 0, NaN)) = +infinity}</li>
* <li>{@code pow(+infinity, (-anything except 0, NaN)) = +0.0}</li>
* <li>{@code pow(-infinity, (anything)) = -pow(0, (-anything))}</li>
- * <li>{@code pow((-anything), (integer))} {@code =}
- * {@code pow(-1,(integer))*pow(+anything,integer) }</li>
+ * <li>{@code pow((-anything), (integer))} {@code =} {@code
+ * pow(-1,(integer))*pow(+anything,integer) }</li>
* <li>{@code pow((-anything except 0 and inf), (non-integer)) = NAN}</li>
* </ul>
- *
+ *
* @param x
* the base of the operation.
* @param y
@@ -735,14 +726,16 @@ public final class Math {
* <li>{@code rint(-infinity) = -infinity}</li>
* <li>{@code rint(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value to be rounded.
* @return the closest integer to the argument (as a double).
*/
+ // BEGIN android-changed
public static native double rint(double d);
+ // END android-changed
- /**
+ /**
* Returns the result of rounding the argument to an integer. The result is
* equivalent to {@code (long) Math.floor(d+0.5)}.
* <p>
@@ -756,17 +749,18 @@ public final class Math {
* <li>{@code round(-infintiy) = Long.MIN_VALUE}</li>
* <li>{@code round(NaN) = +0.0}</li>
* </ul>
- *
+ *
* @param d
* the value to be rounded.
* @return the closest integer to the argument.
*/
- 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
@@ -782,17 +776,18 @@ public final class Math {
* <li>{@code round(-infintiy) = Integer.MIN_VALUE}</li>
* <li>{@code round(NaN) = +0.0}</li>
* </ul>
- *
+ *
* @param f
* the value to be rounded.
* @return the closest integer to the argument.
*/
- 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
@@ -808,7 +803,7 @@ public final class Math {
* <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.
@@ -831,7 +826,7 @@ public final class Math {
* <li>{@code signum(-infinity) = -1.0}</li>
* <li>{@code signum(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param f
* the value whose signum has to be computed.
* @return the value of the signum function.
@@ -853,7 +848,7 @@ public final class Math {
* <li>{@code sin(-infinity) = NaN}</li>
* <li>{@code sin(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the angle whose sin has to be computed, in radians.
* @return the sine of the argument.
@@ -873,7 +868,7 @@ public final class Math {
* <li>{@code sinh(-infinity) = -infinity}</li>
* <li>{@code sinh(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose hyperbolic sine has to be computed.
* @return the hyperbolic sine of the argument.
@@ -892,7 +887,7 @@ public final class Math {
* <li>{@code sqrt(+infinity) = +infinity}</li>
* <li>{@code sqrt(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose square root has to be computed.
* @return the square root of the argument.
@@ -912,7 +907,7 @@ public final class Math {
* <li>{@code tan(-infinity) = NaN}</li>
* <li>{@code tan(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the angle whose tangens has to be computed, in radians.
* @return the tangent of the argument.
@@ -934,7 +929,7 @@ public final class Math {
* <li>{@code tanh(-infinity) = -1.0}</li>
* <li>{@code tanh(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the value whose hyperbolic tangent has to be computed.
* @return the hyperbolic tangent of the argument.
@@ -944,15 +939,15 @@ public final class Math {
/**
* Returns a pseudo-random number between 0.0 (inclusive) and 1.0
* (exclusive).
- *
+ *
* @return a pseudo-random number.
*/
- 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
@@ -966,14 +961,14 @@ public final class Math {
* <li>{@code toRadians(-infinity) = -infinity}</li>
* <li>{@code toRadians(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param angdeg
* an angle in degrees.
* @return the radian measure of the angle.
*/
- 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
@@ -987,20 +982,20 @@ public final class Math {
* <li>{@code toDegrees(-infinity) = -infinity}</li>
* <li>{@code toDegrees(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param angrad
* an angle in radians.
* @return the degree measure of the angle.
*/
- 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},
- * {@code ulp(-x) == ulp(x)}.
+ * value next larger in magnitude. For non-NaN {@code x}, {@code ulp(-x) ==
+ * ulp(x)}.
* <p>
* Special cases:
* <ul>
@@ -1010,7 +1005,7 @@ public final class Math {
* <li>{@code ulp(-infintiy) = infinity}</li>
* <li>{@code ulp(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param d
* the floating-point value to compute ulp of.
* @return the size of a ulp of the argument.
@@ -1029,8 +1024,8 @@ public final class Math {
/**
* Returns the argument's ulp (unit in the last place). The size of a ulp of
* a float value is the positive distance between this value and the float
- * value next larger in magnitude. For non-NaN {@code x},
- * {@code ulp(-x) == ulp(x)}.
+ * value next larger in magnitude. For non-NaN {@code x}, {@code ulp(-x) ==
+ * ulp(x)}.
* <p>
* Special cases:
* <ul>
@@ -1040,7 +1035,7 @@ public final class Math {
* <li>{@code ulp(-infintiy) = infinity}</li>
* <li>{@code ulp(NaN) = NaN}</li>
* </ul>
- *
+ *
* @param f
* the floating-point value to compute ulp of.
* @return the size of a ulp of the argument.
@@ -1060,5 +1055,5 @@ public final class Math {
private native static double nextafter(double x, double y);
- private native static float nextafterf(float x, float y);
+ private native static float nextafterf(float x, float y);
}
diff --git a/luni/src/main/java/java/lang/String.java b/luni/src/main/java/java/lang/String.java
index 22f72cb..6d53357 100644
--- a/luni/src/main/java/java/lang/String.java
+++ b/luni/src/main/java/java/lang/String.java
@@ -77,7 +77,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Create a ConsolePrintStream on the specified OutputStream, usually
* System.out.
- *
+ *
* @param out
* the console OutputStream
*/
@@ -168,6 +168,9 @@ public final class String implements Serializable, Comparable<String>,
count = 0;
}
+ /*
+ * Private constructor used for JIT optimization.
+ */
@SuppressWarnings("unused")
private String(String s, char c) {
offset = 0;
@@ -182,7 +185,7 @@ public final class String implements Serializable, Comparable<String>,
* 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.
*/
@@ -193,7 +196,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -213,7 +216,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -288,7 +291,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Converts the byte array to a string using the specified encoding.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param start
@@ -457,7 +460,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Converts the byte array to a string using the specified encoding.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param encoding
@@ -475,7 +478,7 @@ public final class String implements Serializable, Comparable<String>,
* 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.
* @throws NullPointerException
@@ -489,7 +492,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -527,7 +530,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Creates a {@code String} that is a copy of the specified string.
- *
+ *
* @param string
* the string to copy.
*/
@@ -537,10 +540,51 @@ public final class String implements Serializable, Comparable<String>,
count = string.count;
}
+ /*
+ * Private constructor useful for JIT optimization.
+ */
+ @SuppressWarnings( { "unused", "nls" })
+ private String(String s1, String s2) {
+ if (s1 == null) {
+ s1 = "null";
+ }
+ if (s2 == null) {
+ s2 = "null";
+ }
+ count = s1.count + s2.count;
+ value = new char[count];
+ offset = 0;
+ System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
+ System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
+ }
+
+ /*
+ * Private constructor useful for JIT optimization.
+ */
+ @SuppressWarnings( { "unused", "nls" })
+ private String(String s1, String s2, String s3) {
+ if (s1 == null) {
+ s1 = "null";
+ }
+ if (s2 == null) {
+ s2 = "null";
+ }
+ if (s3 == null) {
+ s3 = "null";
+ }
+ count = s1.count + s2.count + s3.count;
+ value = new char[count];
+ offset = 0;
+ System.arraycopy(s1.value, s1.offset, value, 0, s1.count);
+ System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count);
+ System.arraycopy(s3.value, s3.offset, value, s1.count + s2.count,
+ s3.count);
+ }
+
/**
* Creates a {@code String} from the contents of the specified
* {@code StringBuffer}.
- *
+ *
* @param stringbuffer
* the buffer to get the contents from.
*/
@@ -594,7 +638,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Creates a {@code String} from the contents of the specified {@code
* StringBuilder}.
- *
+ *
* @param sb
* the {@code StringBuilder} to copy the contents from.
* @throws NullPointerException
@@ -630,7 +674,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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.
@@ -688,7 +732,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -721,7 +765,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -750,7 +794,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -771,7 +815,7 @@ public final class String implements Serializable, Comparable<String>,
* 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.
@@ -786,7 +830,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -829,7 +873,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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,
@@ -845,7 +889,7 @@ public final class String implements Serializable, Comparable<String>,
* 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,
@@ -885,7 +929,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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,
@@ -919,7 +963,7 @@ public final class String implements Serializable, Comparable<String>,
* 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.
*/
public byte[] getBytes() {
@@ -933,7 +977,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -967,7 +1011,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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.
@@ -1003,7 +1047,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -1065,7 +1109,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1092,7 +1136,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1124,7 +1168,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1169,7 +1213,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1219,17 +1263,16 @@ public final class String implements Serializable, Comparable<String>,
* 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.
*/
native public String intern();
-
/**
* 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
@@ -1253,7 +1296,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1284,7 +1327,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1301,7 +1344,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1345,7 +1388,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Returns the size of this string.
- *
+ *
* @return the number of characters in this string.
*/
public int length() {
@@ -1355,7 +1398,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -1400,7 +1443,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1451,7 +1494,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Copies this string replacing occurrences of the specified character with
* another character.
- *
+ *
* @param oldChar
* the character to replace.
* @param newChar
@@ -1485,12 +1528,12 @@ public final class String implements Serializable, Comparable<String>,
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
@@ -1530,7 +1573,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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,
@@ -1545,7 +1588,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -1561,7 +1604,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -1581,7 +1624,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Copies a range of characters into a new string.
- *
+ *
* @param start
* the offset of the first character.
* @param end
@@ -1605,7 +1648,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Copies the characters in this string to a character array.
- *
+ *
* @return a character array containing the characters of this string.
*/
public char[] toCharArray() {
@@ -1617,7 +1660,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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.
*/
@@ -1628,7 +1671,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -1672,7 +1715,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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.
*/
@@ -1746,7 +1789,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -1811,7 +1854,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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.
*/
@@ -1834,7 +1877,7 @@ public final class String implements Serializable, Comparable<String>,
* 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.
@@ -1849,7 +1892,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -1869,7 +1912,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Converts the specified character to its string representation.
- *
+ *
* @param value
* the character.
* @return the character converted to a string.
@@ -1887,7 +1930,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Converts the specified double to its string representation.
- *
+ *
* @param value
* the double.
* @return the double converted to a string.
@@ -1898,7 +1941,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Converts the specified float to its string representation.
- *
+ *
* @param value
* the float.
* @return the float converted to a string.
@@ -1909,7 +1952,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Converts the specified integer to its string representation.
- *
+ *
* @param value
* the integer.
* @return the integer converted to a string.
@@ -1920,7 +1963,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Converts the specified long to its string representation.
- *
+ *
* @param value
* the long.
* @return the long converted to a string.
@@ -1933,7 +1976,7 @@ public final class String implements Serializable, Comparable<String>,
* 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"}.
@@ -1946,7 +1989,7 @@ public final class String implements Serializable, Comparable<String>,
* 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.
@@ -1958,7 +2001,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -2008,7 +2051,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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}.
@@ -2026,7 +2069,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -2045,7 +2088,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -2065,7 +2108,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -2086,7 +2129,7 @@ public final class String implements Serializable, Comparable<String>,
* 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
@@ -2108,7 +2151,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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
@@ -2127,7 +2170,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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.
@@ -2148,7 +2191,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* 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.
@@ -2169,7 +2212,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Calculates the number of Unicode code points between {@code beginIndex}
* and {@code endIndex}.
- *
+ *
* @param beginIndex
* the inclusive beginning index of the subsequence.
* @param endIndex
@@ -2232,7 +2275,7 @@ public final class String implements Serializable, Comparable<String>,
/**
* Returns a formatted string, using the supplied format and arguments,
* using the default locale.
- *
+ *
* @param format
* a format string.
* @param args
diff --git a/luni/src/main/java/java/lang/reflect/Modifier.java b/luni/src/main/java/java/lang/reflect/Modifier.java
index 0f9dc98..9005647 100644
--- a/luni/src/main/java/java/lang/reflect/Modifier.java
+++ b/luni/src/main/java/java/lang/reflect/Modifier.java
@@ -279,9 +279,7 @@ public class Modifier {
*/
@SuppressWarnings("nls")
public static java.lang.String toString(int modifiers) {
- StringBuffer buf;
-
- buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
if (isPublic(modifiers)) {
buf.append("public ");
diff --git a/luni/src/main/java/java/net/ServerSocket.java b/luni/src/main/java/java/net/ServerSocket.java
index fc3ad10..99fad3f 100644
--- a/luni/src/main/java/java/net/ServerSocket.java
+++ b/luni/src/main/java/java/net/ServerSocket.java
@@ -336,7 +336,7 @@ public class ServerSocket {
*/
@Override
public String toString() {
- StringBuffer result = new StringBuffer(64);
+ StringBuilder result = new StringBuilder(64);
result.append("ServerSocket["); //$NON-NLS-1$
if (!isBound()) {
return result.append("unbound]").toString(); //$NON-NLS-1$
diff --git a/luni/src/main/java/java/net/SocketImpl.java b/luni/src/main/java/java/net/SocketImpl.java
index be13eca..6ac41cd 100644
--- a/luni/src/main/java/java/net/SocketImpl.java
+++ b/luni/src/main/java/java/net/SocketImpl.java
@@ -259,7 +259,7 @@ public abstract class SocketImpl implements SocketOptions {
@SuppressWarnings("nls")
@Override
public String toString() {
- return new StringBuffer(100).append("Socket[addr=").append(
+ return new StringBuilder(100).append("Socket[addr=").append(
getInetAddress()).append(",port=").append(port).append(
",localport=").append(getLocalPort()).append("]").toString();
}
diff --git a/luni/src/main/java/java/net/SocketPermission.java b/luni/src/main/java/java/net/SocketPermission.java
index 25cc43f..4353e2e 100644
--- a/luni/src/main/java/java/net/SocketPermission.java
+++ b/luni/src/main/java/java/net/SocketPermission.java
@@ -211,7 +211,7 @@ public final class SocketPermission extends Permission implements Serializable {
}
boolean parsing = true;
String action;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
int pos = 0, length = actions.length();
while (parsing) {
char c;
@@ -360,7 +360,7 @@ public final class SocketPermission extends Permission implements Serializable {
return actionNames[SP_RESOLVE]; // If none specified return the
}
// implied action resolve
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
if ((actionsMask & SP_CONNECT) == SP_CONNECT) {
sb.append(',');
sb.append(actionNames[SP_CONNECT]);
diff --git a/luni/src/main/java/java/net/URI.java b/luni/src/main/java/java/net/URI.java
index 7fd08a5..85c16eb 100644
--- a/luni/src/main/java/java/net/URI.java
+++ b/luni/src/main/java/java/net/URI.java
@@ -106,7 +106,7 @@ public final class URI implements Comparable<URI>, Serializable {
*/
public URI(String scheme, String ssp, String frag)
throws URISyntaxException {
- StringBuffer uri = new StringBuffer();
+ StringBuilder uri = new StringBuilder();
if (scheme != null) {
uri.append(scheme);
uri.append(':');
@@ -166,7 +166,7 @@ public final class URI implements Comparable<URI>, Serializable {
throw new URISyntaxException(path, Msg.getString("K0302")); //$NON-NLS-1$
}
- StringBuffer uri = new StringBuffer();
+ StringBuilder uri = new StringBuilder();
if (scheme != null) {
uri.append(scheme);
uri.append(':');
@@ -270,7 +270,7 @@ public final class URI implements Comparable<URI>, Serializable {
throw new URISyntaxException(path, Msg.getString("K0302")); //$NON-NLS-1$
}
- StringBuffer uri = new StringBuffer();
+ StringBuilder uri = new StringBuilder();
if (scheme != null) {
uri.append(scheme);
uri.append(':');
@@ -994,7 +994,7 @@ public final class URI implements Comparable<URI>, Serializable {
* converts the hex values following the '%' to lowercase
*/
private String convertHexToLowerCase(String s) {
- StringBuffer result = new StringBuffer(""); //$NON-NLS-1$
+ StringBuilder result = new StringBuilder(""); //$NON-NLS-1$
if (s.indexOf('%') == -1) {
return s;
}
@@ -1357,7 +1357,7 @@ public final class URI implements Comparable<URI>, Serializable {
}
// put the path back together
- StringBuffer newpath = new StringBuffer();
+ StringBuilder newpath = new StringBuilder();
if (path.startsWith("/")) { //$NON-NLS-1$
newpath.append('/');
}
@@ -1548,7 +1548,7 @@ public final class URI implements Comparable<URI>, Serializable {
*/
private void setSchemeSpecificPart() {
// ssp = [//authority][path][?query]
- StringBuffer ssp = new StringBuffer();
+ StringBuilder ssp = new StringBuilder();
if (authority != null) {
ssp.append("//" + authority); //$NON-NLS-1$
}
@@ -1631,7 +1631,7 @@ public final class URI implements Comparable<URI>, Serializable {
@Override
public String toString() {
if (string == null) {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
if (scheme != null) {
result.append(scheme);
result.append(':');
@@ -1670,7 +1670,7 @@ public final class URI implements Comparable<URI>, Serializable {
* and converts escaped octets to lowercase.
*/
private String getHashString() {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
if (scheme != null) {
result.append(scheme.toLowerCase());
result.append(':');
diff --git a/luni/src/main/java/java/net/URIEncoderDecoder.java b/luni/src/main/java/java/net/URIEncoderDecoder.java
index 4bf95ab..d2b0044 100644
--- a/luni/src/main/java/java/net/URIEncoderDecoder.java
+++ b/luni/src/main/java/java/net/URIEncoderDecoder.java
@@ -112,7 +112,7 @@ class URIEncoderDecoder {
*/
static String quoteIllegal(String s, String legal)
throws UnsupportedEncodingException {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if ((ch >= 'a' && ch <= 'z')
@@ -148,7 +148,7 @@ class URIEncoderDecoder {
* @return java.lang.String the converted string
*/
static String encodeOthers(String s) throws UnsupportedEncodingException {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch <= 127) {
@@ -183,7 +183,7 @@ class URIEncoderDecoder {
*/
static String decode(String s) throws UnsupportedEncodingException {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (int i = 0; i < s.length();) {
char c = s.charAt(i);
diff --git a/luni/src/main/java/java/net/URLClassLoader.java b/luni/src/main/java/java/net/URLClassLoader.java
index dd3c9bf..6dfa385 100644
--- a/luni/src/main/java/java/net/URLClassLoader.java
+++ b/luni/src/main/java/java/net/URLClassLoader.java
@@ -1184,9 +1184,9 @@ public class URLClassLoader extends SecureClassLoader {
String element = tokenizer.nextToken();
if (!element.equals("")) { //$NON-NLS-1$
try {
- URL newURL = new URL(protocol, host, port, file + element
- + "!/"); //$NON-NLS-1$
- addedURLs.add(newURL);
+ // Take absolute path case into consideration
+ URL url = new URL(new URL(file), element);
+ addedURLs.add(createSearchURL(url));
} catch (MalformedURLException e) {
// Nothing is added
}
@@ -1196,10 +1196,6 @@ public class URLClassLoader extends SecureClassLoader {
}
Class<?> findClassImpl(String className) {
- Class<?> loadedClass = findLoadedClass(className);
- if (null != loadedClass) {
- return loadedClass;
- }
String partialName = className.replace('.', '/');
final String classFileName = new StringBuilder(partialName).append(".class").toString(); //$NON-NLS-1$
String packageName = null;
diff --git a/luni/src/main/java/java/net/URLConnection.java b/luni/src/main/java/java/net/URLConnection.java
index b87b11a..573a2d2 100644
--- a/luni/src/main/java/java/net/URLConnection.java
+++ b/luni/src/main/java/java/net/URLConnection.java
@@ -758,7 +758,7 @@ public abstract class URLConnection {
* @return the string to be parsed
*/
private String parseTypeString(String typeString) {
- StringBuffer typeStringBuffer = new StringBuffer(typeString);
+ StringBuilder typeStringBuffer = new StringBuilder(typeString);
for (int i = 0; i < typeStringBuffer.length(); i++) {
// if non-alphanumeric, replace it with '_'
char c = typeStringBuffer.charAt(i);
diff --git a/luni/src/main/java/java/net/URLEncoder.java b/luni/src/main/java/java/net/URLEncoder.java
index 2c21aa6..b764cc7 100644
--- a/luni/src/main/java/java/net/URLEncoder.java
+++ b/luni/src/main/java/java/net/URLEncoder.java
@@ -49,7 +49,7 @@ public class URLEncoder {
*/
@Deprecated
public static String encode(String s) {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
diff --git a/luni/src/main/java/java/net/URLStreamHandler.java b/luni/src/main/java/java/net/URLStreamHandler.java
index f039b00..54e550b 100644
--- a/luni/src/main/java/java/net/URLStreamHandler.java
+++ b/luni/src/main/java/java/net/URLStreamHandler.java
@@ -305,8 +305,7 @@ public abstract class URLStreamHandler {
* @see URL#toExternalForm()
*/
protected String toExternalForm(URL url) {
- StringBuffer answer = new StringBuffer(url.getProtocol().length()
- + url.getFile().length() + 16);
+ StringBuilder answer = new StringBuilder();
answer.append(url.getProtocol());
answer.append(':');
String authority = url.getAuthority();
@@ -317,8 +316,9 @@ public abstract class URLStreamHandler {
String file = url.getFile();
String ref = url.getRef();
- // file is never null
- answer.append(file);
+ if (file != null) {
+ answer.append(file);
+ }
if (ref != null) {
answer.append('#');
answer.append(ref);
diff --git a/luni/src/main/java/java/util/AbstractList.java b/luni/src/main/java/java/util/AbstractList.java
index 899affd..8f1e79f 100644
--- a/luni/src/main/java/java/util/AbstractList.java
+++ b/luni/src/main/java/java/util/AbstractList.java
@@ -360,7 +360,10 @@ public abstract class AbstractList<E> extends AbstractCollection<E> implements
@Override
public int size() {
- return size;
+ if (modCount == fullList.modCount) {
+ return size;
+ }
+ throw new ConcurrentModificationException();
}
void sizeChanged(boolean increment) {
diff --git a/luni/src/main/java/java/util/ArrayList.java b/luni/src/main/java/java/util/ArrayList.java
index ade5d27..b8c7056 100644
--- a/luni/src/main/java/java/util/ArrayList.java
+++ b/luni/src/main/java/java/util/ArrayList.java
@@ -81,10 +81,11 @@ public class ArrayList<E> extends AbstractList<E> implements List<E>,
* the collection of elements to add.
*/
public ArrayList(Collection<? extends E> collection) {
- int size = collection.size();
firstIndex = 0;
+ Object[] objects = collection.toArray();
+ int size = objects.length;
array = newElementArray(size + (size / 10));
- collection.toArray(array);
+ System.arraycopy(objects, 0, array, 0, size);
lastIndex = size;
modCount = 1;
}
@@ -187,7 +188,12 @@ public class ArrayList<E> extends AbstractList<E> implements List<E>,
if (this == collection) {
collection = (ArrayList)clone();
}
- int growSize = collection.size();
+ Object[] dumparray = collection.toArray();
+ int growSize = dumparray.length;
+ if (growSize == 0) {
+ return false;
+ }
+
if (0 < location && location < size) {
if (array.length - size < growSize) {
growForInsert(location, growSize);
@@ -219,15 +225,10 @@ public class ArrayList<E> extends AbstractList<E> implements List<E>,
lastIndex += growSize;
}
- if (growSize > 0) {
- Object[] dumparray = new Object[growSize];
- collection.toArray(dumparray);
- System.arraycopy(dumparray, 0, this.array, location + firstIndex,
- growSize);
- modCount++;
- return true;
- }
- return false;
+ System.arraycopy(dumparray, 0, this.array, location + firstIndex,
+ growSize);
+ modCount++;
+ return true;
}
/**
diff --git a/luni/src/main/java/java/util/BitSet.java b/luni/src/main/java/java/util/BitSet.java
index d2d7c0a..4e01cbf 100644
--- a/luni/src/main/java/java/util/BitSet.java
+++ b/luni/src/main/java/java/util/BitSet.java
@@ -818,7 +818,7 @@ public class BitSet implements Serializable, Cloneable {
*/
@Override
public String toString() {
- StringBuffer sb = new StringBuffer(bits.length / 2);
+ StringBuilder sb = new StringBuilder(bits.length / 2);
int bitCount = 0;
sb.append('{');
boolean comma = false;
diff --git a/luni/src/main/java/java/util/Calendar.java b/luni/src/main/java/java/util/Calendar.java
index 088347d..0ac574c 100644
--- a/luni/src/main/java/java/util/Calendar.java
+++ b/luni/src/main/java/java/util/Calendar.java
@@ -1322,7 +1322,7 @@ public abstract class Calendar implements Serializable, Cloneable,
@Override
@SuppressWarnings("nls")
public String toString() {
- StringBuffer result = new StringBuffer(getClass().getName() + "[time="
+ StringBuilder result = new StringBuilder(getClass().getName() + "[time="
+ (isTimeSet ? String.valueOf(time) : "?")
+ ",areFieldsSet="
+ areFieldsSet
diff --git a/luni/src/main/java/java/util/Date.java b/luni/src/main/java/java/util/Date.java
index 7bd7261..80610d3 100644
--- a/luni/src/main/java/java/util/Date.java
+++ b/luni/src/main/java/java/util/Date.java
@@ -390,7 +390,7 @@ public class Date implements Serializable, Cloneable, Comparable<Date> {
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();
+ StringBuilder buffer = new StringBuilder();
while (offset <= length) {
char next = offset < length ? string.charAt(offset) : '\r';
diff --git a/luni/src/main/java/java/util/HashMap.java b/luni/src/main/java/java/util/HashMap.java
index 4ec7a1b..999063d 100644
--- a/luni/src/main/java/java/util/HashMap.java
+++ b/luni/src/main/java/java/util/HashMap.java
@@ -852,11 +852,11 @@ public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,
}
static boolean areEqualKeys(Object key1, Object key2) {
- return key1.equals(key2);
+ return (key1 == key2) || key1.equals(key2);
}
static boolean areEqualValues(Object value1, Object value2) {
- return value1.equals(value2);
+ return (value1 == value2) || value1.equals(value2);
}
diff --git a/luni/src/main/java/java/util/Hashtable.java b/luni/src/main/java/java/util/Hashtable.java
index f1c1f74..b23364d 100644
--- a/luni/src/main/java/java/util/Hashtable.java
+++ b/luni/src/main/java/java/util/Hashtable.java
@@ -547,10 +547,15 @@ public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>,
while (it.hasNext()) {
Map.Entry<K, V> entry = it.next();
Object key = entry.getKey();
+ if (key == this) {
+ continue;
+ }
Object value = entry.getValue();
- int hash = (key != this ? key.hashCode() : 0)
- ^ (value != this ? (value != null ? value.hashCode() : 0)
- : 0);
+ if (value == this) {
+ continue;
+ }
+ int hash = (key != null ? key.hashCode() : 0)
+ ^ (value != null ? value.hashCode() : 0);
result += hash;
}
return result;
diff --git a/luni/src/main/java/java/util/IdentityHashMap.java b/luni/src/main/java/java/util/IdentityHashMap.java
index 30330b5..053de1d 100644
--- a/luni/src/main/java/java/util/IdentityHashMap.java
+++ b/luni/src/main/java/java/util/IdentityHashMap.java
@@ -267,7 +267,10 @@ public class IdentityHashMap<K, V> extends AbstractMap<K, V> implements
}
private int computeElementArraySize() {
- return (int) (((long) threshold * 10000) / loadFactor) * 2;
+ int arraySize = (int) (((long) threshold * 10000) / loadFactor) * 2;
+ // ensure arraySize is positive, the above cast from long to int type
+ // leads to overflow and negative arraySize if threshold is too big
+ return arraySize < 0 ? -arraySize : arraySize;
}
/**
@@ -748,7 +751,12 @@ public class IdentityHashMap<K, V> extends AbstractMap<K, V> implements
@Override
public Object clone() {
try {
- return super.clone();
+ IdentityHashMap<K, V> cloneHashMap = (IdentityHashMap<K, V>) super
+ .clone();
+ cloneHashMap.elementData = newElementArray(elementData.length);
+ System.arraycopy(elementData, 0, cloneHashMap.elementData, 0,
+ elementData.length);
+ return cloneHashMap;
} catch (CloneNotSupportedException e) {
return null;
}
diff --git a/luni/src/main/java/java/util/Locale.java b/luni/src/main/java/java/util/Locale.java
index b4558aa..b1a1821 100644
--- a/luni/src/main/java/java/util/Locale.java
+++ b/luni/src/main/java/java/util/Locale.java
@@ -564,7 +564,7 @@ public final class Locale implements Cloneable, Serializable {
*/
public String getDisplayName(Locale locale) {
int count = 0;
- StringBuffer buffer = new StringBuffer();
+ StringBuilder buffer = new StringBuilder();
if (languageCode.length() > 0) {
buffer.append(getDisplayLanguage(locale));
count++;
diff --git a/luni/src/main/java/java/util/Properties.java b/luni/src/main/java/java/util/Properties.java
index b1fa938..79d7069 100644
--- a/luni/src/main/java/java/util/Properties.java
+++ b/luni/src/main/java/java/util/Properties.java
@@ -198,7 +198,7 @@ public class Properties extends Hashtable<Object, Object> {
if (out == null) {
throw new NullPointerException();
}
- StringBuffer buffer = new StringBuffer(80);
+ StringBuilder buffer = new StringBuilder(80);
Enumeration<?> keys = propertyNames();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
@@ -234,7 +234,7 @@ public class Properties extends Hashtable<Object, Object> {
if (writer == null) {
throw new NullPointerException();
}
- StringBuffer buffer = new StringBuffer(80);
+ StringBuilder buffer = new StringBuilder(80);
Enumeration<?> keys = propertyNames();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
@@ -392,7 +392,7 @@ public class Properties extends Hashtable<Object, Object> {
case '\r':
mode = NONE;
firstChar = true;
- if (offset > 0) {
+ if (offset > 0 || (offset == 0 && keyLength == 0)) {
if (keyLength == -1) {
keyLength = offset;
}
diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java
index b0bcc6b..b4878ca 100644
--- a/luni/src/main/java/java/util/TimeZone.java
+++ b/luni/src/main/java/java/util/TimeZone.java
@@ -446,7 +446,7 @@ public abstract class TimeZone implements Serializable, Cloneable {
}
private static String formatTimeZoneName(String name, int offset) {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
int index = offset, length = name.length();
buf.append(name.substring(0, offset));
diff --git a/luni/src/main/java/java/util/Timer.java b/luni/src/main/java/java/util/Timer.java
index 48970be..6090031 100644
--- a/luni/src/main/java/java/util/Timer.java
+++ b/luni/src/main/java/java/util/Timer.java
@@ -187,14 +187,10 @@ public class Timer {
/**
* Starts a new timer.
- *
- * @param isDaemon
+ *
+ * @param name thread's name
+ * @param isDaemon daemon thread or not
*/
- TimerImpl(boolean isDaemon) {
- this.setDaemon(isDaemon);
- this.start();
- }
-
TimerImpl(String name, boolean isDaemon) {
this.setName(name);
this.setDaemon(isDaemon);
@@ -324,72 +320,78 @@ public class Timer {
}
}
+
+ private static final class FinalizerHelper {
+ private final TimerImpl impl;
+
+ FinalizerHelper(TimerImpl impl) {
+ super();
+ this.impl = impl;
+ }
+
+ @Override
+ protected void finalize() {
+ synchronized (impl) {
+ impl.finished = true;
+ impl.notify();
+ }
+ }
+ }
+
+ private static long timerId;
+
+ private synchronized static long nextId() {
+ return timerId++;
+ }
/* This object will be used in synchronization purposes */
- private TimerImpl impl;
+ private final TimerImpl impl;
// Used to finalize thread
@SuppressWarnings("unused")
- 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.
- */
- 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}.
- */
- public Timer() {
- // BEGIN android-changed
- impl = new TimerImpl("java.util.Timer", false);
- // END android-changed
- finalizer = newFinalizer();
- }
+ private final FinalizerHelper finalizer;
/**
* 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.
+ * @param name the name of the {@code Timer}.
+ * @param isDaemon true if {@code Timer}'s thread should be a daemon thread.
+ * @throws NullPointerException is {@code name} is {@code null}
*/
public Timer(String name, boolean isDaemon) {
- impl = new TimerImpl(name, isDaemon);
- finalizer = newFinalizer();
+ super();
+ if (name == null){
+ throw new NullPointerException("name is null");
+ }
+ this.impl = new TimerImpl(name, isDaemon);
+ this.finalizer = new FinalizerHelper(impl);
}
-
+
/**
* Creates a new named {@code Timer} which does not run as a daemon thread.
*
- * @param name
- * the name of the Timer.
+ * @param name the name of the Timer.
+ * @throws NullPointerException is {@code name} is {@code null}
*/
public Timer(String name) {
- impl = new TimerImpl(name, false);
- finalizer = newFinalizer();
+ this(name, false);
+ }
+
+ /**
+ * 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.
+ */
+ public Timer(boolean isDaemon) {
+ this("Timer-" + Timer.nextId(), isDaemon);
}
- private Object newFinalizer() {
- return new Object() { // $NON-LOCK-1$
- @Override
- protected void finalize() {
- synchronized (impl) {
- impl.finished = true;
- impl.notify();
- }
- }
- };
+ /**
+ * Creates a new non-daemon {@code Timer}.
+ */
+ public Timer() {
+ this(false);
}
/**
@@ -443,7 +445,7 @@ public class Timer {
* @param task
* the task to schedule.
* @param delay
- * amount of time before execution.
+ * amount of time in milliseconds before execution.
* @throws IllegalArgumentException
* if {@code delay < 0}.
* @throws IllegalStateException
@@ -463,9 +465,9 @@ public class Timer {
* @param task
* the task to schedule.
* @param delay
- * amount of time before first execution.
+ * amount of time in milliseconds before first execution.
* @param period
- * amount of time between subsequent executions.
+ * amount of time in milliseconds between subsequent executions.
* @throws IllegalArgumentException
* if {@code delay < 0} or {@code period < 0}.
* @throws IllegalStateException
@@ -488,7 +490,7 @@ public class Timer {
* @param when
* time of first execution.
* @param period
- * amount of time between subsequent executions.
+ * amount of time in milliseconds between subsequent executions.
* @throws IllegalArgumentException
* if {@code when.getTime() < 0} or {@code period < 0}.
* @throws IllegalStateException
@@ -510,9 +512,9 @@ public class Timer {
* @param task
* the task to schedule.
* @param delay
- * amount of time before first execution.
+ * amount of time in milliseconds before first execution.
* @param period
- * amount of time between subsequent executions.
+ * amount of time in milliseconds between subsequent executions.
* @throws IllegalArgumentException
* if {@code delay < 0} or {@code period < 0}.
* @throws IllegalStateException
@@ -535,7 +537,7 @@ public class Timer {
* @param when
* time of first execution.
* @param period
- * amount of time between subsequent executions.
+ * amount of time in milliseconds between subsequent executions.
* @throws IllegalArgumentException
* if {@code when.getTime() < 0} or {@code period < 0}.
* @throws IllegalStateException
diff --git a/luni/src/main/java/java/util/Vector.java b/luni/src/main/java/java/util/Vector.java
index 8634c13..6a4060a 100644
--- a/luni/src/main/java/java/util/Vector.java
+++ b/luni/src/main/java/java/util/Vector.java
@@ -1009,7 +1009,7 @@ public class Vector<E> extends AbstractList<E> implements List<E>,
return "[]"; //$NON-NLS-1$
}
int length = elementCount - 1;
- StringBuffer buffer = new StringBuffer(elementCount * 16);
+ StringBuilder buffer = new StringBuilder(elementCount * 16);
buffer.append('[');
for (int i = 0; i < length; i++) {
if (elementData[i] == this) {
diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/io/FileCanonPathCache.java b/luni/src/main/java/org/apache/harmony/luni/internal/io/FileCanonPathCache.java
new file mode 100644
index 0000000..e3ea7b5
--- /dev/null
+++ b/luni/src/main/java/org/apache/harmony/luni/internal/io/FileCanonPathCache.java
@@ -0,0 +1,136 @@
+/*
+ * 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.io;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+/**
+ * A simple cache implementation for file's canonical path. The cache has fixed
+ * size <code> CACHE_SIZE </code> and cached elements would be expired. If
+ * <code>put<code> method is invoked when cache is full, the oldest element will be removed.
+ *
+ */
+public class FileCanonPathCache {
+
+ static private class CacheElement {
+ String canonicalPath;
+
+ long timestamp;
+
+ public CacheElement(String path) {
+ this.canonicalPath = path;
+ this.timestamp = System.currentTimeMillis();
+ }
+ }
+
+ /**
+ * Max elemnts could be hold in the cache.
+ */
+ public static final int CACHE_SIZE = 256;
+
+ private static HashMap<String, CacheElement> cache = new HashMap<String, CacheElement>(
+ CACHE_SIZE);
+
+ /**
+ * FIFO queue for tracking age of elements.
+ */
+ private static LinkedList<String> list = new LinkedList<String>();
+
+ private static Object lock = new Object();
+
+ /**
+ * Expired time.
+ */
+ private static long timeout = 600000;
+
+ /**
+ * Retrieve element from cache.
+ *
+ * @param path
+ * absolute path.
+ * @return canonical path of <code>path</code> if it's in cache.
+ *
+ */
+ public static String get(String path) {
+ CacheElement element = null;
+ synchronized (lock) {
+ element = cache.get(path);
+ }
+
+ if (element == null) {
+ return null;
+ }
+
+ long time = System.currentTimeMillis();
+ if (time - element.timestamp > timeout) {
+ // remove all elements older than this one
+ synchronized (lock) {
+ if (cache.get(path) != null) {
+ String oldest = null;
+ do {
+ oldest = list.removeFirst();
+ cache.remove(path);
+ } while (!path.equals(oldest));
+ }
+ }
+ return null;
+ }
+
+ return element.canonicalPath;
+ }
+
+ /**
+ * Put element to cache.
+ *
+ * @param path
+ * absolute path.
+ * @param canonicalPath
+ * the canonical path of <code>path</code>.
+ */
+ public static void put(String path, String canonicalPath) {
+ CacheElement element = new CacheElement(canonicalPath);
+ synchronized (lock) {
+ if (cache.size() >= CACHE_SIZE) {
+ // cache is full
+ String oldest = list.removeFirst();
+ cache.remove(oldest);
+ }
+ cache.put(path, element);
+ list.addLast(path);
+ }
+ }
+
+ /**
+ * Remove all elements from cache.
+ */
+ public static void clear() {
+ synchronized (lock) {
+ cache.clear();
+ list.clear();
+ }
+ }
+
+ public static long getTimeout() {
+ return timeout;
+ }
+
+ public static void setTimeout(long timeout) {
+ FileCanonPathCache.timeout = timeout;
+ }
+}
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 016d5a7..3c361bf 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
@@ -399,7 +399,7 @@ public class FtpURLConnection extends URLConnection {
* Read a line of text and return it for possible parsing
*/
private String readLine() throws IOException {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
int c;
while ((c = ctrlInput.read()) != '\n') {
sb.append((char) c);
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 505c6b2..104a981 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
@@ -1174,7 +1174,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
*/
String readln() throws IOException {
boolean lastCr = false;
- StringBuffer result = new StringBuffer(80);
+ StringBuilder result = new StringBuilder(80);
int c = is.read();
if (c < 0) {
return null;
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 d299913..4db9910 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
@@ -99,7 +99,7 @@ public class Handler extends URLStreamHandler {
*/
@Override
protected String toExternalForm(URL url) {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
sb.append("jar:"); //$NON-NLS-1$
sb.append(url.getFile());
String ref = url.getRef();
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 56c1f3c..34e7d07 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
@@ -138,9 +138,9 @@ public class JarURLConnection extends java.net.JarURLConnection {
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{
+ jar = new JarFile(new File(Util.decode(jarFileURL.getFile(), false,
+ "UTF-8")), true, ZipFile.OPEN_READ);
+ } else {
final InputStream is = jarFileURL.openConnection().getInputStream();
try {
jar = AccessController
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java
index b765c7d..6e8028a 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/IMemorySystem.java
@@ -30,10 +30,22 @@ import java.io.IOException;
*/
public interface IMemorySystem {
+ /**
+ * The constant representing read-only access to data in a memory map
+ * request.
+ */
public final int MMAP_READ_ONLY = 1;
+ /**
+ * The constant representing read-write access to data in a memory map
+ * request.
+ */
public final int MMAP_READ_WRITE = 2;
+ /**
+ * The constant representing copy-on-write access to data in a memory map
+ * request.
+ */
public final int MMAP_WRITE_COPY = 4;
/**
@@ -243,7 +255,17 @@ public interface IMemorySystem {
throws NullPointerException, IndexOutOfBoundsException;
// END android-added
- // Primitive get & set methods
+ /**
+ * Returns the value of a 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 address at which to get the byte value.
+ * @return the value of the byte.
+ */
public byte getByte(int address);
/**
@@ -275,6 +297,21 @@ public interface IMemorySystem {
*/
public short getShort(int address);
+ /**
+ * Gets the value of the signed two-byte integer stored in the given 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.
+ * @param endianness
+ * the required interpretation of the short endianness.
+ * @return the value of the two-byte integer as a Java <code>short</code>.
+ */
public short getShort(int address, Endianness endianness);
/**
@@ -474,17 +511,25 @@ public interface IMemorySystem {
public void setAddress(int address, int value);
/**
- * TODO: JavaDoc
- *
+ * Map file content into memory.
+ *
* @param fileDescriptor
+ * a handle to the file that is to be memory mapped.
* @param alignment
+ * the offset in the file where the mapping should begin.
* @param size
+ * the number of bytes that are requested to map.
* @param mapMode
- * @return
+ * the desired access mode as defined by one of the constants
+ * {@link IMemorySystem#MMAP_READ_ONLY},
+ * {@link IMemorySystem#MMAP_READ_WRITE},
+ * {@link IMemorySystem#MMAP_WRITE_COPY}
+ * @return the start address of the mapped memory area.
* @throws IOException
+ * if an exception occurs mapping the file into memory.
*/
- public int mmap(int fileDescriptor, long alignment, long size,
- int mapMode) throws IOException;
+ public int mmap(int fileDescriptor, long alignment, long size, int mapMode)
+ throws IOException;
/**
* TODO: JavaDoc
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 20cf7cb..08bdac6 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
@@ -24,6 +24,7 @@ package org.apache.harmony.luni.platform;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
/**
* This is the portable implementation of the file system interface.
@@ -239,7 +240,14 @@ class OSFileSystem implements IFileSystem {
}
int handler = openImpl(fileName, mode);
if (handler < 0) {
- throw new FileNotFoundException(new String(fileName));
+ try {
+ throw new FileNotFoundException(new String(fileName, "UTF-8"));
+ } catch (java.io.UnsupportedEncodingException e) {
+ // UTF-8 should always be supported, so throw an assertion
+ FileNotFoundException fnfe = new FileNotFoundException(new String(fileName));
+ e.initCause(fnfe);
+ throw new AssertionError(e);
+ }
}
return handler;
}
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 0c9ac8a..1ec6240 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
@@ -546,8 +546,8 @@ final class OSNetworkSystem implements INetworkSystem {
* 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.
+ * @return each element describes the corresponding state of the descriptor
+ * in the read and write arrays.
* @throws SocketException
*/
public int[] select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
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 c740ae9..280a8f5 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
@@ -325,3 +325,4 @@ 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}
+KA030=Write end dead
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 642d309..8734039 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
@@ -24,94 +24,94 @@ package org.apache.harmony.luni.util;
*/
public final class FloatingPointParser {
- private static final class StringExponentPair {
- String s;
-
- int e;
-
- boolean negative;
-
- StringExponentPair(String s, int e, boolean negative) {
- this.s = s;
- this.e = e;
- this.negative = negative;
- }
- }
-
- /**
- * Takes a String and an integer exponent. The String should hold a positive
- * integer value (or zero). The exponent will be used to calculate the
- * floating point number by taking the positive integer the String
- * represents and multiplying by 10 raised to the power of the of the
- * exponent. Returns the closest double value to the real number
- *
- * @param s
- * the String that will be parsed to a floating point
- * @param e
- * an int represent the 10 to part
- * @return the double closest to the real number
- *
- * @exception NumberFormatException
- * if the String doesn't represent a positive integer value
- */
- private static native double parseDblImpl(String s, int e);
-
- /**
- * Takes a String and an integer exponent. The String should hold a positive
- * integer value (or zero). The exponent will be used to calculate the
- * floating point number by taking the positive integer the String
- * represents and multiplying by 10 raised to the power of the of the
- * exponent. Returns the closest float value to the real number
- *
- * @param s
- * the String that will be parsed to a floating point
- * @param e
- * an int represent the 10 to part
- * @return the float closest to the real number
- *
- * @exception NumberFormatException
- * if the String doesn't represent a positive integer value
- */
- private static native float parseFltImpl(String s, int e);
-
- /**
- * Takes a String and does some initial parsing. Should return a
- * StringExponentPair containing a String with no leading or trailing white
- * space and trailing zeroes eliminated. The exponent of the
- * StringExponentPair will be used to calculate the floating point number by
- * taking the positive integer the String represents and multiplying by 10
- * raised to the power of the of the exponent.
- *
- * @param s
- * the String that will be parsed to a floating point
- * @param length
- * the length of s
- * @return a StringExponentPair with necessary values
- *
- * @exception NumberFormatException
- * if the String doesn't pass basic tests
- */
- private static StringExponentPair initialParse(String s, int length) {
- boolean negative = false;
- char c;
- int start, end, decimal;
- int e = 0;
-
- start = 0;
- if (length == 0)
- throw new NumberFormatException(s);
-
- c = s.charAt(length - 1);
- if (c == 'D' || c == 'd' || c == 'F' || c == 'f') {
- length--;
- if (length == 0)
- throw new NumberFormatException(s);
- }
-
- end = Math.max(s.indexOf('E'), s.indexOf('e'));
- if (end > -1) {
- if (end + 1 == length)
- throw new NumberFormatException(s);
+ private static final class StringExponentPair {
+ String s;
+
+ int e;
+
+ boolean negative;
+
+ StringExponentPair(String s, int e, boolean negative) {
+ this.s = s;
+ this.e = e;
+ this.negative = negative;
+ }
+ }
+
+ /**
+ * Takes a String and an integer exponent. The String should hold a positive
+ * integer value (or zero). The exponent will be used to calculate the
+ * floating point number by taking the positive integer the String
+ * represents and multiplying by 10 raised to the power of the of the
+ * exponent. Returns the closest double value to the real number
+ *
+ * @param s
+ * the String that will be parsed to a floating point
+ * @param e
+ * an int represent the 10 to part
+ * @return the double closest to the real number
+ *
+ * @exception NumberFormatException
+ * if the String doesn't represent a positive integer value
+ */
+ private static native double parseDblImpl(String s, int e);
+
+ /**
+ * Takes a String and an integer exponent. The String should hold a positive
+ * integer value (or zero). The exponent will be used to calculate the
+ * floating point number by taking the positive integer the String
+ * represents and multiplying by 10 raised to the power of the of the
+ * exponent. Returns the closest float value to the real number
+ *
+ * @param s
+ * the String that will be parsed to a floating point
+ * @param e
+ * an int represent the 10 to part
+ * @return the float closest to the real number
+ *
+ * @exception NumberFormatException
+ * if the String doesn't represent a positive integer value
+ */
+ private static native float parseFltImpl(String s, int e);
+
+ /**
+ * Takes a String and does some initial parsing. Should return a
+ * StringExponentPair containing a String with no leading or trailing white
+ * space and trailing zeroes eliminated. The exponent of the
+ * StringExponentPair will be used to calculate the floating point number by
+ * taking the positive integer the String represents and multiplying by 10
+ * raised to the power of the of the exponent.
+ *
+ * @param s
+ * the String that will be parsed to a floating point
+ * @param length
+ * the length of s
+ * @return a StringExponentPair with necessary values
+ *
+ * @exception NumberFormatException
+ * if the String doesn't pass basic tests
+ */
+ private static StringExponentPair initialParse(String s, int length) {
+ boolean negative = false;
+ char c;
+ int start, end, decimal;
+ int e = 0;
+
+ start = 0;
+ if (length == 0)
+ throw new NumberFormatException(s);
+
+ c = s.charAt(length - 1);
+ if (c == 'D' || c == 'd' || c == 'F' || c == 'f') {
+ length--;
+ if (length == 0)
+ throw new NumberFormatException(s);
+ }
+
+ end = Math.max(s.indexOf('E'), s.indexOf('e'));
+ if (end > -1) {
+ if (end + 1 == length)
+ throw new NumberFormatException(s);
int exponent_offset = end + 1;
if (s.charAt(exponent_offset) == '+') {
@@ -120,197 +120,208 @@ public final class FloatingPointParser {
}
exponent_offset++; // skip the plus sign
}
- try {
- e = Integer.parseInt(s.substring(exponent_offset,
+ try {
+ e = Integer.parseInt(s.substring(exponent_offset,
length));
} catch (NumberFormatException ex) {
// ex contains the exponent substring
// only so throw a new exception with
// the correct string
- throw new NumberFormatException(s);
+ throw new NumberFormatException(s);
}
- } else {
- end = length;
- }
- if (length == 0)
- throw new NumberFormatException(s);
-
- c = s.charAt(start);
- if (c == '-') {
- ++start;
- --length;
- negative = true;
- } else if (c == '+') {
- ++start;
- --length;
- }
- if (length == 0)
- throw new NumberFormatException(s);
-
- decimal = s.indexOf('.');
- if (decimal > -1) {
- e -= end - decimal - 1;
- s = s.substring(start, decimal) + s.substring(decimal + 1, end);
- } else {
- s = s.substring(start, end);
- }
-
- if ((length = s.length()) == 0)
- throw new NumberFormatException();
-
- end = length;
- while (end > 1 && s.charAt(end - 1) == '0')
- --end;
-
- start = 0;
- while (start < end - 1 && s.charAt(start) == '0')
- start++;
-
- if (end != length || start != 0) {
- e += length - end;
- s = s.substring(start, end);
+ } else {
+ end = length;
+ }
+ if (length == 0)
+ throw new NumberFormatException(s);
+
+ c = s.charAt(start);
+ if (c == '-') {
+ ++start;
+ --length;
+ negative = true;
+ } else if (c == '+') {
+ ++start;
+ --length;
+ }
+ if (length == 0)
+ throw new NumberFormatException(s);
+
+ decimal = s.indexOf('.');
+ if (decimal > -1) {
+ e -= end - decimal - 1;
+ s = s.substring(start, decimal) + s.substring(decimal + 1, end);
+ } else {
+ s = s.substring(start, end);
+ }
+
+ if ((length = s.length()) == 0)
+ throw new NumberFormatException();
+
+ end = length;
+ while (end > 1 && s.charAt(end - 1) == '0')
+ --end;
+
+ start = 0;
+ while (start < end - 1 && s.charAt(start) == '0')
+ start++;
+
+ if (end != length || start != 0) {
+ e += length - end;
+ s = s.substring(start, end);
+ }
+
+ // Trim the length of very small numbers, natives can only handle down
+ // to E-309
+ final int APPROX_MIN_MAGNITUDE = -359;
+ final int MAX_DIGITS = 52;
+ length = s.length();
+ if (length > MAX_DIGITS && e < APPROX_MIN_MAGNITUDE) {
+ int d = Math.min(APPROX_MIN_MAGNITUDE - e, length - 1);
+ s = s.substring(0, length - d);
+ e += d;
}
- return new StringExponentPair(s, e, negative);
- }
-
- /*
- * Assumes the string is trimmed.
- */
- private static double parseDblName(String namedDouble, int length) {
- // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
- // -Infinity.
- if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
- throw new NumberFormatException();
- }
-
- boolean negative = false;
- int cmpstart = 0;
- switch (namedDouble.charAt(0)) {
- case '-':
- negative = true; // fall through
- case '+':
- cmpstart = 1;
- default:
- }
-
- if (namedDouble.regionMatches(false, cmpstart, "Infinity", 0, 8)) {
- return negative ? Double.NEGATIVE_INFINITY
- : Float.POSITIVE_INFINITY;
- }
-
- if (namedDouble.regionMatches(false, cmpstart, "NaN", 0, 3)) {
- return Double.NaN;
- }
-
- throw new NumberFormatException();
- }
-
- /*
- * Assumes the string is trimmed.
- */
- private static float parseFltName(String namedFloat, int length) {
- // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
- // -Infinity.
- if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
- throw new NumberFormatException();
- }
-
- boolean negative = false;
- int cmpstart = 0;
- switch (namedFloat.charAt(0)) {
- case '-':
- negative = true; // fall through
- case '+':
- cmpstart = 1;
- default:
- }
-
- if (namedFloat.regionMatches(false, cmpstart, "Infinity", 0, 8)) {
- return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
- }
-
- if (namedFloat.regionMatches(false, cmpstart, "NaN", 0, 3)) {
- return Float.NaN;
- }
-
- throw new NumberFormatException();
- }
-
- /**
- * Returns the closest double value to the real number in the string.
- *
- * @param s
- * the String that will be parsed to a floating point
- * @return the double closest to the real number
- *
- * @exception NumberFormatException
- * if the String doesn't represent a double
- */
- public static double parseDouble(String s) {
- s = s.trim();
- int length = s.length();
-
- if (length == 0) {
- throw new NumberFormatException(s);
- }
-
- // See if this could be a named double
- char last = s.charAt(length - 1);
- if ((last == 'y') || (last == 'N')) {
- return parseDblName(s, length);
- }
+ return new StringExponentPair(s, e, negative);
+ }
+
+ /*
+ * Assumes the string is trimmed.
+ */
+ private static double parseDblName(String namedDouble, int length) {
+ // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
+ // -Infinity.
+ if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
+ throw new NumberFormatException();
+ }
+
+ boolean negative = false;
+ int cmpstart = 0;
+ switch (namedDouble.charAt(0)) {
+ case '-':
+ negative = true; // fall through
+ case '+':
+ cmpstart = 1;
+ default:
+ }
+
+ if (namedDouble.regionMatches(false, cmpstart, "Infinity", 0, 8)) {
+ return negative ? Double.NEGATIVE_INFINITY
+ : Float.POSITIVE_INFINITY;
+ }
+
+ if (namedDouble.regionMatches(false, cmpstart, "NaN", 0, 3)) {
+ return Double.NaN;
+ }
+
+ throw new NumberFormatException();
+ }
+
+ /*
+ * Assumes the string is trimmed.
+ */
+ private static float parseFltName(String namedFloat, int length) {
+ // Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
+ // -Infinity.
+ if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
+ throw new NumberFormatException();
+ }
+
+ boolean negative = false;
+ int cmpstart = 0;
+ switch (namedFloat.charAt(0)) {
+ case '-':
+ negative = true; // fall through
+ case '+':
+ cmpstart = 1;
+ default:
+ }
+
+ if (namedFloat.regionMatches(false, cmpstart, "Infinity", 0, 8)) {
+ return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
+ }
+
+ if (namedFloat.regionMatches(false, cmpstart, "NaN", 0, 3)) {
+ return Float.NaN;
+ }
+
+ throw new NumberFormatException();
+ }
+
+ /**
+ * Returns the closest double value to the real number in the string.
+ *
+ * @param s
+ * the String that will be parsed to a floating point
+ * @return the double closest to the real number
+ *
+ * @exception NumberFormatException
+ * if the String doesn't represent a double
+ */
+ public static double parseDouble(String s) {
+ s = s.trim();
+ int length = s.length();
+
+ if (length == 0) {
+ throw new NumberFormatException(s);
+ }
+
+ // See if this could be a named double
+ char last = s.charAt(length - 1);
+ if ((last == 'y') || (last == 'N')) {
+ return parseDblName(s, length);
+ }
// See if it could be a hexadecimal representation
if (s.toLowerCase().indexOf("0x") != -1) { //$NON-NLS-1$
return HexStringParser.parseDouble(s);
}
- StringExponentPair info = initialParse(s, length);
-
- double result = parseDblImpl(info.s, info.e);
- if (info.negative)
- result = -result;
-
- return result;
- }
-
- /**
- * Returns the closest float value to the real number in the string.
- *
- * @param s
- * the String that will be parsed to a floating point
- * @return the float closest to the real number
- *
- * @exception NumberFormatException
- * if the String doesn't represent a float
- */
- public static float parseFloat(String s) {
- s = s.trim();
- int length = s.length();
-
- if (length == 0) {
- throw new NumberFormatException(s);
- }
-
- // See if this could be a named float
- char last = s.charAt(length - 1);
- if ((last == 'y') || (last == 'N')) {
- return parseFltName(s, length);
- }
+ StringExponentPair info = initialParse(s, length);
+
+ double result = parseDblImpl(info.s, info.e);
+ if (info.negative)
+ result = -result;
+
+ return result;
+ }
+
+ /**
+ * Returns the closest float value to the real number in the string.
+ *
+ * @param s
+ * the String that will be parsed to a floating point
+ * @return the float closest to the real number
+ *
+ * @exception NumberFormatException
+ * if the String doesn't represent a float
+ */
+ public static float parseFloat(String s) {
+ s = s.trim();
+ int length = s.length();
+
+ if (length == 0) {
+ throw new NumberFormatException(s);
+ }
+
+ // See if this could be a named float
+ char last = s.charAt(length - 1);
+ if ((last == 'y') || (last == 'N')) {
+ return parseFltName(s, length);
+ }
// See if it could be a hexadecimal representation
if (s.toLowerCase().indexOf("0x") != -1) { //$NON-NLS-1$
return HexStringParser.parseFloat(s);
}
- StringExponentPair info = initialParse(s, length);
+ StringExponentPair info = initialParse(s, length);
- float result = parseFltImpl(info.s, info.e);
- if (info.negative)
- result = -result;
+ float result = parseFltImpl(info.s, info.e);
+ if (info.negative)
+ result = -result;
- return result;
- }
+ return result;
+ }
}
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 0688e7d..e4515ae 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
@@ -20,33 +20,34 @@ package org.apache.harmony.luni.util;
import java.io.ByteArrayOutputStream;
import java.io.UTFDataFormatException;
+import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.TimeZone;
public final class Util {
- private static String[] WEEKDAYS = new String[] { "", "Sunday", "Monday",
- "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
+ private static String[] WEEKDAYS = new String[] { "", "Sunday", "Monday",
+ "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
- private static String[] MONTHS = new String[] { "January", "February",
- "March", "April", "May", "June", "July", "August", "September",
- "October", "November", "December" };
+ private static String[] MONTHS = new String[] { "January", "February",
+ "March", "April", "May", "June", "July", "August", "September",
+ "October", "November", "December" };
- private static final String defaultEncoding;
+ private static final String defaultEncoding;
- static {
+ static {
// BEGIN android-changed
String encoding = System.getProperty("file.encoding");
// END android-changed
- if (encoding != null) {
- try {
- "".getBytes(encoding);
+ if (encoding != null) {
+ try {
+ "".getBytes(encoding);
} catch (Throwable t) {
encoding = null;
- }
- }
+ }
+ }
defaultEncoding = encoding;
- }
+ }
/**
* Get bytes from String using default encoding; default encoding can
@@ -55,15 +56,15 @@ public final class Util {
* @return byte array
*/
public static byte[] getBytes(String name) {
- if (defaultEncoding != null) {
- try {
- return name.getBytes(defaultEncoding);
- } catch (java.io.UnsupportedEncodingException e) {
- }
- }
+ if (defaultEncoding != null) {
+ try {
+ return name.getBytes(defaultEncoding);
+ } catch (java.io.UnsupportedEncodingException e) {
+ }
+ }
return name.getBytes();
- }
-
+ }
+
/**
* Get bytes from String with UTF8 encoding
* @param name
@@ -78,29 +79,29 @@ public final class Util {
}
}
- public static String toString(byte[] bytes) {
- if (defaultEncoding != null) {
- try {
- return new String(bytes, 0, bytes.length, defaultEncoding);
- } catch (java.io.UnsupportedEncodingException e) {
- }
- }
- return new String(bytes, 0, bytes.length);
- }
+ public static String toString(byte[] bytes) {
+ if (defaultEncoding != null) {
+ try {
+ return new String(bytes, 0, bytes.length, defaultEncoding);
+ } catch (java.io.UnsupportedEncodingException e) {
+ }
+ }
+ 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 {
- return new String(bytes, offset, length, defaultEncoding);
- } catch (java.io.UnsupportedEncodingException e) {
- }
- }
- return new String(bytes, offset, length);
- }
+ }
+
+ public static String toString(byte[] bytes, int offset, int length) {
+ if (defaultEncoding != null) {
+ try {
+ return new String(bytes, offset, length, defaultEncoding);
+ } catch (java.io.UnsupportedEncodingException e) {
+ }
+ }
+ return new String(bytes, offset, length);
+ }
public static String toUTF8String(byte[] bytes, int offset, int length) {
try {
@@ -109,174 +110,189 @@ public final class Util {
return toString(bytes, offset, length);
}
}
+
+ /**
+ * Answers 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
+ */
+ public static long parseDate(String string) {
+ int offset = 0, length = string.length(), state = 0;
+ int year = -1, month = -1, date = -1;
+ int hour = -1, minute = -1, second = -1;
+ final int PAD = 0, LETTERS = 1, NUMBERS = 2;
+ StringBuilder buffer = new StringBuilder();
- /**
- * 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
- */
- public static long parseDate(String string) {
- int offset = 0, length = string.length(), state = 0;
- int year = -1, month = -1, date = -1;
- int hour = -1, minute = -1, second = -1;
- final int PAD = 0, LETTERS = 1, NUMBERS = 2;
- StringBuffer buffer = new StringBuffer();
-
- while (offset <= length) {
- char next = offset < length ? string.charAt(offset) : '\r';
- offset++;
+ while (offset <= length) {
+ char next = offset < length ? string.charAt(offset) : '\r';
+ offset++;
- int nextState;
- if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))
- nextState = LETTERS;
- else if (next >= '0' && next <= '9')
- nextState = NUMBERS;
- else if (" ,-:\r\t".indexOf(next) == -1)
- throw new IllegalArgumentException();
- else
- nextState = PAD;
+ int nextState;
+ if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))
+ nextState = LETTERS;
+ else if (next >= '0' && next <= '9')
+ nextState = NUMBERS;
+ else if (" ,-:\r\t".indexOf(next) == -1)
+ throw new IllegalArgumentException();
+ else
+ nextState = PAD;
- if (state == NUMBERS && nextState != NUMBERS) {
- int digit = Integer.parseInt(buffer.toString());
- buffer.setLength(0);
- if (digit >= 70) {
- if (year != -1
- || (next != ' ' && next != ',' && next != '\r'))
- throw new IllegalArgumentException();
- year = digit;
- } else if (next == ':') {
- if (hour == -1)
- hour = digit;
- else if (minute == -1)
- minute = digit;
- else
- throw new IllegalArgumentException();
- } else if (next == ' ' || next == ',' || next == '-'
- || next == '\r') {
- if (hour != -1 && minute == -1)
- minute = digit;
- else if (minute != -1 && second == -1)
- second = digit;
- else if (date == -1)
- date = digit;
- else if (year == -1)
- year = digit;
- else
- throw new IllegalArgumentException();
- } else if (year == -1 && month != -1 && date != -1)
- year = digit;
- else
- throw new IllegalArgumentException();
- } else if (state == LETTERS && nextState != LETTERS) {
- String text = buffer.toString().toUpperCase();
- buffer.setLength(0);
- if (text.length() < 3)
- throw new IllegalArgumentException();
- if (parse(text, WEEKDAYS) != -1) {
- } else if (month == -1 && (month = parse(text, MONTHS)) != -1) {
- } else if (text.equals("GMT")) {
- } else
- throw new IllegalArgumentException();
- }
+ if (state == NUMBERS && nextState != NUMBERS) {
+ int digit = Integer.parseInt(buffer.toString());
+ buffer.setLength(0);
+ if (digit >= 70) {
+ if (year != -1
+ || (next != ' ' && next != ',' && next != '\r'))
+ throw new IllegalArgumentException();
+ year = digit;
+ } else if (next == ':') {
+ if (hour == -1)
+ hour = digit;
+ else if (minute == -1)
+ minute = digit;
+ else
+ throw new IllegalArgumentException();
+ } else if (next == ' ' || next == ',' || next == '-'
+ || next == '\r') {
+ if (hour != -1 && minute == -1)
+ minute = digit;
+ else if (minute != -1 && second == -1)
+ second = digit;
+ else if (date == -1)
+ date = digit;
+ else if (year == -1)
+ year = digit;
+ else
+ throw new IllegalArgumentException();
+ } else if (year == -1 && month != -1 && date != -1)
+ year = digit;
+ else
+ throw new IllegalArgumentException();
+ } else if (state == LETTERS && nextState != LETTERS) {
+ String text = buffer.toString().toUpperCase();
+ buffer.setLength(0);
+ if (text.length() < 3)
+ throw new IllegalArgumentException();
+ if (parse(text, WEEKDAYS) != -1) {
+ } else if (month == -1 && (month = parse(text, MONTHS)) != -1) {
+ } else if (text.equals("GMT")) {
+ } else
+ throw new IllegalArgumentException();
+ }
- if (nextState == LETTERS || nextState == NUMBERS)
- buffer.append(next);
- state = nextState;
- }
+ if (nextState == LETTERS || nextState == NUMBERS)
+ buffer.append(next);
+ state = nextState;
+ }
- if (year != -1 && month != -1 && date != -1) {
- if (hour == -1)
- hour = 0;
- if (minute == -1)
- minute = 0;
- if (second == -1)
- second = 0;
- Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
- int current = cal.get(Calendar.YEAR) - 80;
- if (year < 100) {
- year += current / 100 * 100;
- if (year < current)
- year += 100;
- }
- cal.set(Calendar.YEAR, year);
- cal.set(Calendar.MONTH, month);
- cal.set(Calendar.DATE, date);
- cal.set(Calendar.HOUR_OF_DAY, hour);
- cal.set(Calendar.MINUTE, minute);
- cal.set(Calendar.SECOND, second);
- cal.set(Calendar.MILLISECOND, 0);
- return cal.getTime().getTime();
- }
- throw new IllegalArgumentException();
- }
+ if (year != -1 && month != -1 && date != -1) {
+ if (hour == -1)
+ hour = 0;
+ if (minute == -1)
+ minute = 0;
+ if (second == -1)
+ second = 0;
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ int current = cal.get(Calendar.YEAR) - 80;
+ if (year < 100) {
+ year += current / 100 * 100;
+ if (year < current)
+ year += 100;
+ }
+ cal.set(Calendar.YEAR, year);
+ cal.set(Calendar.MONTH, month);
+ cal.set(Calendar.DATE, date);
+ cal.set(Calendar.HOUR_OF_DAY, hour);
+ cal.set(Calendar.MINUTE, minute);
+ cal.set(Calendar.SECOND, second);
+ cal.set(Calendar.MILLISECOND, 0);
+ return cal.getTime().getTime();
+ }
+ throw new IllegalArgumentException();
+ }
- private static int parse(String string, String[] array) {
- int length = string.length();
- for (int i = 0; i < array.length; i++) {
- if (string.regionMatches(true, 0, array[i], 0, length))
- return i;
- }
- return -1;
- }
+ private static int parse(String string, String[] array) {
+ int length = string.length();
+ for (int i = 0; i < array.length; i++) {
+ if (string.regionMatches(true, 0, array[i], 0, length))
+ return i;
+ }
+ return -1;
+ }
- public static String convertFromUTF8(byte[] buf, int offset, int utfSize)
- throws UTFDataFormatException {
- return convertUTF8WithBuf(buf, new char[utfSize], offset, utfSize);
- }
+ public static String convertFromUTF8(byte[] buf, int offset, int utfSize)
+ throws UTFDataFormatException {
+ return convertUTF8WithBuf(buf, new char[utfSize], offset, utfSize);
+ }
- public static String convertUTF8WithBuf(byte[] buf, char[] out, int offset,
- int utfSize) throws UTFDataFormatException {
- int count = 0, s = 0, a;
- while (count < utfSize) {
- if ((out[s] = (char) buf[offset + count++]) < '\u0080')
- s++;
- else if (((a = out[s]) & 0xe0) == 0xc0) {
- if (count >= utfSize)
- throw new UTFDataFormatException(Msg.getString("K0062",
- count));
+ public static String convertUTF8WithBuf(byte[] buf, char[] out, int offset,
+ int utfSize) throws UTFDataFormatException {
+ int count = 0, s = 0, a;
+ while (count < utfSize) {
+ if ((out[s] = (char) buf[offset + count++]) < '\u0080')
+ s++;
+ else if (((a = out[s]) & 0xe0) == 0xc0) {
+ if (count >= utfSize)
+ throw new UTFDataFormatException(Msg.getString("K0062",
+ count));
// BEGIN android-changed
int b = buf[offset + count++];
// END android-changed
- if ((b & 0xC0) != 0x80)
- throw new UTFDataFormatException(Msg.getString("K0062",
- (count - 1)));
- out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
- } else if ((a & 0xf0) == 0xe0) {
- if (count + 1 >= utfSize)
- throw new UTFDataFormatException(Msg.getString("K0063",
- (count + 1)));
+ if ((b & 0xC0) != 0x80)
+ throw new UTFDataFormatException(Msg.getString("K0062",
+ (count - 1)));
+ out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
+ } else if ((a & 0xf0) == 0xe0) {
+ if (count + 1 >= utfSize)
+ throw new UTFDataFormatException(Msg.getString("K0063",
+ (count + 1)));
// BEGIN android-changed
int b = buf[offset + count++];
int c = buf[offset + count++];
// END android-changed
- if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80))
- throw new UTFDataFormatException(Msg.getString("K0064",
- (count - 2)));
- out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
- } else {
- throw new UTFDataFormatException(Msg.getString("K0065",
- (count - 1)));
- }
- }
- return new String(out, 0, s);
+ if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80))
+ throw new UTFDataFormatException(Msg.getString("K0064",
+ (count - 2)));
+ out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
+ } else {
+ throw new UTFDataFormatException(Msg.getString("K0065",
+ (count - 1)));
+ }
+ }
+ return new String(out, 0, s);
+ }
+
+ /**
+ * '%' 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.
+ */
+ public static String decode(String s, boolean convertPlus) {
+ return decode(s, convertPlus, null);
}
/**
* '%' 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.
+ * @param encoding
+ * the specified encoding
* @return java.lang.String The decoded version.
*/
- public static String decode(String s, boolean convertPlus) {
+ public static String decode(String s, boolean convertPlus, String encoding) {
if (!convertPlus && s.indexOf('%') == -1)
return s;
- StringBuffer result = new StringBuffer(s.length());
+ StringBuilder result = new StringBuilder(s.length());
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (int i = 0; i < s.length();) {
char c = s.charAt(i);
@@ -297,7 +313,15 @@ public final class Util {
out.write((byte) ((d1 << 4) + d2));
i += 3;
} while (i < s.length() && s.charAt(i) == '%');
- result.append(out.toString());
+ if (encoding == null) {
+ result.append(out.toString());
+ } else {
+ try {
+ result.append(out.toString(encoding));
+ } catch (UnsupportedEncodingException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
continue;
} else
result.append(c);
@@ -305,32 +329,32 @@ public final class Util {
}
return result.toString();
}
-
- public static String toASCIILowerCase(String s) {
+
+ public static String toASCIILowerCase(String s) {
int len = s.length();
- StringBuilder buffer = new StringBuilder(len);
- for (int i = 0; i < len; i++) {
- char c = s.charAt(i);
- if ('A' <= c && c <= 'Z') {
- buffer.append((char) (c + ('a' - 'A')));
- } else {
- buffer.append(c);
- }
- }
- return buffer.toString();
- }
-
- public static String toASCIIUpperCase(String s) {
+ StringBuilder buffer = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if ('A' <= c && c <= 'Z') {
+ buffer.append((char) (c + ('a' - 'A')));
+ } else {
+ buffer.append(c);
+ }
+ }
+ return buffer.toString();
+ }
+
+ public static String toASCIIUpperCase(String s) {
int len = s.length();
StringBuilder buffer = new StringBuilder(len);
for (int i = 0; i < len; i++) {
- char c = s.charAt(i);
- if ('a' <= c && c <= 'z') {
- buffer.append((char) (c - ('a' - 'A')));
- } else {
- buffer.append(c);
- }
- }
- return buffer.toString();
- }
+ char c = s.charAt(i);
+ if ('a' <= c && c <= 'z') {
+ buffer.append((char) (c - ('a' - 'A')));
+ } else {
+ buffer.append(c);
+ }
+ }
+ return buffer.toString();
+ }
}
diff --git a/luni/src/main/native/cbigint.c b/luni/src/main/native/cbigint.c
index 77ee0f8..d327940 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) || defined(ZOS)
+#if defined(LINUX) || defined(FREEBSD) || defined(ZOS) || defined(MACOSX) || defined(AIX)
#define USE_LL
#endif
@@ -665,7 +665,7 @@ tenToTheEHighPrecision (U_64 * result, IDATA length, jint e)
do {
overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0);
if (overflow)
- result[length++] = overflow;
+ result[length++] = overflow;
} while (--e);
*/
return length;
@@ -686,7 +686,7 @@ timesTenToTheEHighPrecision (U_64 * result, IDATA length, jint e)
do {
overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0);
if (overflow)
- result[length++] = overflow;
+ result[length++] = overflow;
} while (--e);
*/
/* Replace the current implementaion which performs a
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
index 778e527..056b521 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/AllTests.java
@@ -34,6 +34,7 @@ public class AllTests
TestSuite suite = tests.TestSuiteFactory.createTestSuite("Tests for java.io");
suite.addTestSuite(BufferedReaderTest.class);
+ suite.addTestSuite(FileCanonPathCacheTest.class);
suite.addTestSuite(FilePermissionTest.class);
suite.addTestSuite(FileTest.class);
suite.addTestSuite(InputStreamReaderTest.class);
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileCanonPathCacheTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileCanonPathCacheTest.java
new file mode 100644
index 0000000..f2ac7f3
--- /dev/null
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/io/FileCanonPathCacheTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.tests.java.io;
+
+import java.io.File;
+
+import org.apache.harmony.luni.internal.io.FileCanonPathCache;
+
+import junit.framework.TestCase;
+
+public class FileCanonPathCacheTest extends TestCase {
+
+ private static int DEFAULT_TIMEOUT = 600000;
+
+ @Override
+ public void setUp() throws Exception {
+ FileCanonPathCache.clear();
+ FileCanonPathCache.setTimeout(DEFAULT_TIMEOUT);
+ }
+
+ public void testGetSet() throws Exception {
+ File file1 = new File("test/hello~1");
+ assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
+ FileCanonPathCache.put(file1.getAbsolutePath(), file1
+ .getCanonicalPath());
+ assertEquals(file1.getCanonicalPath(), FileCanonPathCache.get(file1
+ .getAbsolutePath()));
+
+ File file2 = new File("test/world~1");
+ assertNull(FileCanonPathCache.get(file2.getAbsolutePath()));
+ FileCanonPathCache.put(file2.getAbsolutePath(), file2
+ .getCanonicalPath());
+ assertEquals(file2.getCanonicalPath(), FileCanonPathCache.get(file2
+ .getAbsolutePath()));
+
+ assertNull(FileCanonPathCache.get("notexist"));
+ }
+
+ public void testGetTimeout01() throws Exception {
+ FileCanonPathCache.setTimeout(10);
+
+ File file1 = new File("test/hello~1");
+ assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
+ FileCanonPathCache.put(file1.getAbsolutePath(), file1
+ .getCanonicalPath());
+ Thread.sleep(50);
+ assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
+ }
+
+ public void testGetTimeout02() throws Exception {
+ FileCanonPathCache.setTimeout(10);
+
+ File file1 = new File("test/hello~1");
+ assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
+ FileCanonPathCache.put(file1.getAbsolutePath(), file1
+ .getCanonicalPath());
+ File file2 = new File("test/hello~2");
+ assertNull(FileCanonPathCache.get(file2.getAbsolutePath()));
+ FileCanonPathCache.put(file2.getAbsolutePath(), file2
+ .getCanonicalPath());
+ File file3 = new File("test/hello~3");
+ assertNull(FileCanonPathCache.get(file3.getAbsolutePath()));
+ FileCanonPathCache.put(file3.getAbsolutePath(), file3
+ .getCanonicalPath());
+ File file4 = new File("test/hello~4");
+ assertNull(FileCanonPathCache.get(file4.getAbsolutePath()));
+ FileCanonPathCache.put(file4.getAbsolutePath(), file4
+ .getCanonicalPath());
+ File file5 = new File("test/hello~5");
+ assertNull(FileCanonPathCache.get(file5.getAbsolutePath()));
+ FileCanonPathCache.put(file5.getAbsolutePath(), file5
+ .getCanonicalPath());
+
+ Thread.sleep(50);
+
+ assertNull(FileCanonPathCache.get(file1.getAbsolutePath()));
+ assertNull(FileCanonPathCache.get(file2.getAbsolutePath()));
+ assertNull(FileCanonPathCache.get(file3.getAbsolutePath()));
+ assertNull(FileCanonPathCache.get(file4.getAbsolutePath()));
+ assertNull(FileCanonPathCache.get(file5.getAbsolutePath()));
+ }
+
+ public void testCacheFull() throws Exception {
+ int cacheSize = FileCanonPathCache.CACHE_SIZE;
+ File[] files = new File[cacheSize];
+ for (int i = 0; i < cacheSize; ++i) {
+ files[i] = new File("test/world" + i);
+ FileCanonPathCache.put(files[i].getAbsolutePath(), files[i]
+ .getCanonicalPath());
+ }
+
+ for (int i = cacheSize; i < files.length; ++i) {
+ assertEquals(files[i - cacheSize].getCanonicalPath(),
+ FileCanonPathCache.get(files[i - cacheSize]
+ .getAbsolutePath()));
+ files[i] = new File("test/world" + i);
+ FileCanonPathCache.put(files[i].getAbsolutePath(), files[i]
+ .getCanonicalPath());
+ assertEquals(files[i].getCanonicalPath(), FileCanonPathCache
+ .get(files[i].getAbsolutePath()));
+ assertNull(FileCanonPathCache.get(files[i - cacheSize]
+ .getAbsolutePath()));
+ }
+ }
+}