diff options
author | Mark Wielaard <mark@gcc.gnu.org> | 2006-05-18 17:29:21 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2006-05-18 17:29:21 +0000 |
commit | 4f9533c7722fa07511a94d005227961f4a4dec23 (patch) | |
tree | 9f9c470de62ee62fba1331a396450d728d2b1fad /libjava/classpath/java/util | |
parent | eaec4980e139903ae9b274d1abcf3a13946603a8 (diff) | |
download | gcc-4f9533c7722fa07511a94d005227961f4a4dec23.zip gcc-4f9533c7722fa07511a94d005227961f4a4dec23.tar.gz gcc-4f9533c7722fa07511a94d005227961f4a4dec23.tar.bz2 |
Imported GNU Classpath 0.90
Imported GNU Classpath 0.90
* scripts/makemake.tcl: LocaleData.java moved to gnu/java/locale.
* sources.am: Regenerated.
* gcj/javaprims.h: Regenerated.
* Makefile.in: Regenerated.
* gcj/Makefile.in: Regenerated.
* include/Makefile.in: Regenerated.
* testsuite/Makefile.in: Regenerated.
* gnu/java/lang/VMInstrumentationImpl.java: New override.
* gnu/java/net/local/LocalSocketImpl.java: Likewise.
* gnu/classpath/jdwp/VMMethod.java: Likewise.
* gnu/classpath/jdwp/VMVirtualMachine.java: Update to latest
interface.
* java/lang/Thread.java: Add UncaughtExceptionHandler.
* java/lang/reflect/Method.java: Implements GenericDeclaration and
isSynthetic(),
* java/lang/reflect/Field.java: Likewise.
* java/lang/reflect/Constructor.java
* java/lang/Class.java: Implements Type, GenericDeclaration,
getSimpleName() and getEnclosing*() methods.
* java/lang/Class.h: Add new public methods.
* java/lang/Math.java: Add signum(), ulp() and log10().
* java/lang/natMath.cc (log10): New function.
* java/security/VMSecureRandom.java: New override.
* java/util/logging/Logger.java: Updated to latest classpath
version.
* java/util/logging/LogManager.java: New override.
From-SVN: r113887
Diffstat (limited to 'libjava/classpath/java/util')
31 files changed, 844 insertions, 710 deletions
diff --git a/libjava/classpath/java/util/AbstractList.java b/libjava/classpath/java/util/AbstractList.java index 8a9b6f1..114712e 100644 --- a/libjava/classpath/java/util/AbstractList.java +++ b/libjava/classpath/java/util/AbstractList.java @@ -327,12 +327,9 @@ while (i.hasNext()) * * @return True if the end of the list has not yet been * reached. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. */ public boolean hasNext() { - checkMod(); return pos < size; } @@ -461,12 +458,9 @@ while (i.hasNext()) * * @return True if the end of the list has not yet been * reached. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. */ public boolean hasNext() { - checkMod(); return position < size; } @@ -476,12 +470,9 @@ while (i.hasNext()) * * @return True if objects exist prior to the current * position of the iterator. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. */ public boolean hasPrevious() { - checkMod(); return position > 0; } @@ -526,12 +517,9 @@ while (i.hasNext()) * list, which will be retrieved by <code>next()</code> * * @return The index of the next element. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. */ public int nextIndex() { - checkMod(); return position; } @@ -540,12 +528,9 @@ while (i.hasNext()) * list, which will be retrieved by <code>previous()</code> * * @return The index of the previous element. - * @throws ConcurrentModificationException if the list - * has been modified elsewhere. */ public int previousIndex() { - checkMod(); return position - 1; } @@ -1030,12 +1015,9 @@ while (i.hasNext()) * * @return True if the end of the list has not yet been * reached. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. */ public boolean hasNext() { - checkMod(); return position < size; } @@ -1045,12 +1027,9 @@ while (i.hasNext()) * * @return True if objects exist prior to the current * position of the iterator. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. */ public boolean hasPrevious() { - checkMod(); return position > 0; } @@ -1093,8 +1072,6 @@ while (i.hasNext()) * list, which will be retrieved by <code>next()</code> * * @return The index of the next element. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. */ public int nextIndex() { @@ -1106,8 +1083,6 @@ while (i.hasNext()) * list, which will be retrieved by <code>previous()</code> * * @return The index of the previous element. - * @throws ConcurrentModificationException if the - * list has been modified elsewhere. */ public int previousIndex() { diff --git a/libjava/classpath/java/util/Arrays.java b/libjava/classpath/java/util/Arrays.java index b28c156..2913446 100644 --- a/libjava/classpath/java/util/Arrays.java +++ b/libjava/classpath/java/util/Arrays.java @@ -2352,185 +2352,556 @@ public class Arrays return new Arrays.ArrayList(a); } + /** + * Returns the hashcode of an array of long numbers. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents longs in their wrapper class, <code>Long</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of long numbers for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(long[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + { + int elt = (int) (v[i] ^ (v[i] >>> 32)); + result = 31 * result + elt; + } + return result; + } + + /** + * Returns the hashcode of an array of integer numbers. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents ints in their wrapper class, <code>Integer</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of integer numbers for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(int[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + result = 31 * result + v[i]; + return result; + } + + /** + * Returns the hashcode of an array of short numbers. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents shorts in their wrapper class, <code>Short</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of short numbers for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(short[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + result = 31 * result + v[i]; + return result; + } + + /** + * Returns the hashcode of an array of characters. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents chars in their wrapper class, <code>Character</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of characters for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(char[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + result = 31 * result + v[i]; + return result; + } + + /** + * Returns the hashcode of an array of bytes. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents bytes in their wrapper class, <code>Byte</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of bytes for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(byte[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + result = 31 * result + v[i]; + return result; + } + + /** + * Returns the hashcode of an array of booleans. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents booleans in their wrapper class, + * <code>Boolean</code>. For <code>null</code>, 0 is returned. + * + * @param v an array of booleans for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(boolean[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + result = 31 * result + (v[i] ? 1231 : 1237); + return result; + } + + /** + * Returns the hashcode of an array of floats. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents floats in their wrapper class, <code>Float</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of floats for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(float[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + result = 31 * result + Float.floatToIntBits(v[i]); + return result; + } + + /** + * Returns the hashcode of an array of doubles. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents doubles in their wrapper class, <code>Double</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of doubles for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(double[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + { + long l = Double.doubleToLongBits(v[i]); + int elt = (int) (l ^ (l >>> 32)); + result = 31 * result + elt; + } + return result; + } + + /** + * Returns the hashcode of an array of integer numbers. If two arrays + * are equal, according to <code>equals()</code>, they should have the + * same hashcode. The hashcode returned by the method is equal to that + * obtained by the corresponding <code>List</code> object. This has the same + * data, but represents ints in their wrapper class, <code>Integer</code>. + * For <code>null</code>, 0 is returned. + * + * @param v an array of integer numbers for which the hash code should be + * computed. + * @return the hash code of the array, or 0 if null was given. + * @since 1.5 + */ + public static int hashCode(Object[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + { + int elt = v[i] == null ? 0 : v[i].hashCode(); + result = 31 * result + elt; + } + return result; + } + + /** @since 1.5 */ + public static int deepHashCode(Object[] v) + { + if (v == null) + return 0; + int result = 1; + for (int i = 0; i < v.length; ++i) + { + int elt; + if (v[i] == null) + elt = 0; + else if (v[i] instanceof boolean[]) + elt = hashCode((boolean[]) v[i]); + else if (v[i] instanceof byte[]) + elt = hashCode((byte[]) v[i]); + else if (v[i] instanceof char[]) + elt = hashCode((char[]) v[i]); + else if (v[i] instanceof short[]) + elt = hashCode((short[]) v[i]); + else if (v[i] instanceof int[]) + elt = hashCode((int[]) v[i]); + else if (v[i] instanceof long[]) + elt = hashCode((long[]) v[i]); + else if (v[i] instanceof float[]) + elt = hashCode((float[]) v[i]); + else if (v[i] instanceof double[]) + elt = hashCode((double[]) v[i]); + else if (v[i] instanceof Object[]) + elt = hashCode((Object[]) v[i]); + else + elt = v[i].hashCode(); + result = 31 * result + elt; + } + return result; + } + + /** @since 1.5 */ + public static boolean deepEquals(Object[] v1, Object[] v2) + { + if (v1 == null) + return v2 == null; + if (v2 == null || v1.length != v2.length) + return false; + + for (int i = 0; i < v1.length; ++i) + { + Object e1 = v1[i]; + Object e2 = v2[i]; + + if (e1 == e2) + continue; + if (e1 == null || e2 == null) + return false; + + boolean check; + if (e1 instanceof boolean[] && e2 instanceof boolean[]) + check = equals((boolean[]) e1, (boolean[]) e2); + else if (e1 instanceof byte[] && e2 instanceof byte[]) + check = equals((byte[]) e1, (byte[]) e2); + else if (e1 instanceof char[] && e2 instanceof char[]) + check = equals((char[]) e1, (char[]) e2); + else if (e1 instanceof short[] && e2 instanceof short[]) + check = equals((short[]) e1, (short[]) e2); + else if (e1 instanceof int[] && e2 instanceof int[]) + check = equals((int[]) e1, (int[]) e2); + else if (e1 instanceof long[] && e2 instanceof long[]) + check = equals((long[]) e1, (long[]) e2); + else if (e1 instanceof float[] && e2 instanceof float[]) + check = equals((float[]) e1, (float[]) e2); + else if (e1 instanceof double[] && e2 instanceof double[]) + check = equals((double[]) e1, (double[]) e2); + else if (e1 instanceof Object[] && e2 instanceof Object[]) + check = equals((Object[]) e1, (Object[]) e2); + else + check = e1.equals(e2); + if (! check) + return false; + } + + return true; + } + /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (long[] a) + public static String toString(boolean[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } - + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } + /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (int[] a) + public static String toString(byte[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } - + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } + /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (short[] a) + public static String toString(char[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (char[] a) + public static String toString(short[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (byte[] a) + public static String toString(int[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (boolean[] a) + public static String toString(long[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (float[] a) + public static String toString(float[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } - + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } + /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (double[] a) + public static String toString(double[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } /** * Returns a String representation of the argument array. Returns "null" * if <code>a</code> is null. - * @param a the array to represent + * @param v the array to represent * @return a String representing this array * @since 1.5 */ - public static String toString (Object[] a) + public static String toString(Object[] v) { - if (a == null) + if (v == null) return "null"; - if (a.length == 0) - return "[]"; - String result = "["; - for (int i = 0; i < a.length - 1; i++) - result += String.valueOf(a[i]) + ", "; - result += String.valueOf(a[a.length - 1]) + "]"; - return result; - } + StringBuilder b = new StringBuilder("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + b.append(v[i]); + } + b.append("]"); + return b.toString(); + } + + private static void deepToString(Object[] v, StringBuilder b, HashSet seen) + { + b.append("["); + for (int i = 0; i < v.length; ++i) + { + if (i > 0) + b.append(", "); + Object elt = v[i]; + if (elt == null) + b.append("null"); + else if (elt instanceof boolean[]) + b.append(toString((boolean[]) elt)); + else if (elt instanceof byte[]) + b.append(toString((byte[]) elt)); + else if (elt instanceof char[]) + b.append(toString((char[]) elt)); + else if (elt instanceof short[]) + b.append(toString((short[]) elt)); + else if (elt instanceof int[]) + b.append(toString((int[]) elt)); + else if (elt instanceof long[]) + b.append(toString((long[]) elt)); + else if (elt instanceof float[]) + b.append(toString((float[]) elt)); + else if (elt instanceof double[]) + b.append(toString((double[]) elt)); + else if (elt instanceof Object[]) + { + Object[] os = (Object[]) elt; + if (seen.contains(os)) + b.append("[...]"); + else + { + seen.add(os); + deepToString(os, b, seen); + } + } + else + b.append(elt); + } + b.append("]"); + } + + /** @since 1.5 */ + public static String deepToString(Object[] v) + { + if (v == null) + return "null"; + HashSet seen = new HashSet(); + StringBuilder b = new StringBuilder(); + deepToString(v, b, seen); + return b.toString(); + } /** * Inner class used by {@link #asList(Object[])} to provide a list interface diff --git a/libjava/classpath/java/util/BitSet.java b/libjava/classpath/java/util/BitSet.java index ce88794..f1b5aaa 100644 --- a/libjava/classpath/java/util/BitSet.java +++ b/libjava/classpath/java/util/BitSet.java @@ -365,7 +365,7 @@ public class BitSet implements Cloneable, Serializable throw new IndexOutOfBoundsException(); BitSet bs = new BitSet(to - from); int lo_offset = from >>> 6; - if (lo_offset >= bits.length) + if (lo_offset >= bits.length || to == from) return bs; int lo_bit = from & LONG_MASK; diff --git a/libjava/classpath/java/util/Calendar.java b/libjava/classpath/java/util/Calendar.java index f94bed4..a324f5a 100644 --- a/libjava/classpath/java/util/Calendar.java +++ b/libjava/classpath/java/util/Calendar.java @@ -1037,6 +1037,8 @@ public abstract class Calendar implements Serializable, Cloneable public void setTimeZone(TimeZone zone) { this.zone = zone; + computeTime(); + computeFields(); } /** diff --git a/libjava/classpath/java/util/Collection.java b/libjava/classpath/java/util/Collection.java index 29e1b37..f7db708 100644 --- a/libjava/classpath/java/util/Collection.java +++ b/libjava/classpath/java/util/Collection.java @@ -81,9 +81,9 @@ package java.util; * @see Arrays * @see AbstractCollection * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 (minus generics) */ -public interface Collection +public interface Collection extends Iterable { /** * Add an element to this collection. diff --git a/libjava/classpath/java/util/GregorianCalendar.java b/libjava/classpath/java/util/GregorianCalendar.java index 89b7c4db..5ce053a 100644 --- a/libjava/classpath/java/util/GregorianCalendar.java +++ b/libjava/classpath/java/util/GregorianCalendar.java @@ -588,7 +588,7 @@ public class GregorianCalendar extends Calendar day = offs + 7 * (fields[WEEK_OF_MONTH] - 1); offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); - if (offs <= 0) + if (offs < 0) offs += 7; day += offs; } diff --git a/libjava/classpath/java/util/HashMap.java b/libjava/classpath/java/util/HashMap.java index 7176db0..a734af4 100644 --- a/libjava/classpath/java/util/HashMap.java +++ b/libjava/classpath/java/util/HashMap.java @@ -849,12 +849,9 @@ public class HashMap extends AbstractMap /** * Returns true if the Iterator has more elements. * @return true if there are more elements - * @throws ConcurrentModificationException if the HashMap was modified */ public boolean hasNext() { - if (knownMod != modCount) - throw new ConcurrentModificationException(); return count > 0; } diff --git a/libjava/classpath/java/util/Hashtable.java b/libjava/classpath/java/util/Hashtable.java index 76b0d5c..4c00d18 100644 --- a/libjava/classpath/java/util/Hashtable.java +++ b/libjava/classpath/java/util/Hashtable.java @@ -1017,12 +1017,9 @@ public class Hashtable extends Dictionary /** * Returns true if the Iterator has more elements. * @return true if there are more elements - * @throws ConcurrentModificationException if the hashtable was modified */ public boolean hasNext() { - if (knownMod != modCount) - throw new ConcurrentModificationException(); return count > 0; } diff --git a/libjava/classpath/java/util/IdentityHashMap.java b/libjava/classpath/java/util/IdentityHashMap.java index 6369fac..89ef034 100644 --- a/libjava/classpath/java/util/IdentityHashMap.java +++ b/libjava/classpath/java/util/IdentityHashMap.java @@ -705,12 +705,9 @@ public class IdentityHashMap extends AbstractMap /** * Returns true if the Iterator has more elements. * @return true if there are more elements - * @throws ConcurrentModificationException if the Map was modified */ public boolean hasNext() { - if (knownMod != modCount) - throw new ConcurrentModificationException(); return count > 0; } diff --git a/libjava/classpath/java/util/InvalidPropertiesFormatException.java b/libjava/classpath/java/util/InvalidPropertiesFormatException.java index 6540c23..aaa6c4e 100644 --- a/libjava/classpath/java/util/InvalidPropertiesFormatException.java +++ b/libjava/classpath/java/util/InvalidPropertiesFormatException.java @@ -39,11 +39,16 @@ exception statement from your version. */ package java.util; import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; -// FIXME: serialization methods should throw NotSerializableException /** @since 1.5 */ public class InvalidPropertiesFormatException extends IOException { + // This class won't serialize, but we have a UID to placate the compiler. + private static final long serialVersionUID = 7763056076009360219L; + public InvalidPropertiesFormatException(String message) { super(message); @@ -54,4 +59,14 @@ public class InvalidPropertiesFormatException extends IOException super(); initCause(cause); } + + private void writeObject(ObjectOutputStream out) throws IOException + { + throw new NotSerializableException("objects of this type are not serializable"); + } + + private void readObject(ObjectInputStream in) throws IOException + { + throw new NotSerializableException("objects of this type are not serializable"); + } } diff --git a/libjava/classpath/java/util/LinkedHashMap.java b/libjava/classpath/java/util/LinkedHashMap.java index 8e895a9..2b002b2 100644 --- a/libjava/classpath/java/util/LinkedHashMap.java +++ b/libjava/classpath/java/util/LinkedHashMap.java @@ -452,12 +452,9 @@ public class LinkedHashMap extends HashMap * Returns true if the Iterator has more elements. * * @return true if there are more elements - * @throws ConcurrentModificationException if the HashMap was modified */ public boolean hasNext() { - if (knownMod != modCount) - throw new ConcurrentModificationException(); return current != null; } diff --git a/libjava/classpath/java/util/LinkedList.java b/libjava/classpath/java/util/LinkedList.java index 2a35425..e77ae53 100644 --- a/libjava/classpath/java/util/LinkedList.java +++ b/libjava/classpath/java/util/LinkedList.java @@ -804,11 +804,9 @@ public class LinkedList extends AbstractSequentialList * Returns the index of the next element. * * @return the next index - * @throws ConcurrentModificationException if the list was modified */ public int nextIndex() { - checkMod(); return position; } @@ -816,11 +814,9 @@ public class LinkedList extends AbstractSequentialList * Returns the index of the previous element. * * @return the previous index - * @throws ConcurrentModificationException if the list was modified */ public int previousIndex() { - checkMod(); return position - 1; } @@ -828,11 +824,9 @@ public class LinkedList extends AbstractSequentialList * Returns true if more elements exist via next. * * @return true if next will succeed - * @throws ConcurrentModificationException if the list was modified */ public boolean hasNext() { - checkMod(); return (next != null); } @@ -840,11 +834,9 @@ public class LinkedList extends AbstractSequentialList * Returns true if more elements exist via previous. * * @return true if previous will succeed - * @throws ConcurrentModificationException if the list was modified */ public boolean hasPrevious() { - checkMod(); return (previous != null); } diff --git a/libjava/classpath/java/util/Locale.java b/libjava/classpath/java/util/Locale.java index 9e7bbfe..d2aead4 100644 --- a/libjava/classpath/java/util/Locale.java +++ b/libjava/classpath/java/util/Locale.java @@ -39,6 +39,7 @@ exception statement from your version. */ package java.util; import gnu.classpath.SystemProperties; +import gnu.java.locale.LocaleHelper; import java.io.IOException; import java.io.ObjectInputStream; @@ -65,11 +66,12 @@ import java.io.Serializable; * be separated by an underscore (U+005F). * * <p>The default locale is determined by the values of the system properties - * user.language, user.region, and user.variant, defaulting to "en". Note that - * the locale does NOT contain the conversion and formatting capabilities (for - * that, use ResourceBundle and java.text). Rather, it is an immutable tag - * object for identifying a given locale, which is referenced by these other - * classes when they must make locale-dependent decisions. + * user.language, user.country (or user.region), and user.variant, defaulting + * to "en_US". Note that the locale does NOT contain the conversion and + * formatting capabilities (for that, use ResourceBundle and java.text). + * Rather, it is an immutable tag object for identifying a given locale, which + * is referenced by these other classes when they must make locale-dependent + * decisions. * * @see ResourceBundle * @see java.text.Format @@ -209,10 +211,18 @@ public final class Locale implements Serializable, Cloneable * null. Note the logic in the main constructor, to detect when * bootstrapping has completed. */ - private static Locale defaultLocale = - getLocale(SystemProperties.getProperty("user.language", "en"), - SystemProperties.getProperty("user.region", ""), - SystemProperties.getProperty("user.variant", "")); + private static Locale defaultLocale; + + static { + String language = SystemProperties.getProperty("user.language", "en"); + String country = SystemProperties.getProperty("user.country", "US"); + String region = SystemProperties.getProperty("user.region", null); + String variant = SystemProperties.getProperty("user.variant", ""); + + defaultLocale = getLocale(language, + (region != null) ? region : country, + variant); + } /** * Array storing all the available two-letter ISO639 languages. @@ -236,38 +246,38 @@ public final class Locale implements Serializable, Cloneable } /** - * Retrieves the locale with the specified language and region + * Retrieves the locale with the specified language and country * from the cache. * * @param language the language of the locale to retrieve. - * @param region the region of the locale to retrieve. + * @param country the country of the locale to retrieve. * @return the locale. */ - private static Locale getLocale(String language, String region) + private static Locale getLocale(String language, String country) { - return getLocale(language, region, ""); + return getLocale(language, country, ""); } /** - * Retrieves the locale with the specified language, region + * Retrieves the locale with the specified language, country * and variant from the cache. * * @param language the language of the locale to retrieve. - * @param region the region of the locale to retrieve. + * @param country the country of the locale to retrieve. * @param variant the variant of the locale to retrieve. * @return the locale. */ - private static Locale getLocale(String language, String region, String variant) + private static Locale getLocale(String language, String country, String variant) { if (localeMap == null) localeMap = new HashMap(256); - String name = language + "_" + region + "_" + variant; + String name = language + "_" + country + "_" + variant; Locale locale = (Locale) localeMap.get(name); if (locale == null) { - locale = new Locale(language, region, variant); + locale = new Locale(language, country, variant); localeMap.put(name, locale); } @@ -384,33 +394,33 @@ public final class Locale implements Serializable, Cloneable { if (availableLocales == null) { - String[] localeNames = LocaleData.localeNames; - availableLocales = new Locale[localeNames.length]; + int len = LocaleHelper.getLocaleCount(); + availableLocales = new Locale[len]; - for (int i = 0; i < localeNames.length; i++) + for (int i = 0; i < len; i++) { String language; - String region = ""; + String country = ""; String variant = ""; - String name = localeNames[i]; + String name = LocaleHelper.getLocaleName(i); language = name.substring(0, 2); if (name.length() > 2) - region = name.substring(3); + country = name.substring(3); - int index = region.indexOf("_"); + int index = country.indexOf("_"); if (index > 0) { - variant = region.substring(index + 1); - region = region.substring(0, index - 1); + variant = country.substring(index + 1); + country = country.substring(0, index - 1); } - availableLocales[i] = getLocale(language, region, variant); + availableLocales[i] = getLocale(language, country, variant); } } - return availableLocales; + return (Locale[]) availableLocales.clone(); } /** @@ -426,7 +436,7 @@ public final class Locale implements Serializable, Cloneable countryCache = getISOStrings("territories"); } - return countryCache; + return (String[]) countryCache.clone(); } /** @@ -441,7 +451,7 @@ public final class Locale implements Serializable, Cloneable { languageCache = getISOStrings("languages"); } - return languageCache; + return (String[]) languageCache.clone(); } /** diff --git a/libjava/classpath/java/util/SimpleTimeZone.java b/libjava/classpath/java/util/SimpleTimeZone.java index 0bda44c..d94f89a 100644 --- a/libjava/classpath/java/util/SimpleTimeZone.java +++ b/libjava/classpath/java/util/SimpleTimeZone.java @@ -774,7 +774,7 @@ public class SimpleTimeZone extends TimeZone * @param year The year. */ private int getDaysInMonth(int month, int year) - { + { if (month == Calendar.FEBRUARY) { if ((year & 3) != 0) diff --git a/libjava/classpath/java/util/TreeMap.java b/libjava/classpath/java/util/TreeMap.java index a00f257..60d0a4d 100644 --- a/libjava/classpath/java/util/TreeMap.java +++ b/libjava/classpath/java/util/TreeMap.java @@ -1434,12 +1434,9 @@ public class TreeMap extends AbstractMap /** * Returns true if the Iterator has more elements. * @return true if there are more elements - * @throws ConcurrentModificationException if the TreeMap was modified */ public boolean hasNext() { - if (knownMod != modCount) - throw new ConcurrentModificationException(); return next != max; } diff --git a/libjava/classpath/java/util/WeakHashMap.java b/libjava/classpath/java/util/WeakHashMap.java index 2ed982a..ef2444c 100644 --- a/libjava/classpath/java/util/WeakHashMap.java +++ b/libjava/classpath/java/util/WeakHashMap.java @@ -292,12 +292,9 @@ public class WeakHashMap extends AbstractMap implements Map /** * Checks if there are more entries. * @return true, iff there are more elements. - * @throws ConcurrentModificationException if the hash map was - * modified. */ public boolean hasNext() { - checkMod(); return nextEntry != null; } diff --git a/libjava/classpath/java/util/class-dependencies.conf b/libjava/classpath/java/util/class-dependencies.conf deleted file mode 100644 index 39f9606..0000000 --- a/libjava/classpath/java/util/class-dependencies.conf +++ /dev/null @@ -1,78 +0,0 @@ -# This property file contains dependencies of classes, methods, and -# field on other methods or classes. -# -# Syntax: -# -# <used>: <needed 1> [... <needed N>] -# -# means that when <used> is included, <needed 1> (... <needed N>) must -# be included as well. -# -# <needed X> and <used> are of the form -# -# <class.methodOrField(signature)> -# -# or just -# -# <class> -# -# Within dependencies, variables can be used. A variable is defined as -# follows: -# -# {variable}: value1 value2 ... value<n> -# -# variables can be used on the right side of dependencies as follows: -# -# <used>: com.bla.blu.{variable}.Class.m()V -# -# The use of the variable will expand to <n> dependencies of the form -# -# <used>: com.bla.blu.value1.Class.m()V -# <used>: com.bla.blu.value2.Class.m()V -# ... -# <used>: com.bla.blu.value<n>.Class.m()V -# -# Variables can be redefined when building a system to select the -# required support for features like encodings, protocols, etc. -# -# Hints: -# -# - For methods and fields, the signature is mandatory. For -# specification, please see the Java Virtual Machine Specification by -# SUN. Unlike in the spec, field signatures (types) are in brackets. -# -# - Package names must be separated by '/' (and not '.'). E.g., -# java/lang/Class (this is necessary, because the '.' is used to -# separate method or field names from classes) -# -# - In case <needed> refers to a class, only the class itself will be -# included in the resulting binary, NOT necessarily all its methods -# and fields. If you want to refer to all methods and fields, you can -# write class.* as an abbreviation. -# -# - Abbreviations for packages are also possible: my/package/* means all -# methods and fields of all classes in my/package. -# -# - A line with a trailing '\' continues in the next line. - - -# All calendars supported are loaded via java/util/Calendar.getBundle or -# java/util/GregorianCalendar.getBundle from class -# gnu/java/locale/Calendar_{locale_id} -# -# This introduces a dependency for the localized calendars. To allow an easy -# selection and addition of locales, the library variable {calendar_locales} -# can be set to the set of supported calendar locales. -# - -{calendar_locales}: de en nl - -java/util/Calendar.getBundle(Ljava/util/Locale;)Ljava/util/ResourceBundle;: \ - gnu/java/locale/Calendar.* \ - gnu/java/locale/Calendar_{calendar_locales}.* - -java/util/GregorianCalendar.getBundle(Ljava/util/Locale;)Ljava/util/ResourceBundle;: \ - gnu/java/locale/Calendar.* \ - gnu/java/locale/Calendar_{calendar_locales}.* - -# end of file diff --git a/libjava/classpath/java/util/jar/Attributes.java b/libjava/classpath/java/util/jar/Attributes.java index c8babdd..92d29cf 100644 --- a/libjava/classpath/java/util/jar/Attributes.java +++ b/libjava/classpath/java/util/jar/Attributes.java @@ -37,6 +37,8 @@ exception statement from your version. */ package java.util.jar; +import gnu.java.util.jar.JarUtils; + import java.util.Collection; import java.util.Hashtable; import java.util.Map; @@ -65,7 +67,8 @@ import java.util.Set; * @see java.util.jar.Attributes.Name * @author Mark Wielaard (mark@klomp.org) */ -public class Attributes implements Cloneable, Map +public class Attributes + implements Cloneable, java.util.Map // Fully qualified for jikes 1.22 { // Fields @@ -121,14 +124,13 @@ public class Attributes implements Cloneable, Map * General main attribute - * the version of this Manifest file. */ - public static final Name MANIFEST_VERSION = new Name("Manifest-Version"); + public static final Name MANIFEST_VERSION = new Name(JarUtils.MANIFEST_VERSION); /** * General main attribute - * the version of the jar file signature. */ - public static final Name SIGNATURE_VERSION - = new Name("Signature-Version"); + public static final Name SIGNATURE_VERSION = new Name(JarUtils.SIGNATURE_VERSION); /** * General main attribute - @@ -433,7 +435,7 @@ public class Attributes implements Cloneable, Map * @returns the old value of the attribute name or null if it didn't exist * yet */ - public String putValue(Name name, String value) + private String putValue(Name name, String value) { return (String) put(name, value); } diff --git a/libjava/classpath/java/util/jar/JarFile.java b/libjava/classpath/java/util/jar/JarFile.java index 7ccbc60..88814f1 100644 --- a/libjava/classpath/java/util/jar/JarFile.java +++ b/libjava/classpath/java/util/jar/JarFile.java @@ -1,5 +1,5 @@ /* JarFile.java - Representation of a jar file - Copyright (C) 2000, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,7 @@ import gnu.java.io.Base64InputStream; import gnu.java.security.OID; import gnu.java.security.pkcs.PKCS7SignedData; import gnu.java.security.pkcs.SignerInfo; +import gnu.java.security.provider.Gnu; import java.io.ByteArrayOutputStream; import java.io.File; @@ -105,6 +106,14 @@ public class JarFile extends ZipFile /** The suffix for signature files. */ private static final String SF_SUFFIX = ".SF"; + /** + * The security provider to use for signature verification. + * We need a known fallback to be able to read any signed jar file + * (which might contain the user selected security provider). + * This is package-private to avoid accessor methods for inner classes. + */ + static final Gnu provider = new Gnu(); + // Signature OIDs. private static final OID MD2_OID = new OID("1.2.840.113549.2.2"); private static final OID MD4_OID = new OID("1.2.840.113549.2.4"); @@ -636,19 +645,19 @@ public class JarFile extends ZipFile { if (!signerInfo.getDigestAlgorithmId().equals(SHA1_OID)) return; - sig = Signature.getInstance("SHA1withDSA"); + sig = Signature.getInstance("SHA1withDSA", provider); } else if (alg.equals(RSA_ENCRYPTION_OID)) { OID hash = signerInfo.getDigestAlgorithmId(); if (hash.equals(MD2_OID)) - sig = Signature.getInstance("md2WithRsaEncryption"); + sig = Signature.getInstance("md2WithRsaEncryption", provider); else if (hash.equals(MD4_OID)) - sig = Signature.getInstance("md4WithRsaEncryption"); + sig = Signature.getInstance("md4WithRsaEncryption", provider); else if (hash.equals(MD5_OID)) - sig = Signature.getInstance("md5WithRsaEncryption"); + sig = Signature.getInstance("md5WithRsaEncryption", provider); else if (hash.equals(SHA1_OID)) - sig = Signature.getInstance("sha1WithRsaEncryption"); + sig = Signature.getInstance("sha1WithRsaEncryption", provider); else return; } @@ -756,7 +765,7 @@ public class JarFile extends ZipFile try { byte[] hash = Base64InputStream.decode((String) e.getValue()); - MessageDigest md = MessageDigest.getInstance(alg); + MessageDigest md = MessageDigest.getInstance(alg, provider); md.update(entryBytes); byte[] hash2 = md.digest(); if (DEBUG) @@ -939,8 +948,9 @@ public class JarFile extends ZipFile hashes.add(Base64InputStream.decode((String) e.getValue())); try { - md.add(MessageDigest.getInstance - (key.substring(0, key.length() - DIGEST_KEY_SUFFIX.length()))); + int length = key.length() - DIGEST_KEY_SUFFIX.length(); + String alg = key.substring(0, length); + md.add(MessageDigest.getInstance(alg, provider)); } catch (NoSuchAlgorithmException nsae) { diff --git a/libjava/classpath/java/util/jar/Manifest.java b/libjava/classpath/java/util/jar/Manifest.java index ff82aa2..aa869f4 100644 --- a/libjava/classpath/java/util/jar/Manifest.java +++ b/libjava/classpath/java/util/jar/Manifest.java @@ -37,16 +37,12 @@ exception statement from your version. */ package java.util.jar; -import java.io.BufferedReader; -import java.io.BufferedWriter; +import gnu.java.util.jar.JarUtils; + import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; import java.util.Hashtable; -import java.util.Iterator; import java.util.Map; /** @@ -156,282 +152,27 @@ public class Manifest implements Cloneable } /** - * XXX + * Read and merge a <code>Mainfest</code> from the designated input stream. + * + * @param in the input stream to read from. + * @throws IOException if an I/O related exception occurs during the process. */ public void read(InputStream in) throws IOException { - BufferedReader br = - new BufferedReader(new InputStreamReader(in, "8859_1")); - read_main_section(getMainAttributes(), br); - read_individual_sections(getEntries(), br); - } - - // Private Static methods for reading the Manifest file from BufferedReader - - private static void read_main_section(Attributes attr, - BufferedReader br) throws IOException - { - // According to the spec we should actually call read_version_info() here. - read_attributes(attr, br); - // Explicitly set Manifest-Version attribute if not set in Main - // attributes of Manifest. - if (attr.getValue(Attributes.Name.MANIFEST_VERSION) == null) - attr.putValue(Attributes.Name.MANIFEST_VERSION, "0.0"); - } - - /** - * Pedantic method that requires the next attribute in the Manifest to be - * the "Manifest-Version". This follows the Manifest spec closely but - * reject some jar Manifest files out in the wild. - */ - private static void read_version_info(Attributes attr, - BufferedReader br) throws IOException - { - String version_header = Attributes.Name.MANIFEST_VERSION.toString(); - try - { - String value = expect_header(version_header, br); - attr.putValue(Attributes.Name.MANIFEST_VERSION, value); - } - catch (IOException ioe) - { - throw new JarException("Manifest should start with a " + - version_header + ": " + ioe.getMessage()); - } - } - - private static String expect_header(String header, BufferedReader br) - throws IOException - { - String s = br.readLine(); - if (s == null) - { - throw new JarException("unexpected end of file"); - } - return expect_header(header, br, s); - } - - private static String expect_header(String header, BufferedReader br, - String s) throws IOException - { - try - { - String name = s.substring(0, header.length() + 1); - if (name.equalsIgnoreCase(header + ":")) - { - String value_start = s.substring(header.length() + 2); - return read_header_value(value_start, br); - } - } - catch (IndexOutOfBoundsException iobe) - { - } - // If we arrive here, something went wrong - throw new JarException("unexpected '" + s + "'"); - } - - private static String read_header_value(String s, BufferedReader br) - throws IOException - { - boolean try_next = true; - while (try_next) - { - // Lets see if there is something on the next line - br.mark(1); - if (br.read() == ' ') - { - s += br.readLine(); - } - else - { - br.reset(); - try_next = false; - } - } - return s; - } - - private static void read_attributes(Attributes attr, - BufferedReader br) throws IOException - { - String s = br.readLine(); - while (s != null && (!s.equals(""))) - { - read_attribute(attr, s, br); - s = br.readLine(); - } - } - - private static void read_attribute(Attributes attr, String s, - BufferedReader br) throws IOException - { - try - { - int colon = s.indexOf(": "); - String name = s.substring(0, colon); - String value_start = s.substring(colon + 2); - String value = read_header_value(value_start, br); - attr.putValue(name, value); - } - catch (IndexOutOfBoundsException iobe) - { - throw new JarException("Manifest contains a bad header: " + s); - } - } - - private static void read_individual_sections(Map entries, - BufferedReader br) throws - IOException - { - String s = br.readLine(); - while (s != null && (!s.equals(""))) - { - Attributes attr = read_section_name(s, br, entries); - read_attributes(attr, br); - s = br.readLine(); - } - } - - private static Attributes read_section_name(String s, BufferedReader br, - Map entries) throws JarException - { - try - { - String name = expect_header("Name", br, s); - Attributes attr = new Attributes(); - entries.put(name, attr); - return attr; - } - catch (IOException ioe) - { - throw new JarException - ("Section should start with a Name header: " + ioe.getMessage()); - } + JarUtils.readMFManifest(getMainAttributes(), getEntries(), in); } /** - * XXX + * Writes the contents of this <code>Manifest</code> to the designated + * output stream. Line-endings are platform-independent and consist of the + * 2-codepoint sequence <code>0x0D</code> and <code>0x0A</code>. + * + * @param out the output stream to write this <code>Manifest</code> to. + * @throws IOException if an I/O related exception occurs during the process. */ public void write(OutputStream out) throws IOException { - PrintWriter pw = - new PrintWriter(new - BufferedWriter(new OutputStreamWriter(out, "8859_1"))); - write_main_section(getMainAttributes(), pw); - pw.println(); - write_individual_sections(getEntries(), pw); - if (pw.checkError()) - { - throw new JarException("Error while writing manifest"); - } - } - - // Private Static functions for writing the Manifest file to a PrintWriter - - private static void write_main_section(Attributes attr, - PrintWriter pw) throws JarException - { - write_version_info(attr, pw); - write_main_attributes(attr, pw); - } - - private static void write_version_info(Attributes attr, PrintWriter pw) - { - // First check if there is already a version attribute set - String version = attr.getValue(Attributes.Name.MANIFEST_VERSION); - if (version == null) - { - version = "1.0"; - } - write_header(Attributes.Name.MANIFEST_VERSION.toString(), version, pw); - } - - private static void write_header(String name, String value, PrintWriter pw) - { - pw.print(name + ": "); - - int last = 68 - name.length(); - if (last > value.length()) - { - pw.println(value); - } - else - { - pw.println(value.substring(0, last)); - } - while (last < value.length()) - { - pw.print(" "); - int end = (last + 69); - if (end > value.length()) - { - pw.println(value.substring(last)); - } - else - { - pw.println(value.substring(last, end)); - } - last = end; - } - } - - private static void write_main_attributes(Attributes attr, PrintWriter pw) - throws JarException - { - Iterator it = attr.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry entry = (Map.Entry) it.next(); - // Don't print the manifest version again - if (!Attributes.Name.MANIFEST_VERSION.equals(entry.getKey())) - { - write_attribute_entry(entry, pw); - } - } - } - - private static void write_attribute_entry(Map.Entry entry, PrintWriter pw) - throws JarException - { - String name = entry.getKey().toString(); - String value = entry.getValue().toString(); - - if (name.equalsIgnoreCase("Name")) - { - throw new JarException("Attributes cannot be called 'Name'"); - } - if (name.startsWith("From")) - { - throw new - JarException("Header cannot start with the four letters 'From'" + - name); - } - write_header(name, value, pw); - } - - private static void write_individual_sections(Map entries, PrintWriter pw) - throws JarException - { - - Iterator it = entries.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry entry = (Map.Entry) it.next(); - write_header("Name", entry.getKey().toString(), pw); - write_entry_attributes((Attributes) entry.getValue(), pw); - pw.println(); - } - } - - private static void write_entry_attributes(Attributes attr, PrintWriter pw) - throws JarException - { - Iterator it = attr.entrySet().iterator(); - while (it.hasNext()) - { - Map.Entry entry = (Map.Entry) it.next(); - write_attribute_entry(entry, pw); - } + JarUtils.writeMFManifest(getMainAttributes(), getEntries(), out); } /** diff --git a/libjava/classpath/java/util/logging/Level.java b/libjava/classpath/java/util/logging/Level.java index 2c400dc..48ff318 100644 --- a/libjava/classpath/java/util/logging/Level.java +++ b/libjava/classpath/java/util/logging/Level.java @@ -1,5 +1,5 @@ /* Level.java -- a class for indicating logging levels - Copyright (C) 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -341,6 +341,9 @@ public class Level implements Serializable for (int i = 0; i < knownLevels.length; i++) { + // It's safe to use == instead of .equals here because only the + // standard logging levels will be returned by this method, and + // they are all created using string literals. if (name == knownLevels[i].name) return knownLevels[i]; } diff --git a/libjava/classpath/java/util/logging/LogManager.java b/libjava/classpath/java/util/logging/LogManager.java index 73eb9bc..e260481 100644 --- a/libjava/classpath/java/util/logging/LogManager.java +++ b/libjava/classpath/java/util/logging/LogManager.java @@ -1,6 +1,6 @@ /* LogManager.java -- a class for maintaining Loggers and managing configuration properties - Copyright (C) 2002,2005 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -48,11 +48,14 @@ import java.lang.ref.WeakReference; import java.net.URL; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.StringTokenizer; +import gnu.classpath.SystemProperties; + /** * The <code>LogManager</code> maintains a hierarchical namespace * of Logger objects and manages properties for configuring the logging @@ -114,7 +117,6 @@ public class LogManager * a WeakReference to it. */ private Map loggers; - final Logger rootLogger; /** * The properties for the logging framework which have been @@ -135,83 +137,62 @@ public class LogManager * this case. */ private final PropertyChangeSupport pcs = new PropertyChangeSupport( /* source bean */ - LogManager.class); + LogManager.class); protected LogManager() { - if (logManager != null) - throw new IllegalStateException("there can be only one LogManager; use LogManager.getLogManager()"); - - logManager = this; - loggers = new java.util.HashMap(); - rootLogger = new Logger("", null); - rootLogger.setLevel(Level.INFO); - addLogger(rootLogger); - - /* Make sure that Logger.global has the rootLogger as its parent. - * - * Logger.global is set during class initialization of Logger, - * which may or may not be before this code is being executed. - * For example, on the Sun 1.3.1 and 1.4.0 JVMs, Logger.global - * has been set before this code is being executed. In contrast, - * Logger.global still is null on GCJ 3.2. Since the LogManager - * and Logger classes are mutually dependent, both behaviors are - * correct. - * - * This means that we cannot depend on Logger.global to have its - * value when this code executes, although that variable is final. - * Since Logger.getLogger will always return the same logger for - * the same name, the subsequent line works fine irrespective of - * the order in which classes are initialized. - */ - Logger.getLogger("global").setParent(rootLogger); - Logger.getLogger("global").setUseParentHandlers(true); + loggers = new HashMap(); } /** * Returns the globally shared LogManager instance. */ - public static LogManager getLogManager() + public static synchronized LogManager getLogManager() { + if (logManager == null) + { + logManager = makeLogManager(); + initLogManager(); + } return logManager; } - static - { - makeLogManager(); - - /* The Javadoc description of the class explains - * what is going on here. - */ - Object configurator = createInstance(System.getProperty("java.util.logging.config.class"), - /* must be instance of */ Object.class); - - try - { - if (configurator == null) - getLogManager().readConfiguration(); - } - catch (IOException ex) - { - /* FIXME: Is it ok to ignore exceptions here? */ - } - } + private static final String MANAGER_PROPERTY = "java.util.logging.manager"; private static LogManager makeLogManager() { - String managerClassName; - LogManager manager; + String managerClassName = SystemProperties.getProperty(MANAGER_PROPERTY); + LogManager manager = (LogManager) createInstance + (managerClassName, LogManager.class, MANAGER_PROPERTY); + if (manager == null) + manager = new LogManager(); + return manager; + } - managerClassName = System.getProperty("java.util.logging.manager"); - manager = (LogManager) createInstance(managerClassName, LogManager.class); - if (manager != null) - return manager; + private static final String CONFIG_PROPERTY = "java.util.logging.config.class"; - if (managerClassName != null) - System.err.println("WARNING: System property \"java.util.logging.manager\"" - + " should be the name of a subclass of java.util.logging.LogManager"); + private static void initLogManager() + { + LogManager manager = getLogManager(); + Logger.root.setLevel(Level.INFO); + manager.addLogger(Logger.root); + + /* The Javadoc description of the class explains + * what is going on here. + */ + Object configurator = createInstance(System.getProperty(CONFIG_PROPERTY), + /* must be instance of */ Object.class, + CONFIG_PROPERTY); - return new LogManager(); + try + { + if (configurator == null) + manager.readConfiguration(); + } + catch (IOException ex) + { + /* FIXME: Is it ok to ignore exceptions here? */ + } } /** @@ -314,7 +295,7 @@ public class LogManager if(index > -1) searchName = searchName.substring(0,index); else - searchName = ""; + searchName = ""; } logger.setLevel(logLevel); @@ -324,12 +305,12 @@ public class LogManager * When adding "foo.bar", the logger "foo.bar.baz" should change * its parent to "foo.bar". */ - if (parent != rootLogger) + if (parent != Logger.root) { for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();) { Logger possChild = (Logger) ((WeakReference) loggers.get(iter.next())) - .get(); + .get(); if ((possChild == null) || (possChild == logger) || (possChild.getParent() != parent)) continue; @@ -367,14 +348,14 @@ public class LogManager { String childName = child.getName(); int childNameLength = childName.length(); - Logger best = rootLogger; + Logger best = Logger.root; int bestNameLength = 0; Logger cand; String candName; int candNameLength; - if (child == rootLogger) + if (child == Logger.root) return null; for (Iterator iter = loggers.keySet().iterator(); iter.hasNext();) @@ -468,7 +449,7 @@ public class LogManager if (logger == null) iter.remove(); - else if (logger != rootLogger) + else if (logger != Logger.root) { logger.resetLogger(); logger.setLevel(null); @@ -476,8 +457,8 @@ public class LogManager } } - rootLogger.setLevel(Level.INFO); - rootLogger.resetLogger(); + Logger.root.setLevel(Level.INFO); + Logger.root.resetLogger(); } /** @@ -524,11 +505,11 @@ public class LogManager // If no config file could be found use a default configuration. if(inputStream == null) - { - String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n" + { + String defaultConfig = "handlers = java.util.logging.ConsoleHandler \n" + ".level=INFO \n"; - inputStream = new ByteArrayInputStream(defaultConfig.getBytes()); - } + inputStream = new ByteArrayInputStream(defaultConfig.getBytes()); + } } else inputStream = new java.io.FileInputStream(path); @@ -574,21 +555,9 @@ public class LogManager while (tokenizer.hasMoreTokens()) { String handlerName = tokenizer.nextToken(); - try - { - Class handlerClass = ClassLoader.getSystemClassLoader().loadClass(handlerName); - getLogger("").addHandler((Handler) handlerClass - .newInstance()); - } - catch (ClassCastException ex) - { - System.err.println("[LogManager] class " + handlerName - + " is not subclass of java.util.logging.Handler"); - } - catch (Exception ex) - { - //System.out.println("[LogManager.readConfiguration]"+ex); - } + Handler handler = (Handler) + createInstance(handlerName, Handler.class, key); + Logger.root.addHandler(handler); } } @@ -602,14 +571,19 @@ public class LogManager logger = Logger.getLogger(loggerName); addLogger(logger); } + Level level = null; try - { - logger.setLevel(Level.parse(value)); - } - catch (Exception _) - { - //System.out.println("[LogManager.readConfiguration] "+_); - } + { + level = Level.parse(value); + } + catch (IllegalArgumentException e) + { + warn("bad level \'" + value + "\'", e); + } + if (level != null) + { + logger.setLevel(level); + } continue; } } @@ -748,19 +722,17 @@ public class LogManager */ static final Class getClassProperty(String propertyName, Class defaultValue) { - Class usingClass = null; + String propertyValue = logManager.getProperty(propertyName); - try - { - String propertyValue = logManager.getProperty(propertyName); - if (propertyValue != null) - usingClass = Class.forName(propertyValue); - if (usingClass != null) - return usingClass; - } - catch (Exception _) - { - } + if (propertyValue != null) + try + { + return locateClass(propertyValue); + } + catch (ClassNotFoundException e) + { + warn(propertyName + " = " + propertyValue, e); + } return defaultValue; } @@ -774,12 +746,17 @@ public class LogManager try { - Object obj = klass.newInstance(); - if (ofClass.isInstance(obj)) - return obj; + Object obj = klass.newInstance(); + if (ofClass.isInstance(obj)) + return obj; } - catch (Exception _) + catch (InstantiationException e) { + warn(propertyName + " = " + klass.getName(), e); + } + catch (IllegalAccessException e) + { + warn(propertyName + " = " + klass.getName(), e); } if (defaultClass == null) @@ -824,14 +801,17 @@ public class LogManager } /** - * Creates a new instance of a class specified by name. + * Creates a new instance of a class specified by name and verifies + * that it is an instance (or subclass of) a given type. * * @param className the name of the class of which a new instance * should be created. * - * @param ofClass the class to which the new instance should - * be either an instance or an instance of a subclass. - * FIXME: This description is just terrible. + * @param type the object created must be an instance of + * <code>type</code> or any subclass of <code>type</code> + * + * @param property the system property to reference in error + * messages * * @return the new instance, or <code>null</code> if * <code>className</code> is <code>null</code>, if no class @@ -839,28 +819,89 @@ public class LogManager * loading that class, or if the constructor of the class * has thrown an exception. */ - static final Object createInstance(String className, Class ofClass) + private static final Object createInstance(String className, Class type, + String property) { - Class klass; + Class klass = null; if ((className == null) || (className.length() == 0)) return null; try { - klass = Class.forName(className); - if (! ofClass.isAssignableFrom(klass)) - return null; - - return klass.newInstance(); + klass = locateClass(className); + if (type.isAssignableFrom(klass)) + return klass.newInstance(); + warn(property, className, "not an instance of " + type.getName()); + } + catch (ClassNotFoundException e) + { + warn(property, className, "class not found"); + } + catch (IllegalAccessException e) + { + warn(property, className, "illegal access"); } - catch (Exception _) + catch (InstantiationException e) { - return null; + warn(property, className, e); } - catch (java.lang.LinkageError _) + catch (java.lang.LinkageError e) { - return null; + warn(property, className, "linkage error"); } + + return null; } + + private static final void warn(String property, String klass, Throwable t) + { + warn(property, klass, null, t); + } + + private static final void warn(String property, String klass, String msg) + { + warn(property, klass, msg, null); + } + + private static final void warn(String property, String klass, String msg, + Throwable t) + { + warn("error instantiating '" + klass + "' referenced by " + property + + (msg == null ? "" : ", " + msg), t); + } + + /** + * All debug warnings go through this method. + */ + + private static final void warn(String msg, Throwable t) + { + System.err.println("WARNING: " + msg); + if (t != null) + t.printStackTrace(System.err); + } + + /** + * Locates a class by first checking the system class loader and + * then checking the context class loader. + * + * @param name the fully qualified name of the Class to locate + * @return Class the located Class + */ + + private static Class locateClass(String name) throws ClassNotFoundException + { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + try + { + return Class.forName(name, true, loader); + } + catch (ClassNotFoundException e) + { + loader = ClassLoader.getSystemClassLoader(); + return Class.forName(name, true, loader); + } + } + } diff --git a/libjava/classpath/java/util/logging/Logger.java b/libjava/classpath/java/util/logging/Logger.java index 367faad..29f19e4 100644 --- a/libjava/classpath/java/util/logging/Logger.java +++ b/libjava/classpath/java/util/logging/Logger.java @@ -1,5 +1,5 @@ /* Logger.java -- a class for logging messages - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -41,6 +41,8 @@ package java.util.logging; import java.util.List; import java.util.MissingResourceException; import java.util.ResourceBundle; +import java.security.AccessController; +import java.security.PrivilegedAction; /** * A Logger is used for logging information about events. Usually, there @@ -67,13 +69,29 @@ import java.util.ResourceBundle; */ public class Logger { + + static final Logger root = new Logger("", null); + /** * A logger provided to applications that make only occasional use * of the logging framework, typically early prototypes. Serious * products are supposed to create and use their own Loggers, so * they can be controlled individually. */ - public static final Logger global = getLogger("global"); + public static final Logger global; + + static + { + // Our class might be initialized from an unprivileged context + global = (Logger) AccessController.doPrivileged + (new PrivilegedAction() + { + public Object run() + { + return getLogger("global"); + } + }); + } /** @@ -175,7 +193,7 @@ public class Logger /* This is null when the root logger is being constructed, * and the root logger afterwards. */ - parent = LogManager.getLogManager().rootLogger; + parent = root; useParentHandlers = (parent != null); } @@ -1148,16 +1166,12 @@ public class Logger */ public synchronized void setParent(Logger parent) { - LogManager lm; - /* Throw a new NullPointerException if parent is null. */ parent.getClass(); - lm = LogManager.getLogManager(); - - if (this == lm.rootLogger) + if (this == root) throw new IllegalArgumentException( - "only the root logger can have a null parent"); + "the root logger can only have a null parent"); /* An application is allowed to control an anonymous logger * without having the permission to control the logging diff --git a/libjava/classpath/java/util/regex/Matcher.java b/libjava/classpath/java/util/regex/Matcher.java index 98086bf..e86be25 100644 --- a/libjava/classpath/java/util/regex/Matcher.java +++ b/libjava/classpath/java/util/regex/Matcher.java @@ -40,6 +40,7 @@ package java.util.regex; import gnu.regexp.RE; import gnu.regexp.REMatch; +import gnu.regexp.CharIndexed; /** * Instance of a regular expression applied to a char sequence. @@ -50,6 +51,10 @@ public final class Matcher implements MatchResult { private Pattern pattern; private CharSequence input; + // We use CharIndexed as an input object to the getMatch method in order + // that /\G/ (the end of the previous match) may work. The information + // of the previous match is stored in the CharIndexed object. + private CharIndexed inputCharIndexed; private int position; private int appendPosition; private REMatch match; @@ -58,6 +63,7 @@ public final class Matcher implements MatchResult { this.pattern = pattern; this.input = input; + this.inputCharIndexed = RE.makeCharIndexed(input, 0); } /** @@ -119,7 +125,7 @@ public final class Matcher implements MatchResult public boolean find () { boolean first = (match == null); - match = pattern.getRE().getMatch(input, position); + match = pattern.getRE().getMatch(inputCharIndexed, position); if (match != null) { int endIndex = match.getEndIndex(); @@ -150,7 +156,7 @@ public final class Matcher implements MatchResult */ public boolean find (int start) { - match = pattern.getRE().getMatch(input, start); + match = pattern.getRE().getMatch(inputCharIndexed, start); if (match != null) { position = match.getEndIndex(); @@ -212,7 +218,7 @@ public final class Matcher implements MatchResult public boolean lookingAt () { - match = pattern.getRE().getMatch(input, 0); + match = pattern.getRE().getMatch(inputCharIndexed, 0); if (match != null) { if (match.getStartIndex() == 0) @@ -237,7 +243,7 @@ public final class Matcher implements MatchResult */ public boolean matches () { - match = pattern.getRE().getMatch(input, 0, RE.REG_TRY_ENTIRE_MATCH); + match = pattern.getRE().getMatch(inputCharIndexed, 0, RE.REG_TRY_ENTIRE_MATCH); if (match != null) { if (match.getStartIndex() == 0) diff --git a/libjava/classpath/java/util/regex/Pattern.java b/libjava/classpath/java/util/regex/Pattern.java index d39f1cf..8c19983 100644 --- a/libjava/classpath/java/util/regex/Pattern.java +++ b/libjava/classpath/java/util/regex/Pattern.java @@ -74,14 +74,16 @@ public final class Pattern implements Serializable this.flags = flags; int gnuFlags = 0; + gnuFlags |= RE.REG_ICASE_USASCII; if ((flags & CASE_INSENSITIVE) != 0) gnuFlags |= RE.REG_ICASE; if ((flags & MULTILINE) != 0) gnuFlags |= RE.REG_MULTILINE; if ((flags & DOTALL) != 0) gnuFlags |= RE.REG_DOT_NEWLINE; + if ((flags & UNICODE_CASE) != 0) + gnuFlags &= ~RE.REG_ICASE_USASCII; // not yet supported: - // if ((flags & UNICODE_CASE) != 0) gnuFlags = // if ((flags & CANON_EQ) != 0) gnuFlags = RESyntax syntax = RESyntax.RE_SYNTAX_JAVA_1_4; @@ -94,7 +96,7 @@ public final class Pattern implements Serializable if ((flags & COMMENTS) != 0) { - // Use a syntax with support for comments? + gnuFlags |= RE.REG_X_COMMENTS; } try diff --git a/libjava/classpath/java/util/zip/Deflater.java b/libjava/classpath/java/util/zip/Deflater.java index 7bc1a19..a4ec0e6 100644 --- a/libjava/classpath/java/util/zip/Deflater.java +++ b/libjava/classpath/java/util/zip/Deflater.java @@ -221,7 +221,6 @@ public class Deflater * where the compressor allocates native memory. * If you call any method (even reset) afterwards the behaviour is * <i>undefined</i>. - * @deprecated Just clear all references to deflater instead. */ public void end() { diff --git a/libjava/classpath/java/util/zip/DeflaterEngine.java b/libjava/classpath/java/util/zip/DeflaterEngine.java index 3eea7c2..f79e477 100644 --- a/libjava/classpath/java/util/zip/DeflaterEngine.java +++ b/libjava/classpath/java/util/zip/DeflaterEngine.java @@ -497,7 +497,7 @@ class DeflaterEngine implements DeflaterConstants throw new InternalError(); } } - huffman.tallyDist(strstart - matchStart, matchLen); + boolean full = huffman.tallyDist(strstart - matchStart, matchLen); lookahead -= matchLen; if (matchLen <= max_lazy && lookahead >= MIN_MATCH) @@ -516,7 +516,8 @@ class DeflaterEngine implements DeflaterConstants updateHash(); } matchLen = MIN_MATCH - 1; - continue; + if (!full) + continue; } else { diff --git a/libjava/classpath/java/util/zip/GZIPInputStream.java b/libjava/classpath/java/util/zip/GZIPInputStream.java index 2cea755..f244810 100644 --- a/libjava/classpath/java/util/zip/GZIPInputStream.java +++ b/libjava/classpath/java/util/zip/GZIPInputStream.java @@ -207,7 +207,7 @@ public class GZIPInputStream /* 2. Check the compression type (must be 8) */ int CM = in.read(); - if (CM != 8) + if (CM != Deflater.DEFLATED) throw new IOException("Error in GZIP header, data not in deflate format"); headCRC.update(CM); diff --git a/libjava/classpath/java/util/zip/Inflater.java b/libjava/classpath/java/util/zip/Inflater.java index 76de891..f1616d6 100644 --- a/libjava/classpath/java/util/zip/Inflater.java +++ b/libjava/classpath/java/util/zip/Inflater.java @@ -199,7 +199,6 @@ public class Inflater * with Sun's JDK, where the compressor allocates native memory. * If you call any method (even reset) afterwards the behaviour is * <i>undefined</i>. - * @deprecated Just clear all references to inflater instead. */ public void end () { diff --git a/libjava/classpath/java/util/zip/ZipConstants.java b/libjava/classpath/java/util/zip/ZipConstants.java index 6d66419..bdf9450 100644 --- a/libjava/classpath/java/util/zip/ZipConstants.java +++ b/libjava/classpath/java/util/zip/ZipConstants.java @@ -85,9 +85,6 @@ interface ZipConstants long ENDSIG = 'P'|('K'<<8)|(5<<16)|(6<<24); int ENDHDR = 22; - /* The following two fields are missing in SUN JDK */ - int ENDNRD = 4; - int ENDDCD = 6; int ENDSUB = 8; int ENDTOT = 10; int ENDSIZ = 12; diff --git a/libjava/classpath/java/util/zip/ZipFile.java b/libjava/classpath/java/util/zip/ZipFile.java index 7307ee9..b849551 100644 --- a/libjava/classpath/java/util/zip/ZipFile.java +++ b/libjava/classpath/java/util/zip/ZipFile.java @@ -43,6 +43,7 @@ import gnu.java.util.EmptyEnumeration; import java.io.EOFException; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; @@ -75,6 +76,11 @@ public class ZipFile implements ZipConstants */ public static final int OPEN_DELETE = 0x4; + /** + * This field isn't defined in the JDK's ZipConstants, but should be. + */ + static final int ENDNRD = 4; + // Name of this zip file. private final String name; @@ -86,6 +92,37 @@ public class ZipFile implements ZipConstants private boolean closed = false; + + /** + * Helper function to open RandomAccessFile and throw the proper + * ZipException in case opening the file fails. + * + * @param name the file name, or null if file is provided + * + * @param file the file, or null if name is provided + * + * @return the newly open RandomAccessFile, never null + */ + private RandomAccessFile openFile(String name, + File file) + throws ZipException, IOException + { + try + { + return + (name != null) + ? new RandomAccessFile(name, "r") + : new RandomAccessFile(file, "r"); + } + catch (FileNotFoundException f) + { + ZipException ze = new ZipException(f.getMessage()); + ze.initCause(f); + throw ze; + } + } + + /** * Opens a Zip file with the given name for reading. * @exception IOException if a i/o error occured. @@ -94,7 +131,7 @@ public class ZipFile implements ZipConstants */ public ZipFile(String name) throws ZipException, IOException { - this.raf = new RandomAccessFile(name, "r"); + this.raf = openFile(name,null); this.name = name; checkZipFile(); } @@ -107,7 +144,7 @@ public class ZipFile implements ZipConstants */ public ZipFile(File file) throws ZipException, IOException { - this.raf = new RandomAccessFile(file, "r"); + this.raf = openFile(null,file); this.name = file.getPath(); checkZipFile(); } @@ -134,7 +171,7 @@ public class ZipFile implements ZipConstants throw new IllegalArgumentException("invalid mode"); if ((mode & OPEN_DELETE) != 0) file.deleteOnExit(); - this.raf = new RandomAccessFile(file, "r"); + this.raf = openFile(null,file); this.name = file.getPath(); checkZipFile(); } @@ -408,7 +445,19 @@ public class ZipFile implements ZipConstants case ZipOutputStream.STORED: return inp; case ZipOutputStream.DEFLATED: - return new InflaterInputStream(inp, new Inflater(true)); + final Inflater inf = new Inflater(true); + final int sz = (int) entry.getSize(); + return new InflaterInputStream(inp, inf) + { + public int available() throws IOException + { + if (sz == -1) + return super.available(); + if (super.available() != 0) + return sz - inf.getTotalOut(); + return 0; + } + }; default: throw new ZipException("Unknown compression method " + method); } @@ -514,6 +563,7 @@ public class ZipFile implements ZipConstants pos = 0; fillBuffer(); } + return buffer[pos++] & 0xFF; } @@ -544,7 +594,7 @@ public class ZipFile implements ZipConstants len -= remain; totalBytesRead += remain; } - + return totalBytesRead; } |