* some extra space is required to hold the buffer and that copying takes place
* when filling that buffer, but this is usually outweighed by the performance
* benefits.
- *
+ *
* <p/>A typical application pattern for the class looks like this:<p/>
*
* <pre>
* BufferedReader buf = new BufferedReader(new FileReader("file.java"));
* </pre>
- *
+ *
* @see BufferedWriter
* @since 1.1
*/
/**
* Constructs a new BufferedReader on the Reader {@code in}. The
* buffer gets the default size (8 KB).
- *
+ *
* @param in
* the Reader that is buffered.
*/
/**
* 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
* 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.
*/
/**
* Indicates whether or not this reader is closed.
- *
+ *
* @return {@code true} if this reader is closed, {@code false}
* otherwise.
*/
* 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.
/**
* 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()
* 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
* 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 \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
// 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') {
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;
}
}
// 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')) {
}
pos = charPos + 1;
return result.toString();
- } else if (eol != '\0') {
+ } else {
if (charPos > pos) {
result.append(buf, pos, charPos - pos - 1);
}
* 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)
* {@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.
*/
@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();
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;
*/
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);
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;
}
/*
@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
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()
}
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
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()
}
// 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;
}
/**
}
// 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();
// 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') {
}
if (end > start) {
int length = count - end;
- if (length > 0) {
+ if (length >= 0) {
if (!shared) {
System.arraycopy(value, end, value, start, length);
} else {
package java.lang;
-
/**
* Class Math provides basic math constants and operations such as trigonometric
* functions, hyperbolic functions, exponential, logarithms, etc.
* <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.
* <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
* <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
* <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
* <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.
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>
* <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
* <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.
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>
* <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.
* <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.
* <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.
* <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.
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>
* <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);
* <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>
* <li>{@code hypot((anything including NaN), -infinity) = +infinity}</li>
* <li>{@code hypot(NaN, NaN) = NaN}</li>
* </ul>
- *
+ *
* @param x
* a double number.
* @param y
* <li>{@code IEEEremainder(x, -infinity) = x } where x is anything but
* +/-infinity</li>
* </ul>
- *
+ *
* @param x
* the numerator of the operation.
* @param y
* <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.
* <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.
* <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.
* <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;
}
return d2;
}
return 0.0d;
- // END android-changed
- }
+ }
/**
* Returns the most positive (closest to positive infinity) of the two
* <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;
}
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
* <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;
}
return -0.0d;
}
return d2;
- // END android-changed
- }
+ }
/**
* Returns the most negative (closest to negative infinity) of the two
* <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;
}
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>
* <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
* <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>
* <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
* <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
* <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.
* <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.
* <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.
* <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.
* <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.
* <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.
* <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.
/**
* 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
* <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
* <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>
* <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.
/**
* 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>
* <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.
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);
}
/**
* Create a ConsolePrintStream on the specified OutputStream, usually
* System.out.
- *
+ *
* @param out
* the console OutputStream
*/
count = 0;
}
+ /*
+ * Private constructor used for JIT optimization.
+ */
@SuppressWarnings("unused")
private String(String s, char c) {
offset = 0;
* 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.
*/
/**
* 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
* 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
/**
* Converts the byte array to a string using the specified encoding.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param start
/**
* Converts the byte array to a string using the specified encoding.
- *
+ *
* @param data
* the byte array to convert to a string.
* @param encoding
* 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
* 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
/**
* Creates a {@code String} that is a copy of the specified string.
- *
+ *
* @param string
* the string to copy.
*/
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.
*/
/**
* Creates a {@code String} from the contents of the specified {@code
* StringBuilder}.
- *
+ *
* @param sb
* the {@code StringBuilder} to copy the contents from.
* @throws NullPointerException
/**
* 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.
* 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
* 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
/**
* 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
* 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.
* 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
/**
* 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,
* 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,
/**
* 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,
* 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() {
/**
* 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
/**
* 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.
/**
* 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
* 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
* 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
* 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
* 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
* 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
* 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
* 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
* 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
/**
* Returns the size of this string.
- *
+ *
* @return the number of characters in this string.
*/
public int length() {
/**
* 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
* 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
/**
* Copies this string replacing occurrences of the specified character with
* another character.
- *
+ *
* @param oldChar
* the character to replace.
* @param newChar
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
/**
* 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,
/**
* 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
/**
* 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
/**
* Copies a range of characters into a new string.
- *
+ *
* @param start
* the offset of the first character.
* @param end
/**
* Copies the characters in this string to a character array.
- *
+ *
* @return a character array containing the characters of this string.
*/
public char[] toCharArray() {
/**
* 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.
*/
/**
* 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
/**
* 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.
*/
/**
* 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
/**
* 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.
*/
* 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.
* 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
/**
* Converts the specified character to its string representation.
- *
+ *
* @param value
* the character.
* @return the character converted to a string.
/**
* Converts the specified double to its string representation.
- *
+ *
* @param value
* the double.
* @return the double converted to a string.
/**
* Converts the specified float to its string representation.
- *
+ *
* @param value
* the float.
* @return the float converted to a string.
/**
* Converts the specified integer to its string representation.
- *
+ *
* @param value
* the integer.
* @return the integer converted to a string.
/**
* Converts the specified long to its string representation.
- *
+ *
* @param value
* the long.
* @return the long converted to a 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"}.
* 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.
/**
* 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
/**
* 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}.
/**
* 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
/**
* 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
/**
* 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
* 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
/**
* 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
/**
* 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.
/**
* 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.
/**
* Calculates the number of Unicode code points between {@code beginIndex}
* and {@code endIndex}.
- *
+ *
* @param beginIndex
* the inclusive beginning index of the subsequence.
* @param endIndex
/**
* Returns a formatted string, using the supplied format and arguments,
* using the default locale.
- *
+ *
* @param format
* a format string.
* @param args
*/
@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 ");
*/
@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$
@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();
}
}
boolean parsing = true;
String action;
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder();
int pos = 0, length = actions.length();
while (parsing) {
char c;
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]);
*/
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(':');
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(':');
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(':');
* 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;
}
}
// put the path back together
- StringBuffer newpath = new StringBuffer();
+ StringBuilder newpath = new StringBuilder();
if (path.startsWith("/")) { //$NON-NLS-1$
newpath.append('/');
}
*/
private void setSchemeSpecificPart() {
// ssp = [//authority][path][?query]
- StringBuffer ssp = new StringBuffer();
+ StringBuilder ssp = new StringBuilder();
if (authority != null) {
ssp.append("//" + authority); //$NON-NLS-1$
}
@Override
public String toString() {
if (string == null) {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
if (scheme != null) {
result.append(scheme);
result.append(':');
* 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(':');
*/
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')
* @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) {
*/
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);
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
}
}
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;
* @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);
*/
@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')
* @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();
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);
@Override
public int size() {
- return size;
+ if (modCount == fullList.modCount) {
+ return size;
+ }
+ throw new ConcurrentModificationException();
}
void sizeChanged(boolean increment) {
* 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;
}
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);
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;
}
/**
*/
@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;
@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
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';
}
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);
}
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;
}
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;
}
/**
@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;
}
*/
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++;
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();
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();
case '\r':
mode = NONE;
firstChar = true;
- if (offset > 0) {
+ if (offset > 0 || (offset == 0 && keyLength == 0)) {
if (keyLength == -1) {
keyLength = offset;
}
}
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));
/**
* 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);
}
}
+
+ 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);
}
/**
* @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
* @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
* @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
* @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
* @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
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) {
--- /dev/null
+/*
+ * 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;
+ }
+}
* 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);
*/
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;
*/
@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();
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
*/
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;
/**
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);
/**
*/
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);
/**
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
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.
}
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;
}
* 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,
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
*/
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) == '+') {
}
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;
+ }
}
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
* @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
}
}
- 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 {
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);
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);
}
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();
+ }
}
#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
do {
overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0);
if (overflow)
- result[length++] = overflow;
+ result[length++] = overflow;
} while (--e);
*/
return length;
do {
overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0);
if (overflow)
- result[length++] = overflow;
+ result[length++] = overflow;
} while (--e);
*/
/* Replace the current implementaion which performs a
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);
--- /dev/null
+/*
+ * 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()));
+ }
+ }
+}