diff options
author | Tom Tromey <tromey@redhat.com> | 2001-09-05 00:00:55 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2001-09-05 00:00:55 +0000 |
commit | a1f4e5ed0ad7c060fc1b90c3b363877cb8cca198 (patch) | |
tree | e84d2d5f42b8908733b2858f19c7f95e32335a86 | |
parent | 45932d27fb140524de00d4a08efea4cf75dd7ca0 (diff) | |
download | gcc-a1f4e5ed0ad7c060fc1b90c3b363877cb8cca198.zip gcc-a1f4e5ed0ad7c060fc1b90c3b363877cb8cca198.tar.gz gcc-a1f4e5ed0ad7c060fc1b90c3b363877cb8cca198.tar.bz2 |
SimpleDateFormat.java: Re-merged with Classpath.
* java/text/SimpleDateFormat.java: Re-merged with Classpath.
* gnu/gcj/text/LocaleData.java, gnu/gcj/text/LocaleData_en.java,
gnu/gcj/text/LocaleData_en_US.java: Removed.
* java/text/DateFormatSymbols.java (clone): Use Classpath
implementation.
(equals): Simplified.
(DateFormatSymbols): Look in gnu.java.locale for information.
(DateFormatSymbols(DateFormatSymbols)): Removed.
(safeGetResource): Removed.
(DateFormatSymbols): Throws MissingResourceException.
(ampmsDefault, erasDefault, localPatternCharsDefault,
monthsDefault, shortMonthsDefault, shortWeekdaysDefault,
weekdaysDefault, zoneStringsDefault): Removed.
* java/text/Collator.java (getAvailableLocales): Use modified
Classpath implementation.
(getInstance): Look in gnu.java.locale for information.
(clone): Rewrote.
* java/text/MessageFormat.java: Reindented.
(clone): Rewrote.
* java/text/FieldPosition.java: Merged with Classpath.
* java/text/ParsePosition.java: Merged with Classpath.
* java/text/Format.java: Merged with Classpath.
* java/text/StringCharacterIterator.java
(StringCharacterIterator(StringCharacterIterator,int,int)): New
constructor from Classpath.
* java/text/Annotation.java,
java/text/AttributedCharacterIterator.java,
java/text/AttributedString.java,
java/text/AttributedStringIterator.java: New from Classpath.
* java/text/CharacterIterator.java: Copied from Classpath.
* java/text/ChoiceFormat.java: Reindented.
(clone): Removed.
* gnu/java/text/BaseBreakIterator.java,
gnu/java/text/CharacterBreakIterator.java,
gnu/java/text/LineBreakIterator.java,
gnu/java/text/LocaleData_en.java,
gnu/java/text/LocaleData_en_US.java,
gnu/java/text/SentenceBreakIterator.java,
gnu/java/text/WordBreakIterator.java: Renamed from gnu/gcj/text/*.
* gnu/gcj/text/BaseBreakIterator.java (last): Advance past final
character.
* java/text/BreakIterator.java (getAvailableLocales): Use
Classpath implementation.
(getInstance): Look in gnu.java.locale for information.
(getCharacterInstance, getLineInstance, getSentenceInstance,
getWordInstance): Look in gnu.java.text for implementations.
* java/text/DecimalFormatSymbols.java: Reindented
(clone): Use Classpath implementation.
(DecimalFormatSymbols(DecimalFormatSymbols)): Removed.
(DecimalFormatSymbols(Locale)): Look in gnu.java.locale for
information.
* java/text/DateFormat.java: Merged with Classpath.
(getAvailableLocales): Use Classpath implementation.
(format(Object,StringBuffer,FieldPosition)): Minor cleanup.
(computeInstance): Look in gnu.java.locale for information.
* java/text/NumberFormat.java: Reindented.
(computeInstance): Look in gnu.java.locale for information.
(getAvailableLocales): Use implementation from Classpath.
(setMaximumIntegerDigits): Likewise.
(setMinimumIntegerDigits): Likewise.
(setMaximumFractionDigits): Likewise.
(clone): Removed.
* java/text/DecimalFormat.java: Reindented.
* gnu/java/locale/LocaleInformation_en.java: Copied from Classpath.
* gnu/java/locale/LocaleInformation_en_US.java: Copied from Classpath.
* Makefile.in: Rebuilt.
* Makefile.am (ordinary_java_source_files): Added all new files.
(ordinary_java_source_files): Renamed or removed gnu/gcj/text/*.
* java/security/spec/AlgorithmParameterSpec.java,
java/security/spec/KeySpec.java: Re-merged with Classpath.
From-SVN: r45390
35 files changed, 5757 insertions, 2494 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 46741e1..1a542aa 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,76 @@ 2001-09-04 Tom Tromey <tromey@redhat.com> + * java/text/SimpleDateFormat.java: Re-merged with Classpath. + * gnu/gcj/text/LocaleData.java, gnu/gcj/text/LocaleData_en.java, + gnu/gcj/text/LocaleData_en_US.java: Removed. + * java/text/DateFormatSymbols.java (clone): Use Classpath + implementation. + (equals): Simplified. + (DateFormatSymbols): Look in gnu.java.locale for information. + (DateFormatSymbols(DateFormatSymbols)): Removed. + (safeGetResource): Removed. + (DateFormatSymbols): Throws MissingResourceException. + (ampmsDefault, erasDefault, localPatternCharsDefault, + monthsDefault, shortMonthsDefault, shortWeekdaysDefault, + weekdaysDefault, zoneStringsDefault): Removed. + * java/text/Collator.java (getAvailableLocales): Use modified + Classpath implementation. + (getInstance): Look in gnu.java.locale for information. + (clone): Rewrote. + * java/text/MessageFormat.java: Reindented. + (clone): Rewrote. + * java/text/FieldPosition.java: Merged with Classpath. + * java/text/ParsePosition.java: Merged with Classpath. + * java/text/Format.java: Merged with Classpath. + * java/text/StringCharacterIterator.java + (StringCharacterIterator(StringCharacterIterator,int,int)): New + constructor from Classpath. + * java/text/Annotation.java, + java/text/AttributedCharacterIterator.java, + java/text/AttributedString.java, + java/text/AttributedStringIterator.java: New from Classpath. + * java/text/CharacterIterator.java: Copied from Classpath. + * java/text/ChoiceFormat.java: Reindented. + (clone): Removed. + * gnu/java/text/BaseBreakIterator.java, + gnu/java/text/CharacterBreakIterator.java, + gnu/java/text/LineBreakIterator.java, + gnu/java/text/LocaleData_en.java, + gnu/java/text/LocaleData_en_US.java, + gnu/java/text/SentenceBreakIterator.java, + gnu/java/text/WordBreakIterator.java: Renamed from gnu/gcj/text/*. + * gnu/gcj/text/BaseBreakIterator.java (last): Advance past final + character. + * java/text/BreakIterator.java (getAvailableLocales): Use + Classpath implementation. + (getInstance): Look in gnu.java.locale for information. + (getCharacterInstance, getLineInstance, getSentenceInstance, + getWordInstance): Look in gnu.java.text for implementations. + * java/text/DecimalFormatSymbols.java: Reindented + (clone): Use Classpath implementation. + (DecimalFormatSymbols(DecimalFormatSymbols)): Removed. + (DecimalFormatSymbols(Locale)): Look in gnu.java.locale for + information. + * java/text/DateFormat.java: Merged with Classpath. + (getAvailableLocales): Use Classpath implementation. + (format(Object,StringBuffer,FieldPosition)): Minor cleanup. + (computeInstance): Look in gnu.java.locale for information. + * java/text/NumberFormat.java: Reindented. + (computeInstance): Look in gnu.java.locale for information. + (getAvailableLocales): Use implementation from Classpath. + (setMaximumIntegerDigits): Likewise. + (setMinimumIntegerDigits): Likewise. + (setMaximumFractionDigits): Likewise. + (clone): Removed. + * java/text/DecimalFormat.java: Reindented. + * gnu/java/locale/LocaleInformation_en.java: Copied from Classpath. + * gnu/java/locale/LocaleInformation_en_US.java: Copied from Classpath. + * Makefile.in: Rebuilt. + * Makefile.am (ordinary_java_source_files): Added all new files. + (ordinary_java_source_files): Renamed or removed gnu/gcj/text/*. + * java/security/spec/AlgorithmParameterSpec.java, + java/security/spec/KeySpec.java: Re-merged with Classpath. + Fix for PR libgcj/4213: * Makefile.am (ordinary_java_source_files): Added new file. * gnu/gcj/text/LocaleData.java: New file. diff --git a/libjava/Makefile.am b/libjava/Makefile.am index d80838a..65748dd 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -1123,14 +1123,6 @@ gnu/gcj/protocol/jar/Handler.java \ gnu/gcj/runtime/FileDeleter.java \ gnu/gcj/runtime/FirstThread.java \ gnu/gcj/runtime/VMClassLoader.java \ -gnu/gcj/text/BaseBreakIterator.java \ -gnu/gcj/text/CharacterBreakIterator.java \ -gnu/gcj/text/LineBreakIterator.java \ -gnu/gcj/text/LocaleData.java \ -gnu/gcj/text/LocaleData_en.java \ -gnu/gcj/text/LocaleData_en_US.java \ -gnu/gcj/text/SentenceBreakIterator.java \ -gnu/gcj/text/WordBreakIterator.java \ gnu/java/io/ClassLoaderObjectInputStream.java \ gnu/java/io/NullOutputStream.java \ gnu/java/io/ObjectIdentityWrapper.java \ @@ -1141,10 +1133,20 @@ gnu/java/locale/Calendar.java \ gnu/java/locale/Calendar_de.java \ gnu/java/locale/Calendar_en.java \ gnu/java/locale/Calendar_nl.java \ +gnu/java/locale/LocaleInformation.java \ +gnu/java/locale/LocaleInformation_de.java \ +gnu/java/locale/LocaleInformation_en.java \ +gnu/java/locale/LocaleInformation_en_US.java \ +gnu/java/locale/LocaleInformation_nl.java \ gnu/java/security/provider/DefaultPolicy.java \ gnu/java/security/provider/Gnu.java \ gnu/java/security/provider/SHA.java \ gnu/java/security/provider/SHA1PRNG.java \ +gnu/java/text/BaseBreakIterator.java \ +gnu/java/text/CharacterBreakIterator.java \ +gnu/java/text/LineBreakIterator.java \ +gnu/java/text/SentenceBreakIterator.java \ +gnu/java/text/WordBreakIterator.java \ gnu/java/util/DoubleEnumeration.java \ java/lang/ref/PhantomReference.java \ java/lang/ref/Reference.java \ @@ -1333,6 +1335,10 @@ java/sql/Struct.java \ java/sql/Time.java \ java/sql/Timestamp.java \ java/sql/Types.java \ +java/text/Annotation.java \ +java/text/AttributedCharacterIterator.java \ +java/text/AttributedString.java \ +java/text/AttributedStringIterator.java \ java/text/BreakIterator.java \ java/text/CharacterIterator.java \ java/text/ChoiceFormat.java \ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index b888b64..ff899e7 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -873,14 +873,6 @@ gnu/gcj/protocol/jar/Handler.java \ gnu/gcj/runtime/FileDeleter.java \ gnu/gcj/runtime/FirstThread.java \ gnu/gcj/runtime/VMClassLoader.java \ -gnu/gcj/text/BaseBreakIterator.java \ -gnu/gcj/text/CharacterBreakIterator.java \ -gnu/gcj/text/LineBreakIterator.java \ -gnu/gcj/text/LocaleData.java \ -gnu/gcj/text/LocaleData_en.java \ -gnu/gcj/text/LocaleData_en_US.java \ -gnu/gcj/text/SentenceBreakIterator.java \ -gnu/gcj/text/WordBreakIterator.java \ gnu/java/io/ClassLoaderObjectInputStream.java \ gnu/java/io/NullOutputStream.java \ gnu/java/io/ObjectIdentityWrapper.java \ @@ -891,10 +883,20 @@ gnu/java/locale/Calendar.java \ gnu/java/locale/Calendar_de.java \ gnu/java/locale/Calendar_en.java \ gnu/java/locale/Calendar_nl.java \ +gnu/java/locale/LocaleInformation.java \ +gnu/java/locale/LocaleInformation_de.java \ +gnu/java/locale/LocaleInformation_en.java \ +gnu/java/locale/LocaleInformation_en_US.java \ +gnu/java/locale/LocaleInformation_nl.java \ gnu/java/security/provider/DefaultPolicy.java \ gnu/java/security/provider/Gnu.java \ gnu/java/security/provider/SHA.java \ gnu/java/security/provider/SHA1PRNG.java \ +gnu/java/text/BaseBreakIterator.java \ +gnu/java/text/CharacterBreakIterator.java \ +gnu/java/text/LineBreakIterator.java \ +gnu/java/text/SentenceBreakIterator.java \ +gnu/java/text/WordBreakIterator.java \ gnu/java/util/DoubleEnumeration.java \ java/lang/ref/PhantomReference.java \ java/lang/ref/Reference.java \ @@ -1083,6 +1085,10 @@ java/sql/Struct.java \ java/sql/Time.java \ java/sql/Timestamp.java \ java/sql/Types.java \ +java/text/Annotation.java \ +java/text/AttributedCharacterIterator.java \ +java/text/AttributedString.java \ +java/text/AttributedStringIterator.java \ java/text/BreakIterator.java \ java/text/CharacterIterator.java \ java/text/ChoiceFormat.java \ @@ -1491,14 +1497,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/gnu/gcj/protocol/jar/Handler.P \ .deps/gnu/gcj/runtime/FileDeleter.P .deps/gnu/gcj/runtime/FirstThread.P \ .deps/gnu/gcj/runtime/VMClassLoader.P \ -.deps/gnu/gcj/runtime/natFirstThread.P \ -.deps/gnu/gcj/text/BaseBreakIterator.P \ -.deps/gnu/gcj/text/CharacterBreakIterator.P \ -.deps/gnu/gcj/text/LineBreakIterator.P .deps/gnu/gcj/text/LocaleData.P \ -.deps/gnu/gcj/text/LocaleData_en.P \ -.deps/gnu/gcj/text/LocaleData_en_US.P \ -.deps/gnu/gcj/text/SentenceBreakIterator.P \ -.deps/gnu/gcj/text/WordBreakIterator.P .deps/gnu/gcj/xlib/Clip.P \ +.deps/gnu/gcj/runtime/natFirstThread.P .deps/gnu/gcj/xlib/Clip.P \ .deps/gnu/gcj/xlib/Colormap.P .deps/gnu/gcj/xlib/Display.P \ .deps/gnu/gcj/xlib/Drawable.P .deps/gnu/gcj/xlib/Font.P \ .deps/gnu/gcj/xlib/GC.P .deps/gnu/gcj/xlib/Pixmap.P \ @@ -1543,6 +1542,11 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/gnu/java/lang/reflect/TypeSignature.P \ .deps/gnu/java/locale/Calendar.P .deps/gnu/java/locale/Calendar_de.P \ .deps/gnu/java/locale/Calendar_en.P .deps/gnu/java/locale/Calendar_nl.P \ +.deps/gnu/java/locale/LocaleInformation.P \ +.deps/gnu/java/locale/LocaleInformation_de.P \ +.deps/gnu/java/locale/LocaleInformation_en.P \ +.deps/gnu/java/locale/LocaleInformation_en_US.P \ +.deps/gnu/java/locale/LocaleInformation_nl.P \ .deps/gnu/java/rmi/dgc/DGCImpl.P .deps/gnu/java/rmi/dgc/DGCImpl_Skel.P \ .deps/gnu/java/rmi/dgc/DGCImpl_Stub.P \ .deps/gnu/java/rmi/registry/RegistryImpl.P \ @@ -1565,6 +1569,11 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/gnu/java/security/provider/Gnu.P \ .deps/gnu/java/security/provider/SHA.P \ .deps/gnu/java/security/provider/SHA1PRNG.P \ +.deps/gnu/java/text/BaseBreakIterator.P \ +.deps/gnu/java/text/CharacterBreakIterator.P \ +.deps/gnu/java/text/LineBreakIterator.P \ +.deps/gnu/java/text/SentenceBreakIterator.P \ +.deps/gnu/java/text/WordBreakIterator.P \ .deps/gnu/java/util/DoubleEnumeration.P .deps/interpret.P \ .deps/java/applet/Applet.P .deps/java/applet/AppletContext.P \ .deps/java/applet/AppletStub.P .deps/java/applet/AudioClip.P \ @@ -2024,6 +2033,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/java/sql/SQLOutput.P .deps/java/sql/SQLWarning.P \ .deps/java/sql/Statement.P .deps/java/sql/Struct.P \ .deps/java/sql/Time.P .deps/java/sql/Timestamp.P .deps/java/sql/Types.P \ +.deps/java/text/Annotation.P \ +.deps/java/text/AttributedCharacterIterator.P \ +.deps/java/text/AttributedString.P \ +.deps/java/text/AttributedStringIterator.P \ .deps/java/text/BreakIterator.P .deps/java/text/CharacterIterator.P \ .deps/java/text/ChoiceFormat.P \ .deps/java/text/CollationElementIterator.P \ diff --git a/libjava/gnu/gcj/text/BaseBreakIterator.java b/libjava/gnu/gcj/text/BaseBreakIterator.java deleted file mode 100644 index 8c20d46..0000000 --- a/libjava/gnu/gcj/text/BaseBreakIterator.java +++ /dev/null @@ -1,82 +0,0 @@ -// Base class for default BreakIterators. - -/* Copyright (C) 1999 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; - -import java.text.BreakIterator; -import java.text.CharacterIterator; - -/** - * @author Tom Tromey <tromey@cygnus.com> - * @date March 22, 1999 - */ - -public abstract class BaseBreakIterator extends BreakIterator -{ - public int current () - { - return iter.getIndex(); - } - - public int first () - { - iter.first(); - return iter.getBeginIndex(); - } - - public int following (int pos) - { - int save = iter.getIndex(); - iter.setIndex(pos); - int r = next (); - iter.setIndex(save); - return r; - } - - public CharacterIterator getText () - { - return iter; - } - - public int last () - { - iter.last(); - return iter.getEndIndex(); - } - - public int next (int n) - { - int r = iter.getIndex (); - if (n > 0) - { - while (n > 0 && r != DONE) - { - r = next (); - --n; - } - } - else if (n < 0) - { - while (n < 0 && r != DONE) - { - r = previous (); - ++n; - } - } - return r; - } - - public void setText (CharacterIterator newText) - { - iter = newText; - } - - protected CharacterIterator iter; -} diff --git a/libjava/gnu/gcj/text/LocaleData.java b/libjava/gnu/gcj/text/LocaleData.java deleted file mode 100644 index fc273b9..0000000 --- a/libjava/gnu/gcj/text/LocaleData.java +++ /dev/null @@ -1,25 +0,0 @@ -// Generic locale data for java.text. - -/* Copyright (C) 2001 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; - -import java.util.ListResourceBundle; - -public class LocaleData extends ListResourceBundle -{ - private static final Object[][] contents = - { - }; - - protected Object[][] getContents () - { - return contents; - } -} diff --git a/libjava/gnu/gcj/text/LocaleData_en.java b/libjava/gnu/gcj/text/LocaleData_en.java deleted file mode 100644 index c24c1121..0000000 --- a/libjava/gnu/gcj/text/LocaleData_en.java +++ /dev/null @@ -1,92 +0,0 @@ -// Generic English locale data for java.text. - -/* Copyright (C) 1999, 2000 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; - -import java.util.ListResourceBundle; - -/** - * @author Tom Tromey <tromey@cygnus.com> - * @date March 4, 1999 - */ - -public final class LocaleData_en extends ListResourceBundle -{ - // These are for DateFormatSymbols. - static final String[] ampmsDefault = {"AM", "PM" }; - static final String[] erasDefault = {"BC", "AD" }; - static final String localPatternCharsDefault = "GyMdkHmsSEDFwWahKz"; - static final String[] monthsDefault = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December", "" - }; - static final String[] shortMonthsDefault = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" - }; - static final String[] shortWeekdaysDefault = { - "", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - static final String[] weekdaysDefault = { - "", "Sunday", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", "Saturday" - }; - - private static final Object[][] contents = - { - // These are for DecimalFormatSymbols. - { "decimalSeparator", "." }, - { "digit", "#" }, - { "exponential", "E" }, - { "groupingSeparator", "," }, - { "infinity", "\u221e" }, - { "minusSign", "-" }, - { "monetarySeparator", "." }, - { "NaN", "\ufffd" }, - { "patternSeparator", ";" }, - { "percent", "%" }, - { "perMill", "\u2030" }, - { "zeroDigit", "0" }, - - // These are for NumberFormat. - { "numberFormat", "#,##0.###" }, - { "percentFormat", "#,##0%" }, - - // These are for DateFormatSymbols. - { "ampm", ampmsDefault }, - { "eras", erasDefault }, - { "datePatternChars", localPatternCharsDefault }, - { "months", monthsDefault }, - { "shortMonths", shortMonthsDefault }, - { "shortWeekdays", shortWeekdaysDefault }, - { "weekdays", weekdaysDefault }, - - // These are for DateFormat. - { "shortDateFormat", "M/d/yy" }, // Java's Y2K bug. - { "mediumDateFormat", "d-MMM-yy" }, - { "longDateFormat", "MMMM d, yyyy" }, - { "fullDateFormat", "EEEE MMMM d, yyyy G" }, - { "shortTimeFormat", "h:mm a" }, - { "mediumTimeFormat", "h:mm:ss a" }, - { "longTimeFormat", "h:mm:ss a z" }, - { "fullTimeFormat", "h:mm:ss;S 'o''clock' a z" }, - - // For RuleBasedCollator. - // FIXME: this is nowhere near complete. - // In particular we must mark accents as ignorable, - // and probably other things as well. - { "collatorRule", "< 0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < a,A < b,B < c,C < d,D < e,E < f,F < g,G < h,H < i,I < j,J < k,K < l,L < m,M < n,N < o,O < p,P < q,Q < r,R < s,S < t,T < u,U < v,V < w,W < x,X < y,Y < z,Z" } - }; - - protected Object[][] getContents () - { - return contents; - } -} diff --git a/libjava/gnu/gcj/text/LocaleData_en_US.java b/libjava/gnu/gcj/text/LocaleData_en_US.java deleted file mode 100644 index eb5d4f1..0000000 --- a/libjava/gnu/gcj/text/LocaleData_en_US.java +++ /dev/null @@ -1,81 +0,0 @@ -// US English locale data for java.text. - -/* Copyright (C) 1999 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; - -import java.util.ListResourceBundle; - -/** - * @author Tom Tromey <tromey@cygnus.com> - * @date March 4, 1999 - */ - -public final class LocaleData_en_US extends ListResourceBundle -{ - // These are for DateFormatSymbols. - static String[][] zoneStringsDefault = { - { "GMT", "Greenwich Mean Time", "GMT", - /**/ "Greenwich Mean Time", "GMT", "GMT" }, - { "PST", "Pacific Standard Time", "PST", - /**/ "Pacific Daylight Time", "PDT", "San Francisco" }, - { "MST", "Mountain Standard Time", "MST", - /**/ "Mountain Daylight Time", "MDT", "Denver" }, - { "PNT", "Mountain Standard Time", "MST", - /**/ "Mountain Standard Time", "MST", "Phoenix" }, - { "CST", "Central Standard Time", "CST", - /**/ "Central Daylight Time", "CDT", "Chicago" }, - { "EST", "Eastern Standard Time", "EST", - /**/ "Eastern Daylight Time", "EDT", "Boston" }, - { "IET", "Eastern Standard Time", "EST", - /**/ "Eastern Standard Time", "EST", "Indianapolis" }, - { "PRT", "Atlantic Standard Time", "AST", - /**/ "Atlantic Daylight Time", "ADT", "Halifax" }, - { "CNT", "Newfoundland Standard Time", "NST", - /**/ "Newfoundland Daylight Time", "NDT", "St. Johns" }, - { "ECT", "Central European Standard Time", "CET", - /**/ "Central European Daylight Time", "CEST", "Paris" }, - { "CTT", "China Standard Time", "CST", - /**/ "China Standard Time", "CST", "Shanghai" }, - { "JST", "Japan Standard Time", "JST", - /**/ "Japan Standard Time", "JST", "Tokyo" }, - { "HST", "Hawaii Standard Time", "HST", - /**/ "Hawaii Standard Time", "HST", "Honolulu" }, - { "AST", "Alaska Standard Time", "AKST", - /**/ "Alaska Daylight Time", "AKDT", "Anchorage" } - }; - - private static final Object[][] contents = - { - // These are for DecimalFormatSymbols. - { "currency", "$" }, - { "intlCurrencySymbol", "$" }, // FIXME? - - // These are for NumberFormat. - { "currencyFormat", "$#,##0.00;($#,##0.00)" }, - - // These are for DateFormatSymbols. - { "zoneStrings", zoneStringsDefault }, - - // These are for DateFormat. - { "shortDateFormat", "M/d/yy" }, // Java's Y2K bug. - { "mediumDateFormat", "d-MMM-yy" }, - { "longDateFormat", "MMMM d, yyyy" }, - { "fullDateFormat", "EEEE MMMM d, yyyy G" }, - { "shortTimeFormat", "h:mm a" }, - { "mediumTimeFormat", "h:mm:ss a" }, - { "longTimeFormat", "h:mm:ss a z" }, - { "fullTimeFormat", "h:mm:ss;S 'o''clock' a z" } - }; - - protected Object[][] getContents () - { - return contents; - } -} diff --git a/libjava/gnu/java/locale/LocaleInformation_de.java b/libjava/gnu/java/locale/LocaleInformation_de.java index 5eea905..208f2c5 100644 --- a/libjava/gnu/java/locale/LocaleInformation_de.java +++ b/libjava/gnu/java/locale/LocaleInformation_de.java @@ -1,5 +1,5 @@ /* LocaleInformation_de.java -- German locale data - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -47,7 +47,7 @@ public class LocaleInformation_de extends ListResourceBundle * proper format. */ private static final String collation_rules = - "-<0,1<2<3<4<5<6<7<8<9<A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<j,K" + + "<0<1<2<3<4<5<6<7<8<9<A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<k,K" + "<l,L<m,M<n,N<o,O<p,P<q,Q<r,R<s,S<t,T<u,U<v,V<w,W<x,X<y,Y,z<Z" + "&ae,\u00e4&Ae,\u00c4&oe,\u00f6&Oe,\u00d6&ue,\u00fc&Ue,\u00dc&ss,\u00df"; diff --git a/libjava/gnu/java/locale/LocaleInformation_en.java b/libjava/gnu/java/locale/LocaleInformation_en.java index 22e7371..61e351d 100644 --- a/libjava/gnu/java/locale/LocaleInformation_en.java +++ b/libjava/gnu/java/locale/LocaleInformation_en.java @@ -1,5 +1,5 @@ /* LocaleInformation_en.java -- US English locale data - Copyright (C) 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -32,301 +32,123 @@ import java.util.Calendar; import java.util.Date; /** - * This class contains locale data for the US English locale - */ - + * This class contains locale data for English. + */ public class LocaleInformation_en extends ListResourceBundle { -/* - * This area is used for defining object values - */ - -/** - * This is the set of collation rules used by java.text.RuleBasedCollator - * to sort strings properly. See the documentation of that class for the - * proper format. - */ -private static final String collation_rules = - "-<0,1<2<3<4<5<6<7<8<9A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<j,K" + + /* + * This area is used for defining object values + */ + + /** + * This is the set of collation rules used by java.text.RuleBasedCollator + * to sort strings properly. See the documentation of that class for the + * proper format. + */ + // FIXME: this is nowhere near complete. + // In particular we must mark accents as ignorable, + // and probably other things as well. + private static final String collation_rules = + "<0<1<2<3<4<5<6<7<8<9<A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<k,K" + "<l,L<m,M<n,N<o,O<p,P<q,Q<r,R<s,S<t,T<u,U<v,V<w,W<x,X<y,Y,z<Z"; -/* - * For the followings lists, strings that are subsets of other break strigns - * must be listed first. For example, if "\r" and "\r\n" are sequences, - * the "\r" must be first or it will never be used. - */ - -/** - * This is the list of word separator characters used by - * java.text.BreakIterator - */ -private static final String[] word_breaks = { " ", "\t", "\r\n", "\n" }; - -/** - * This is the list of sentence break sequences used by - * java.text.BreakIterator - */ -private static final String[] sentence_breaks = { ". " }; - -/** - * This is the list of potential line break locations. - */ -private static final String[] line_breaks = { "\t", "-", "\r\n", - "\n", ". ", ". ", ".", "? ", "? ", "?", "! ", "! ", "!", ", ", " " }; - -/** - * This is the list of months, fully spelled out - */ -private static final String[] months = { "January", "February", "March", - "April", "May", "June", "July", "August", "September", "October", - "November", "December", null }; - -/** - * This is the list of abbreviated month names - */ -private static final String[] shortMonths = { "Jan", "Feb", "Mar", "Apr", "May", - "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", null }; - -/** - * This is the list of weekdays, fully spelled out - */ -private static final String[] weekdays = { null, "Sunday", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", "Saturday" }; - -/** - * This is the list of abbreviated weekdays - */ -private static final String[] shortWeekdays = { null, "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" }; - -/** - * This is the list of AM/PM strings - */ -private static final String[] ampms = { "AM", "PM" }; - -/** - * This is the list of era identifiers - */ -private static final String[] eras = { "BC", "AD" }; - -/** - * This is the list of timezone strings. The JDK appears to include a - * city name as the sixth element. - */ -private static final String[][] zoneStrings = -{ - { "EST6EDT", "Eastern Standard Time", "EST", "Eastern Daylight Time", "EDT", - "New York" }, - { "EST6", "Eastern Standard Time", "EST", "Eastern Standard Time", "EST", - "Indianapolis" }, - { "CST6CDT", "Central Standard Time", "CST", "Central Daylight Time", "CDT", - "Chicago" }, - { "MST6MDT", "Mountain Standard Time", "MST", "Mountain Daylight Time", - "MDT", "Denver" }, - { "MST6", "Mountain Standard Time", "MST", "Mountain Standard Time", "MST", - "Phoenix" }, - { "PST6PDT", "Pacific Standard Time", "PDT", "Pacific Daylight Time", "PDT", - "San Francisco" }, - { "AST6ADT", "Alaska Standard Time", "AST", "Alaska Daylight Time", "ADT", - "Anchorage" }, - { "HST6HDT", "Hawaii Standard Time", "HST", "Hawaii Daylight Time", "HDT", - "Honolulu" }, - // European time zones. The city names are a little bit random. - { "WET", "Western European Time", "WET", "Western European Savings Time", "WEST", "London" }, - { "CET", "Central European Time", "CET", "Central European Savings Time", "CEST", "Berlin" }, - { "EET", "Eastern European Time", "EET", "Eastern European Savings Time", "EEST", "Istanbul" }, -}; - -/** - * This is the list of pattern characters for formatting dates - */ -private static final String localPatternChars = "GyMdkHmsSEDFwWahKz"; // Not a mistake! - -/** - * This is the DateFormat.SHORT date format - */ -private static final String shortDateFormat = "M/d/yy"; - -/** - * This is the DateFormat.MEDIUM format - */ -private static final String mediumDateFormat = "dd-MMM-yy"; - -/** - * This is the DateFormat.LONG format - */ -private static final String longDateFormat = "MMMM d, yyyy"; - -/** - * This is the DateFormat.FULL format - */ -private static final String fullDateFormat = "EEEE, MMMM d, yyyy"; - -/** - * This is the DateFormat.DEFAULT format - */ -private static final String defaultDateFormat = "dd-MMM-yy"; - -/** - * This is the DateFormat.SHORT format - */ -private static final String shortTimeFormat = "h:mm a"; - -/** - * This is the DateFormat.MEDIUM format - */ -private static final String mediumTimeFormat = "h:mm:ss a"; - -/** - * This is the DateFormat.LONG format - */ -private static final String longTimeFormat = "h:mm:ss a z"; - -/** - * This is the DateFormat.FULL format - */ -private static final String fullTimeFormat = "h:mm:ss 'o''clock' a z"; - -/** - * This is the DateFormat.DEFAULT format - */ -private static final String defaultTimeFormat = "h:mm:ss a"; - -/** - * This is the currency symbol - */ -private static final String currencySymbol = "$"; - -/** - * This is the international currency symbol. - */ -private static final String intlCurrencySymbol = "US$"; - -/** - * This is the decimal point. - */ -private static final String decimalSeparator = "."; - -/** - * This is the exponential symbol - */ -private static final String exponential = "E"; - -/** - * This is the char used for digits in format strings - */ -private static final String digit = "#"; - -/** - * This is the grouping separator symbols - */ -private static final String groupingSeparator = ","; - -/** - * This is the symbols for infinity - */ -private static final String infinity = "\u221e"; - -/** - * This is the symbol for the not a number value - */ -private static final String NaN = "\ufffd"; - -/** - * This is the minus sign symbol. - */ -private static final String minusSign = "-"; - -/** - * This is the decimal separator in monetary values. - */ -private static final String monetarySeparator = "."; - -/** - * This is the separator between positive and negative subpatterns. - */ -private static final String patternSeparator = ";"; - -/** - * This is the percent sign - */ -private static final String percent = "%"; - -/** - * This is the per mille sign - */ -private static final String perMill = "\u2030"; - -/** - * This is the character for zero. - */ -private static final String zeroDigit = "0"; - -/*************************************************************************/ - -/** - * This is the object array used to hold the keys and values - * for this bundle - */ - -private static final Object[][] contents = -{ - // For RuleBasedCollator - { "collation_rules", collation_rules }, - // For BreakIterator - { "word_breaks", word_breaks }, - { "sentence_breaks", sentence_breaks }, - { "line_breaks", line_breaks }, - // For SimpleDateFormat/DateFormatSymbols - { "months", months }, - { "shortMonths", shortMonths }, - { "weekdays", weekdays }, - { "shortWeekdays", shortWeekdays }, - { "ampms", ampms }, - { "eras", eras }, - { "zoneStrings", zoneStrings }, - { "localPatternChars", localPatternChars }, - { "shortDateFormat", shortDateFormat }, - { "mediumDateFormat", mediumDateFormat }, - { "longDateFormat", longDateFormat }, - { "fullDateFormat", fullDateFormat }, - { "defaultDateFormat", defaultDateFormat }, - { "shortTimeFormat", shortTimeFormat }, - { "mediumTimeFormat", mediumTimeFormat }, - { "longTimeFormat", longTimeFormat }, - { "fullTimeFormat", fullTimeFormat }, - { "defaultTimeFormat", defaultTimeFormat }, - // For DecimalFormat/DecimalFormatSymbols - { "currencySymbol", currencySymbol }, - { "intlCurrencySymbol", intlCurrencySymbol }, - { "decimalSeparator", decimalSeparator }, - { "digit", digit }, - { "exponential", exponential }, - { "groupingSeparator", groupingSeparator }, - { "infinity", infinity }, - { "NaN", NaN }, - { "minusSign", minusSign }, - { "monetarySeparator", monetarySeparator }, - { "patternSeparator", patternSeparator }, - { "percent", percent }, - { "perMill", perMill }, - { "zeroDigit", zeroDigit }, -}; - -/*************************************************************************/ - -/** - * This method returns the object array of key, value pairs containing - * the data for this bundle. - * - * @return The key, value information. - */ -public Object[][] -getContents() -{ - return(contents); + /** + * This is the list of months, fully spelled out + */ + private static final String[] months = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December", null + }; + + /** + * This is the list of abbreviated month names + */ + private static final String[] shortMonths = + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", null + }; + + /** + * This is the list of weekdays, fully spelled out + */ + private static final String[] weekdays = + { + null, "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; + + /** + * This is the list of abbreviated weekdays + */ + private static final String[] shortWeekdays = + { + null, "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat" + }; + + /** + * This is the list of AM/PM strings + */ + private static final String[] ampms = { "AM", "PM" }; + + /** + * This is the list of era identifiers + */ + private static final String[] eras = { "BC", "AD" }; + + /*************************************************************************/ + + /** + * This is the object array used to hold the keys and values + * for this bundle + */ + + private static final Object[][] contents = + { + // For RuleBasedCollator + { "collation_rules", collation_rules }, + + // For SimpleDateFormat/DateFormatSymbols + { "months", months }, + { "shortMonths", shortMonths }, + { "weekdays", weekdays }, + { "shortWeekdays", shortWeekdays }, + { "ampms", ampms }, + { "eras", eras }, + { "localPatternChars", "GyMdkHmsSEDFwWahKz" }, + + // For DecimalFormat/DecimalFormatSymbols + { "decimalSeparator", "." }, + { "digit", "#" }, + { "exponential", "E" }, + { "groupingSeparator", "," }, + { "infinity", "\u221e" }, + { "NaN", "\ufffd" }, + { "minusSign", "-" }, + { "monetarySeparator", "." }, + { "patternSeparator", ";" }, + { "percent", "%" }, + { "perMill", "\u2030" }, + { "zeroDigit", "0" }, + + // For NumberFormat. + { "numberFormat", "#,##0.###" }, + { "percentFormat", "#,##0%" }, + }; + + /*************************************************************************/ + + /** + * This method returns the object array of key, value pairs containing + * the data for this bundle. + * + * @return The key, value information. + */ + public Object[][] getContents () + { + return contents; + } } - -} // class LocaleInformation_en - diff --git a/libjava/gnu/java/locale/LocaleInformation_en_US.java b/libjava/gnu/java/locale/LocaleInformation_en_US.java new file mode 100644 index 0000000..1278ccd --- /dev/null +++ b/libjava/gnu/java/locale/LocaleInformation_en_US.java @@ -0,0 +1,112 @@ +/* LocaleInformation_en.java -- US English locale data + Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package gnu.java.locale; + +import java.util.ListResourceBundle; +import java.util.Calendar; +import java.util.Date; + +/** + * This class contains locale data for English in the US. + */ +public class LocaleInformation_en_US extends ListResourceBundle +{ + // These are for DateFormatSymbols. + private static final String[][] zoneStrings = + { + { "GMT", "Greenwich Mean Time", "GMT", + /**/ "Greenwich Mean Time", "GMT", "GMT" }, + { "PST", "Pacific Standard Time", "PST", + /**/ "Pacific Daylight Time", "PDT", "San Francisco" }, + { "MST", "Mountain Standard Time", "MST", + /**/ "Mountain Daylight Time", "MDT", "Denver" }, + { "PNT", "Mountain Standard Time", "MST", + /**/ "Mountain Standard Time", "MST", "Phoenix" }, + { "CST", "Central Standard Time", "CST", + /**/ "Central Daylight Time", "CDT", "Chicago" }, + { "EST", "Eastern Standard Time", "EST", + /**/ "Eastern Daylight Time", "EDT", "Boston" }, + { "IET", "Eastern Standard Time", "EST", + /**/ "Eastern Standard Time", "EST", "Indianapolis" }, + { "PRT", "Atlantic Standard Time", "AST", + /**/ "Atlantic Daylight Time", "ADT", "Halifax" }, + { "CNT", "Newfoundland Standard Time", "NST", + /**/ "Newfoundland Daylight Time", "NDT", "St. Johns" }, + { "ECT", "Central European Standard Time", "CET", + /**/ "Central European Daylight Time", "CEST", "Paris" }, + { "CTT", "China Standard Time", "CST", + /**/ "China Standard Time", "CST", "Shanghai" }, + { "JST", "Japan Standard Time", "JST", + /**/ "Japan Standard Time", "JST", "Tokyo" }, + { "HST", "Hawaii Standard Time", "HST", + /**/ "Hawaii Standard Time", "HST", "Honolulu" }, + { "AST", "Alaska Standard Time", "AKST", + /**/ "Alaska Daylight Time", "AKDT", "Anchorage" } + }; + + /** + * This is the object array used to hold the keys and values + * for this bundle + */ + + private static final Object[][] contents = + { + // For SimpleDateFormat/DateFormatSymbols + { "zoneStrings", zoneStrings }, + { "shortDateFormat", "M/d/yy" }, // Java's Y2K bug. + { "mediumDateFormat", "d-MMM-yy" }, + { "longDateFormat", "MMMM d, yyyy" }, + { "defaultDateFormat", "d-MMMM-yy" }, + { "fullDateFormat", "EEEE MMMM d, yyyy G" }, + { "shortTimeFormat", "h:mm a" }, + { "mediumTimeFormat", "h:mm:ss a" }, + { "longTimeFormat", "h:mm:ss a z" }, + { "fullTimeFormat", "h:mm:ss;S 'o''clock' a z" }, + { "defaultTimeFormat", "h:mm:ss a" }, + + // For DecimalFormat/DecimalFormatSymbols + { "currencySymbol", "$" }, + { "intlCurrencySymbol", "US$" }, + + // For NumberFormat. + { "currencyFormat", "$#,##0.00;($#,##0.00)" } + }; + + /*************************************************************************/ + + /** + * This method returns the object array of key, value pairs containing + * the data for this bundle. + * + * @return The key, value information. + */ + public Object[][] getContents () + { + return contents; + } +} diff --git a/libjava/gnu/java/locale/LocaleInformation_nl.java b/libjava/gnu/java/locale/LocaleInformation_nl.java index 8b74c5b..43cdeb2 100644 --- a/libjava/gnu/java/locale/LocaleInformation_nl.java +++ b/libjava/gnu/java/locale/LocaleInformation_nl.java @@ -1,5 +1,5 @@ /* LocaleInformation_nl.java -- Dutch locale data - Copyright (C) 1999 Free Software Foundation, Inc. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -50,39 +50,9 @@ public class LocaleInformation_nl extends ListResourceBundle * This is the same rule as used in the English locale. */ private static final String collation_rules = - "-<0,1<2<3<4<5<6<7<8<9A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<j,K" + + "<0<1<2<3<4<5<6<7<8<9<A,a<b,B<c,C<d,D<e,E<f,F<g,G<h,H<i,I<j,J<k,K" + "<l,L<m,M<n,N<o,O<p,P<q,Q<r,R<s,S<t,T<u,U<v,V<w,W<x,X<y,Y,z<Z"; -/* - * For the followings lists, strings that are subsets of other break strings - * must be listed first. For example, if "\r" and "\r\n" are sequences, - * the "\r" must be first or it will never be used. - */ - -/** - * This is the list of word separator characters used by - * java.text.BreakIterator - * <p> - * This is the same list as used in the English local - */ -private static final String[] word_breaks = { " ", "\t", "\r\n", "\n" }; - -/** - * This is the list of sentence break sequences used by - * java.text.BreakIterator - * <p> - * This is the same list as used in the English local - */ -private static final String[] sentence_breaks = { ". " }; - -/** - * This is the list of potential line break locations. - * <p> - * This is the same list as used in the English local - */ -private static final String[] line_breaks = { "\t", "-", "\r\n", - "\n", ". ", ". ", ".", "? ", "? ", "?", "! ", "! ", "!", ", ", " " }; - /** * This is the list of months, fully spelled out */ @@ -281,10 +251,6 @@ private static final Object[][] contents = { // For RuleBasedCollator { "collation_rules", collation_rules }, - // For BreakIterator - { "word_breaks", word_breaks }, - { "sentence_breaks", sentence_breaks }, - { "line_breaks", line_breaks }, // For SimpleDateFormat/DateFormatSymbols { "months", months }, { "shortMonths", shortMonths }, diff --git a/libjava/gnu/java/text/BaseBreakIterator.java b/libjava/gnu/java/text/BaseBreakIterator.java new file mode 100644 index 0000000..3220253 --- /dev/null +++ b/libjava/gnu/java/text/BaseBreakIterator.java @@ -0,0 +1,101 @@ +/* BaseBreakIterator.java -- Base class for default BreakIterators + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package gnu.java.text; + +import java.text.BreakIterator; +import java.text.CharacterIterator; + +/** + * @author Tom Tromey <tromey@cygnus.com> + * @date March 22, 1999 + */ + +public abstract class BaseBreakIterator extends BreakIterator +{ + public int current () + { + return iter.getIndex(); + } + + public int first () + { + iter.first(); + return iter.getBeginIndex(); + } + + public int following (int pos) + { + int save = iter.getIndex(); + iter.setIndex(pos); + int r = next (); + iter.setIndex(save); + return r; + } + + public CharacterIterator getText () + { + return iter; + } + + public int last () + { + iter.last(); + // Go past the last character. + iter.next(); + return iter.getEndIndex(); + } + + public int next (int n) + { + int r = iter.getIndex (); + if (n > 0) + { + while (n > 0 && r != DONE) + { + r = next (); + --n; + } + } + else if (n < 0) + { + while (n < 0 && r != DONE) + { + r = previous (); + ++n; + } + } + return r; + } + + public void setText (CharacterIterator newText) + { + iter = newText; + } + + protected CharacterIterator iter; +} diff --git a/libjava/gnu/gcj/text/CharacterBreakIterator.java b/libjava/gnu/java/text/CharacterBreakIterator.java index ba087cc..68207ce 100644 --- a/libjava/gnu/gcj/text/CharacterBreakIterator.java +++ b/libjava/gnu/java/text/CharacterBreakIterator.java @@ -1,14 +1,31 @@ -// Default character BreakIterator. - -/* Copyright (C) 1999 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; +/* CharacterBreakIterator.java - Default character BreakIterator. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package gnu.java.text; import java.text.BreakIterator; import java.text.CharacterIterator; diff --git a/libjava/gnu/gcj/text/LineBreakIterator.java b/libjava/gnu/java/text/LineBreakIterator.java index 4540b7a..14c1b70 100644 --- a/libjava/gnu/gcj/text/LineBreakIterator.java +++ b/libjava/gnu/java/text/LineBreakIterator.java @@ -1,14 +1,31 @@ -// Default word BreakIterator. - -/* Copyright (C) 1999 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; +/* LineBreakIterator.java - Default word BreakIterator. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package gnu.java.text; import java.text.BreakIterator; import java.text.CharacterIterator; diff --git a/libjava/gnu/gcj/text/SentenceBreakIterator.java b/libjava/gnu/java/text/SentenceBreakIterator.java index af2ccf1..9f9e816 100644 --- a/libjava/gnu/gcj/text/SentenceBreakIterator.java +++ b/libjava/gnu/java/text/SentenceBreakIterator.java @@ -1,14 +1,31 @@ -// Default sentence BreakIterator. - -/* Copyright (C) 1999 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; +/* SentenceBreakIterator.java - Default sentence BreakIterator. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package gnu.java.text; import java.text.BreakIterator; import java.text.CharacterIterator; diff --git a/libjava/gnu/gcj/text/WordBreakIterator.java b/libjava/gnu/java/text/WordBreakIterator.java index 553cdef..5cf5014 100644 --- a/libjava/gnu/gcj/text/WordBreakIterator.java +++ b/libjava/gnu/java/text/WordBreakIterator.java @@ -1,14 +1,31 @@ -// Default word BreakIterator. - -/* Copyright (C) 1999 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ - -package gnu.gcj.text; +/* WordBreakIterator.java - Default word BreakIterator. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package gnu.java.text; import java.text.BreakIterator; import java.text.CharacterIterator; diff --git a/libjava/java/text/Annotation.java b/libjava/java/text/Annotation.java new file mode 100644 index 0000000..8e04a76 --- /dev/null +++ b/libjava/java/text/Annotation.java @@ -0,0 +1,102 @@ +/* Annotation.java -- Wrapper for a text attribute object + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package java.text; + +/** + * This class is used as a wrapper for a text attribute object. Annotation + * objects are associated with a specific range of text. Changing either + * the text range or the underlying text invalidates the object. + * + * @version 0.0 + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class Annotation +{ + +/* + * Instance Variables + */ + +/** + * This is the attribute object being wrappered + */ +private Object attrib; + +/*************************************************************************/ + +/** + * Constructors + */ + +/** + * This method initializes a new instance of <code>Annotation</code> to + * wrapper the specified text attribute object. + * + * @param attrib The text attribute <code>Object</code> to wrapper. + */ +public +Annotation(Object attrib) +{ + this.attrib = attrib; +} + +/*************************************************************************/ + +/* + * Instance Variables + */ + +/** + * This method returns the text attribute object this <code>Annotation</code> + * instance is wrappering. + * + * @return The text attribute object for this <code>Annotation</code>. + */ +public Object +getValue() +{ + return(attrib); +} + +/*************************************************************************/ + +/** + * This method returns a <code>String</code> representation of this + * object. + * + * @return This object as a <code>String</code>. + */ +public String +toString() +{ + return(getClass().getName() + "[value=" + attrib.toString() + "]"); +} + +} // class Annotation + diff --git a/libjava/java/text/AttributedCharacterIterator.java b/libjava/java/text/AttributedCharacterIterator.java new file mode 100644 index 0000000..379181e --- /dev/null +++ b/libjava/java/text/AttributedCharacterIterator.java @@ -0,0 +1,333 @@ +/* AttributedCharacterIterator.java -- Iterate over attributes + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package java.text; + +import java.io.Serializable; +import java.io.InvalidObjectException; +import java.util.Set; +import java.util.Map; + +/** + * This interface extends the <code>CharacterIterator</code> interface + * in order to support iteration over character attributes as well as + * over the characters themselves. + * <p> + * In addition to attributes of specific characters, this interface + * supports the concept of the "attribute run", which is an attribute + * that is defined for a particular value across an entire range of + * characters or which is undefined over a range of characters. + * + * @version 0.0 + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface AttributedCharacterIterator extends CharacterIterator +{ + +/* + * Inner Classes + */ + +/** + * This class defines attribute keys that are used as text attributes. + */ +public static class Attribute implements Serializable +{ + +/*************************************************************************/ + +/* + * Static Variables + */ + +/** + * This is the attribute for the language of the text. The value of + * attributes of this key type are instances of <code>Locale</code>. + */ +public static final Attribute LANGUAGE = new Attribute("LANGUAGE"); + +/** + * This is the attribute for the reading form of text. This is used + * for storing pronunciation along with the written text for languages + * which need it. The value of attributes of this key type are + * instances of <code>Annotation</code> which wrappers a <code>String</code>. + */ +public static final Attribute READING = new Attribute("READING"); + +/** + * This is the attribute for input method segments. The value of attributes + * of this key type are instances of <code>Annotation</code> which wrapper + * a <code>String</code>. + */ +public static final Attribute INPUT_METHOD_SEGMENT = + new Attribute("INPUT_METHOD_SEGMENT"); + +/*************************************************************************/ + +/* + * Instance Variables + */ + +/** + * This is the name of the attribute key + * @serial + */ +private String name; + +/*************************************************************************/ + +/* + * Constructors + */ + +/** + * This method initializes a new instance of this class with the specified + * name. + * + * @param name The name of this attribute key. + */ +protected +Attribute(String name) +{ + this.name = name; +} + +/*************************************************************************/ + +/* + * Instance Methods + */ + +/** + * This method returns the name of this attribute. + * + * @return The attribute name + */ +protected String +getName() +{ + return(name); +} + +/*************************************************************************/ + +/** + * This method resolves an instance of <code>AttributedCharacterIterator.Attribute</code> + * that is being deserialized to one of the three pre-defined attribute + * constants. It does this by comparing the names of the attributes. The + * constant that the deserialized object resolves to is returned. + * + * @return The resolved contant value + * + * @exception InvalidObjectException If the object being deserialized cannot be resolved. + */ +protected Object +readResolve() throws InvalidObjectException +{ + if (this.equals(READING)) + return(READING); + + if (this.equals(LANGUAGE)) + return(LANGUAGE); + + if (this.equals(INPUT_METHOD_SEGMENT)) + return(INPUT_METHOD_SEGMENT); + + throw new InvalidObjectException("Can't resolve Attribute: " + getName()); +} + +/*************************************************************************/ + +/** + * This method tests this object for equality against the specified object. + * The two objects will be considered equal if and only if: + * <ul> + * <li>The specified object is not <code>null</code>. + * <li>The specified object is an instance of <code>AttributedCharacterIterator.Attribute</code>. + * <li>The specified object has the same attribute name as this object. + * </ul> + * + * @param The <code>Object</code> to test for equality against this object. + * + * @return <code>true</code> if the specified object is equal to this one, <code>false</code> otherwise. + */ +public final boolean +equals(Object obj) +{ + if (obj == this) + return(true); + else + return(false); +} + +/*************************************************************************/ + +/** + * This method returns a hash value for this object. + * + * @return A hash value for this object. + */ +public final int +hashCode() +{ + return(super.hashCode()); +} + +/*************************************************************************/ + +/** + * This method returns a <code>String</code> representation of this object. + * + * @return A <code>String</code> representation of this object. + */ +public String +toString() +{ + return(getClass().getName() + "(" + getName() + ")"); +} + +} // Inner class Attribute + +/*************************************************************************/ + +/* + * Instance Methods + */ + +/** + * This method returns a list of all keys that are defined for the + * text range. This can be an empty list if no attributes are defined. + * + * @return A list of keys + */ +public abstract Set +getAllAttributeKeys(); + +/*************************************************************************/ + +/** + * This method returns a <code>Map</code> of the attributed defined for + * the current character. + * + * @return A <code>Map</code> of the attributes for the current character. + */ +public abstract Map +getAttributes(); + +/*************************************************************************/ + +/** + * This method returns the value of the specified attribute for the + * current character. If the attribute is not defined for the current + * character, <code>null</code> is returned. + * + * @param attrib The attribute to retrieve the value of. + * + * @return The value of the specified attribute + */ +public abstract Object +getAttribute(AttributedCharacterIterator.Attribute attrib); + +/*************************************************************************/ + +/** + * This method returns the index of the first character in the run that + * contains all attributes defined for the current character. + * + * @return The start index of the run + */ +public abstract int +getRunStart(); + +/*************************************************************************/ + +/** + * This method returns the index of the first character in the run that + * contains all attributes in the specified <code>Set</code> defined for + * the current character. + * + * @param attribs The <code>Set</code> of attributes. + * + * @return The start index of the run. + */ +public abstract int +getRunStart(Set attribs); + +/*************************************************************************/ + +/** + * This method returns the index of the first character in the run that + * contains the specified attribute defined for the current character. + * + * @param attrib The attribute. + * + * @return The start index of the run. + */ +public abstract int +getRunStart(AttributedCharacterIterator.Attribute attrib); + +/*************************************************************************/ + +/** + * This method returns the index of the character after the end of the run + * that contains all attributed defined for the current character. + * + * @return The end index of the run. + */ +public abstract int +getRunLimit(); + +/*************************************************************************/ + +/** + * This method returns the index of the character after the end of the run + * that contains all attributes in the specified <code>Set</code> defined + * for the current character. + * + * @param attribs The <code>Set</code> of attributes. + * + * @return The end index of the run. + */ +public abstract int +getRunLimit(Set attribs); + +/*************************************************************************/ + +/** + * This methods returns the index of the character after the end of the run + * that contains the specified attribute defined for the current character. + * + * @param attrib The attribute. + * + * @return The end index of the run. + */ +public abstract int +getRunLimit(AttributedCharacterIterator.Attribute attrib); + +} // interface AttributedCharacterIterator + diff --git a/libjava/java/text/AttributedString.java b/libjava/java/text/AttributedString.java new file mode 100644 index 0000000..cc664de --- /dev/null +++ b/libjava/java/text/AttributedString.java @@ -0,0 +1,431 @@ +/* AttributedString.java -- Models text with attributes + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package java.text; + +import java.util.Iterator; +import java.util.Hashtable; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * This class models a <code>String</code> with attributes over various + * subranges of the string. It allows applications to access this + * information via the <code>AttributedCharcterIterator</code> interface. + * + * @version 0.0 + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class AttributedString +{ + +/*************************************************************************/ + +/* + * Inner Classes + */ + +/** + * This class contains the attributes and ranges of text over which + * that attributes apply. + */ +final class AttributeRange +{ + +/* + * Instance Variables + */ + +/** + * A Map of the attributes + */ +Map attribs; + +/** + * The beginning index of the attributes + */ +int begin_index; + +/** + * The ending index of the attributes + */ +int end_index; + +/*************************************************************************/ + +/* + * Constructors + */ + +AttributeRange(Map attribs, int begin_index, int end_index) +{ + this.attribs = attribs; + this.begin_index = begin_index; + this.end_index = end_index; +} + +} // Inner class AttributeRange + +/*************************************************************************/ + +/* + * Instance Variables + */ + +/** + * This object holds the string we are representing. + */ +private StringCharacterIterator sci; + +/** + * This is the attribute information + */ +private AttributeRange[] attribs; + +/*************************************************************************/ + +/* + * Constructors + */ + +/** + * This method initializes a new instance of <code>AttributedString</code> + * that represents the specified <code>String</code> with no attributes. + * + * @param str The <code>String</code> to be attributed. + */ +public +AttributedString(String str) +{ + sci = new StringCharacterIterator(str); + attribs = new AttributeRange[0]; +} + +/*************************************************************************/ + +/** + * This method initializes a new instance of <code>AttributedString</code> + * that represents that specified <code>String</code> with the specified + * attributes over the entire length of the <code>String</code>. + * + * @param str The <code>String</code> to be attributed. + * @param attributes The attribute list. + */ +public +AttributedString(String str, Map attributes) +{ + this(str); + + attribs = new AttributeRange[1]; + attribs[0] = new AttributeRange(attributes, 0, str.length()); +} + +/*************************************************************************/ + +/** + * This method initializes a new instance of <code>AttributedString</code> + * that will use the text and attribute information from the specified + * <code>AttributedCharacterIterator</code>. + * + * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information. + */ +public +AttributedString(AttributedCharacterIterator aci) +{ + this(aci, aci.getBeginIndex(), aci.getEndIndex(), null); +} + +/*************************************************************************/ + +/** + * This method initializes a new instance of <code>AttributedString</code> + * that will use the text and attribute information from the specified + * subrange of the specified <code>AttributedCharacterIterator</code>. + * + * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information. + * @param begin_index The beginning index of the text subrange. + * @param end_index The ending index of the text subrange. + */ +public +AttributedString(AttributedCharacterIterator aci, int begin_index, + int end_index) +{ + this(aci, begin_index, end_index, null); +} + +/*************************************************************************/ + +/** + * This method initializes a new instance of <code>AttributedString</code> + * that will use the text and attribute information from the specified + * subrange of the specified <code>AttributedCharacterIterator</code>. + * Only attributes from the source iterator that are present in the + * specified array of attributes will be included in the attribute list + * for this object. + * + * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information. + * @param begin_index The beginning index of the text subrange. + * @param end_index The ending index of the text subrange. + * @param attributes A list of attributes to include from the iterator, or <code>null</code> to include all attributes. + */ +public +AttributedString(AttributedCharacterIterator aci, int begin_index, + int end_index, AttributedCharacterIterator.Attribute[] attributes) +{ + // Validate some arguments + if ((begin_index < 0) || (end_index < begin_index)) + throw new IllegalArgumentException("Bad index values"); + + StringBuffer sb = new StringBuffer(""); + + // Get the valid attribute list + Set all_attribs = aci.getAllAttributeKeys(); + if (attributes != null) + { + Set valid_attribs = new HashSet(); + Iterator iter = all_attribs.iterator(); + while (iter.hasNext()) + { + Object obj = iter.next(); + + int i; + for (i = 0; i < attributes.length; i++) + if (obj.equals(attributes[0])) + break; + + if (i == attributes.length) + continue; + + valid_attribs.add(obj); + } + + all_attribs = valid_attribs; + } + + // Loop through and extract the attributes + char c = aci.setIndex(begin_index); + + do + { + sb.append(c); + + Iterator iter = all_attribs.iterator(); + while(iter.hasNext()) + { + Object obj = iter.next(); + + // What should we do if this is not true? + if (!(obj instanceof AttributedCharacterIterator.Attribute)) + continue; + + AttributedCharacterIterator.Attribute attrib = + (AttributedCharacterIterator.Attribute)obj; + + // Make sure the attribute is defined. + int rl = aci.getRunLimit(attrib); + if (rl == -1) + continue; + if (rl > end_index) + rl = end_index; + rl -= begin_index; + + // Check to see if we already processed this one + int rs = aci.getRunStart(attrib); + if ((rs < aci.getIndex()) && (aci.getIndex() != begin_index)) + continue; + + // If the attribute run starts before the beginning index, we + // need to junk it if it is an Annotation. + Object attrib_obj = aci.getAttribute(attrib); + if (rs < begin_index) + { + if (attrib_obj instanceof Annotation) + continue; + + rs = begin_index; + } + else + { + rs -= begin_index; + } + + // Create a map object. Yes this will only contain one attribute + Map new_map = new Hashtable(); + new_map.put(attrib, attrib_obj); + + // Add it to the attribute list. Yes this is a bad way to do things. + AttributeRange[] new_list = new AttributeRange[attribs.length + 1]; + System.arraycopy(attribs, 0, new_list, 0, attribs.length); + attribs = new_list; + attribs[attribs.length - 1] = new AttributeRange(new_map, rs, rl); + } + + c = aci.next(); + } + while(c != CharacterIterator.DONE); + + sci = new StringCharacterIterator(sb.toString()); +} + +/*************************************************************************/ + +/* + * Instance Methods + */ + +/** + * This method adds a new attribute that will cover the entire string. + * + * @param attrib The attribute to add. + * @param value The value of the attribute. + */ +public void +addAttribute(AttributedCharacterIterator.Attribute attrib, Object value) +{ + addAttribute(attrib, value, 0, sci.getEndIndex() - 1); +} + +/*************************************************************************/ + +/** + * This method adds a new attribute that will cover the specified subrange + * of the string. + * + * @param attrib The attribute to add. + * @param value The value of the attribute. + * @param begin_index The beginning index of the subrange. + * @param end_index The ending index of the subrange. + * + * @exception IllegalArgumentException If attribute is <code>null</code> or the subrange is not valid. + */ +public void +addAttribute(AttributedCharacterIterator.Attribute attrib, Object value, + int begin_index, int end_index) +{ + if (attrib == null) + throw new IllegalArgumentException("null attribute"); + + Hashtable ht = new Hashtable(); + ht.put(attrib, value); + + addAttributes(ht, begin_index, end_index); +} + +/*************************************************************************/ + +/** + * This method adds all of the attributes in the specified list to the + * specified subrange of the string. + * + * @param attributes The list of attributes. + * @param begin_index The beginning index. + * @param end_index The ending index + * + * @param IllegalArgumentException If the list is <code>null</code> or the subrange is not valid. + */ +public void +addAttributes(Map attributes, int begin_index, int end_index) +{ + if (attributes == null) + throw new IllegalArgumentException("null attribute"); + + if ((begin_index < 0) || (end_index > sci.getEndIndex()) || + (end_index < begin_index)) + throw new IllegalArgumentException("bad range"); + + AttributeRange[] new_list = new AttributeRange[attribs.length + 1]; + System.arraycopy(attribs, 0, new_list, 0, attribs.length); + attribs = new_list; + attribs[attribs.length - 1] = new AttributeRange(attributes, begin_index, + end_index); +} + +/*************************************************************************/ + +/** + * This method returns an <code>AttributedCharacterIterator</code> that + * will iterate over the entire string. + * + * @return An <code>AttributedCharacterIterator</code> for the entire string. + */ +public AttributedCharacterIterator +getIterator() +{ + return(new AttributedStringIterator(sci, attribs, 0, sci.getEndIndex() - 1, + null)); +} + +/*************************************************************************/ + +/** + * This method returns an <code>AttributedCharacterIterator</code> that + * will iterate over the entire string. This iterator will return information + * about the list of attributes in the specified array. Attributes not in + * the array may or may not be returned by the iterator. If the specified + * array is <code>null</code>, all attributes will be returned. + * + * @param attributes A list of attributes to include in the returned iterator. + * + * @return An <code>AttributedCharacterIterator</code> for this string. + */ +public AttributedCharacterIterator +getIterator(AttributedCharacterIterator.Attribute[] attributes) +{ + return(getIterator(attributes, 0, sci.getEndIndex() - 1)); +} + +/*************************************************************************/ + +/** + * This method returns an <code>AttributedCharacterIterator</code> that + * will iterate over the specified subrange. This iterator will return information + * about the list of attributes in the specified array. Attributes not in + * the array may or may not be returned by the iterator. If the specified + * array is <code>null</code>, all attributes will be returned. + * + * @param attributes A list of attributes to include in the returned iterator. + * @param begin_index The beginning index of the subrange. + * @param end_index The ending index of the subrange. + * + * @return An <code>AttributedCharacterIterator</code> for this string. + */ +public AttributedCharacterIterator +getIterator(AttributedCharacterIterator.Attribute[] attributes, + int begin_index, int end_index) +{ + if ((begin_index < 0) || (end_index > sci.getEndIndex()) || + (end_index < begin_index)) + throw new IllegalArgumentException("bad range"); + + return(new AttributedStringIterator(sci, attribs, begin_index, end_index, + attributes)); +} + +} // class AttributedString + diff --git a/libjava/java/text/AttributedStringIterator.java b/libjava/java/text/AttributedStringIterator.java new file mode 100644 index 0000000..4d0e4e6 --- /dev/null +++ b/libjava/java/text/AttributedStringIterator.java @@ -0,0 +1,351 @@ +/* AttributedStringIterator.java -- Class to iterate over AttributedString + Copyright (C) 1998, 1999 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package java.text; + +import java.util.Set; +import java.util.HashSet; +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; + +/** + * This class implements the AttributedCharacterIterator interface. It + * is used by AttributedString.getIterator(). + * + * @version 0.0 + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +class AttributedStringIterator implements AttributedCharacterIterator +{ + +/*************************************************************************/ + +/** + * Instance Variables + */ + +/** + * The character iterator containing the text + */ +private CharacterIterator ci; + +/** + * The list of attributes and ranges + */ +private AttributedString.AttributeRange[] attribs; + +/** + * The list of attributes that the user is interested in. We may, + * at our option, not return any other attributes. + */ +private AttributedCharacterIterator.Attribute[] restricts; + +/*************************************************************************/ + +/* + * Constructors + */ + +AttributedStringIterator(StringCharacterIterator sci, + AttributedString.AttributeRange[] attribs, + int begin_index, int end_index, + AttributedCharacterIterator.Attribute[] restricts) +{ + this.ci = new StringCharacterIterator(sci, begin_index, end_index); + this.attribs = attribs; + this.restricts = restricts; +} + +/*************************************************************************/ + +/* + * Instance Methods + */ + +// First we have a bunch of stupid redirects. If StringCharacterIterator +// weren't final, I just would have extended that for this class. Alas, no. + +public Object +clone() +{ + return(ci.clone()); +} + +public char +current() +{ + return(ci.current()); +} + +public char +next() +{ + return(ci.next()); +} + +public char +previous() +{ + return(ci.previous()); +} + +public char +first() +{ + return(ci.first()); +} + +public char +last() +{ + return(ci.last()); +} + +public int +getIndex() +{ + return(ci.getIndex()); +} + +public char +setIndex(int index) +{ + return(ci.setIndex(index)); +} + +public int +getBeginIndex() +{ + return(ci.getBeginIndex()); +} + +public int +getEndIndex() +{ + return(ci.getEndIndex()); +} + +/* + * Here is where the AttributedCharacterIterator methods start. + */ + +/*************************************************************************/ + +/** + * Returns a list of all the attribute keys that are defined anywhere + * on this string. + */ +public Set +getAllAttributeKeys() +{ + HashSet s = new HashSet(); + if (attribs == null) + return(s); + + for (int i = 0; i < attribs.length; i++) + { + Set key_set = attribs[i].attribs.keySet(); + Iterator iter = key_set.iterator(); + while (iter.hasNext()) + { + s.add(iter.next()); + } + } + + return(s); +} + +/*************************************************************************/ + +/** + * Various methods that determine how far the run extends for various + * attribute combinations. + */ + +public int +getRunLimit() +{ + return(getRunLimit(getAttributes().keySet())); +} + +public int +getRunLimit(AttributedCharacterIterator.Attribute attrib) +{ + HashSet s = new HashSet(); + s.add(attrib); + + return(getRunLimit(s)); +} + +public synchronized int +getRunLimit(Set attribute_set) +{ + int orig_index = ci.getIndex(); + int run_limit; + + do + { + run_limit = ci.getIndex(); + + Map attribute_map = getAttributes(); + + boolean found = false; + Iterator iter = attribute_set.iterator(); + while(iter.hasNext()) + if (!attribute_map.containsKey(iter.next())) + { + found = true; + break; + } + + if (found) + break; + } + while (ci.next() != CharacterIterator.DONE); + + boolean hit_end = (ci.previous() == CharacterIterator.DONE); + + ci.setIndex(orig_index); + + if (run_limit == orig_index) + return(-1); // No characters match the given attributes +// else if (!hit_end) +// --run_limit; + + return(run_limit); +} + +/*************************************************************************/ + +/** + * Various methods that determine where the run begins for various + * attribute combinations. + */ + +public int +getRunStart() +{ + return(getRunStart(getAttributes().keySet())); +} + +public int +getRunStart(AttributedCharacterIterator.Attribute attrib) +{ + HashSet s = new HashSet(); + s.add(attrib); + + return(getRunStart(s)); +} + +public int +getRunStart(Set attribute_set) +{ + int orig_index = ci.getIndex(); + int run_start; + + do + { + run_start = ci.getIndex(); + + Map attribute_map = getAttributes(); + + Iterator iter = attribute_set.iterator(); + while(iter.hasNext()) + if (!attribute_map.containsKey(iter.next())) + break; + + if (iter.hasNext()) + break; + } + while (ci.previous() != CharacterIterator.DONE); + + boolean hit_beginning = (ci.previous() == CharacterIterator.DONE); + + ci.setIndex(orig_index); + + if (run_start == orig_index) + return(-1); // No characters match the given attributes + else if (!hit_beginning) + ++run_start; + + return(run_start); +} + +/*************************************************************************/ + +public Object +getAttribute(AttributedCharacterIterator.Attribute attrib) +{ + if (attribs == null) + return(null); + + for (int i = 0; i < attribs.length; i++) + { + Set key_set = attribs[i].attribs.keySet(); + Iterator iter = key_set.iterator(); + while (iter.hasNext()) + { + Object obj = iter.next(); + + // Check for attribute match and range match + if (obj.equals(attrib)) + if ((ci.getIndex() >= attribs[i].begin_index) && + (ci.getIndex() <= attribs[i].end_index)) + return(attribs[i].attribs.get(obj)); + } + } + + return(null); +} + +/*************************************************************************/ + +/** + * Return a list of all the attributes and values defined for this + * character + */ +public Map +getAttributes() +{ + HashMap m = new HashMap(); + if (attribs == null) + return(m); + + for (int i = 0; i < attribs.length; i++) + { + if ((ci.getIndex() >= attribs[i].begin_index) && + (ci.getIndex() <= attribs[i].end_index)) + m.putAll(attribs[i].attribs); + } + + return(m); +} + +} // class AttributedStringIterator + diff --git a/libjava/java/text/BreakIterator.java b/libjava/java/text/BreakIterator.java index ef971bf..907e07d 100644 --- a/libjava/java/text/BreakIterator.java +++ b/libjava/java/text/BreakIterator.java @@ -1,12 +1,29 @@ -// BreakIterator.java - Iterate over logical breaks in text. +/* BreakIterator.java -- Breaks text into elements + Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. -/* Copyright (C) 1999 Free Software Foundation +This file is part of GNU Classpath. - This file is part of libgcj. +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; @@ -15,31 +32,75 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; /** + * This class iterates over text elements such as words, lines, sentences, + * and characters. It can only iterate over one of these text elements at + * a time. An instance of this class configured for the desired iteration + * type is created by calling one of the static factory methods, not + * by directly calling a constructor. + * * @author Tom Tromey <tromey@cygnus.com> + * @author Aaron M. Renn (arenn@urbanophile.com) * @date March 19, 1999 */ /* Written using "Java Class Libraries", 2nd edition, plus online * API docs for JDK 1.2 beta from http://www.javasoft.com. * Status: Believed complete and correct to 1.1. */ - public abstract class BreakIterator implements Cloneable { + /** + * This value is returned by the <code>next()</code> and + * <code>previous</code> in order to indicate that the end of the + * text has been reached. + */ // The value was discovered by writing a test program. public static final int DONE = -1; + /** + * This method initializes a new instance of <code>BreakIterator</code>. + * This protected constructor is available to subclasses as a default + * no-arg superclass constructor. + */ protected BreakIterator () { } + /** + * This method returns the index of the current text element boundary. + * + * @return The current text boundary. + */ public abstract int current (); + + /** + * This method returns the first text element boundary in the text being + * iterated over. + * + * @return The first text boundary. + */ public abstract int first (); + + /** + * This methdod returns the offset of the text element boundary following + * the specified offset. + * + * @param offset The text index from which to find the next text boundary. + * + * @param The next text boundary following the specified index. + */ public abstract int following (int pos); + /** + * This method returns a list of locales for which instances of + * <code>BreakIterator</code> are available. + * + * @return A list of available locales + */ public static synchronized Locale[] getAvailableLocales () { - // FIXME. - return null; + Locale[] l = new Locale[1]; + l[0] = Locale.US; + return l; } private static BreakIterator getInstance (String type, Locale loc) @@ -48,7 +109,8 @@ public abstract class BreakIterator implements Cloneable try { ResourceBundle res - = ResourceBundle.getBundle("gnu.gcj.text.LocaleData", loc); + = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + loc); className = res.getString(type); } catch (MissingResourceException x) @@ -74,60 +136,135 @@ public abstract class BreakIterator implements Cloneable } } + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over characters as defined in the default locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getCharacterInstance () { return getCharacterInstance (Locale.getDefault()); } + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over characters as defined in the specified locale. If the + * desired locale is not available, the default locale is used. + * + * @param locale The desired locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getCharacterInstance (Locale loc) { BreakIterator r = getInstance ("CharacterIterator", loc); if (r == null) - r = new gnu.gcj.text.CharacterBreakIterator (); + r = new gnu.java.text.CharacterBreakIterator (); return r; } + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over line breaks as defined in the default locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getLineInstance () { return getLineInstance (Locale.getDefault()); } + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over line breaks as defined in the specified locale. If the + * desired locale is not available, the default locale is used. + * + * @param locale The desired locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getLineInstance (Locale loc) { BreakIterator r = getInstance ("LineIterator", loc); if (r == null) - r = new gnu.gcj.text.LineBreakIterator (); + r = new gnu.java.text.LineBreakIterator (); return r; } + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over sentences as defined in the default locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getSentenceInstance () { return getSentenceInstance (Locale.getDefault()); } + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over sentences as defined in the specified locale. If the + * desired locale is not available, the default locale is used. + * + * @param locale The desired locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getSentenceInstance (Locale loc) { BreakIterator r = getInstance ("SentenceIterator", loc); if (r == null) - r = new gnu.gcj.text.SentenceBreakIterator (); + r = new gnu.java.text.SentenceBreakIterator (); return r; } + /** + * This method returns the text this object is iterating over as a + * <code>CharacterIterator</code>. + * + * @param The text being iterated over. + */ public abstract CharacterIterator getText (); + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over words as defined in the default locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getWordInstance () { return getWordInstance (Locale.getDefault()); } + /** + * This method returns an instance of <code>BreakIterator</code> that will + * iterate over words as defined in the specified locale. If the + * desired locale is not available, the default locale is used. + * + * @param locale The desired locale. + * + * @return A <code>BreakIterator</code> instance for the default locale. + */ public static BreakIterator getWordInstance (Locale loc) { BreakIterator r = getInstance ("WordIterator", loc); if (r == null) - r = new gnu.gcj.text.WordBreakIterator (); + r = new gnu.java.text.WordBreakIterator (); return r; } + /** + * This method tests whether or not the specified position is a text + * element boundary. + * + * @param offset The text position to test. + * + * @return <code>true</code> if the position is a boundary, + * <code>false</code> otherwise. + */ public boolean isBoundary (int pos) { if (pos == 0) @@ -135,10 +272,41 @@ public abstract class BreakIterator implements Cloneable return following (pos - 1) == pos; } + /** + * This method returns the last text element boundary in the text being + * iterated over. + * + * @return The last text boundary. + */ public abstract int last (); + + /** + * This method returns the text element boundary following the current + * text position. + * + * @return The next text boundary. + */ public abstract int next (); + + /** + * This method returns the n'th text element boundary following the current + * text position. + * + * @param n The number of text element boundaries to skip. + * + * @return The next text boundary. + */ public abstract int next (int n); + /** + * This methdod returns the offset of the text element boundary preceding + * the specified offset. + * + * @param offset The text index from which to find the preceding + * text boundary. + * + * @returns The next text boundary preceding the specified index. + */ public int preceding (int pos) { if (following (pos) == DONE) @@ -148,12 +316,29 @@ public abstract class BreakIterator implements Cloneable return current (); } + /** + * This method returns the text element boundary preceding the current + * text position. + * + * @return The previous text boundary. + */ public abstract int previous (); + /** + * This method sets the text string to iterate over. + * + * @param str The <code>String</code> to iterate over. + */ public void setText (String newText) { setText (new StringCharacterIterator (newText)); } + /** + * This method sets the text to iterate over from the specified + * <code>CharacterIterator</code>. + * + * @param ci The desired <code>CharacterIterator</code>. + */ public abstract void setText (CharacterIterator newText); } diff --git a/libjava/java/text/CharacterIterator.java b/libjava/java/text/CharacterIterator.java index a10ee4a..5ab7974 100644 --- a/libjava/java/text/CharacterIterator.java +++ b/libjava/java/text/CharacterIterator.java @@ -1,36 +1,163 @@ -// CharacterIterator.java - Protocol for iterating over Unicode characters. +/* CharacterIterator.java -- Iterate over a character range + Copyright (C) 1998, 2001 Free Software Foundation, Inc. -/* Copyright (C) 1999 Free Software Foundation +This file is part of GNU Classpath. - This file is part of libgcj. +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; /** - * @author Tom Tromey <tromey@cygnus.com> - * @date February 22, 1999 - */ -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct to 1.1. - */ - + * This interface defines a mechanism for iterating over a range of + * characters. For a given range of text, a beginning and ending index, + * as well as a current index are defined. These values can be queried + * by the methods in this interface. Additionally, various methods allow + * the index to be set. + * + * @version 0.0 + * + * @author Aaron M. Renn (arenn@urbanophile.com) + */ public interface CharacterIterator extends Cloneable { - public abstract Object clone (); + + /*************************************************************************/ + + /* + * Static Variables + */ + + /** + * This is a special constant value that is returned when the beginning or + * end of the character range has been reached. + */ + public static final char DONE = '\uFFFF'; + + /*************************************************************************/ + + /* + * Instance Methods + */ + + /** + * This method returns the character at the current index position + * + * @return The character at the current index position. + */ public abstract char current (); + + /*************************************************************************/ + + /** + * This method increments the current index and then returns the character + * at the new index value. If the index is already at <code>getEndIndex() - 1</code>, + * it will not be incremented. + * + * @return The character at the position of the incremented index value, or <code>DONE</code> if the index has reached getEndIndex() - 1 + */ + public abstract char next (); + + /*************************************************************************/ + + /** + * This method decrements the current index and then returns the character + * at the new index value. If the index value is already at the beginning + * index, it will not be decremented. + * + * @return The character at the position of the decremented index value, or <code>DONE</code> if index was already equal to the beginning index value. + */ + public abstract char previous (); + + /*************************************************************************/ + + /** + * This method sets the index value to the beginning of the range and returns + * the character there. + * + * @return The character at the beginning of the range, or <code>DONE</code> if the range is empty. + */ public abstract char first (); + + /*************************************************************************/ + + /** + * This method sets the index value to <code>getEndIndex() - 1</code> and + * returns the character there. If the range is empty, then the index value + * will be set equal to the beginning index. + * + * @return The character at the end of the range, or <code>DONE</code> if the range is empty. + */ + public abstract char last (); + + /*************************************************************************/ + + /** + * This method returns the current value of the index. + * + * @return The current index value + */ + public abstract int getIndex (); + + /*************************************************************************/ + + /** + * This method sets the value of the index to the specified value, then + * returns the character at that position. + * + * @param index The new index value. + * + * @return The character at the new index value or <code>DONE</code> if the index value is equal to <code>getEndIndex</code>. + */ + public abstract char setIndex (int index) throws IllegalArgumentException; + + /*************************************************************************/ + + /** + * This method returns the character position of the first character in the + * range. + * + * @return The index of the first character in the range. + */ public abstract int getBeginIndex (); + + /*************************************************************************/ + + /** + * This method returns the character position of the end of the text range. + * This will actually be the index of the first character following the + * end of the range. In the event the text range is empty, this will be + * equal to the first character in the range. + * + * @return The index of the end of the range. + */ public abstract int getEndIndex (); - public abstract int getIndex (); - public abstract char last (); - public abstract char next (); - public abstract char previous (); - public abstract char setIndex (int idx); - public static final char DONE = '\uffff'; + /*************************************************************************/ + + /** + * This method creates a copy of this <code>CharacterIterator</code>. + * + * @return A copy of this <code>CharacterIterator</code>. + */ + public abstract Object clone (); } diff --git a/libjava/java/text/ChoiceFormat.java b/libjava/java/text/ChoiceFormat.java index 584ece5..8e2d920 100644 --- a/libjava/java/text/ChoiceFormat.java +++ b/libjava/java/text/ChoiceFormat.java @@ -1,306 +1,487 @@ -// ChoiceFormat.java - Formatter for `switch'-like string substitution. +/* ChoiceFormat.java -- Format over a range of numbers + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. -/* Copyright (C) 1999, 2000 Free Software Foundation +This file is part of GNU Classpath. - This file is part of libgcj. +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; import java.util.Vector; /** + * This class allows a format to be specified based on a range of numbers. + * To use this class, first specify two lists of formats and range terminators. + * These lists must be arrays of equal length. The format of index + * <code>i</code> will be selected for value <code>X</code> if + * <code>terminator[i] <= X < limit[i + 1]</code>. If the value X is not + * included in any range, then either the first or last format will be + * used depending on whether the value X falls outside the range. + * <p> + * This sounds complicated, but that is because I did a poor job of + * explaining it. Consider the following example: + * <p> + * <pre> + * terminators = { 1, ChoiceFormat.nextDouble(1) } + * formats = { "file", "files" } + * </pre> + * <p> + * In this case if the actual number tested is one or less, then the word + * "file" is used as the format value. If the number tested is greater than + * one, then "files" is used. This allows plurals to be handled + * gracefully. Note the use of the method <code>nextDouble</code>. This + * method selects the next highest double number than its argument. This + * effectively makes any double greater than 1.0 cause the "files" string + * to be selected. (Note that all terminator values are specified as + * doubles. + * <p> + * Note that in order for this class to work properly, the range terminator + * array must be sorted in ascending order and the format string array + * must be the same length as the terminator array. + * * @author Tom Tromey <tromey@cygnus.com> + * @author Aaron M. Renn (arenn@urbanophile.com) * @date March 9, 1999 */ /* Written using "Java Class Libraries", 2nd edition, plus online * API docs for JDK 1.2 from http://www.javasoft.com. * Status: Believed complete and correct to 1.1. */ - public class ChoiceFormat extends NumberFormat { - // Note: we assume the same kind of quoting rules apply here. - // This isn't explicitly documented. But for instance we accept - // '#' as a literal hash in a format string. + /** + * This method sets new range terminators and format strings for this + * object based on the specified pattern. This pattern is of the form + * "term#string|term#string...". For example "1#Sunday|2#Monday|#Tuesday". + * + * @param pattern The pattern of terminators and format strings. + * + * @exception IllegalArgumentException If the pattern is not valid + */ public void applyPattern (String newPattern) - { - int index = 0, max = newPattern.length(); - Vector stringVec = new Vector (); - Vector limitVec = new Vector (); - StringBuffer buf = new StringBuffer (); - - while (true) - { - // Find end of double. - int dstart = index; - while (index < max) - { - char c = newPattern.charAt(index); - if (c == '#' || c == '\u2064' || c == '<') - break; - ++index; - } - - if (index == max) - throw new IllegalArgumentException ("unexpected end of text"); - Double d = new Double (newPattern.substring(dstart, index)); - - if (newPattern.charAt(index) == '<') - d = new Double (nextDouble (d.doubleValue())); - - limitVec.addElement(d); - - // Scan text. - ++index; - buf.setLength(0); - while (index < max) - { - char c = newPattern.charAt(index); - if (c == '\'' && index < max + 1 - && newPattern.charAt(index + 1) == '\'') - { - buf.append(c); - ++index; - } - else if (c == '\'' && index < max + 2) - { - buf.append(newPattern.charAt(index + 1)); - index += 2; - } - else if (c == '|') - break; - else + { + // Note: we assume the same kind of quoting rules apply here. + // This isn't explicitly documented. But for instance we accept + // '#' as a literal hash in a format string. + int index = 0, max = newPattern.length(); + Vector stringVec = new Vector (); + Vector limitVec = new Vector (); + StringBuffer buf = new StringBuffer (); + + while (true) + { + // Find end of double. + int dstart = index; + while (index < max) + { + char c = newPattern.charAt(index); + if (c == '#' || c == '\u2064' || c == '<') + break; + ++index; + } + + if (index == max) + throw new IllegalArgumentException ("unexpected end of text"); + Double d = new Double (newPattern.substring(dstart, index)); + + if (newPattern.charAt(index) == '<') + d = new Double (nextDouble (d.doubleValue())); + + limitVec.addElement(d); + + // Scan text. + ++index; + buf.setLength(0); + while (index < max) + { + char c = newPattern.charAt(index); + if (c == '\'' && index < max + 1 + && newPattern.charAt(index + 1) == '\'') + { buf.append(c); - ++index; - } - - stringVec.addElement(buf.toString()); - if (index == max) - break; - ++index; - } - - choiceFormats = new String[stringVec.size()]; - stringVec.copyInto(choiceFormats); - - choiceLimits = new double[limitVec.size()]; - for (int i = 0; i < choiceLimits.length; ++i) - { - Double d = (Double) limitVec.elementAt(i); - choiceLimits[i] = d.doubleValue(); - } - } - + ++index; + } + else if (c == '\'' && index < max + 2) + { + buf.append(newPattern.charAt(index + 1)); + index += 2; + } + else if (c == '|') + break; + else + buf.append(c); + ++index; + } + + stringVec.addElement(buf.toString()); + if (index == max) + break; + ++index; + } + + choiceFormats = new String[stringVec.size()]; + stringVec.copyInto(choiceFormats); + + choiceLimits = new double[limitVec.size()]; + for (int i = 0; i < choiceLimits.length; ++i) + { + Double d = (Double) limitVec.elementAt(i); + choiceLimits[i] = d.doubleValue(); + } + } + + /** + * This method initializes a new instance of <code>ChoiceFormat</code> that + * generates its range terminator and format string arrays from the + * specified pattern. This pattern is of the form + * "term#string|term#string...". For example "1#Sunday|2#Monday|#Tuesday". + * This is the same pattern type used by the <code>applyPattern</code> + * method. + * + * @param pattern The pattern of terminators and format strings. + * + * @exception IllegalArgumentException If the pattern is not valid + */ public ChoiceFormat (String newPattern) - { - super (); - applyPattern (newPattern); - } - + { + super (); + applyPattern (newPattern); + } + + /** + * This method initializes a new instance of <code>ChoiceFormat</code> that + * will use the specified range terminators and format strings. + * + * @param choiceLimits The array of range terminators + * @param choiceFormats The array of format strings + */ public ChoiceFormat (double[] choiceLimits, String[] choiceFormats) - { - super (); - setChoices (choiceLimits, choiceFormats); - } - - public Object clone () - { - return new ChoiceFormat (choiceLimits, choiceFormats); - } - + { + super (); + setChoices (choiceLimits, choiceFormats); + } + + /** + * This method tests this object for equality with the specified + * object. This will be true if and only if: + * <ul> + * <li>The specified object is not <code>null</code>. + * <li>The specified object is an instance of <code>ChoiceFormat</code>. + * <li>The termination ranges and format strings are identical to + * this object's. + * </ul> + * + * @param obj The object to test for equality against. + * + * @return <code>true</code> if the specified object is equal to + * this one, <code>false</code> otherwise. + */ public boolean equals (Object obj) - { - if (! (obj instanceof ChoiceFormat)) - return false; - ChoiceFormat cf = (ChoiceFormat) obj; - if (choiceLimits.length != cf.choiceLimits.length) - return false; - for (int i = choiceLimits.length - 1; i >= 0; --i) - { - if (choiceLimits[i] != cf.choiceLimits[i] - || !choiceFormats[i].equals(cf.choiceFormats[i])) - return false; - } - return true; - } - + { + if (! (obj instanceof ChoiceFormat)) + return false; + ChoiceFormat cf = (ChoiceFormat) obj; + if (choiceLimits.length != cf.choiceLimits.length) + return false; + for (int i = choiceLimits.length - 1; i >= 0; --i) + { + if (choiceLimits[i] != cf.choiceLimits[i] + || !choiceFormats[i].equals(cf.choiceFormats[i])) + return false; + } + return true; + } + + /** + * This method appends the appropriate format string to the specified + * <code>StringBuffer</code> based on the supplied <code>long</code> + * argument. + * + * @param number The number used for determine (based on the range + * terminators) which format string to append. + * @param sb The <code>StringBuffer</code> to append the format string to. + * @param status Unused. + * + * @return The <code>StringBuffer</code> with the format string appended. + */ public StringBuffer format (long num, StringBuffer appendBuf, FieldPosition pos) - { - return format ((double) num, appendBuf, pos); - } - + { + return format ((double) num, appendBuf, pos); + } + + /** + * This method appends the appropriate format string to the specified + * <code>StringBuffer</code> based on the supplied <code>double</code> + * argument. + * + * @param number The number used for determine (based on the range + * terminators) which format string to append. + * @param sb The <code>StringBuffer</code> to append the format string to. + * @param status Unused. + * + * @return The <code>StringBuffer</code> with the format string appended. + */ public StringBuffer format (double num, StringBuffer appendBuf, FieldPosition pos) - { - if (choiceLimits.length == 0) - return appendBuf; - - int index = 0; - if (! Double.isNaN(num) && num >= choiceLimits[0]) - { - for (; index < choiceLimits.length - 1; ++index) - { - if (choiceLimits[index] <= num - && index != choiceLimits.length - 2 - && num < choiceLimits[index + 1]) - break; - } - } - - return appendBuf.append(choiceFormats[index]); - } - + { + if (choiceLimits.length == 0) + return appendBuf; + + int index = 0; + if (! Double.isNaN(num) && num >= choiceLimits[0]) + { + for (; index < choiceLimits.length - 1; ++index) + { + if (choiceLimits[index] <= num + && index != choiceLimits.length - 2 + && num < choiceLimits[index + 1]) + break; + } + } + + return appendBuf.append(choiceFormats[index]); + } + + /** + * This method returns the list of format strings in use. + * + * @return The list of format objects. + */ public Object[] getFormats () - { - return (Object[]) choiceFormats.clone(); - } - + { + return (Object[]) choiceFormats.clone(); + } + + /** + * This method returns the list of range terminators in use. + * + * @return The list of range terminators. + */ public double[] getLimits () - { - return (double[]) choiceLimits.clone(); - } - + { + return (double[]) choiceLimits.clone(); + } + + /** + * This method returns a hash value for this object + * + * @return A hash value for this object. + */ public int hashCode () - { - int hash = 0; - for (int i = 0; i < choiceLimits.length; ++i) - { - long v = Double.doubleToLongBits(choiceLimits[i]); - hash ^= (v ^ (v >>> 32)); - hash ^= choiceFormats[i].hashCode(); - } - return hash; - } - + { + int hash = 0; + for (int i = 0; i < choiceLimits.length; ++i) + { + long v = Double.doubleToLongBits(choiceLimits[i]); + hash ^= (v ^ (v >>> 32)); + hash ^= choiceFormats[i].hashCode(); + } + return hash; + } + + /** + * This method returns the lowest possible double greater than the + * specified double. If the specified double value is equal to + * <code>Double.NaN</code> then that is the value returned. + * + * @param d The specified double + * + * @return The lowest double value greater than the specified double. + */ public static final double nextDouble (double d) - { - return nextDouble (d, true); - } - + { + return nextDouble (d, true); + } + + /** + * This method returns a double that is either the next highest double + * or next lowest double compared to the specified double depending on the + * value of the passed boolean parameter. If the boolean parameter is + * <code>true</code>, then the lowest possible double greater than the + * specified double will be returned. Otherwise the highest possible + * double less than the specified double will be returned. + * + * @param d The specified double + * @param positive <code>true</code> to return the next highest + * double, <code>false</code> otherwise. + * + * @return The next highest or lowest double value. + */ public static double nextDouble (double d, boolean next) - { - if (Double.isInfinite(d) || Double.isNaN(d)) - return d; + { + if (Double.isInfinite(d) || Double.isNaN(d)) + return d; - long bits = Double.doubleToLongBits(d); + long bits = Double.doubleToLongBits(d); - long mantMask = (1L << mantissaBits) - 1; - long mantissa = bits & mantMask; + long mantMask = (1L << mantissaBits) - 1; + long mantissa = bits & mantMask; - long expMask = (1L << exponentBits) - 1; - long exponent = (bits >>> mantissaBits) & expMask; + long expMask = (1L << exponentBits) - 1; + long exponent = (bits >>> mantissaBits) & expMask; - if (next ^ (bits < 0)) // Increment magnitude - { - if (mantissa == (1L << mantissaBits) - 1) - { - mantissa = 0L; - exponent++; + if (next ^ (bits < 0)) // Increment magnitude + { + if (mantissa == (1L << mantissaBits) - 1) + { + mantissa = 0L; + exponent++; - // Check for absolute overflow. - if (exponent >= (1L << mantissaBits)) - return (bits > 0) ? Double.POSITIVE_INFINITY - : Double.NEGATIVE_INFINITY; - } - else - mantissa++; - } - else // Decrement magnitude - { - if (exponent == 0L && mantissa == 0L) - { - // The only case where there is a change of sign - return next ? Double.MIN_VALUE : -Double.MIN_VALUE; - } - else - { - if (mantissa == 0L) - { - mantissa = (1L << mantissaBits) - 1; - exponent--; - } - else - mantissa--; - } - } - - long result = bits < 0 ? 1 : 0; - result = (result << exponentBits) | exponent; - result = (result << mantissaBits) | mantissa; - return Double.longBitsToDouble(result); - } - + // Check for absolute overflow. + if (exponent >= (1L << mantissaBits)) + return (bits > 0) ? Double.POSITIVE_INFINITY + : Double.NEGATIVE_INFINITY; + } + else + mantissa++; + } + else // Decrement magnitude + { + if (exponent == 0L && mantissa == 0L) + { + // The only case where there is a change of sign + return next ? Double.MIN_VALUE : -Double.MIN_VALUE; + } + else + { + if (mantissa == 0L) + { + mantissa = (1L << mantissaBits) - 1; + exponent--; + } + else + mantissa--; + } + } + + long result = bits < 0 ? 1 : 0; + result = (result << exponentBits) | exponent; + result = (result << mantissaBits) | mantissa; + return Double.longBitsToDouble(result); + } + + /** + * I'm not sure what this method is really supposed to do, as it is + * not documented. + */ public Number parse (String sourceStr, ParsePosition pos) - { - int index = pos.getIndex(); - for (int i = 0; i < choiceLimits.length; ++i) - { - if (sourceStr.startsWith(choiceFormats[i], index)) - { - pos.setIndex(index + choiceFormats[i].length()); - return new Double (choiceLimits[i]); - } - } - pos.setErrorIndex(index); - return new Double (Double.NaN); - } - + { + int index = pos.getIndex(); + for (int i = 0; i < choiceLimits.length; ++i) + { + if (sourceStr.startsWith(choiceFormats[i], index)) + { + pos.setIndex(index + choiceFormats[i].length()); + return new Double (choiceLimits[i]); + } + } + pos.setErrorIndex(index); + return new Double (Double.NaN); + } + + /** + * This method returns the highest possible double less than the + * specified double. If the specified double value is equal to + * <code>Double.NaN</code> then that is the value returned. + * + * @param d The specified double + * + * @return The highest double value less than the specified double. + */ public static final double previousDouble (double d) - { - return nextDouble (d, false); - } - + { + return nextDouble (d, false); + } + + /** + * This method sets new range terminators and format strings for this + * object. + * + * @param choiceLimits The new range terminators + * @param choiceFormats The new choice formats + */ public void setChoices (double[] choiceLimits, String[] choiceFormats) - { - if (choiceLimits == null || choiceFormats == null) - throw new NullPointerException (); - if (choiceLimits.length != choiceFormats.length) - throw new IllegalArgumentException (); - this.choiceFormats = (String[]) choiceFormats.clone(); - this.choiceLimits = (double[]) choiceLimits.clone(); - } + { + if (choiceLimits == null || choiceFormats == null) + throw new NullPointerException (); + if (choiceLimits.length != choiceFormats.length) + throw new IllegalArgumentException (); + this.choiceFormats = (String[]) choiceFormats.clone(); + this.choiceLimits = (double[]) choiceLimits.clone(); + } private final void quoteString (StringBuffer dest, String text) - { - int max = text.length(); - for (int i = 0; i < max; ++i) - { - char c = text.charAt(i); - if (c == '\'') - { - dest.append(c); - dest.append(c); - } - else if (c == '#' || c == '|' || c == '\u2064' || c == '<') - { - dest.append('\''); - dest.append(c); - dest.append('\''); - } - else + { + int max = text.length(); + for (int i = 0; i < max; ++i) + { + char c = text.charAt(i); + if (c == '\'') + { dest.append(c); - } - } - + dest.append(c); + } + else if (c == '#' || c == '|' || c == '\u2064' || c == '<') + { + dest.append('\''); + dest.append(c); + dest.append('\''); + } + else + dest.append(c); + } + } + + /** + * This method returns the range terminator list and format string list + * as a <code>String</code> suitable for using with the + * <code>applyPattern</code> method. + * + * @return A pattern string for this object + */ public String toPattern () - { - StringBuffer result = new StringBuffer (); - for (int i = 0; i < choiceLimits.length; ++i) - { - result.append(choiceLimits[i]); - result.append('#'); - quoteString (result, choiceFormats[i]); - } - return result.toString(); - } - - // Formats and limits. + { + StringBuffer result = new StringBuffer (); + for (int i = 0; i < choiceLimits.length; ++i) + { + result.append(choiceLimits[i]); + result.append('#'); + quoteString (result, choiceFormats[i]); + } + return result.toString(); + } + + /** + * This is the list of format strings. Note that this variable is + * specified by the serialization spec of this class. + */ private String[] choiceFormats; + + /** + * This is the list of range terminator values. Note that this variable is + * specified by the serialization spec of this class. + */ private double[] choiceLimits; // Number of mantissa bits in double. diff --git a/libjava/java/text/Collator.java b/libjava/java/text/Collator.java index 9a356c1..51a053d 100644 --- a/libjava/java/text/Collator.java +++ b/libjava/java/text/Collator.java @@ -1,12 +1,29 @@ -// Collator.java - Locale-sensitive string comparison. +/* Collator.java -- Perform locale dependent String comparisons. + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. -/* Copyright (C) 1999, 2000 Free Software Foundation +This file is part of GNU Classpath. - This file is part of libgcj. +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; @@ -16,38 +33,157 @@ import java.util.ResourceBundle; import java.util.Comparator; /** + * This class is the abstract superclass of classes which perform + * locale dependent <code>String</code> comparisons. A caller requests + * an instance of <code>Collator</code> for a particular locale using + * the <code>getInstance()</code> static method in this class. That method + * will return a locale specific subclass of <code>Collator</code> which + * can be used to perform <code>String</code> comparisons for that locale. + * If a subclass of <code>Collator</code> cannot be located for a particular + * locale, a default instance for the current locale will be returned. + * + * In addition to setting the correct locale, there are two additional + * settings that can be adjusted to affect <code>String</code> comparisons: + * strength and decomposition. The strength value determines the level + * of signficance of character differences required for them to sort + * differently. (For example, whether or not capital letters are considered + * different from lower case letters). The decomposition value affects how + * variants of the same character are treated for sorting purposes. (For + * example, whether or not an accent is signficant or not). These settings + * are described in detail in the documentation for the methods and values + * that are related to them. + * * @author Tom Tromey <tromey@cygnus.com> + * @author Aaron M. Renn (arenn@urbanophile.com) * @date March 18, 1999 */ /* Written using "Java Class Libraries", 2nd edition, plus online * API docs for JDK 1.2 from http://www.javasoft.com. * Status: Mostly complete, but parts stubbed out. Look for FIXME. */ - public abstract class Collator implements Comparator, Cloneable { - public static final int NO_DECOMPOSITION = 0; - public static final int CANONICAL_DECOMPOSITION = 1; - public static final int FULL_DECOMPOSITION = 2; - + /** + * This constant is a strength value which indicates that only primary + * differences between characters will be considered signficant. As an + * example, two completely different English letters such as 'a' and 'b' + * are considered to have a primary difference. + */ public static final int PRIMARY = 0; + + /** + * This constant is a strength value which indicates that only secondary + * or primary differences between characters will be considered + * significant. An example of a secondary difference between characters + * are instances of the same letter with different accented forms. + */ public static final int SECONDARY = 1; + + /** + * This constant is a strength value which indicates that tertiary, + * secondary, and primary differences will be considered during sorting. + * An example of a tertiary difference is capitalization of a given letter. + * This is the default value for the strength setting. + */ public static final int TERTIARY = 2; + + /** + * This constant is a strength value which indicates that any difference + * at all between character values are considered significant. + */ public static final int IDENTICAL = 3; + + /** + * This constant indicates that accented characters won't be decomposed + * when performing comparisons. This will yield the fastest results, but + * will only work correctly in call cases for languages which do not + * use accents such as English. + */ + public static final int NO_DECOMPOSITION = 0; + + /** + * This constant indicates that only characters which are canonical variants + * in Unicode 2.0 will be decomposed prior to performing comparisons. This + * will cause accented languages to be sorted correctly. This is the + * default decomposition value. + */ + public static final int CANONICAL_DECOMPOSITION = 1; + + /** + * This constant indicates that both canonical variants and compatibility + * variants in Unicode 2.0 will be decomposed prior to performing + * comparisons. This is the slowest mode, but is required to get the + * correct sorting for certain languages with certain special formats. + */ + public static final int FULL_DECOMPOSITION = 2; + /** + * This method initializes a new instance of <code>Collator</code> to have + * the default strength (TERTIARY) and decomposition + * (CANONICAL_DECOMPOSITION) settings. This constructor is protected and + * is for use by subclasses only. Non-subclass callers should use the + * static <code>getInstance()</code> methods of this class to instantiate + * <code>Collation</code> objects for the desired locale. + */ protected Collator () { strength = TERTIARY; decmp = CANONICAL_DECOMPOSITION; } + /** + * This method compares the two <code>String</code>'s and returns an + * integer indicating whether or not the first argument is less than, + * equal to, or greater than the second argument. The comparison is + * performed according to the rules of the locale for this + * <code>Collator</code> and the strength and decomposition rules in + * effect. + * + * @param str1 The first object to compare + * @param str2 The second object to compare + * + * @return A negative integer if str1 < str2, 0 if str1 == str2, or + * a positive integer if str1 > str2. + */ public abstract int compare (String source, String target); + /** + * This method compares the two <code>Object</code>'s and returns an + * integer indicating whether or not the first argument is less than, + * equal to, or greater than the second argument. These two objects + * must be <code>String</code>'s or an exception will be thrown. + * + * @param obj1 The first object to compare + * @param obj2 The second object to compare + * + * @return A negative integer if obj1 < obj2, 0 if obj1 == obj2, or + * a positive integer if obj1 > obj2. + * + * @exception ClassCastException If the arguments are not instances + * of <code>String</code>. + */ public int compare (Object o1, Object o2) { return compare ((String) o1, (String) o2); } + /** + * This method tests the specified object for equality against this + * object. This will be true if and only if the following conditions are + * met: + * <ul> + * <li>The specified object is not <code>null</code>. + * <li>The specified object is an instance of <code>Collator</code>. + * <li>The specified object has the same strength and decomposition + * settings as this object. + * </ul> + * + * @param obj The <code>Object</code> to test for equality against + * this object. + * + * @return <code>true</code> if the specified object is equal to + * this one, <code>false</code> otherwise. + */ public boolean equals (Object obj) { if (! (obj instanceof Collator)) @@ -56,42 +192,108 @@ public abstract class Collator implements Comparator, Cloneable return decmp == c.decmp && strength == c.strength; } + /** + * This method tests whether the specified <code>String</code>'s are equal + * according to the collation rules for the locale of this object and + * the current strength and decomposition settings. + * + * @param str1 The first <code>String</code> to compare + * @param str2 The second <code>String</code> to compare + * + * @return <code>true</code> if the two strings are equal, + * <code>false</code> otherwise. + */ public boolean equals (String source, String target) { return compare (source, target) == 0; } + /** + * This method returns a copy of this <code>Collator</code> object. + * + * @return A duplicate of this object. + */ public Object clone () { - return super.clone (); + try + { + return super.clone (); + } + catch (CloneNotSupportedException _) + { + return null; + } } + /** + * This method returns an array of <code>Locale</code> objects which is + * the list of locales for which <code>Collator</code> objects exist. + * + * @return The list of locales for which <code>Collator</code>'s exist. + */ public static synchronized Locale[] getAvailableLocales () { - // FIXME. - return null; + // FIXME + Locale[] l = new Locale[1]; + l[0] = Locale.US; + return l; } + /** + * This method transforms the specified <code>String</code> into a + * <code>CollationKey</code> for faster comparisons. This is useful when + * comparisons against a string might be performed multiple times, such + * as during a sort operation. + * + * @param str The <code>String</code> to convert. + * + * @return A <code>CollationKey</code> for the specified <code>String</code>. + */ public abstract CollationKey getCollationKey (String source); + /** + * This method returns the current decomposition setting for this + * object. This * will be one of NO_DECOMPOSITION, + * CANONICAL_DECOMPOSITION, or * FULL_DECOMPOSITION. See the + * documentation for those constants for an * explanation of this + * setting. + * + * @return The current decomposition setting. + */ public synchronized int getDecomposition () { return decmp; } + /** + * This method returns an instance of <code>Collator</code> for the + * default locale. + * + * @return A <code>Collator</code> for the default locale. + */ public static Collator getInstance () { return getInstance (Locale.getDefault()); } + /** + * This method returns an instance of <code>Collator</code> for the + * specified locale. If no <code>Collator</code> exists for the desired + * locale, a <code>Collator</code> for the default locale will be returned. + * + * @param locale The desired localed to load a <code>Collator</code> for. + * + * @return A <code>Collator</code> for the requested locale + */ public static Collator getInstance (Locale loc) { ResourceBundle res; String pattern; try { - res = ResourceBundle.getBundle("gnu.gcj.text.LocaleData", loc); - pattern = res.getString("collatorRule"); + res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + loc); + pattern = res.getString("collation_rules"); } catch (MissingResourceException x) { @@ -107,13 +309,37 @@ public abstract class Collator implements Comparator, Cloneable } } + /** + * This method returns the current strength setting for this object. This + * will be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL. See the + * documentation for those constants for an explanation of this setting. + * + * @return The current strength setting. + */ public synchronized int getStrength () { return strength; } + /** + * This method returns a hash code value for this object. + * + * @return A hash value for this object. + */ public abstract int hashCode (); + /** + * This method sets the decomposition setting for this object to the + * specified value. This must be one of NO_DECOMPOSITION, + * CANONICAL_DECOMPOSITION, or FULL_DECOMPOSITION. Otherwise an + * exception will be thrown. See the documentation for those + * contants for an explanation of this setting. + * + * @param decmp The new decomposition setting. + * + * @exception IllegalArgumentException If the requested + * decomposition setting is not valid. + */ public synchronized void setDecomposition (int mode) { if (mode != NO_DECOMPOSITION @@ -123,6 +349,17 @@ public abstract class Collator implements Comparator, Cloneable decmp = mode; } + /** + * This method sets the strength setting for this object to the specified + * value. This must be one of PRIMARY, SECONDARY, TERTIARY, or IDENTICAL. + * Otherwise an exception is thrown. See the documentation for these + * constants for an explanation of this setting. + * + * @param strength The new strength setting. + * + * @exception IllegalArgumentException If the requested strength + * setting value is not valid. + */ public synchronized void setStrength (int strength) { if (strength != PRIMARY && strength != SECONDARY @@ -134,7 +371,13 @@ public abstract class Collator implements Comparator, Cloneable // Decompose a single character and append results to the buffer. native final void decomposeCharacter (char c, StringBuffer buf); - // These names are fixed by the serialization spec. + /** + * This is the current collation decomposition setting. + */ int decmp; + + /** + * This is the current collation strength setting. + */ int strength; } diff --git a/libjava/java/text/DateFormat.java b/libjava/java/text/DateFormat.java index 604a1d5..0e84f87 100644 --- a/libjava/java/text/DateFormat.java +++ b/libjava/java/text/DateFormat.java @@ -1,10 +1,29 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* DateFormat.java -- Class for formatting/parsing date/times + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; @@ -25,35 +44,60 @@ public abstract class DateFormat extends Format implements Cloneable protected NumberFormat numberFormat; // (Values determined using a test program.) - public final static int FULL = 0; - public final static int LONG = 1; - public final static int MEDIUM = 2; - public final static int SHORT = 3; - public final static int DEFAULT = MEDIUM; - - public final static int ERA_FIELD = 0; - public final static int YEAR_FIELD = 1; - public final static int MONTH_FIELD = 2; - public final static int DATE_FIELD = 3; - public final static int HOUR_OF_DAY1_FIELD = 4; - public final static int HOUR_OF_DAY0_FIELD = 5; - public final static int MINUTE_FIELD = 6; - public final static int SECOND_FIELD = 7; - public final static int MILLISECOND_FIELD = 8; - public final static int DAY_OF_WEEK_FIELD = 9; - public final static int DAY_OF_YEAR_FIELD = 10; - public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11; - public final static int WEEK_OF_YEAR_FIELD = 12; - public final static int WEEK_OF_MONTH_FIELD = 13; - public final static int AM_PM_FIELD = 14; - public final static int HOUR1_FIELD = 15; - public final static int HOUR0_FIELD = 16; - public final static int TIMEZONE_FIELD = 17; - + public static final int FULL = 0; + public static final int LONG = 1; + public static final int MEDIUM = 2; + public static final int SHORT = 3; + public static final int DEFAULT = MEDIUM; + + /* These constants need to have these exact values. They + * correspond to index positions within the localPatternChars + * string for a given locale. For example, the US locale uses + * the string "GyMdkHmsSEDFwWahKz", where 'G' is the character + * for era, 'y' for year, and so on down to 'z' for time zone. + */ + public static final int ERA_FIELD = 0; + public static final int YEAR_FIELD = 1; + public static final int MONTH_FIELD = 2; + public static final int DATE_FIELD = 3; + public static final int HOUR_OF_DAY1_FIELD = 4; + public static final int HOUR_OF_DAY0_FIELD = 5; + public static final int MINUTE_FIELD = 6; + public static final int SECOND_FIELD = 7; + public static final int MILLISECOND_FIELD = 8; + public static final int DAY_OF_WEEK_FIELD = 9; + public static final int DAY_OF_YEAR_FIELD = 10; + public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11; + public static final int WEEK_OF_YEAR_FIELD = 12; + public static final int WEEK_OF_MONTH_FIELD = 13; + public static final int AM_PM_FIELD = 14; + public static final int HOUR1_FIELD = 15; + public static final int HOUR0_FIELD = 16; + public static final int TIMEZONE_FIELD = 17; + + /** + * This method initializes a new instance of <code>DateFormat</code>. + */ protected DateFormat () { } + /** + * This method tests this object for equality against the specified object. + * The two objects will be considered equal if an only if the specified + * object: + * <P> + * <ul> + * <li>Is not <code>null</code>. + * <li>Is an instance of <code>DateFormat</code>. + * <li>Has the same calendar and numberFormat field values as this object. + * </ul> + * + * @param obj The object to test for equality against. + * + * @return <code>true</code> if the specified object is equal to this object, + * <code>false</code> otherwise. + */ public boolean equals (Object obj) { if (! (obj instanceof DateFormat)) @@ -62,20 +106,46 @@ public abstract class DateFormat extends Format implements Cloneable return calendar.equals(d.calendar) && numberFormat.equals(d.numberFormat); } + /** + * This method returns a copy of this object. + * + * @return A copy of this object. + */ public Object clone () { // We know the superclass just call's Object's generic cloner. return super.clone (); } + /** + * This method formats the specified <code>Object</code> into a date string + * and appends it to the specified <code>StringBuffer</code>. + * The specified object must be an instance of <code>Number</code> or + * <code>Date</code> or an <code>IllegalArgumentException</code> will be + * thrown. + * + * @param obj The <code>Object</code> to format. + * @param toAppendTo The <code>StringBuffer</code> to append the resultant + * <code>String</code> to. + * @param fieldPosition Is updated to the start and end index of the + * specified field. + * + * @return The <code>StringBuffer</code> supplied on input, with the + * formatted date/time appended. + */ public final StringBuffer format (Object obj, StringBuffer buf, FieldPosition pos) { if (obj instanceof Number) - return format (new Date(((Number) obj).longValue()), buf, pos); + obj = new Date(((Number) obj).longValue()); return format ((Date) obj, buf, pos); } + /** + * Formats the date argument according to the pattern specified. + * + * @param date The formatted date. + */ public final String format (Date date) { StringBuffer sb = new StringBuffer (); @@ -83,14 +153,42 @@ public abstract class DateFormat extends Format implements Cloneable return sb.toString(); } + /** + * This method formats a <code>Date</code> into a string and appends it + * to the specified <code>StringBuffer</code>. + * + * @param date The <code>Date</code> value to format. + * @param toAppendTo The <code>StringBuffer</code> to append the resultant + * <code>String</code> to. + * @param fieldPosition Is updated to the start and end index of the + * specified field. + * + * @return The <code>StringBuffer</code> supplied on input, with the + * formatted date/time appended. + */ public abstract StringBuffer format (Date date, StringBuffer buf, FieldPosition pos); + /** + * This method returns a list of available locales supported by this + * class. + */ public static Locale[] getAvailableLocales () { - return null; // FIXME + // FIXME + Locale[] l = new Locale[1]; + l[0] = Locale.US; + return l; } + /** + * This method returns the <code>Calendar</code> object being used by + * this object to parse/format datetimes. + * + * @return The <code>Calendar</code> being used by this object. + * + * @see java.util.Calendar + */ public Calendar getCalendar () { return calendar; @@ -112,7 +210,8 @@ public abstract class DateFormat extends Format implements Cloneable ResourceBundle res; try { - res = ResourceBundle.getBundle("gnu.gcj.text.LocaleData", loc); + res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + loc); } catch (MissingResourceException x) { @@ -199,32 +298,77 @@ public abstract class DateFormat extends Format implements Cloneable return new SimpleDateFormat (pattern, loc); } + /** + * This method returns an instance of <code>DateFormat</code> that will + * format using the default formatting style for dates. + * + * @return A new <code>DateFormat</code> instance. + */ public static final DateFormat getDateInstance () { return getDateInstance (DEFAULT, Locale.getDefault()); } + /** + * This method returns an instance of <code>DateFormat</code> that will + * format using the specified formatting style for dates. + * + * @param style The type of formatting to perform. + * + * @return A new <code>DateFormat</code> instance. + */ public static final DateFormat getDateInstance (int style) { return getDateInstance (style, Locale.getDefault()); } + /** + * This method returns an instance of <code>DateFormat</code> that will + * format using the specified formatting style for dates. The specified + * localed will be used in place of the default. + * + * @param style The type of formatting to perform. + * @param aLocale The desired locale. + * + * @return A new <code>DateFormat</code> instance. + */ public static final DateFormat getDateInstance (int style, Locale loc) { return computeInstance (style, loc, true, false); } + /** + * This method returns a new instance of <code>DateFormat</code> that + * formats both dates and times using the <code>SHORT</code> style. + * + * @return A new <code>DateFormat</code>instance. + */ public static final DateFormat getDateTimeInstance () { return getDateTimeInstance (DEFAULT, DEFAULT, Locale.getDefault()); } + /** + * This method returns a new instance of <code>DateFormat</code> that + * formats both dates and times using the <code>DEFAULT</code> style. + * + * @return A new <code>DateFormat</code>instance. + */ public static final DateFormat getDateTimeInstance (int dateStyle, int timeStyle) { return getDateTimeInstance (dateStyle, timeStyle, Locale.getDefault()); } + /** + * This method returns a new instance of <code>DateFormat</code> that + * formats both dates and times using the specified styles. + * + * @param dateStyle The desired style for date formatting. + * @param timeStyle The desired style for time formatting + * + * @return A new <code>DateFormat</code>instance. + */ public static final DateFormat getDateTimeInstance (int dateStyle, int timeStyle, Locale loc) @@ -232,37 +376,84 @@ public abstract class DateFormat extends Format implements Cloneable return computeInstance (dateStyle, timeStyle, loc, true, true); } + /** + * This method returns a new instance of <code>DateFormat</code> that + * formats both dates and times using the <code>SHORT</code> style. + * + * @return A new <code>DateFormat</code>instance. + */ public static final DateFormat getInstance () { // JCL book says SHORT. return getDateTimeInstance (SHORT, SHORT, Locale.getDefault()); } + /** + * This method returns the <code>NumberFormat</code> object being used + * by this object to parse/format time values. + * + * @return The <code>NumberFormat</code> in use by this object. + */ public NumberFormat getNumberFormat () { return numberFormat; } + /** + * This method returns an instance of <code>DateFormat</code> that will + * format using the default formatting style for times. + * + * @return A new <code>DateFormat</code> instance. + */ public static final DateFormat getTimeInstance () { return getTimeInstance (DEFAULT, Locale.getDefault()); } + /** + * This method returns an instance of <code>DateFormat</code> that will + * format using the specified formatting style for times. + * + * @param style The type of formatting to perform. + * + * @return A new <code>DateFormat</code> instance. + */ public static final DateFormat getTimeInstance (int style) { return getTimeInstance (style, Locale.getDefault()); } + /** + * This method returns an instance of <code>DateFormat</code> that will + * format using the specified formatting style for times. The specified + * localed will be used in place of the default. + * + * @param style The type of formatting to perform. + * @param aLocale The desired locale. + * + * @return A new <code>DateFormat</code> instance. + */ public static final DateFormat getTimeInstance (int style, Locale loc) { return computeInstance (style, loc, false, true); } + /** + * This method returns the <code>TimeZone</code> object being used by + * this instance. + * + * @return The time zone in use. + */ public TimeZone getTimeZone () { return calendar.getTimeZone(); } + /** + * This method returns a hash value for this object. + * + * @return A hash value for this object. + */ public int hashCode () { int hash = calendar.hashCode(); @@ -271,11 +462,25 @@ public abstract class DateFormat extends Format implements Cloneable return hash; } + /** + * This method indicates whether or not the parsing of date and time + * values should be done in a lenient value. + * + * @return <code>true</code> if date/time parsing is lenient, + * <code>false</code> otherwise. + */ public boolean isLenient () { return calendar.isLenient(); } + /** + * This method parses the specified date/time string. + * + * @return The resultant date. + * + * @exception ParseException If the specified string cannot be parsed. + */ public Date parse (String source) throws ParseException { ParsePosition pos = new ParsePosition(0); @@ -290,28 +495,79 @@ public abstract class DateFormat extends Format implements Cloneable return result; } + /** + * This method parses the specified <code>String</code> into a + * <code>Date</code>. The <code>pos</code> argument contains the + * starting parse position on method entry and the ending parse + * position on method exit. + * + * @param text The string to parse. + * @param pos The starting parse position in entry, the ending parse + * position on exit. + * + * @return The parsed date, or <code>null</code> if the string cannot + * be parsed. + */ public abstract Date parse (String source, ParsePosition pos); + /** + * This method is identical to <code>parse(String, ParsePosition)</code>, + * but returns its result as an <code>Object</code> instead of a + * <code>Date</code>. + * + * @param source The string to parse. + * @param pos The starting parse position in entry, the ending parse + * position on exit. + * + * @return The parsed date, or <code>null</code> if the string cannot + * be parsed. + */ public Object parseObject (String source, ParsePosition pos) { return parse(source, pos); } + /** + * This method specified the <code>Calendar</code> that should be used + * by this object to parse/format datetimes. + * + * @param The new <code>Calendar</code> for this object. + * + * @see java.util.Calendar + */ public void setCalendar (Calendar calendar) { this.calendar = calendar; } + /** + * This method specifies whether or not this object should be lenient in + * the syntax it accepts while parsing date/time values. + * + * @param lenient <code>true</code> if parsing should be lenient, + * <code>false</code> otherwise. + */ public void setLenient (boolean lenient) { calendar.setLenient(lenient); } + /** + * This method specifies the <code>NumberFormat</code> object that should + * be used by this object to parse/format times. + * + * @param The <code>NumberFormat</code> in use by this object. + */ public void setNumberFormat (NumberFormat numberFormat) { this.numberFormat = numberFormat; } + /** + * This method sets the time zone that should be used by this object. + * + * @param The new time zone. + */ public void setTimeZone (TimeZone timeZone) { calendar.setTimeZone(timeZone); diff --git a/libjava/java/text/DateFormatSymbols.java b/libjava/java/text/DateFormatSymbols.java index 252f9fa..4f45a4d 100644 --- a/libjava/java/text/DateFormatSymbols.java +++ b/libjava/java/text/DateFormatSymbols.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -13,16 +13,15 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; /** + * This class acts as container for locale specific date/time formatting + * information such as the days of the week and the months of the year. * @author Per Bothner <bothner@cygnus.com> * @date October 24, 1998. */ - /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3. * Status: Believed complete and correct. */ - -public class DateFormatSymbols extends Object - implements java.io.Serializable, Cloneable +public class DateFormatSymbols implements java.io.Serializable, Cloneable { String[] ampms; String[] eras; @@ -36,63 +35,9 @@ public class DateFormatSymbols extends Object private static final long serialVersionUID = -5987973545549424702L; // The order of these prefixes must be the same as in DateFormat - // FIXME: XXX: Note that this differs from the Classpath implemention - // in that there is no "default" entry; that is due to differing - // implementations where DateFormat.DEFAULT is MEDIUM here but 4 in - // Classpath (the JCL says it should be MEDIUM). That will need to be - // resolved in the merge. - private static final String[] formatPrefixes = { "full", "long", "medium", "short" }; - - private static final String[] ampmsDefault = {"AM", "PM" }; - private static final String[] erasDefault = {"BC", "AD" }; - // localPatternCharsDefault is used by SimpleDateFormat. - private static final String localPatternCharsDefault - = "GyMdkHmsSEDFwWahKz"; - private static final String[] monthsDefault = { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December", "" - }; - private static final String[] shortMonthsDefault = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" - }; - private static final String[] shortWeekdaysDefault = { - "", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; - private static final String[] weekdaysDefault = { - "", "Sunday", "Monday", "Tuesday", - "Wednesday", "Thursday", "Friday", "Saturday" - }; - - private static String[][] zoneStringsDefault = { - { "GMT", "Greenwich Mean Time", "GMT", - /**/ "Greenwich Mean Time", "GMT", "GMT" }, - { "PST", "Pacific Standard Time", "PST", - /**/ "Pacific Daylight Time", "PDT", "San Francisco" }, - { "MST", "Mountain Standard Time", "MST", - /**/ "Mountain Daylight Time", "MDT", "Denver" }, - { "PNT", "Mountain Standard Time", "MST", - /**/ "Mountain Standard Time", "MST", "Phoenix" }, - { "CST", "Central Standard Time", "CST", - /**/ "Central Daylight Time", "CDT", "Chicago" }, - { "EST", "Eastern Standard Time", "EST", - /**/ "Eastern Daylight Time", "EDT", "Boston" }, - { "IET", "Eastern Standard Time", "EST", - /**/ "Eastern Standard Time", "EST", "Indianapolis" }, - { "PRT", "Atlantic Standard Time", "AST", - /**/ "Atlantic Daylight Time", "ADT", "Halifax" }, - { "CNT", "Newfoundland Standard Time", "NST", - /**/ "Newfoundland Daylight Time", "NDT", "St. Johns" }, - { "ECT", "Central European Standard Time", "CET", - /**/ "Central European Daylight Time", "CEST", "Paris" }, - { "CTT", "China Standard Time", "CST", - /**/ "China Standard Time", "CST", "Shanghai" }, - { "JST", "Japan Standard Time", "JST", - /**/ "Japan Standard Time", "JST", "Tokyo" }, - { "HST", "Hawaii Standard Time", "HST", - /**/ "Hawaii Standard Time", "HST", "Honolulu" }, - { "AST", "Alaska Standard Time", "AKST", - /**/ "Alaska Daylight Time", "AKDT", "Anchorage" } + private static final String[] formatPrefixes = + { + "full", "long", "medium", "short" }; // These are each arrays with a value for SHORT, MEDIUM, LONG, FULL, @@ -113,146 +58,312 @@ public class DateFormatSymbols extends Object return values; } - private final Object safeGetResource (ResourceBundle res, - String key, Object def) - { - if (res != null) - { - try - { - return res.getObject(key); - } - catch (MissingResourceException x) - { - } - } - return def; - } - - public DateFormatSymbols (Locale locale) + /** + * This method initializes a new instance of <code>DateFormatSymbols</code> + * by loading the date format information for the specified locale. + * + * @param locale The locale for which date formatting symbols should + * be loaded. + */ + public DateFormatSymbols (Locale locale) throws MissingResourceException { - ResourceBundle res; - try - { - res = ResourceBundle.getBundle("gnu.gcj.text.LocaleData", locale); - } - catch (MissingResourceException x) - { - res = null; - } - ampms = (String[]) safeGetResource (res, "ampm", ampmsDefault); - eras = (String[]) safeGetResource (res, "eras", erasDefault); - localPatternChars = (String) safeGetResource (res, "datePatternChars", - localPatternCharsDefault); - months = (String[]) safeGetResource (res, "months", monthsDefault); - shortMonths = (String[]) safeGetResource (res, "shortMonths", - shortMonthsDefault); - shortWeekdays = (String[]) safeGetResource (res, "shortWeekdays", - shortWeekdaysDefault); - weekdays = (String[]) safeGetResource (res, "weekdays", weekdaysDefault); - zoneStrings = (String[][]) safeGetResource (res, "zoneStrings", - zoneStringsDefault); + ResourceBundle res + = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", locale); + + ampms = res.getStringArray ("ampms"); + eras = res.getStringArray ("eras"); + localPatternChars = res.getString ("localPatternChars"); + months = res.getStringArray ("months"); + shortMonths = res.getStringArray ("shortMonths"); + shortWeekdays = res.getStringArray ("shortWeekdays"); + weekdays = res.getStringArray ("weekdays"); + zoneStrings = (String[][]) res.getObject ("zoneStrings"); dateFormats = formatsForKey(res, "DateFormat"); timeFormats = formatsForKey(res, "TimeFormat"); } - public DateFormatSymbols () + /** + * This method loads the format symbol information for the default + * locale. + */ + public DateFormatSymbols () throws MissingResourceException { this (Locale.getDefault()); } - // Copy constructor. - private DateFormatSymbols (DateFormatSymbols old) - { - ampms = old.ampms; - eras = old.eras; - localPatternChars = old.localPatternChars; - months = old.months; - shortMonths = old.shortMonths; - shortWeekdays = old.shortWeekdays; - weekdays = old.weekdays; - zoneStrings = old.zoneStrings; - dateFormats = old.dateFormats; - timeFormats = old.timeFormats; - } - + /** + * This method returns the list of strings used for displaying AM or PM. + * This is a two element <code>String</code> array indexed by + * <code>Calendar.AM</code> and <code>Calendar.PM</code> + * + * @return The list of AM/PM display strings. + */ public String[] getAmPmStrings() { return ampms; } + /** + * This method returns the list of strings used for displaying eras + * (e.g., "BC" and "AD"). This is a two element <code>String</code> + * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>. + * + * @return The list of era disply strings. + */ public String[] getEras() { return eras; } - + /** + * This method returns the pattern character information for this + * object. This is an 18 character string that contains the characters + * that are used in creating the date formatting strings in + * <code>SimpleDateFormat</code>. The following are the character + * positions in the string and which format character they correspond + * to (the character in parentheses is the default value in the US English + * locale): + * <p> + * <ul> + * <li>0 - era (G) + * <li>1 - year (y) + * <li>2 - month (M) + * <li 3 - day of month (d) + * <li>4 - hour out of 12, from 1-12 (h) + * <li>5 - hour out of 24, from 0-23 (H) + * <li>6 - minute (m) + * <li>7 - second (s) + * <li>8 - millisecond (S) + * <li>9 - date of week (E) + * <li>10 - date of year (D) + * <li>11 - day of week in month, eg. "4th Thur in Nov" (F) + * <li>12 - week in year (w) + * <li>13 - week in month (W) + * <li>14 - am/pm (a) + * <li>15 - hour out of 24, from 1-24 (k) + * <li>16 - hour out of 12, from 0-11 (K) + * <li>17 - time zone (z) + * </ul> + * + * @return The format patter characters + */ public String getLocalPatternChars() { return localPatternChars; } + /** + * This method returns the list of strings used for displaying month + * names (e.g., "January" and "February"). This is a thirteen element + * string array indexed by <code>Calendar.JANUARY</code> through + * <code>Calendar.UNDECEMBER</code>. Note that there are thirteen + * elements because some calendars have thriteen months. + * + * @return The list of month display strings. + */ public String[] getMonths () { return months; } + /** + * This method returns the list of strings used for displaying abbreviated + * month names (e.g., "Jan" and "Feb"). This is a thirteen element + * <code>String</code> array indexed by <code>Calendar.JANUARY</code> + * through <code>Calendar.UNDECEMBER</code>. Note that there are thirteen + * elements because some calendars have thirteen months. + * + * @return The list of abbreviated month display strings. + */ public String[] getShortMonths () { return shortMonths; } + /** + * This method returns the list of strings used for displaying abbreviated + * weekday names (e.g., "Sun" and "Mon"). This is an eight element + * <code>String</code> array indexed by <code>Calendar.SUNDAY</code> + * through <code>Calendar.SATURDAY</code>. Note that the first element + * of this array is ignored. + * + * @return This list of abbreviated weekday display strings. + */ public String[] getShortWeekdays () { return shortWeekdays; } + /** + * This method returns the list of strings used for displaying weekday + * names (e.g., "Sunday" and "Monday"). This is an eight element + * <code>String</code> array indexed by <code>Calendar.SUNDAY</code> + * through <code>Calendar.SATURDAY</code>. Note that the first element + * of this array is ignored. + * + * @return This list of weekday display strings. + */ public String[] getWeekdays () { return weekdays; } + /** + * This method returns this list of localized timezone display strings. + * This is a two dimensional <code>String</code> array where each row in + * the array contains five values: + * <P> + * <ul> + * <li>0 - The non-localized time zone id string. + * <li>1 - The long name of the time zone (standard time). + * <li>2 - The short name of the time zone (standard time). + * <li>3 - The long name of the time zone (daylight savings time). + * <li>4 - the short name of the time zone (daylight savings time). + * + * @return The list of time zone display strings. + */ public String[] [] getZoneStrings () { return zoneStrings; } + /** + * This method sets the list of strings used to display AM/PM values to + * the specified list. + * This is a two element <code>String</code> array indexed by + * <code>Calendar.AM</code> and <code>Calendar.PM</code> + * + * @param ampms The new list of AM/PM display strings. + */ public void setAmPmStrings (String[] value) { ampms = value; } + /** + * This method sets the list of strings used to display time eras to + * to the specified list. + * This is a two element <code>String</code> + * array indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>. + * + * @param eras The new list of era disply strings. + */ public void setEras (String[] value) { eras = value; } + /** + * This method sets the list of characters used to specific date/time + * formatting strings. + * This is an 18 character string that contains the characters + * that are used in creating the date formatting strings in + * <code>SimpleDateFormat</code>. The following are the character + * positions in the string and which format character they correspond + * to (the character in parentheses is the default value in the US English + * locale): + * <p> + * <ul> + * <li>0 - era (G) + * <li>1 - year (y) + * <li>2 - month (M) + * <li 3 - day of month (d) + * <li>4 - hour out of 12, from 1-12 (h) + * <li>5 - hour out of 24, from 0-23 (H) + * <li>6 - minute (m) + * <li>7 - second (s) + * <li>8 - millisecond (S) + * <li>9 - date of week (E) + * <li>10 - date of year (D) + * <li>11 - day of week in month, eg. "4th Thur in Nov" (F) + * <li>12 - week in year (w) + * <li>13 - week in month (W) + * <li>14 - am/pm (a) + * <li>15 - hour out of 24, from 1-24 (k) + * <li>16 - hour out of 12, from 0-11 (K) + * <li>17 - time zone (z) + * </ul> + * + * @param localPatternChars The new format patter characters + */ public void setLocalPatternChars (String value) { localPatternChars = value; } + /** + * This method sets the list of strings used to display month names. + * This is a thirteen element + * string array indexed by <code>Calendar.JANUARY</code> through + * <code>Calendar.UNDECEMBER</code>. Note that there are thirteen + * elements because some calendars have thriteen months. + * + * @param months The list of month display strings. + */ public void setMonths (String[] value) { months = value; } + /** + * This method sets the list of strings used to display abbreviated month + * names. + * This is a thirteen element + * <code>String</code> array indexed by <code>Calendar.JANUARY</code> + * through <code>Calendar.UNDECEMBER</code>. Note that there are thirteen + * elements because some calendars have thirteen months. + * + * @param shortMonths The new list of abbreviated month display strings. + */ public void setShortMonths (String[] value) { shortMonths = value; } + /** + * This method sets the list of strings used to display abbreviated + * weekday names. + * This is an eight element + * <code>String</code> array indexed by <code>Calendar.SUNDAY</code> + * through <code>Calendar.SATURDAY</code>. Note that the first element + * of this array is ignored. + * + * @param shortWeekdays This list of abbreviated weekday display strings. + */ public void setShortWeekdays (String[] value) { shortWeekdays = value; } + /** + * This method sets the list of strings used to display weekday names. + * This is an eight element + * <code>String</code> array indexed by <code>Calendar.SUNDAY</code> + * through <code>Calendar.SATURDAY</code>. Note that the first element + * of this array is ignored. + * + * @param weekdays This list of weekday display strings. + */ public void setWeekdays (String[] value) { weekdays = value; } + /** + * This method sets the list of display strings for time zones. + * This is a two dimensional <code>String</code> array where each row in + * the array contains five values: + * <P> + * <ul> + * <li>0 - The non-localized time zone id string. + * <li>1 - The long name of the time zone (standard time). + * <li>2 - The short name of the time zone (standard time). + * <li>3 - The long name of the time zone (daylight savings time). + * <li>4 - the short name of the time zone (daylight savings time). + * + * @return The list of time zone display strings. + */ public void setZoneStrings (String[][] value) { zoneStrings = value; @@ -292,9 +403,24 @@ public class DateFormatSymbols extends Object return hash; } + /** + * This method tests a specified object for equality against this object. + * This will be true if and only if the specified object: + * <p> + * <ul> + * <li> Is not <code>null</code>. + * <li> Is an instance of <code>DateFormatSymbols</code>. + * <li> Contains identical formatting symbols to this object. + * </ul> + * + * @param obj The <code>Object</code> to test for equality against. + * + * @return <code>true</code> if the specified object is equal to this one, + * </code>false</code> otherwise. + */ public boolean equals (Object obj) { - if (obj == null || ! (obj instanceof DateFormatSymbols)) + if (! (obj instanceof DateFormatSymbols)) return false; DateFormatSymbols other = (DateFormatSymbols) obj; return (equals(ampms, other.ampms) @@ -307,11 +433,28 @@ public class DateFormatSymbols extends Object && equals(zoneStrings, other.zoneStrings)); } + /** + * Returns a new copy of this object. + * + * @param A copy of this object + */ public Object clone () { - return new DateFormatSymbols (this); + try + { + return super.clone (); + } + catch (CloneNotSupportedException e) + { + return null; + } } + /** + * This method returns a hash value for this object. + * + * @return A hash value for this object. + */ public int hashCode () { return (hashCode(ampms) diff --git a/libjava/java/text/DecimalFormat.java b/libjava/java/text/DecimalFormat.java index 42c8107..f6b7223 100644 --- a/libjava/java/text/DecimalFormat.java +++ b/libjava/java/text/DecimalFormat.java @@ -1,12 +1,28 @@ -// DecimalFormat.java - Localized number formatting. - -/* Copyright (C) 1999, 2000 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ +/* DecimalFormat.java -- Formats and parses numbers + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ package java.text; @@ -26,7 +42,6 @@ import java.io.IOException; * Note however that the docs are very unclear about how format parsing * should work. No doubt there are problems here. */ - public class DecimalFormat extends NumberFormat { // This is a helper for applyPatternWithSymbols. It reads a prefix @@ -34,940 +49,940 @@ public class DecimalFormat extends NumberFormat private final int scanFix (String pattern, int index, StringBuffer buf, String patChars, DecimalFormatSymbols syms, boolean is_suffix) - { - int len = pattern.length(); - buf.setLength(0); - boolean multiplierSet = false; - while (index < len) - { - char c = pattern.charAt(index); - if (c == '\'' && index + 1 < len - && pattern.charAt(index + 1) == '\'') - { - buf.append(c); - ++index; - } - else if (c == '\'' && index + 2 < len - && pattern.charAt(index + 2) == '\'') - { - buf.append(pattern.charAt(index + 1)); - index += 2; - } - else if (c == '\u00a4') - { - if (index + 1 < len && pattern.charAt(index + 1) == '\u00a4') - { - buf.append(syms.getInternationalCurrencySymbol()); - ++index; - } - else - buf.append(syms.getCurrencySymbol()); - } - else if (is_suffix && c == syms.getPercent()) - { - if (multiplierSet) - throw new IllegalArgumentException ("multiplier already set " + - "- index: " + index); - multiplierSet = true; - multiplier = 100; - buf.append(c); - } - else if (is_suffix && c == syms.getPerMill()) - { - if (multiplierSet) - throw new IllegalArgumentException ("multiplier already set " + - "- index: " + index); - multiplierSet = true; - multiplier = 1000; - buf.append(c); - } - else if (patChars.indexOf(c) != -1) - { - // This is a pattern character. - break; - } - else + { + int len = pattern.length(); + buf.setLength(0); + boolean multiplierSet = false; + while (index < len) + { + char c = pattern.charAt(index); + if (c == '\'' && index + 1 < len + && pattern.charAt(index + 1) == '\'') + { buf.append(c); - ++index; - } + ++index; + } + else if (c == '\'' && index + 2 < len + && pattern.charAt(index + 2) == '\'') + { + buf.append(pattern.charAt(index + 1)); + index += 2; + } + else if (c == '\u00a4') + { + if (index + 1 < len && pattern.charAt(index + 1) == '\u00a4') + { + buf.append(syms.getInternationalCurrencySymbol()); + ++index; + } + else + buf.append(syms.getCurrencySymbol()); + } + else if (is_suffix && c == syms.getPercent()) + { + if (multiplierSet) + throw new IllegalArgumentException ("multiplier already set " + + "- index: " + index); + multiplierSet = true; + multiplier = 100; + buf.append(c); + } + else if (is_suffix && c == syms.getPerMill()) + { + if (multiplierSet) + throw new IllegalArgumentException ("multiplier already set " + + "- index: " + index); + multiplierSet = true; + multiplier = 1000; + buf.append(c); + } + else if (patChars.indexOf(c) != -1) + { + // This is a pattern character. + break; + } + else + buf.append(c); + ++index; + } - return index; - } + return index; + } // A helper which reads a number format. private final int scanFormat (String pattern, int index, String patChars, DecimalFormatSymbols syms, boolean is_positive) - { - int max = pattern.length(); - - int countSinceGroup = 0; - int zeroCount = 0; - boolean saw_group = false; - - // - // Scan integer part. - // - while (index < max) - { - char c = pattern.charAt(index); - - if (c == syms.getDigit()) - { - if (zeroCount > 0) - throw new IllegalArgumentException ("digit mark following " + - "zero - index: " + index); - ++countSinceGroup; - } - else if (c == syms.getZeroDigit()) - { - ++zeroCount; - ++countSinceGroup; - } - else if (c == syms.getGroupingSeparator()) - { - countSinceGroup = 0; - saw_group = true; - } - else - break; + { + int max = pattern.length(); - ++index; - } - - // We can only side-effect when parsing the positive format. - if (is_positive) - { - groupingUsed = saw_group; - groupingSize = (byte) countSinceGroup; - minimumIntegerDigits = zeroCount; - } - - // Early termination. - if (index == max || pattern.charAt(index) == syms.getGroupingSeparator()) - { - if (is_positive) - decimalSeparatorAlwaysShown = false; - return index; - } - - if (pattern.charAt(index) == syms.getDecimalSeparator()) - { - ++index; - - // - // Scan fractional part. - // - int hashCount = 0; - zeroCount = 0; - while (index < max) - { - char c = pattern.charAt(index); - if (c == syms.getZeroDigit()) - { - if (hashCount > 0) - throw new IllegalArgumentException ("zero mark " + - "following digit - index: " + index); - ++zeroCount; - } - else if (c == syms.getDigit()) - { - ++hashCount; - } - else if (c != syms.getExponential() - && c != syms.getPatternSeparator() - && patChars.indexOf(c) != -1) - throw new IllegalArgumentException ("unexpected special " + - "character - index: " + index); - else - break; - - ++index; - } - - if (is_positive) - { - maximumFractionDigits = hashCount + zeroCount; - minimumFractionDigits = zeroCount; - } - - if (index == max) - return index; - } - - if (pattern.charAt(index) == syms.getExponential()) - { - // - // Scan exponential format. - // - zeroCount = 0; - ++index; - while (index < max) - { - char c = pattern.charAt(index); - if (c == syms.getZeroDigit()) + int countSinceGroup = 0; + int zeroCount = 0; + boolean saw_group = false; + + // + // Scan integer part. + // + while (index < max) + { + char c = pattern.charAt(index); + + if (c == syms.getDigit()) + { + if (zeroCount > 0) + throw new IllegalArgumentException ("digit mark following " + + "zero - index: " + index); + ++countSinceGroup; + } + else if (c == syms.getZeroDigit()) + { + ++zeroCount; + ++countSinceGroup; + } + else if (c == syms.getGroupingSeparator()) + { + countSinceGroup = 0; + saw_group = true; + } + else + break; + + ++index; + } + + // We can only side-effect when parsing the positive format. + if (is_positive) + { + groupingUsed = saw_group; + groupingSize = (byte) countSinceGroup; + minimumIntegerDigits = zeroCount; + } + + // Early termination. + if (index == max || pattern.charAt(index) == syms.getGroupingSeparator()) + { + if (is_positive) + decimalSeparatorAlwaysShown = false; + return index; + } + + if (pattern.charAt(index) == syms.getDecimalSeparator()) + { + ++index; + + // + // Scan fractional part. + // + int hashCount = 0; + zeroCount = 0; + while (index < max) + { + char c = pattern.charAt(index); + if (c == syms.getZeroDigit()) + { + if (hashCount > 0) + throw new IllegalArgumentException ("zero mark " + + "following digit - index: " + index); ++zeroCount; - else if (c == syms.getDigit()) - { - if (zeroCount > 0) - throw new - IllegalArgumentException ("digit mark following zero " + - "in exponent - index: " + - index); - } - else if (patChars.indexOf(c) != -1) - throw new IllegalArgumentException ("unexpected special " + - "character - index: " + - index); - else - break; - - ++index; - } - - if (is_positive) - { - useExponentialNotation = true; - minExponentDigits = (byte) zeroCount; - } - } - - return index; - } + } + else if (c == syms.getDigit()) + { + ++hashCount; + } + else if (c != syms.getExponential() + && c != syms.getPatternSeparator() + && patChars.indexOf(c) != -1) + throw new IllegalArgumentException ("unexpected special " + + "character - index: " + index); + else + break; + + ++index; + } + + if (is_positive) + { + maximumFractionDigits = hashCount + zeroCount; + minimumFractionDigits = zeroCount; + } + + if (index == max) + return index; + } + + if (pattern.charAt(index) == syms.getExponential()) + { + // + // Scan exponential format. + // + zeroCount = 0; + ++index; + while (index < max) + { + char c = pattern.charAt(index); + if (c == syms.getZeroDigit()) + ++zeroCount; + else if (c == syms.getDigit()) + { + if (zeroCount > 0) + throw new + IllegalArgumentException ("digit mark following zero " + + "in exponent - index: " + + index); + } + else if (patChars.indexOf(c) != -1) + throw new IllegalArgumentException ("unexpected special " + + "character - index: " + + index); + else + break; + + ++index; + } + + if (is_positive) + { + useExponentialNotation = true; + minExponentDigits = (byte) zeroCount; + } + } + + return index; + } // This helper function creates a string consisting of all the // characters which can appear in a pattern and must be quoted. private final String patternChars (DecimalFormatSymbols syms) - { - StringBuffer buf = new StringBuffer (); - buf.append(syms.getDecimalSeparator()); - buf.append(syms.getDigit()); - buf.append(syms.getExponential()); - buf.append(syms.getGroupingSeparator()); - // Adding this one causes pattern application to fail. - // Of course, omitting is causes toPattern to fail. - // ... but we already have bugs there. FIXME. - // buf.append(syms.getMinusSign()); - buf.append(syms.getPatternSeparator()); - buf.append(syms.getPercent()); - buf.append(syms.getPerMill()); - buf.append(syms.getZeroDigit()); - buf.append('\u00a4'); - return buf.toString(); - } + { + StringBuffer buf = new StringBuffer (); + buf.append(syms.getDecimalSeparator()); + buf.append(syms.getDigit()); + buf.append(syms.getExponential()); + buf.append(syms.getGroupingSeparator()); + // Adding this one causes pattern application to fail. + // Of course, omitting is causes toPattern to fail. + // ... but we already have bugs there. FIXME. + // buf.append(syms.getMinusSign()); + buf.append(syms.getPatternSeparator()); + buf.append(syms.getPercent()); + buf.append(syms.getPerMill()); + buf.append(syms.getZeroDigit()); + buf.append('\u00a4'); + return buf.toString(); + } private final void applyPatternWithSymbols (String pattern, DecimalFormatSymbols syms) - { - // Initialize to the state the parser expects. - negativePrefix = ""; - negativeSuffix = ""; - positivePrefix = ""; - positiveSuffix = ""; - decimalSeparatorAlwaysShown = false; - groupingSize = 0; - minExponentDigits = 0; - multiplier = 1; - useExponentialNotation = false; - groupingUsed = false; - maximumFractionDigits = 0; - maximumIntegerDigits = 309; - minimumFractionDigits = 0; - minimumIntegerDigits = 1; - - StringBuffer buf = new StringBuffer (); - String patChars = patternChars (syms); - - int max = pattern.length(); - int index = scanFix (pattern, 0, buf, patChars, syms, false); - positivePrefix = buf.toString(); - - index = scanFormat (pattern, index, patChars, syms, true); - - index = scanFix (pattern, index, buf, patChars, syms, true); - positiveSuffix = buf.toString(); - - if (index == pattern.length()) - { - // No negative info. - negativePrefix = null; - negativeSuffix = null; - } - else - { - if (pattern.charAt(index) != syms.getPatternSeparator()) - throw new IllegalArgumentException ("separator character " + - "expected - index: " + index); - - index = scanFix (pattern, index + 1, buf, patChars, syms, false); - negativePrefix = buf.toString(); - - // We parse the negative format for errors but we don't let - // it side-effect this object. - index = scanFormat (pattern, index, patChars, syms, false); - - index = scanFix (pattern, index, buf, patChars, syms, true); - negativeSuffix = buf.toString(); - - if (index != pattern.length()) - throw new IllegalArgumentException ("end of pattern expected " + - "- index: " + index); - } - } + { + // Initialize to the state the parser expects. + negativePrefix = ""; + negativeSuffix = ""; + positivePrefix = ""; + positiveSuffix = ""; + decimalSeparatorAlwaysShown = false; + groupingSize = 0; + minExponentDigits = 0; + multiplier = 1; + useExponentialNotation = false; + groupingUsed = false; + maximumFractionDigits = 0; + maximumIntegerDigits = 309; + minimumFractionDigits = 0; + minimumIntegerDigits = 1; + + StringBuffer buf = new StringBuffer (); + String patChars = patternChars (syms); + + int max = pattern.length(); + int index = scanFix (pattern, 0, buf, patChars, syms, false); + positivePrefix = buf.toString(); + + index = scanFormat (pattern, index, patChars, syms, true); + + index = scanFix (pattern, index, buf, patChars, syms, true); + positiveSuffix = buf.toString(); + + if (index == pattern.length()) + { + // No negative info. + negativePrefix = null; + negativeSuffix = null; + } + else + { + if (pattern.charAt(index) != syms.getPatternSeparator()) + throw new IllegalArgumentException ("separator character " + + "expected - index: " + index); + + index = scanFix (pattern, index + 1, buf, patChars, syms, false); + negativePrefix = buf.toString(); + + // We parse the negative format for errors but we don't let + // it side-effect this object. + index = scanFormat (pattern, index, patChars, syms, false); + + index = scanFix (pattern, index, buf, patChars, syms, true); + negativeSuffix = buf.toString(); + + if (index != pattern.length()) + throw new IllegalArgumentException ("end of pattern expected " + + "- index: " + index); + } + } public void applyLocalizedPattern (String pattern) - { - // JCL p. 638 claims this throws a ParseException but p. 629 - // contradicts this. Empirical tests with patterns of "0,###.0" - // and "#.#.#" corroborate the p. 629 statement that an - // IllegalArgumentException is thrown. - applyPatternWithSymbols (pattern, symbols); - } + { + // JCL p. 638 claims this throws a ParseException but p. 629 + // contradicts this. Empirical tests with patterns of "0,###.0" + // and "#.#.#" corroborate the p. 629 statement that an + // IllegalArgumentException is thrown. + applyPatternWithSymbols (pattern, symbols); + } public void applyPattern (String pattern) - { - // JCL p. 638 claims this throws a ParseException but p. 629 - // contradicts this. Empirical tests with patterns of "0,###.0" - // and "#.#.#" corroborate the p. 629 statement that an - // IllegalArgumentException is thrown. - applyPatternWithSymbols (pattern, nonLocalizedSymbols); - } + { + // JCL p. 638 claims this throws a ParseException but p. 629 + // contradicts this. Empirical tests with patterns of "0,###.0" + // and "#.#.#" corroborate the p. 629 statement that an + // IllegalArgumentException is thrown. + applyPatternWithSymbols (pattern, nonLocalizedSymbols); + } public Object clone () - { - return new DecimalFormat (this); - } + { + return new DecimalFormat (this); + } private DecimalFormat (DecimalFormat dup) - { - decimalSeparatorAlwaysShown = dup.decimalSeparatorAlwaysShown; - groupingSize = dup.groupingSize; - minExponentDigits = dup.minExponentDigits; - multiplier = dup.multiplier; - negativePrefix = dup.negativePrefix; - negativeSuffix = dup.negativeSuffix; - positivePrefix = dup.positivePrefix; - positiveSuffix = dup.positiveSuffix; - symbols = (DecimalFormatSymbols) dup.symbols.clone(); - useExponentialNotation = dup.useExponentialNotation; - } + { + decimalSeparatorAlwaysShown = dup.decimalSeparatorAlwaysShown; + groupingSize = dup.groupingSize; + minExponentDigits = dup.minExponentDigits; + multiplier = dup.multiplier; + negativePrefix = dup.negativePrefix; + negativeSuffix = dup.negativeSuffix; + positivePrefix = dup.positivePrefix; + positiveSuffix = dup.positiveSuffix; + symbols = (DecimalFormatSymbols) dup.symbols.clone(); + useExponentialNotation = dup.useExponentialNotation; + } public DecimalFormat () - { - this ("#,##0.###"); - } + { + this ("#,##0.###"); + } public DecimalFormat (String pattern) - { - this (pattern, new DecimalFormatSymbols ()); - } + { + this (pattern, new DecimalFormatSymbols ()); + } public DecimalFormat (String pattern, DecimalFormatSymbols symbols) - { - this.symbols = symbols; - applyPattern (pattern); - } + { + this.symbols = symbols; + applyPattern (pattern); + } private final boolean equals (String s1, String s2) - { - if (s1 == null || s2 == null) - return s1 == s2; - return s1.equals(s2); - } + { + if (s1 == null || s2 == null) + return s1 == s2; + return s1.equals(s2); + } public boolean equals (Object obj) - { - if (! (obj instanceof DecimalFormat)) - return false; - DecimalFormat dup = (DecimalFormat) obj; - return (decimalSeparatorAlwaysShown == dup.decimalSeparatorAlwaysShown - && groupingSize == dup.groupingSize - && minExponentDigits == dup.minExponentDigits - && multiplier == dup.multiplier - && equals(negativePrefix, dup.negativePrefix) - && equals(negativeSuffix, dup.negativeSuffix) - && equals(positivePrefix, dup.positivePrefix) - && equals(positiveSuffix, dup.positiveSuffix) - && symbols.equals(dup.symbols) - && useExponentialNotation == dup.useExponentialNotation); - } + { + if (! (obj instanceof DecimalFormat)) + return false; + DecimalFormat dup = (DecimalFormat) obj; + return (decimalSeparatorAlwaysShown == dup.decimalSeparatorAlwaysShown + && groupingSize == dup.groupingSize + && minExponentDigits == dup.minExponentDigits + && multiplier == dup.multiplier + && equals(negativePrefix, dup.negativePrefix) + && equals(negativeSuffix, dup.negativeSuffix) + && equals(positivePrefix, dup.positivePrefix) + && equals(positiveSuffix, dup.positiveSuffix) + && symbols.equals(dup.symbols) + && useExponentialNotation == dup.useExponentialNotation); + } public StringBuffer format (double number, StringBuffer dest, FieldPosition fieldPos) - { - // A very special case. - if (Double.isNaN(number)) - { - dest.append(symbols.getNaN()); - if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) - { - int index = dest.length(); - fieldPos.setBeginIndex(index - symbols.getNaN().length()); - fieldPos.setEndIndex(index); - } - return dest; - } - - boolean is_neg = number < 0; - if (is_neg) - { - if (negativePrefix != null) - dest.append(negativePrefix); - else - { - dest.append(symbols.getMinusSign()); - dest.append(positivePrefix); - } - number = - number; - } - else - dest.append(positivePrefix); - - int integerBeginIndex = dest.length(); - int integerEndIndex = 0; - if (Double.isInfinite (number)) - { - dest.append(symbols.getInfinity()); - integerEndIndex = dest.length(); - } - else - { - number *= multiplier; - - // Compute exponent. - long exponent = 0; - double baseNumber; - if (useExponentialNotation) - { - exponent = (long) (Math.log(number) / Math.log(10)); - if (minimumIntegerDigits > 0) - exponent -= minimumIntegerDigits - 1; - baseNumber = (long) (number / Math.pow(10.0, exponent)); - } - else - baseNumber = number; - - // Round to the correct number of digits. - baseNumber += 5 * Math.pow(10.0, - maximumFractionDigits - 1); - - int index = dest.length(); - double intPart = Math.floor(baseNumber); - int count = 0; - while (count < maximumIntegerDigits - && (intPart > 0 || count < minimumIntegerDigits)) - { - long dig = (long) (intPart % 10); - intPart = Math.floor(intPart / 10); - - // Append group separator if required. - if (groupingUsed && count > 0 && count % groupingSize == 0) - dest.insert(index, symbols.getGroupingSeparator()); - - dest.insert(index, (char) (symbols.getZeroDigit() + dig)); - - ++count; - } - - integerEndIndex = dest.length(); - - int decimal_index = integerEndIndex; - int consecutive_zeros = 0; - int total_digits = 0; - - // Strip integer part from NUMBER. - double fracPart = baseNumber - Math.floor(baseNumber); - for (count = 0; - count < maximumFractionDigits - && (fracPart != 0 || count < minimumFractionDigits); - ++count) - { - ++total_digits; - fracPart *= 10; - long dig = (long) fracPart; - if (dig == 0) - ++consecutive_zeros; - else - consecutive_zeros = 0; - dest.append((char) (symbols.getZeroDigit() + dig)); - - // Strip integer part from FRACPART. - fracPart = fracPart - Math.floor (fracPart); - } - - // Strip extraneous trailing `0's. We can't always detect - // these in the loop. - int extra_zeros = Math.min (consecutive_zeros, - total_digits - minimumFractionDigits); - if (extra_zeros > 0) - { - dest.setLength(dest.length() - extra_zeros); - total_digits -= extra_zeros; - } - - // If required, add the decimal symbol. - if (decimalSeparatorAlwaysShown - || total_digits > 0) - { - dest.insert(decimal_index, symbols.getDecimalSeparator()); - if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD) - { - fieldPos.setBeginIndex(decimal_index + 1); - fieldPos.setEndIndex(dest.length()); - } - } - - // Finally, print the exponent. - if (useExponentialNotation) - { - dest.append(symbols.getExponential()); - dest.append(exponent < 0 ? '-' : '+'); - index = dest.length(); - for (count = 0; - exponent > 0 || count < minExponentDigits; - ++count) - { - long dig = exponent % 10; - exponent /= 10; - dest.insert(index, (char) (symbols.getZeroDigit() + dig)); - } - } - } - - if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) - { - fieldPos.setBeginIndex(integerBeginIndex); - fieldPos.setEndIndex(integerEndIndex); - } - - dest.append((is_neg && negativeSuffix != null) - ? negativeSuffix - : positiveSuffix); - return dest; - } + { + // A very special case. + if (Double.isNaN(number)) + { + dest.append(symbols.getNaN()); + if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) + { + int index = dest.length(); + fieldPos.setBeginIndex(index - symbols.getNaN().length()); + fieldPos.setEndIndex(index); + } + return dest; + } + + boolean is_neg = number < 0; + if (is_neg) + { + if (negativePrefix != null) + dest.append(negativePrefix); + else + { + dest.append(symbols.getMinusSign()); + dest.append(positivePrefix); + } + number = - number; + } + else + dest.append(positivePrefix); + + int integerBeginIndex = dest.length(); + int integerEndIndex = 0; + if (Double.isInfinite (number)) + { + dest.append(symbols.getInfinity()); + integerEndIndex = dest.length(); + } + else + { + number *= multiplier; + + // Compute exponent. + long exponent = 0; + double baseNumber; + if (useExponentialNotation) + { + exponent = (long) (Math.log(number) / Math.log(10)); + if (minimumIntegerDigits > 0) + exponent -= minimumIntegerDigits - 1; + baseNumber = (long) (number / Math.pow(10.0, exponent)); + } + else + baseNumber = number; + + // Round to the correct number of digits. + baseNumber += 5 * Math.pow(10.0, - maximumFractionDigits - 1); + + int index = dest.length(); + double intPart = Math.floor(baseNumber); + int count = 0; + while (count < maximumIntegerDigits + && (intPart > 0 || count < minimumIntegerDigits)) + { + long dig = (long) (intPart % 10); + intPart = Math.floor(intPart / 10); + + // Append group separator if required. + if (groupingUsed && count > 0 && count % groupingSize == 0) + dest.insert(index, symbols.getGroupingSeparator()); + + dest.insert(index, (char) (symbols.getZeroDigit() + dig)); + + ++count; + } + + integerEndIndex = dest.length(); + + int decimal_index = integerEndIndex; + int consecutive_zeros = 0; + int total_digits = 0; + + // Strip integer part from NUMBER. + double fracPart = baseNumber - Math.floor(baseNumber); + for (count = 0; + count < maximumFractionDigits + && (fracPart != 0 || count < minimumFractionDigits); + ++count) + { + ++total_digits; + fracPart *= 10; + long dig = (long) fracPart; + if (dig == 0) + ++consecutive_zeros; + else + consecutive_zeros = 0; + dest.append((char) (symbols.getZeroDigit() + dig)); + + // Strip integer part from FRACPART. + fracPart = fracPart - Math.floor (fracPart); + } + + // Strip extraneous trailing `0's. We can't always detect + // these in the loop. + int extra_zeros = Math.min (consecutive_zeros, + total_digits - minimumFractionDigits); + if (extra_zeros > 0) + { + dest.setLength(dest.length() - extra_zeros); + total_digits -= extra_zeros; + } + + // If required, add the decimal symbol. + if (decimalSeparatorAlwaysShown + || total_digits > 0) + { + dest.insert(decimal_index, symbols.getDecimalSeparator()); + if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD) + { + fieldPos.setBeginIndex(decimal_index + 1); + fieldPos.setEndIndex(dest.length()); + } + } + + // Finally, print the exponent. + if (useExponentialNotation) + { + dest.append(symbols.getExponential()); + dest.append(exponent < 0 ? '-' : '+'); + index = dest.length(); + for (count = 0; + exponent > 0 || count < minExponentDigits; + ++count) + { + long dig = exponent % 10; + exponent /= 10; + dest.insert(index, (char) (symbols.getZeroDigit() + dig)); + } + } + } + + if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) + { + fieldPos.setBeginIndex(integerBeginIndex); + fieldPos.setEndIndex(integerEndIndex); + } + + dest.append((is_neg && negativeSuffix != null) + ? negativeSuffix + : positiveSuffix); + return dest; + } public StringBuffer format (long number, StringBuffer dest, FieldPosition fieldPos) - { - // If using exponential notation, we just format as a double. - if (useExponentialNotation) - return format ((double) number, dest, fieldPos); - - boolean is_neg = number < 0; - if (is_neg) - { - if (negativePrefix != null) - dest.append(negativePrefix); - else - { - dest.append(symbols.getMinusSign()); - dest.append(positivePrefix); - } - number = - number; - } - else - dest.append(positivePrefix); - - int integerBeginIndex = dest.length(); - int index = dest.length(); - int count = 0; - while (count < maximumIntegerDigits - && (number > 0 || count < minimumIntegerDigits)) - { - long dig = number % 10; - number /= 10; - // NUMBER and DIG will be less than 0 if the original number - // was the most negative long. - if (dig < 0) - { - dig = - dig; - number = - number; - } - - // Append group separator if required. - if (groupingUsed && count > 0 && count % groupingSize == 0) - dest.insert(index, symbols.getGroupingSeparator()); - - dest.insert(index, (char) (symbols.getZeroDigit() + dig)); - - ++count; - } - - if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) - { - fieldPos.setBeginIndex(integerBeginIndex); - fieldPos.setEndIndex(dest.length()); - } - - if (decimalSeparatorAlwaysShown || minimumFractionDigits > 0) - { - dest.append(symbols.getDecimalSeparator()); - if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD) - { - fieldPos.setBeginIndex(dest.length()); - fieldPos.setEndIndex(dest.length() + minimumFractionDigits); - } - } - - for (count = 0; count < minimumFractionDigits; ++count) - dest.append(symbols.getZeroDigit()); - - dest.append((is_neg && negativeSuffix != null) - ? negativeSuffix - : positiveSuffix); - return dest; - } + { + // If using exponential notation, we just format as a double. + if (useExponentialNotation) + return format ((double) number, dest, fieldPos); + + boolean is_neg = number < 0; + if (is_neg) + { + if (negativePrefix != null) + dest.append(negativePrefix); + else + { + dest.append(symbols.getMinusSign()); + dest.append(positivePrefix); + } + number = - number; + } + else + dest.append(positivePrefix); + + int integerBeginIndex = dest.length(); + int index = dest.length(); + int count = 0; + while (count < maximumIntegerDigits + && (number > 0 || count < minimumIntegerDigits)) + { + long dig = number % 10; + number /= 10; + // NUMBER and DIG will be less than 0 if the original number + // was the most negative long. + if (dig < 0) + { + dig = - dig; + number = - number; + } + + // Append group separator if required. + if (groupingUsed && count > 0 && count % groupingSize == 0) + dest.insert(index, symbols.getGroupingSeparator()); + + dest.insert(index, (char) (symbols.getZeroDigit() + dig)); + + ++count; + } + + if (fieldPos != null && fieldPos.getField() == INTEGER_FIELD) + { + fieldPos.setBeginIndex(integerBeginIndex); + fieldPos.setEndIndex(dest.length()); + } + + if (decimalSeparatorAlwaysShown || minimumFractionDigits > 0) + { + dest.append(symbols.getDecimalSeparator()); + if (fieldPos != null && fieldPos.getField() == FRACTION_FIELD) + { + fieldPos.setBeginIndex(dest.length()); + fieldPos.setEndIndex(dest.length() + minimumFractionDigits); + } + } + + for (count = 0; count < minimumFractionDigits; ++count) + dest.append(symbols.getZeroDigit()); + + dest.append((is_neg && negativeSuffix != null) + ? negativeSuffix + : positiveSuffix); + return dest; + } public DecimalFormatSymbols getDecimalFormatSymbols () - { - return symbols; - } + { + return symbols; + } public int getGroupingSize () - { - return groupingSize; - } + { + return groupingSize; + } public int getMultiplier () - { - return multiplier; - } + { + return multiplier; + } public String getNegativePrefix () - { - return negativePrefix; - } + { + return negativePrefix; + } public String getNegativeSuffix () - { - return negativeSuffix; - } + { + return negativeSuffix; + } public String getPositivePrefix () - { - return positivePrefix; - } + { + return positivePrefix; + } public String getPositiveSuffix () - { - return positiveSuffix; - } + { + return positiveSuffix; + } public int hashCode () - { - int hash = (negativeSuffix.hashCode() ^ negativePrefix.hashCode() - ^positivePrefix.hashCode() ^ positiveSuffix.hashCode()); - // FIXME. - return hash; - } + { + int hash = (negativeSuffix.hashCode() ^ negativePrefix.hashCode() + ^positivePrefix.hashCode() ^ positiveSuffix.hashCode()); + // FIXME. + return hash; + } public boolean isDecimalSeparatorAlwaysShown () - { - return decimalSeparatorAlwaysShown; - } + { + return decimalSeparatorAlwaysShown; + } public Number parse (String str, ParsePosition pos) - { - // Our strategy is simple: copy the text into a buffer, - // translating or omitting locale-specific information. Then - // let Double or Long convert the number for us. + { + // Our strategy is simple: copy the text into a buffer, + // translating or omitting locale-specific information. Then + // let Double or Long convert the number for us. - boolean is_neg = false; - int index = pos.getIndex(); - StringBuffer buf = new StringBuffer (); + boolean is_neg = false; + int index = pos.getIndex(); + StringBuffer buf = new StringBuffer (); // We have to check both prefixes, because one might be empty. // We want to pick the longest prefix that matches. - boolean got_pos = str.startsWith(positivePrefix, index); - String np = (negativePrefix != null - ? negativePrefix - : positivePrefix + symbols.getMinusSign()); - boolean got_neg = str.startsWith(np, index); - - if (got_pos && got_neg) - { - // By checking this way, we preserve ambiguity in the case - // where the negative format differs only in suffix. We - // check this again later. - if (np.length() > positivePrefix.length()) - { - is_neg = true; - index += np.length(); - } - else - index += positivePrefix.length(); - } - else if (got_neg) - { - is_neg = true; - index += np.length(); - } - else if (got_pos) - index += positivePrefix.length(); - else - { - pos.setErrorIndex (index); - return null; - } - - // FIXME: handle Inf and NaN. + boolean got_pos = str.startsWith(positivePrefix, index); + String np = (negativePrefix != null + ? negativePrefix + : positivePrefix + symbols.getMinusSign()); + boolean got_neg = str.startsWith(np, index); + + if (got_pos && got_neg) + { + // By checking this way, we preserve ambiguity in the case + // where the negative format differs only in suffix. We + // check this again later. + if (np.length() > positivePrefix.length()) + { + is_neg = true; + index += np.length(); + } + else + index += positivePrefix.length(); + } + else if (got_neg) + { + is_neg = true; + index += np.length(); + } + else if (got_pos) + index += positivePrefix.length(); + else + { + pos.setErrorIndex (index); + return null; + } + + // FIXME: handle Inf and NaN. // FIXME: do we have to respect minimum/maxmimum digit stuff? // What about leading zeros? What about multiplier? - int start_index = index; - int max = str.length(); - char zero = symbols.getZeroDigit(); - int last_group = -1; - boolean int_part = true; - boolean exp_part = false; - for (; index < max; ++index) - { - char c = str.charAt(index); - - // FIXME: what about grouping size? - if (groupingUsed && c == symbols.getGroupingSeparator()) - { - if (last_group != -1 - && (index - last_group) % groupingSize != 0) - { - pos.setErrorIndex(index); - return null; - } - last_group = index; - } - else if (c >= zero && c <= zero + 9) - { - buf.append((char) (c - zero + '0')); - exp_part = false; - } - else if (parseIntegerOnly) - break; - else if (c == symbols.getDecimalSeparator()) - { - if (last_group != -1 - && (index - last_group) % groupingSize != 0) - { - pos.setErrorIndex(index); - return null; - } - buf.append('.'); - int_part = false; - } - else if (c == symbols.getExponential()) - { - buf.append('E'); - int_part = false; - exp_part = true; - } - else if (exp_part - && (c == '+' || c == '-' || c == symbols.getMinusSign())) - { - // For exponential notation. - buf.append(c); - } - else - break; - } - - if (index == start_index) - { - // Didn't see any digits. - pos.setErrorIndex(index); - return null; - } - - // Check the suffix. We must do this before converting the - // buffer to a number to handle the case of a number which is - // the most negative Long. - boolean got_pos_suf = str.startsWith(positiveSuffix, index); - String ns = (negativePrefix == null ? positiveSuffix : negativeSuffix); - boolean got_neg_suf = str.startsWith(ns, index); - if (is_neg) - { - if (! got_neg_suf) - { - pos.setErrorIndex(index); - return null; - } - } - else if (got_pos && got_neg && got_neg_suf) - { - is_neg = true; - } - else if (got_pos != got_pos_suf && got_neg != got_neg_suf) - { - pos.setErrorIndex(index); - return null; - } - - String suffix = is_neg ? ns : positiveSuffix; - if (is_neg) - buf.insert(0, '-'); - - String t = buf.toString(); - Number result = null; - try - { - result = new Long (t); - } - catch (NumberFormatException x1) - { - try - { - result = new Double (t); - } - catch (NumberFormatException x2) - { - } - } - if (result == null) - { - pos.setErrorIndex(index); - return null; - } - - pos.setIndex(index + suffix.length()); - - return result; - } + int start_index = index; + int max = str.length(); + char zero = symbols.getZeroDigit(); + int last_group = -1; + boolean int_part = true; + boolean exp_part = false; + for (; index < max; ++index) + { + char c = str.charAt(index); + + // FIXME: what about grouping size? + if (groupingUsed && c == symbols.getGroupingSeparator()) + { + if (last_group != -1 + && (index - last_group) % groupingSize != 0) + { + pos.setErrorIndex(index); + return null; + } + last_group = index; + } + else if (c >= zero && c <= zero + 9) + { + buf.append((char) (c - zero + '0')); + exp_part = false; + } + else if (parseIntegerOnly) + break; + else if (c == symbols.getDecimalSeparator()) + { + if (last_group != -1 + && (index - last_group) % groupingSize != 0) + { + pos.setErrorIndex(index); + return null; + } + buf.append('.'); + int_part = false; + } + else if (c == symbols.getExponential()) + { + buf.append('E'); + int_part = false; + exp_part = true; + } + else if (exp_part + && (c == '+' || c == '-' || c == symbols.getMinusSign())) + { + // For exponential notation. + buf.append(c); + } + else + break; + } + + if (index == start_index) + { + // Didn't see any digits. + pos.setErrorIndex(index); + return null; + } + + // Check the suffix. We must do this before converting the + // buffer to a number to handle the case of a number which is + // the most negative Long. + boolean got_pos_suf = str.startsWith(positiveSuffix, index); + String ns = (negativePrefix == null ? positiveSuffix : negativeSuffix); + boolean got_neg_suf = str.startsWith(ns, index); + if (is_neg) + { + if (! got_neg_suf) + { + pos.setErrorIndex(index); + return null; + } + } + else if (got_pos && got_neg && got_neg_suf) + { + is_neg = true; + } + else if (got_pos != got_pos_suf && got_neg != got_neg_suf) + { + pos.setErrorIndex(index); + return null; + } + + String suffix = is_neg ? ns : positiveSuffix; + if (is_neg) + buf.insert(0, '-'); + + String t = buf.toString(); + Number result = null; + try + { + result = new Long (t); + } + catch (NumberFormatException x1) + { + try + { + result = new Double (t); + } + catch (NumberFormatException x2) + { + } + } + if (result == null) + { + pos.setErrorIndex(index); + return null; + } + + pos.setIndex(index + suffix.length()); + + return result; + } public void setDecimalFormatSymbols (DecimalFormatSymbols newSymbols) - { - symbols = newSymbols; - } + { + symbols = newSymbols; + } public void setDecimalSeparatorAlwaysShown (boolean newValue) - { - decimalSeparatorAlwaysShown = newValue; - } + { + decimalSeparatorAlwaysShown = newValue; + } public void setGroupingSize (int groupSize) - { - groupingSize = (byte) groupSize; - } + { + groupingSize = (byte) groupSize; + } public void setMaximumFractionDigits (int newValue) - { - maximumFractionDigits = Math.min(newValue, 340); - } + { + maximumFractionDigits = Math.min(newValue, 340); + } public void setMaximumIntegerDigits (int newValue) - { - maximumIntegerDigits = Math.min(newValue, 309); - } + { + maximumIntegerDigits = Math.min(newValue, 309); + } public void setMinimumFractionDigits (int newValue) - { - minimumFractionDigits = Math.min(newValue, 340); - } + { + minimumFractionDigits = Math.min(newValue, 340); + } public void setMinimumIntegerDigits (int newValue) - { - minimumIntegerDigits = Math.min(newValue, 309); - } + { + minimumIntegerDigits = Math.min(newValue, 309); + } public void setMultiplier (int newValue) - { - multiplier = newValue; - } + { + multiplier = newValue; + } public void setNegativePrefix (String newValue) - { - negativePrefix = newValue; - } + { + negativePrefix = newValue; + } public void setNegativeSuffix (String newValue) - { - negativeSuffix = newValue; - } + { + negativeSuffix = newValue; + } public void setPositivePrefix (String newValue) - { - positivePrefix = newValue; - } + { + positivePrefix = newValue; + } public void setPositiveSuffix (String newValue) - { - positiveSuffix = newValue; - } + { + positiveSuffix = newValue; + } private final void quoteFix (StringBuffer buf, String text, String patChars) - { - int len = text.length(); - for (int index = 0; index < len; ++index) - { - char c = text.charAt(index); - if (patChars.indexOf(c) != -1) - { - buf.append('\''); - buf.append(c); - buf.append('\''); - } - else + { + int len = text.length(); + for (int index = 0; index < len; ++index) + { + char c = text.charAt(index); + if (patChars.indexOf(c) != -1) + { + buf.append('\''); buf.append(c); - } - } + buf.append('\''); + } + else + buf.append(c); + } + } private final String computePattern (DecimalFormatSymbols syms) - { - StringBuffer mainPattern = new StringBuffer (); - // We have to at least emit a zero for the minimum number of - // digits. Past that we need hash marks up to the grouping - // separator (and one beyond). - int total_digits = Math.max(minimumIntegerDigits, - groupingUsed ? groupingSize + 1: 0); - for (int i = 0; i < total_digits - minimumIntegerDigits; ++i) - mainPattern.append(syms.getDigit()); - for (int i = total_digits - minimumIntegerDigits; i < total_digits; ++i) - mainPattern.append(syms.getZeroDigit()); - // Inserting the gropuing operator afterwards is easier. - if (groupingUsed) - mainPattern.insert(mainPattern.length() - groupingSize, - syms.getGroupingSeparator()); - // See if we need decimal info. - if (minimumFractionDigits > 0 || maximumFractionDigits > 0 - || decimalSeparatorAlwaysShown) - mainPattern.append(syms.getDecimalSeparator()); - for (int i = 0; i < minimumFractionDigits; ++i) - mainPattern.append(syms.getZeroDigit()); - for (int i = minimumFractionDigits; i < maximumFractionDigits; ++i) - mainPattern.append(syms.getDigit()); - if (useExponentialNotation) - { - mainPattern.append(syms.getExponential()); - for (int i = 0; i < minExponentDigits; ++i) - mainPattern.append(syms.getZeroDigit()); - if (minExponentDigits == 0) - mainPattern.append(syms.getDigit()); - } - - String main = mainPattern.toString(); - String patChars = patternChars (syms); - mainPattern.setLength(0); - - quoteFix (mainPattern, positivePrefix, patChars); - mainPattern.append(main); - quoteFix (mainPattern, positiveSuffix, patChars); - - if (negativePrefix != null) - { - quoteFix (mainPattern, negativePrefix, patChars); - mainPattern.append(main); - quoteFix (mainPattern, negativeSuffix, patChars); - } - - return mainPattern.toString(); - } + { + StringBuffer mainPattern = new StringBuffer (); + // We have to at least emit a zero for the minimum number of + // digits. Past that we need hash marks up to the grouping + // separator (and one beyond). + int total_digits = Math.max(minimumIntegerDigits, + groupingUsed ? groupingSize + 1: 0); + for (int i = 0; i < total_digits - minimumIntegerDigits; ++i) + mainPattern.append(syms.getDigit()); + for (int i = total_digits - minimumIntegerDigits; i < total_digits; ++i) + mainPattern.append(syms.getZeroDigit()); + // Inserting the gropuing operator afterwards is easier. + if (groupingUsed) + mainPattern.insert(mainPattern.length() - groupingSize, + syms.getGroupingSeparator()); + // See if we need decimal info. + if (minimumFractionDigits > 0 || maximumFractionDigits > 0 + || decimalSeparatorAlwaysShown) + mainPattern.append(syms.getDecimalSeparator()); + for (int i = 0; i < minimumFractionDigits; ++i) + mainPattern.append(syms.getZeroDigit()); + for (int i = minimumFractionDigits; i < maximumFractionDigits; ++i) + mainPattern.append(syms.getDigit()); + if (useExponentialNotation) + { + mainPattern.append(syms.getExponential()); + for (int i = 0; i < minExponentDigits; ++i) + mainPattern.append(syms.getZeroDigit()); + if (minExponentDigits == 0) + mainPattern.append(syms.getDigit()); + } + + String main = mainPattern.toString(); + String patChars = patternChars (syms); + mainPattern.setLength(0); + + quoteFix (mainPattern, positivePrefix, patChars); + mainPattern.append(main); + quoteFix (mainPattern, positiveSuffix, patChars); + + if (negativePrefix != null) + { + quoteFix (mainPattern, negativePrefix, patChars); + mainPattern.append(main); + quoteFix (mainPattern, negativeSuffix, patChars); + } + + return mainPattern.toString(); + } public String toLocalizedPattern () - { - return computePattern (symbols); - } + { + return computePattern (symbols); + } public String toPattern () - { - return computePattern (nonLocalizedSymbols); - } + { + return computePattern (nonLocalizedSymbols); + } // These names are fixed by the serialization spec. private boolean decimalSeparatorAlwaysShown; diff --git a/libjava/java/text/DecimalFormatSymbols.java b/libjava/java/text/DecimalFormatSymbols.java index 0f404a5..bc5776a 100644 --- a/libjava/java/text/DecimalFormatSymbols.java +++ b/libjava/java/text/DecimalFormatSymbols.java @@ -1,12 +1,29 @@ -// DecimalFormatSymbols.java - Symbols used to format numbers. +/* DecimalFormatSymbols.java -- Format symbols used by DecimalFormat + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. -/* Copyright (C) 1999, 2000 Free Software Foundation +This file is part of GNU Classpath. - This file is part of libgcj. +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; @@ -18,302 +35,524 @@ import java.io.ObjectInputStream; import java.io.IOException; /** + * This class is a container for the symbols used by + * <code>DecimalFormat</code> to format numbers and currency. These are + * normally handled automatically, but an application can override + * values as desired using this class. + * * @author Tom Tromey <tromey@cygnus.com> + * @author Aaron M. Renn (arenn@urbanophile.com) * @date February 24, 1999 */ /* Written using "Java Class Libraries", 2nd edition, plus online * API docs for JDK 1.2 from http://www.javasoft.com. * Status: Believed complete and correct to 1.2. */ - public final class DecimalFormatSymbols implements Cloneable, Serializable { public Object clone () - { - return new DecimalFormatSymbols (this); - } - - private DecimalFormatSymbols (DecimalFormatSymbols orig) - { - this.currencySymbol = orig.currencySymbol; - this.decimalSeparator = orig.decimalSeparator; - this.digit = orig.digit; - this.exponential = orig.exponential; - this.groupingSeparator = orig.groupingSeparator; - this.infinity = orig.infinity; - this.intlCurrencySymbol = orig.intlCurrencySymbol; - this.monetarySeparator = orig.monetarySeparator; - this.minusSign = orig.minusSign; - this.NaN = orig.NaN; - this.patternSeparator = orig.patternSeparator; - this.percent = orig.percent; - this.perMill = orig.perMill; - this.zeroDigit = orig.zeroDigit; - } + { + try + { + return super.clone (); + } + catch(CloneNotSupportedException e) + { + return null; + } + } + /** + * This method initializes a new instance of + * <code>DecimalFormatSymbols</code> for the default locale. + */ public DecimalFormatSymbols () - { - this (Locale.getDefault()); - } + { + this (Locale.getDefault()); + } private final String safeGetString (ResourceBundle bundle, String name, String def) - { - if (bundle != null) - { - try - { - return bundle.getString(name); - } - catch (MissingResourceException x) - { - } - } - return def; - } + { + if (bundle != null) + { + try + { + return bundle.getString(name); + } + catch (MissingResourceException x) + { + } + } + return def; + } private final char safeGetChar (ResourceBundle bundle, String name, char def) - { - String r = null; - if (bundle != null) - { - try - { - r = bundle.getString(name); - } - catch (MissingResourceException x) - { - } - } - if (r == null || r.length() < 1) - return def; - return r.charAt(0); - } + { + String r = null; + if (bundle != null) + { + try + { + r = bundle.getString(name); + } + catch (MissingResourceException x) + { + } + } + if (r == null || r.length() < 1) + return def; + return r.charAt(0); + } + /** + * This method initializes a new instance of + * <code>DecimalFormatSymbols</code> for the specified locale. + * + * @param locale The local to load symbols for. + */ public DecimalFormatSymbols (Locale loc) - { - ResourceBundle res; - try - { - res = ResourceBundle.getBundle("gnu.gcj.text.LocaleData", loc); - } - catch (MissingResourceException x) - { - res = null; - } - currencySymbol = safeGetString (res, "currencySymbol", "$"); - decimalSeparator = safeGetChar (res, "decimalSeparator", '.'); - digit = safeGetChar (res, "digit", '#'); - exponential = safeGetChar (res, "exponential", 'E'); - groupingSeparator = safeGetChar (res, "groupingSeparator", ','); - infinity = safeGetString (res, "infinity", "\u221e"); - // FIXME: default? - intlCurrencySymbol = safeGetString (res, "intlCurrencySymbol", "$"); - try - { - monetarySeparator = safeGetChar (res, "monetarySeparator", '.'); - } - catch (MissingResourceException x) - { - monetarySeparator = decimalSeparator; - } - minusSign = safeGetChar (res, "minusSign", '-'); - NaN = safeGetString (res, "NaN", "\ufffd"); - patternSeparator = safeGetChar (res, "patternSeparator", ';'); - percent = safeGetChar (res, "percent", '%'); - perMill = safeGetChar (res, "perMill", '\u2030'); - zeroDigit = safeGetChar (res, "zeroDigit", '0'); - } + { + ResourceBundle res; + try + { + res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + loc); + } + catch (MissingResourceException x) + { + res = null; + } + currencySymbol = safeGetString (res, "currencySymbol", "$"); + decimalSeparator = safeGetChar (res, "decimalSeparator", '.'); + digit = safeGetChar (res, "digit", '#'); + exponential = safeGetChar (res, "exponential", 'E'); + groupingSeparator = safeGetChar (res, "groupingSeparator", ','); + infinity = safeGetString (res, "infinity", "\u221e"); + // FIXME: default? + intlCurrencySymbol = safeGetString (res, "intlCurrencySymbol", "$"); + try + { + monetarySeparator = safeGetChar (res, "monetarySeparator", '.'); + } + catch (MissingResourceException x) + { + monetarySeparator = decimalSeparator; + } + minusSign = safeGetChar (res, "minusSign", '-'); + NaN = safeGetString (res, "NaN", "\ufffd"); + patternSeparator = safeGetChar (res, "patternSeparator", ';'); + percent = safeGetChar (res, "percent", '%'); + perMill = safeGetChar (res, "perMill", '\u2030'); + zeroDigit = safeGetChar (res, "zeroDigit", '0'); + } + /** + * This method this this object for equality against the specified object. + * This will be true if and only if the following criteria are met with + * regard to the specified object: + * <p> + * <ul> + * <li>It is not <code>null</code>. + * <li>It is an instance of <code>DecimalFormatSymbols</code> + * <li>All of its symbols are identical to the symbols in this object. + * </ul> + * + * @return <code>true</code> if the specified object is equal to this + * object, <code>false</code> otherwise. + */ public boolean equals (Object obj) - { - if (! (obj instanceof DecimalFormatSymbols)) - return false; - DecimalFormatSymbols dfs = (DecimalFormatSymbols) obj; - return (currencySymbol.equals(dfs.currencySymbol) - && decimalSeparator == dfs.decimalSeparator - && digit == dfs.digit - && exponential == dfs.exponential - && groupingSeparator == dfs.groupingSeparator - && infinity.equals(dfs.infinity) - && intlCurrencySymbol.equals(dfs.intlCurrencySymbol) - && minusSign == dfs.minusSign - && monetarySeparator == dfs.monetarySeparator - && NaN.equals(dfs.NaN) - && patternSeparator == dfs.patternSeparator - && percent == dfs.percent - && perMill == dfs.perMill - && zeroDigit == dfs.zeroDigit); - } + { + if (! (obj instanceof DecimalFormatSymbols)) + return false; + DecimalFormatSymbols dfs = (DecimalFormatSymbols) obj; + return (currencySymbol.equals(dfs.currencySymbol) + && decimalSeparator == dfs.decimalSeparator + && digit == dfs.digit + && exponential == dfs.exponential + && groupingSeparator == dfs.groupingSeparator + && infinity.equals(dfs.infinity) + && intlCurrencySymbol.equals(dfs.intlCurrencySymbol) + && minusSign == dfs.minusSign + && monetarySeparator == dfs.monetarySeparator + && NaN.equals(dfs.NaN) + && patternSeparator == dfs.patternSeparator + && percent == dfs.percent + && perMill == dfs.perMill + && zeroDigit == dfs.zeroDigit); + } + /** + * This method returns the currency symbol in local format. For example, + * "$" for Canadian dollars. + * + * @return The currency symbol in local format. + */ public String getCurrencySymbol () - { - return currencySymbol; - } + { + return currencySymbol; + } + /** + * This method returns the character used as the decimal point. + * + * @return The character used as the decimal point. + */ public char getDecimalSeparator () - { - return decimalSeparator; - } + { + return decimalSeparator; + } + /** + * This method returns the character used to represent a digit in a + * format pattern string. + * + * @return The character used to represent a digit in a format + * pattern string. + */ public char getDigit () - { - return digit; - } + { + return digit; + } // This is our own extension. char getExponential () - { - return exponential; - } + { + return exponential; + } + /** + * This method sets the character used to separate groups of digits. For + * example, the United States uses a comma (,) to separate thousands in + * a number. + * + * @return The character used to separate groups of digits. + */ public char getGroupingSeparator () - { - return groupingSeparator; - } + { + return groupingSeparator; + } + /** + * This method returns the character used to represent infinity. + * + * @return The character used to represent infinity. + */ public String getInfinity () - { - return infinity; - } + { + return infinity; + } + /** + * This method returns the currency symbol in international format. For + * example, "C$" for Canadian dollars. + * + * @return The currency symbol in international format. + */ public String getInternationalCurrencySymbol () - { - return intlCurrencySymbol; - } + { + return intlCurrencySymbol; + } + /** + * This method returns the character used to represent the minus sign. + * + * @return The character used to represent the minus sign. + */ public char getMinusSign () - { - return minusSign; - } + { + return minusSign; + } + /** + * This method returns the character used to represent the decimal + * point for currency values. + * + * @return The decimal point character used in currency values. + */ public char getMonetaryDecimalSeparator () - { - return monetarySeparator; - } + { + return monetarySeparator; + } + /** + * This method returns the string used to represent the NaN (not a number) + * value. + * + * @return The string used to represent NaN + */ public String getNaN () - { - return NaN; - } + { + return NaN; + } + /** + * This method returns the character used to separate positive and negative + * subpatterns in a format pattern. + * + * @return The character used to separate positive and negative subpatterns + * in a format pattern. + */ public char getPatternSeparator () - { - return patternSeparator; - } + { + return patternSeparator; + } + /** + * This method returns the character used as the percent sign. + * + * @return The character used as the percent sign. + */ public char getPercent () - { - return percent; - } + { + return percent; + } + /** + * This method returns the character used as the per mille character. + * + * @return The per mille character. + */ public char getPerMill () - { - return perMill; - } + { + return perMill; + } + /** + * This method returns the character used to represent the digit zero. + * + * @return The character used to represent the digit zero. + */ public char getZeroDigit () - { - return zeroDigit; - } + { + return zeroDigit; + } + /** + * This method returns a hash value for this object. + * + * @return A hash value for this object. + */ public int hashCode () - { - // Compute based on zero digit, grouping separator, and decimal - // separator -- JCL book. This probably isn't a very good hash - // code. - return zeroDigit << 16 + groupingSeparator << 8 + decimalSeparator; - } + { + // Compute based on zero digit, grouping separator, and decimal + // separator -- JCL book. This probably isn't a very good hash + // code. + return zeroDigit << 16 + groupingSeparator << 8 + decimalSeparator; + } + /** + * This method sets the currency symbol to the specified value. + * + * @param currencySymbol The new currency symbol + */ public void setCurrencySymbol (String currency) - { - currencySymbol = currency; - } + { + currencySymbol = currency; + } + /** + * This method sets the decimal point character to the specified value. + * + * @param decimalSeparator The new decimal point character + */ public void setDecimalSeparator (char decimalSep) - { - decimalSeparator = decimalSep; - } + { + decimalSeparator = decimalSep; + } + /** + * This method sets the character used to represents a digit in a format + * string to the specified value. + * + * @param digit The character used to represent a digit in a format pattern. + */ public void setDigit (char digit) - { - this.digit = digit; - } + { + this.digit = digit; + } // This is our own extension. void setExponential (char exp) - { - exponential = exp; - } + { + exponential = exp; + } + /** + * This method sets the character used to separate groups of digits. + * + * @param groupingSeparator The character used to separate groups of digits. + */ public void setGroupingSeparator (char groupSep) - { - groupingSeparator = groupSep; - } + { + groupingSeparator = groupSep; + } + /** + * This method sets the string used to represents infinity. + * + * @param infinity The string used to represent infinity. + */ public void setInfinity (String infinity) - { - this.infinity = infinity; - } + { + this.infinity = infinity; + } + /** + * This method sets the international currency symbols to the + * specified value. + * + * @param intlCurrencySymbol The new international currency symbol. + */ public void setInternationalCurrencySymbol (String currency) - { - intlCurrencySymbol = currency; - } + { + intlCurrencySymbol = currency; + } + /** + * This method sets the character used to represent the minus sign. + * + * @param minusSign The character used to represent the minus sign. + */ public void setMinusSign (char minusSign) - { - this.minusSign = minusSign; - } + { + this.minusSign = minusSign; + } + /** + * This method sets the character used for the decimal point in currency + * values. + * + * @param monetarySeparator The decimal point character used in + * currency values. + */ public void setMonetaryDecimalSeparator (char decimalSep) - { - monetarySeparator = decimalSep; - } + { + monetarySeparator = decimalSep; + } + /** + * This method sets the string used to represent the NaN (not a + * number) value. + * + * @param NaN The string used to represent NaN + */ public void setNaN (String nan) - { - NaN = nan; - } + { + NaN = nan; + } + /** + * This method sets the character used to separate positive and negative + * subpatterns in a format pattern. + * + * @param patternSeparator The character used to separate positive and + * negative subpatterns in a format pattern. + */ public void setPatternSeparator (char patternSep) - { - patternSeparator = patternSep; - } + { + patternSeparator = patternSep; + } + /** + * This method sets the character used as the percent sign. + * + * @param percent The character used as the percent sign. + */ public void setPercent (char percent) - { - this.percent = percent; - } + { + this.percent = percent; + } + /** + * This method sets the character used as the per mille character. + * + * @param perMill The per mille character. + */ public void setPerMill (char perMill) - { - this.perMill = perMill; - } + { + this.perMill = perMill; + } + /** + * This method sets the charcter used to represen the digit zero. + * + * @param zeroDigit The character used to represent the digit zero. + */ public void setZeroDigit (char zeroDigit) - { - this.zeroDigit = zeroDigit; - } + { + this.zeroDigit = zeroDigit; + } - // The names of the instance variables are fixed by the - // serialization spec. + /** + * @serial A string used for the local currency + */ private String currencySymbol; + /** + * @serial The <code>char</code> used to separate decimals in a number. + */ private char decimalSeparator; + /** + * @serial This is the <code>char</code> used to represent a digit in + * a format specification. + */ private char digit; + /** + * @serial This is the <code>char</code> used to represent the exponent + * separator in exponential notation. + */ private char exponential; + /** + * @serial This separates groups of thousands in numbers. + */ private char groupingSeparator; + /** + * @serial This string represents infinity. + */ private String infinity; + /** + * @serial This string represents the local currency in an international + * context, eg, "C$" for Canadian dollars. + */ private String intlCurrencySymbol; + /** + * @serial This is the character used to represent the minus sign. + */ private char minusSign; + /** + * @serial This character is used to separate decimals when formatting + * currency values. + */ private char monetarySeparator; + /** + * @serial This string is used the represent the Java NaN value for + * "not a number". + */ private String NaN; + /** + * @serial This is the character used to separate positive and negative + * subpatterns in a format pattern. + */ private char patternSeparator; + /** + * @serial This is the percent symbols + */ private char percent; + /** + * @serial This character is used for the mille percent sign. + */ private char perMill; + /** + * @serial This value represents the type of object being de-serialized. + * 0 indicates a pre-Java 1.1.6 version, 1 indicates 1.1.6 or later. + */ private int serialVersionOnStream = 1; + /** + * @serial This is the character used to represent 0. + */ private char zeroDigit; + private static final long serialVersionUID = 5772796243397350300L; private void readObject(ObjectInputStream stream) diff --git a/libjava/java/text/FieldPosition.java b/libjava/java/text/FieldPosition.java index c149e0e..57ede5b 100644 --- a/libjava/java/text/FieldPosition.java +++ b/libjava/java/text/FieldPosition.java @@ -1,65 +1,155 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation +/* FieldPosition.java -- Keeps track of field positions while formatting + Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; /** + * This class is used by the java.text formatting classes to track + * field positions. A field position is defined by an identifier value + * and begin and end index positions. The formatting classes in java.text + * typically define constant values for the field identifiers. + * + * @author Aaron M. Renn (arenn@urbanophile.com) * @author Per Bothner <bothner@cygnus.com> - * @date October 25, 1998. - */ -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct. - * Includes JDK 1.2 methods. */ - public class FieldPosition { - int field; - int beginIndex; - int endIndex; + /** + * This is the field identifier value. + */ + private int field_id; + + /** + * This is the beginning index of the field. + */ + private int begin; + + /** + * This is the ending index of the field. + */ + private int end; - public FieldPosition (int field) + /** + * This method initializes a new instance of <code>FieldPosition</code> to + * have the specified field id. + * + * @param field_id The field identifier value. + */ + public FieldPosition (int field_id) { - this.field = field; + this.field_id = field_id; } + /** + * This method returns the field identifier value for this object. + * + * @return The field identifier. + */ public int getField () { - return field; + return field_id; } + /** + * This method returns the beginning index for this field. + * + * @return The beginning index. + */ public int getBeginIndex () { - return beginIndex; + return begin; } - public int getEndIndex () + /** + * This method sets the beginning index of this field to the specified value. + * + * @param begin The new beginning index. + */ + public void setBeginIndex (int begin) { - return endIndex; + this.begin = begin; } - public void setBeginIndex (int index) + /** + * This method returns the ending index for the field. + * + * @return The ending index. + */ + public int getEndIndex () { - beginIndex = index; + return end; } - public void setEndIndex (int index) + /** + * This method sets the ending index of this field to the specified value. + * + * @param end The new ending index. + */ + public void setEndIndex (int end) { - endIndex = index; + this.end = end; } + /** + * This method tests this object for equality against the specified object. + * The objects will be considered equal if and only if: + * <p> + * <ul> + * <li>The specified object is not <code>null</code>. + * <li>The specified object is an instance of <code>FieldPosition</code>. + * <li>The specified object has the same field identifier and beginning + * and ending index as this object. + * </ul> + * + * @param obj The object to test for equality to this object. + * + * @return <code>true</code> if the specified object is equal to + * this object, <code>false</code> otherwise. + */ public boolean equals (Object obj) { if (! (obj instanceof FieldPosition)) return false; - FieldPosition other = (FieldPosition) obj; - return (field == other.field - && beginIndex == other.beginIndex && endIndex == other.endIndex); + + FieldPosition fp = (FieldPosition) obj; + return (field_id == fp.field_id + && begin == fp.begin + && end == fp.end); + } + + /** + * This method returns a <code>String</code> representation of this + * object. + * + * @return A <code>String</code> representation of this object. + */ + public String toString () + { + return (getClass ().getName () + "[field=" + getField () + ",beginIndex=" + + getBeginIndex () + ",endIndex=" + getEndIndex () + "]"); } } diff --git a/libjava/java/text/Format.java b/libjava/java/text/Format.java index 8360415..3aa68c8 100644 --- a/libjava/java/text/Format.java +++ b/libjava/java/text/Format.java @@ -1,44 +1,111 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Format.java -- Abstract superclass for formatting/parsing strings. + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; +import java.io.Serializable; + /** + * This class is the abstract superclass of classes that format and parse + * data to/from <code>Strings</code>. It is guaranteed that any + * <code>String</code> produced by a concrete subclass of <code>Format</code> + * will be parseable by that same subclass. + * <p> + * In addition to implementing the abstract methods in this class, subclasses + * should provide static factory methods of the form + * <code>getInstance()</code> and <code>getInstance(Locale)</code> if the + * subclass loads different formatting/parsing schemes based on locale. + * These subclasses should also implement a static method called + * <code>getAvailableLocales()</code> which returns an array of + * available locales in the current runtime environment. + * + * @author Aaron M. Renn (arenn@urbanophile.com) * @author Per Bothner <bothner@cygnus.com> - * @date October 25, 1998. - */ -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct. */ - -public abstract class Format implements java.io.Serializable, Cloneable +public abstract class Format implements Serializable, Cloneable { + /** + * This method initializes a new instance of <code>Format</code>. + * It performs no actions, but acts as a default constructor for + * subclasses. + */ public Format () { } - public abstract StringBuffer format (Object obj, - StringBuffer sbuf, FieldPosition pos); - - public final String format (Object obj) + /** + * This method formats an <code>Object</code> into a <code>String</code>. + * + * @param obj The <code>Object</code> to format. + * + * @return The formatted <code>String</code>. + * + * @exception IllegalArgumentException If the <code>Object</code> + * cannot be formatted. + */ + public final String format(Object obj) throws IllegalArgumentException { - StringBuffer sbuf = new StringBuffer(); - format(obj, sbuf, new FieldPosition(0)); - return sbuf.toString(); + StringBuffer sb = new StringBuffer (); + format (obj, sb, new FieldPosition (0)); + return sb.toString (); } - public abstract Object parseObject (String source, ParsePosition pos); + /** + * This method formats an <code>Object</code> into a <code>String</code> and + * appends the <code>String</code> to a <code>StringBuffer</code>. + * + * @param obj The <code>Object</code> to format. + * @param sb The <code>StringBuffer</code> to append to. + * @param pos The desired <code>FieldPosition</code>, which is also + * updated by this call. + * + * @return The updated <code>StringBuffer</code>. + * + * @exception IllegalArgumentException If the <code>Object</code> + * cannot be formatted. + */ + public abstract StringBuffer format (Object obj, StringBuffer sb, + FieldPosition pos) + throws IllegalArgumentException; - public Object parseObject (String source) throws ParseException + /** + * This method parses a <code>String</code> and converts the parsed + * contents into an <code>Object</code>. + * + * @param str The <code>String to parse. + * + * @return The resulting <code>Object</code>. + * + * @exception ParseException If the <code>String</code> cannot be parsed. + */ + public Object parseObject (String str) throws ParseException { ParsePosition pos = new ParsePosition(0); - Object result = parseObject (source, pos); + Object result = parseObject (str, pos); if (result == null) { int index = pos.getErrorIndex(); @@ -49,8 +116,33 @@ public abstract class Format implements java.io.Serializable, Cloneable return result; } + /** + * This method parses a <code>String</code> and converts the parsed + * contents into an <code>Object</code>. + * + * @param str The <code>String</code> to parse. + * @param pos The starting parse index on input, the ending parse + * index on output. + * + * @return The parsed <code>Object</code>, or <code>null</code> in + * case of error. + */ + public abstract Object parseObject (String str, ParsePosition pos); + + /** + * Creates a copy of this object. + * + * @return The copied <code>Object</code>. + */ public Object clone () { - return super.clone (); + try + { + return super.clone (); + } + catch (CloneNotSupportedException e) + { + return null; + } } } diff --git a/libjava/java/text/MessageFormat.java b/libjava/java/text/MessageFormat.java index bb2a4c3..ffe34a6 100644 --- a/libjava/java/text/MessageFormat.java +++ b/libjava/java/text/MessageFormat.java @@ -1,12 +1,29 @@ -// MessageFormat.java - Localized message formatting. +/* MessageFormat.java - Localized message formatting. + Copyright (C) 1999, 2001 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -/* Copyright (C) 1999, 2001 Free Software Foundation - - This file is part of libgcj. - -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; diff --git a/libjava/java/text/NumberFormat.java b/libjava/java/text/NumberFormat.java index 80d5c13..739ca31 100644 --- a/libjava/java/text/NumberFormat.java +++ b/libjava/java/text/NumberFormat.java @@ -1,10 +1,29 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* NumberFormat.java -- Formats and parses numbers + Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; @@ -16,50 +35,108 @@ import java.io.ObjectOutputStream; import java.io.IOException; /** + * This is the abstract superclass of all classes which format and + * parse numeric values such as decimal numbers, integers, currency values, + * and percentages. These classes perform their parsing and formatting + * in a locale specific manner, accounting for such items as differing + * currency symbols and thousands separators. + * <p> + * To create an instance of a concrete subclass of <code>NumberFormat</code>, + * do not call a class constructor directly. Instead, use one of the + * static factory methods in this class such as + * <code>getCurrencyInstance</code>. + * * @author Tom Tromey <tromey@cygnus.com> + * @author Aaron M. Renn (arenn@urbanophile.com) * @date March 4, 1999 */ /* Written using "Java Class Libraries", 2nd edition, plus online * API docs for JDK 1.2 from http://www.javasoft.com. * Status: Believed complete and correct to 1.2, except getAvailableLocales. */ - public abstract class NumberFormat extends Format implements Cloneable { + /** + * This is a constant used to create a <code>FieldPosition</code> object + * that will return the integer portion of a formatted number. + */ public static final int INTEGER_FIELD = 0; + + /** + * This is a constant used to create a <code>FieldPosition</code> object + * that will return the fractional portion of a formatted number. + */ public static final int FRACTION_FIELD = 1; + /** + * This method is a specialization of the format method that performs + * a simple formatting of the specified <code>long</code> number. + * + * @param number The <code>long</code> to format. + * + * @return The formatted number + */ public final String format (long number) - { - StringBuffer sbuf = new StringBuffer(50); - format (number, sbuf, null); - return sbuf.toString(); - } + { + StringBuffer sbuf = new StringBuffer(50); + format (number, sbuf, null); + return sbuf.toString(); + } public final StringBuffer format (Object obj, StringBuffer sbuf, FieldPosition pos) - { - if (obj instanceof Number) - return format(((Number) obj).doubleValue(), sbuf, pos); - else - throw new IllegalArgumentException - ("Cannot format given Object as a Number"); - } + { + if (obj instanceof Number) + return format(((Number) obj).doubleValue(), sbuf, pos); + else + throw new IllegalArgumentException + ("Cannot format given Object as a Number"); + } + /** + * This method formats the specified <code>double</code> and appends it to + * a <code>StringBuffer</code>. + * + * @param number The <code>double</code> to format. + * @param sb The <code>StringBuffer</code> to append the formatted number to. + * @param pos The desired <code>FieldPosition</code>. + * + * @return The <code>StringBuffer</code> with the appended number. + */ public abstract StringBuffer format (double number, StringBuffer sbuf, FieldPosition pos); + /** + * This method formats the specified <code>long</code> and appends it to + * a <code>StringBuffer</code>. + * + * @param number The <code>long</code> to format. + * @param sb The <code>StringBuffer</code> to append the formatted number to. + * @param pos The desired <code>FieldPosition</code>. + * + * @return The <code>StringBuffer</code> with the appended number. + */ public abstract StringBuffer format (long number, StringBuffer sbuf, FieldPosition pos); - public Object clone () - { - // We know the superclass just uses Object's generic cloner. - // Why not just inherit? Because the online docs specify that - // this method exists for this class. - return super.clone (); - } - + /** + * This method tests the specified object for equality against this object. + * This will be <code>true</code> if the following conditions are met: + * <p> + * <ul> + * <li>The specified object is not <code>null</code>. + * <li>The specified object is an instance of <code>NumberFormat</code>. + * </ul> + * <p> + * Since this method does not test much, it is highly advised that + * concrete subclasses override this method. + * + * @param obj The <code>Object</code> to test against equality with + * this object. + * + * @return <code>true</code> if the specified object is equal to + * this object, <code>false</code> otherwise. + */ public boolean equals (Object obj) { if (! (obj instanceof NumberFormat)) @@ -73,182 +150,406 @@ public abstract class NumberFormat extends Format implements Cloneable && parseIntegerOnly == nf.parseIntegerOnly); } + /** + * This method returns a list of locales for which concrete instances + * of <code>NumberFormat</code> subclasses may be created. + * + * @return The list of available locales. + */ public static Locale[] getAvailableLocales () - { - // FIXME. - return null; - } + { + Locale[] list = new Locale[1]; + list[0] = Locale.US; + return list; + } private static final NumberFormat computeInstance (Locale loc, String resource, String def) - { - ResourceBundle res; - try - { - res = ResourceBundle.getBundle("gnu.gcj.text.LocaleData", loc); - } - catch (MissingResourceException x) - { - res = null; - } - String fmt; - try - { - fmt = res == null ? def : res.getString(resource); - } - catch (MissingResourceException x) - { - fmt = def; - } - DecimalFormatSymbols dfs = new DecimalFormatSymbols (loc); - return new DecimalFormat (fmt, dfs); - } + { + ResourceBundle res; + try + { + res = ResourceBundle.getBundle("gnu.java.locale.LocaleInformation", + loc); + } + catch (MissingResourceException x) + { + res = null; + } + String fmt; + try + { + fmt = res == null ? def : res.getString(resource); + } + catch (MissingResourceException x) + { + fmt = def; + } + DecimalFormatSymbols dfs = new DecimalFormatSymbols (loc); + return new DecimalFormat (fmt, dfs); + } + /** + * This method returns an instance of <code>NumberFormat</code> suitable + * for formatting and parsing currency values in the default locale. + * + * @return An instance of <code>NumberFormat</code> for handling currencies. + */ public static final NumberFormat getCurrencyInstance () - { - return getCurrencyInstance (Locale.getDefault()); - } + { + return getCurrencyInstance (Locale.getDefault()); + } + /** + * This method returns an instance of <code>NumberFormat</code> suitable + * for formatting and parsing currency values in the specified locale. + * + * @return An instance of <code>NumberFormat</code> for handling currencies. + */ public static NumberFormat getCurrencyInstance (Locale loc) - { - return computeInstance (loc, "currencyFormat", "$#,##0.00;($#,##0.00)"); - } + { + return computeInstance (loc, "currencyFormat", "$#,##0.00;($#,##0.00)"); + } + /** + * This method returns a default instance for the default locale. This + * will be a concrete subclass of <code>NumberFormat</code>, but the + * actual class returned is dependent on the locale. + * + * @return An instance of the default <code>NumberFormat</code> class. + */ public static final NumberFormat getInstance () - { - return getInstance (Locale.getDefault()); - } + { + return getInstance (Locale.getDefault()); + } + /** + * This method returns a default instance for the specified locale. This + * will be a concrete subclass of <code>NumberFormat</code>, but the + * actual class returned is dependent on the locale. + * + * @param locale The desired locale. + * + * @return An instance of the default <code>NumberFormat</code> class. + */ public static NumberFormat getInstance (Locale loc) - { - // For now always return a number instance. - return getNumberInstance (loc); - } + { + // For now always return a number instance. + return getNumberInstance (loc); + } + /** + * This method returns the maximum number of digits allowed in the fraction + * portion of a number. + * + * @return The maximum number of digits allowed in the fraction + * portion of a number. + */ public int getMaximumFractionDigits () - { - return maximumFractionDigits; - } + { + return maximumFractionDigits; + } + /** + * This method returns the maximum number of digits allowed in the integer + * portion of a number. + * + * @return The maximum number of digits allowed in the integer + * portion of a number. + */ public int getMaximumIntegerDigits () - { - return maximumIntegerDigits; - } + { + return maximumIntegerDigits; + } + /** + * This method returns the minimum number of digits allowed in the fraction + * portion of a number. + * + * @return The minimum number of digits allowed in the fraction + * portion of a number. + */ public int getMinimumFractionDigits () - { - return minimumFractionDigits; - } + { + return minimumFractionDigits; + } + /** + * This method returns the minimum number of digits allowed in the integer + * portion of a number. + * + * @return The minimum number of digits allowed in the integer + * portion of a number. + */ public int getMinimumIntegerDigits () - { - return minimumIntegerDigits; - } + { + return minimumIntegerDigits; + } + /** + * This method returns a default instance for the specified locale. This + * will be a concrete subclass of <code>NumberFormat</code>, but the + * actual class returned is dependent on the locale. + * + * @param locale The desired locale. + * + * @return An instance of the default <code>NumberFormat</code> class. + */ public static final NumberFormat getNumberInstance () - { - return getNumberInstance (Locale.getDefault()); - } + { + return getNumberInstance (Locale.getDefault()); + } + /** + * This method returns a general purpose number formatting and parsing + * class for the default locale. This will be a concrete subclass of + * <code>NumberFormat</code>, but the actual class returned is dependent + * on the locale. + * + * @return An instance of a generic number formatter for the default locale. + */ public static NumberFormat getNumberInstance (Locale loc) - { - return computeInstance (loc, "numberFormat", "#,##0.###"); - } + { + return computeInstance (loc, "numberFormat", "#,##0.###"); + } + /** + * This method returns an instance of <code>NumberFormat</code> suitable + * for formatting and parsing percentage values in the default locale. + * + * @return An instance of <code>NumberFormat</code> for handling percentages. + */ public static final NumberFormat getPercentInstance () - { - return getPercentInstance (Locale.getDefault()); - } + { + return getPercentInstance (Locale.getDefault()); + } + /** + * This method returns an instance of <code>NumberFormat</code> suitable + * for formatting and parsing percentage values in the specified locale. + * + * @param locale The desired locale. + * + * @return An instance of <code>NumberFormat</code> for handling percentages. + */ public static NumberFormat getPercentInstance (Locale loc) - { - return computeInstance (loc, "percentFormat", "#,##0%"); - } + { + return computeInstance (loc, "percentFormat", "#,##0%"); + } + /** + * This method returns a hash value for this object. + * + * @return The hash code. + */ public int hashCode () - { - int hash = super.hashCode(); - hash ^= (maximumFractionDigits + maximumIntegerDigits - + minimumFractionDigits + minimumIntegerDigits); - if (groupingUsed) - hash ^= 0xf0f0; - if (parseIntegerOnly) - hash ^= 0x0f0f; - return hash; - } + { + int hash = super.hashCode(); + hash ^= (maximumFractionDigits + maximumIntegerDigits + + minimumFractionDigits + minimumIntegerDigits); + if (groupingUsed) + hash ^= 0xf0f0; + if (parseIntegerOnly) + hash ^= 0x0f0f; + return hash; + } + /** + * This method tests whether or not grouping is in use. Grouping is + * a method of marking separations in numbers, such as thousand separators + * in the US English locale. The grouping positions and symbols are all + * locale specific. As an example, with grouping disabled, the number one + * million would appear as "1000000". With grouping enabled, this number + * might appear as "1,000,000". (Both of these assume the US English + * locale). + * + * @return <code>true</code> if grouping is enabled, + * <code>false</code> otherwise. + */ public boolean isGroupingUsed () - { - return groupingUsed; - } + { + return groupingUsed; + } + /** + * This method tests whether or not only integer values should be parsed. + * If this class is parsing only integers, parsing stops at the decimal + * point. + * + * @return <code>true</code> if only integers are parsed, + * <code>false</code> otherwise. + */ public boolean isParseIntegerOnly () - { - return parseIntegerOnly; - } + { + return parseIntegerOnly; + } + /** + * This is a default constructor for use by subclasses. + */ public NumberFormat () - { - } + { + } + /** + * This method parses the specified string into a <code>Number</code>. This + * will be a <code>Long</code> if possible, otherwise it will be a + * <code>Double</code>. If no number can be parsed, no exception is + * thrown. Instead, the parse position remains at its initial index. + * + * @param str The string to parse. + * @param pp The desired <code>ParsePosition</code>. + * + * @return The parsed <code>Number</code> + */ public abstract Number parse (String sourceStr, ParsePosition pos); + /** + * This method parses the specified string into a <code>Number</code>. This + * will be a <code>Long</code> if possible, otherwise it will be a + * <code>Double</code>. If no number can be parsed, an exception will be + * thrown. + * + * @param str The string to parse. + * + * @return The parsed <code>Number</code> + * + * @exception ParseException If no number can be parsed. + */ public Number parse (String sourceStr) throws ParseException - { - ParsePosition pp = new ParsePosition (0); - Number r = parse (sourceStr, pp); - if (r == null) - { - int index = pp.getErrorIndex(); - if (index < 0) - index = pp.getIndex(); - throw new ParseException ("couldn't parse number", index); - } - return r; - } + { + ParsePosition pp = new ParsePosition (0); + Number r = parse (sourceStr, pp); + if (r == null) + { + int index = pp.getErrorIndex(); + if (index < 0) + index = pp.getIndex(); + throw new ParseException ("couldn't parse number", index); + } + return r; + } + /** + * This method parses the specified string into an <code>Object</code>. This + * will be a <code>Long</code> if possible, otherwise it will be a + * <code>Double</code>. If no number can be parsed, no exception is + * thrown. Instead, the parse position remains at its initial index. + * + * @param str The string to parse. + * @param pp The desired <code>ParsePosition</code>. + * + * @return The parsed <code>Object</code> + */ public final Object parseObject (String sourceStr, ParsePosition pos) - { - return parse (sourceStr, pos); - } + { + return parse (sourceStr, pos); + } + /** + * This method sets the grouping behavior of this formatter. Grouping is + * a method of marking separations in numbers, such as thousand separators + * in the US English locale. The grouping positions and symbols are all + * locale specific. As an example, with grouping disabled, the number one + * million would appear as "1000000". With grouping enabled, this number + * might appear as "1,000,000". (Both of these assume the US English + * locale). + * + * @param groupingUsed <code>true</code> to enable grouping, + * <code>false</code> to disable it. + */ public void setGroupingUsed (boolean newValue) - { - groupingUsed = newValue; - } + { + groupingUsed = newValue; + } + /** + * This method sets the maximum number of digits allowed in the fraction + * portion of a number to the specified value. If this is less than the + * current minimum allowed digits, the minimum allowed digits value will + * be lowered to be equal to the new maximum allowed digits value. + * + * @param maximumFractionDigits The new maximum fraction digits value. + */ public void setMaximumFractionDigits (int newValue) - { - maximumFractionDigits = newValue; - } + { + maximumFractionDigits = newValue; + if (getMinimumFractionDigits () > maximumFractionDigits) + setMinimumFractionDigits (maximumFractionDigits); + } + /** + * This method sets the maximum number of digits allowed in the integer + * portion of a number to the specified value. If this is less than the + * current minimum allowed digits, the minimum allowed digits value will + * be lowered to be equal to the new maximum allowed digits value. + * + * @param maximumIntegerDigits The new maximum integer digits value. + */ public void setMaximumIntegerDigits (int newValue) - { - maximumIntegerDigits = newValue; - } + { + maximumIntegerDigits = newValue; + if (getMinimumIntegerDigits () > maximumIntegerDigits) + setMinimumIntegerDigits (maximumIntegerDigits); + } + /** + * This method sets the minimum number of digits allowed in the fraction + * portion of a number to the specified value. If this is greater than the + * current maximum allowed digits, the maximum allowed digits value will + * be raised to be equal to the new minimum allowed digits value. + * + * @param minimumFractionDigits The new minimum fraction digits value. + */ public void setMinimumFractionDigits (int newValue) - { - minimumFractionDigits = newValue; - } + { + minimumFractionDigits = newValue; + if (getMaximumFractionDigits () < minimumFractionDigits) + setMaximumFractionDigits (minimumFractionDigits); + } + /** + * This method sets the minimum number of digits allowed in the integer + * portion of a number to the specified value. If this is greater than the + * current maximum allowed digits, the maximum allowed digits value will + * be raised to be equal to the new minimum allowed digits value. + * + * @param minimumIntegerDigits The new minimum integer digits value. + */ public void setMinimumIntegerDigits (int newValue) - { - minimumIntegerDigits = newValue; - } + { + minimumIntegerDigits = newValue; + if (getMaximumIntegerDigits () < minimumIntegerDigits) + setMaximumIntegerDigits (minimumIntegerDigits); + } + /** + * This method sets the parsing behavior of this object to parse only + * integers or not. + * + * @param parseIntegerOnly <code>true</code> to parse only integers, + * <code>false</code> otherwise. + */ public void setParseIntegerOnly (boolean value) - { - parseIntegerOnly = value; - } + { + parseIntegerOnly = value; + } + /** + * This method is a specialization of the format method that performs + * a simple formatting of the specified <code>double</code> number. + * + * @param number The <code>double</code> to format. + * + * @return The formatted number + */ public final String format (double number) - { - StringBuffer sbuf = new StringBuffer(50); - format (number, sbuf, null); - return sbuf.toString(); - } + { + StringBuffer sbuf = new StringBuffer(50); + format (number, sbuf, null); + return sbuf.toString(); + } // These field names are fixed by the serialization spec. boolean groupingUsed; diff --git a/libjava/java/text/ParsePosition.java b/libjava/java/text/ParsePosition.java index 55f7f8b..765ac4d 100644 --- a/libjava/java/text/ParsePosition.java +++ b/libjava/java/text/ParsePosition.java @@ -1,59 +1,140 @@ -/* Copyright (C) 1998, 1999 Free Software Foundation +/* ParsePosition.java -- Keep track of position while parsing. + Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. - This file is part of libgcj. +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; /** + * This class is used to keep track of the current position during parsing + * operations. + * + * @author Aaron M. Renn (arenn@urbanophile.com) * @author Per Bothner <bothner@cygnus.com> - * @date October 25, 1998. */ -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct. - * Includes JDK 1.2 methods. - */ - public class ParsePosition { - int index; - int errorIndex; + /** + * This is the index of the current parse position. + */ + private int index; + /** + * This is the index of the position where an error occurred during parsing. + */ + private int error_index; + + /** + * This method initializes a new instance of <code>ParsePosition</code> to + * have the specified initial index value. + * + * @param index The initial parsing index. + */ public ParsePosition (int index) { this.index = index; - errorIndex = -1; + error_index = -1; } + /** + * This method returns the current parsing index. + * + * @return The current parsing index + */ public int getIndex () { return index; } + /** + * This method sets the current parsing index to the specified value. + * + * @param index The new parsing index. + */ public void setIndex (int index) { this.index = index; } + /** + * This method returns the error index value. This value defaults to -1 + * unless explicitly set to another value. + * + * @return The error index. + */ public int getErrorIndex () { - return errorIndex; + return error_index; } - public void setErrorIndex (int ei) + /** + * This method sets the error index to the specified value. + * + * @param error_index The new error index + */ + public void setErrorIndex (int error_index) { - errorIndex = ei; + this.error_index = error_index; } + /** + * This method tests the specified object for equality with this + * object. The two objects will be considered equal if and only if + * all of the following conditions are met. + * <p> + * <ul> + * <li>The specified object is not <code>null</code>. + * <li>The specified object is an instance of <code>ParsePosition</code>. + * <li>The specified object has the same index and error index as + * this object. + * </ul> + * + * @param obj The <code>Object</code> to test for equality against + * this object. + * + * @return <code>true</code> if the specified object is equal to + * this object, <code>false</code> otherwise. + */ public boolean equals (Object obj) { - if (obj != null || ! (obj instanceof ParsePosition)) + if (! (obj instanceof ParsePosition)) return false; + ParsePosition other = (ParsePosition) obj; - return index == other.index && errorIndex == other.errorIndex; + return index == other.index && error_index == other.error_index; + } + + /** + * This method returns a <code>String</code> representation of this + * object. + * + * @return A <code>String</code> that represents this object. + */ + public String toString () + { + return (getClass ().getName () + "[index=" + getIndex () + + ",errorIndex=" + getErrorIndex () + "]"); } } diff --git a/libjava/java/text/SimpleDateFormat.java b/libjava/java/text/SimpleDateFormat.java index 8d914fb..6366082 100644 --- a/libjava/java/text/SimpleDateFormat.java +++ b/libjava/java/text/SimpleDateFormat.java @@ -207,6 +207,7 @@ public class SimpleDateFormat extends DateFormat { super(); calendar = new GregorianCalendar(); + computeCenturyStart (); tokens = new Vector(); this.formatData = formatData; compileFormat(pattern); diff --git a/libjava/java/text/StringCharacterIterator.java b/libjava/java/text/StringCharacterIterator.java index 487b09c..64af260 100644 --- a/libjava/java/text/StringCharacterIterator.java +++ b/libjava/java/text/StringCharacterIterator.java @@ -1,149 +1,345 @@ -// StringCharacterIterator.java - Iterate over string of Unicode characters. +/* StringCharacterIterator.java -- Iterate over a character range in a string + Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc. -/* Copyright (C) 1999, 2000 Free Software Foundation +This file is part of GNU Classpath. - This file is part of libgcj. +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ -This software is copyrighted work licensed under the terms of the -Libgcj License. Please consult the file "LIBGCJ_LICENSE" for -details. */ package java.text; /** + * This class iterates over a range of characters in a <code>String</code>. + * For a given range of text, a beginning and ending index, + * as well as a current index are defined. These values can be queried + * by the methods in this interface. Additionally, various methods allow + * the index to be set. + * + * @author Aaron M. Renn (arenn@urbanophile.com) * @author Tom Tromey <tromey@cygnus.com> - * @date February 22, 1999 - */ -/* Written using "Java Class Libraries", 2nd edition, plus online - * API docs for JDK 1.2 beta from http://www.javasoft.com. - * Status: Believed complete and correct to 1.1. */ - public final class StringCharacterIterator implements CharacterIterator { - public Object clone () + /** + * This is the string to iterate over + */ + private String text; + + /** + * This is the value of the start position of the text range. + */ + private int begin; + + /** + * This is the value of the ending position of the text range. + */ + private int end; + + /** + * This is the current value of the scan index. + */ + private int index; + + /** + * This method initializes a new instance of + * <code>StringCharacterIterator</code> to iterate over the entire + * text of the specified <code>String</code>. The initial index + * value will be set to the first character in the string. + * + * @param text The <code>String</code> to iterate through. + */ + public StringCharacterIterator (String text) { - return (Object) new StringCharacterIterator (text, begin, end, pos); + this (text, 0, text.length (), 0); } - public char current () + /*************************************************************************/ + + /** + * This method initializes a new instance of + * <code>StringCharacterIterator</code> to iterate over the entire + * text of the specified <code>String</code>. The initial index + * value will be set to the specified value. + * + * @param text The <code>String</code> to iterate through. + * @param index The initial index position. + */ + public StringCharacterIterator (String text, int index) { - // This follows JDK 1.2 semantics and not 1.1 semantics. - // In 1.1 we would throw an exception if begin==end. - return (pos < end) ? text.charAt(pos) : CharacterIterator.DONE; + this (text, 0, text.length (), index); } - public boolean equals (Object obj) + /*************************************************************************/ + + /** + * This method initializes a new instance of + * <code>StringCharacterIterator</code> that iterates over the text + * in a subrange of the specified <code>String</code>. The + * beginning and end of the range are specified by the caller, as is + * the initial index position. + * + * @param text The <code>String</code> to iterate through. + * @param begin The beginning position in the character range. + * @param end The ending position in the character range. + * @param index The initial index position. + * + * @param IllegalArgumentException If any of the range values are + * invalid. + */ + public StringCharacterIterator (String text, int begin, int end, int index) { - if (! (obj instanceof StringCharacterIterator)) - return false; - StringCharacterIterator sci = (StringCharacterIterator) obj; - // The spec says "the same text". We take this to mean equals, - // not ==. - return (pos == sci.pos - && begin == sci.begin - && end == sci.end - && text.equals(sci.text)); + int len = text.length (); + + if ((begin < 0) || (begin > len)) + throw new IllegalArgumentException ("Bad begin position"); + + if ((end < begin) || (end > len)) + throw new IllegalArgumentException ("Bad end position"); + + if ((index < begin) || (index > end)) + throw new IllegalArgumentException ("Bad initial index position"); + + this.text = text; + this.begin = begin; + this.end = end; + this.index = index; } - public char first () + /** + * This is a package level constructor that copies the text out of + * an existing StringCharacterIterator and resets the beginning and + * ending index. + * + * @param scci The StringCharacterIterator to copy the info from + * @param begin The beginning index of the range we are interested in. + * @param end The ending index of the range we are interested in. + */ + StringCharacterIterator (StringCharacterIterator sci, int begin, int end) { - pos = begin; - return current (); + this (sci.text, begin, end, begin); } - public int getBeginIndex () + /** + * This method returns the character at the current index position + * + * @return The character at the current index position. + */ + public char current () { - return begin; + return (index < end) ? text.charAt (index) : DONE; } - public int getEndIndex () + /*************************************************************************/ + + /** + * This method increments the current index and then returns the + * character at the new index value. If the index is already at + * <code>getEndIndex () - 1</code>, it will not be incremented. + * + * @return The character at the position of the incremented index + * value, or <code>DONE</code> if the index has reached + * getEndIndex () - 1. + */ + public char next () { - return end; + if (index == end) + return DONE; + + ++index; + return current (); } - public int getIndex () + /*************************************************************************/ + + /** + * This method decrements the current index and then returns the + * character at the new index value. If the index value is already + * at the beginning index, it will not be decremented. + * + * @return The character at the position of the decremented index + * value, or <code>DONE</code> if index was already equal to the + * beginning index value. + */ + public char previous () { - return pos; + if (index == begin) + return DONE; + + --index; + return current (); } - public int hashCode () + /*************************************************************************/ + + /** + * This method sets the index value to the beginning of the range and returns + * the character there. + * + * @return The character at the beginning of the range, or + * <code>DONE</code> if the range is empty. + */ + public char first () { - // FIXME: this is a terrible hash code. Find a better one. - return text.hashCode() + pos + begin + end; + index = begin; + return current (); } + /*************************************************************************/ + + /** + * This method sets the index value to <code>getEndIndex () - 1</code> and + * returns the character there. If the range is empty, then the index value + * will be set equal to the beginning index. + * + * @return The character at the end of the range, or + * <code>DONE</code> if the range is empty. + */ public char last () { - pos = end; + if (end == begin) + return DONE; + + index = end - 1; return current (); } - public char next () + /*************************************************************************/ + + /** + * This method returns the current value of the index. + * + * @return The current index value + */ + public int getIndex () { - if (pos == end) - return CharacterIterator.DONE; - ++pos; - return current (); + return index; } - public char previous () + /*************************************************************************/ + + /** + * This method sets the value of the index to the specified value, then + * returns the character at that position. + * + * @param index The new index value. + * + * @return The character at the new index value or <code>DONE</code> + * if the index value is equal to <code>getEndIndex</code>. + * + * @exception IllegalArgumentException If the specified index is not valid + */ + public char setIndex (int index) { - if (pos == begin) - return CharacterIterator.DONE; - --pos; + if ((index < begin) || (index > end)) + throw new IllegalArgumentException ("Bad index specified"); + + this.index = index; return current (); } - public char setIndex (int idx) + /*************************************************************************/ + + /** + * This method returns the character position of the first character in the + * range. + * + * @return The index of the first character in the range. + */ + public int getBeginIndex () { - // In 1.1 we would throw an error if `idx == end'. - if (idx < begin || idx > end) - throw new IllegalArgumentException (); - pos = idx; - return current (); + return begin; } - public StringCharacterIterator (String text) + /*************************************************************************/ + + /** + * This method returns the character position of the end of the text range. + * This will actually be the index of the first character following the + * end of the range. In the event the text range is empty, this will be + * equal to the first character in the range. + * + * @return The index of the end of the range. + */ + public int getEndIndex () { - this (text, 0, text.length(), 0); + return end; } - public StringCharacterIterator (String text, int pos) + /*************************************************************************/ + + /** + * This method creates a copy of this <code>CharacterIterator</code>. + * + * @return A copy of this <code>CharacterIterator</code>. + */ + public Object clone () { - this (text, 0, text.length(), pos); + return new StringCharacterIterator (text, begin, end, index); } - public StringCharacterIterator (String text, int begin, int end, int pos) + /*************************************************************************/ + + /** + * This method tests this object for equality againt the specified + * object. This will be true if and only if the specified object: + * <p> + * <ul> + * <li>is not <code>null</code>. + * <li>is an instance of <code>StringCharacterIterator</code> + * <li>has the same text as this object + * <li>has the same beginning, ending, and current index as this object. + * </ul> + * + * @param obj The object to test for equality against. + * + * @return <code>true</code> if the specified object is equal to this + * object, <code>false</code> otherwise. + */ + public boolean equals (Object obj) { - if (begin < 0 || begin > end || end > text.length() - // In 1.1 we would also throw if `pos == end'. - || pos < begin || pos > end) - throw new IllegalArgumentException (); + if (! (obj instanceof StringCharacterIterator)) + return false; - this.text = text; - this.begin = begin; - this.end = end; - this.pos = pos; + StringCharacterIterator sci = (StringCharacterIterator) obj; + + return (begin == sci.begin + && end == sci.end + && index == sci.index + && text.equals (sci.text)); } - // The online 1.2 docs say that this is "package visible" in the - // method description, but they also say it is public. We choose - // the latter for compatibility with the actual implementation. + /*************************************************************************/ + + /** + * This method allows other classes in java.text to change the value + * of the underlying text being iterated through. + * + * @param text The new <code>String</code> to iterate through. + */ public void setText (String text) { this.text = text; this.begin = 0; this.end = text.length (); - this.pos = 0; + this.index = 0; } - - // String to iterate over. - private String text; - // Current position. - private int pos; - // Start position in string. - private int begin; - // End position in string. - private int end; } |