mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-14 09:21:03 +00:00
ICU-7444 Created ICU4J 4.4 release branch from trunk r27783.
X-SVN-Rev: 27784
This commit is contained in:
commit
83bcd1bc1f
1401 changed files with 1329801 additions and 0 deletions
357
.gitattributes
vendored
Normal file
357
.gitattributes
vendored
Normal file
|
@ -0,0 +1,357 @@
|
|||
* text=auto !eol
|
||||
|
||||
*.c text !eol
|
||||
*.cc text !eol
|
||||
*.classpath text !eol
|
||||
*.cpp text !eol
|
||||
*.css text !eol
|
||||
*.dsp text !eol
|
||||
*.dsw text !eol
|
||||
*.filters text !eol
|
||||
*.h text !eol
|
||||
*.htm text !eol
|
||||
*.html text !eol
|
||||
*.in text !eol
|
||||
*.java text !eol
|
||||
*.launch text !eol
|
||||
*.mak text !eol
|
||||
*.md text !eol
|
||||
*.MF text !eol
|
||||
*.mk text !eol
|
||||
*.pl text !eol
|
||||
*.pm text !eol
|
||||
*.project text !eol
|
||||
*.properties text !eol
|
||||
*.py text !eol
|
||||
*.rc text !eol
|
||||
*.sh text eol=lf
|
||||
*.sln text !eol
|
||||
*.stub text !eol
|
||||
*.txt text !eol
|
||||
*.ucm text !eol
|
||||
*.vcproj text !eol
|
||||
*.vcxproj text !eol
|
||||
*.xml text !eol
|
||||
*.xsl text !eol
|
||||
*.xslt text !eol
|
||||
Makefile text !eol
|
||||
configure text !eol
|
||||
LICENSE text !eol
|
||||
README text !eol
|
||||
|
||||
*.bin -text
|
||||
*.brk -text
|
||||
*.cnv -text
|
||||
*.icu -text
|
||||
*.res -text
|
||||
*.nrm -text
|
||||
*.spp -text
|
||||
*.tri2 -text
|
||||
|
||||
/build.properties -text
|
||||
demos/manifest.stub -text
|
||||
main/classes/charset/.classpath -text
|
||||
main/classes/charset/.project -text
|
||||
main/classes/charset/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/charset/manifest.stub -text
|
||||
main/classes/collate/.classpath -text
|
||||
main/classes/collate/.project -text
|
||||
main/classes/collate/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/collate/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/classes/collate/collate-build.launch -text
|
||||
main/classes/core/.classpath -text
|
||||
main/classes/core/.project -text
|
||||
main/classes/core/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/core/manifest.stub -text
|
||||
main/classes/core/src/com/ibm/icu/impl/BMPSet.java -text
|
||||
main/classes/core/src/com/ibm/icu/impl/UnicodeSetStringSpan.java -text
|
||||
main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text
|
||||
main/classes/currdata/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/currdata/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/classes/currdata/currdata-build.launch -text
|
||||
main/classes/langdata/.externalToolBuilders/copy-data-langdata.launch -text
|
||||
main/classes/langdata/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/langdata/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/classes/langdata/langdata-build.launch -text
|
||||
main/classes/localespi/.classpath -text
|
||||
main/classes/localespi/.project -text
|
||||
main/classes/localespi/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/localespi/manifest.stub -text
|
||||
main/classes/localespi/src/META-INF/services/java.text.spi.BreakIteratorProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.text.spi.CollatorProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.text.spi.DateFormatProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.text.spi.DateFormatSymbolsProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.text.spi.DecimalFormatSymbolsProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.text.spi.NumberFormatProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.util.spi.CurrencyNameProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.util.spi.LocaleNameProvider -text
|
||||
main/classes/localespi/src/META-INF/services/java.util.spi.TimeZoneNameProvider -text
|
||||
main/classes/localespi/src/com/ibm/icu/impl/javaspi/ICULocaleServiceProviderConfig.properties -text
|
||||
main/classes/regiondata/.externalToolBuilders/copy-data-regiondata.launch -text
|
||||
main/classes/regiondata/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/regiondata/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/classes/regiondata/regiondata-build.launch -text
|
||||
main/classes/translit/.externalToolBuilders/copy-data-translit.launch -text
|
||||
main/classes/translit/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/classes/translit/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/classes/translit/translit-build.launch -text
|
||||
main/shared/.project -text
|
||||
main/shared/data/icudata.jar -text
|
||||
main/shared/data/testdata.jar -text
|
||||
main/tests/charset/.classpath -text
|
||||
main/tests/charset/.project -text
|
||||
main/tests/charset/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/tests/charset/manifest.stub -text
|
||||
main/tests/collate/.classpath -text
|
||||
main/tests/collate/.project -text
|
||||
main/tests/collate/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/tests/collate/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/tests/collate/collate-tests-build.launch -text
|
||||
main/tests/core/.classpath -text
|
||||
main/tests/core/.project -text
|
||||
main/tests/core/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/tests/core/manifest.stub -text
|
||||
main/tests/core/src/com/ibm/icu/dev/data/rbbi/english.dict -text
|
||||
main/tests/core/src/com/ibm/icu/dev/data/resources/testmessages.properties -text
|
||||
main/tests/core/src/com/ibm/icu/dev/data/thai6.ucs -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/lang/UnicodeSetStringSpanTest.java -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.impl.OlsonTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.impl.TimeZoneAdapter.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.math.BigDecimal.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.math.MathContext.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.ArabicShapingException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.ChineseDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.ChineseDateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.DateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.DateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.DecimalFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.DecimalFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.MessageFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.NumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.RuleBasedNumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.SimpleDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.text.StringPrepParseException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.BuddhistCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.Calendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.ChineseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.CopticCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.Currency.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.EthiopicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.GregorianCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.HebrewCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.IslamicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.JapaneseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.SimpleTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.TimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.ULocale.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.6/com.ibm.icu.util.UResourceTypeMismatchException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.impl.DateNumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.impl.InvalidFormatException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.impl.OlsonTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.impl.RelativeDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.impl.TimeZoneAdapter.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.math.BigDecimal.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.math.MathContext.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.ArabicShapingException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.ChineseDateFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.ChineseDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.DateFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.DateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.DateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.DecimalFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.DecimalFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.MessageFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.MessageFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.NumberFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.NumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.PluralFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.PluralRules.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.RuleBasedNumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.SimpleDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.text.StringPrepParseException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.AnnualTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.BuddhistCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.Calendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.ChineseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.CopticCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.Currency.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.DateTimeRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.EthiopicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.GregorianCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.HebrewCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.IndianCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.InitialTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.IslamicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.JapaneseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.RuleBasedTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.SimpleTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.TaiwanCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.TimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.ULocale.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.UResourceTypeMismatchException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_3.8.1/com.ibm.icu.util.VTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.impl.DateNumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.impl.InvalidFormatException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.impl.JavaTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.impl.OlsonTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.impl.RelativeDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.impl.TimeZoneAdapter.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.impl.duration.BasicDurationFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.math.BigDecimal.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.math.MathContext.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.ArabicShapingException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.ChineseDateFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.ChineseDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.ChineseDateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DateFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DateIntervalFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DateIntervalInfo.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DecimalFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.DecimalFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.MessageFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.MessageFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.NumberFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.NumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.PluralFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.PluralRules.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.RuleBasedNumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.SimpleDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.StringPrepParseException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.text.TimeUnitFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.AnnualTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.BuddhistCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.Calendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.ChineseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.CopticCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.Currency.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.DateInterval.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.DateTimeRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.EthiopicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.GregorianCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.HebrewCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.IndianCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.InitialTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.IslamicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.JapaneseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.RuleBasedTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.SimpleTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.TaiwanCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.TimeArrayTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.TimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.ULocale.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.UResourceTypeMismatchException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.0/com.ibm.icu.util.VTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.DateNumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.IllegalIcuArgumentException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.InvalidFormatException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.JavaTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.OlsonTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.RelativeDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.TimeZoneAdapter.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.duration.BasicDurationFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.impl.locale.LocaleSyntaxException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.math.BigDecimal.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.math.MathContext.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.ArabicShapingException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.ChineseDateFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.ChineseDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.ChineseDateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.CurrencyPluralInfo.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DateFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DateFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DateIntervalFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DateIntervalInfo$PatternInfo.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DateIntervalInfo.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DecimalFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.DecimalFormatSymbols.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.MessageFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.MessageFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.NumberFormat$Field.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.NumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.PluralFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.PluralRules.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.RuleBasedNumberFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.SimpleDateFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.StringPrepParseException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.text.TimeUnitFormat.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.AnnualTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.BuddhistCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.Calendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.ChineseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.CopticCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.Currency.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.DateInterval.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.DateTimeRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.EthiopicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.GregorianCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.HebrewCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.IllformedLocaleException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.IndianCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.InitialTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.IslamicCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.JapaneseCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.RuleBasedTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.SimpleTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.TaiwanCalendar.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.TimeArrayTimeZoneRule.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.TimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.ULocale.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.UResourceTypeMismatchException.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/serializable/data/ICU_4.2.1/com.ibm.icu.util.VTimeZone.dat -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges1.16.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges1.32.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges2.16.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges2.32.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges3.16.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRanges3.32.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesEmpty.16.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesEmpty.32.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesSingleValue.16.tri2 -text
|
||||
main/tests/core/src/com/ibm/icu/dev/test/util/Trie2Test.setRangesSingleValue.32.tri2 -text
|
||||
main/tests/framework/.classpath -text
|
||||
main/tests/framework/.project -text
|
||||
main/tests/framework/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/tests/framework/manifest.stub -text
|
||||
main/tests/localespi/.classpath -text
|
||||
main/tests/localespi/.project -text
|
||||
main/tests/localespi/manifest.stub -text
|
||||
main/tests/packaging/.externalToolBuilders/copy-test-data.launch -text
|
||||
main/tests/packaging/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/tests/packaging/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/tests/packaging/packaging-tests-build.launch -text
|
||||
main/tests/translit/.externalToolBuilders/copy-translit-test-data.launch -text
|
||||
main/tests/translit/.settings/org.eclipse.jdt.core.prefs -text
|
||||
main/tests/translit/.settings/org.eclipse.jdt.ui.prefs -text
|
||||
main/tests/translit/translit-tests-build.launch -text
|
||||
tools/build/icu4j28.api.gz -text
|
||||
tools/build/icu4j30.api.gz -text
|
||||
tools/build/icu4j32.api.gz -text
|
||||
tools/build/icu4j34.api.gz -text
|
||||
tools/build/icu4j341.api.gz -text
|
||||
tools/build/icu4j342.api.gz -text
|
||||
tools/build/icu4j343.api.gz -text
|
||||
tools/build/icu4j36.api.gz -text
|
||||
tools/build/icu4j38.api.gz -text
|
||||
tools/build/icu4j381.api.gz -text
|
||||
tools/build/icu4j400.api.gz -text
|
||||
tools/build/icu4j401.api.gz -text
|
||||
tools/build/icu4j42.api.gz -text
|
||||
tools/build/icu4j421.api.gz -text
|
||||
tools/build/manifest.stub -text
|
||||
tools/misc/manifest.stub -text
|
||||
|
||||
# The following file types are stored in Git-LFS.
|
||||
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||
*.dat filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.gif filter=lfs diff=lfs merge=lfs -text
|
||||
|
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*.jar
|
||||
/.project
|
||||
demos/out
|
||||
/doc
|
||||
main/classes/charset/out
|
||||
main/classes/collate/out
|
||||
main/classes/core/out
|
||||
main/classes/currdata/out
|
||||
main/classes/langdata/out
|
||||
main/classes/localespi/out
|
||||
main/classes/regiondata/out
|
||||
main/classes/translit/out
|
||||
main/tests/charset/out
|
||||
main/tests/collate/out
|
||||
main/tests/core/out
|
||||
main/tests/framework/out
|
||||
main/tests/localespi/out
|
||||
main/tests/packaging/out
|
||||
main/tests/translit/out
|
||||
/out
|
||||
tools/build/out
|
||||
tools/misc/out
|
591
APIChangeReport.html
Normal file
591
APIChangeReport.html
Normal file
|
@ -0,0 +1,591 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>ICU4J API Comparison: ICU4J 4.2.1 with ICU4J 4.4</title>
|
||||
<!-- Copyright 2010, IBM, All Rights Reserved. -->
|
||||
</head>
|
||||
<body>
|
||||
<h1>ICU4J API Comparison: ICU4J 4.2.1 with ICU4J 4.4</h1>
|
||||
|
||||
<hr/>
|
||||
<h2>Removed from ICU4J 4.2.1</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.charset</h3>
|
||||
<ul>
|
||||
CharsetCallback
|
||||
<ul>
|
||||
<li>(draft) public <i>CharsetCallback</i>()</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.math</h3>
|
||||
<ul>
|
||||
BigDecimal
|
||||
<ul>
|
||||
<li>(stable) public int <i>compareTo</i>(java.lang.Object)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>public class <i>BreakDictionary</i></li>
|
||||
ArabicShaping
|
||||
<ul>
|
||||
<li>(draft) public static int <i>countSpaceSub</i>(char[], int, char)</li>
|
||||
<li>(draft) public static int <i>flipArray</i>(char[], int, int, int)</li>
|
||||
<li>(draft) public static void <i>shiftArray</i>(char[], int, int, char)</li>
|
||||
</ul>
|
||||
CollationKey
|
||||
<ul>
|
||||
<li>(stable) public int <i>compareTo</i>(java.lang.Object)</li>
|
||||
</ul>
|
||||
DateIntervalInfo
|
||||
<ul>
|
||||
<li>(stable) public java.lang.Object <i>cloneAsThawed</i>()</li>
|
||||
<li>(stable) public java.lang.Object <i>freeze</i>()</li>
|
||||
</ul>
|
||||
DateTimePatternGenerator
|
||||
<ul>
|
||||
<li>(stable) public java.lang.Object <i>cloneAsThawed</i>()</li>
|
||||
<li>(stable) public java.lang.Object <i>freeze</i>()</li>
|
||||
</ul>
|
||||
DecimalFormatSymbols
|
||||
<ul>
|
||||
<li>(draft) public static final int CURRENCT_SPC_SURROUNDING_MATCH</li>
|
||||
</ul>
|
||||
IndexCharacters
|
||||
<ul>
|
||||
<li>(draft) public static final char CGJ</li>
|
||||
</ul>
|
||||
Normalizer
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>public static boolean <i>isNFSkippable</i>(int, Normalizer.Mode)</li>
|
||||
</ul>
|
||||
Normalizer.Mode
|
||||
<ul>
|
||||
<li>(stable) protected int <i>getMask</i>()</li>
|
||||
<li>(stable) protected int <i>getMinC</i>()</li>
|
||||
<li>(stable) protected Normalizer.IsNextBoundary <i>getNextBoundary</i>()</li>
|
||||
<li>(stable) protected Normalizer.IsPrevBoundary <i>getPrevBoundary</i>()</li>
|
||||
<li>(stable) protected boolean <i>isNFSkippable</i>(int)</li>
|
||||
<li>(stable) protected int <i>normalize</i>(char[], int, int, char[], int, int, UnicodeSet)</li>
|
||||
<li>(stable) protected int <i>normalize</i>(char[], int, int, char[], int, int, int)</li>
|
||||
<li>(stable) protected java.lang.String <i>normalize</i>(java.lang.String, int)</li>
|
||||
<li>(stable) protected Normalizer.QuickCheckResult <i>quickCheck</i>(char[], int, int, boolean, UnicodeSet)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
Calendar
|
||||
<ul>
|
||||
<li>(stable) public int <i>compareTo</i>(java.lang.Object)</li>
|
||||
</ul>
|
||||
ChineseCalendar
|
||||
<ul>
|
||||
<li>(stable) public static int IS_LEAP_MONTH</li>
|
||||
<li>(stable) protected int[] <i>handleCreateFields</i>()</li>
|
||||
</ul>
|
||||
GlobalizationPreferences
|
||||
<ul>
|
||||
<li>(draft) public java.lang.Object <i>cloneAsThawed</i>()</li>
|
||||
<li>(draft) public java.lang.Object <i>freeze</i>()</li>
|
||||
</ul>
|
||||
ULocale
|
||||
<ul>
|
||||
<li>(draft) public static final char LDML_EXTENSION</li>
|
||||
<li>(draft) public static VersionInfo <i>getCLDRVersion</i>()</li>
|
||||
<li>(draft) public java.util.Set <i>getLDMLExtensionKeys</i>()</li>
|
||||
<li>(draft) public java.lang.String <i>getLDMLExtensionValue</i>(java.lang.String)</li>
|
||||
</ul>
|
||||
ULocale.Builder
|
||||
<ul>
|
||||
<li>(draft) public ULocale <i>create</i>()</li>
|
||||
<li>(draft) public ULocale.Builder <i>setLDMLExtensionValue</i>(java.lang.String, java.lang.String)</li>
|
||||
</ul>
|
||||
UResourceBundle
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>protected static final int ALIAS</li>
|
||||
<li><span style='color:red'>*internal* </span>protected static final int TABLE32</li>
|
||||
<li><span style='color:red'>*internal* </span>protected boolean isTopLevel</li>
|
||||
<li><span style='color:red'>*internal* </span>protected java.lang.String key</li>
|
||||
<li><span style='color:red'>*internal* </span>protected long resource</li>
|
||||
<li><span style='color:red'>*internal* </span>protected int size</li>
|
||||
</ul>
|
||||
VersionInfo
|
||||
<ul>
|
||||
<li>(draft) public int <i>compareTo</i>(java.lang.Object)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
<h2>Withdrawn, Deprecated, or Obsoleted in ICU4J 4.4</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
SimpleDateFormat
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>protected NumberFormat <i>getNumberFormat</i>(char)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
Calendar.FormatConfiguration
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>public java.lang.String <i>getOverrideString</i>()</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
<h2>Changed in ICU4J 4.4 (old, new)</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.charset</h3>
|
||||
<ul>
|
||||
CharsetProviderICU
|
||||
<ul>
|
||||
<li> <span style='color:red'>*internal* </span>public static final java.lang.Object[] <i>getAvailableNames</i>()</br>
|
||||
<span style='color:red'>*internal* </span>public static final java.lang.String[] <i>getAvailableNames</i>()</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
CharsetMatch
|
||||
<ul>
|
||||
<li> (stable) public int <i>compareTo</i>(java.lang.Object)</br>
|
||||
(stable) public int <i>compareTo</i>(com.ibm.icu.text.CharsetMatch)</li>
|
||||
</ul>
|
||||
RawCollationKey
|
||||
<ul>
|
||||
<li> (stable) public int <i>compareTo</i>(java.lang.Object)</br>
|
||||
(stable) public int <i>compareTo</i>(com.ibm.icu.text.RawCollationKey)</li>
|
||||
<li> (stable) public interface <i>StringTransform</i> </br>
|
||||
(stable) public interface <i>StringTransform</i> implements com.ibm.icu.text.Transform</li>
|
||||
</ul>
|
||||
UTF16.StringComparator
|
||||
<ul>
|
||||
<li> (stable) public int <i>compare</i>(java.lang.Object, java.lang.Object)</br>
|
||||
(stable) public int <i>compare</i>(java.lang.String, java.lang.String)</li>
|
||||
<li> (stable) public class <i>UnicodeSet</i> extends com.ibm.icu.text.UnicodeFilter implements com.ibm.icu.util.Freezable</br>
|
||||
(stable) public class <i>UnicodeSet</i> extends com.ibm.icu.text.UnicodeFilter implements java.lang.Iterable, java.lang.Comparable, com.ibm.icu.util.Freezable</li>
|
||||
</ul>
|
||||
UnicodeSet
|
||||
<ul>
|
||||
<li> (stable) public void <i>addAll</i>(java.util.Collection)</br>
|
||||
(draft) public com.ibm.icu.text.UnicodeSet <i>addAll</i>(int, int)</li>
|
||||
<li> (stable) public void <i>addAllTo</i>(java.util.Collection)</br>
|
||||
(draft) public static java.lang.Object[] <i>addAllTo</i>(java.lang.Iterable, T[])</li>
|
||||
<li> (stable) public java.lang.Object <i>cloneAsThawed</i>()</br>
|
||||
(stable) public com.ibm.icu.text.UnicodeSet <i>cloneAsThawed</i>()</li>
|
||||
<li> (stable) public java.lang.Object <i>freeze</i>()</br>
|
||||
(stable) public com.ibm.icu.text.UnicodeSet <i>freeze</i>()</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
ByteArrayWrapper
|
||||
<ul>
|
||||
<li> (stable) public int <i>compareTo</i>(java.lang.Object)</br>
|
||||
(stable) public int <i>compareTo</i>(com.ibm.icu.util.ByteArrayWrapper)</li>
|
||||
</ul>
|
||||
UResourceBundle
|
||||
<ul>
|
||||
<li> <span style='color:red'>*internal* </span>protected static void <i>addToCache</i>(java.lang.ClassLoader, java.lang.String, com.ibm.icu.util.ULocale, com.ibm.icu.util.UResourceBundle)</br>
|
||||
<span style='color:red'>*internal* </span>protected static com.ibm.icu.util.UResourceBundle <i>addToCache</i>(java.lang.ClassLoader, java.lang.String, com.ibm.icu.util.ULocale, com.ibm.icu.util.UResourceBundle)</li>
|
||||
</ul>
|
||||
VersionInfo
|
||||
<ul>
|
||||
<li> <span style='color:red'>*internal* </span>public static final java.lang.String ICU_DATA_VERSION</br>
|
||||
<span style='color:red'>*internal* </span>public static final com.ibm.icu.util.VersionInfo ICU_DATA_VERSION</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
<h2>Promoted to stable in ICU4J 4.4</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.charset</h3>
|
||||
<ul>
|
||||
<li>(stable) public final class <i>CharsetSelector</i></li>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
<li>(stable) public class <i>CurrencyPluralInfo</i></li>
|
||||
ChineseDateFormat
|
||||
<ul>
|
||||
<li>(draft) public <i>ChineseDateFormat</i>(java.lang.String, java.lang.String, ULocale)</li>
|
||||
</ul>
|
||||
Collator
|
||||
<ul>
|
||||
<li>(stable) public static final java.lang.String[] <i>getKeywordValuesForLocale</i>(java.lang.String, ULocale, boolean)</li>
|
||||
</ul>
|
||||
DecimalFormat
|
||||
<ul>
|
||||
<li>(stable) public <i>DecimalFormat</i>(java.lang.String, DecimalFormatSymbols, CurrencyPluralInfo, int)</li>
|
||||
<li>(stable) public CurrencyPluralInfo <i>getCurrencyPluralInfo</i>()</li>
|
||||
<li>(stable) public java.math.MathContext <i>getMathContext</i>()</li>
|
||||
<li>(stable) public MathContext <i>getMathContextICU</i>()</li>
|
||||
<li>(stable) public void <i>setCurrencyPluralInfo</i>(CurrencyPluralInfo)</li>
|
||||
<li>(stable) public void <i>setMathContext</i>(java.math.MathContext)</li>
|
||||
<li>(stable) public void <i>setMathContextICU</i>(MathContext)</li>
|
||||
</ul>
|
||||
NumberFormat
|
||||
<ul>
|
||||
<li>(stable) public static final int CURRENCYSTYLE</li>
|
||||
<li>(stable) public static final int INTEGERSTYLE</li>
|
||||
<li>(stable) public static final int ISOCURRENCYSTYLE</li>
|
||||
<li>(stable) public static final int NUMBERSTYLE</li>
|
||||
<li>(stable) public static final int PERCENTSTYLE</li>
|
||||
<li>(stable) public static final int PLURALCURRENCYSTYLE</li>
|
||||
<li>(stable) public static final int SCIENTIFICSTYLE</li>
|
||||
<li>(stable) public static NumberFormat <i>getInstance</i>(ULocale, int)</li>
|
||||
<li>(stable) public static final NumberFormat <i>getInstance</i>(int)</li>
|
||||
<li>(stable) public static NumberFormat <i>getInstance</i>(java.util.Locale, int)</li>
|
||||
</ul>
|
||||
PluralFormat
|
||||
<ul>
|
||||
<li>(stable) public java.lang.String <i>toPattern</i>()</li>
|
||||
</ul>
|
||||
RuleBasedNumberFormat
|
||||
<ul>
|
||||
<li>(stable) public static final int NUMBERING_SYSTEM</li>
|
||||
</ul>
|
||||
SimpleDateFormat
|
||||
<ul>
|
||||
<li>(stable) public <i>SimpleDateFormat</i>(java.lang.String, java.lang.String, ULocale)</li>
|
||||
</ul>
|
||||
StringPrep
|
||||
<ul>
|
||||
<li>(stable) public static final int RFC3491_NAMEPREP</li>
|
||||
<li>(stable) public static final int RFC3530_NFS4_CIS_PREP</li>
|
||||
<li>(stable) public static final int RFC3530_NFS4_CS_PREP</li>
|
||||
<li>(stable) public static final int RFC3530_NFS4_CS_PREP_CI</li>
|
||||
<li>(stable) public static final int RFC3530_NFS4_MIXED_PREP_PREFIX</li>
|
||||
<li>(stable) public static final int RFC3530_NFS4_MIXED_PREP_SUFFIX</li>
|
||||
<li>(stable) public static final int RFC3722_ISCSI</li>
|
||||
<li>(stable) public static final int RFC3920_NODEPREP</li>
|
||||
<li>(stable) public static final int RFC3920_RESOURCEPREP</li>
|
||||
<li>(stable) public static final int RFC4011_MIB</li>
|
||||
<li>(stable) public static final int RFC4013_SASLPREP</li>
|
||||
<li>(stable) public static final int RFC4505_TRACE</li>
|
||||
<li>(stable) public static final int RFC4518_LDAP</li>
|
||||
<li>(stable) public static final int RFC4518_LDAP_CI</li>
|
||||
<li>(stable) public static StringPrep <i>getInstance</i>(int)</li>
|
||||
<li>(stable) public java.lang.String <i>prepare</i>(java.lang.String, int)</li>
|
||||
</ul>
|
||||
TimeUnitFormat
|
||||
<ul>
|
||||
<li>(stable) public static final int ABBREVIATED_NAME</li>
|
||||
<li>(stable) public static final int FULL_NAME</li>
|
||||
<li>(stable) public <i>TimeUnitFormat</i>(ULocale, int)</li>
|
||||
<li>(stable) public <i>TimeUnitFormat</i>(java.util.Locale, int)</li>
|
||||
</ul>
|
||||
UnicodeSet
|
||||
<ul>
|
||||
<li>(stable) public final UnicodeSet <i>removeAllStrings</i>()</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
Calendar
|
||||
<ul>
|
||||
<li>(stable) public static final java.lang.String[] <i>getKeywordValuesForLocale</i>(java.lang.String, ULocale, boolean)</li>
|
||||
</ul>
|
||||
Currency
|
||||
<ul>
|
||||
<li>(stable) public static final int PLURAL_LONG_NAME</li>
|
||||
<li>(stable) public static final java.lang.String[] <i>getKeywordValuesForLocale</i>(java.lang.String, ULocale, boolean)</li>
|
||||
<li>(stable) public java.lang.String <i>getName</i>(ULocale, int, java.lang.String, boolean[])</li>
|
||||
<li>(stable) public java.lang.String <i>getName</i>(java.util.Locale, int, java.lang.String, boolean[])</li>
|
||||
</ul>
|
||||
LocaleData
|
||||
<ul>
|
||||
<li>(stable) public java.lang.String <i>getLocaleDisplayPattern</i>()</li>
|
||||
<li>(stable) public java.lang.String <i>getLocaleSeparator</i>()</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
<h2>Added in ICU4J 4.4</h2>
|
||||
|
||||
<h3>Package com.ibm.icu.charset</h3>
|
||||
<ul>
|
||||
CharsetDecoderICU
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>protected static final int EXT_MAX_BYTES</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.lang</h3>
|
||||
<ul>
|
||||
UCharacter
|
||||
<ul>
|
||||
<li>(draft) public static int <i>getCharFromNameAlias</i>(java.lang.String)</li>
|
||||
<li>(draft) public static java.lang.String <i>getNameAlias</i>(int)</li>
|
||||
</ul>
|
||||
UCharacter.JoiningGroup
|
||||
<ul>
|
||||
<li>(stable) public static final int FARSI_YEH</li>
|
||||
<li>(stable) public static final int NYA</li>
|
||||
</ul>
|
||||
UCharacter.LineBreak
|
||||
<ul>
|
||||
<li>(stable) public static final int CLOSE_PARENTHESIS</li>
|
||||
</ul>
|
||||
UCharacter.UnicodeBlock
|
||||
<ul>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock AVESTAN</li>
|
||||
<li>(stable) public static final int AVESTAN_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock BAMUM</li>
|
||||
<li>(stable) public static final int BAMUM_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C</li>
|
||||
<li>(stable) public static final int CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock COMMON_INDIC_NUMBER_FORMS</li>
|
||||
<li>(stable) public static final int COMMON_INDIC_NUMBER_FORMS_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock DEVANAGARI_EXTENDED</li>
|
||||
<li>(stable) public static final int DEVANAGARI_EXTENDED_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock EGYPTIAN_HIEROGLYPHS</li>
|
||||
<li>(stable) public static final int EGYPTIAN_HIEROGLYPHS_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT</li>
|
||||
<li>(stable) public static final int ENCLOSED_ALPHANUMERIC_SUPPLEMENT_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT</li>
|
||||
<li>(stable) public static final int ENCLOSED_IDEOGRAPHIC_SUPPLEMENT_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock HANGUL_JAMO_EXTENDED_A</li>
|
||||
<li>(stable) public static final int HANGUL_JAMO_EXTENDED_A_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock HANGUL_JAMO_EXTENDED_B</li>
|
||||
<li>(stable) public static final int HANGUL_JAMO_EXTENDED_B_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock IMPERIAL_ARAMAIC</li>
|
||||
<li>(stable) public static final int IMPERIAL_ARAMAIC_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock INSCRIPTIONAL_PAHLAVI</li>
|
||||
<li>(stable) public static final int INSCRIPTIONAL_PAHLAVI_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock INSCRIPTIONAL_PARTHIAN</li>
|
||||
<li>(stable) public static final int INSCRIPTIONAL_PARTHIAN_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock JAVANESE</li>
|
||||
<li>(stable) public static final int JAVANESE_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock KAITHI</li>
|
||||
<li>(stable) public static final int KAITHI_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock LISU</li>
|
||||
<li>(stable) public static final int LISU_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock MEETEI_MAYEK</li>
|
||||
<li>(stable) public static final int MEETEI_MAYEK_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock MYANMAR_EXTENDED_A</li>
|
||||
<li>(stable) public static final int MYANMAR_EXTENDED_A_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock OLD_SOUTH_ARABIAN</li>
|
||||
<li>(stable) public static final int OLD_SOUTH_ARABIAN_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock OLD_TURKIC</li>
|
||||
<li>(stable) public static final int OLD_TURKIC_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock RUMI_NUMERAL_SYMBOLS</li>
|
||||
<li>(stable) public static final int RUMI_NUMERAL_SYMBOLS_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock SAMARITAN</li>
|
||||
<li>(stable) public static final int SAMARITAN_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock TAI_THAM</li>
|
||||
<li>(stable) public static final int TAI_THAM_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock TAI_VIET</li>
|
||||
<li>(stable) public static final int TAI_VIET_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED</li>
|
||||
<li>(stable) public static final int UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_ID</li>
|
||||
<li>(stable) public static final UCharacter.UnicodeBlock VEDIC_EXTENSIONS</li>
|
||||
<li>(stable) public static final int VEDIC_EXTENSIONS_ID</li>
|
||||
</ul>
|
||||
UProperty
|
||||
<ul>
|
||||
<li>(stable) public static final int CASED</li>
|
||||
<li>(stable) public static final int CASE_IGNORABLE</li>
|
||||
<li>(stable) public static final int CHANGES_WHEN_CASEFOLDED</li>
|
||||
<li>(stable) public static final int CHANGES_WHEN_CASEMAPPED</li>
|
||||
<li>(stable) public static final int CHANGES_WHEN_LOWERCASED</li>
|
||||
<li>(stable) public static final int CHANGES_WHEN_NFKC_CASEFOLDED</li>
|
||||
<li>(stable) public static final int CHANGES_WHEN_TITLECASED</li>
|
||||
<li>(stable) public static final int CHANGES_WHEN_UPPERCASED</li>
|
||||
<li><span style='color:red'>*internal* </span>public static final int UNDEFINED</li>
|
||||
</ul>
|
||||
UScript
|
||||
<ul>
|
||||
<li>(stable) public static final int BAMUM</li>
|
||||
<li>(stable) public static final int LISU</li>
|
||||
<li>(stable) public static final int NAKHI_GEBA</li>
|
||||
<li>(stable) public static final int OLD_SOUTH_ARABIAN</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.text</h3>
|
||||
<ul>
|
||||
<li>(draft) public abstract class <i>CurrencyDisplayNames</i></li>
|
||||
<li>(draft) public class <i>CurrencyMetaInfo</i></li>
|
||||
<li>(draft) public static final class <i>CurrencyMetaInfo.CurrencyDigits</i></li>
|
||||
<li>(draft) public static final class <i>CurrencyMetaInfo.CurrencyFilter</i></li>
|
||||
<li>(draft) public static final class <i>CurrencyMetaInfo.CurrencyInfo</i></li>
|
||||
<li>(draft) public class <i>FilteredNormalizer2</i></li>
|
||||
<li>(draft) public abstract class <i>LocaleDisplayNames</i></li>
|
||||
<li>(draft) public static final class <i>LocaleDisplayNames.DialectHandling</i></li>
|
||||
<li>(draft) public abstract class <i>Normalizer2</i></li>
|
||||
<li>(draft) public static final class <i>Normalizer2.Mode</i></li>
|
||||
<li>(draft) public interface <i>RbnfLenientScanner</i></li>
|
||||
<li>(draft) public interface <i>RbnfLenientScannerProvider</i></li>
|
||||
<li><span style='color:red'>*internal* </span>public class <i>RbnfScannerProviderImpl</i></li>
|
||||
<li>(draft) public class <i>SelectFormat</i></li>
|
||||
<li>(draft) public interface <i>Transform</i></li>
|
||||
<li>(draft) public static final class <i>UnicodeSet.ComparisonStyle</i></li>
|
||||
<li>(draft) public static final class <i>UnicodeSet.SpanCondition</i></li>
|
||||
Collator
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>public Collator <i>setStrength2</i>(int)</li>
|
||||
</ul>
|
||||
DateIntervalInfo
|
||||
<ul>
|
||||
<li>(stable) public DateIntervalInfo <i>cloneAsThawed</i>()</li>
|
||||
<li>(stable) public DateIntervalInfo <i>freeze</i>()</li>
|
||||
</ul>
|
||||
DateTimePatternGenerator
|
||||
<ul>
|
||||
<li>(draft) public static final int MATCH_ALL_FIELDS_LENGTH</li>
|
||||
<li>(draft) public static final int MATCH_HOUR_FIELD_LENGTH</li>
|
||||
<li><span style='color:red'>*internal* </span>public static final int MATCH_MINUTE_FIELD_LENGTH</li>
|
||||
<li>(draft) public static final int MATCH_NO_OPTIONS</li>
|
||||
<li><span style='color:red'>*internal* </span>public static final int MATCH_SECOND_FIELD_LENGTH</li>
|
||||
<li>(stable) public DateTimePatternGenerator <i>cloneAsThawed</i>()</li>
|
||||
<li>(stable) public DateTimePatternGenerator <i>freeze</i>()</li>
|
||||
<li>(draft) public java.lang.String <i>getBestPattern</i>(java.lang.String, int)</li>
|
||||
<li><span style='color:red'>*internal* </span>public static DateTimePatternGenerator <i>getFrozenInstance</i>(ULocale)</li>
|
||||
<li>(draft) public java.lang.String <i>replaceFieldTypes</i>(java.lang.String, java.lang.String, int)</li>
|
||||
<li><span style='color:red'>*internal* </span>public boolean <i>skeletonsAreSimilar</i>(java.lang.String, java.lang.String)</li>
|
||||
</ul>
|
||||
DateTimePatternGenerator.VariableField
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>protected boolean <i>isNumeric</i>()</li>
|
||||
</ul>
|
||||
DecimalFormatSymbols
|
||||
<ul>
|
||||
<li>(draft) public static final int CURRENCY_SPC_SURROUNDING_MATCH</li>
|
||||
</ul>
|
||||
IndexCharacters
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>public <i>IndexCharacters</i>(ULocale, UnicodeSet, Collator)</li>
|
||||
</ul>
|
||||
Normalizer.Mode
|
||||
<ul>
|
||||
<li>(draft) public <i>Normalizer.Mode</i>()</li>
|
||||
<li><span style='color:red'>*internal* </span>protected abstract Normalizer2 <i>getNormalizer2</i>(int)</li>
|
||||
</ul>
|
||||
RuleBasedNumberFormat
|
||||
<ul>
|
||||
<li>(draft) public RbnfLenientScannerProvider <i>getLenientScannerProvider</i>()</li>
|
||||
<li>(draft) public void <i>setLenientScannerProvider</i>(RbnfLenientScannerProvider)</li>
|
||||
</ul>
|
||||
UnicodeSet
|
||||
<ul>
|
||||
<li>(draft) public <i>UnicodeSet</i>(int[])</li>
|
||||
<li>(stable) public UnicodeSet <i>add</i>(java.util.Collection)</li>
|
||||
<li>(draft) public UnicodeSet <i>addAll</i>(java.lang.String[])</li>
|
||||
<li>(stable) public UnicodeSet <i>addAll</i>(java.util.Collection)</li>
|
||||
<li>(draft) public java.lang.String[] <i>addAllTo</i>(java.lang.String[])</li>
|
||||
<li>(draft) public java.util.Collection <i>addAllTo</i>(T)</li>
|
||||
<li>(draft) public static java.util.Collection <i>addAllTo</i>(java.lang.Iterable, U)</li>
|
||||
<li><span style='color:red'>*internal* </span>public UnicodeSet <i>addBridges</i>(UnicodeSet)</li>
|
||||
<li>(draft) public static int <i>compare</i>(int, java.lang.String)</li>
|
||||
<li>(draft) public static int <i>compare</i>(java.lang.Iterable, java.lang.Iterable)</li>
|
||||
<li>(draft) public static int <i>compare</i>(java.lang.String, int)</li>
|
||||
<li>(draft) public static int <i>compare</i>(java.util.Collection, java.util.Collection, UnicodeSet.ComparisonStyle)</li>
|
||||
<li>(draft) public int <i>compareTo</i>(UnicodeSet)</li>
|
||||
<li>(draft) public int <i>compareTo</i>(UnicodeSet, UnicodeSet.ComparisonStyle)</li>
|
||||
<li>(draft) public int <i>compareTo</i>(java.lang.Iterable)</li>
|
||||
<li>(draft) public boolean <i>containsAll</i>(java.util.Collection)</li>
|
||||
<li>(draft) public boolean <i>containsNone</i>(java.util.Collection)</li>
|
||||
<li>(draft) public final boolean <i>containsSome</i>(java.util.Collection)</li>
|
||||
<li><span style='color:red'>*internal* </span>public int <i>findIn</i>(java.lang.CharSequence, int, boolean)</li>
|
||||
<li><span style='color:red'>*internal* </span>public int <i>findLastIn</i>(java.lang.CharSequence, int, boolean)</li>
|
||||
<li><span style='color:red'>*internal* </span>public static int <i>getSingleCodePoint</i>(java.lang.String)</li>
|
||||
<li>(draft) public java.util.Iterator <i>iterator</i>()</li>
|
||||
<li>(draft) public UnicodeSet <i>removeAll</i>(java.util.Collection)</li>
|
||||
<li>(draft) public UnicodeSet <i>retainAll</i>(java.util.Collection)</li>
|
||||
<li>(draft) public int <i>span</i>(java.lang.CharSequence, UnicodeSet.SpanCondition)</li>
|
||||
<li>(draft) public int <i>span</i>(java.lang.CharSequence, int, UnicodeSet.SpanCondition)</li>
|
||||
<li>(draft) public int <i>spanBack</i>(java.lang.CharSequence, UnicodeSet.SpanCondition)</li>
|
||||
<li>(draft) public int <i>spanBack</i>(java.lang.CharSequence, int, UnicodeSet.SpanCondition)</li>
|
||||
<li>(draft) public java.lang.Iterable <i>strings</i>()</li>
|
||||
<li><span style='color:red'>*internal* </span>public java.lang.String <i>stripFrom</i>(java.lang.CharSequence, boolean)</li>
|
||||
<li>(draft) public static java.lang.String[] <i>toArray</i>(UnicodeSet)</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<h3>Package com.ibm.icu.util</h3>
|
||||
<ul>
|
||||
<li>(draft) public class <i>LocaleMatcher</i></li>
|
||||
<li><span style='color:red'>*internal* </span>public static class <i>LocaleMatcher.LanguageMatcherData</i></li>
|
||||
<li>(draft) public class <i>LocalePriorityList</i></li>
|
||||
<li>(draft) public static class <i>LocalePriorityList.Builder</i></li>
|
||||
Calendar
|
||||
<ul>
|
||||
<li>(draft) public static final int IS_LEAP_MONTH</li>
|
||||
</ul>
|
||||
GlobalizationPreferences
|
||||
<ul>
|
||||
<li>(draft) public GlobalizationPreferences <i>cloneAsThawed</i>()</li>
|
||||
<li>(draft) public GlobalizationPreferences <i>freeze</i>()</li>
|
||||
</ul>
|
||||
HebrewCalendar
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>public static boolean <i>isLeapYear</i>(int)</li>
|
||||
</ul>
|
||||
LocaleData
|
||||
<ul>
|
||||
<li>(stable) public static VersionInfo <i>getCLDRVersion</i>()</li>
|
||||
</ul>
|
||||
TimeZone
|
||||
<ul>
|
||||
<li>(draft) public static final int GENERIC_LOCATION</li>
|
||||
<li>(draft) public static final int LONG_GENERIC</li>
|
||||
<li>(draft) public static final int LONG_GMT</li>
|
||||
<li>(draft) public static final int SHORT_COMMONLY_USED</li>
|
||||
<li>(draft) public static final int SHORT_GENERIC</li>
|
||||
<li>(draft) public static final int SHORT_GMT</li>
|
||||
<li>(draft) public static ICULogger TimeZoneLogger</li>
|
||||
</ul>
|
||||
ULocale
|
||||
<ul>
|
||||
<li>(draft) public static final char UNICODE_LOCALE_EXTENSION</li>
|
||||
<li>(draft) public java.lang.String <i>getDisplayLanguageWithDialect</i>()</li>
|
||||
<li>(draft) public java.lang.String <i>getDisplayLanguageWithDialect</i>(ULocale)</li>
|
||||
<li>(draft) public static java.lang.String <i>getDisplayLanguageWithDialect</i>(java.lang.String, ULocale)</li>
|
||||
<li>(draft) public static java.lang.String <i>getDisplayLanguageWithDialect</i>(java.lang.String, java.lang.String)</li>
|
||||
<li>(draft) public java.lang.String <i>getDisplayNameWithDialect</i>()</li>
|
||||
<li>(draft) public java.lang.String <i>getDisplayNameWithDialect</i>(ULocale)</li>
|
||||
<li>(draft) public static java.lang.String <i>getDisplayNameWithDialect</i>(java.lang.String, ULocale)</li>
|
||||
<li>(draft) public static java.lang.String <i>getDisplayNameWithDialect</i>(java.lang.String, java.lang.String)</li>
|
||||
<li>(draft) public java.util.Set <i>getUnicodeLocaleKeys</i>()</li>
|
||||
<li>(draft) public java.lang.String <i>getUnicodeLocaleType</i>(java.lang.String)</li>
|
||||
</ul>
|
||||
ULocale.Builder
|
||||
<ul>
|
||||
<li>(draft) public <i>ULocale.Builder</i>(boolean)</li>
|
||||
<li>(draft) public ULocale <i>build</i>()</li>
|
||||
<li>(draft) public boolean <i>isLenientVariant</i>()</li>
|
||||
<li>(draft) public ULocale.Builder <i>setUnicodeLocaleKeyword</i>(java.lang.String, java.lang.String)</li>
|
||||
</ul>
|
||||
UResourceBundle
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>protected UResourceBundle <i>findTopLevel</i>(int)</li>
|
||||
<li><span style='color:red'>*internal* </span>protected UResourceBundle <i>findTopLevel</i>(java.lang.String)</li>
|
||||
<li><span style='color:red'>*internal* </span>protected java.util.Set <i>handleKeySet</i>()</li>
|
||||
<li><span style='color:red'>*internal* </span>protected boolean <i>isTopLevelResource</i>()</li>
|
||||
<li><span style='color:red'>*internal* </span>public java.util.Set <i>keySet</i>()</li>
|
||||
</ul>
|
||||
VersionInfo
|
||||
<ul>
|
||||
<li><span style='color:red'>*internal* </span>public static final java.lang.String ICU_DATA_VERSION_PATH</li>
|
||||
<li>(stable) public static final VersionInfo UNICODE_5_2</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
<p><i><font size="-1">Contents generated by ReportAPI tool on Wed Mar 03 00:10:36 EST 2010<br/>Copyright (C) 2010, International Business Machines Corporation, All Rights Reserved.</font></i></p>
|
||||
</body>
|
||||
</html>
|
6
build.properties
Normal file
6
build.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
#*******************************************************************************
|
||||
#* Copyright (C) 2009-2010, International Business Machines Corporation and *
|
||||
#* others. All Rights Reserved. *
|
||||
#*******************************************************************************
|
||||
api.report.version = 44
|
||||
api.report.prev.version = 421
|
9
demos/.classpath
Normal file
9
demos/.classpath
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/icu4j-charset"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/icu4j-core"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/icu4j-translit"/>
|
||||
<classpathentry kind="output" path="out/bin"/>
|
||||
</classpath>
|
20
demos/.project
Normal file
20
demos/.project
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>icu4j-demos</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>icu4j-charset</project>
|
||||
<project>icu4j-core</project>
|
||||
<project>icu4j-shared</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
330
demos/.settings/org.eclipse.jdt.core.prefs
Normal file
330
demos/.settings/org.eclipse.jdt.core.prefs
Normal file
|
@ -0,0 +1,330 @@
|
|||
#Fri Aug 28 16:05:27 EDT 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=120
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=120
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
6
demos/.settings/org.eclipse.jdt.ui.prefs
Normal file
6
demos/.settings/org.eclipse.jdt.ui.prefs
Normal file
File diff suppressed because one or more lines are too long
5
demos/build.properties
Normal file
5
demos/build.properties
Normal file
|
@ -0,0 +1,5 @@
|
|||
#*******************************************************************************
|
||||
#* Copyright (C) 2009, International Business Machines Corporation and *
|
||||
#* others. All Rights Reserved. *
|
||||
#*******************************************************************************
|
||||
shared.dir = ../main/shared
|
29
demos/build.xml
Normal file
29
demos/build.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
-->
|
||||
<project name="demos" default="build" basedir=".">
|
||||
<property file="build-local.properties"/>
|
||||
<property file="build.properties"/>
|
||||
<import file="${shared.dir}/build/common-targets.xml"/>
|
||||
|
||||
<path id="javac.classpathref">
|
||||
<path refid="javac.classpathref.${ant.project.name}"/>
|
||||
</path>
|
||||
<property name="jar.file" value="${icu4j.demos.jar}"/>
|
||||
|
||||
<target name="build" depends="compile, copy, jar" description="Build the project"/>
|
||||
|
||||
<target name="build-all" depends="@build-all" description="Build the project including all dependencies"/>
|
||||
|
||||
<target name="clean" depends="@clean" description="Clean up the build outputs"/>
|
||||
|
||||
<target name="compile" depends="@compile" description="Compile java source files"/>
|
||||
|
||||
<target name="copy" depends="@copy" description="Copy non-java runtime files to the project's binary directory"/>
|
||||
|
||||
<target name="jar" depends="compile, copy, @jar" description="Create the project's jar file"/>
|
||||
|
||||
</project>
|
21
demos/demos-build.launch
Normal file
21
demos/demos-build.launch
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ant.AntLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/icu4j-demos/build.xml"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="icu4j-demos"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
|
||||
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTIES">
|
||||
<mapEntry key="eclipse.pdebuild.templates" value="/D:/eclipse-SDK-3.4.2-win32/eclipse/plugins/org.eclipse.pde.build_3.4.1.R34x_v20081217/templates/"/>
|
||||
<mapEntry key="eclipse.pdebuild.home" value="/D:/eclipse-SDK-3.4.2-win32/eclipse/plugins/org.eclipse.pde.build_3.4.1.R34x_v20081217/./"/>
|
||||
<mapEntry key="eclipse.pdebuild.scripts" value="/D:/eclipse-SDK-3.4.2-win32/eclipse/plugins/org.eclipse.pde.build_3.4.1.R34x_v20081217/scripts/"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTY_FILES" value="${workspace_loc:/icu4j-shared/build/locations-eclipse.properties},"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/icu4j-demos/build.xml}"/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
|
||||
</launchConfiguration>
|
13
demos/manifest.stub
Normal file
13
demos/manifest.stub
Normal file
|
@ -0,0 +1,13 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: com.ibm.icu.dev.demo.Launcher
|
||||
Class-Path: icu4j.jar
|
||||
|
||||
Name: com/ibm/icu/dev/demo
|
||||
Specification-Title: ICU for Java Demo
|
||||
Specification-Version: @SPECVERSION@
|
||||
Specification-Vendor: ICU
|
||||
Implementation-Title: ICU for Java Demo
|
||||
Implementation-Version: @IMPLVERSION@
|
||||
Implementation-Vendor: IBM Corporation
|
||||
Implementation-Vendor-Id: com.ibm
|
||||
Copyright-Info: @COPYRIGHT@
|
192
demos/src/com/ibm/icu/dev/demo/Launcher.java
Normal file
192
demos/src/com/ibm/icu/dev/demo/Launcher.java
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.Color;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DemoApplet;
|
||||
import com.ibm.icu.dev.demo.impl.DemoUtility;
|
||||
import com.ibm.icu.util.VersionInfo;
|
||||
|
||||
|
||||
/**
|
||||
* @author srl
|
||||
* Application to provide a panel of demos to launch
|
||||
*/
|
||||
public class Launcher extends DemoApplet {
|
||||
private static final long serialVersionUID = -8054963875776183877L;
|
||||
|
||||
/**
|
||||
* base package of all demos
|
||||
*/
|
||||
public static final String demoBase = "com.ibm.icu.dev.demo";
|
||||
/**
|
||||
* list of classes, relative to the demoBase. all must have a static void main(String[])
|
||||
*/
|
||||
public static final String demoList[] = {
|
||||
"calendar.CalendarApp",
|
||||
"charsetdet.DetectingViewer",
|
||||
"holiday.HolidayCalendarDemo",
|
||||
// "number.CurrencyDemo", -- console
|
||||
// "rbbi.DBBIDemo",
|
||||
// "rbbi.RBBIDemo",
|
||||
// "rbbi.TextBoundDemo",
|
||||
"rbnf.RbnfDemo",
|
||||
// "timescale.PivotDemo", -- console
|
||||
"translit.Demo",
|
||||
};
|
||||
|
||||
public class LauncherFrame extends Frame implements ActionListener {
|
||||
private static final long serialVersionUID = -8054963875776183878L;
|
||||
|
||||
public Button buttonList[] = new Button[demoList.length]; // one button for each demo
|
||||
public Label statusLabel;
|
||||
private DemoApplet applet;
|
||||
|
||||
LauncherFrame(DemoApplet applet) {
|
||||
init();
|
||||
this.applet = applet;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
// close down when close is clicked.
|
||||
// TODO: this should be factored..
|
||||
addWindowListener(
|
||||
new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
|
||||
if (applet != null) {
|
||||
applet.demoClosed();
|
||||
} else System.exit(0);
|
||||
}
|
||||
} );
|
||||
|
||||
setBackground(DemoUtility.bgColor);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
Panel topPanel = new Panel();
|
||||
topPanel.setLayout(new GridLayout(5,3));
|
||||
|
||||
for(int i=0;i<buttonList.length;i++) {
|
||||
String demo = demoList[i];
|
||||
Button b = new Button(demo);
|
||||
b.addActionListener(this);
|
||||
buttonList[i]=b;
|
||||
topPanel.add(b);
|
||||
}
|
||||
add(BorderLayout.CENTER,topPanel);
|
||||
statusLabel = new Label("");
|
||||
statusLabel.setAlignment(Label.LEFT);
|
||||
String javaVersion = "";
|
||||
try {
|
||||
javaVersion = "* Java: "+System.getProperty("java.version");
|
||||
} catch (Throwable t) {
|
||||
javaVersion = "";
|
||||
}
|
||||
add(BorderLayout.NORTH, new Label(
|
||||
"ICU Demos * ICU version "+VersionInfo.ICU_VERSION +
|
||||
" * http://icu-project.org "+javaVersion));
|
||||
add(BorderLayout.SOUTH,statusLabel);
|
||||
// set up an initial status.
|
||||
showStatus(buttonList.length+" demos ready. ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the 'status' field, and set it to black
|
||||
* @param status
|
||||
*/
|
||||
void showStatus(String status) {
|
||||
statusLabel.setText(status);
|
||||
statusLabel.setForeground(Color.BLACK);
|
||||
statusLabel.setBackground(Color.WHITE);
|
||||
// statusLabel.setFont(Font.PLAIN);
|
||||
doLayout();
|
||||
}
|
||||
void showStatus(String demo, String status) {
|
||||
showStatus(demo+": "+status);
|
||||
}
|
||||
void showFailure(String status) {
|
||||
statusLabel.setText(status);
|
||||
statusLabel.setBackground(Color.GRAY);
|
||||
statusLabel.setForeground(Color.RED);
|
||||
// statusLabel.setFont(Font.BOLD);
|
||||
doLayout();
|
||||
}
|
||||
void showFailure(String demo, String status) {
|
||||
showFailure(demo+": "+status);
|
||||
}
|
||||
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// find button
|
||||
for(int i=0;i<buttonList.length;i++) {
|
||||
if(e.getSource() == buttonList[i]) {
|
||||
String demoShort = demoList[i];
|
||||
String demo = demoBase+'.'+demoShort;
|
||||
showStatus(demoShort, "launching");
|
||||
try {
|
||||
Class c = Class.forName(demo);
|
||||
String args[] = new String[0];
|
||||
Class params[] = new Class[1];
|
||||
params[0] = args.getClass();
|
||||
Method m = c.getMethod("main", params );
|
||||
Object[] argList = { args };
|
||||
m.invoke(null, argList);
|
||||
showStatus(demoShort, "launched.");
|
||||
} catch (ClassNotFoundException e1) {
|
||||
showFailure(demoShort,e1.toString());
|
||||
e1.printStackTrace();
|
||||
} catch (SecurityException se) {
|
||||
showFailure(demoShort,se.toString());
|
||||
se.printStackTrace();
|
||||
} catch (NoSuchMethodException nsme) {
|
||||
showFailure(demoShort,nsme.toString());
|
||||
nsme.printStackTrace();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
showFailure(demoShort,iae.toString());
|
||||
iae.printStackTrace();
|
||||
} catch (IllegalAccessException iae) {
|
||||
showFailure(demoShort,iae.toString());
|
||||
iae.printStackTrace();
|
||||
} catch (InvocationTargetException ite) {
|
||||
showFailure(demoShort,ite.toString());
|
||||
ite.printStackTrace();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* This creates a Frame for the demo applet. */
|
||||
protected Frame createDemoFrame(DemoApplet applet) {
|
||||
return new LauncherFrame(applet);
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function which defines the behavior of the Demo
|
||||
* applet when an applet is started.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
new Launcher().showDemo();
|
||||
}
|
||||
}
|
37
demos/src/com/ibm/icu/dev/demo/calendar/CalendarApp.java
Normal file
37
demos/src/com/ibm/icu/dev/demo/calendar/CalendarApp.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.calendar;
|
||||
|
||||
import java.awt.Frame;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DemoApplet;
|
||||
|
||||
/**
|
||||
* CalendarApp demonstrates how Calendar works.
|
||||
*/
|
||||
public class CalendarApp extends DemoApplet
|
||||
{
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -4270137898405840825L;
|
||||
|
||||
/**
|
||||
* The main function which defines the behavior of the CalendarDemo
|
||||
* applet when an applet is started.
|
||||
*/
|
||||
public static void main(String argv[]) {
|
||||
|
||||
new CalendarApp().showDemo();
|
||||
}
|
||||
|
||||
/* This creates a CalendarFrame for the demo applet. */
|
||||
public Frame createDemoFrame(DemoApplet applet) {
|
||||
return new CalendarFrame(applet);
|
||||
}
|
||||
}
|
595
demos/src/com/ibm/icu/dev/demo/calendar/CalendarCalc.java
Normal file
595
demos/src/com/ibm/icu/dev/demo/calendar/CalendarCalc.java
Normal file
|
@ -0,0 +1,595 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.calendar;
|
||||
|
||||
import java.awt.Button;
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.CheckboxGroup;
|
||||
import java.awt.Choice;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.TextField;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DemoApplet;
|
||||
import com.ibm.icu.dev.demo.impl.DemoUtility;
|
||||
import com.ibm.icu.text.DateFormat;
|
||||
import com.ibm.icu.text.SimpleDateFormat;
|
||||
import com.ibm.icu.util.BuddhistCalendar;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
import com.ibm.icu.util.GregorianCalendar;
|
||||
import com.ibm.icu.util.HebrewCalendar;
|
||||
import com.ibm.icu.util.IslamicCalendar;
|
||||
import com.ibm.icu.util.JapaneseCalendar;
|
||||
import com.ibm.icu.util.TimeZone;
|
||||
|
||||
/**
|
||||
* CalendarCalc demonstrates how Date/Time formatter works.
|
||||
*/
|
||||
public class CalendarCalc extends DemoApplet
|
||||
{
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 4540103433916539296L;
|
||||
|
||||
/**
|
||||
* The main function which defines the behavior of the MultiCalendarDemo
|
||||
* applet when an applet is started.
|
||||
*/
|
||||
public static void main(String argv[]) {
|
||||
new CalendarCalc().showDemo();
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates a CalendarCalcFrame for the demo applet.
|
||||
*/
|
||||
public Frame createDemoFrame(DemoApplet applet) {
|
||||
return new CalendarCalcFrame(applet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Frame is a top-level window with a title. The default layout for a frame
|
||||
* is BorderLayout. The CalendarCalcFrame class defines the window layout of
|
||||
* MultiCalendarDemo.
|
||||
*/
|
||||
class CalendarCalcFrame extends Frame implements ActionListener
|
||||
{
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 8901485296258761846L;
|
||||
|
||||
static final Locale[] locales = DemoUtility.getG7Locales();
|
||||
|
||||
private DemoApplet applet;
|
||||
private long time = System.currentTimeMillis();
|
||||
|
||||
private static final RollAddField kRollAddFields[] = {
|
||||
new RollAddField(Calendar.YEAR, "Year" ),
|
||||
new RollAddField(Calendar.MONTH, "Month" ),
|
||||
new RollAddField(Calendar.WEEK_OF_MONTH, "Week of Month" ),
|
||||
new RollAddField(Calendar.WEEK_OF_YEAR, "Week of Year" ),
|
||||
new RollAddField(Calendar.DAY_OF_MONTH, "Day of Month" ),
|
||||
new RollAddField(Calendar.DAY_OF_WEEK, "Day of Week" ),
|
||||
new RollAddField(Calendar.DAY_OF_WEEK_IN_MONTH, "Day of Week in Month" ),
|
||||
new RollAddField(Calendar.DAY_OF_YEAR, "Day of Year" ),
|
||||
new RollAddField(Calendar.AM_PM, "AM/PM" ),
|
||||
new RollAddField(Calendar.HOUR_OF_DAY, "Hour of day" ),
|
||||
new RollAddField(Calendar.HOUR, "Hour" ),
|
||||
new RollAddField(Calendar.MINUTE, "Minute" ),
|
||||
new RollAddField(Calendar.SECOND, "Second" ),
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new CalendarCalcFrame that is initially invisible.
|
||||
*/
|
||||
public CalendarCalcFrame(DemoApplet applet)
|
||||
{
|
||||
super("Multiple Calendar Demo");
|
||||
this.applet = applet;
|
||||
init();
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the applet. You never need to call this directly, it
|
||||
* is called automatically by the system once the applet is created.
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
buildGUI();
|
||||
|
||||
patternText.setText( calendars[0].toPattern() );
|
||||
|
||||
// Force an update of the display
|
||||
cityChanged();
|
||||
millisFormat();
|
||||
enableEvents(KeyEvent.KEY_RELEASED);
|
||||
enableEvents(WindowEvent.WINDOW_CLOSING);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// package private
|
||||
//------------------------------------------------------------
|
||||
void addWithFont(Container container, Component foo, Font font) {
|
||||
if (font != null)
|
||||
foo.setFont(font);
|
||||
container.add(foo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to start the applet. You never need to call this method
|
||||
* directly, it is called when the applet's document is visited.
|
||||
*/
|
||||
public void start()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
TextField patternText;
|
||||
|
||||
Choice dateMenu;
|
||||
Choice localeMenu;
|
||||
|
||||
Button up;
|
||||
Button down;
|
||||
|
||||
Checkbox getRoll;
|
||||
Checkbox getAdd;
|
||||
|
||||
public void buildGUI()
|
||||
{
|
||||
setBackground(DemoUtility.bgColor);
|
||||
setLayout(new FlowLayout()); // shouldn't be necessary, but it is.
|
||||
|
||||
// TITLE
|
||||
Label label1=new Label("Calendar Converter", Label.CENTER);
|
||||
label1.setFont(DemoUtility.titleFont);
|
||||
add(label1);
|
||||
add(DemoUtility.createSpacer());
|
||||
|
||||
// IO Panel
|
||||
Panel topPanel = new Panel();
|
||||
topPanel.setLayout(new FlowLayout());
|
||||
|
||||
CheckboxGroup group1= new CheckboxGroup();
|
||||
|
||||
// Set up the controls for each calendar we're demonstrating
|
||||
for (int i = 0; i < calendars.length; i++)
|
||||
{
|
||||
Label label = new Label(calendars[i].name, Label.RIGHT);
|
||||
label.setFont(DemoUtility.labelFont);
|
||||
topPanel.add(label);
|
||||
|
||||
topPanel.add(calendars[i].text);
|
||||
|
||||
final int j = i;
|
||||
calendars[i].text.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
textChanged(j);
|
||||
}
|
||||
} );
|
||||
|
||||
calendars[i].rollAdd.setCheckboxGroup(group1);
|
||||
topPanel.add(calendars[i].rollAdd);
|
||||
}
|
||||
calendars[0].rollAdd.setState(true); // Make the first one selected
|
||||
|
||||
Label label4=new Label("Pattern", Label.RIGHT);
|
||||
label4.setFont(DemoUtility.labelFont);
|
||||
topPanel.add(label4);
|
||||
|
||||
patternText=new TextField(FIELD_COLUMNS);
|
||||
patternText.setFont(DemoUtility.editFont);
|
||||
topPanel.add(patternText);
|
||||
topPanel.add(new Label(""));
|
||||
|
||||
DemoUtility.fixGrid(topPanel,3);
|
||||
add(topPanel);
|
||||
add(DemoUtility.createSpacer());
|
||||
|
||||
// ROLL / ADD
|
||||
Panel rollAddPanel=new Panel();
|
||||
{
|
||||
rollAddPanel.setLayout(new FlowLayout());
|
||||
|
||||
Panel rollAddBoxes = new Panel();
|
||||
{
|
||||
rollAddBoxes.setLayout(new GridLayout(2,1));
|
||||
CheckboxGroup group2= new CheckboxGroup();
|
||||
getRoll = new Checkbox("Roll",group2, false);
|
||||
getAdd = new Checkbox("Add",group2, true);
|
||||
|
||||
rollAddBoxes.add(getRoll);
|
||||
rollAddBoxes.add(getAdd);
|
||||
}
|
||||
|
||||
Label dateLabel=new Label("Date Fields");
|
||||
dateLabel.setFont(DemoUtility.labelFont);
|
||||
|
||||
dateMenu= new Choice();
|
||||
dateMenu.setBackground(DemoUtility.choiceColor);
|
||||
for (int i = 0; i < kRollAddFields.length; i++) {
|
||||
dateMenu.addItem(kRollAddFields[i].name);
|
||||
if (kRollAddFields[i].field == Calendar.MONTH) {
|
||||
dateMenu.select(i);
|
||||
}
|
||||
}
|
||||
|
||||
Panel upDown = new Panel();
|
||||
{
|
||||
upDown.setLayout(new GridLayout(2,1));
|
||||
|
||||
// *** If the images are not found, we use the label.
|
||||
up = new Button("^");
|
||||
down = new Button("v");
|
||||
up.setBackground(DemoUtility.bgColor);
|
||||
down.setBackground(DemoUtility.bgColor);
|
||||
upDown.add(up);
|
||||
upDown.add(down);
|
||||
up.addActionListener(this);
|
||||
down.addActionListener(this);
|
||||
}
|
||||
|
||||
rollAddPanel.add(dateLabel);
|
||||
rollAddPanel.add(dateMenu);
|
||||
rollAddPanel.add(rollAddBoxes);
|
||||
rollAddPanel.add(upDown);
|
||||
|
||||
}
|
||||
Panel localePanel = new Panel();
|
||||
{
|
||||
// Make the locale popup menus
|
||||
localeMenu= new Choice();
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
int bestMatch = -1, thisMatch = -1;
|
||||
int selectMe = 0;
|
||||
|
||||
for (int i = 0; i < locales.length; i++) {
|
||||
if (i > 0 && locales[i].getLanguage().equals(locales[i-1].getLanguage()) ||
|
||||
i < locales.length - 1 &&
|
||||
locales[i].getLanguage().equals(locales[i+1].getLanguage()))
|
||||
{
|
||||
localeMenu.addItem( locales[i].getDisplayName() );
|
||||
} else {
|
||||
localeMenu.addItem( locales[i].getDisplayLanguage());
|
||||
}
|
||||
|
||||
thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale);
|
||||
|
||||
if (thisMatch >= bestMatch) {
|
||||
bestMatch = thisMatch;
|
||||
selectMe = i;
|
||||
}
|
||||
}
|
||||
|
||||
localeMenu.setBackground(DemoUtility.choiceColor);
|
||||
localeMenu.select(selectMe);
|
||||
|
||||
Label localeLabel =new Label("Display Locale");
|
||||
localeLabel.setFont(DemoUtility.labelFont);
|
||||
|
||||
localePanel.add(localeLabel);
|
||||
localePanel.add(localeMenu);
|
||||
DemoUtility.fixGrid(localePanel,2);
|
||||
|
||||
localeMenu.addItemListener( new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
Locale loc = locales[localeMenu.getSelectedIndex()];
|
||||
System.out.println("Change locale to " + loc.getDisplayName());
|
||||
|
||||
for (int i = 0; i < calendars.length; i++) {
|
||||
calendars[i].setLocale(loc);
|
||||
}
|
||||
millisFormat();
|
||||
}
|
||||
} );
|
||||
}
|
||||
add(rollAddPanel);
|
||||
add(DemoUtility.createSpacer());
|
||||
add(localePanel);
|
||||
add(DemoUtility.createSpacer());
|
||||
|
||||
// COPYRIGHT
|
||||
Panel copyrightPanel = new Panel();
|
||||
addWithFont (copyrightPanel,new Label(DemoUtility.copyright1, Label.LEFT),
|
||||
DemoUtility.creditFont);
|
||||
DemoUtility.fixGrid(copyrightPanel,1);
|
||||
add(copyrightPanel);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when users change the pattern text.
|
||||
*/
|
||||
public void setFormatFromPattern() {
|
||||
String timePattern = patternText.getText();
|
||||
|
||||
for (int i = 0; i < calendars.length; i++) {
|
||||
calendars[i].applyPattern(timePattern);
|
||||
}
|
||||
|
||||
millisFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when it is necessary to parse the time
|
||||
* string in one of the formatted date fields
|
||||
*/
|
||||
public void textChanged(int index) {
|
||||
String rightString = calendars[index].text.getText();
|
||||
|
||||
ParsePosition status = new ParsePosition(0);
|
||||
|
||||
if (rightString.length() == 0)
|
||||
{
|
||||
errorText("Error: no input to parse!");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Date date = calendars[index].format.parse(rightString, status);
|
||||
time = date.getTime();
|
||||
}
|
||||
catch (Exception e) {
|
||||
for (int i = 0; i < calendars.length; i++) {
|
||||
if (i != index) {
|
||||
calendars[i].text.setText("ERROR");
|
||||
}
|
||||
}
|
||||
errorText("Exception: " + e.getClass().toString() + " parsing: "+rightString);
|
||||
return;
|
||||
}
|
||||
|
||||
int start = calendars[index].text.getSelectionStart();
|
||||
int end = calendars[index].text.getSelectionEnd();
|
||||
|
||||
millisFormat();
|
||||
|
||||
calendars[index].text.select(start,end);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when it is necessary to format the time
|
||||
* in the "Millis" text field.
|
||||
*/
|
||||
public void millisFormat() {
|
||||
String out = "";
|
||||
|
||||
for (int i = 0; i < calendars.length; i++) {
|
||||
try {
|
||||
out = calendars[i].format.format(new Date(time));
|
||||
calendars[i].text.setText(out);
|
||||
}
|
||||
catch (Exception e) {
|
||||
calendars[i].text.setText("ERROR");
|
||||
errorText("Exception: " + e.getClass().toString() + " formatting "
|
||||
+ calendars[i].name + " " + time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is called when users change the pattern text.
|
||||
*/
|
||||
public void patternTextChanged() {
|
||||
setFormatFromPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when users select a new representative city.
|
||||
*/
|
||||
public void cityChanged() {
|
||||
TimeZone timeZone = TimeZone.getDefault();
|
||||
|
||||
for (int i = 0; i < calendars.length; i++) {
|
||||
calendars[i].format.setTimeZone(timeZone);
|
||||
}
|
||||
millisFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when users select a new time field
|
||||
* to add or roll its value.
|
||||
*/
|
||||
public void dateFieldChanged(boolean isUp) {
|
||||
int field = kRollAddFields[dateMenu.getSelectedIndex()].field;
|
||||
|
||||
for (int i = 0; i < calendars.length; i++)
|
||||
{
|
||||
if (calendars[i].rollAdd.getState())
|
||||
{
|
||||
Calendar c = calendars[i].calendar;
|
||||
c.setTime(new Date(time));
|
||||
|
||||
if (getAdd.getState()) {
|
||||
c.add(field, isUp ? 1 : -1);
|
||||
} else {
|
||||
c.roll(field, isUp);
|
||||
}
|
||||
|
||||
time = c.getTime().getTime();
|
||||
millisFormat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out the error message while debugging this program.
|
||||
*/
|
||||
public void errorText(String s)
|
||||
{
|
||||
if (true) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called if an action occurs in the CalendarCalcFrame object.
|
||||
*/
|
||||
public void actionPerformed(ActionEvent evt)
|
||||
{
|
||||
// *** Button events are handled here.
|
||||
Object obj = evt.getSource();
|
||||
System.out.println("action " + obj);
|
||||
if (obj instanceof Button) {
|
||||
if (evt.getSource() == up) {
|
||||
dateFieldChanged(false);
|
||||
} else
|
||||
if (evt.getSource() == down) {
|
||||
dateFieldChanged(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the event. Returns true if the event is handled and should not
|
||||
* be passed to the parent of this component. The default event handler
|
||||
* calls some helper methods to make life easier on the programmer.
|
||||
*/
|
||||
protected void processKeyEvent(KeyEvent evt)
|
||||
{
|
||||
System.out.println("key " + evt);
|
||||
if (evt.getID() == KeyEvent.KEY_RELEASED) {
|
||||
if (evt.getSource() == patternText) {
|
||||
patternTextChanged();
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < calendars.length; i++) {
|
||||
if (evt.getSource() == calendars[i].text) {
|
||||
textChanged(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void processWindowEvent(WindowEvent evt)
|
||||
{
|
||||
System.out.println("window " + evt);
|
||||
if (evt.getID() == WindowEvent.WINDOW_CLOSING &&
|
||||
evt.getSource() == this) {
|
||||
this.hide();
|
||||
this.dispose();
|
||||
|
||||
if (applet != null) {
|
||||
applet.demoClosed();
|
||||
} else System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
protected void processEvent(AWTEvent evt)
|
||||
{
|
||||
if (evt.getID() == AWTEvent. Event.ACTION_EVENT && evt.target == up) {
|
||||
dateFieldChanged(true);
|
||||
return true;
|
||||
}
|
||||
else if (evt.id == Event.ACTION_EVENT && evt.target == down) {
|
||||
dateFieldChanged(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private static final int FIELD_COLUMNS = 35;
|
||||
|
||||
|
||||
class CalendarRec {
|
||||
public CalendarRec(String nameStr, Calendar cal)
|
||||
{
|
||||
name = nameStr;
|
||||
calendar = cal;
|
||||
rollAdd = new Checkbox();
|
||||
|
||||
text = new JTextField("",FIELD_COLUMNS);
|
||||
text.setFont(DemoUtility.editFont);
|
||||
|
||||
format = DateFormat.getDateInstance(cal, DateFormat.FULL,
|
||||
Locale.getDefault());
|
||||
//format.applyPattern(DEFAULT_FORMAT);
|
||||
}
|
||||
|
||||
public void setLocale(Locale loc) {
|
||||
String pattern = toPattern();
|
||||
|
||||
format = DateFormat.getDateInstance(calendar, DateFormat.FULL,
|
||||
loc);
|
||||
applyPattern(pattern);
|
||||
}
|
||||
|
||||
public void applyPattern(String pattern) {
|
||||
if (format instanceof SimpleDateFormat) {
|
||||
((SimpleDateFormat)format).applyPattern(pattern);
|
||||
//hey {al} -
|
||||
// } else if (format instanceof java.text.SimpleDateFormat) {
|
||||
// ((java.text.SimpleDateFormat)format).applyPattern(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
private String toPattern() {
|
||||
if (format instanceof SimpleDateFormat) {
|
||||
return ((SimpleDateFormat)format).toPattern();
|
||||
//hey {al} -
|
||||
// } else if (format instanceof java.text.SimpleDateFormat) {
|
||||
// return ((java.text.SimpleDateFormat)format).toPattern();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Calendar calendar;
|
||||
DateFormat format;
|
||||
String name;
|
||||
JTextField text;
|
||||
Checkbox rollAdd;
|
||||
}
|
||||
|
||||
private final CalendarRec[] calendars = {
|
||||
new CalendarRec("Gregorian", new GregorianCalendar()),
|
||||
new CalendarRec("Hebrew", new HebrewCalendar()),
|
||||
new CalendarRec("Islamic (civil)", makeIslamic(true)),
|
||||
new CalendarRec("Islamic (true)", makeIslamic(false)),
|
||||
new CalendarRec("Buddhist", new BuddhistCalendar()),
|
||||
new CalendarRec("Japanese", new JapaneseCalendar()),
|
||||
// new CalendarRec("Chinese", new ChineseCalendar()),
|
||||
};
|
||||
|
||||
static private final Calendar makeIslamic(boolean civil) {
|
||||
IslamicCalendar cal = new IslamicCalendar();
|
||||
cal.setCivil(civil);
|
||||
return cal;
|
||||
}
|
||||
}
|
||||
|
||||
class RollAddField {
|
||||
RollAddField(int field, String name) {
|
||||
this.field = field;
|
||||
this.name = name;
|
||||
}
|
||||
int field;
|
||||
String name;
|
||||
}
|
442
demos/src/com/ibm/icu/dev/demo/calendar/CalendarFrame.java
Normal file
442
demos/src/com/ibm/icu/dev/demo/calendar/CalendarFrame.java
Normal file
|
@ -0,0 +1,442 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2007, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.calendar;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.Choice;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DemoApplet;
|
||||
import com.ibm.icu.dev.demo.impl.DemoUtility;
|
||||
import com.ibm.icu.text.DateFormat;
|
||||
import com.ibm.icu.util.BuddhistCalendar;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
import com.ibm.icu.util.GregorianCalendar;
|
||||
import com.ibm.icu.util.HebrewCalendar;
|
||||
import com.ibm.icu.util.IslamicCalendar;
|
||||
import com.ibm.icu.util.JapaneseCalendar;
|
||||
import com.ibm.icu.util.SimpleTimeZone;
|
||||
|
||||
/**
|
||||
* A Frame is a top-level window with a title. The default layout for a frame
|
||||
* is BorderLayout. The CalendarFrame class defines the window layout of
|
||||
* CalendarDemo.
|
||||
*/
|
||||
class CalendarFrame extends Frame
|
||||
{
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -4289697663503820619L;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private DemoApplet applet;
|
||||
|
||||
/**
|
||||
* Constructs a new CalendarFrame that is initially invisible.
|
||||
*/
|
||||
public CalendarFrame(DemoApplet myApplet)
|
||||
{
|
||||
super("Calendar Demo");
|
||||
this.applet = myApplet;
|
||||
init();
|
||||
|
||||
// When the window is closed, we want to shut down the applet or application
|
||||
addWindowListener(
|
||||
new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
setVisible(false);
|
||||
dispose();
|
||||
|
||||
if (applet != null) {
|
||||
applet.demoClosed();
|
||||
} else System.exit(0);
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private Choice displayMenu;
|
||||
private Locale[] locales = DemoUtility.getG7Locales();
|
||||
|
||||
private Calendar calendars[] = new Calendar[2];
|
||||
private Choice calMenu[] = new Choice[2];
|
||||
private ColoredLabel monthLabel[] = new ColoredLabel[2];
|
||||
private DateFormat monthFormat[] = new DateFormat[2];
|
||||
|
||||
private Button prevYear;
|
||||
private Button prevMonth;
|
||||
private Button gotoToday;
|
||||
private Button nextMonth;
|
||||
private Button nextYear;
|
||||
private CalendarPanel calendarPanel;
|
||||
|
||||
private static void add(Container container, Component component,
|
||||
GridBagLayout g, GridBagConstraints c,
|
||||
int gridwidth, int weightx)
|
||||
{
|
||||
c.gridwidth = gridwidth;
|
||||
c.weightx = weightx;
|
||||
g.setConstraints(component, c);
|
||||
container.add(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the applet. You never need to call this directly, it
|
||||
* is called automatically by the system once the applet is created.
|
||||
*/
|
||||
public void init() {
|
||||
setBackground(DemoUtility.bgColor);
|
||||
setLayout(new BorderLayout(10,10));
|
||||
|
||||
Panel topPanel = new Panel();
|
||||
GridBagLayout g = new GridBagLayout();
|
||||
topPanel.setLayout(g);
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
// Build the two menus for selecting which calendar is displayed,
|
||||
// plus the month/year label for each calendar
|
||||
for (int i = 0; i < 2; i++) {
|
||||
calMenu[i] = new Choice();
|
||||
for (int j = 0; j < CALENDARS.length; j++) {
|
||||
calMenu[i].addItem(CALENDARS[j].name);
|
||||
}
|
||||
calMenu[i].setBackground(DemoUtility.choiceColor);
|
||||
calMenu[i].select(i);
|
||||
calMenu[i].addItemListener(new CalMenuListener());
|
||||
|
||||
// Label for the current month name
|
||||
monthLabel[i] = new ColoredLabel("", COLORS[i]);
|
||||
monthLabel[i].setFont(DemoUtility.titleFont);
|
||||
|
||||
// And the default calendar to use for this slot
|
||||
calendars[i] = CALENDARS[i].calendar;
|
||||
|
||||
add(topPanel, calMenu[i], g, c, 5, 0);
|
||||
add(topPanel, monthLabel[i], g, c, GridBagConstraints.REMAINDER, 1);
|
||||
}
|
||||
|
||||
// Now add the next/previous year/month buttons:
|
||||
prevYear = new Button("<<");
|
||||
prevYear.addActionListener(new AddAction(Calendar.YEAR, -1));
|
||||
|
||||
prevMonth = new Button("<");
|
||||
prevMonth.addActionListener(new AddAction(Calendar.MONTH, -1));
|
||||
|
||||
gotoToday = new Button("Today");
|
||||
gotoToday.addActionListener( new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
calendarPanel.setDate( new Date() );
|
||||
updateMonthName();
|
||||
}
|
||||
} );
|
||||
|
||||
nextMonth = new Button(">");
|
||||
nextMonth.addActionListener(new AddAction(Calendar.MONTH, 1));
|
||||
|
||||
nextYear = new Button(">>");
|
||||
nextYear.addActionListener(new AddAction(Calendar.YEAR, 1));
|
||||
|
||||
c.fill = GridBagConstraints.NONE;
|
||||
add(topPanel, prevYear, g, c, 1, 0);
|
||||
add(topPanel, prevMonth, g, c, 1, 0);
|
||||
add(topPanel, gotoToday, g, c, 1, 0);
|
||||
add(topPanel, nextMonth, g, c, 1, 0);
|
||||
add(topPanel, nextYear, g, c, 1, 0);
|
||||
|
||||
// Now add the menu for selecting the display language
|
||||
Panel displayPanel = new Panel();
|
||||
{
|
||||
displayMenu = new Choice();
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
int bestMatch = -1, thisMatch = -1;
|
||||
int selectMe = 0;
|
||||
|
||||
for (int i = 0; i < locales.length; i++) {
|
||||
if (i > 0 &&
|
||||
locales[i].getLanguage().equals(locales[i-1].getLanguage()) ||
|
||||
i < locales.length - 1 &&
|
||||
locales[i].getLanguage().equals(locales[i+1].getLanguage()))
|
||||
{
|
||||
displayMenu.addItem( locales[i].getDisplayName() );
|
||||
} else {
|
||||
displayMenu.addItem( locales[i].getDisplayLanguage());
|
||||
}
|
||||
|
||||
thisMatch = DemoUtility.compareLocales(locales[i], defaultLocale);
|
||||
|
||||
if (thisMatch >= bestMatch) {
|
||||
bestMatch = thisMatch;
|
||||
selectMe = i;
|
||||
}
|
||||
}
|
||||
|
||||
displayMenu.setBackground(DemoUtility.choiceColor);
|
||||
displayMenu.select(selectMe);
|
||||
|
||||
displayMenu.addItemListener( new ItemListener()
|
||||
{
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
Locale loc = locales[displayMenu.getSelectedIndex()];
|
||||
calendarPanel.setLocale( loc );
|
||||
monthFormat[0] = monthFormat[1] = null;
|
||||
updateMonthName();
|
||||
repaint();
|
||||
}
|
||||
} );
|
||||
|
||||
Label l1 = new Label("Display Language:", Label.RIGHT);
|
||||
l1.setFont(DemoUtility.labelFont);
|
||||
|
||||
displayPanel.setLayout(new FlowLayout());
|
||||
displayPanel.add(l1);
|
||||
displayPanel.add(displayMenu);
|
||||
|
||||
}
|
||||
c.fill = GridBagConstraints.NONE;
|
||||
c.anchor = GridBagConstraints.EAST;
|
||||
|
||||
add(topPanel, displayPanel, g, c, GridBagConstraints.REMAINDER, 0);
|
||||
|
||||
// The title, buttons, etc. go in a panel at the top of the window
|
||||
add("North", topPanel);
|
||||
|
||||
// The copyright notice goes at the bottom of the window
|
||||
Label copyright = new Label(DemoUtility.copyright1, Label.LEFT);
|
||||
copyright.setFont(DemoUtility.creditFont);
|
||||
add("South", copyright);
|
||||
|
||||
// Now create the big calendar panel and stick it in the middle
|
||||
calendarPanel = new CalendarPanel( locales[displayMenu.getSelectedIndex()] );
|
||||
add("Center", calendarPanel);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
calendarPanel.setCalendar(i, calendars[i]);
|
||||
calendarPanel.setColor(i, COLORS[i]);
|
||||
}
|
||||
|
||||
updateMonthName();
|
||||
}
|
||||
|
||||
|
||||
private void updateMonthName()
|
||||
{
|
||||
for (int i = 0; i < 2; i++) {
|
||||
try {
|
||||
if (monthFormat[i] == null) { // TODO: optimize
|
||||
DateFormat f = DateFormat.getDateTimeInstance(
|
||||
calendars[i], DateFormat.MEDIUM, -1,
|
||||
locales[displayMenu.getSelectedIndex()]);
|
||||
if (f instanceof com.ibm.icu.text.SimpleDateFormat) {
|
||||
com.ibm.icu.text.SimpleDateFormat f1 = (com.ibm.icu.text.SimpleDateFormat) f;
|
||||
f1.applyPattern("MMMM, yyyy G");
|
||||
f1.setTimeZone(new SimpleTimeZone(0, "UTC"));
|
||||
}
|
||||
monthFormat[i] = f;
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
//hey {lw} - there's something wrong in this routine that cuases exceptions.
|
||||
System.out.println(e);
|
||||
}
|
||||
|
||||
monthLabel[i].setText( monthFormat[i].format( calendarPanel.firstOfMonth() ));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CalMenuListener responds to events in the two popup menus that select
|
||||
* the calendar systems to be used in the display. It figures out which
|
||||
* of the two menus the event occurred in and updates the corresponding
|
||||
* element of the calendars[] array to match the new selection.
|
||||
*/
|
||||
private class CalMenuListener implements ItemListener
|
||||
{
|
||||
public void itemStateChanged(ItemEvent e)
|
||||
{
|
||||
for (int i = 0; i < calMenu.length; i++)
|
||||
{
|
||||
if (e.getItemSelectable() == calMenu[i])
|
||||
{
|
||||
// We found the menu that the event happened in.
|
||||
// Figure out which new calendar they selected.
|
||||
Calendar newCal = CALENDARS[ calMenu[i].getSelectedIndex() ].calendar;
|
||||
|
||||
if (newCal != calendars[i])
|
||||
{
|
||||
// If any of the other menus are set to the same new calendar
|
||||
// we're about to use for this menu, set them to the current
|
||||
// calendar from *this* menu so we won't have two the same
|
||||
for (int j = 0; j < calendars.length; j++) {
|
||||
if (j != i && calendars[j] == newCal) {
|
||||
calendars[j] = calendars[i];
|
||||
calendarPanel.setCalendar(j, calendars[j]);
|
||||
monthFormat[j] = null;
|
||||
|
||||
for (int k = 0; k < CALENDARS.length; k++) {
|
||||
if (calendars[j] == CALENDARS[k].calendar) {
|
||||
calMenu[j].select(k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now update this menu to use the new calendar the user selected
|
||||
calendars[i] = newCal;
|
||||
calendarPanel.setCalendar(i, newCal);
|
||||
monthFormat[i] = null;
|
||||
|
||||
updateMonthName();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AddAction handles the next/previous year/month buttons...
|
||||
*/
|
||||
private class AddAction implements ActionListener {
|
||||
AddAction(int field, int amount) {
|
||||
this.field = field;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
calendarPanel.add(field, amount);
|
||||
updateMonthName();
|
||||
}
|
||||
|
||||
private int field, amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* ColoredLabel is similar to java.awt.Label, with two differences:
|
||||
*
|
||||
* - You can set its text color
|
||||
*
|
||||
* - It draws text using drawString rather than using a host-specific
|
||||
* "Peer" object like AWT does. On 1.2, using drawString gives
|
||||
* us Bidi reordering for free.
|
||||
*/
|
||||
static private class ColoredLabel extends Component {
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 5004484960341875722L;
|
||||
public ColoredLabel(String label) {
|
||||
text = label;
|
||||
}
|
||||
|
||||
public ColoredLabel(String label, Color c) {
|
||||
text = label;
|
||||
color = c;
|
||||
}
|
||||
|
||||
public void setText(String label) {
|
||||
text = label;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setFont(Font f) {
|
||||
font = f;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
FontMetrics fm = g.getFontMetrics(font);
|
||||
|
||||
Rectangle bounds = getBounds();
|
||||
|
||||
g.setColor(color);
|
||||
g.setFont(font);
|
||||
g.drawString(text, fm.stringWidth("\u00a0"),
|
||||
bounds.height/2 + fm.getHeight()
|
||||
- fm.getAscent() + fm.getLeading()/2);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return getMinimumSize();
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
FontMetrics fm = getFontMetrics(font);
|
||||
|
||||
return new Dimension( fm.stringWidth(text) + 2*fm.stringWidth("\u00a0"),
|
||||
fm.getHeight() + fm.getLeading()*2);
|
||||
}
|
||||
|
||||
String text;
|
||||
Color color = Color.black;
|
||||
Font font = DemoUtility.labelFont;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out the error message while debugging this program.
|
||||
*/
|
||||
public void errorText(String s)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
class CalendarRec {
|
||||
public CalendarRec(String nameStr, Calendar cal)
|
||||
{
|
||||
name = nameStr;
|
||||
calendar = cal;
|
||||
}
|
||||
|
||||
Calendar calendar;
|
||||
String name;
|
||||
}
|
||||
|
||||
private final CalendarRec[] CALENDARS = {
|
||||
new CalendarRec("Gregorian Calendar", new GregorianCalendar()),
|
||||
new CalendarRec("Hebrew Calendar", new HebrewCalendar()),
|
||||
new CalendarRec("Islamic Calendar", makeIslamic(false)),
|
||||
new CalendarRec("Islamic Civil Calendar ", makeIslamic(true)),
|
||||
new CalendarRec("Buddhist Calendar", new BuddhistCalendar()),
|
||||
new CalendarRec("Japanese Calendar", new JapaneseCalendar()),
|
||||
};
|
||||
|
||||
static private final Calendar makeIslamic(boolean civil) {
|
||||
IslamicCalendar cal = new IslamicCalendar();
|
||||
cal.setCivil(civil);
|
||||
return cal;
|
||||
}
|
||||
|
||||
static final Color[] COLORS = { Color.blue, Color.black };
|
||||
}
|
||||
|
365
demos/src/com/ibm/icu/dev/demo/calendar/CalendarPanel.java
Normal file
365
demos/src/com/ibm/icu/dev/demo/calendar/CalendarPanel.java
Normal file
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2007, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.calendar;
|
||||
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Point;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DemoUtility;
|
||||
import com.ibm.icu.text.DateFormatSymbols;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
import com.ibm.icu.util.SimpleTimeZone;
|
||||
|
||||
class CalendarPanel extends Canvas {
|
||||
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 625400018027387141L;
|
||||
|
||||
public CalendarPanel( Locale locale ) {
|
||||
setLocale(locale);
|
||||
}
|
||||
|
||||
public void setLocale(Locale locale) {
|
||||
if (fDisplayLocale == null || !fDisplayLocale.equals(locale)) {
|
||||
fDisplayLocale = locale;
|
||||
dirty = true;
|
||||
|
||||
for (int i = 0; i < fCalendar.length; i++) {
|
||||
if (fCalendar[i] != null) {
|
||||
fSymbols[i] = new DateFormatSymbols(fCalendar[i],
|
||||
fDisplayLocale);
|
||||
}
|
||||
}
|
||||
String lang = locale.getLanguage();
|
||||
leftToRight = !(lang.equals("iw") || lang.equals("ar"));
|
||||
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
fStartOfMonth = date;
|
||||
dirty = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void add(int field, int delta)
|
||||
{
|
||||
synchronized(fCalendar) {
|
||||
fCalendar[0].setTime(fStartOfMonth);
|
||||
fCalendar[0].add(field, delta);
|
||||
fStartOfMonth = fCalendar[0].getTime();
|
||||
}
|
||||
dirty = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setColor(int index, Color c) {
|
||||
fColor[index] = c;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void setCalendar(int index, Calendar c) {
|
||||
Date date = (fCalendar[index] == null) ? new Date()
|
||||
: fCalendar[index].getTime();
|
||||
|
||||
fCalendar[index] = c;
|
||||
fCalendar[index].setTime(date);
|
||||
|
||||
fSymbols[index] = new DateFormatSymbols(c, fDisplayLocale);
|
||||
dirty = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public Calendar getCalendar(int index) {
|
||||
return fCalendar[index];
|
||||
}
|
||||
|
||||
public Locale getDisplayLocale() {
|
||||
return fDisplayLocale;
|
||||
}
|
||||
|
||||
public Date firstOfMonth() {
|
||||
return fStartOfMonth;
|
||||
}
|
||||
|
||||
private Date startOfMonth(Date dateInMonth)
|
||||
{
|
||||
synchronized(fCalendar) {
|
||||
fCalendar[0].setTime(dateInMonth);
|
||||
|
||||
int era = fCalendar[0].get(Calendar.ERA);
|
||||
int year = fCalendar[0].get(Calendar.YEAR);
|
||||
int month = fCalendar[0].get(Calendar.MONTH);
|
||||
|
||||
fCalendar[0].clear();
|
||||
fCalendar[0].set(Calendar.ERA, era);
|
||||
fCalendar[0].set(Calendar.YEAR, year);
|
||||
fCalendar[0].set(Calendar.MONTH, month);
|
||||
fCalendar[0].set(Calendar.DATE, 1);
|
||||
|
||||
return fCalendar[0].getTime();
|
||||
}
|
||||
}
|
||||
|
||||
private void calculate()
|
||||
{
|
||||
//
|
||||
// As a workaround for JDK 1.1.3 and below, where Calendars and time
|
||||
// zones are a bit goofy, always set my calendar's time zone to UTC.
|
||||
// You would think I would want to do this in the "set" function above,
|
||||
// but if I do that, the program hangs when this class is loaded,
|
||||
// perhaps due to some sort of static initialization ordering problem.
|
||||
// So I do it here instead.
|
||||
//
|
||||
fCalendar[0].setTimeZone(new SimpleTimeZone(0, "UTC"));
|
||||
|
||||
Calendar c = (Calendar)fCalendar[0].clone(); // Temporary copy
|
||||
|
||||
fStartOfMonth = startOfMonth(fStartOfMonth);
|
||||
|
||||
// Stash away a few useful constants for this calendar and display
|
||||
minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
|
||||
daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
|
||||
|
||||
firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
|
||||
|
||||
// Stash away a Date for the start of this month
|
||||
|
||||
// Find the day of week of the first day in this month
|
||||
c.setTime(fStartOfMonth);
|
||||
firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
|
||||
int firstWeek = c.get(Calendar.WEEK_OF_MONTH);
|
||||
|
||||
// Now find the # of days in the month
|
||||
c.roll(Calendar.DATE, false);
|
||||
daysInMonth = c.get(Calendar.DATE);
|
||||
|
||||
// Finally, find the end of the month, i.e. the start of the next one
|
||||
c.roll(Calendar.DATE, true);
|
||||
c.add(Calendar.MONTH, 1);
|
||||
c.getTime(); // JDK 1.1.2 bug workaround
|
||||
c.add(Calendar.SECOND, -1);
|
||||
Date endOfMonth = c.getTime();
|
||||
if(endOfMonth==null){
|
||||
//do nothing
|
||||
}
|
||||
endOfMonth = null;
|
||||
int lastWeek = c.get(Calendar.WEEK_OF_MONTH);
|
||||
|
||||
// Calculate the number of full or partial weeks in this month.
|
||||
numWeeks = lastWeek - firstWeek + 1;
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
static final int XINSET = 4;
|
||||
static final int YINSET = 2;
|
||||
|
||||
/*
|
||||
* Convert from the day number within a month (1-based)
|
||||
* to the cell coordinates on the calendar (0-based)
|
||||
*/
|
||||
private void dateToCell(int date, Point pos)
|
||||
{
|
||||
int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
|
||||
if (firstDayInMonth < firstDayOfWeek) {
|
||||
cell += daysInWeek;
|
||||
}
|
||||
|
||||
pos.x = cell % daysInWeek;
|
||||
pos.y = cell / daysInWeek;
|
||||
}
|
||||
//private Point dateToCell(int date) {
|
||||
// Point p = new Point(0,0);
|
||||
// dateToCell(date, p);
|
||||
// return p;
|
||||
//}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
|
||||
if (dirty) {
|
||||
calculate();
|
||||
}
|
||||
|
||||
Point cellPos = new Point(0,0); // Temporary variable
|
||||
Dimension d = this.getSize();
|
||||
|
||||
g.setColor(Color.lightGray);
|
||||
g.fillRect(0,0,d.width,d.height);
|
||||
|
||||
// Draw the day names at the top
|
||||
g.setColor(Color.black);
|
||||
g.setFont(DemoUtility.labelFont);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int labelHeight = fm.getHeight() + YINSET * 2;
|
||||
|
||||
int v = fm.getAscent() + YINSET;
|
||||
for (int i = 0; i < daysInWeek; i++) {
|
||||
int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
|
||||
String dayName = fSymbols[0].getWeekdays()[dayNum];
|
||||
|
||||
|
||||
double h;
|
||||
if (leftToRight) {
|
||||
h = d.width*(i + 0.5) / daysInWeek;
|
||||
} else {
|
||||
h = d.width*(daysInWeek - i - 0.5) / daysInWeek;
|
||||
}
|
||||
h -= fm.stringWidth(dayName) / 2;
|
||||
|
||||
g.drawString(dayName, (int)h, v);
|
||||
}
|
||||
|
||||
double cellHeight = (d.height - labelHeight - 1) / numWeeks;
|
||||
double cellWidth = (double)(d.width - 1) / daysInWeek;
|
||||
|
||||
// Draw a white background in the part of the calendar
|
||||
// that displays this month.
|
||||
// First figure out how much of the first week should be shaded.
|
||||
{
|
||||
g.setColor(Color.white);
|
||||
dateToCell(1, cellPos);
|
||||
int width = (int)(cellPos.x*cellWidth); // Width of unshaded area
|
||||
|
||||
if (leftToRight) {
|
||||
g.fillRect((int)(width), labelHeight ,
|
||||
d.width - width, (int)cellHeight);
|
||||
} else {
|
||||
g.fillRect(0, labelHeight ,
|
||||
d.width - width, (int)cellHeight);
|
||||
}
|
||||
|
||||
// All of the intermediate weeks get shaded completely
|
||||
g.fillRect(0, (int)(labelHeight + cellHeight),
|
||||
d.width, (int)(cellHeight * (numWeeks - 2)));
|
||||
|
||||
// Now figure out the last week.
|
||||
dateToCell(daysInMonth, cellPos);
|
||||
width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area
|
||||
|
||||
if (leftToRight) {
|
||||
g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
|
||||
width, (int)cellHeight);
|
||||
} else {
|
||||
g.fillRect(d.width - width, (int)(labelHeight + (numWeeks-1) * cellHeight),
|
||||
width, (int)cellHeight);
|
||||
}
|
||||
|
||||
}
|
||||
// Draw the X/Y grid lines
|
||||
g.setColor(Color.black);
|
||||
for (int i = 0; i <= numWeeks; i++) {
|
||||
int y = (int)(labelHeight + i * cellHeight);
|
||||
g.drawLine(0, y, d.width - 1, y);
|
||||
}
|
||||
for (int i = 0; i <= daysInWeek; i++) {
|
||||
int x = (int)(i * cellWidth);
|
||||
g.drawLine(x, labelHeight, x, d.height - 1);
|
||||
}
|
||||
|
||||
// Now loop through all of the days in the month, figure out where
|
||||
// they go in the grid, and draw the day # for each one
|
||||
|
||||
// Figure out the date of the first cell in the calendar display
|
||||
int cell = (1 + firstDayInMonth - firstDayOfWeek - minDay);
|
||||
if (firstDayInMonth < firstDayOfWeek) {
|
||||
cell += daysInWeek;
|
||||
}
|
||||
|
||||
Calendar c = (Calendar)fCalendar[0].clone();
|
||||
c.setTime(fStartOfMonth);
|
||||
c.add(Calendar.DATE, -cell);
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
for (int row = 0; row < numWeeks; row++) {
|
||||
for (int col = 0; col < daysInWeek; col++) {
|
||||
|
||||
g.setFont(DemoUtility.numberFont);
|
||||
g.setColor(Color.black);
|
||||
fm = g.getFontMetrics();
|
||||
|
||||
int cellx;
|
||||
if (leftToRight) {
|
||||
cellx = (int)((col) * cellWidth);
|
||||
} else {
|
||||
cellx = (int)((daysInWeek - col - 1) * cellWidth);
|
||||
}
|
||||
|
||||
int celly = (int)(row * cellHeight + labelHeight);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
fCalendar[i].setTime(c.getTime());
|
||||
|
||||
int date = fCalendar[i].get(Calendar.DATE);
|
||||
buffer.setLength(0);
|
||||
buffer.append(date);
|
||||
String dayNum = buffer.toString();
|
||||
|
||||
int x;
|
||||
|
||||
if (leftToRight) {
|
||||
x = cellx + (int)cellWidth - XINSET - fm.stringWidth(dayNum);
|
||||
} else {
|
||||
x = cellx + XINSET;
|
||||
}
|
||||
int y = celly + + fm.getAscent() + YINSET + i * fm.getHeight();
|
||||
|
||||
if (fColor[i] != null) {
|
||||
g.setColor(fColor[i]);
|
||||
}
|
||||
g.drawString(dayNum, x, y);
|
||||
|
||||
if (date == 1 || row == 0 && col == 0) {
|
||||
g.setFont(DemoUtility.numberFont);
|
||||
String month = fSymbols[i].getMonths()[
|
||||
fCalendar[i].get(Calendar.MONTH)];
|
||||
|
||||
if (leftToRight) {
|
||||
x = cellx + XINSET;
|
||||
} else {
|
||||
x = cellx + (int)cellWidth - XINSET - fm.stringWidth(month);
|
||||
}
|
||||
g.drawString(month, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
c.add(Calendar.DATE, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Important state variables
|
||||
private Calendar[] fCalendar = new Calendar[4];
|
||||
private Color[] fColor = new Color[4];
|
||||
|
||||
private Locale fDisplayLocale;
|
||||
private DateFormatSymbols[] fSymbols = new DateFormatSymbols[4];
|
||||
|
||||
private Date fStartOfMonth = new Date(); // 00:00:00 on first day of month
|
||||
|
||||
// Cached calculations to make drawing faster.
|
||||
private transient int minDay; // Minimum legal day #
|
||||
private transient int daysInWeek; // # of days in a week
|
||||
private transient int firstDayOfWeek; // First day to display in week
|
||||
private transient int numWeeks; // # full or partial weeks in month
|
||||
private transient int daysInMonth; // # days in this month
|
||||
private transient int firstDayInMonth; // Day of week of first day in month
|
||||
private transient boolean leftToRight;
|
||||
|
||||
private transient boolean dirty = true;
|
||||
}
|
12
demos/src/com/ibm/icu/dev/demo/calendar/package.html
Normal file
12
demos/src/com/ibm/icu/dev/demo/calendar/package.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<!-- Copyright (C) 2000-2004, International Business Machines Corporation and
|
||||
others. All Rights Reserved.
|
||||
|
||||
-->
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
Calendar demo applications including date/time arithmetic.
|
||||
</body>
|
||||
</html>
|
421
demos/src/com/ibm/icu/dev/demo/charsetdet/DetectingViewer.java
Normal file
421
demos/src/com/ibm/icu/dev/demo/charsetdet/DetectingViewer.java
Normal file
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
**************************************************************************
|
||||
* Copyright (C) 2005-2010, International Business Machines Corporation *
|
||||
* and others. All Rights Reserved. *
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.charsetdet;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.AccessControlException;
|
||||
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import com.ibm.icu.charset.CharsetICU;
|
||||
import com.ibm.icu.dev.demo.impl.DemoApplet;
|
||||
import com.ibm.icu.text.CharsetDetector;
|
||||
import com.ibm.icu.text.CharsetMatch;
|
||||
|
||||
/**
|
||||
* This simple application demonstrates how to use the CharsetDetector API. It
|
||||
* opens a file or web page, detects the encoding, and then displays it using that
|
||||
* encoding.
|
||||
*/
|
||||
public class DetectingViewer extends JFrame implements ActionListener
|
||||
{
|
||||
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -2307065724464747775L;
|
||||
private JTextPane text;
|
||||
private JFileChooser fileChooser;
|
||||
|
||||
/**
|
||||
* @throws java.awt.HeadlessException
|
||||
*/
|
||||
public DetectingViewer()
|
||||
{
|
||||
super();
|
||||
DemoApplet.demoFrameOpened();
|
||||
|
||||
try {
|
||||
fileChooser = new JFileChooser();
|
||||
} catch (AccessControlException ace) {
|
||||
System.err.println("no file chooser - access control exception. Continuing without file browsing. "+ace.toString());
|
||||
fileChooser = null; //
|
||||
}
|
||||
|
||||
// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setSize(800, 800);
|
||||
|
||||
setJMenuBar(makeMenus());
|
||||
text = new JTextPane();
|
||||
text.setContentType("text/plain");
|
||||
text.setText("");
|
||||
text.setSize(800, 800);
|
||||
|
||||
Font font = new Font("Arial Unicode MS", Font.PLAIN, 24);
|
||||
text.setFont(font);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane(text);
|
||||
|
||||
getContentPane().add(scrollPane);
|
||||
setVisible(true);
|
||||
|
||||
addWindowListener(
|
||||
new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
// setVisible(false);
|
||||
// dispose();
|
||||
|
||||
doQuit();
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
String cmd = event.getActionCommand();
|
||||
|
||||
if (cmd.equals("New...")) {
|
||||
doNew();
|
||||
} else if (cmd.equals("Open File...")) {
|
||||
doOpenFile();
|
||||
} else if (cmd.equals("Open URL...")) {
|
||||
doOpenURL();
|
||||
} else if (cmd.equals("Quit")) {
|
||||
doQuit();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DetectingViewer();
|
||||
}
|
||||
|
||||
private void errorDialog(String title, String msg)
|
||||
{
|
||||
JOptionPane.showMessageDialog(this, msg, title, JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
private BufferedInputStream openFile(File file)
|
||||
{
|
||||
FileInputStream fileStream = null;
|
||||
|
||||
try {
|
||||
fileStream = new FileInputStream(file);
|
||||
} catch (Exception e) {
|
||||
errorDialog("Error Opening File", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BufferedInputStream(fileStream);
|
||||
}
|
||||
|
||||
// private void openFile(String directory, String filename)
|
||||
// {
|
||||
// openFile(new File(directory, filename));
|
||||
// }
|
||||
|
||||
|
||||
private BufferedInputStream openURL(String url)
|
||||
{
|
||||
InputStream s = null;
|
||||
|
||||
try {
|
||||
URL aURL = new URL(url);
|
||||
s = aURL.openStream();
|
||||
} catch (Exception e) {
|
||||
errorDialog("Error Opening URL", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BufferedInputStream(s);
|
||||
}
|
||||
|
||||
private String encodingName(CharsetMatch match)
|
||||
{
|
||||
return match.getName() + " (" + match.getLanguage() + ")";
|
||||
}
|
||||
|
||||
private void setMatchMenu(CharsetMatch[] matches)
|
||||
{
|
||||
JMenu menu = getJMenuBar().getMenu(1);
|
||||
JMenuItem menuItem;
|
||||
|
||||
menu.removeAll();
|
||||
|
||||
for (int i = 0; i < matches.length; i += 1) {
|
||||
CharsetMatch match = matches[i];
|
||||
|
||||
menuItem = new JMenuItem(encodingName(match) + " " + match.getConfidence());
|
||||
|
||||
menu.add(menuItem);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] scriptTag = {(byte) 's', (byte) 'c', (byte) 'r', (byte) 'i', (byte) 'p', (byte) 't'};
|
||||
private byte[] styleTag = {(byte) 's', (byte) 't', (byte) 'y', (byte) 'l', (byte) 'e'};
|
||||
private static int BUFFER_SIZE = 100000;
|
||||
|
||||
private boolean openTag(byte[] buffer, int offset, int length, byte[] tag)
|
||||
{
|
||||
int tagLen = tag.length;
|
||||
int bufRem = length - offset;
|
||||
int b;
|
||||
|
||||
for (b = 0; b < tagLen && b < bufRem; b += 1) {
|
||||
if (buffer[b + offset] != tag[b]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return b == tagLen;
|
||||
}
|
||||
|
||||
private boolean closedTag(byte[] buffer, int offset, int length, byte[] tag)
|
||||
{
|
||||
if (buffer[offset] != (byte) '/') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return openTag(buffer, offset + 1, length, tag);
|
||||
}
|
||||
|
||||
private byte[] filter(InputStream in)
|
||||
{
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int bytesRemaining = BUFFER_SIZE;
|
||||
int bufLen = 0;
|
||||
|
||||
in.mark(BUFFER_SIZE);
|
||||
|
||||
try {
|
||||
while (bytesRemaining > 0) {
|
||||
int bytesRead = in.read(buffer, bufLen, bytesRemaining);
|
||||
|
||||
if (bytesRead <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
bufLen += bytesRead;
|
||||
bytesRemaining -= bytesRead;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO: error handling?
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean inTag = false;
|
||||
boolean skip = false;
|
||||
int out = 0;
|
||||
|
||||
for (int i = 0; i < bufLen; i += 1) {
|
||||
byte b = buffer[i];
|
||||
|
||||
if (b == (byte) '<') {
|
||||
inTag = true;
|
||||
|
||||
if (openTag(buffer, i + 1, bufLen, scriptTag) ||
|
||||
openTag(buffer, i + 1, bufLen, styleTag)) {
|
||||
skip = true;
|
||||
} else if (closedTag(buffer, i + 1, bufLen, scriptTag) ||
|
||||
closedTag(buffer, i + 1, bufLen, styleTag)) {
|
||||
skip = false;
|
||||
}
|
||||
} else if (b == (byte) '>') {
|
||||
inTag = false;
|
||||
} else if (! (inTag || skip)) {
|
||||
buffer[out++] = b;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] filtered = new byte[out];
|
||||
|
||||
System.arraycopy(buffer, 0, filtered, 0, out);
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private CharsetMatch[] detect(byte[] bytes)
|
||||
{
|
||||
CharsetDetector det = new CharsetDetector();
|
||||
|
||||
det.setText(bytes);
|
||||
|
||||
return det.detectAll();
|
||||
}
|
||||
|
||||
private CharsetMatch[] detect(BufferedInputStream inputStream)
|
||||
{
|
||||
CharsetDetector det = new CharsetDetector();
|
||||
|
||||
try {
|
||||
det.setText(inputStream);
|
||||
|
||||
return det.detectAll();
|
||||
} catch (Exception e) {
|
||||
// TODO: error message?
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void show(InputStream inputStream, CharsetMatch[] matches, String title)
|
||||
{
|
||||
InputStreamReader isr;
|
||||
char[] buffer = new char[1024];
|
||||
int bytesRead = 0;
|
||||
|
||||
if (matches == null || matches.length == 0) {
|
||||
errorDialog("Match Error", "No matches!");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
String encoding = matches[0].getName();
|
||||
|
||||
inputStream.reset();
|
||||
|
||||
if (encoding.startsWith("UTF-32")) {
|
||||
byte[] bytes = new byte[1024];
|
||||
int offset = 0;
|
||||
int chBytes = 0;
|
||||
Charset utf32 = CharsetICU.forNameICU(encoding);
|
||||
|
||||
while ((bytesRead = inputStream.read(bytes, offset, 1024)) >= 0) {
|
||||
offset = bytesRead % 4;
|
||||
chBytes = bytesRead - offset;
|
||||
|
||||
sb.append(utf32.decode(ByteBuffer.wrap(bytes)).toString());
|
||||
|
||||
if (offset != 0) {
|
||||
for (int i = 0; i < offset; i += 1) {
|
||||
bytes[i] = bytes[chBytes + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isr = new InputStreamReader(inputStream, encoding);
|
||||
|
||||
while ((bytesRead = isr.read(buffer, 0, 1024)) >= 0) {
|
||||
sb.append(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
isr.close();
|
||||
}
|
||||
|
||||
this.setTitle(title + " - " + encodingName(matches[0]));
|
||||
|
||||
setMatchMenu(matches);
|
||||
text.setText(sb.toString());
|
||||
} catch (IOException e) {
|
||||
errorDialog("IO Error", e.getMessage());
|
||||
} catch (Exception e) {
|
||||
errorDialog("Internal Error", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void doNew()
|
||||
{
|
||||
// open a new window...
|
||||
}
|
||||
|
||||
private void doOpenFile()
|
||||
{
|
||||
int retVal = fileChooser.showOpenDialog(this);
|
||||
|
||||
if (retVal == JFileChooser.APPROVE_OPTION) {
|
||||
File file = fileChooser.getSelectedFile();
|
||||
BufferedInputStream inputStream = openFile(file);
|
||||
|
||||
if (inputStream != null) {
|
||||
CharsetMatch[] matches = detect(inputStream);
|
||||
|
||||
show(inputStream, matches, file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doOpenURL()
|
||||
{
|
||||
String url = (String) JOptionPane.showInputDialog(this, "URL to open:", "Open URL", JOptionPane.PLAIN_MESSAGE,
|
||||
null, null, null);
|
||||
|
||||
if (url != null && url.length() > 0) {
|
||||
BufferedInputStream inputStream = openURL(url);
|
||||
|
||||
if (inputStream != null) {
|
||||
byte[] filtered = filter(inputStream);
|
||||
CharsetMatch[] matches = detect(filtered);
|
||||
|
||||
show(inputStream, matches, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void doQuit()
|
||||
{
|
||||
DemoApplet.demoFrameClosed();
|
||||
this.setVisible(false);
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
private JMenuBar makeMenus()
|
||||
{
|
||||
JMenu menu = new JMenu("File");
|
||||
JMenuItem mi;
|
||||
|
||||
mi = new JMenuItem("Open File...");
|
||||
mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK)));
|
||||
mi.addActionListener(this);
|
||||
menu.add(mi);
|
||||
if(fileChooser == null) {
|
||||
mi.setEnabled(false); // no file chooser.
|
||||
}
|
||||
|
||||
mi = new JMenuItem("Open URL...");
|
||||
mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_U, ActionEvent.CTRL_MASK)));
|
||||
mi.addActionListener(this);
|
||||
menu.add(mi);
|
||||
|
||||
mi = new JMenuItem("Quit");
|
||||
mi.setAccelerator((KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK)));
|
||||
mi.addActionListener(this);
|
||||
menu.add(mi);
|
||||
|
||||
JMenuBar mbar = new JMenuBar();
|
||||
mbar.add(menu);
|
||||
|
||||
menu = new JMenu("Detected Encodings");
|
||||
mbar.add(menu);
|
||||
|
||||
return mbar;
|
||||
}
|
||||
}
|
552
demos/src/com/ibm/icu/dev/demo/holiday/HolidayBorderPanel.java
Normal file
552
demos/src/com/ibm/icu/dev/demo/holiday/HolidayBorderPanel.java
Normal file
|
@ -0,0 +1,552 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.holiday;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Panel;
|
||||
|
||||
/**
|
||||
* Various graphical borders. The border itself is a Panel so that it can
|
||||
* contain other Components (i.e. it borders something). You use the
|
||||
* HolidayBorderPanel like any other Panel: you set the layout that you prefer and
|
||||
* add Components to it. Beware that a null layout does not obey the insets
|
||||
* of the panel so if you use null layouts, adjust your measurements to
|
||||
* handle the border by calling insets().
|
||||
*
|
||||
* @author Andy Clark, Taligent Inc.
|
||||
* @version 1.0
|
||||
*/
|
||||
public class HolidayBorderPanel extends Panel {
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 4669213306492461159L;
|
||||
// Constants
|
||||
|
||||
/** Solid border. */
|
||||
public final static int SOLID = 0;
|
||||
/** A raised border. */
|
||||
public final static int RAISED = 1;
|
||||
/** A lowered border. */
|
||||
public final static int LOWERED = 2;
|
||||
/** An etched in border. */
|
||||
public final static int IN = 3;
|
||||
/** An etched out border. */
|
||||
public final static int OUT = 4;
|
||||
|
||||
/** Left alignment. */
|
||||
public final static int LEFT = 0;
|
||||
/** Center alignment. */
|
||||
public final static int CENTER = 1;
|
||||
/** Right alignment. */
|
||||
public final static int RIGHT = 2;
|
||||
|
||||
/** Default style (IN). */
|
||||
public final static int DEFAULT_STYLE = IN;
|
||||
/** Default thickness (10). */
|
||||
public final static int DEFAULT_THICKNESS = 10;
|
||||
/** Default thickness for solid borders (4). */
|
||||
public final static int DEFAULT_SOLID_THICKNESS = 4;
|
||||
/** Default thickness for raised borders (2). */
|
||||
public final static int DEFAULT_RAISED_THICKNESS = 2;
|
||||
/** Default thickness for lowered borders (2). */
|
||||
public final static int DEFAULT_LOWERED_THICKNESS = 2;
|
||||
/** Default thickness for etched-in borders (10). */
|
||||
public final static int DEFAULT_IN_THICKNESS = 10;
|
||||
/** Default thickness for etched-out borders (10). */
|
||||
public final static int DEFAULT_OUT_THICKNESS = 10;
|
||||
/** Default gap between border and contained component (5). */
|
||||
public final static int DEFAULT_GAP = 5;
|
||||
/** Default color (black). Applies to SOLID and etched borders. */
|
||||
public final static Color DEFAULT_COLOR = Color.black;
|
||||
|
||||
/** Default font (TimesRoman,PLAIN,14). Only applies to etched borders. */
|
||||
public final static Font DEFAULT_FONT = new Font("TimesRoman", Font.PLAIN, 14);
|
||||
/** Default alignment (LEFT). Only applies to etched borders. */
|
||||
public final static int DEFAULT_ALIGNMENT = LEFT;
|
||||
|
||||
// Data
|
||||
private int style;
|
||||
private int thickness;
|
||||
private int gap;
|
||||
private Color color;
|
||||
|
||||
private Font font;
|
||||
private String text;
|
||||
private int alignment;
|
||||
|
||||
/**
|
||||
* Constructor. Makes default border.
|
||||
*/
|
||||
public HolidayBorderPanel() {
|
||||
|
||||
// initialize data
|
||||
style = DEFAULT_STYLE;
|
||||
thickness = DEFAULT_THICKNESS;
|
||||
gap = DEFAULT_GAP;
|
||||
color = DEFAULT_COLOR;
|
||||
|
||||
text = null;
|
||||
font = DEFAULT_FONT;
|
||||
alignment = DEFAULT_ALIGNMENT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Makes an etched IN border with given text caption.
|
||||
*
|
||||
* @param text Text caption
|
||||
*/
|
||||
public HolidayBorderPanel(String text) {
|
||||
this();
|
||||
|
||||
style = IN;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Makes SOLID border with color and thickness given.
|
||||
*
|
||||
* @param color The color for the border.
|
||||
* @param thickness The thickness of the border.
|
||||
*/
|
||||
public HolidayBorderPanel(Color color, int thickness) {
|
||||
this();
|
||||
|
||||
style = SOLID;
|
||||
this.color = color;
|
||||
this.thickness = thickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Makes a border of the given style with the default
|
||||
* thickness for that style.
|
||||
*
|
||||
* @param style The style for this border.
|
||||
*/
|
||||
public HolidayBorderPanel(int style) {
|
||||
this();
|
||||
|
||||
// set thickness appropriate to this style
|
||||
switch (style) {
|
||||
case SOLID: thickness = DEFAULT_SOLID_THICKNESS; break;
|
||||
case RAISED: thickness = DEFAULT_RAISED_THICKNESS; break;
|
||||
case LOWERED: thickness = DEFAULT_LOWERED_THICKNESS; break;
|
||||
case IN: thickness = DEFAULT_IN_THICKNESS; break;
|
||||
case OUT: thickness = DEFAULT_OUT_THICKNESS; break;
|
||||
default:
|
||||
thickness = DEFAULT_THICKNESS;
|
||||
}
|
||||
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Makes border with given style and thickness.
|
||||
*
|
||||
* @param style The style for this border.
|
||||
* @param thickness The thickness for this border.
|
||||
*/
|
||||
public HolidayBorderPanel(int style, int thickness) {
|
||||
this();
|
||||
|
||||
this.style = style;
|
||||
this.thickness = thickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the insets of this panel..
|
||||
*/
|
||||
public Insets getInsets() {
|
||||
int adjustment = 0;
|
||||
|
||||
// adjust for text string
|
||||
if (style == IN || style == OUT) {
|
||||
if (text != null && text.length() > 0) {
|
||||
try {
|
||||
// set font and get info
|
||||
int height = getGraphics().getFontMetrics(font).getHeight();
|
||||
if (height > thickness)
|
||||
adjustment = height - thickness;
|
||||
}
|
||||
catch (Exception e) {
|
||||
// nothing: just in case there is no graphics context
|
||||
// at the beginning.
|
||||
System.out.print("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return appropriate insets
|
||||
int dist = thickness + gap;
|
||||
return new Insets(dist + adjustment, dist, dist, dist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style of the border
|
||||
*
|
||||
* @param style The new style.
|
||||
*/
|
||||
public HolidayBorderPanel setStyle(int style) {
|
||||
|
||||
// set the style and re-layout the panel
|
||||
this.style = style;
|
||||
doLayout();
|
||||
repaint();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the style of the border
|
||||
*/
|
||||
public int getStyle() {
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the thickness of the border.
|
||||
*
|
||||
* @param thickness The new thickness
|
||||
*/
|
||||
public HolidayBorderPanel setThickness(int thickness) {
|
||||
|
||||
if (thickness > 0) {
|
||||
this.thickness = thickness;
|
||||
doLayout();
|
||||
repaint();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the thickness of the border.
|
||||
*/
|
||||
public int getThickness() {
|
||||
|
||||
return thickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the gap between the border and the contained Component.
|
||||
*
|
||||
* @param gap The new gap, in pixels.
|
||||
*/
|
||||
public HolidayBorderPanel setGap(int gap) {
|
||||
|
||||
if (gap > -1) {
|
||||
this.gap = gap;
|
||||
doLayout();
|
||||
repaint();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the gap between the border and the contained Component.
|
||||
*/
|
||||
public int getGap() {
|
||||
|
||||
return gap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current color for SOLID borders and the caption text
|
||||
* color for etched borders.
|
||||
*
|
||||
* @param color The new color.
|
||||
*/
|
||||
public HolidayBorderPanel setColor(Color color) {
|
||||
|
||||
this.color = color;
|
||||
if (style == SOLID || style == IN || style == OUT)
|
||||
repaint();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current color for SOLID borders and the caption
|
||||
* text color for etched borders.
|
||||
*/
|
||||
public Color getColor() {
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font. Only applies to etched borders.
|
||||
*/
|
||||
public HolidayBorderPanel setTextFont(Font font) {
|
||||
|
||||
// set font
|
||||
if (font != null) {
|
||||
this.font = font;
|
||||
if (style == IN || style == OUT) {
|
||||
doLayout();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the font of the text. Only applies to etched borders.
|
||||
*/
|
||||
public Font getTextFont() {
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text. Only applies to etched borders.
|
||||
*
|
||||
* @param text The new text.
|
||||
*/
|
||||
public HolidayBorderPanel setText(String text) {
|
||||
|
||||
this.text = text;
|
||||
if (style == IN || style == OUT) {
|
||||
doLayout();
|
||||
repaint();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text. Only applies to etched borders.
|
||||
*/
|
||||
public String getText() {
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text alignment. Only applies to etched borders.
|
||||
*
|
||||
* @param alignment The new alignment.
|
||||
*/
|
||||
public HolidayBorderPanel setAlignment(int alignment) {
|
||||
|
||||
this.alignment = alignment;
|
||||
if (style == IN || style == OUT) {
|
||||
doLayout();
|
||||
repaint();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text alignment.
|
||||
*/
|
||||
public int getAlignment() {
|
||||
|
||||
return alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repaints the border.
|
||||
*
|
||||
* @param g The graphics context.
|
||||
*/
|
||||
public void paint(Graphics g) {
|
||||
|
||||
// get current dimensions
|
||||
Dimension size = getSize();
|
||||
int width = size.width;
|
||||
int height = size.height;
|
||||
|
||||
// set colors
|
||||
Color light = getBackground().brighter().brighter().brighter();
|
||||
Color dark = getBackground().darker().darker().darker();
|
||||
|
||||
// Draw border
|
||||
switch (style) {
|
||||
case RAISED: // 3D Border (in or out)
|
||||
case LOWERED:
|
||||
Color topleft = null;
|
||||
Color bottomright = null;
|
||||
|
||||
// set colors
|
||||
if (style == RAISED) {
|
||||
topleft = light;
|
||||
bottomright = dark;
|
||||
}
|
||||
else {
|
||||
topleft = dark;
|
||||
bottomright = light;
|
||||
}
|
||||
|
||||
// draw border
|
||||
g.setColor(topleft);
|
||||
for (int i = 0; i < thickness; i++) {
|
||||
g.drawLine(i, i, width - i - 2, i);
|
||||
g.drawLine(i, i + 1, i, height - i - 1);
|
||||
}
|
||||
g.setColor(bottomright);
|
||||
for (int i = 0; i < thickness; i++) {
|
||||
g.drawLine(i + 1, height - i - 1, width - i - 1, height - i - 1);
|
||||
g.drawLine(width - i - 1, i, width - i - 1, height - i - 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case IN: // Etched Border (in or out)
|
||||
case OUT:
|
||||
int adjust1 = 0;
|
||||
int adjust2 = 0;
|
||||
|
||||
// set font and get info
|
||||
Font oldfont = g.getFont();
|
||||
g.setFont(font);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int ascent = fm.getAscent();
|
||||
|
||||
// set adjustment
|
||||
if (style == IN)
|
||||
adjust1 = 1;
|
||||
else
|
||||
adjust2 = 1;
|
||||
|
||||
// Calculate adjustment for text
|
||||
int adjustment = 0;
|
||||
if (text != null && text.length() > 0) {
|
||||
if (ascent > thickness)
|
||||
adjustment = (ascent - thickness) / 2;
|
||||
}
|
||||
|
||||
// The adjustment is there so that we always draw the
|
||||
// light rectangle first. Otherwise, your eye picks up
|
||||
// the discrepancy where the light rect. passes over
|
||||
// the darker rect.
|
||||
int x = thickness / 2;
|
||||
int y = thickness / 2 + adjustment;
|
||||
int w = width - thickness - 1;
|
||||
int h = height - thickness - 1 - adjustment;
|
||||
|
||||
// draw rectangles
|
||||
g.setColor(light);
|
||||
g.drawRect(x + adjust1, y + adjust1, w, h);
|
||||
g.setColor(dark);
|
||||
g.drawRect(x + adjust2, y + adjust2, w, h);
|
||||
|
||||
// draw text, if applicable
|
||||
if (text != null && text.length() > 0) {
|
||||
// calculate drawing area
|
||||
int fontheight = fm.getHeight();
|
||||
int strwidth = fm.stringWidth(text);
|
||||
|
||||
int textwidth = width - 2 * (thickness + 5);
|
||||
if (strwidth > textwidth)
|
||||
strwidth = textwidth;
|
||||
|
||||
// calculate offset for alignment
|
||||
int offset;
|
||||
switch (alignment) {
|
||||
case CENTER:
|
||||
offset = (width - strwidth) / 2;
|
||||
break;
|
||||
case RIGHT:
|
||||
offset = width - strwidth - thickness - 5;
|
||||
break;
|
||||
case LEFT:
|
||||
default: // assume left alignment if invalid
|
||||
offset = thickness + 5;
|
||||
break;
|
||||
}
|
||||
|
||||
// clear drawing area and set clipping region
|
||||
g.clearRect(offset - 5, 0, strwidth + 10, fontheight);
|
||||
g.clipRect(offset, 0, strwidth, fontheight);
|
||||
|
||||
// draw text
|
||||
g.setColor(color);
|
||||
g.drawString(text, offset, ascent);
|
||||
|
||||
// restore old clipping area
|
||||
g.clipRect(0, 0, width, height);
|
||||
}
|
||||
|
||||
g.setFont(oldfont);
|
||||
break;
|
||||
|
||||
case SOLID:
|
||||
default: // assume SOLID
|
||||
g.setColor(color);
|
||||
for (int i = 0; i < thickness; i++)
|
||||
g.drawRect(i, i, width - 2 * i - 1, height - 2 * i - 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the settings of this HolidayBorderPanel instance as a string.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer str = new StringBuffer("HolidayBorderPanel[");
|
||||
|
||||
// style
|
||||
str.append("style=");
|
||||
switch (style) {
|
||||
case SOLID: str.append("SOLID"); break;
|
||||
case RAISED: str.append("RAISED"); break;
|
||||
case LOWERED: str.append("LOWERED"); break;
|
||||
case IN: str.append("IN"); break;
|
||||
case OUT: str.append("OUT"); break;
|
||||
default: str.append("unknown");
|
||||
}
|
||||
str.append(",");
|
||||
|
||||
// thickness
|
||||
str.append("thickness=");
|
||||
str.append(thickness);
|
||||
str.append(",");
|
||||
|
||||
// gap
|
||||
str.append("gap=");
|
||||
str.append(gap);
|
||||
str.append(",");
|
||||
|
||||
// color
|
||||
str.append(color);
|
||||
str.append(",");
|
||||
|
||||
// font
|
||||
str.append(font);
|
||||
str.append(",");
|
||||
|
||||
// text
|
||||
str.append("text=");
|
||||
str.append(text);
|
||||
str.append(",");
|
||||
|
||||
// alignment
|
||||
str.append("alignment=");
|
||||
switch (alignment) {
|
||||
case LEFT: str.append("LEFT"); break;
|
||||
case CENTER: str.append("CENTER"); break;
|
||||
case RIGHT: str.append("RIGHT"); break;
|
||||
default: str.append("unknown");
|
||||
}
|
||||
|
||||
str.append("]");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
744
demos/src/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java
Normal file
744
demos/src/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java
Normal file
|
@ -0,0 +1,744 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2007, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.holiday;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Choice;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.text.DateFormatSymbols;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DemoApplet;
|
||||
import com.ibm.icu.dev.demo.impl.DemoTextBox;
|
||||
import com.ibm.icu.dev.demo.impl.DemoUtility;
|
||||
import com.ibm.icu.text.SimpleDateFormat;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
import com.ibm.icu.util.Holiday;
|
||||
import com.ibm.icu.util.SimpleTimeZone;
|
||||
|
||||
/**
|
||||
* CalendarDemo demonstrates how Calendar works.
|
||||
*/
|
||||
public class HolidayCalendarDemo extends DemoApplet
|
||||
{
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 4546085430817359372L;
|
||||
|
||||
/**
|
||||
* The main function which defines the behavior of the CalendarDemo
|
||||
* applet when an applet is started.
|
||||
*/
|
||||
public static void main(String argv[]) {
|
||||
|
||||
new HolidayCalendarDemo().showDemo();
|
||||
}
|
||||
|
||||
/* This creates a CalendarFrame for the demo applet. */
|
||||
public Frame createDemoFrame(DemoApplet applet) {
|
||||
return new CalendarFrame(applet);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Frame is a top-level window with a title. The default layout for a frame
|
||||
* is BorderLayout. The CalendarFrame class defines the window layout of
|
||||
* CalendarDemo.
|
||||
*/
|
||||
private static class CalendarFrame extends Frame implements ActionListener,
|
||||
ItemListener
|
||||
{
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -7023296782393042761L;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
//private Locale curLocale = Locale.US; // unused
|
||||
|
||||
private DemoApplet applet;
|
||||
|
||||
private static final Locale[] calendars = {
|
||||
//new Locale("de","AT"),
|
||||
Locale.CANADA,
|
||||
Locale.CANADA_FRENCH,
|
||||
Locale.FRANCE,
|
||||
Locale.GERMANY,
|
||||
new Locale("iw","IL"),
|
||||
new Locale("el","GR"),
|
||||
//new Locale("es","MX"),
|
||||
Locale.UK,
|
||||
Locale.US,
|
||||
};
|
||||
private static final Locale[] displays = {
|
||||
Locale.CANADA,
|
||||
Locale.UK,
|
||||
Locale.US,
|
||||
Locale.FRANCE,
|
||||
Locale.CANADA_FRENCH,
|
||||
//new Locale("de","AT"),
|
||||
Locale.GERMAN,
|
||||
new Locale("el","GR"),
|
||||
//new Locale("iw","IL"),
|
||||
new Locale("es","MX"),
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new CalendarFrame that is initially invisible.
|
||||
*/
|
||||
public CalendarFrame(DemoApplet applet)
|
||||
{
|
||||
super("Calendar Demo");
|
||||
this.applet = applet;
|
||||
init();
|
||||
start();
|
||||
enableEvents(WindowEvent.WINDOW_CLOSING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the applet. You never need to call this directly, it
|
||||
* is called automatically by the system once the applet is created.
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
// Get G7 locales only for demo purpose. To get all the locales
|
||||
// supported, switch to calling Calendar.getAvailableLocales().
|
||||
// commented
|
||||
locales = displays;
|
||||
|
||||
buildGUI();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// package private
|
||||
//------------------------------------------------------------
|
||||
void addWithFont(Container container, Component foo, Font font) {
|
||||
if (font != null)
|
||||
foo.setFont(font);
|
||||
container.add(foo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to start the applet. You never need to call this method
|
||||
* directly, it is called when the applet's document is visited.
|
||||
*/
|
||||
public void start()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
private Choice localeMenu;
|
||||
private Choice displayMenu;
|
||||
private Locale[] locales;
|
||||
|
||||
private Label monthLabel;
|
||||
private Button prevYear;
|
||||
private Button prevMonth;
|
||||
private Button gotoToday;
|
||||
private Button nextMonth;
|
||||
private Button nextYear;
|
||||
private CalendarPanel calendarPanel;
|
||||
|
||||
private static final Locale kFirstLocale = Locale.US;
|
||||
|
||||
private static void add(Container container, Component component,
|
||||
GridBagLayout g, GridBagConstraints c)
|
||||
{
|
||||
g.setConstraints(component, c);
|
||||
container.add(component);
|
||||
}
|
||||
|
||||
public void buildGUI()
|
||||
{
|
||||
setBackground(DemoUtility.bgColor);
|
||||
setLayout(new BorderLayout(10,10));
|
||||
|
||||
// Label for the demo's title
|
||||
Label titleLabel = new Label("Calendar Demo", Label.CENTER);
|
||||
titleLabel.setFont(DemoUtility.titleFont);
|
||||
|
||||
// Label for the current month name
|
||||
monthLabel = new Label("", Label.LEFT);
|
||||
monthLabel.setFont(new Font(DemoUtility.titleFont.getName(),
|
||||
DemoUtility.titleFont.getStyle(),
|
||||
(DemoUtility.titleFont.getSize() * 3)/2));
|
||||
|
||||
// Make the locale popup menus
|
||||
localeMenu= new Choice();
|
||||
localeMenu.addItemListener(this);
|
||||
int selectMe = 0;
|
||||
|
||||
for (int i = 0; i < calendars.length; i++) {
|
||||
if (i > 0 &&
|
||||
calendars[i].getCountry().equals(calendars[i-1].getCountry()) ||
|
||||
i < calendars.length - 1 &&
|
||||
calendars[i].getCountry().equals(calendars[i+1].getCountry()))
|
||||
{
|
||||
localeMenu.addItem(calendars[i].getDisplayCountry() + " (" +
|
||||
calendars[i].getDisplayLanguage() + ")");
|
||||
} else {
|
||||
localeMenu.addItem( calendars[i].getDisplayCountry() );
|
||||
}
|
||||
|
||||
if (calendars[i].equals(kFirstLocale)) {
|
||||
selectMe = i;
|
||||
}
|
||||
}
|
||||
|
||||
localeMenu.setBackground(DemoUtility.choiceColor);
|
||||
localeMenu.select(selectMe);
|
||||
|
||||
displayMenu = new Choice();
|
||||
displayMenu.addItemListener(this);
|
||||
|
||||
selectMe = 0;
|
||||
for (int i = 0; i < locales.length; i++) {
|
||||
if (i > 0 &&
|
||||
locales[i].getLanguage().equals(locales[i-1].getLanguage()) ||
|
||||
i < locales.length - 1 &&
|
||||
locales[i].getLanguage().equals(locales[i+1].getLanguage()))
|
||||
{
|
||||
displayMenu.addItem( locales[i].getDisplayName() );
|
||||
} else {
|
||||
displayMenu.addItem( locales[i].getDisplayLanguage());
|
||||
}
|
||||
|
||||
if (locales[i].equals(kFirstLocale)) {
|
||||
selectMe = i;
|
||||
}
|
||||
}
|
||||
|
||||
displayMenu.setBackground(DemoUtility.choiceColor);
|
||||
displayMenu.select(selectMe);
|
||||
|
||||
// Make all the next/previous/today buttons
|
||||
prevYear = new Button("<<");
|
||||
prevYear.addActionListener(this);
|
||||
prevMonth = new Button("<");
|
||||
prevMonth.addActionListener(this);
|
||||
gotoToday = new Button("Today");
|
||||
gotoToday.addActionListener(this);
|
||||
nextMonth = new Button(">");
|
||||
nextMonth.addActionListener(this);
|
||||
nextYear = new Button(">>");
|
||||
nextYear.addActionListener(this);
|
||||
|
||||
// The month name and the control buttons are bunched together
|
||||
Panel monthPanel = new Panel();
|
||||
{
|
||||
GridBagLayout g = new GridBagLayout();
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
monthPanel.setLayout(g);
|
||||
|
||||
c.weightx = 1;
|
||||
c.weighty = 1;
|
||||
|
||||
c.gridwidth = 1;
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
add(monthPanel, monthLabel, g, c);
|
||||
|
||||
c.gridwidth = 1;
|
||||
add(monthPanel, prevYear, g, c);
|
||||
add(monthPanel, prevMonth, g, c);
|
||||
add(monthPanel, gotoToday, g, c);
|
||||
add(monthPanel, nextMonth, g, c);
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
add(monthPanel, nextYear, g, c);
|
||||
}
|
||||
|
||||
// Stick the menu and buttons in a little "control panel"
|
||||
Panel menuPanel = new Panel();
|
||||
{
|
||||
GridBagLayout g = new GridBagLayout();
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
menuPanel.setLayout(g);
|
||||
|
||||
c.weightx = 1;
|
||||
c.weighty = 1;
|
||||
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
|
||||
c.gridwidth = GridBagConstraints.RELATIVE;
|
||||
Label l1 = new Label("Holidays");
|
||||
l1.setFont(DemoUtility.labelFont);
|
||||
add(menuPanel, l1, g, c);
|
||||
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
add(menuPanel, localeMenu, g, c);
|
||||
|
||||
c.gridwidth = GridBagConstraints.RELATIVE;
|
||||
Label l2 = new Label("Display:");
|
||||
l2.setFont(DemoUtility.labelFont);
|
||||
add(menuPanel, l2, g, c);
|
||||
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
add(menuPanel, displayMenu, g, c);
|
||||
}
|
||||
|
||||
// The title, buttons, etc. go in a panel at the top of the window
|
||||
Panel topPanel = new Panel();
|
||||
{
|
||||
topPanel.setLayout(new BorderLayout());
|
||||
|
||||
//topPanel.add("North", titleLabel);
|
||||
topPanel.add("Center", monthPanel);
|
||||
topPanel.add("East", menuPanel);
|
||||
}
|
||||
add("North", topPanel);
|
||||
|
||||
// The copyright notice goes at the bottom of the window
|
||||
Label copyright = new Label(DemoUtility.copyright1, Label.LEFT);
|
||||
copyright.setFont(DemoUtility.creditFont);
|
||||
add("South", copyright);
|
||||
|
||||
// Now create the big calendar panel and stick it in the middle
|
||||
calendarPanel = new CalendarPanel( kFirstLocale );
|
||||
add("Center", calendarPanel);
|
||||
|
||||
updateMonthName();
|
||||
}
|
||||
|
||||
private void updateMonthName()
|
||||
{
|
||||
SimpleDateFormat f = new SimpleDateFormat("MMMM yyyyy",
|
||||
calendarPanel.getDisplayLocale());
|
||||
f.setCalendar(calendarPanel.getCalendar());
|
||||
f.setTimeZone(new SimpleTimeZone(0, "UTC")); // JDK 1.1.2 workaround
|
||||
monthLabel.setText( f.format( calendarPanel.firstOfMonth() ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the event. Returns true if the event is handled and should not
|
||||
* be passed to the parent of this component. The default event handler
|
||||
* calls some helper methods to make life easier on the programmer.
|
||||
*/
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Object obj = e.getSource();
|
||||
|
||||
// *** Button events are handled here.
|
||||
if (obj instanceof Button) {
|
||||
if (obj == nextMonth) {
|
||||
calendarPanel.add(Calendar.MONTH, +1);
|
||||
}
|
||||
else
|
||||
if (obj == prevMonth) {
|
||||
calendarPanel.add(Calendar.MONTH, -1);
|
||||
}
|
||||
else
|
||||
if (obj == prevYear) {
|
||||
calendarPanel.add(Calendar.YEAR, -1);
|
||||
}
|
||||
else
|
||||
if (obj == nextYear) {
|
||||
calendarPanel.add(Calendar.YEAR, +1);
|
||||
}
|
||||
else
|
||||
if (obj == gotoToday) {
|
||||
calendarPanel.set( new Date() );
|
||||
}
|
||||
updateMonthName();
|
||||
}
|
||||
}
|
||||
|
||||
public void itemStateChanged(ItemEvent e)
|
||||
{
|
||||
Object obj = e.getSource();
|
||||
if (obj == localeMenu) {
|
||||
calendarPanel.setCalendarLocale(calendars[localeMenu.getSelectedIndex()]);
|
||||
updateMonthName();
|
||||
}
|
||||
else
|
||||
if (obj == displayMenu) {
|
||||
calendarPanel.setDisplayLocale(locales[displayMenu.getSelectedIndex()]);
|
||||
updateMonthName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out the error message while debugging this program.
|
||||
*/
|
||||
public void errorText(String s)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
protected void processWindowEvent(WindowEvent e)
|
||||
{
|
||||
System.out.println("event " + e);
|
||||
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
|
||||
this.hide();
|
||||
this.dispose();
|
||||
|
||||
if (applet != null) {
|
||||
applet.demoClosed();
|
||||
} else {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class CalendarPanel extends Canvas {
|
||||
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 1521099412250120821L;
|
||||
|
||||
public CalendarPanel( Locale locale ) {
|
||||
set(locale, locale, new Date());
|
||||
}
|
||||
|
||||
public void setCalendarLocale(Locale locale) {
|
||||
set(locale, fDisplayLocale, fCalendar.getTime());
|
||||
}
|
||||
|
||||
public void setDisplayLocale(Locale locale) {
|
||||
set(fCalendarLocale, locale, fCalendar.getTime());
|
||||
}
|
||||
|
||||
public void set(Date date) {
|
||||
set(fCalendarLocale, fDisplayLocale, date);
|
||||
}
|
||||
|
||||
public void set(Locale loc, Locale display, Date date)
|
||||
{
|
||||
if (fCalendarLocale == null || !loc.equals(fCalendarLocale)) {
|
||||
fCalendarLocale = loc;
|
||||
fCalendar = Calendar.getInstance(fCalendarLocale);
|
||||
fAllHolidays = Holiday.getHolidays(fCalendarLocale);
|
||||
}
|
||||
if (fDisplayLocale == null || !display.equals(fDisplayLocale)) {
|
||||
fDisplayLocale = display;
|
||||
fSymbols = new DateFormatSymbols(fDisplayLocale);
|
||||
}
|
||||
|
||||
fStartOfMonth = date;
|
||||
|
||||
dirty = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void add(int field, int delta)
|
||||
{
|
||||
synchronized(fCalendar) {
|
||||
fCalendar.setTime(fStartOfMonth);
|
||||
fCalendar.add(field, delta);
|
||||
fStartOfMonth = fCalendar.getTime();
|
||||
}
|
||||
dirty = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
public com.ibm.icu.util.Calendar getCalendar() {
|
||||
return fCalendar;
|
||||
}
|
||||
|
||||
public Locale getCalendarLocale() {
|
||||
return fCalendarLocale;
|
||||
}
|
||||
|
||||
public Locale getDisplayLocale() {
|
||||
return fDisplayLocale;
|
||||
}
|
||||
|
||||
|
||||
public Date firstOfMonth() {
|
||||
return fStartOfMonth;
|
||||
}
|
||||
|
||||
private Date startOfMonth(Date dateInMonth)
|
||||
{
|
||||
synchronized(fCalendar) {
|
||||
fCalendar.setTime(dateInMonth); // TODO: synchronization
|
||||
|
||||
int era = fCalendar.get(Calendar.ERA);
|
||||
int year = fCalendar.get(Calendar.YEAR);
|
||||
int month = fCalendar.get(Calendar.MONTH);
|
||||
|
||||
fCalendar.clear();
|
||||
fCalendar.set(Calendar.ERA, era);
|
||||
fCalendar.set(Calendar.YEAR, year);
|
||||
fCalendar.set(Calendar.MONTH, month);
|
||||
fCalendar.set(Calendar.DATE, 1);
|
||||
|
||||
return fCalendar.getTime();
|
||||
}
|
||||
}
|
||||
|
||||
private void calculate()
|
||||
{
|
||||
//
|
||||
// As a workaround for JDK 1.1.3 and below, where Calendars and time
|
||||
// zones are a bit goofy, always set my calendar's time zone to UTC.
|
||||
// You would think I would want to do this in the "set" function above,
|
||||
// but if I do that, the program hangs when this class is loaded,
|
||||
// perhaps due to some sort of static initialization ordering problem.
|
||||
// So I do it here instead.
|
||||
//
|
||||
fCalendar.setTimeZone(new SimpleTimeZone(0, "UTC"));
|
||||
|
||||
Calendar c = (Calendar)fCalendar.clone(); // Temporary copy
|
||||
|
||||
fStartOfMonth = startOfMonth(fStartOfMonth);
|
||||
|
||||
// Stash away a few useful constants for this calendar and display
|
||||
minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
|
||||
daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
|
||||
|
||||
firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
|
||||
|
||||
// Stash away a Date for the start of this month
|
||||
|
||||
// Find the day of week of the first day in this month
|
||||
c.setTime(fStartOfMonth);
|
||||
firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
// Now find the # of days in the month
|
||||
c.roll(Calendar.DATE, false);
|
||||
daysInMonth = c.get(Calendar.DATE);
|
||||
|
||||
// Finally, find the end of the month, i.e. the start of the next one
|
||||
c.roll(Calendar.DATE, true);
|
||||
c.add(Calendar.MONTH, 1);
|
||||
c.getTime(); // JDK 1.1.2 bug workaround
|
||||
c.add(Calendar.SECOND, -1);
|
||||
Date endOfMonth = c.getTime();
|
||||
|
||||
//
|
||||
// Calculate the number of full or partial weeks in this month.
|
||||
// To do this I can just reuse the code that calculates which
|
||||
// calendar cell contains a given date.
|
||||
//
|
||||
numWeeks = dateToCell(daysInMonth).y - dateToCell(1).y + 1;
|
||||
|
||||
// Remember which holidays fall on which days in this month,
|
||||
// to save the trouble of having to do it later
|
||||
fHolidays.setSize(0);
|
||||
|
||||
for (int h = 0; h < fAllHolidays.length; h++)
|
||||
{
|
||||
Date d = fStartOfMonth;
|
||||
while ( (d = fAllHolidays[h].firstBetween(d, endOfMonth) ) != null)
|
||||
{
|
||||
c.setTime(d);
|
||||
fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE),
|
||||
fAllHolidays[h],
|
||||
fAllHolidays[h].getDisplayName(fDisplayLocale) ));
|
||||
|
||||
d.setTime( d.getTime() + 1000 ); // "d++"
|
||||
}
|
||||
}
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
static final int INSET = 2;
|
||||
|
||||
/*
|
||||
* Convert from the day number within a month (1-based)
|
||||
* to the cell coordinates on the calendar (0-based)
|
||||
*/
|
||||
private void dateToCell(int date, Point pos)
|
||||
{
|
||||
int cell = (date + firstDayInMonth - firstDayOfWeek - minDay);
|
||||
if (firstDayInMonth < firstDayOfWeek) {
|
||||
cell += daysInWeek;
|
||||
}
|
||||
|
||||
pos.x = cell % daysInWeek;
|
||||
pos.y = cell / daysInWeek;
|
||||
}
|
||||
private Point dateToCell(int date) {
|
||||
Point p = new Point(0,0);
|
||||
dateToCell(date, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
|
||||
if (dirty) {
|
||||
calculate();
|
||||
}
|
||||
|
||||
Point cellPos = new Point(0,0); // Temporary variable
|
||||
Dimension d = getSize();
|
||||
|
||||
g.setColor(DemoUtility.bgColor);
|
||||
g.fillRect(0,0,d.width,d.height);
|
||||
|
||||
// Draw the day names at the top
|
||||
g.setColor(Color.black);
|
||||
g.setFont(DemoUtility.labelFont);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int labelHeight = fm.getHeight() + INSET * 2;
|
||||
|
||||
int v = fm.getAscent() + INSET;
|
||||
for (int i = 0; i < daysInWeek; i++) {
|
||||
int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1;
|
||||
String dayName = fSymbols.getWeekdays()[dayNum];
|
||||
|
||||
int h = (int) (d.width * (i + 0.5)) / daysInWeek;
|
||||
h -= fm.stringWidth(dayName) / 2;
|
||||
|
||||
g.drawString(dayName, h, v);
|
||||
}
|
||||
|
||||
double cellHeight = (d.height - labelHeight - 1) / numWeeks;
|
||||
double cellWidth = (double)(d.width - 1) / daysInWeek;
|
||||
|
||||
// Draw a white background in the part of the calendar
|
||||
// that displays this month.
|
||||
// First figure out how much of the first week should be shaded.
|
||||
{
|
||||
g.setColor(Color.white);
|
||||
dateToCell(1, cellPos);
|
||||
int width = (int)(cellPos.x*cellWidth); // Width of unshaded area
|
||||
|
||||
g.fillRect((int)(width), labelHeight ,
|
||||
(int)(d.width - width), (int)cellHeight);
|
||||
|
||||
// All of the intermediate weeks get shaded completely
|
||||
g.fillRect(0, (int)(labelHeight + cellHeight),
|
||||
d.width, (int)(cellHeight * (numWeeks - 2)));
|
||||
|
||||
// Now figure out the last week.
|
||||
dateToCell(daysInMonth, cellPos);
|
||||
width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area
|
||||
|
||||
g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight),
|
||||
width, (int)(cellHeight));
|
||||
|
||||
}
|
||||
// Draw the X/Y grid lines
|
||||
g.setColor(Color.black);
|
||||
for (int i = 0; i <= numWeeks; i++) {
|
||||
int y = (int)(labelHeight + i * cellHeight);
|
||||
g.drawLine(0, y, d.width - 1, y);
|
||||
}
|
||||
for (int i = 0; i <= daysInWeek; i++) {
|
||||
int x = (int)(i * cellWidth);
|
||||
g.drawLine(x, labelHeight, x, d.height - 1);
|
||||
}
|
||||
|
||||
// Now loop through all of the days in the month, figure out where
|
||||
// they go in the grid, and draw the day # for each one
|
||||
Font numberFont = new Font("Helvetica",Font.PLAIN,12);
|
||||
// not used Font holidayFont = DemoUtility.creditFont;
|
||||
|
||||
Calendar c = (Calendar)fCalendar.clone();
|
||||
c.setTime(fStartOfMonth);
|
||||
|
||||
for (int i = 1, h = 0; i <= daysInMonth; i++) {
|
||||
g.setFont(numberFont);
|
||||
g.setColor(Color.black);
|
||||
fm = g.getFontMetrics();
|
||||
|
||||
dateToCell(i, cellPos);
|
||||
int x = (int)((cellPos.x + 1) * cellWidth);
|
||||
int y = (int)(cellPos.y * cellHeight + labelHeight);
|
||||
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(i);
|
||||
String dayNum = buffer.toString();
|
||||
|
||||
x = x - INSET - fm.stringWidth(dayNum);
|
||||
y = y + fm.getAscent() + INSET;
|
||||
|
||||
g.drawString(dayNum, x, y);
|
||||
|
||||
// See if any of the holidays land on this day....
|
||||
HolidayInfo info = null;
|
||||
int count = 0;
|
||||
|
||||
// Coordinates of lower-left corner of cell.
|
||||
x = (int)((cellPos.x) * cellWidth);
|
||||
y = (int)((cellPos.y+1) * cellHeight) + labelHeight;
|
||||
|
||||
while (h < fHolidays.size() &&
|
||||
(info = (HolidayInfo)fHolidays.elementAt(h)).date <= i)
|
||||
{
|
||||
if (info.date == i) {
|
||||
// Draw the holiday here.
|
||||
g.setFont(numberFont);
|
||||
g.setColor(Color.red);
|
||||
|
||||
DemoTextBox box = new DemoTextBox(g, info.name, (int)(cellWidth - INSET));
|
||||
box.draw(g, x + INSET, y - INSET - box.getHeight());
|
||||
|
||||
y -= (box.getHeight() + INSET);
|
||||
count++;
|
||||
}
|
||||
h++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Important state variables
|
||||
private Locale fCalendarLocale; // Whose calendar
|
||||
private Calendar fCalendar; // Calendar for calculations
|
||||
|
||||
private Locale fDisplayLocale; // How to display it
|
||||
private DateFormatSymbols fSymbols; // Symbols for drawing
|
||||
|
||||
private Date fStartOfMonth; // 00:00:00 on first day of month
|
||||
|
||||
// Cached calculations to make drawing faster.
|
||||
private transient int minDay; // Minimum legal day #
|
||||
private transient int daysInWeek; // # of days in a week
|
||||
private transient int firstDayOfWeek; // First day to display in week
|
||||
private transient int numWeeks; // # full or partial weeks in month
|
||||
private transient int daysInMonth; // # days in this month
|
||||
private transient int firstDayInMonth; // Day of week of first day in month
|
||||
|
||||
private transient Holiday[] fAllHolidays;
|
||||
private transient Vector fHolidays = new Vector(5,5);
|
||||
|
||||
private transient boolean dirty = true;
|
||||
}
|
||||
|
||||
private static class HolidayInfo {
|
||||
public HolidayInfo(int date, Holiday holiday, String name) {
|
||||
this.date = date;
|
||||
this.holiday = holiday;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Holiday holiday;
|
||||
public int date;
|
||||
public String name;
|
||||
}
|
||||
}
|
||||
|
12
demos/src/com/ibm/icu/dev/demo/holiday/package.html
Normal file
12
demos/src/com/ibm/icu/dev/demo/holiday/package.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<!-- Copyright (C) 2000-2004, International Business Machines Corporation and
|
||||
others. All Rights Reserved.
|
||||
|
||||
-->
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
Holiday demo application.
|
||||
</body>
|
||||
</html>
|
149
demos/src/com/ibm/icu/dev/demo/impl/AppletFrame.java
Normal file
149
demos/src/com/ibm/icu/dev/demo/impl/AppletFrame.java
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.impl;
|
||||
import java.applet.Applet;
|
||||
import java.applet.AppletContext;
|
||||
import java.applet.AppletStub;
|
||||
import java.applet.AudioClip;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* <p>A Frame that runs an Applet within itself, making it possible
|
||||
* for an applet to run as an application. Usage:
|
||||
*
|
||||
* <pre>
|
||||
* public class MyApplet extends Applet {
|
||||
* public static void main(String args[]) {
|
||||
* MyApplet applet = new MyApplet();
|
||||
* new AppletFrame("My Applet Running As An App", applet, 640, 480);
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
* <pre>
|
||||
*
|
||||
* @author Alan Liu
|
||||
*/
|
||||
public class AppletFrame extends Frame implements AppletStub, AppletContext {
|
||||
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 818828281190757725L;
|
||||
Applet applet;
|
||||
|
||||
/**
|
||||
* Construct a Frame running the given Applet with the default size
|
||||
* of 640 by 480.
|
||||
* When the Frame is closed, the applet's stop() method is called,
|
||||
* the Frame is dispose()d of, and System.exit(0) is called.
|
||||
*
|
||||
* @param name the Frame title
|
||||
* @param applet the applet to be run
|
||||
*/
|
||||
public AppletFrame(String name, Applet applet) {
|
||||
this(name, applet, 640, 480);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Frame running the given Applet with the given size.
|
||||
* When the Frame is closed, the applet's stop() method is called,
|
||||
* the Frame is dispose()d of, and System.exit(0) is called.
|
||||
*
|
||||
* @param name the Frame title
|
||||
* @param applet the applet to be run
|
||||
* @param width width of the Frame
|
||||
* @param height height of the Frame
|
||||
*/
|
||||
public AppletFrame(String name, Applet applet, int width, int height) {
|
||||
super(name);
|
||||
this.applet = applet;
|
||||
applet.setStub(this);
|
||||
|
||||
setSize(width, height);
|
||||
add("Center", applet);
|
||||
show();
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
AppletFrame.this.applet.stop();
|
||||
dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
applet.init();
|
||||
applet.start();
|
||||
}
|
||||
|
||||
// AppletStub API
|
||||
public void appletResize(int width, int height) {
|
||||
setSize(width, height);
|
||||
}
|
||||
|
||||
public AppletContext getAppletContext() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public URL getCodeBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public URL getDocumentBase() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getParameter(String name) {
|
||||
return "PARAMETER";
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// AppletContext API
|
||||
public Applet getApplet(String name) {
|
||||
return applet;
|
||||
}
|
||||
|
||||
public Enumeration getApplets() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AudioClip getAudioClip(URL url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Image getImage(URL url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void showDocument(URL url) {}
|
||||
public void showDocument(URL url, String target) {}
|
||||
|
||||
public void showStatus(String status) {
|
||||
System.out.println(status);
|
||||
}
|
||||
|
||||
public void setStream(String key, InputStream stream) throws IOException {
|
||||
}
|
||||
|
||||
public InputStream getStream(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator getStreamKeys() {
|
||||
return null;
|
||||
}
|
||||
}
|
80
demos/src/com/ibm/icu/dev/demo/impl/DemoApplet.java
Normal file
80
demos/src/com/ibm/icu/dev/demo/impl/DemoApplet.java
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.impl;
|
||||
|
||||
import java.awt.Button;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public abstract class DemoApplet extends java.applet.Applet {
|
||||
private static final long serialVersionUID = -8983602961925702071L;
|
||||
private Button demoButton;
|
||||
private Frame demoFrame;
|
||||
private static int demoFrameCount = 0;
|
||||
|
||||
protected abstract Frame createDemoFrame(DemoApplet applet);
|
||||
protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
|
||||
return new Dimension(700, 550);
|
||||
}
|
||||
|
||||
//Create a button that will display the demo
|
||||
public void init()
|
||||
{
|
||||
setBackground(Color.white);
|
||||
demoButton = new Button("Demo");
|
||||
demoButton.setBackground(Color.yellow);
|
||||
add( demoButton );
|
||||
|
||||
demoButton.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getID() == ActionEvent.ACTION_PERFORMED) {
|
||||
demoButton.setLabel("loading");
|
||||
|
||||
if (demoFrame == null) {
|
||||
demoFrame = createDemoFrame(DemoApplet.this);
|
||||
showDemo();
|
||||
}
|
||||
|
||||
demoButton.setLabel("Demo");
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public void showDemo()
|
||||
{
|
||||
demoFrame = createDemoFrame(this);
|
||||
demoFrame.doLayout();
|
||||
Dimension d = getDefaultFrameSize(this, demoFrame);
|
||||
demoFrame.setSize(d.width, d.height);
|
||||
demoFrame.show();
|
||||
demoFrameOpened();
|
||||
}
|
||||
|
||||
public void demoClosed()
|
||||
{
|
||||
demoFrame = null;
|
||||
demoFrameClosed();
|
||||
}
|
||||
|
||||
public static void demoFrameOpened() {
|
||||
demoFrameCount++;
|
||||
System.err.println("DemoFrameOpened, now at:"+demoFrameCount);
|
||||
}
|
||||
public static void demoFrameClosed() {
|
||||
if (--demoFrameCount == 0) {
|
||||
System.err.println("DemoFrameClosed, now at:"+demoFrameCount + " - quitting");
|
||||
System.exit(0);
|
||||
}
|
||||
System.err.println("DemoFrameClosed, now at:"+demoFrameCount);
|
||||
}
|
||||
}
|
||||
|
96
demos/src/com/ibm/icu/dev/demo/impl/DemoTextBox.java
Normal file
96
demos/src/com/ibm/icu/dev/demo/impl/DemoTextBox.java
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.impl;
|
||||
|
||||
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.text.BreakIterator;
|
||||
|
||||
public class DemoTextBox {
|
||||
|
||||
public DemoTextBox(Graphics g, String text, int width)
|
||||
{
|
||||
this.text = text;
|
||||
this.chars = new char[text.length()];
|
||||
text.getChars(0, text.length(), chars, 0);
|
||||
|
||||
this.width = width;
|
||||
// this.port = g;
|
||||
this.metrics = g.getFontMetrics();
|
||||
|
||||
breakText();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return (nbreaks + 1) * metrics.getHeight();
|
||||
}
|
||||
|
||||
public void draw(Graphics g, int x, int y)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
y += metrics.getAscent();
|
||||
|
||||
for (int i = 0; i < nbreaks; i++)
|
||||
{
|
||||
g.drawChars(chars, index, breakPos[i] - index, x, y);
|
||||
index = breakPos[i];
|
||||
y += metrics.getHeight();
|
||||
}
|
||||
|
||||
g.drawChars(chars, index, chars.length - index, x, y);
|
||||
}
|
||||
|
||||
|
||||
private void breakText()
|
||||
{
|
||||
if (metrics.charsWidth(chars, 0, chars.length) > width)
|
||||
{
|
||||
BreakIterator iter = BreakIterator.getWordInstance();
|
||||
iter.setText(text);
|
||||
|
||||
int start = iter.first();
|
||||
int end = start;
|
||||
int pos;
|
||||
|
||||
while ( (pos = iter.next()) != BreakIterator.DONE )
|
||||
{
|
||||
int w = metrics.charsWidth(chars, start, pos - start);
|
||||
if (w > width)
|
||||
{
|
||||
// We've gone past the maximum width, so break the line
|
||||
if (end > start) {
|
||||
// There was at least one break position before this point
|
||||
breakPos[nbreaks++] = end;
|
||||
start = end;
|
||||
end = pos;
|
||||
} else {
|
||||
// There weren't any break positions before this one, so
|
||||
// let this word overflow the margin (yuck)
|
||||
breakPos[nbreaks++] = pos;
|
||||
start = end = pos;
|
||||
}
|
||||
} else {
|
||||
// the current position still fits on the line; it's the best
|
||||
// tentative break position we have so far.
|
||||
end = pos;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String text;
|
||||
private char[] chars;
|
||||
// private Graphics port;
|
||||
private FontMetrics metrics;
|
||||
private int width;
|
||||
|
||||
private int[] breakPos = new int[10]; // TODO: get real
|
||||
private int nbreaks = 0;
|
||||
}
|
136
demos/src/com/ibm/icu/dev/demo/impl/DemoUtility.java
Normal file
136
demos/src/com/ibm/icu/dev/demo/impl/DemoUtility.java
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.impl;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.TextComponent;
|
||||
import java.util.Locale;
|
||||
|
||||
public class DemoUtility
|
||||
{
|
||||
public static final Font titleFont = new Font("TimesRoman",Font.BOLD,18);
|
||||
public static final Font labelFont = new Font("TimesRoman",Font.BOLD,14);
|
||||
public static final Font choiceFont = new Font("Helvetica",Font.BOLD,12);
|
||||
public static final Font editFont = new Font("Helvetica",Font.PLAIN,14);
|
||||
public static final Font creditFont = new Font("Helvetica",Font.PLAIN,10);
|
||||
public static final Font numberFont = new Font("sansserif", Font.PLAIN, 14);
|
||||
|
||||
public static final Color bgColor = Color.lightGray;
|
||||
public static final Color choiceColor = Color.white;
|
||||
|
||||
public static final String copyright1 =
|
||||
"Copyright (C) IBM Corp and others. 1997 - 2002 All Rights Reserved";
|
||||
|
||||
/**
|
||||
Provides easy way to use basic functions of GridBagLayout, without
|
||||
the complications. After building a panel, and inserting all the
|
||||
* subcomponents, call this to lay it out in the desired number of columns.
|
||||
*/
|
||||
public static void fixGrid(Container cont, int columns) {
|
||||
GridBagLayout gridbag = new GridBagLayout();
|
||||
cont.setLayout(gridbag);
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.VERTICAL;
|
||||
c.weightx = 1.0;
|
||||
c.insets = new Insets(2,2,2,2);
|
||||
|
||||
Component[] components = cont.getComponents();
|
||||
for (int i = 0; i < components.length; ++i) {
|
||||
// not used int colNumber = i%columns;
|
||||
c.gridwidth = 1; // default
|
||||
if ((i%columns) == columns - 1)
|
||||
c.gridwidth = GridBagConstraints.REMAINDER; // last in grid
|
||||
if (components[i] instanceof Label) {
|
||||
switch (((Label)components[i]).getAlignment()) {
|
||||
case Label.CENTER: c.anchor = GridBagConstraints.CENTER; break;
|
||||
case Label.LEFT: c.anchor = GridBagConstraints.WEST; break;
|
||||
case Label.RIGHT: c.anchor = GridBagConstraints.EAST; break;
|
||||
}
|
||||
}
|
||||
gridbag.setConstraints(components[i], c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Provides easy way to change the spacing around an object in a GridBagLayout.
|
||||
Call AFTER fixGridBag, passing in the container, the component, and the
|
||||
new insets.
|
||||
*/
|
||||
public static void setInsets(Container cont, Component comp, Insets insets) {
|
||||
GridBagLayout gbl = (GridBagLayout)cont.getLayout();
|
||||
GridBagConstraints g = gbl.getConstraints(comp);
|
||||
g.insets = insets;
|
||||
gbl.setConstraints(comp,g);
|
||||
}
|
||||
|
||||
public static Panel createSpacer() {
|
||||
Panel spacer = new Panel();
|
||||
spacer.setLayout(null);
|
||||
spacer.setSize(1000, 1);
|
||||
return spacer;
|
||||
}
|
||||
|
||||
// to avoid goofy updates and misplaced cursors
|
||||
public static void setText(TextComponent area, String newText) {
|
||||
String foo = area.getText();
|
||||
if (foo.equals(newText)) return;
|
||||
area.setText(newText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two locals. Return value is negative
|
||||
* if they're different, and more positive the more
|
||||
* fields that match.
|
||||
*/
|
||||
|
||||
public static int compareLocales(Locale l1, Locale l2)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (l1.getLanguage().equals(l2.getLanguage())) {
|
||||
result += 1;
|
||||
|
||||
if (l1.getCountry().equals(l2.getCountry())) {
|
||||
result += 1;
|
||||
|
||||
if (l1.getVariant().equals(l2.getVariant())) {
|
||||
result += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the G7 locale list for demos.
|
||||
*/
|
||||
public static Locale[] getG7Locales() {
|
||||
return localeList;
|
||||
}
|
||||
private static Locale[] localeList = {
|
||||
new Locale("DA", "DK", ""),
|
||||
new Locale("EN", "US", ""),
|
||||
new Locale("EN", "GB", ""),
|
||||
new Locale("EN", "CA", ""),
|
||||
new Locale("FR", "FR", ""),
|
||||
new Locale("FR", "CA", ""),
|
||||
new Locale("DE", "DE", ""),
|
||||
new Locale("IT", "IT", ""),
|
||||
//new Locale("JA", "JP", ""),
|
||||
};
|
||||
}
|
827
demos/src/com/ibm/icu/dev/demo/impl/DumbTextComponent.java
Normal file
827
demos/src/com/ibm/icu/dev/demo/impl/DumbTextComponent.java
Normal file
|
@ -0,0 +1,827 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.impl;
|
||||
import java.awt.AWTEventMulticaster;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.TextEvent;
|
||||
import java.awt.event.TextListener;
|
||||
import java.text.BreakIterator;
|
||||
|
||||
// LIU: Changed from final to non-final
|
||||
public class DumbTextComponent extends Canvas
|
||||
implements KeyListener, MouseListener, MouseMotionListener, FocusListener
|
||||
{
|
||||
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 8265547730738652151L;
|
||||
|
||||
// private transient static final String copyright =
|
||||
// "Copyright \u00A9 1998, Mark Davis. All Rights Reserved.";
|
||||
private transient static boolean DEBUG = false;
|
||||
|
||||
private String contents = "";
|
||||
private Selection selection = new Selection();
|
||||
private int activeStart = -1;
|
||||
private boolean editable = true;
|
||||
|
||||
private transient Selection tempSelection = new Selection();
|
||||
private transient boolean focus;
|
||||
private transient BreakIterator lineBreaker = BreakIterator.getLineInstance();
|
||||
private transient BreakIterator wordBreaker = BreakIterator.getWordInstance();
|
||||
private transient BreakIterator charBreaker = BreakIterator.getCharacterInstance();
|
||||
private transient int lineAscent;
|
||||
private transient int lineHeight;
|
||||
private transient int lineLeading;
|
||||
private transient int lastHeight = 10;
|
||||
private transient int lastWidth = 50;
|
||||
private static final int MAX_LINES = 200; // LIU: Use symbolic name
|
||||
private transient int[] lineStarts = new int[MAX_LINES]; // LIU
|
||||
private transient int lineCount = 1;
|
||||
|
||||
private transient boolean valid = false;
|
||||
private transient FontMetrics fm;
|
||||
private transient boolean redoLines = true;
|
||||
private transient boolean doubleClick = false;
|
||||
private transient TextListener textListener;
|
||||
private transient ActionListener selectionListener;
|
||||
private transient Image cacheImage;
|
||||
private transient Dimension mySize;
|
||||
private transient int xInset = 5;
|
||||
private transient int yInset = 5;
|
||||
private transient Point startPoint = new Point();
|
||||
private transient Point endPoint = new Point();
|
||||
private transient Point caretPoint = new Point();
|
||||
private transient Point activePoint = new Point();
|
||||
|
||||
//private transient static String clipBoard;
|
||||
|
||||
private static final char CR = '\015'; // LIU
|
||||
|
||||
// ============================================
|
||||
|
||||
public DumbTextComponent() {
|
||||
addMouseListener(this);
|
||||
addMouseMotionListener(this);
|
||||
addKeyListener(this);
|
||||
addFocusListener(this);
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
|
||||
|
||||
}
|
||||
|
||||
// ================ Events ====================
|
||||
|
||||
// public boolean isFocusTraversable() { return true; }
|
||||
|
||||
public void addActionListener(ActionListener l) {
|
||||
selectionListener = AWTEventMulticaster.add(selectionListener, l);
|
||||
}
|
||||
|
||||
public void removeActionListener(ActionListener l) {
|
||||
selectionListener = AWTEventMulticaster.remove(selectionListener, l);
|
||||
}
|
||||
|
||||
public void addTextListener(TextListener l) {
|
||||
textListener = AWTEventMulticaster.add(textListener, l);
|
||||
}
|
||||
|
||||
public void removeTextListener(TextListener l) {
|
||||
textListener = AWTEventMulticaster.remove(textListener, l);
|
||||
}
|
||||
|
||||
private transient boolean pressed;
|
||||
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (DEBUG) System.out.println("mousePressed");
|
||||
if (pressed) {
|
||||
select(e,false);
|
||||
} else {
|
||||
doubleClick = e.getClickCount() > 1;
|
||||
requestFocus();
|
||||
select(e, true);
|
||||
pressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (DEBUG) System.out.println("mouseDragged");
|
||||
select(e, false);
|
||||
}
|
||||
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (DEBUG) System.out.println("mouseReleased");
|
||||
pressed = false;
|
||||
}
|
||||
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
//if (pressed) select(e, false);
|
||||
}
|
||||
|
||||
public void mouseExited(MouseEvent e){
|
||||
//if (pressed) select(e, false);
|
||||
}
|
||||
|
||||
public void mouseClicked(MouseEvent e) {}
|
||||
public void mouseMoved(MouseEvent e) {}
|
||||
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
if (DEBUG) System.out.println("focusGained");
|
||||
focus = true;
|
||||
valid = false;
|
||||
repaint(16);
|
||||
}
|
||||
public void focusLost(FocusEvent e) {
|
||||
if (DEBUG) System.out.println("focusLost");
|
||||
focus = false;
|
||||
valid = false;
|
||||
repaint(16);
|
||||
}
|
||||
|
||||
public void select(MouseEvent e, boolean first) {
|
||||
setKeyStart(-1);
|
||||
point2Offset(e.getPoint(), tempSelection);
|
||||
if (first) {
|
||||
if ((e.getModifiers() & InputEvent.SHIFT_MASK) == 0) {
|
||||
tempSelection.anchor = tempSelection.caret;
|
||||
}
|
||||
}
|
||||
// fix words
|
||||
if (doubleClick) {
|
||||
tempSelection.expand(wordBreaker);
|
||||
}
|
||||
select(tempSelection);
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e) {
|
||||
int code = e.getKeyCode();
|
||||
if (DEBUG) System.out.println("keyPressed "
|
||||
+ hex((char)code) + ", " + hex((char)e.getModifiers()));
|
||||
int start = selection.getStart();
|
||||
int end = selection.getEnd();
|
||||
boolean shift = (e.getModifiers() & InputEvent.SHIFT_MASK) != 0;
|
||||
boolean ctrl = (e.getModifiers() & InputEvent.CTRL_MASK) != 0;
|
||||
|
||||
switch (code) {
|
||||
case KeyEvent.VK_Q:
|
||||
if (!ctrl || !editable) break;
|
||||
setKeyStart(-1);
|
||||
fixHex();
|
||||
break;
|
||||
case KeyEvent.VK_V:
|
||||
if (!ctrl) break;
|
||||
if (!editable) {
|
||||
this.getToolkit().beep();
|
||||
} else {
|
||||
paste();
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_C:
|
||||
if (!ctrl) break;
|
||||
copy();
|
||||
break;
|
||||
case KeyEvent.VK_X:
|
||||
if (!ctrl) break;
|
||||
if (!editable) {
|
||||
this.getToolkit().beep();
|
||||
} else {
|
||||
copy();
|
||||
insertText("");
|
||||
}
|
||||
break;
|
||||
case KeyEvent.VK_A:
|
||||
if (!ctrl) break;
|
||||
setKeyStart(-1);
|
||||
select(Integer.MAX_VALUE, 0, false);
|
||||
break;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
setKeyStart(-1);
|
||||
tempSelection.set(selection);
|
||||
tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, +1, shift);
|
||||
select(tempSelection);
|
||||
break;
|
||||
case KeyEvent.VK_LEFT:
|
||||
setKeyStart(-1);
|
||||
tempSelection.set(selection);
|
||||
tempSelection.nextBound(ctrl ? wordBreaker : charBreaker, -1, shift);
|
||||
select(tempSelection);
|
||||
break;
|
||||
case KeyEvent.VK_UP: // LIU: Add support for up arrow
|
||||
setKeyStart(-1);
|
||||
tempSelection.set(selection);
|
||||
tempSelection.caret = lineDelta(tempSelection.caret, -1);
|
||||
if (!shift) {
|
||||
tempSelection.anchor = tempSelection.caret;
|
||||
}
|
||||
select(tempSelection);
|
||||
break;
|
||||
case KeyEvent.VK_DOWN: // LIU: Add support for down arrow
|
||||
setKeyStart(-1);
|
||||
tempSelection.set(selection);
|
||||
tempSelection.caret = lineDelta(tempSelection.caret, +1);
|
||||
if (!shift) {
|
||||
tempSelection.anchor = tempSelection.caret;
|
||||
}
|
||||
select(tempSelection);
|
||||
break;
|
||||
case KeyEvent.VK_DELETE: // LIU: Add delete key support
|
||||
if (!editable) break;
|
||||
setKeyStart(-1);
|
||||
if (contents.length() == 0) break;
|
||||
start = selection.getStart();
|
||||
end = selection.getEnd();
|
||||
if (start == end) {
|
||||
++end;
|
||||
if (end > contents.length()) {
|
||||
getToolkit().beep();
|
||||
return;
|
||||
}
|
||||
}
|
||||
replaceRange("", start, end);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void copy() {
|
||||
Clipboard cb = this.getToolkit().getSystemClipboard();
|
||||
StringSelection ss = new StringSelection(
|
||||
contents.substring(selection.getStart(), selection.getEnd()));
|
||||
cb.setContents(ss, ss);
|
||||
}
|
||||
|
||||
void paste () {
|
||||
Clipboard cb = this.getToolkit().getSystemClipboard();
|
||||
Transferable t = cb.getContents(this);
|
||||
if (t == null) {
|
||||
this.getToolkit().beep();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String temp = (String) t.getTransferData(DataFlavor.stringFlavor);
|
||||
insertText(temp);
|
||||
} catch (Exception e) {
|
||||
this.getToolkit().beep();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LIU: Given an offset into contents, moves up or down by lines,
|
||||
* according to lineStarts[].
|
||||
* @param off the offset into contents
|
||||
* @param delta how many lines to move up (< 0) or down (> 0)
|
||||
* @return the new offset into contents
|
||||
*/
|
||||
private int lineDelta(int off, int delta) {
|
||||
int line = findLine(off, false);
|
||||
int posInLine = off - lineStarts[line];
|
||||
// System.out.println("off=" + off + " at " + line + ":" + posInLine);
|
||||
line += delta;
|
||||
if (line < 0) {
|
||||
line = posInLine = 0;
|
||||
} else if (line >= lineCount) {
|
||||
return contents.length();
|
||||
}
|
||||
off = lineStarts[line] + posInLine;
|
||||
if (off >= lineStarts[line+1]) {
|
||||
off = lineStarts[line+1] - 1;
|
||||
}
|
||||
return off;
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e) {
|
||||
int code = e.getKeyCode();
|
||||
if (DEBUG) System.out.println("keyReleased "
|
||||
+ hex((char)code) + ", " + hex((char)e.getModifiers()));
|
||||
}
|
||||
|
||||
public void keyTyped(KeyEvent e) {
|
||||
char ch = e.getKeyChar();
|
||||
if (DEBUG) System.out.println("keyTyped "
|
||||
+ hex((char)ch) + ", " + hex((char)e.getModifiers()));
|
||||
if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0) return;
|
||||
int start, end;
|
||||
switch (ch) {
|
||||
case KeyEvent.CHAR_UNDEFINED:
|
||||
break;
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
//setKeyStart(-1);
|
||||
if (!editable) break;
|
||||
if (contents.length() == 0) break;
|
||||
start = selection.getStart();
|
||||
end = selection.getEnd();
|
||||
if (start == end) {
|
||||
--start;
|
||||
if (start < 0) {
|
||||
getToolkit().beep(); // LIU: Add audio feedback of NOP
|
||||
return;
|
||||
}
|
||||
}
|
||||
replaceRange("", start, end);
|
||||
break;
|
||||
case KeyEvent.VK_DELETE:
|
||||
//setKeyStart(-1);
|
||||
if (!editable) break;
|
||||
if (contents.length() == 0) break;
|
||||
start = selection.getStart();
|
||||
end = selection.getEnd();
|
||||
if (start == end) {
|
||||
++end;
|
||||
if (end > contents.length()) {
|
||||
getToolkit().beep(); // LIU: Add audio feedback of NOP
|
||||
return;
|
||||
}
|
||||
}
|
||||
replaceRange("", start, end);
|
||||
break;
|
||||
default:
|
||||
if (!editable) break;
|
||||
// LIU: Dispatch to subclass API
|
||||
handleKeyTyped(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// LIU: Subclass API for handling of key typing
|
||||
protected void handleKeyTyped(KeyEvent e) {
|
||||
insertText(String.valueOf(e.getKeyChar()));
|
||||
}
|
||||
|
||||
protected void setKeyStart(int keyStart) {
|
||||
if (activeStart != keyStart) {
|
||||
activeStart = keyStart;
|
||||
repaint(10);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateKeyStart() {
|
||||
if (activeStart > selection.getStart()) {
|
||||
activeStart = selection.getStart();
|
||||
repaint(10);
|
||||
}
|
||||
}
|
||||
|
||||
protected int getKeyStart() {
|
||||
return activeStart;
|
||||
}
|
||||
|
||||
// ===================== Control ======================
|
||||
|
||||
public synchronized void setEditable(boolean b) {
|
||||
editable = b;
|
||||
}
|
||||
|
||||
public boolean isEditable() {
|
||||
return editable;
|
||||
}
|
||||
|
||||
public void select(Selection newSelection) {
|
||||
newSelection.pin(contents);
|
||||
if (!selection.equals(newSelection)) {
|
||||
selection.set(newSelection);
|
||||
if (selectionListener != null) {
|
||||
selectionListener.actionPerformed(
|
||||
new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
|
||||
"Selection Changed", 0));
|
||||
}
|
||||
repaint(10);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void select(int start, int end) {
|
||||
select(start, end, false);
|
||||
}
|
||||
|
||||
public void select(int start, int end, boolean clickAfter) {
|
||||
tempSelection.set(start, end, clickAfter);
|
||||
select(tempSelection);
|
||||
}
|
||||
|
||||
public int getSelectionStart() {
|
||||
return selection.getStart();
|
||||
}
|
||||
|
||||
public int getSelectionEnd() {
|
||||
return selection.getEnd();
|
||||
}
|
||||
|
||||
public void setBounds(int x, int y, int w, int h) {
|
||||
super.setBounds(x,y,w,h);
|
||||
redoLines = true;
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(lastWidth,lastHeight);
|
||||
}
|
||||
|
||||
public Dimension getMaximumSize() {
|
||||
return new Dimension(lastWidth,lastHeight);
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
return new Dimension(lastHeight,lastHeight);
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
setText2(text);
|
||||
select(tempSelection.set(selection).pin(contents));
|
||||
}
|
||||
|
||||
public void setText2(String text) {
|
||||
contents = text;
|
||||
charBreaker.setText(text);
|
||||
wordBreaker.setText(text);
|
||||
lineBreaker.setText(text);
|
||||
redoLines = true;
|
||||
if (textListener != null)
|
||||
textListener.textValueChanged(
|
||||
new TextEvent(this, TextEvent.TEXT_VALUE_CHANGED));
|
||||
repaint(16);
|
||||
}
|
||||
|
||||
public void insertText(String text) {
|
||||
if (activeStart == -1) activeStart = selection.getStart();
|
||||
replaceRange(text, selection.getStart(), selection.getEnd());
|
||||
}
|
||||
|
||||
public void replaceRange(String s, int start, int end) {
|
||||
setText2(contents.substring(0,start) + s
|
||||
+ contents.substring(end));
|
||||
select(tempSelection.set(selection).
|
||||
fixAfterReplace(start, end, s.length()));
|
||||
validateKeyStart();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
public void setFont(Font font) {
|
||||
super.setFont(font);
|
||||
redoLines = true;
|
||||
repaint(16);
|
||||
}
|
||||
|
||||
// ================== Graphics ======================
|
||||
|
||||
public void update(Graphics g) {
|
||||
if (DEBUG) System.out.println("update");
|
||||
paint(g);
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
mySize = getSize();
|
||||
if (cacheImage == null
|
||||
|| cacheImage.getHeight(this) != mySize.height
|
||||
|| cacheImage.getWidth(this) != mySize.width) {
|
||||
cacheImage = createImage(mySize.width, mySize.height);
|
||||
valid = false;
|
||||
}
|
||||
if (!valid || redoLines) {
|
||||
if (DEBUG) System.out.println("painting");
|
||||
paint2(cacheImage.getGraphics());
|
||||
valid = true;
|
||||
}
|
||||
//getToolkit().sync();
|
||||
if (DEBUG) System.out.println("copying");
|
||||
g.drawImage(cacheImage,
|
||||
0, 0, mySize.width, mySize.height,
|
||||
0, 0, mySize.width, mySize.height,
|
||||
this);
|
||||
}
|
||||
|
||||
public void paint2(Graphics g) {
|
||||
g.clearRect(0, 0, mySize.width, mySize.height);
|
||||
if (DEBUG) System.out.println("print");
|
||||
if (focus) g.setColor(Color.black);
|
||||
else g.setColor(Color.gray);
|
||||
g.drawRect(0,0,mySize.width-1,mySize.height-1);
|
||||
g.setClip(1,1,
|
||||
mySize.width-2,mySize.height-2);
|
||||
g.setColor(Color.black);
|
||||
g.setFont(getFont());
|
||||
fm = g.getFontMetrics();
|
||||
lineAscent = fm.getAscent();
|
||||
lineLeading = fm.getLeading();
|
||||
lineHeight = lineAscent + fm.getDescent() + lineLeading;
|
||||
int y = yInset + lineAscent;
|
||||
String lastSubstring = "";
|
||||
if (redoLines) fixLineStarts(mySize.width-xInset-xInset);
|
||||
for (int i = 0; i < lineCount; y += lineHeight, ++i) {
|
||||
// LIU: Don't display terminating ^M characters
|
||||
int lim = lineStarts[i+1];
|
||||
if (lim > 0 && contents.length() > 0 &&
|
||||
contents.charAt(lim-1) == CR) --lim;
|
||||
lastSubstring = contents.substring(lineStarts[i],lim);
|
||||
g.drawString(lastSubstring, xInset, y);
|
||||
}
|
||||
drawSelection(g, lastSubstring);
|
||||
lastHeight = y + yInset - lineHeight + yInset;
|
||||
lastWidth = mySize.width-xInset-xInset;
|
||||
}
|
||||
|
||||
void paintRect(Graphics g, int x, int y, int w, int h) {
|
||||
if (focus) {
|
||||
g.fillRect(x, y, w, h);
|
||||
} else {
|
||||
g.drawRect(x, y, w-1, h-1);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawSelection(Graphics g, String lastSubstring) {
|
||||
g.setXORMode(Color.black);
|
||||
if (activeStart != -1) {
|
||||
offset2Point(activeStart, false, activePoint);
|
||||
g.setColor(Color.magenta);
|
||||
int line = activePoint.x - 1;
|
||||
g.fillRect(line, activePoint.y, 1, lineHeight);
|
||||
}
|
||||
if (selection.isCaret()) {
|
||||
offset2Point(selection.caret, selection.clickAfter, caretPoint);
|
||||
} else {
|
||||
if (focus) g.setColor(Color.blue);
|
||||
else g.setColor(Color.yellow);
|
||||
offset2Point(selection.getStart(), true, startPoint);
|
||||
offset2Point(selection.getEnd(), false, endPoint);
|
||||
if (selection.getStart() == selection.caret)
|
||||
caretPoint.setLocation(startPoint);
|
||||
else caretPoint.setLocation(endPoint);
|
||||
if (startPoint.y == endPoint.y) {
|
||||
paintRect(g, startPoint.x, startPoint.y,
|
||||
Math.max(1,endPoint.x-startPoint.x), lineHeight);
|
||||
} else {
|
||||
paintRect(g, startPoint.x, startPoint.y,
|
||||
(mySize.width-xInset)-startPoint.x, lineHeight);
|
||||
if (startPoint.y + lineHeight < endPoint.y)
|
||||
paintRect(g, xInset, startPoint.y + lineHeight,
|
||||
(mySize.width-xInset)-xInset, endPoint.y - startPoint.y - lineHeight);
|
||||
paintRect(g, xInset, endPoint.y, endPoint.x-xInset, lineHeight);
|
||||
}
|
||||
}
|
||||
if (focus || selection.isCaret()) {
|
||||
if (focus) g.setColor(Color.green);
|
||||
else g.setColor(Color.red);
|
||||
int line = caretPoint.x - (selection.clickAfter ? 0 : 1);
|
||||
g.fillRect(line, caretPoint.y, 1, lineHeight);
|
||||
int w = lineHeight/12 + 1;
|
||||
int braces = line - (selection.clickAfter ? -1 : w);
|
||||
g.fillRect(braces, caretPoint.y, w, 1);
|
||||
g.fillRect(braces, caretPoint.y + lineHeight - 1, w, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public Point offset2Point(int off, boolean start, Point p) {
|
||||
int line = findLine(off, start);
|
||||
int width = 0;
|
||||
try {
|
||||
width = fm.stringWidth(
|
||||
contents.substring(lineStarts[line], off));
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
p.x = width + xInset;
|
||||
if (p.x > mySize.width - xInset)
|
||||
p.x = mySize.width - xInset;
|
||||
p.y = lineHeight * line + yInset;
|
||||
return p;
|
||||
}
|
||||
|
||||
private int findLine(int off, boolean start) {
|
||||
// if it is start, then go to the next line!
|
||||
if (start) ++off;
|
||||
for (int i = 1; i < lineCount; ++i) {
|
||||
// LIU: This was <= ; changed to < to make caret after
|
||||
// final CR in line appear at START of next line.
|
||||
if (off < lineStarts[i]) return i-1;
|
||||
}
|
||||
// LIU: Check for special case; after CR at end of the last line
|
||||
if (off == lineStarts[lineCount] &&
|
||||
off > 0 && contents.length() > 0 && contents.charAt(off-1) == CR) {
|
||||
return lineCount;
|
||||
}
|
||||
return lineCount-1;
|
||||
}
|
||||
|
||||
// offsets on any line will go from start,true to end,false
|
||||
// excluding start,false and end,true
|
||||
public Selection point2Offset(Point p, Selection o) {
|
||||
if (p.y < yInset) {
|
||||
o.caret = 0;
|
||||
o.clickAfter = true;
|
||||
return o;
|
||||
}
|
||||
int line = (p.y - yInset)/lineHeight;
|
||||
if (line >= lineCount) {
|
||||
o.caret = contents.length();
|
||||
o.clickAfter = false;
|
||||
return o;
|
||||
}
|
||||
int target = p.x - xInset;
|
||||
if (target <= 0) {
|
||||
o.caret = lineStarts[line];
|
||||
o.clickAfter = true;
|
||||
return o;
|
||||
}
|
||||
int lowGuess = lineStarts[line];
|
||||
int lowWidth = 0;
|
||||
int highGuess = lineStarts[line+1];
|
||||
int highWidth = fm.stringWidth(contents.substring(lineStarts[line],highGuess));
|
||||
if (target >= highWidth) {
|
||||
o.caret = lineStarts[line+1];
|
||||
o.clickAfter = false;
|
||||
return o;
|
||||
}
|
||||
while (lowGuess < highGuess - 1) {
|
||||
int guess = (lowGuess + highGuess)/2;
|
||||
int width = fm.stringWidth(contents.substring(lineStarts[line],guess));
|
||||
if (width <= target) {
|
||||
lowGuess = guess;
|
||||
lowWidth = width;
|
||||
if (width == target) break;
|
||||
} else {
|
||||
highGuess = guess;
|
||||
highWidth = width;
|
||||
}
|
||||
}
|
||||
// at end, either lowWidth < target < width(low+1), or lowWidth = target
|
||||
int highBound = charBreaker.following(lowGuess);
|
||||
int lowBound = charBreaker.previous();
|
||||
// we are now at character boundaries
|
||||
if (lowBound != lowGuess)
|
||||
lowWidth = fm.stringWidth(contents.substring(lineStarts[line],lowBound));
|
||||
if (highBound != highGuess)
|
||||
highWidth = fm.stringWidth(contents.substring(lineStarts[line],highBound));
|
||||
// we now have the right widths
|
||||
if (target - lowWidth < highWidth - target) {
|
||||
o.caret = lowBound;
|
||||
o.clickAfter = true;
|
||||
} else {
|
||||
o.caret = highBound;
|
||||
o.clickAfter = false;
|
||||
}
|
||||
// we now have the closest!
|
||||
return o;
|
||||
}
|
||||
|
||||
private void fixLineStarts(int width) {
|
||||
lineCount = 1;
|
||||
lineStarts[0] = 0;
|
||||
if (contents.length() == 0) {
|
||||
lineStarts[1] = 0;
|
||||
return;
|
||||
}
|
||||
int end = 0;
|
||||
// LIU: Add check for MAX_LINES
|
||||
for (int start = 0; start < contents.length() && lineCount < MAX_LINES;
|
||||
start = end) {
|
||||
end = nextLine(fm, start, width);
|
||||
lineStarts[lineCount++] = end;
|
||||
if (end == start) { // LIU: Assertion
|
||||
throw new RuntimeException("nextLine broken");
|
||||
}
|
||||
}
|
||||
--lineCount;
|
||||
redoLines = false;
|
||||
}
|
||||
|
||||
// LIU: Enhanced to wrap long lines. Bug with return of start fixed.
|
||||
public int nextLine(FontMetrics fMtr, int start, int width) {
|
||||
int len = contents.length();
|
||||
for (int i = start; i < len; ++i) {
|
||||
// check for line separator
|
||||
char ch = (contents.charAt(i));
|
||||
if (ch >= 0x000A && ch <= 0x000D || ch == 0x2028 || ch == 0x2029) {
|
||||
len = i + 1;
|
||||
if (ch == 0x000D && i+1 < len && contents.charAt(i+1) == 0x000A) // crlf
|
||||
++len; // grab extra char
|
||||
break;
|
||||
}
|
||||
}
|
||||
String subject = contents.substring(start,len);
|
||||
if (visibleWidth(fMtr, subject) <= width)
|
||||
return len;
|
||||
|
||||
// LIU: Remainder of this method rewritten to accomodate lines
|
||||
// longer than the component width by first trying to break
|
||||
// into lines; then words; finally chars.
|
||||
int n = findFittingBreak(fMtr, subject, width, lineBreaker);
|
||||
if (n == 0) {
|
||||
n = findFittingBreak(fMtr, subject, width, wordBreaker);
|
||||
}
|
||||
if (n == 0) {
|
||||
n = findFittingBreak(fMtr, subject, width, charBreaker);
|
||||
}
|
||||
return n > 0 ? start + n : len;
|
||||
}
|
||||
|
||||
/**
|
||||
* LIU: Finds the longest substring that fits a given width
|
||||
* composed of subunits returned by a BreakIterator. If the smallest
|
||||
* subunit is too long, returns 0.
|
||||
* @param fMtr metrics to use
|
||||
* @param line the string to be fix into width
|
||||
* @param width line.substring(0, result) must be <= width
|
||||
* @param breaker the BreakIterator that will be used to find subunits
|
||||
* @return maximum characters, at boundaries returned by breaker,
|
||||
* that fit into width, or zero on failure
|
||||
*/
|
||||
private int findFittingBreak(FontMetrics fMtr, String line, int width,
|
||||
BreakIterator breaker) {
|
||||
breaker.setText(line);
|
||||
int last = breaker.first();
|
||||
int end = breaker.next();
|
||||
while (end != BreakIterator.DONE &&
|
||||
visibleWidth(fMtr, line.substring(0, end)) <= width) {
|
||||
last = end;
|
||||
end = breaker.next();
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
public int visibleWidth(FontMetrics fMtr, String s) {
|
||||
int i;
|
||||
for (i = s.length()-1; i >= 0; --i) {
|
||||
char ch = s.charAt(i);
|
||||
if (!(ch == ' ' || ch >= 0x000A && ch <= 0x000D || ch == 0x2028 || ch == 0x2029))
|
||||
return fMtr.stringWidth(s.substring(0,i+1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// =============== Utility ====================
|
||||
|
||||
private void fixHex() {
|
||||
if (selection.getEnd() == 0) return;
|
||||
int store = 0;
|
||||
int places = 1;
|
||||
int count = 0;
|
||||
int min = Math.min(8,selection.getEnd());
|
||||
for (int i = 0; i < min; ++i) {
|
||||
char ch = contents.charAt(selection.getEnd()-1-i);
|
||||
int value = Character.getNumericValue(ch);
|
||||
if (value < 0 || value > 15) break;
|
||||
store += places * value;
|
||||
++count;
|
||||
places *= 16;
|
||||
}
|
||||
String add = "";
|
||||
int bottom = store & 0xFFFF;
|
||||
if (store >= 0xD8000000 && store < 0xDC000000
|
||||
&& bottom >= 0xDC00 && bottom < 0xE000) { // surrogates
|
||||
add = "" + (char)(store >> 16) + (char)bottom;
|
||||
} else if (store > 0xFFFF && store <= 0x10FFFF) {
|
||||
store -= 0x10000;
|
||||
add = "" + (char)(((store >> 10) & 0x3FF) + 0xD800)
|
||||
+ (char)((store & 0x3FF) + 0xDC00);
|
||||
|
||||
} else if (count >= 4) {
|
||||
count = 4;
|
||||
add = ""+(char)(store & 0xFFFF);
|
||||
} else {
|
||||
count = 1;
|
||||
char ch = contents.charAt(selection.getEnd()-1);
|
||||
add = hex(ch);
|
||||
if (ch >= 0xDC00 && ch <= 0xDFFF && selection.getEnd() > 1) {
|
||||
ch = contents.charAt(selection.getEnd()-2);
|
||||
if (ch >= 0xD800 && ch <= 0xDBFF) {
|
||||
count = 2;
|
||||
add = hex(ch) + add;
|
||||
}
|
||||
}
|
||||
}
|
||||
replaceRange(add, selection.getEnd()-count, selection.getEnd());
|
||||
}
|
||||
|
||||
public static String hex(char ch) {
|
||||
String result = Integer.toString(ch,16).toUpperCase();
|
||||
result = "0000".substring(result.length(),4) + result;
|
||||
return result;
|
||||
}
|
||||
}
|
161
demos/src/com/ibm/icu/dev/demo/impl/Selection.java
Normal file
161
demos/src/com/ibm/icu/dev/demo/impl/Selection.java
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.impl;
|
||||
import java.text.BreakIterator;
|
||||
|
||||
public final class Selection {
|
||||
|
||||
public int anchor;
|
||||
public int caret;
|
||||
public boolean clickAfter;
|
||||
|
||||
public int getStart() {
|
||||
return anchor < caret ? anchor : caret;
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return anchor > caret ? anchor : caret;
|
||||
}
|
||||
|
||||
public boolean isCaret() {
|
||||
return anchor == caret;
|
||||
}
|
||||
|
||||
public Selection set(Selection other) {
|
||||
anchor = other.anchor;
|
||||
caret = other.caret;
|
||||
clickAfter = other.clickAfter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Selection set(int anchor, int caret, boolean clickAfter) {
|
||||
this.anchor = anchor;
|
||||
this.caret = caret;
|
||||
this.clickAfter = clickAfter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
Selection other2 = (Selection)other;
|
||||
return anchor == other2.anchor
|
||||
&& caret == other2.caret
|
||||
&& clickAfter == other2.clickAfter;
|
||||
}
|
||||
|
||||
public boolean isLessThan(Selection other) {
|
||||
return getStart() < other.getEnd();
|
||||
}
|
||||
|
||||
public Selection pin(String text) {
|
||||
if (anchor > text.length()) {
|
||||
anchor = text.length();
|
||||
} else if (anchor < 0) {
|
||||
anchor = 0;
|
||||
}
|
||||
if (caret > text.length()) {
|
||||
caret = text.length();
|
||||
clickAfter = true;
|
||||
} else if (caret < 0) {
|
||||
caret = 0;
|
||||
clickAfter = false;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Selection swap(Selection after) {
|
||||
int temp = anchor;
|
||||
anchor = after.anchor;
|
||||
after.anchor = temp;
|
||||
temp = caret;
|
||||
caret = after.caret;
|
||||
after.caret = temp;
|
||||
boolean b = clickAfter;
|
||||
clickAfter = after.clickAfter;
|
||||
after.clickAfter = b;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Selection fixAfterReplace(int start, int end, int len) {
|
||||
if (anchor >= start) {
|
||||
if (anchor < end) anchor = end;
|
||||
anchor = start + len + anchor - end;
|
||||
}
|
||||
if (caret >= start) {
|
||||
if (caret < end) caret = end;
|
||||
caret = start + len + caret - end;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Mac & Windows considerably different
|
||||
// Mac: end++. If start!=end, start=end
|
||||
// SHIFT: move end right
|
||||
// CTL: no different
|
||||
// Windows:
|
||||
// UNSHIFTED: if start!=end, start = end, else start=end=end+1;
|
||||
// anchor = tip = start
|
||||
// SHIFT: tip++
|
||||
// CTL: if start!=end, start = end = nextbound(end-1),
|
||||
// else start=end=nextbound(end)
|
||||
// anchor = tip = start
|
||||
// CTL/SHIFT: tip = nextbound(tip)
|
||||
|
||||
public Selection nextBound(BreakIterator breaker,
|
||||
int direction, boolean extend) {
|
||||
if (!extend && anchor != caret) caret -= direction;
|
||||
caret = next(caret, breaker, direction, true);
|
||||
if (!extend) anchor = caret;
|
||||
clickAfter = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
// expand start and end to word breaks--if they are not already on one
|
||||
public void expand(BreakIterator breaker) {
|
||||
if (anchor <= caret) {
|
||||
anchor = next(anchor,breaker,-1,false);
|
||||
caret = next(caret,breaker,1,false);
|
||||
/*
|
||||
try {
|
||||
breaker.following(anchor);
|
||||
anchor = breaker.previous();
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
caret = breaker.following(caret-1);
|
||||
} catch (Exception e) {}
|
||||
*/
|
||||
} else {
|
||||
anchor = next(anchor,breaker,1,false);
|
||||
caret = next(caret,breaker,-1,false);
|
||||
/*
|
||||
try {
|
||||
breaker.following(caret);
|
||||
caret = breaker.previous();
|
||||
} catch (Exception e) {}
|
||||
try {
|
||||
anchor = breaker.following(anchor-1);
|
||||
} catch (Exception e) {}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// different = false - move to next boundary, unless on one
|
||||
// true - move to next boundary, even if on one
|
||||
public static int next(int position, BreakIterator breaker,
|
||||
int direction, boolean different) {
|
||||
if (!different) position -= direction;
|
||||
try {
|
||||
if (direction > 0) {
|
||||
position = breaker.following(position);
|
||||
} else {
|
||||
breaker.following(position-1);
|
||||
position = breaker.previous();
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
12
demos/src/com/ibm/icu/dev/demo/impl/package.html
Normal file
12
demos/src/com/ibm/icu/dev/demo/impl/package.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<!-- Copyright (C) 2000-2004, International Business Machines Corporation and
|
||||
others. All Rights Reserved.
|
||||
|
||||
-->
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
Shared utilities for demo applications and Applets.
|
||||
</body>
|
||||
</html>
|
114
demos/src/com/ibm/icu/dev/demo/number/CurrencyDemo.java
Normal file
114
demos/src/com/ibm/icu/dev/demo/number/CurrencyDemo.java
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2003-2010, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Mark Davis
|
||||
* Created: May 22 2003
|
||||
* Since: ICU 2.6
|
||||
**********************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.number;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.icu.impl.Utility;
|
||||
import com.ibm.icu.text.DecimalFormat;
|
||||
import com.ibm.icu.text.DecimalFormatSymbols;
|
||||
import com.ibm.icu.text.NumberFormat;
|
||||
import com.ibm.icu.util.Currency;
|
||||
|
||||
/**
|
||||
* Demonstration code to illustrate how to obtain ICU 2.6-like currency
|
||||
* behavior using pre-ICU 2.6 ICU4J.
|
||||
* @author Mark Davis
|
||||
*/
|
||||
public class CurrencyDemo {
|
||||
|
||||
public static void main(String[] args) {
|
||||
testFormatHack(true);
|
||||
}
|
||||
|
||||
static NumberFormat getCurrencyFormat(Currency currency,
|
||||
Locale displayLocale,
|
||||
boolean ICU26) {
|
||||
// code for ICU 2.6
|
||||
if (ICU26) {
|
||||
NumberFormat result = NumberFormat.getCurrencyInstance(displayLocale);
|
||||
result.setCurrency(currency);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ugly work-around for 2.4
|
||||
DecimalFormat result = (DecimalFormat)NumberFormat.getCurrencyInstance(displayLocale);
|
||||
HackCurrencyInfo hack = (HackCurrencyInfo)(hackData.get(currency.getCurrencyCode()));
|
||||
result.setMinimumFractionDigits(hack.decimals);
|
||||
result.setMaximumFractionDigits(hack.decimals);
|
||||
result.setRoundingIncrement(hack.rounding);
|
||||
DecimalFormatSymbols symbols = result.getDecimalFormatSymbols();
|
||||
symbols.setCurrencySymbol(hack.symbol);
|
||||
result.setDecimalFormatSymbols(symbols);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Map hackData = new HashMap();
|
||||
static class HackCurrencyInfo {
|
||||
int decimals;
|
||||
double rounding;
|
||||
String symbol;
|
||||
HackCurrencyInfo(int decimals, double rounding, String symbol) {
|
||||
this.decimals = decimals;
|
||||
this.rounding = rounding;
|
||||
this.symbol = symbol;
|
||||
}
|
||||
}
|
||||
static {
|
||||
hackData.put("USD", new HackCurrencyInfo(2, 0, "$"));
|
||||
hackData.put("GBP", new HackCurrencyInfo(2, 0, "\u00A3"));
|
||||
hackData.put("JPY", new HackCurrencyInfo(0, 0, "\u00A5"));
|
||||
hackData.put("EUR", new HackCurrencyInfo(2, 0, "\u20AC"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk through all locales and compare the output of the ICU26
|
||||
* currency format with the "hacked" currency format.
|
||||
* @param quiet if true, only display discrepancies. Otherwise,
|
||||
* display all results.
|
||||
*/
|
||||
static void testFormatHack(boolean quiet) {
|
||||
String[] testCurrencies = {"USD","GBP","JPY","EUR"};
|
||||
Locale[] testLocales = NumberFormat.getAvailableLocales();
|
||||
for (int i = 0; i < testLocales.length; ++i) {
|
||||
// since none of this should vary by country, we'll just do by language
|
||||
if (!testLocales[i].getCountry().equals("")) continue;
|
||||
boolean noOutput = true;
|
||||
if (!quiet) {
|
||||
System.out.println(testLocales[i].getDisplayName());
|
||||
noOutput = false;
|
||||
}
|
||||
for (int j = 0; j < testCurrencies.length; ++j) {
|
||||
NumberFormat nf26 = getCurrencyFormat(Currency.getInstance(testCurrencies[j]), testLocales[i], true);
|
||||
String str26 = nf26.format(1234.567);
|
||||
if (!quiet) {
|
||||
System.out.print("\t" + Utility.escape(str26));
|
||||
}
|
||||
NumberFormat nf24 = getCurrencyFormat(Currency.getInstance(testCurrencies[j]), testLocales[i], false);
|
||||
String str24 = nf24.format(1234.567);
|
||||
if (!str24.equals(str26)) {
|
||||
if (noOutput) {
|
||||
System.out.println(testLocales[i].getDisplayName());
|
||||
noOutput = false;
|
||||
}
|
||||
if (quiet) {
|
||||
System.out.print("\t" + Utility.escape(str26));
|
||||
}
|
||||
System.out.print(" (" + Utility.escape(str24) + ")");
|
||||
}
|
||||
}
|
||||
if (!noOutput) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
580
demos/src/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java
Normal file
580
demos/src/com/ibm/icu/dev/demo/rbnf/RbnfDemo.java
Normal file
|
@ -0,0 +1,580 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.rbnf;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.CardLayout;
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.Choice;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Panel;
|
||||
import java.awt.ScrollPane;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.TextComponent;
|
||||
import java.awt.TextField;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.TextEvent;
|
||||
import java.awt.event.TextListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.text.BreakIterator;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DemoApplet;
|
||||
import com.ibm.icu.text.RuleBasedNumberFormat;
|
||||
|
||||
public class RbnfDemo extends DemoApplet {
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -9119861296873763536L;
|
||||
|
||||
/**
|
||||
* Puts a copyright in the .class file
|
||||
*/
|
||||
// private static final String copyrightNotice
|
||||
// = "Copyright \u00a91997-1998 IBM Corp. All rights reserved.";
|
||||
|
||||
/*
|
||||
* code to run the demo as an application
|
||||
*/
|
||||
public static void main(String[] argv) {
|
||||
new RbnfDemo().showDemo();
|
||||
}
|
||||
|
||||
protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
|
||||
return new Dimension(430,270);
|
||||
}
|
||||
|
||||
protected Frame createDemoFrame(DemoApplet applet) {
|
||||
final Frame window = new Frame("Number Spellout Demo");
|
||||
window.setSize(800, 600);
|
||||
window.setLayout(new BorderLayout());
|
||||
|
||||
Panel mainPanel = new Panel();
|
||||
mainPanel.setLayout(new GridLayout(1,2));
|
||||
|
||||
commentaryField = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
|
||||
commentaryField.setSize(800, 50);
|
||||
commentaryField.setText(RbnfSampleRuleSets.sampleRuleSetCommentary[0]);
|
||||
commentaryField.setEditable(false);
|
||||
commentaryField.setFont(new Font("Helvetica", Font.PLAIN, 14));
|
||||
|
||||
spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.usEnglish, Locale.US);
|
||||
spelloutFormatter.setLenientParseMode(lenientParse);
|
||||
populateRuleSetMenu();
|
||||
numberFormatter = new DecimalFormat("#,##0.##########");
|
||||
parsePosition = new ParsePosition(0);
|
||||
theNumber = 0;
|
||||
|
||||
numberField = new TextField();
|
||||
numberField.setFont(new Font("Serif", Font.PLAIN, 24));
|
||||
textField = new DemoTextFieldHolder();
|
||||
textField.setFont(new Font("Serif", Font.PLAIN, 24));
|
||||
rulesField = new DemoTextFieldHolder();
|
||||
rulesField.setFont(new Font("Serif", Font.PLAIN, 14));
|
||||
lenientParseButton = new Checkbox("Lenient parse", lenientParse);
|
||||
|
||||
numberField.addTextListener(new TextListener() {
|
||||
public void textValueChanged(TextEvent e) {
|
||||
if (!numberFieldHasFocus)
|
||||
return;
|
||||
|
||||
String fieldText = ((TextComponent)(e.getSource())).getText();
|
||||
parsePosition.setIndex(0);
|
||||
Number temp = numberFormatter.parse(fieldText, parsePosition);
|
||||
if (temp == null || parsePosition.getIndex() == 0) {
|
||||
theNumber = 0;
|
||||
textField.setText("PARSE ERROR");
|
||||
}
|
||||
else {
|
||||
theNumber = temp.doubleValue();
|
||||
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
numberField.addFocusListener(new FocusAdapter() {
|
||||
public void focusLost(FocusEvent e) {
|
||||
numberFieldHasFocus = false;
|
||||
numberField.setText(numberFormatter.format(theNumber));
|
||||
}
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
numberFieldHasFocus = true;
|
||||
numberField.selectAll();
|
||||
}
|
||||
} );
|
||||
|
||||
textField.addKeyListener(new KeyAdapter() {
|
||||
public void keyTyped(KeyEvent e) {
|
||||
if (e.getKeyChar() == '\t') {
|
||||
String fieldText = ((TextComponent)(e.getSource())).getText();
|
||||
parsePosition.setIndex(0);
|
||||
theNumber = spelloutFormatter.parse(fieldText, parsePosition)
|
||||
.doubleValue();
|
||||
if (parsePosition.getIndex() == 0) {
|
||||
theNumber = 0;
|
||||
numberField.setText("PARSE ERROR");
|
||||
textField.selectAll();
|
||||
}
|
||||
else if (parsePosition.getIndex() < fieldText.length()) {
|
||||
textField.select(parsePosition.getIndex(), fieldText.length());
|
||||
numberField.setText(numberFormatter.format(theNumber));
|
||||
}
|
||||
else {
|
||||
textField.selectAll();
|
||||
numberField.setText(numberFormatter.format(theNumber));
|
||||
}
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
textField.addFocusListener(new FocusAdapter() {
|
||||
public void focusLost(FocusEvent e) {
|
||||
String fieldText = ((TextComponent)(e.getSource())).getText();
|
||||
parsePosition.setIndex(0);
|
||||
theNumber = spelloutFormatter.parse(fieldText, parsePosition)
|
||||
.doubleValue();
|
||||
if (parsePosition.getIndex() == 0)
|
||||
numberField.setText("PARSE ERROR");
|
||||
else
|
||||
numberField.setText(numberFormatter.format(theNumber));
|
||||
textField.setText(textField.getText()); // textField.repaint() didn't work right
|
||||
}
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
textField.selectAll();
|
||||
}
|
||||
} );
|
||||
|
||||
rulesField.addKeyListener(new KeyAdapter() {
|
||||
public void keyTyped(KeyEvent e) {
|
||||
if (e.getKeyChar() == '\t') {
|
||||
String fieldText = ((TextComponent)(e.getSource())).getText();
|
||||
if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
|
||||
RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
|
||||
try {
|
||||
RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
|
||||
temp.setLenientParseMode(lenientParse);
|
||||
populateRuleSetMenu();
|
||||
spelloutFormatter = temp;
|
||||
customRuleSet = fieldText;
|
||||
formatterMenu.select("Custom");
|
||||
commentaryField.setText(RbnfSampleRuleSets.
|
||||
sampleRuleSetCommentary[RbnfSampleRuleSets.
|
||||
sampleRuleSetCommentary.length - 1]);
|
||||
redisplay();
|
||||
}
|
||||
catch (Exception x) {
|
||||
textField.setText(x.toString());
|
||||
}
|
||||
}
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
rulesField.addFocusListener(new FocusAdapter() {
|
||||
public void focusLost(FocusEvent e) {
|
||||
String fieldText = ((TextComponent)(e.getSource())).getText();
|
||||
if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
|
||||
RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
|
||||
try {
|
||||
RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
|
||||
temp.setLenientParseMode(lenientParse);
|
||||
populateRuleSetMenu();
|
||||
spelloutFormatter = temp;
|
||||
customRuleSet = fieldText;
|
||||
formatterMenu.select("Custom");
|
||||
redisplay();
|
||||
}
|
||||
catch (Exception x) {
|
||||
textField.setText(x.toString());
|
||||
}
|
||||
}
|
||||
rulesField.setText(rulesField.getText()); // rulesField.repaint() didn't work right
|
||||
}
|
||||
} );
|
||||
|
||||
lenientParseButton.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
lenientParse = lenientParseButton.getState();
|
||||
spelloutFormatter.setLenientParseMode(lenientParse);
|
||||
}
|
||||
} );
|
||||
|
||||
numberField.setText(numberFormatter.format(theNumber));
|
||||
numberField.selectAll();
|
||||
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
|
||||
|
||||
Panel leftPanel = new Panel();
|
||||
leftPanel.setLayout(new BorderLayout());
|
||||
Panel panel = new Panel();
|
||||
panel.setLayout(new BorderLayout());
|
||||
Panel panel1 = new Panel();
|
||||
panel1.setLayout(new GridLayout(3, 1));
|
||||
panel1.add(new Panel());
|
||||
panel1.add(numberField, "Center");
|
||||
panel1.add(lenientParseButton);
|
||||
panel.add(panel1, "Center");
|
||||
Panel panel2 = new Panel();
|
||||
panel2.setLayout(new GridLayout(3, 3));
|
||||
Button button = new Button("+100");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
roll(100);
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
button = new Button("+10");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
roll(10);
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
button = new Button("+1");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
roll(1);
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
button = new Button("<");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
theNumber *= 10;
|
||||
redisplay();
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
panel2.add(new Panel());
|
||||
button = new Button(">");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
theNumber /= 10;
|
||||
redisplay();
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
button = new Button("-100");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
roll(-100);
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
button = new Button("-10");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
roll(-10);
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
button = new Button("-1");
|
||||
button.addActionListener( new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
roll(-1);
|
||||
}
|
||||
} );
|
||||
panel2.add(button);
|
||||
panel.add(panel2, "East");
|
||||
leftPanel.add(panel, "North");
|
||||
leftPanel.add(textField, "Center");
|
||||
|
||||
Panel rightPanel = new Panel();
|
||||
rightPanel.setLayout(new BorderLayout());
|
||||
formatterMenu = new Choice();
|
||||
for (int i = 0; i < RbnfSampleRuleSets.sampleRuleSetNames.length; i++)
|
||||
formatterMenu.addItem(RbnfSampleRuleSets.sampleRuleSetNames[i]);
|
||||
formatterMenu.addItem("Custom");
|
||||
formatterMenu.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
Choice source = (Choice)(e.getSource());
|
||||
int item = source.getSelectedIndex();
|
||||
Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
|
||||
|
||||
commentaryField.setText(RbnfSampleRuleSets.
|
||||
sampleRuleSetCommentary[item]);
|
||||
|
||||
if (locale != null && (locale.getLanguage().equals("iw")
|
||||
|| locale.getLanguage().equals("ru") || locale.getLanguage().equals("ja")
|
||||
|| locale.getLanguage().equals("el")
|
||||
|| locale.getLanguage().equals("zh"))) {
|
||||
textField.togglePanes(false);
|
||||
rulesField.togglePanes(false);
|
||||
}
|
||||
else {
|
||||
textField.togglePanes(true);
|
||||
rulesField.togglePanes(true);
|
||||
}
|
||||
|
||||
makeNewSpelloutFormatter();
|
||||
redisplay();
|
||||
}
|
||||
} );
|
||||
|
||||
ruleSetMenu = new Choice();
|
||||
populateRuleSetMenu();
|
||||
|
||||
ruleSetMenu.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
ruleSetName = ruleSetMenu.getSelectedItem();
|
||||
redisplay();
|
||||
}
|
||||
} );
|
||||
|
||||
Panel menuPanel = new Panel();
|
||||
menuPanel.setLayout(new GridLayout(1, 2));
|
||||
menuPanel.add(formatterMenu);
|
||||
menuPanel.add(ruleSetMenu);
|
||||
rightPanel.add(menuPanel, "North");
|
||||
|
||||
rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()]);
|
||||
rightPanel.add(rulesField, "Center");
|
||||
|
||||
mainPanel.add(leftPanel);
|
||||
mainPanel.add(rightPanel);
|
||||
|
||||
window.add(mainPanel, "Center");
|
||||
window.add(commentaryField, "South");
|
||||
|
||||
window.doLayout();
|
||||
window.show();
|
||||
final DemoApplet theApplet = applet;
|
||||
window.addWindowListener(
|
||||
new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
setVisible(false);
|
||||
window.dispose();
|
||||
|
||||
if (theApplet != null) {
|
||||
theApplet.demoClosed();
|
||||
} else System.exit(0);
|
||||
}
|
||||
} );
|
||||
return window;
|
||||
}
|
||||
|
||||
void roll(int delta) {
|
||||
theNumber += delta;
|
||||
redisplay();
|
||||
}
|
||||
|
||||
void redisplay() {
|
||||
numberField.setText(numberFormatter.format(theNumber));
|
||||
textField.setText(spelloutFormatter.format(theNumber, ruleSetName));
|
||||
}
|
||||
|
||||
void makeNewSpelloutFormatter() {
|
||||
int item = formatterMenu.getSelectedIndex();
|
||||
String formatterMenuItem = formatterMenu.getSelectedItem();
|
||||
|
||||
if (formatterMenuItem.equals("Custom")) {
|
||||
rulesField.setText(customRuleSet);
|
||||
spelloutFormatter = new RuleBasedNumberFormat(customRuleSet);
|
||||
}
|
||||
else {
|
||||
rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[item]);
|
||||
|
||||
Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
|
||||
if (locale == null)
|
||||
locale = Locale.getDefault();
|
||||
|
||||
spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.
|
||||
sampleRuleSets[item], locale);
|
||||
}
|
||||
spelloutFormatter.setLenientParseMode(lenientParse);
|
||||
populateRuleSetMenu();
|
||||
}
|
||||
|
||||
void populateRuleSetMenu() {
|
||||
String[] ruleSetNames = spelloutFormatter.getRuleSetNames();
|
||||
|
||||
if (ruleSetMenu != null) {
|
||||
ruleSetMenu.removeAll();
|
||||
for (int i = 0; i < ruleSetNames.length; i++)
|
||||
ruleSetMenu.addItem(ruleSetNames[i]);
|
||||
|
||||
ruleSetName = ruleSetMenu.getSelectedItem();
|
||||
}
|
||||
else
|
||||
ruleSetName = ruleSetNames[0];
|
||||
}
|
||||
|
||||
// private Frame demoWindow = null;
|
||||
|
||||
private TextComponent numberField;
|
||||
private DemoTextFieldHolder textField;
|
||||
private DemoTextFieldHolder rulesField;
|
||||
private TextComponent commentaryField;
|
||||
private Checkbox lenientParseButton;
|
||||
|
||||
private boolean numberFieldHasFocus = true;
|
||||
|
||||
private RuleBasedNumberFormat spelloutFormatter;
|
||||
private DecimalFormat numberFormatter;
|
||||
private ParsePosition parsePosition;
|
||||
|
||||
private boolean lenientParse = true;
|
||||
|
||||
private double theNumber = 0;
|
||||
// private boolean canEdit = true;
|
||||
|
||||
private Choice formatterMenu;
|
||||
private Choice ruleSetMenu;
|
||||
private String ruleSetName;
|
||||
|
||||
private String customRuleSet = "NO RULES!";
|
||||
}
|
||||
|
||||
class DemoTextField extends Component {
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -7947090021239472658L;
|
||||
public DemoTextField() {
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
Font font = getFont();
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
g.setFont(font);
|
||||
String txt = getText();
|
||||
BreakIterator bi = BreakIterator.getLineInstance();
|
||||
bi.setText(txt);
|
||||
int lineHeight = fm.getHeight();
|
||||
int width = getSize().width;
|
||||
int penY = fm.getAscent();
|
||||
int lineStart = 0;
|
||||
int tempLineEnd = bi.first();
|
||||
int lineEnd = 0;
|
||||
int maxLineEnd = 0;
|
||||
totalHeight = 0;
|
||||
|
||||
while (lineStart < txt.length()) {
|
||||
maxLineEnd = txt.indexOf('\n', lineStart);
|
||||
if (maxLineEnd == -1)
|
||||
maxLineEnd = Integer.MAX_VALUE;
|
||||
while (tempLineEnd != BreakIterator.DONE && fm.stringWidth(txt.substring(
|
||||
lineStart, tempLineEnd)) < width) {
|
||||
lineEnd = tempLineEnd;
|
||||
tempLineEnd = bi.next();
|
||||
}
|
||||
if (lineStart >= lineEnd) {
|
||||
if (tempLineEnd == BreakIterator.DONE)
|
||||
lineEnd = txt.length();
|
||||
else
|
||||
lineEnd = tempLineEnd;
|
||||
}
|
||||
if (lineEnd > maxLineEnd)
|
||||
lineEnd = maxLineEnd;
|
||||
g.drawString(txt.substring(lineStart, lineEnd), 0, penY);
|
||||
penY += lineHeight;
|
||||
totalHeight += lineHeight;
|
||||
lineStart = lineEnd;
|
||||
if (lineStart < txt.length() && txt.charAt(lineStart) == '\n')
|
||||
++lineStart;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = getParent().getSize();
|
||||
return new Dimension(size.width, totalHeight);
|
||||
}
|
||||
*/
|
||||
|
||||
private String text;
|
||||
private int totalHeight;
|
||||
}
|
||||
|
||||
class DemoTextFieldHolder extends Panel {
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 7514498764062569858L;
|
||||
public DemoTextFieldHolder() {
|
||||
tf1 = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
|
||||
tf2 = new DemoTextField();
|
||||
sp = new ScrollPane();
|
||||
|
||||
setLayout(new CardLayout());
|
||||
|
||||
sp.add(tf2, "TextField1");
|
||||
sp.setVisible(false);
|
||||
add(tf1, "TestField2");
|
||||
add(sp, "ScrollPane");
|
||||
}
|
||||
|
||||
public void addFocusListener(FocusListener l) {
|
||||
tf1.addFocusListener(l);
|
||||
}
|
||||
|
||||
public void addKeyListener(KeyListener l) {
|
||||
tf1.addKeyListener(l);
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
tf1.setText(text);
|
||||
tf2.setText(text);
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return tf1.getText();
|
||||
}
|
||||
|
||||
public void select(int start, int end) {
|
||||
tf1.select(start, end);
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
tf1.selectAll();
|
||||
}
|
||||
|
||||
public void togglePanes(boolean canShowRealTextField) {
|
||||
if (canShowRealTextField != showingRealTextField) {
|
||||
CardLayout layout = (CardLayout)(getLayout());
|
||||
layout.next(this);
|
||||
showingRealTextField = canShowRealTextField;
|
||||
}
|
||||
}
|
||||
|
||||
private TextArea tf1 = null;
|
||||
private DemoTextField tf2 = null;
|
||||
private ScrollPane sp = null;
|
||||
private boolean showingRealTextField = true;
|
||||
}
|
1941
demos/src/com/ibm/icu/dev/demo/rbnf/RbnfSampleRuleSets.java
Normal file
1941
demos/src/com/ibm/icu/dev/demo/rbnf/RbnfSampleRuleSets.java
Normal file
File diff suppressed because it is too large
Load diff
12
demos/src/com/ibm/icu/dev/demo/rbnf/package.html
Normal file
12
demos/src/com/ibm/icu/dev/demo/rbnf/package.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<!-- Copyright (C) 2000-2004, International Business Machines Corporation and
|
||||
others. All Rights Reserved.
|
||||
|
||||
-->
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
RuleBasedNumberFormat demo appliation.
|
||||
</body>
|
||||
</html>
|
78
demos/src/com/ibm/icu/dev/demo/timescale/PivotDemo.java
Normal file
78
demos/src/com/ibm/icu/dev/demo/timescale/PivotDemo.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.timescale;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
import com.ibm.icu.util.SimpleTimeZone;
|
||||
import com.ibm.icu.util.TimeZone;
|
||||
import com.ibm.icu.util.UniversalTimeScale;
|
||||
|
||||
/**
|
||||
* This class demonstrates how to use <code>UniversalTimeScale</code> to
|
||||
* convert from one local time scale to another.
|
||||
*
|
||||
* @see UniversalTimeScale
|
||||
*/
|
||||
public class PivotDemo {
|
||||
|
||||
/**
|
||||
* The default constructor.
|
||||
*/
|
||||
public PivotDemo()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>main()</code> method uses <code>UniversalTimeScale</code> to
|
||||
* convert from the Java and Unix time scales to the ICU time scale. It uses
|
||||
* a <code>Calendar</code> object to display the ICU time values.
|
||||
*
|
||||
* @param args the command line arguments.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
TimeZone utc = new SimpleTimeZone(0, "UTC");
|
||||
Calendar cal = Calendar.getInstance(utc, Locale.ENGLISH);
|
||||
MessageFormat fmt = new MessageFormat("{1} = {0, date, full} {0, time, full}");
|
||||
Object arguments[] = {cal, null};
|
||||
|
||||
arguments[0] = cal;
|
||||
|
||||
System.out.println("\nJava test:");
|
||||
cal.setTimeInMillis(UniversalTimeScale.toLong(UniversalTimeScale.from(0, UniversalTimeScale.JAVA_TIME), UniversalTimeScale.ICU4C_TIME));
|
||||
arguments[1] = " 000000000000000";
|
||||
System.out.println(fmt.format(arguments));
|
||||
|
||||
cal.setTimeInMillis(UniversalTimeScale.toLong(UniversalTimeScale.from(-62164684800000L, UniversalTimeScale.JAVA_TIME), UniversalTimeScale.ICU4C_TIME));
|
||||
arguments[1] = "-62164684800000L";
|
||||
System.out.println(fmt.format(arguments));
|
||||
|
||||
cal.setTimeInMillis(UniversalTimeScale.toLong(UniversalTimeScale.from(-62135769600000L, UniversalTimeScale.JAVA_TIME), UniversalTimeScale.ICU4C_TIME));
|
||||
arguments[1] = "-62135769600000L";
|
||||
System.out.println(fmt.format(arguments));
|
||||
|
||||
System.out.println("\nUnix test:");
|
||||
|
||||
cal.setTimeInMillis(UniversalTimeScale.toLong(UniversalTimeScale.from(0x80000000, UniversalTimeScale.UNIX_TIME), UniversalTimeScale.ICU4C_TIME));
|
||||
arguments[1] = "0x80000000";
|
||||
System.out.println(fmt.format(arguments));
|
||||
|
||||
cal.setTimeInMillis(UniversalTimeScale.toLong(UniversalTimeScale.from(0, UniversalTimeScale.UNIX_TIME), UniversalTimeScale.ICU4C_TIME));
|
||||
arguments[1] = "0x00000000";
|
||||
System.out.println(fmt.format(arguments));
|
||||
|
||||
cal.setTimeInMillis(UniversalTimeScale.toLong(UniversalTimeScale.from(0x7FFFFFFF, UniversalTimeScale.UNIX_TIME), UniversalTimeScale.ICU4C_TIME));
|
||||
arguments[1] = "0x7FFFFFFF";
|
||||
System.out.println(fmt.format(arguments));
|
||||
|
||||
}
|
||||
}
|
308
demos/src/com/ibm/icu/dev/demo/translit/AnyTransliterator.java
Normal file
308
demos/src/com/ibm/icu/dev/demo/translit/AnyTransliterator.java
Normal file
|
@ -0,0 +1,308 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2001-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.translit;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.ibm.icu.lang.UScript;
|
||||
import com.ibm.icu.text.Replaceable;
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeFilter;
|
||||
|
||||
public class AnyTransliterator extends Transliterator {
|
||||
|
||||
static final boolean DEBUG = false;
|
||||
private String targetName;
|
||||
private RunIterator it;
|
||||
private Position run;
|
||||
|
||||
|
||||
public AnyTransliterator(String targetName, UnicodeFilter filter, RunIterator it){
|
||||
super("Any-" + targetName, filter);
|
||||
this.targetName = targetName;
|
||||
this.it = it;
|
||||
run = new Position();
|
||||
}
|
||||
|
||||
public AnyTransliterator(String targetName, UnicodeFilter filter){
|
||||
this(targetName, filter, new ScriptRunIterator());
|
||||
}
|
||||
|
||||
static private Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex");
|
||||
|
||||
protected void handleTransliterate(Replaceable text,
|
||||
Position offsets, boolean isIncremental) {
|
||||
if (DEBUG) {
|
||||
System.out.println("- handleTransliterate " + hex.transliterate(text.toString())
|
||||
+ ", " + toString(offsets));
|
||||
}
|
||||
it.reset(text, offsets);
|
||||
|
||||
while (it.next(run)) {
|
||||
if (targetName.equalsIgnoreCase(it.getName())) {
|
||||
if (DEBUG) System.out.println("Skipping identical: " + targetName);
|
||||
run.start = run.limit; // show we processed
|
||||
continue; // skip if same
|
||||
}
|
||||
|
||||
Transliterator t;
|
||||
String id = it.getName() + '-' + targetName;
|
||||
try {
|
||||
t = Transliterator.getInstance(id);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
if (DEBUG) System.out.println("Couldn't find: " + id + ", Trying Latin as Pivot");
|
||||
id = it.getName() + "-Latin; Latin-" + targetName;
|
||||
try {
|
||||
t = Transliterator.getInstance(id);
|
||||
} catch (IllegalArgumentException ex2) {
|
||||
if (DEBUG) System.out.println("Couldn't find: " + id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// TODO catch error later!!
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(t.getID());
|
||||
System.out.println("input: " + hex.transliterate(text.toString())
|
||||
+ ", " + toString(run));
|
||||
}
|
||||
|
||||
if (isIncremental && it.atEnd()) {
|
||||
t.transliterate(text, run);
|
||||
} else {
|
||||
t.finishTransliteration(text, run);
|
||||
}
|
||||
// adjust the offsets in line with the changes
|
||||
it.adjust(run.limit);
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("output: " + hex.transliterate(text.toString())
|
||||
+ ", " + toString(run));
|
||||
}
|
||||
}
|
||||
|
||||
// show how far we got!
|
||||
it.getExpanse(offsets);
|
||||
if (run.start == run.limit) offsets.start = offsets.limit;
|
||||
else offsets.start = run.start;
|
||||
if (DEBUG) {
|
||||
System.out.println("+ handleTransliterate: " + ", " + toString(offsets));
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
// should be method on Position
|
||||
public static String toString(Position offsets) {
|
||||
return "[cs: " + offsets.contextStart
|
||||
+ ", s: " + offsets.start
|
||||
+ ", l: " + offsets.limit
|
||||
+ ", cl: " + offsets.contextLimit
|
||||
+ "]";
|
||||
}
|
||||
|
||||
public interface RunIterator {
|
||||
public void reset(Replaceable text, Position expanse);
|
||||
public void getExpanse(Position run);
|
||||
public void reset();
|
||||
public boolean next(Position run);
|
||||
public void getCurrent(Position run);
|
||||
public String getName();
|
||||
public void adjust(int newCurrentLimit);
|
||||
public boolean atEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a series of ranges corresponding to scripts. They will be of the form:
|
||||
* ccccSScSSccccTTcTcccc - where c is common, S is the first script and T is the second
|
||||
*| | - first run
|
||||
* | | - second run
|
||||
* That is, the runs will overlap. The reason for this is so that a transliterator can
|
||||
* consider common characters both before and after the scripts.
|
||||
* The only time that contextStart != start is for the first run
|
||||
* (the context is the start context of the entire expanse)
|
||||
* The only time that contextLimit != limit is for the last run
|
||||
* (the context is the end context of the entire expanse)
|
||||
*/
|
||||
public static class ScriptRunIterator implements RunIterator {
|
||||
private Replaceable text;
|
||||
private Position expanse = new Position();
|
||||
private Position current = new Position();
|
||||
private int script;
|
||||
private boolean done = true;
|
||||
|
||||
|
||||
public void reset(Replaceable repText, Position expansePos) {
|
||||
set(this.expanse, expansePos);
|
||||
this.text = repText;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
done = false;
|
||||
//this.expanse = expanse;
|
||||
script = UScript.INVALID_CODE;
|
||||
// set up first range to be empty, at beginning
|
||||
current.contextStart = expanse.contextStart;
|
||||
current.start = current.limit = current.contextLimit = expanse.start;
|
||||
}
|
||||
|
||||
public boolean next(Position run) {
|
||||
if (done) return false;
|
||||
if (DEBUG) {
|
||||
System.out.println("+cs: " + current.contextStart
|
||||
+ ", s: " + current.start
|
||||
+ ", l: " + current.limit
|
||||
+ ", cl: " + current.contextLimit);
|
||||
}
|
||||
// reset start context run to the last end
|
||||
current.start = current.limit;
|
||||
|
||||
// Phase 1. Backup the START value through COMMON until we get to expanse.start or a real script.
|
||||
int i, cp;
|
||||
int limit = expanse.start;
|
||||
for (i = current.start; i > limit; i -= UTF16.getCharCount(cp)) {
|
||||
cp = text.char32At(i);
|
||||
int scrpt = UScript.getScript(cp);
|
||||
if (scrpt != UScript.COMMON && scrpt != UScript.INHERITED) break;
|
||||
}
|
||||
current.start = i;
|
||||
current.contextStart = (i == limit) ? expanse.contextStart : i; // extend at start
|
||||
|
||||
// PHASE 2. Move up the LIMIT value through COMMON or single script until we get to expanse.limit
|
||||
int lastScript = UScript.COMMON;
|
||||
//int veryLastScript = UScript.COMMON;
|
||||
limit = expanse.limit;
|
||||
for (i = current.limit; i < limit; i += UTF16.getCharCount(cp)) {
|
||||
cp = text.char32At(i);
|
||||
int scrpt = UScript.getScript(cp);
|
||||
if (scrpt == UScript.INHERITED) scrpt = UScript.COMMON;
|
||||
if (scrpt != UScript.COMMON) {
|
||||
// if we find a real script:
|
||||
// if we already had a script, bail
|
||||
// otherwise set our script
|
||||
if (lastScript == UScript.COMMON) lastScript = scrpt;
|
||||
else if (lastScript != scrpt) break;
|
||||
}
|
||||
}
|
||||
current.limit = i;
|
||||
current.contextLimit = (i == limit) ? expanse.contextLimit : i; // extend at end
|
||||
done = (i == limit);
|
||||
script = lastScript;
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("-cs: " + current.contextStart
|
||||
+ ", s: " + current.start
|
||||
+ ", l: " + current.limit
|
||||
+ ", cl: " + current.contextLimit);
|
||||
}
|
||||
|
||||
set(run, current);
|
||||
return true;
|
||||
}
|
||||
|
||||
// SHOULD BE METHOD ON POSITION
|
||||
public static void set(Position run, Position current) {
|
||||
run.contextStart = current.contextStart;
|
||||
run.start = current.start;
|
||||
run.limit = current.limit;
|
||||
run.contextLimit = current.contextLimit;
|
||||
}
|
||||
|
||||
public boolean atEnd() {
|
||||
return current.limit == expanse.limit;
|
||||
}
|
||||
|
||||
public void getCurrent(Position run) {
|
||||
set(run, current);
|
||||
}
|
||||
|
||||
public void getExpanse(Position run) {
|
||||
set(run, expanse);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return UScript.getName(script);
|
||||
}
|
||||
|
||||
public void adjust(int newCurrentLimit) {
|
||||
if (expanse == null) {
|
||||
throw new IllegalArgumentException("Must reset() before calling");
|
||||
}
|
||||
int delta = newCurrentLimit - current.limit;
|
||||
current.limit += delta;
|
||||
current.contextLimit += delta;
|
||||
expanse.limit += delta;
|
||||
expanse.contextLimit += delta;
|
||||
}
|
||||
|
||||
// register Any-Script for every script.
|
||||
|
||||
private static Set scriptList = new HashSet();
|
||||
|
||||
public static void registerAnyToScript() {
|
||||
synchronized (scriptList) {
|
||||
Enumeration sources = Transliterator.getAvailableSources();
|
||||
while(sources.hasMoreElements()) {
|
||||
String source = (String) sources.nextElement();
|
||||
if (source.equals("Any")) continue; // to keep from looping
|
||||
|
||||
Enumeration targets = Transliterator.getAvailableTargets(source);
|
||||
while(targets.hasMoreElements()) {
|
||||
String target = (String) targets.nextElement();
|
||||
if (UScript.getCode(target) == null) continue; // SKIP unless we have a script (or locale)
|
||||
if (scriptList.contains(target)) continue; // already encountered
|
||||
scriptList.add(target); // otherwise add for later testing
|
||||
|
||||
Set variantSet = add(new TreeSet(), Transliterator.getAvailableVariants(source, target));
|
||||
if (variantSet.size() < 2) {
|
||||
AnyTransliterator at = new AnyTransliterator(target, null);
|
||||
DummyFactory.add(at.getID(), at);
|
||||
} else {
|
||||
Iterator variants = variantSet.iterator();
|
||||
while(variants.hasNext()) {
|
||||
String variant = (String) variants.next();
|
||||
AnyTransliterator at = new AnyTransliterator(
|
||||
(variant.length() > 0) ? target + "/" + variant : target, null);
|
||||
DummyFactory.add(at.getID(), at);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class DummyFactory implements Transliterator.Factory {
|
||||
static DummyFactory singleton = new DummyFactory();
|
||||
static HashMap m = new HashMap();
|
||||
|
||||
// Since Transliterators are immutable, we don't have to clone on set & get
|
||||
static void add(String ID, Transliterator t) {
|
||||
m.put(ID, t);
|
||||
System.out.println("Registering: " + ID + ", " + t.toRules(true));
|
||||
Transliterator.registerFactory(ID, singleton);
|
||||
}
|
||||
public Transliterator getInstance(String ID) {
|
||||
return (Transliterator) m.get(ID);
|
||||
}
|
||||
}
|
||||
|
||||
// Nice little Utility for converting Enumeration to collection
|
||||
static Set add(Set s, Enumeration enumeration) {
|
||||
while(enumeration.hasMoreElements()) {
|
||||
s.add(enumeration.nextElement());
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
560
demos/src/com/ibm/icu/dev/demo/translit/CaseIterator.java
Normal file
560
demos/src/com/ibm/icu/dev/demo/translit/CaseIterator.java
Normal file
|
@ -0,0 +1,560 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.dev.demo.translit;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* Incrementally returns the set of all strings that case-fold to the same value.
|
||||
*/
|
||||
public class CaseIterator {
|
||||
|
||||
// testing stuff
|
||||
static Transliterator toName = Transliterator.getInstance("[:^ascii:] Any-Name");
|
||||
static Transliterator toHex = Transliterator.getInstance("[:^ascii:] Any-Hex");
|
||||
static Transliterator toHex2 = Transliterator.getInstance("[[^\u0021-\u007F]-[,]] Any-Hex");
|
||||
|
||||
// global tables (could be precompiled)
|
||||
private static Map fromCaseFold = new HashMap();
|
||||
private static Map toCaseFold = new HashMap();
|
||||
private static int maxLength = 0;
|
||||
|
||||
// This exception list is generated on the console by turning on the GENERATED flag,
|
||||
// which MUST be false for normal operation.
|
||||
// Once the list is generated, it is pasted in here.
|
||||
// A bit of a cludge, but this bootstrapping is the easiest way
|
||||
// to get around certain complications in the data.
|
||||
|
||||
private static final boolean GENERATE = false;
|
||||
|
||||
private static final boolean DUMP = false;
|
||||
|
||||
private static String[][] exceptionList = {
|
||||
// a\N{MODIFIER LETTER RIGHT HALF RING}
|
||||
{"a\u02BE","A\u02BE","a\u02BE",},
|
||||
// ff
|
||||
{"ff","FF","Ff","fF","ff",},
|
||||
// ffi
|
||||
{"ffi","FFI","FFi","FfI","Ffi","F\uFB01","fFI","fFi","ffI","ffi","f\uFB01","\uFB00I","\uFB00i",},
|
||||
// ffl
|
||||
{"ffl","FFL","FFl","FfL","Ffl","F\uFB02","fFL","fFl","ffL","ffl","f\uFB02","\uFB00L","\uFB00l",},
|
||||
// fi
|
||||
{"fi","FI","Fi","fI","fi",},
|
||||
// fl
|
||||
{"fl","FL","Fl","fL","fl",},
|
||||
// h\N{COMBINING MACRON BELOW}
|
||||
{"h\u0331","H\u0331","h\u0331",},
|
||||
// i\N{COMBINING DOT ABOVE}
|
||||
{"i\u0307","I\u0307","i\u0307",},
|
||||
// j\N{COMBINING CARON}
|
||||
{"j\u030C","J\u030C","j\u030C",},
|
||||
// ss
|
||||
{"ss","SS","Ss","S\u017F","sS","ss","s\u017F","\u017FS","\u017Fs","\u017F\u017F",},
|
||||
// st
|
||||
{"st","ST","St","sT","st","\u017FT","\u017Ft",},
|
||||
// t\N{COMBINING DIAERESIS}
|
||||
{"t\u0308","T\u0308","t\u0308",},
|
||||
// w\N{COMBINING RING ABOVE}
|
||||
{"w\u030A","W\u030A","w\u030A",},
|
||||
// y\N{COMBINING RING ABOVE}
|
||||
{"y\u030A","Y\u030A","y\u030A",},
|
||||
// \N{MODIFIER LETTER APOSTROPHE}n
|
||||
{"\u02BCn","\u02BCN","\u02BCn",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH TONOS}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03AC\u03B9","\u0386\u0345","\u0386\u0399","\u0386\u03B9","\u0386\u1FBE","\u03AC\u0345","\u03AC\u0399","\u03AC\u03B9","\u03AC\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH TONOS}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03AE\u03B9","\u0389\u0345","\u0389\u0399","\u0389\u03B9","\u0389\u1FBE","\u03AE\u0345","\u03AE\u0399","\u03AE\u03B9","\u03AE\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03B1\u0342","\u0391\u0342","\u03B1\u0342",},
|
||||
// \N{GREEK SMALL LETTER ALPHA}\N{COMBINING GREEK PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03B1\u0342\u03B9","\u0391\u0342\u0345","\u0391\u0342\u0399","\u0391\u0342\u03B9","\u0391\u0342\u1FBE",
|
||||
"\u03B1\u0342\u0345","\u03B1\u0342\u0399","\u03B1\u0342\u03B9","\u03B1\u0342\u1FBE","\u1FB6\u0345",
|
||||
"\u1FB6\u0399","\u1FB6\u03B9","\u1FB6\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03B1\u03B9","\u0391\u0345","\u0391\u0399","\u0391\u03B9","\u0391\u1FBE","\u03B1\u0345","\u03B1\u0399","\u03B1\u03B9","\u03B1\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03B7\u0342","\u0397\u0342","\u03B7\u0342",},
|
||||
// \N{GREEK SMALL LETTER ETA}\N{COMBINING GREEK PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03B7\u0342\u03B9","\u0397\u0342\u0345","\u0397\u0342\u0399","\u0397\u0342\u03B9","\u0397\u0342\u1FBE",
|
||||
"\u03B7\u0342\u0345","\u03B7\u0342\u0399","\u03B7\u0342\u03B9","\u03B7\u0342\u1FBE","\u1FC6\u0345","\u1FC6\u0399",
|
||||
"\u1FC6\u03B9","\u1FC6\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03B7\u03B9","\u0397\u0345","\u0397\u0399","\u0397\u03B9","\u0397\u1FBE","\u03B7\u0345","\u03B7\u0399","\u03B7\u03B9","\u03B7\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER IOTA}\N{COMBINING DIAERESIS}\N{COMBINING GRAVE ACCENT}
|
||||
{"\u03B9\u0308\u0300","\u0345\u0308\u0300","\u0399\u0308\u0300","\u03B9\u0308\u0300","\u1FBE\u0308\u0300",},
|
||||
// \N{GREEK SMALL LETTER IOTA}\N{COMBINING DIAERESIS}\N{COMBINING ACUTE ACCENT}
|
||||
{"\u03B9\u0308\u0301","\u0345\u0308\u0301","\u0399\u0308\u0301","\u03B9\u0308\u0301","\u1FBE\u0308\u0301",},
|
||||
// \N{GREEK SMALL LETTER IOTA}\N{COMBINING DIAERESIS}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03B9\u0308\u0342","\u0345\u0308\u0342","\u0399\u0308\u0342","\u03B9\u0308\u0342","\u1FBE\u0308\u0342",},
|
||||
// \N{GREEK SMALL LETTER IOTA}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03B9\u0342","\u0345\u0342","\u0399\u0342","\u03B9\u0342","\u1FBE\u0342",},
|
||||
// \N{GREEK SMALL LETTER RHO}\N{COMBINING COMMA ABOVE}
|
||||
{"\u03C1\u0313","\u03A1\u0313","\u03C1\u0313","\u03F1\u0313",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING DIAERESIS}\N{COMBINING GRAVE ACCENT}
|
||||
{"\u03C5\u0308\u0300","\u03A5\u0308\u0300","\u03C5\u0308\u0300",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING DIAERESIS}\N{COMBINING ACUTE ACCENT}
|
||||
{"\u03C5\u0308\u0301","\u03A5\u0308\u0301","\u03C5\u0308\u0301",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING DIAERESIS}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03C5\u0308\u0342","\u03A5\u0308\u0342","\u03C5\u0308\u0342",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE}
|
||||
{"\u03C5\u0313","\u03A5\u0313","\u03C5\u0313",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE}\N{COMBINING GRAVE ACCENT}
|
||||
{"\u03C5\u0313\u0300","\u03A5\u0313\u0300","\u03C5\u0313\u0300","\u1F50\u0300",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE}\N{COMBINING ACUTE ACCENT}
|
||||
{"\u03C5\u0313\u0301","\u03A5\u0313\u0301","\u03C5\u0313\u0301","\u1F50\u0301",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING COMMA ABOVE}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03C5\u0313\u0342","\u03A5\u0313\u0342","\u03C5\u0313\u0342","\u1F50\u0342",},
|
||||
// \N{GREEK SMALL LETTER UPSILON}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03C5\u0342","\u03A5\u0342","\u03C5\u0342",},
|
||||
// \N{GREEK SMALL LETTER OMEGA}\N{COMBINING GREEK PERISPOMENI}
|
||||
{"\u03C9\u0342","\u03A9\u0342","\u03C9\u0342","\u2126\u0342",},
|
||||
// \N{GREEK SMALL LETTER OMEGA}\N{COMBINING GREEK PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03C9\u0342\u03B9","\u03A9\u0342\u0345","\u03A9\u0342\u0399","\u03A9\u0342\u03B9","\u03A9\u0342\u1FBE","\u03C9\u0342\u0345","\u03C9\u0342\u0399","\u03C9\u0342\u03B9","\u03C9\u0342\u1FBE","\u1FF6\u0345",
|
||||
"\u1FF6\u0399","\u1FF6\u03B9","\u1FF6\u1FBE","\u2126\u0342\u0345","\u2126\u0342\u0399","\u2126\u0342\u03B9","\u2126\u0342\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03C9\u03B9","\u03A9\u0345","\u03A9\u0399","\u03A9\u03B9","\u03A9\u1FBE","\u03C9\u0345","\u03C9\u0399","\u03C9\u03B9","\u03C9\u1FBE","\u2126\u0345","\u2126\u0399","\u2126\u03B9","\u2126\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH TONOS}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u03CE\u03B9","\u038F\u0345","\u038F\u0399","\u038F\u03B9","\u038F\u1FBE","\u03CE\u0345","\u03CE\u0399","\u03CE\u03B9","\u03CE\u1FBE",},
|
||||
// \N{ARMENIAN SMALL LETTER ECH}\N{ARMENIAN SMALL LETTER YIWN}
|
||||
{"\u0565\u0582","\u0535\u0552","\u0535\u0582","\u0565\u0552","\u0565\u0582",},
|
||||
// \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER ECH}
|
||||
{"\u0574\u0565","\u0544\u0535","\u0544\u0565","\u0574\u0535","\u0574\u0565",},
|
||||
// \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER INI}
|
||||
{"\u0574\u056B","\u0544\u053B","\u0544\u056B","\u0574\u053B","\u0574\u056B",},
|
||||
// \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER XEH}
|
||||
{"\u0574\u056D","\u0544\u053D","\u0544\u056D","\u0574\u053D","\u0574\u056D",},
|
||||
// \N{ARMENIAN SMALL LETTER MEN}\N{ARMENIAN SMALL LETTER NOW}
|
||||
{"\u0574\u0576","\u0544\u0546","\u0544\u0576","\u0574\u0546","\u0574\u0576",},
|
||||
// \N{ARMENIAN SMALL LETTER VEW}\N{ARMENIAN SMALL LETTER NOW}
|
||||
{"\u057E\u0576","\u054E\u0546","\u054E\u0576","\u057E\u0546","\u057E\u0576",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH PSILI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F00\u03B9","\u1F00\u0345","\u1F00\u0399","\u1F00\u03B9","\u1F00\u1FBE","\u1F08\u0345","\u1F08\u0399","\u1F08\u03B9","\u1F08\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH DASIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F01\u03B9","\u1F01\u0345","\u1F01\u0399","\u1F01\u03B9","\u1F01\u1FBE","\u1F09\u0345","\u1F09\u0399","\u1F09\u03B9","\u1F09\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F02\u03B9","\u1F02\u0345","\u1F02\u0399","\u1F02\u03B9","\u1F02\u1FBE","\u1F0A\u0345","\u1F0A\u0399","\u1F0A\u03B9","\u1F0A\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F03\u03B9","\u1F03\u0345","\u1F03\u0399","\u1F03\u03B9","\u1F03\u1FBE","\u1F0B\u0345","\u1F0B\u0399","\u1F0B\u03B9","\u1F0B\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F04\u03B9","\u1F04\u0345","\u1F04\u0399","\u1F04\u03B9","\u1F04\u1FBE","\u1F0C\u0345","\u1F0C\u0399","\u1F0C\u03B9","\u1F0C\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F05\u03B9","\u1F05\u0345","\u1F05\u0399","\u1F05\u03B9","\u1F05\u1FBE","\u1F0D\u0345","\u1F0D\u0399","\u1F0D\u03B9","\u1F0D\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F06\u03B9","\u1F06\u0345","\u1F06\u0399","\u1F06\u03B9","\u1F06\u1FBE","\u1F0E\u0345","\u1F0E\u0399","\u1F0E\u03B9","\u1F0E\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F07\u03B9","\u1F07\u0345","\u1F07\u0399","\u1F07\u03B9","\u1F07\u1FBE","\u1F0F\u0345","\u1F0F\u0399","\u1F0F\u03B9","\u1F0F\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH PSILI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F20\u03B9","\u1F20\u0345","\u1F20\u0399","\u1F20\u03B9","\u1F20\u1FBE","\u1F28\u0345","\u1F28\u0399","\u1F28\u03B9","\u1F28\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH DASIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F21\u03B9","\u1F21\u0345","\u1F21\u0399","\u1F21\u03B9","\u1F21\u1FBE","\u1F29\u0345","\u1F29\u0399","\u1F29\u03B9","\u1F29\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH PSILI AND VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F22\u03B9","\u1F22\u0345","\u1F22\u0399","\u1F22\u03B9","\u1F22\u1FBE","\u1F2A\u0345","\u1F2A\u0399","\u1F2A\u03B9","\u1F2A\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH DASIA AND VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F23\u03B9","\u1F23\u0345","\u1F23\u0399","\u1F23\u03B9","\u1F23\u1FBE","\u1F2B\u0345","\u1F2B\u0399","\u1F2B\u03B9","\u1F2B\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH PSILI AND OXIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F24\u03B9","\u1F24\u0345","\u1F24\u0399","\u1F24\u03B9","\u1F24\u1FBE","\u1F2C\u0345","\u1F2C\u0399","\u1F2C\u03B9","\u1F2C\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH DASIA AND OXIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F25\u03B9","\u1F25\u0345","\u1F25\u0399","\u1F25\u03B9","\u1F25\u1FBE","\u1F2D\u0345","\u1F2D\u0399","\u1F2D\u03B9","\u1F2D\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F26\u03B9","\u1F26\u0345","\u1F26\u0399","\u1F26\u03B9","\u1F26\u1FBE","\u1F2E\u0345","\u1F2E\u0399","\u1F2E\u03B9","\u1F2E\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F27\u03B9","\u1F27\u0345","\u1F27\u0399","\u1F27\u03B9","\u1F27\u1FBE","\u1F2F\u0345","\u1F2F\u0399","\u1F2F\u03B9","\u1F2F\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH PSILI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F60\u03B9","\u1F60\u0345","\u1F60\u0399","\u1F60\u03B9","\u1F60\u1FBE","\u1F68\u0345","\u1F68\u0399","\u1F68\u03B9","\u1F68\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH DASIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F61\u03B9","\u1F61\u0345","\u1F61\u0399","\u1F61\u03B9","\u1F61\u1FBE","\u1F69\u0345","\u1F69\u0399","\u1F69\u03B9","\u1F69\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F62\u03B9","\u1F62\u0345","\u1F62\u0399","\u1F62\u03B9","\u1F62\u1FBE","\u1F6A\u0345","\u1F6A\u0399","\u1F6A\u03B9","\u1F6A\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F63\u03B9","\u1F63\u0345","\u1F63\u0399","\u1F63\u03B9","\u1F63\u1FBE","\u1F6B\u0345","\u1F6B\u0399","\u1F6B\u03B9","\u1F6B\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F64\u03B9","\u1F64\u0345","\u1F64\u0399","\u1F64\u03B9","\u1F64\u1FBE","\u1F6C\u0345","\u1F6C\u0399","\u1F6C\u03B9","\u1F6C\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F65\u03B9","\u1F65\u0345","\u1F65\u0399","\u1F65\u03B9","\u1F65\u1FBE","\u1F6D\u0345","\u1F6D\u0399","\u1F6D\u03B9","\u1F6D\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F66\u03B9","\u1F66\u0345","\u1F66\u0399","\u1F66\u03B9","\u1F66\u1FBE","\u1F6E\u0345","\u1F6E\u0399","\u1F6E\u03B9","\u1F6E\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F67\u03B9","\u1F67\u0345","\u1F67\u0399","\u1F67\u03B9","\u1F67\u1FBE","\u1F6F\u0345","\u1F6F\u0399","\u1F6F\u03B9","\u1F6F\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ALPHA WITH VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F70\u03B9","\u1F70\u0345","\u1F70\u0399","\u1F70\u03B9","\u1F70\u1FBE","\u1FBA\u0345","\u1FBA\u0399","\u1FBA\u03B9","\u1FBA\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER ETA WITH VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F74\u03B9","\u1F74\u0345","\u1F74\u0399","\u1F74\u03B9","\u1F74\u1FBE","\u1FCA\u0345","\u1FCA\u0399","\u1FCA\u03B9","\u1FCA\u1FBE",},
|
||||
// \N{GREEK SMALL LETTER OMEGA WITH VARIA}\N{GREEK SMALL LETTER IOTA}
|
||||
{"\u1F7C\u03B9","\u1F7C\u0345","\u1F7C\u0399","\u1F7C\u03B9","\u1F7C\u1FBE","\u1FFA\u0345","\u1FFA\u0399","\u1FFA\u03B9","\u1FFA\u1FBE",},
|
||||
};
|
||||
|
||||
// this initializes the data used to generated the case-equivalents
|
||||
|
||||
static {
|
||||
|
||||
// Gather up the exceptions in a form we can use
|
||||
|
||||
if (!GENERATE) {
|
||||
for (int i = 0; i < exceptionList.length; ++i) {
|
||||
String[] exception = exceptionList[i];
|
||||
Set s = new HashSet();
|
||||
// there has to be some method to do the following, but I can't find it in the collections
|
||||
for (int j = 0; j < exception.length; ++j) {
|
||||
s.add(exception[j]);
|
||||
}
|
||||
fromCaseFold.put(exception[0], s);
|
||||
}
|
||||
}
|
||||
|
||||
// walk through all the characters, and at every case fold result,
|
||||
// put a set of all the characters that map to that result
|
||||
|
||||
boolean defaultmapping = true; // false for turkish
|
||||
for (int i = 0; i <= 0x10FFFF; ++i) {
|
||||
int cat = UCharacter.getType(i);
|
||||
if (cat == Character.UNASSIGNED || cat == Character.PRIVATE_USE) continue;
|
||||
|
||||
String cp = UTF16.valueOf(i);
|
||||
String mapped = UCharacter.foldCase(cp, defaultmapping);
|
||||
if (mapped.equals(cp)) continue;
|
||||
|
||||
if (maxLength < mapped.length()) maxLength = mapped.length();
|
||||
|
||||
// at this point, have different case folding
|
||||
|
||||
Set s = (Set) fromCaseFold.get(mapped);
|
||||
if (s == null) {
|
||||
s = new HashSet();
|
||||
s.add(mapped); // add the case fold result itself
|
||||
fromCaseFold.put(mapped, s);
|
||||
}
|
||||
s.add(cp);
|
||||
toCaseFold.put(cp, mapped);
|
||||
toCaseFold.put(mapped, mapped); // add mapping to self
|
||||
}
|
||||
|
||||
// Emit the final data
|
||||
|
||||
if (DUMP) {
|
||||
System.out.println("maxLength = " + maxLength);
|
||||
|
||||
System.out.println("\nfromCaseFold:");
|
||||
Iterator it = fromCaseFold.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Object key = it.next();
|
||||
System.out.print(" " + toHex2.transliterate((String)key) + ": ");
|
||||
Set s = (Set) fromCaseFold.get(key);
|
||||
Iterator it2 = s.iterator();
|
||||
boolean first = true;
|
||||
while (it2.hasNext()) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
System.out.print(", ");
|
||||
}
|
||||
System.out.print(toHex2.transliterate((String)it2.next()));
|
||||
}
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
System.out.println("\ntoCaseFold:");
|
||||
it = toCaseFold.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
String key = (String) it.next();
|
||||
String value = (String) toCaseFold.get(key);
|
||||
System.out.println(" " + toHex2.transliterate(key) + ": " + toHex2.transliterate(value));
|
||||
}
|
||||
}
|
||||
|
||||
// Now convert all those sets into linear arrays
|
||||
// We can't do this in place in Java, so make a temporary target array
|
||||
|
||||
// Note: This could be transformed into a single array, with offsets into it.
|
||||
// Might be best choice in C.
|
||||
|
||||
|
||||
Map fromCaseFold2 = new HashMap();
|
||||
Iterator it = fromCaseFold.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Object key = it.next();
|
||||
Set s = (Set) fromCaseFold.get(key);
|
||||
String[] temp = new String[s.size()];
|
||||
s.toArray(temp);
|
||||
fromCaseFold2.put(key, temp);
|
||||
}
|
||||
fromCaseFold = fromCaseFold2;
|
||||
|
||||
// We have processed everything, so the iterator will now work
|
||||
// The following is normally OFF.
|
||||
// It is here to generate (under the GENERATE flag) the static exception list.
|
||||
// It must be at the very end of initialization, so that the iterator is functional.
|
||||
// (easiest to do it that way)
|
||||
|
||||
if (GENERATE) {
|
||||
|
||||
// first get small set of items that have multiple characters
|
||||
|
||||
Set multichars = new TreeSet();
|
||||
it = fromCaseFold.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
String key = (String) it.next();
|
||||
if (UTF16.countCodePoint(key) < 2) continue;
|
||||
multichars.add(key);
|
||||
}
|
||||
|
||||
// now we will go through each of them.
|
||||
|
||||
CaseIterator ci = new CaseIterator();
|
||||
it = multichars.iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
String key = (String) it.next();
|
||||
|
||||
// here is a nasty complication. Take 'ffi' ligature. We
|
||||
// can't just close it, since we would miss the combination
|
||||
// that includes the 'fi' => "fi" ligature
|
||||
// so first do a pass through, and add substring combinations
|
||||
// we call this a 'partial closure'
|
||||
|
||||
Set partialClosure = new TreeSet();
|
||||
partialClosure.add(key);
|
||||
|
||||
if (UTF16.countCodePoint(key) > 2) {
|
||||
Iterator multiIt2 = multichars.iterator();
|
||||
while (multiIt2.hasNext()) {
|
||||
String otherKey = (String) multiIt2.next();
|
||||
if (otherKey.length() >= key.length()) continue;
|
||||
int pos = -1;
|
||||
while (true) {
|
||||
// The following is not completely general
|
||||
// but works for the actual cased stuff,
|
||||
// and should work for future characters, since we won't have
|
||||
// more ligatures & other oddities.
|
||||
pos = key.indexOf(otherKey, pos+1);
|
||||
if (pos < 0) break;
|
||||
int endPos = pos + otherKey.length();
|
||||
// we know we have a proper substring,
|
||||
// so get the combinations
|
||||
String[] choices = (String[]) fromCaseFold.get(otherKey);
|
||||
for (int ii = 0; ii < choices.length; ++ii) {
|
||||
String patchwork = key.substring(0, pos)
|
||||
+ choices[ii]
|
||||
+ key.substring(endPos);
|
||||
partialClosure.add(patchwork);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now, for each thing in the partial closure, get its
|
||||
// case closure and add it to the final result.
|
||||
|
||||
Set closure = new TreeSet(); // this will be the real closure
|
||||
Iterator partialIt = partialClosure.iterator();
|
||||
while (partialIt.hasNext()) {
|
||||
String key2 = (String) partialIt.next();
|
||||
ci.reset(key2);
|
||||
for (String temp = ci.next(); temp != null; temp = ci.next()) {
|
||||
closure.add(temp);
|
||||
}
|
||||
// form closure
|
||||
/*String[] choices = (String[]) fromCaseFold.get(key2);
|
||||
for (int i = 0; i < choices.length; ++i) {
|
||||
ci.reset(choices[i]);
|
||||
String temp;
|
||||
while (null != (temp = ci.next())) {
|
||||
closure.add(temp);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// print it out, so that it can be cut and pasted back into this document.
|
||||
|
||||
Iterator it2 = closure.iterator();
|
||||
System.out.println("\t// " + toName.transliterate(key));
|
||||
System.out.print("\t{\"" + toHex.transliterate(key) + "\",");
|
||||
while (it2.hasNext()) {
|
||||
String item = (String)it2.next();
|
||||
System.out.print("\"" + toHex.transliterate(item) + "\",");
|
||||
}
|
||||
System.out.println("},");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============ PRIVATE CLASS DATA ============
|
||||
|
||||
// pieces that we will put together
|
||||
// is not changed during iteration
|
||||
private int count = 0;
|
||||
private String[][] variants;
|
||||
|
||||
// state information, changes during iteration
|
||||
private boolean done = false;
|
||||
private int[] counts;
|
||||
|
||||
// internal buffer for efficiency
|
||||
private StringBuffer nextBuffer = new StringBuffer();
|
||||
|
||||
// ========================
|
||||
|
||||
/**
|
||||
* Reset to different source. Once reset, the iteration starts from the beginning.
|
||||
* @param source The string to get case variants for
|
||||
*/
|
||||
public void reset(String source) {
|
||||
|
||||
// allocate arrays to store pieces
|
||||
// using length might be slightly too long, but we don't care much
|
||||
|
||||
counts = new int[source.length()];
|
||||
variants = new String[source.length()][];
|
||||
|
||||
// walk through the source, and break up into pieces
|
||||
// each piece becomes an array of equivalent values
|
||||
// TODO: could optimized this later to coalesce all single string pieces
|
||||
|
||||
String piece = null;
|
||||
count = 0;
|
||||
for (int i = 0; i < source.length(); i += piece.length()) {
|
||||
|
||||
// find *longest* matching piece
|
||||
String caseFold = null;
|
||||
|
||||
if (GENERATE) {
|
||||
// do exactly one CP
|
||||
piece = UTF16.valueOf(source, i);
|
||||
caseFold = (String) toCaseFold.get(piece);
|
||||
} else {
|
||||
int max = i + maxLength;
|
||||
if (max > source.length()) max = source.length();
|
||||
for (int j = max; j > i; --j) {
|
||||
piece = source.substring(i, j);
|
||||
caseFold = (String) toCaseFold.get(piece);
|
||||
if (caseFold != null) break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we fail, pick one code point
|
||||
if (caseFold == null) {
|
||||
piece = UTF16.valueOf(source, i);
|
||||
variants[count++] = new String[] {piece}; // single item string
|
||||
} else {
|
||||
variants[count++] = (String[])fromCaseFold.get(caseFold);
|
||||
}
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart the iteration from the beginning, but with same source
|
||||
*/
|
||||
public void reset() {
|
||||
done = false;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
counts[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the case variants.
|
||||
* @return next case variant. Each variant will case-fold to the same value as the source will.
|
||||
* When the iteration is done, null is returned.
|
||||
*/
|
||||
public String next() {
|
||||
|
||||
if (done) return null;
|
||||
int i;
|
||||
|
||||
// TODO Optimize so we keep the piece before and after the current position
|
||||
// so we don't have so much concatenation
|
||||
|
||||
// get the result, a concatenation
|
||||
|
||||
nextBuffer.setLength(0);
|
||||
for (i = 0; i < count; ++i) {
|
||||
nextBuffer.append(variants[i][counts[i]]);
|
||||
}
|
||||
|
||||
// find the next right set of pieces to concatenate
|
||||
|
||||
for (i = count-1; i >= 0; --i) {
|
||||
counts[i]++;
|
||||
if (counts[i] < variants[i].length) break;
|
||||
counts[i] = 0;
|
||||
}
|
||||
|
||||
// if we go too far, bail
|
||||
|
||||
if (i < 0) {
|
||||
done = true;
|
||||
}
|
||||
|
||||
return nextBuffer.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Temporary test, just to see how the stuff works.
|
||||
*/
|
||||
static public void main(String[] args) {
|
||||
String[] testCases = {"fiss", "h\u03a3"};
|
||||
CaseIterator ci = new CaseIterator();
|
||||
|
||||
for (int i = 0; i < testCases.length; ++i) {
|
||||
String item = testCases[i];
|
||||
System.out.println();
|
||||
System.out.println("Testing: " + toName.transliterate(item));
|
||||
System.out.println();
|
||||
ci.reset(item);
|
||||
int count = 0;
|
||||
for (String temp = ci.next(); temp != null; temp = ci.next()) {
|
||||
System.out.println(toName.transliterate(temp));
|
||||
count++;
|
||||
}
|
||||
System.out.println("Total: " + count);
|
||||
}
|
||||
|
||||
// generate a list of all caseless characters -- characters whose
|
||||
// case closure is themselves.
|
||||
|
||||
UnicodeSet caseless = new UnicodeSet();
|
||||
|
||||
for (int i = 0; i <= 0x10FFFF; ++i) {
|
||||
String cp = UTF16.valueOf(i);
|
||||
ci.reset(cp);
|
||||
int count = 0;
|
||||
String fold = null;
|
||||
for (String temp = ci.next(); temp != null; temp = ci.next()) {
|
||||
fold = temp;
|
||||
if (++count > 1) break;
|
||||
}
|
||||
if (count==1 && fold.equals(cp)) {
|
||||
caseless.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("caseless = " + caseless.toPattern(true));
|
||||
|
||||
UnicodeSet not_lc = new UnicodeSet("[:^lc:]");
|
||||
|
||||
UnicodeSet a = new UnicodeSet();
|
||||
a.set(not_lc);
|
||||
a.removeAll(caseless);
|
||||
System.out.println("[:^lc:] - caseless = " + a.toPattern(true));
|
||||
|
||||
a.set(caseless);
|
||||
a.removeAll(not_lc);
|
||||
System.out.println("caseless - [:^lc:] = " + a.toPattern(true));
|
||||
}
|
||||
}
|
1417
demos/src/com/ibm/icu/dev/demo/translit/Demo.java
Normal file
1417
demos/src/com/ibm/icu/dev/demo/translit/Demo.java
Normal file
File diff suppressed because it is too large
Load diff
73
demos/src/com/ibm/icu/dev/demo/translit/DemoApplet.java
Normal file
73
demos/src/com/ibm/icu/dev/demo/translit/DemoApplet.java
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.translit;
|
||||
import java.applet.Applet;
|
||||
import java.awt.Button;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.AppletFrame;
|
||||
|
||||
/**
|
||||
* A simple Applet that shows a button. When pressed, the button
|
||||
* shows the DemoAppletFrame. This Applet is meant to be embedded
|
||||
* in a web page.
|
||||
*
|
||||
* <p>Copyright (c) IBM Corporation 1999. All rights reserved.
|
||||
*
|
||||
* @author Alan Liu
|
||||
*/
|
||||
public class DemoApplet extends Applet {
|
||||
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = 8214879807740061678L;
|
||||
Demo frame = null;
|
||||
|
||||
public static void main(String args[]) {
|
||||
final DemoApplet applet = new DemoApplet();
|
||||
new AppletFrame("Transliteration Demo", applet, 640, 480);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
Button button = new Button("Transliteration Demo");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (frame == null) {
|
||||
frame = new Demo(600, 200);
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent we) {
|
||||
frame = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
frame.setVisible(true);
|
||||
frame.toFront();
|
||||
}
|
||||
});
|
||||
|
||||
add(button);
|
||||
|
||||
Dimension size = button.getPreferredSize();
|
||||
size.width += 10;
|
||||
size.height += 10;
|
||||
|
||||
resize(size);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (frame != null) {
|
||||
frame.dispose();
|
||||
}
|
||||
frame = null;
|
||||
}
|
||||
}
|
66
demos/src/com/ibm/icu/dev/demo/translit/InfoDialog.java
Normal file
66
demos/src/com/ibm/icu/dev/demo/translit/InfoDialog.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2001-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.translit;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Button;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
public class InfoDialog extends Dialog {
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -3086665546137919018L;
|
||||
protected Button button;
|
||||
protected TextArea area;
|
||||
protected Dialog me;
|
||||
protected Panel bottom;
|
||||
|
||||
public TextArea getArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
public Panel getBottom() {
|
||||
return bottom;
|
||||
}
|
||||
|
||||
InfoDialog(Frame parent, String title, String label, String message) {
|
||||
super(parent, title, false);
|
||||
me = this;
|
||||
this.setLayout(new BorderLayout());
|
||||
if (label.length() != 0) {
|
||||
this.add("North", new Label(label));
|
||||
}
|
||||
|
||||
area = new TextArea(message, 8, 80, TextArea.SCROLLBARS_VERTICAL_ONLY);
|
||||
this.add("Center", area);
|
||||
|
||||
button = new Button("Hide");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
me.hide();
|
||||
}
|
||||
});
|
||||
bottom = new Panel();
|
||||
bottom.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
|
||||
bottom.add(button);
|
||||
this.add("South", bottom);
|
||||
this.pack();
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
me.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#--------------------------------------------------------------------
|
||||
# Copyright (c) 1999-2004, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#--------------------------------------------------------------------
|
||||
@UPPERFILTER@
|
||||
ما هي الشفرة الموحدة "يونِكود" ؟
|
||||
|
||||
أساسًا، تتعامل الحواسيب فقط مع الأرقام، وتقوم بتخزين الأحرف والمحارف الأخرى بعد أن تُعطي رقما معينا لكل واحد منها. وقبل اختراع "يونِكود"، كان هناك مئات الأنظمة للتشفير وتخصيص هذه الأرقام للمحارف، ولم يوجد نظام تشفير واحد يحتوي على جميع المحارف الضرورية. وعلى سبيل المثال، فإن الاتحاد الأوروبي لوحده، احتوى العديد من الشفرات المختلفة ليغطي جميع اللغات المستخدمة في الاتحاد. وحتى لو اعتبرنا لغة واحدة، كاللغة الإنجليزية، فإن جدول شفرة واحد لم يكف لاستيعاب جميع الأحرف وعلامات الترقيم والرموز الفنية والعلمية الشائعة الاستعمال.
|
||||
|
||||
|
||||
|
||||
وتجدر الملاحظة أن أنظمة التشفير المختلفة تتعارض مع بعضها البعض. وبعبارة أخرى، يمكن أن يستخدِم جدولي شفرة نفس الرقم لتمثيل محرفين مختلفين، أو رقمين مختلفين لتمثيل نفس المحرف. ولو أخذنا أي جهاز حاسوب، وبخاصة جهاز النادل (server)، فيجب أن تكون لديه القدرة على التعامل مع عدد كبير من الشفرات المختلفة، ويتم تصميمه على هذا الأساس. ومع ذلك، فعندما تمر البيانات عبر أنظمة مختلفة، توجد هناك خطورة لضياع أو تحريف بعض هذه البيانات.
|
||||
|
||||
|
||||
|
||||
"يونِكود" تغير هذا كليا !
|
||||
|
||||
تخصص الشفرة الموحدة "يونِكود" رقما وحيدا لكل محرف في جميع اللغات العالمية، وذلك بغض النظر عن نوع الحاسوب أو البرامج المستخدمة. وقد تم تبني مواصفة "يونِكود" من قبل قادة الصانعين لأنظمة الحواسيب في العالم، مثل شركات آي.بي.إم. (IBM)، أبل (APPLE)، هِيْولِت باكرد (Hewlett-Packard) ، مايكروسوفت (Microsoft)، أوراكِل (Oracle) ، صن (Sun) وغيرها. كما أن المواصفات والمقاييس الحديثة (مثل لغة البرمجة "جافا" "JAVA" ولغة "إكس إم إل" "XML" التي تستخدم لبرمجة الانترنيت) تتطلب استخدام "يونِكود". علاوة على ذلك ، فإن "يونِكود" هي الطريقة الرسمية لتطبيق المقياس العالمي إيزو ١٠٦٤٦ (ISO 10646) .
|
||||
|
||||
|
||||
|
||||
إن بزوغ مواصفة "يونِكود" وتوفُّر الأنظمة التي تستخدمه وتدعمه، يعتبر من أهم الاختراعات الحديثة في عولمة البرمجيات لجميع اللغات في العالم. وإن استخدام "يونِكود" في عالم الانترنيت سيؤدي إلى توفير كبير مقارنة مع استخدام المجموعات التقليدية للمحارف المشفرة. كما أن استخدام "يونِكود" سيُمكِّن المبرمج من كتابة البرنامج مرة واحدة، واستخدامه على أي نوع من الأجهزة أو الأنظمة، ولأي لغة أو دولة في العالم أينما كانت، دون الحاجة لإعادة البرمجة أو إجراء أي تعديل. وأخيرا، فإن استخدام "يونِكود" سيمكن البيانات من الانتقال عبر الأنظمة والأجهزة المختلفة دون أي خطورة لتحريفها، مهما تعددت الشركات الصانعة للأنظمة واللغات، والدول التي تمر من خلالها هذه البيانات.
|
||||
|
||||
@SET [[[:Arabic:] & [\u0600-\u06FF]] [\u060C\u061B\u061F\u0640\u064B-\u0655\u0660-\u066C\u06F0-\u06F9]]
|
73
demos/src/com/ibm/icu/dev/demo/translit/Test_Greek-Latin.txt
Normal file
73
demos/src/com/ibm/icu/dev/demo/translit/Test_Greek-Latin.txt
Normal file
|
@ -0,0 +1,73 @@
|
|||
#--------------------------------------------------------------------
|
||||
# Copyright (c) 1999-2004, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#--------------------------------------------------------------------
|
||||
|
||||
Τι είναι το Unicode?
|
||||
|
||||
Η κωδικοσελίδα Unicode προτείνει έναν και μοναδικό αριθμό για κάθε χαρακτήρα, ανεξάρτητα από το λειτουργικό σύστημα, ανεξάρτητα από το λογισμικό, ανεξάρτητα από την γλώσσα.
|
||||
|
||||
Οι ηλεκτρονικοί υπολογιστές, σε τελική ανάλυση, χειρίζονται απλώς αριθμούς. Αποθηκεύουν γράμματα και άλλους χαρακτήρες αντιστοιχώντας στο καθένα τους από έναν αριθμό (ονομάζουμε μία τέτοια αντιστοιχία κωδικοσελίδα). Πριν την εφεύρεση του Unicode, υπήρχαν εκατοντάδες διαφορετικές κωδικοσελίδες. Λόγω περιορισμών μεγέθους όμως, σε καμία κωδικοσελίδα δεν χωρούσαν αρκετοί χαρακτήρες: λόγου χάριν, η Ευρωπαϊκή Ένωση χρειαζόταν πλήθος διαφορετικών κωδικοσελίδων για να καλύψει όλες τις γλώσσες των χωρών-μελών της. Ακόμα και για μία και μόνη γλώσσα, όπως π.χ. τα Αγγλικά, μία κωδικοσελίδα δεν επαρκούσε για να καλύψει όλα τα γράμματα, σημεία στίξης και τεχνικά σύμβολα ευρείας χρήσης.
|
||||
|
||||
Εκτός αυτού, οι κωδικοσελίδες αυτές διαφωνούσαν μεταξύ τους. Έτσι, δύο κωδικοσελίδες μπορούσαν κάλλιστα να χρησιμοποιούν τον ίδιο αριθμό για δύο διαφορετικούς χαρακτήρες, ή να χρησιμοποιούν διαφορετικούς αριθμούς για τον ίδιο χαρακτήρα. Κάθε υπολογιστής (και ιδίως εάν ήταν διακομιστής) έπρεπε να υποστηρίζει πλήθος διαφορετικών κωδικοσελίδων· ταυτόχρονα κάθε φορά που δεδομένα μεταφέρονταν μεταξύ διαφορετικών κωδικοσελίδων ή λειτουργικών συστημάτων, τα δεδομένα αυτά κινδύνευαν να αλλοιωθούν.
|
||||
|
||||
Το Unicode αλλάζει αυτή την κατάσταση!
|
||||
Το Unicode προτείνει έναν μοναδικό αριθμό για κάθε χαρακτήρα, ανεξάρτητα από το λειτουργικό σύστημα, ανεξάρτητα από το λογισμικό, ανεξάρτητα από την γλώσσα. Την κωδικοσελίδα Unicode έχουν ασπασθεί κορυφαίοι παράγοντες του χώρου των λογισμικών όπως οι: Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys και πολλοί άλλοι. Το Unicode απαιτούν πολλές σύγχρονες τυποποιήσεις όπως οι: XML, Java, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML, κ.λπ., και είναι η επίσημη μέθοδος εφαρμογής της τυποποίησης ISO/IEC 10646. Υποστηρίζεται από πολλά λειτουργικά συστήματα, όλους τους σύχρονους περιηγητές Διαδικτύου, και πολλά άλλα προϊόντα. Η εμφάνιση της κωδικοσελίδας Unicode, και η διαθεσιμότητα εργαλείων που να την υποστηρίζουν είναι από τις σημαντικότερες εξελίξεις της πρόσφατης τεχνολογίας λογισμικών.
|
||||
|
||||
Η ενσωμάτωση του Unicode σε εφαρμογές πελάτη-διακομιστή ή "multi-tiered" προσφέρει σημαντικές οικονομίες σε σχέση με τις ως τώρα υπάρχουσες κωδικοσελίδες. Χάρις στο Unicode ένα και μόνο προϊόν ή μία και μόνη τοποθεσία Διαδικτύου μπορεί να επικοινωνεί με διάφορα λειτουργικά συστήματα, σε διάφορες γλώσσες και χώρες, χωρίς την ανάγκη επαναπρογραμματισμού. Γίνεται έτσι δυνατή η μεταφορά δεδομένων ανάμεσα σε πλήθος διαφορετικών συστημάτων δίχως κίνδυνο αλλοίωσης.
|
||||
|
||||
Σχετικά με το Κονσόρτιουμ Unicode
|
||||
Tο Κονσόρτιουμ Unicode είναι ένας κοινωφελής οργανισμός· ιδρύθηκε για να αναπτύξει, να επεκτείνει και να μεταδώσει την χρήση της κωδικοσελίδας Unicode που καθορίζει την αναπαράσταση κειμένου σε σύγχρονα λογισμικά προϊόντα και τυποποιήσεις. Μεγάλος αριθμός εταιρειών και οργανισμών της διεθνούς βιομηχανίας υπολογιστών και λογισμικών είναι μέλη του Κονσόρτιουμ Unicode. Το Κονσόρτιουμ χρηματοδοτείται μόνο από τις συνδρομές των μελών του. Μέλος του κονσόρτιουμ Unicode μπορεί να γίνει οιοσδήποτε (οργανισμός, εταιρεία ή ιδιώτης, οπουδήποτε στον κόσμο) που να υποστηρίζει την κωδικοσελίδα Unicode και να επιθυμεί να συνδράμει στην επέκταση και στην εφαρμογή της.
|
||||
|
||||
Για περαιτέρω πληροφορίες, βλέπε τις εξής ιστοσελίδες: Γλωσσάρι, Δείγματα προϊόντων συμβατών με το Unicode, Τεχνική Εισαγωγή και Χρήσιμες πηγές πληροφοριών.
|
||||
|
||||
(ANCIENT)
|
||||
|
||||
ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
|
||||
πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν:
|
||||
πολλῶν δ’ ἀνθρώπων ἴδεν ἄστεα καὶ νόον ἔγνω,
|
||||
πολλὰ δ’ ὅ γ’ ἐν πόντῳ πάθεν ἄλγεα ὃν κατὰ θυμόν,
|
||||
ἀρνύμενος ἥν τε ψυχὴν καὶ νόστον ἑταίρων.
|
||||
ἀλλ’ οὐδ’ ὣς ἑτάρους ἐρρύσατο, ἱέμενός περ:
|
||||
αὐτῶν γὰρ σφετέρῃσιν ἀτασθαλίῃσιν ὄλοντο,
|
||||
νήπιοι, οἳ κατὰ βοῦς Ὑπερίονος Ἠελίοιο
|
||||
ἤσθιον: αὐτὰρ ὁ τοῖσιν ἀφείλετο νόστιμον ἦμαρ.
|
||||
τῶν ἁμόθεν γε, θεά, θύγατερ Διός, εἰπὲ καὶ ἡμῖν.
|
||||
*
|
||||
ἔνθ’ ἄλλοι μὲν πάντες, ὅσοι φύγον αἰπὺν ὄλεθρον,
|
||||
οἴκοι ἔσαν, πόλεμόν τε πεφευγότες ἠδὲ θάλασσαν:
|
||||
τὸν δ’ οἶον νόστου κεχρημένον ἠδὲ γυναικὸς
|
||||
νύμφη πότνι’ ἔρυκε Καλυψὼ δῖα θεάων
|
||||
ἐν σπέσσι γλαφυροῖσι, λιλαιομένη πόσιν εἶναι.
|
||||
ἀλλ’ ὅτε δὴ ἔτος ἦλθε περιπλομένων ἐνιαυτῶν,
|
||||
τῷ οἱ ἐπεκλώσαντο θεοὶ οἶκόνδε νέεσθαι
|
||||
εἰς Ἰθάκην, οὐδ’ ἔνθα πεφυγμένος ἦεν ἀέθλων
|
||||
καὶ μετὰ οἷσι φίλοισι. θεοὶ δ’ ἐλέαιρον ἅπαντες
|
||||
νόσφι Ποσειδάωνος: ὁ δ’ ἀσπερχὲς μενέαινεν
|
||||
ἀντιθέῳ Ὀδυσῆι πάρος ἣν γαῖαν ἱκέσθαι.
|
||||
*
|
||||
ἀλλ’ ὁ μὲν Αἰθίοπας μετεκίαθε τηλόθ’ ἐόντας,
|
||||
Αἰθίοπας τοὶ διχθὰ δεδαίαται, ἔσχατοι ἀνδρῶν,
|
||||
οἱ μὲν δυσομένου Ὑπερίονος οἱ δ’ ἀνιόντος,
|
||||
ἀντιόων ταύρων τε καὶ ἀρνειῶν ἑκατόμβης.
|
||||
ἔνθ’ ὅ γ’ ἐτέρπετο δαιτὶ παρήμενος: οἱ δὲ δὴ ἄλλοι
|
||||
Ζηνὸς ἐνὶ μεγάροισιν Ὀλυμπίου ἁθρόοι ἦσαν.
|
||||
τοῖσι δὲ μύθων ἦρχε πατὴρ ἀνδρῶν τε θεῶν τε:
|
||||
μνήσατο γὰρ κατὰ θυμὸν ἀμύμονος Αἰγίσθοιο,
|
||||
τόν ῥ’ Ἀγαμεμνονίδης τηλεκλυτὸς ἔκταν’ Ὀρέστης:
|
||||
τοῦ ὅ γ’ ἐπιμνησθεὶς ἔπε’ ἀθανάτοισι μετηύδα:
|
||||
*
|
||||
“ὢ πόποι, οἷον δή νυ θεοὺς βροτοὶ αἰτιόωνται:
|
||||
ἐξ ἡμέων γάρ φασι κάκ’ ἔμμεναι, οἱ δὲ καὶ αὐτοὶ
|
||||
σφῇσιν ἀτασθαλίῃσιν ὑπὲρ μόρον ἄλγε’ ἔχουσιν,
|
||||
ὡς καὶ νῦν Αἴγισθος ὑπὲρ μόρον Ἀτρεί̈δαο
|
||||
γῆμ’ ἄλοχον μνηστήν, τὸν δ’ ἔκτανε νοστήσαντα,
|
||||
εἰδὼς αἰπὺν ὄλεθρον, ἐπεὶ πρό οἱ εἴπομεν ἡμεῖς,
|
||||
Ἑρμείαν πέμψαντες, ἐύσκοπον ἀργεϊφόντην,
|
||||
μήτ’ αὐτὸν κτείνειν μήτε μνάασθαι ἄκοιτιν:
|
||||
ἐκ γὰρ Ὀρέσταο τίσις ἔσσεται Ἀτρεί̈δαο,
|
||||
ὁππότ’ ἂν ἡβήσῃ τε καὶ ἧς ἱμείρεται αἴης.
|
||||
ὣς ἔφαθ’ Ἑρμείας, ἀλλ’ οὐ φρένας Αἰγίσθοιο
|
||||
πεῖθ’ ἀγαθὰ φρονέων: νῦν δ’ ἁθρόα πάντ’ ἀπέτισεν.”
|
||||
|
||||
@SET [[[:Greek:]&[\u0370-\u03E1 \u03F0-\u03FF]] [\:-;?\u00B7\u037E\u0387]]
|
26
demos/src/com/ibm/icu/dev/demo/translit/Test_Han-Latin.txt
Normal file
26
demos/src/com/ibm/icu/dev/demo/translit/Test_Han-Latin.txt
Normal file
|
@ -0,0 +1,26 @@
|
|||
#--------------------------------------------------------------------
|
||||
# Copyright (c) 1999-2004, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#--------------------------------------------------------------------
|
||||
@UPPERFILTER@
|
||||
什么是Unicode(统一码)?
|
||||
Unicode给每个字符提供了一个唯一的数字,
|
||||
不论是什么平台,
|
||||
不论是什么程序,
|
||||
不论是什么语言。
|
||||
|
||||
基本上,计算机只是处理数字。它们指定一个数字,来储存字母或其他字符。在创造Unicode之前,有数百种指定这些数字的编码系统。没有一个编码可以包含足够的字符:例如,单单欧州共同体就需要好几种不同的编码来包括所有的语言。即使是单一种语言,例如英语,也没有哪一个编码可以适用于所有的字母,标点符号,和常用的技术符号。
|
||||
|
||||
这些编码系统也会互相冲突。也就是说,两种编码可能使用相同的数字代表两个不同的字符,或使用不同的数字代表相同的字符。任何一台特定的计算机(特别是服务器)都需要支持许多不同的编码,但是,不论什么时候数据通过不同的编码或平台之间,那些数据总会有损坏的危险。
|
||||
|
||||
Unicode正在改变所有这一切!
|
||||
Unicode给每个字符提供了一个唯一的数字,不论是什么平台,不论是什么程序,不论什么语言。Unicode标准已经被这些工业界的领导们所采用,例如:Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys和其它许多公司。最新的标准都需要Unicode,例如XML, Java, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML等等,并且,Unicode是实现ISO/IEC 10646的正规方式。许多操作系统,所有最新的浏览器和许多其他产品都支持它。Unicode标准的出现和支持它工具的存在,是近来全球软件技术最重要的发展趋势。
|
||||
|
||||
将Unicode与客户服务器或多层应用程序和网站结合,比使用传统字符集节省费用。Unicode使单一软件产品或单一网站能够贯穿多个平台,语言和国家,而不需要重建。它可将数据传输到许多不同的系统,而无损坏。
|
||||
|
||||
关于Unicode学术学会
|
||||
Unicode学术学会是一个非盈利的组织,是为发展,扩展和推广使用Unicode标准而建立的,Unicode学术学会设立了现代软件产品和标准文本的表示法。学术学会的会员代表了广泛领域的计算机和资讯工业的公司和组织。学术学会只由会员提供资金。Unicode学术学会的会员资格开放给世界上任何支持Unicode标准和希望协助其扩展和执行的组织及个人。
|
||||
|
||||
欲知更多信息,请参阅术语词汇表,Unicode产品样本,技术简介和参考资料。
|
||||
|
||||
Chinese translation by 黎國珍, Xerox
|
|
@ -0,0 +1,26 @@
|
|||
#--------------------------------------------------------------------
|
||||
# Copyright (c) 1999-2004, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#--------------------------------------------------------------------
|
||||
@UPPERFILTER@
|
||||
מה זה יוניקוד (Unicode)?
|
||||
יוניקוד מקצה מספר ייחודי לכל תו,
|
||||
לא משנה על איזו פלטפורמה,
|
||||
לא משנה באיזו תוכנית,
|
||||
ולא משנה באיזו שפה.
|
||||
|
||||
באופן בסיסי, מחשבים עוסקים רק במספרים. הם מאחסנים אותיות ותווים אחרים על-ידי הקצאת מספר לכל אחד מהם. בטרם הומצא היוניקוד, היו מאות מערכות קידוד שונות להקצאת המספרים הללו. אף לא אחת מהן יכלה להכיל כמות תווים מספקת. לדוגמא: רק לאיחוד האירופאי נדרשים כמה סוגי קידודים שונים על מנת לכסות את כל השפות המדוברות בו. יתירה מזאת אף לשפה בודדת, כמו אנגלית למשל, לא היה די במערכת קידוד אחת בעבור כל האותיות, סימני הפיסוק והסמלים הטכניים שבשימוש שוטף.
|
||||
|
||||
מערכות קידוד אלו אף סותרות זו את זו. כלומר, שני קידודים יכולים להשתמש באותו מספר לשני תוים נבדלים, או להשתמש במספרים שונים לאותו תו. על כל מחשב (ובמיוחד שרתים) לתמוך במספר רב של מערכות קידוד שונות; אולם כל אימת שנתונים עוברים בין מערכות קידוד או פלטפורמות שונות קיים הסיכון שייפגמו.
|
||||
|
||||
יוניקוד משנה את כל זה!
|
||||
יוניקוד מקצה מספר ייחודי לכל תו, ללא תלות בפלטפורמה, בתוכנית, או בשפה. תקן היוניקוד אומץ על-ידי המובילים בתעשייה כמו Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys ורבים אחרים. יוניקוד נדרש על-ידי תקנים מודרניים כמו XML, Java, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML וכדומה, ומהווה למעשה את היישום הרשמי של תקן ISO/IEC 10646. הוא נתמך על ידי מערכות הפעלה רבות, כל הדפדפנים החדישים, ומוצרים רבים אחרים. הופעת תקן היוניקוד וזמינות הכלים התומכים בו נמנות עם המגמות הכלל-עולמיות החשובות ביותר, אשר מסתמנות לאחרונה בטכנולוגיית התוכנה.
|
||||
|
||||
שילוב יוניקוד ביישומי שרת-לקוח או ביישומים רבי-שכבות ובאתרי אינטרנט מאפשר חיסכון ניכר בעלויות לעומת השימוש בסדרות התווים המסורתיות. הודות ליוניקוד, מוצר תוכנה אחד או אתר יחיד ברשת יכול להרחיב את יעדיו למגוון פלטפורמות, ארצות ושפות ללא צורך בשינויים מרחיקים. יוניקוד מאפשר מעבר נתונים דרך מערכות רבות ושונות מבלי שייפגמו.
|
||||
|
||||
פרטים אודות הקונסורציום של יוניקוד (Unicode Consortium)
|
||||
הקונסורציום של יוניקוד הוא ארגון ללא מטרת רווח שנוסד כדי לפתח, להרחיב ולקדם את השימוש בתקן יוניקוד, אשר מגדיר את ייצוג הטקסט במוצרי תוכנה ותקנים מודרניים. חברים בקונסורציום מגוון רחב של תאגידים וארגונים בתעשיית המחשבים ועיבוד המידע. הקונסורציום ממומן על-ידי דמי-חבר בלבד. החברות בקונסורציום יוניקוד פתוחה לארגונים ולאנשים פרטיים, בכל רחבי העולם, אשר תומכים בתקן יוניקוד ומעוניינים לסייע בהתפתחותו והטמעתו.
|
||||
|
||||
למידע נוסף, ראה מילון מונחים, רשימה חלקית של מוצרים מותאמים ליוניקוד, מבוא טכני ו- חומרי עזר [קישורים באנגלית].
|
||||
|
||||
@SET [[:Hebrew:] [\u05B0-\u05B9\u05BB-\u05BC\u05C1-\u05C2\u2135-\u2138]]
|
154
demos/src/com/ibm/icu/dev/demo/translit/Test_Instructions.html
Normal file
154
demos/src/com/ibm/icu/dev/demo/translit/Test_Instructions.html
Normal file
|
@ -0,0 +1,154 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="COPYRIGHT" content="Copyright 2006-2007, International Business Machines Corporation and others. All Rights Reserved.">
|
||||
<title>New Transliteration Test Files</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF">
|
||||
|
||||
<h2>New Transliteration Test Files</h2>
|
||||
<p>The Test_*.html files show the transliteration of characters for given
|
||||
languages. The sample for each language consists of "What Is Unicode"
|
||||
in Thai, followed by other available text. The text is broken apart into
|
||||
sentences for ease of viewing (note: we know of some problems with the sentence
|
||||
rules for Japanese and Chinese). The left column is the original, and the right
|
||||
is the romanization. The program also converts back to the original script. If
|
||||
there is a discrepancy between the source and the reverse transformation, that
|
||||
is indicated by making the background <font color="#FF0000"><b>red</b></font>
|
||||
from that point on.</p>
|
||||
<blockquote>
|
||||
<p><i><b>Note: </b>If you have some more text that you would like added to the
|
||||
sample, just let me know. I am particularly interested in name lists, since
|
||||
they are the typical source.</i></p>
|
||||
</blockquote>
|
||||
<h3>Standards</h3>
|
||||
<p>The goal is to follow a given standard, such as ISO* or UNGEGN wherever
|
||||
possible. We also need to round-trip, so in some cases, that means adding some
|
||||
additional accent marks to disambiguate characters. And often the source
|
||||
standards are missing some characters, such as characters with combining Hamzas
|
||||
in Arabic. Remember that the goal for these is transliteration (unambiguously
|
||||
representing all the letters in the original), not transcription (representing
|
||||
the best pronunciation).</p>
|
||||
<ul>
|
||||
<li><b><a href="Test_Thai-Latin.html">Thai</a>:</b> ISO 11940 < <a href="http://homepage.mac.com/sirbinks/pdf/Thai.r2.pdf">http://homepage.mac.com/sirbinks/pdf/Thai.r2.pdf</a>
|
||||
> plus a few items:
|
||||
<ul>
|
||||
<li>Accents may be added to the Latin for disambiguation.</li>
|
||||
<li>In the next release, we'd like to do the UNGEGN version < <a href="http://www.eki.ee/wgrs/rom1_th.pdf">http://www.eki.ee/wgrs/rom1_th.pdf</a>
|
||||
> which is probably more useful (and readable), and follows more
|
||||
closely the Thai standard.</li>
|
||||
<li>Spaces are provided at word-breaks, using the Thai BreakIterator.</li>
|
||||
<li>An inherent vowel (ọ) is added, as in UNGEGN. The dot is for
|
||||
disambiguation.
|
||||
<ul>
|
||||
<li><i>Note: if the inherent vowel positions cannot be algorithmically
|
||||
determined, let me know and I will remove them.</i></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b><a href="Test_Arabic-Latin.html">Arabic</a>: </b>Generally follows
|
||||
UNGEGN < <a href="http://www.eki.ee/wgrs/rom1_ar.pdf">http://www.eki.ee/wgrs/rom1_ar.pdf</a>
|
||||
>
|
||||
<ul>
|
||||
<li>Accents may be added to the Latin for disambiguation.</li>
|
||||
<li>Occasionally deviates in the direction of ISO 233 < <a href="http://homepage.mac.com/sirbinks/pdf/Arabic.pdf">http://homepage.mac.com/sirbinks/pdf/Arabic.pdf</a>
|
||||
>
|
||||
<ul>
|
||||
<li>with underdot instead of cedilla for letter like SAD, since those
|
||||
are explicitly in Unicode for transliteration of Arabic</li>
|
||||
<li>adding extra non-Arabic-language letters, like PEH. Note: not all
|
||||
extended Arabic characters are handled yet.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Does <i>not</i> do assimilation of "al", nor hyphenation of
|
||||
it.
|
||||
<ul>
|
||||
<li>While it could be done, we need to determine whether a prefix
|
||||
"al" could occur other than as the definite article (since
|
||||
no space is used).</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>This is transliteration. For <i>transcription</i> one would want an
|
||||
engine that added points appropriately to the Hebrew.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b><a href="Test_Hebrew-Latin.html">Hebrew</a></b><b>: </b>Generally
|
||||
follows UNGEGN < <a href="http://www.eki.ee/wgrs/rom1_he.pdf">http://www.eki.ee/wgrs/rom1_he.pdf</a>
|
||||
>, with some exceptions:
|
||||
<ul>
|
||||
<li>Accents may be added to the Latin for disambiguation.</li>
|
||||
<li>Combinations of dagesh, shin/sin dot that would produce different
|
||||
letters are not yet called out.</li>
|
||||
<li>Note that the final forms are not preserved. Thus, when going from
|
||||
Latin to Hebrew, a character is given final form depending on its
|
||||
position.
|
||||
<ul>
|
||||
<li>E.g. מםמם => mmmm =>
|
||||
מממם</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>This is transliteration. For <i>transcription</i> one would want an
|
||||
engine that added points appropriately to the Hebrew.</li>
|
||||
<li>See also < <a href="http://homepage.mac.com/sirbinks/pdf/Hebrew.r1.pdf">http://homepage.mac.com/sirbinks/pdf/Hebrew.r1.pdf</a>
|
||||
> for the ISO version. The Chicago Manual of Style has a clear table
|
||||
of mappings for the vowel marks.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><b><a href="Test_Han-Latin.html">Han</a>:</b> Uses the <a href="http://www.mandarintools.com/cedict.html">CEDICT</a>
|
||||
data plus Unicode Unihan <i>kMandarin</i> values for pinyin. Doesn't
|
||||
roundtrip!
|
||||
<ul>
|
||||
<li><i>Note: </i>the Chinese pronunciation of Han characters varies by
|
||||
context and grammar, though nowhere near as much a Japanese.
|
||||
<ul>
|
||||
<li>Ideally we'd have an underlying engine for this. In 2.4 we will
|
||||
have a plug-in interface so that people could add one, such as the
|
||||
IBM engine.</li>
|
||||
<li>The data from CEDICT and Unihan don't list the most frequent
|
||||
choice first, so we will be updating that.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="Test_Greek-Latin_UNGEGN.html"><b>Greek/UNGEGN</b></a>: Uses a
|
||||
modern Greek transliteration, based on the UNGEGN rules at < <a href="http://www.eki.ee/wgrs/rom1_el.pdf">http://www.eki.ee/wgrs/rom1_el.pdf</a>
|
||||
>. This version will not roundtrip ancient Greek.</li>
|
||||
<li><a href="Test_Greek-Latin.html"><b>Greek</b></a>: Uses a classic Greek
|
||||
transliteration. This version will not roundtrip modern Greek.</li>
|
||||
</ul>
|
||||
<h3><b>Notes</b></h3>
|
||||
<ol>
|
||||
<li>For readability, the files have a few other things besides just the
|
||||
transliteration:
|
||||
<ul>
|
||||
<li>The first word of the sentences are titlecased, as are names (where we
|
||||
have a name-list, such as in Thai).</li>
|
||||
<li>The Latin in the original is mapped to the private-use zone before
|
||||
conversion, and then again after conversion. This does have the downside
|
||||
that any rules (such as in Han) that need to know the context (e.g. for
|
||||
inserting spaces or capitalization) will gum up a little bit. This is
|
||||
just an artifact of the test display.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>I don't think that ISO 11940 is a particularly good way to romanize, but
|
||||
it is at least complete and a standard. So what I am interested in just for
|
||||
now is whether the samples in the file follow it (with the above
|
||||
exceptions).</li>
|
||||
<li>Some of the files also have a set of characters at the end, one character
|
||||
per row, with a following row listing the hex and name.</li>
|
||||
<li>The source rules for all of these is in the following URL. So if you want
|
||||
to know the details of how the characters are handled, that is the place to
|
||||
look.
|
||||
<ul>
|
||||
<li><a href="http://source.icu-project.org/repos/icu/icu/trunk/source/data/translit/">http://source.icu-project.org/repos/icu/icu/trunk/source/data/translit/</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
69
demos/src/com/ibm/icu/dev/demo/translit/Test_Thai-Latin.txt
Normal file
69
demos/src/com/ibm/icu/dev/demo/translit/Test_Thai-Latin.txt
Normal file
|
@ -0,0 +1,69 @@
|
|||
#--------------------------------------------------------------------
|
||||
# Copyright (c) 1999-2004, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#--------------------------------------------------------------------
|
||||
@UPPERFILTER@
|
||||
Unicode คืออะไร?
|
||||
Unicode กำหนดหมายเลขเฉพาะสำหรับทุกอักขระ
|
||||
โดยไม่สนใจว่าเป็นแพล็ตฟอร์มใด
|
||||
ไม่ขึ้นกับว่าจะเป็นโปรแกรมใด
|
||||
และไม่ว่าจะเป็นภาษาใด
|
||||
|
||||
โดยพื้นฐานแล้ว, คอมพิวเตอร์จะเกี่ยวข้องกับเรื่องของตัวเลข. คอมพิวเตอร์จัดเก็บตัวอักษรและอักขระอื่นๆ โดยการกำหนดหมายเลขให้สำหรับแต่ละตัว. ก่อนหน้าที่๊ Unicode จะถูกสร้างขึ้น, ได้มีระบบ encoding อยู่หลายร้อยระบบสำหรับการกำหนดหมายเลขเหล่านี้. ไม่มี encoding ใดที่มีจำนวนตัวอักขระมากเพียงพอ: ยกตัวอย่างเช่น, เฉพาะในกลุ่มสหภาพยุโรปเพียงแห่งเดียว ก็ต้องการหลาย encoding ในการครอบคลุมทุกภาษาในกลุ่ม. หรือแม้แต่ในภาษาเดี่ยว เช่น ภาษาอังกฤษ ก็ไม่มี encoding ใดที่เพียงพอสำหรับทุกตัวอักษร, เครื่องหมายวรรคตอน และสัญลักษณ์ทางเทคนิคที่ใช้กันอยู่ทั่วไป.
|
||||
|
||||
ระบบ encoding เหล่านี้ยังขัดแย้งซึ่งกันและกัน. นั่นก็คือ, ในสอง encoding สามารถใช้หมายเลขเดียวกันสำหรับตัวอักขระสองตัวที่แตกต่างกัน,หรือใช้หมายเลขต่างกันสำหรับอักขระตัวเดียวกัน. ในระบบคอมพิวเตอร์ (โดยเฉพาะเซิร์ฟเวอร์) ต้องมีการสนับสนุนหลาย encoding; และเมื่อข้อมูลที่ผ่านไปมาระหว่างการเข้ารหัสหรือแพล็ตฟอร์มที่ต่างกัน, ข้อมูลนั้นจะเสี่ยงต่อการผิดพลาดเสียหาย.
|
||||
|
||||
Unicode จะเปลี่ยนแปลงสิ่งเหล่านั้นทั้งหมด!
|
||||
Unicode กำหนดหมายเลขเฉพาะสำหรับแต่ละอักขระ, โดยไม่สนใจว่าเป็นแพล็ตฟอร์มใด, ไม่ขึ้นกับว่าจะเป็นโปรแกรมใดและไม่ว่าจะเป็นภาษาใด. มาตรฐาน Unicode ได้ถูกนำไปใช้โดยผู้นำในอุตสาหกรรม เช่น Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys และอื่นๆ อีกมาก. Unicode เป็นสิ่งที่จำเป็นสำหรับมาตรฐานใหม่ๆ เช่น XML, Java, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML ฯลฯ., และเป็นแนวทางอย่างเป็นทางการในการทำ ISO/IEC 10646. Unicode ได้รับการสนับสนุนในระบบปฏิบัติการจำนวนมาก, บราวเซอร์ใหม่ๆ ทกตัว, และผลิตภัณฑ์อื่นๆ อีกมาก. การเกิดขึ้นของ Unicode Standard และทูลส์ต่างๆ ที่มีในการสนับสนุน Unicode, เป็นหนึ่งในแนวโน้มทางเทคโนโลยีซอฟต์แวร์ระดับโลกที่มีความสำคัญที่สุด.
|
||||
|
||||
การรวม Unicode เข้าไปในระบบไคลเอ็นต์-เซิร์ฟเวอร์ หรือแอ็พพลิเคชันแบบ multi-tiered และเว็บไซต์ จะทำให้เกิดการประหยัดค่าใช้จ่ายมากกว่าการใช้ชุดอักขระแบบเดิม. Unicode ทำให้ผลิตภัณฑ์ซอฟต์แวร์หนึ่งเดียว หรือเว็บไซต์แห่งเดียว รองรับได้หลายแพล็ตฟอร์ม, หลายภาษาและหลายประเทศโดยไม่ต้องทำการรื้อปรับระบบ. Unicode ยังทำให้ข้อมูลสามารถเคลื่อนย้ายไปมาในหลายๆ ระบบโดยไม่เกิดความผิดพลาดเสียหาย.
|
||||
|
||||
เกี่ยวกับ Unicode Consortium
|
||||
Unicode Consortium เป็นองค์กรไม่แสวงหากำไรที่ก่อตั้งขึ้นเพื่อพัฒนา, ขยายและส่งเสริมการใช้ Unicode Standard, ซึ่งกำหนดรูปแบบการแทนค่าของข้อความในผลิตภัณฑ์ซอฟต์แวร์และมาตรฐานใหม่ๆ. สมาชิกของสมาคมเป็นตัวแทนจากบริษัทและองค์กรในอุตสาหกรรมคอมพิวเตอร์และการประมวลผลสารสนเทศ. สมาคมได้รับการสนับสนุนทางการเงินผ่านทางค่าธรรมเนียมของการเป็นสมาชิกเท่านั้น. สมาชิกภาพของ Unicode Consortium เปิดกว้างสำหรับองค์กรหรือบุคคลใดๆ ในโลกที่ต้องการสนับสนุน Unicode Standard และช่วยเหลือการขยายตัวและการนำ Unicode ไปใช้งาน.
|
||||
|
||||
สำหรับข้อมูลเพิ่มเติม, ให้ดูที่ Glossary, Sample Unicode-Enabled Products, Technical Introduction และ Useful Resources.
|
||||
|
||||
เป็นมนุษย์สุดประเสริฐเลิศคุณค่า
|
||||
กว่าบรรดาฝูงสัตว์เดรัจฉาน
|
||||
จงฝ่าฟันพัฒนาวิชาการ
|
||||
อย่าล้างผลาญฤๅเข่นฆ่าบีฑาใคร
|
||||
ไม่ถือโทษโกรธแช่งซัดฮึดฮัดด่า
|
||||
หัดอภัยเหมือนกีฬาอัชฌาสัย
|
||||
ปฏิบัติประพฤติกฎกำหนดใจ
|
||||
พูดจาให้จ๊ะ ๆ จ๋า ๆ น่าฟังเอยฯ
|
||||
|
||||
แหล่งที่มา : สมาคมคอมพิวเตอร์แห่งประเทศไทย
|
||||
|
||||
ฅนฃวด kho khuat and kho khon
|
||||
@TITLECASE@
|
||||
ก๊กเฮง แซ่แต้
|
||||
กชกร ศราทธทัต
|
||||
กติกา อังคสุภณ
|
||||
กนก ธรรมประทีป
|
||||
กนก วงศ์ทองศรี
|
||||
กนกกร ช้างเย็นฉ่ำ
|
||||
กนกฉัตร์ ถาวรนันท์
|
||||
กนกนวล โปษยะนันทน์
|
||||
กนกพร คมคาย
|
||||
กนกพร ตีรเลิศพานิช
|
||||
กนกพร พันทร
|
||||
กนกพร ศรีบัณฑิต
|
||||
กนกพร อติวรรณาพัฒน์
|
||||
กนกพรรณ ศรีวนาภิรมย์
|
||||
กนกรัตน์ เกียรติยิ่งอังศุลี
|
||||
กนกรัตน์ สุธรรมพิทักษ์
|
||||
กนกวรรณ คงคาประเสริฐ
|
||||
กนกวรรณ แซ่เตียว
|
||||
กนกวรรณ บุญประเสริฐ
|
||||
กนกวรรณ รักทรัพย์
|
||||
กนกวรรณ สัจจพงษ์
|
||||
กนกวรรณ อุ้ยวงศ์ไพศาล
|
||||
กนกศักดิ์ ยิ่งยง
|
||||
กนกแก้ว กรสมิต
|
||||
กนิษฐา ทนุถนอมราษฎร์
|
||||
กนิษฐา หวังวิบูลย์กิจ
|
||||
กมล กาญจนโรจน์
|
||||
กมล คัมภีร์
|
||||
กมล เจตน์มงคลรัตน์
|
||||
กมล ชูตระกูลธรรม
|
||||
@SET [[:thai:] \u0E01-\u0E3A\u0E40-\u0E5B]
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.translit;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import com.ibm.icu.dev.demo.impl.DumbTextComponent;
|
||||
import com.ibm.icu.text.ReplaceableString;
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
|
||||
/**
|
||||
* A subclass of {@link DumbTextComponent} that passes key events through
|
||||
* a {@link com.ibm.icu.text.Transliterator}.
|
||||
*
|
||||
* @author Alan Liu
|
||||
*/
|
||||
public class TransliteratingTextComponent extends DumbTextComponent {
|
||||
|
||||
/**
|
||||
* For serialization
|
||||
*/
|
||||
private static final long serialVersionUID = -8672128213174154047L;
|
||||
|
||||
private static boolean DEBUG = false;
|
||||
|
||||
private Transliterator translit = null;
|
||||
|
||||
// NOTE: DISABLE THE START AND CURSOR UNTIL WE CAN GET IT TO WORK AT ALL
|
||||
|
||||
// Index into getText() where the start of transliteration is.
|
||||
// As we commit text during transliteration, we advance
|
||||
// this.
|
||||
//private int start = 0;
|
||||
|
||||
// Index into getText() where the cursor is; cursor >= start
|
||||
//private int cursor = 0;
|
||||
|
||||
// private static final String COPYRIGHT =
|
||||
// "\u00A9 IBM Corporation 1999. All rights reserved.";
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public TransliteratingTextComponent() {
|
||||
super();
|
||||
/*
|
||||
addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// We get an ActionEvent only when the selection changes
|
||||
resetTransliterationStart();
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link DumbTextComponent} API. Framework method that is called
|
||||
* when a <code>KeyEvent</code> is received. This implementation
|
||||
* runs the new character through the current
|
||||
* <code>Transliterator</code>, if one is set, and inserts the
|
||||
* transliterated text into the buffer.
|
||||
*/
|
||||
protected void handleKeyTyped(KeyEvent e) {
|
||||
char ch = e.getKeyChar();
|
||||
|
||||
if (translit == null) {
|
||||
setKeyStart(-1);
|
||||
super.handleKeyTyped(e);
|
||||
return;
|
||||
}
|
||||
|
||||
transliterate(ch, false);
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
if (translit != null) transliterate('\uFFFF', true);
|
||||
}
|
||||
|
||||
|
||||
protected void transliterate(char ch, boolean flush) {
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// The following case motivates the two lines that recompute
|
||||
// start and cursor below.
|
||||
|
||||
// " "
|
||||
// a b c q r|s t u m m
|
||||
// 0 1 2 3 4 5 6 7 8 9
|
||||
// 0 1 2
|
||||
|
||||
// start 3, cursor 5, sel 6 -> { 0, 3, 2 }
|
||||
// : new int[] { 0, sel - start, cursor - start };
|
||||
|
||||
// sz>99|9
|
||||
|
||||
// " { "
|
||||
// a b c q r 9 9|9 t u m m
|
||||
// 0 1 2 3 4 5 6 7 8 9 a b
|
||||
// 0 1 2 3 4
|
||||
|
||||
// { 3, 5, 4 } -> start 6, cursor 7, sel 8
|
||||
// : start += index[0];
|
||||
// : cursor = start + index[2] - index[0];
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Need to save start because calls to replaceRange will update
|
||||
// start and cursor.
|
||||
//int saveStart = start;
|
||||
|
||||
int end = flush ? getSelectionEnd() : getSelectionStart();
|
||||
String sourceText = getText().substring(0,end);
|
||||
ReplaceableString buf = new ReplaceableString(sourceText);
|
||||
/*buf.replace(0, 1, getText().substring(start,
|
||||
getSelectionStart()));*/
|
||||
|
||||
Transliterator.Position index = new Transliterator.Position();
|
||||
index.contextLimit = buf.length();
|
||||
index.contextStart = 0;
|
||||
index.start = getKeyStart();
|
||||
if (index.start == -1) index.start = getSelectionStart();
|
||||
index.limit = buf.length();
|
||||
|
||||
// StringBuffer log = null;
|
||||
if (DEBUG) {
|
||||
System.out.println("Transliterator: " + translit.getID());
|
||||
System.out.println("From:\t" + '"' + buf.toString() + '"'
|
||||
+ "; {cs: " + index.contextStart
|
||||
+ ", s: " + index.start
|
||||
+ ", l: " + index.limit
|
||||
+ ", cl: " + index.contextLimit
|
||||
+ "}" + "; '" + ch + "'"
|
||||
+ " " + getKeyStart()
|
||||
);
|
||||
}
|
||||
|
||||
if (flush) {
|
||||
translit.finishTransliteration(buf, index);
|
||||
} else {
|
||||
translit.transliterate(buf, index, ch);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println("To:\t" + '"' + buf.toString() + '"'
|
||||
+ "; {cs: " + index.contextStart
|
||||
+ ", s: " + index.start
|
||||
+ ", l: " + index.limit
|
||||
+ ", cl: " + index.contextLimit
|
||||
+ "}"
|
||||
);
|
||||
System.out.println();
|
||||
}
|
||||
/*
|
||||
buf.replace(buf.length(), buf.length(), String.valueOf(ch));
|
||||
translit.transliterate(buf);
|
||||
*/
|
||||
|
||||
String result = buf.toString();
|
||||
//if (result.equals(sourceText + ch)) return;
|
||||
|
||||
replaceRange(result, 0, getSelectionEnd());
|
||||
setKeyStart(index.start);
|
||||
|
||||
// At this point start has been changed by the callback to
|
||||
// resetTransliteratorStart() via replaceRange() -- so use our
|
||||
// local copy, saveStart.
|
||||
|
||||
// The START index is zero-based. On entry to transliterate(),
|
||||
// it was zero. We can therefore just add it to our original
|
||||
// getText()-based index value of start (in saveStart) to get
|
||||
// the new getText()-based start.
|
||||
// start = saveStart + index.contextStart;
|
||||
|
||||
// Make the cursor getText()-based. The CURSOR index is zero-based.
|
||||
// cursor = start + index.start - index.contextStart;
|
||||
|
||||
/*
|
||||
if (DEBUG) {
|
||||
String out = buf.toString();
|
||||
log.append(out.substring(0, index.contextStart)).
|
||||
append('{').
|
||||
append(out.substring(index.contextStart, index.start)).
|
||||
append('|').
|
||||
append(out.substring(index.start)).
|
||||
append('"');
|
||||
log.append(", {" + index.contextStart + ", " + index.contextLimit + ", " + index.start + "}, ");
|
||||
// log.append("start " + start + ", cursor " + cursor);
|
||||
log.append(", sel " + getSelectionStart());
|
||||
System.out.println(escape(log.toString()));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link com.ibm.icu.text.Transliterator} and direction to
|
||||
* use to process incoming <code>KeyEvent</code>s.
|
||||
* @param t the {@link com.ibm.icu.text.Transliterator} to use
|
||||
*/
|
||||
public void setTransliterator(Transliterator t) {
|
||||
/*
|
||||
if (translit != t) { // [sic] pointer compare ok; singletons
|
||||
resetTransliterationStart();
|
||||
}
|
||||
*/
|
||||
translit = t;
|
||||
}
|
||||
|
||||
public Transliterator getTransliterator() {
|
||||
return translit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the start point at which transliteration begins. This
|
||||
* needs to be done when the user moves the cursor or when the
|
||||
* current {@link com.ibm.icu.text.Transliterator} is changed.
|
||||
*/
|
||||
/*
|
||||
private void resetTransliterationStart() {
|
||||
start = getSelectionStart();
|
||||
cursor = start;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Escape non-ASCII characters as Unicode.
|
||||
* JUST FOR DEBUGGING OUTPUT.
|
||||
*/
|
||||
public static final String escape(String s) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i=0; i<s.length(); ++i) {
|
||||
char c = s.charAt(i);
|
||||
if (c >= ' ' && c <= 0x007F) {
|
||||
if (c == '\\') {
|
||||
buf.append("\\\\"); // That is, "\\"
|
||||
} else {
|
||||
buf.append(c);
|
||||
}
|
||||
} else {
|
||||
buf.append("\\u");
|
||||
if (c < 0x1000) {
|
||||
buf.append('0');
|
||||
if (c < 0x100) {
|
||||
buf.append('0');
|
||||
if (c < 0x10) {
|
||||
buf.append('0');
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.append(Integer.toHexString(c));
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2001-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.demo.translit;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.ibm.icu.impl.Utility;
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.lang.UScript;
|
||||
import com.ibm.icu.text.Normalizer;
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
import com.ibm.icu.text.UnicodeSetIterator;
|
||||
|
||||
public class TransliterationChart {
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.out.println("Start");
|
||||
UnicodeSet lengthMarks = new UnicodeSet("[\u09D7\u0B56-\u0B57\u0BD7\u0C56\u0CD5-\u0CD6\u0D57\u0C55\u0CD5]");
|
||||
int[] indicScripts = {
|
||||
UScript.LATIN,
|
||||
UScript.DEVANAGARI,
|
||||
UScript.BENGALI,
|
||||
UScript.GURMUKHI,
|
||||
UScript.GUJARATI,
|
||||
UScript.ORIYA,
|
||||
UScript.TAMIL,
|
||||
UScript.TELUGU,
|
||||
UScript.KANNADA,
|
||||
UScript.MALAYALAM,
|
||||
};
|
||||
String[] names = new String[indicScripts.length];
|
||||
UnicodeSet[] sets = new UnicodeSet[indicScripts.length];
|
||||
Transliterator[] fallbacks = new Transliterator[indicScripts.length];
|
||||
for (int i = 0; i < indicScripts.length; ++i) {
|
||||
names[i] = UScript.getName(indicScripts[i]);
|
||||
sets[i] = new UnicodeSet("[[:" + names[i] + ":]&[[:L:][:M:]]&[:age=3.1:]]");
|
||||
fallbacks[i] = Transliterator.getInstance("any-" + names[i]);
|
||||
}
|
||||
EquivClass eq = new EquivClass(new ReverseComparator());
|
||||
PrintWriter pw = openPrintWriter("transChart.html");
|
||||
pw.println("<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>");
|
||||
pw.println("<title>Indic Transliteration Chart</title><style>");
|
||||
pw.println("td { text-align: Center; font-size: 200% }");
|
||||
pw.println("tt { font-size: 50% }");
|
||||
pw.println("td.miss { background-color: #CCCCFF }");
|
||||
pw.println("</style></head><body bgcolor='#FFFFFF'>");
|
||||
|
||||
Transliterator anyToLatin = Transliterator.getInstance("any-latin");
|
||||
|
||||
String testString = "\u0946\u093E";
|
||||
|
||||
UnicodeSet failNorm = new UnicodeSet();
|
||||
Set latinFail = new TreeSet();
|
||||
|
||||
for (int i = 0; i < indicScripts.length; ++i) {
|
||||
if (indicScripts[i] == UScript.LATIN) continue;
|
||||
String source = names[i];
|
||||
System.out.println(source);
|
||||
UnicodeSet sourceChars = sets[i];
|
||||
|
||||
for (int j = 0; j < indicScripts.length; ++j) {
|
||||
if (i == j) continue;
|
||||
String target = names[j];
|
||||
Transliterator forward = Transliterator.getInstance(source + '-' + target);
|
||||
Transliterator backward = forward.getInverse();
|
||||
UnicodeSetIterator it = new UnicodeSetIterator(sourceChars);
|
||||
while (it.next()) {
|
||||
if (lengthMarks.contains(it.codepoint)) continue;
|
||||
String s = Normalizer.normalize(it.codepoint,Normalizer.NFC,0);
|
||||
//if (!Normalizer.isNormalized(s,Normalizer.NFC,0)) continue;
|
||||
if (!s.equals(Normalizer.normalize(s,Normalizer.NFD,0))) {
|
||||
failNorm.add(it.codepoint);
|
||||
}
|
||||
String t = fix(forward.transliterate(s));
|
||||
if (t.equals(testString)) {
|
||||
System.out.println("debug");
|
||||
}
|
||||
|
||||
String r = fix(backward.transliterate(t));
|
||||
if (Normalizer.compare(s,r,0) == 0) {
|
||||
if (indicScripts[j] != UScript.LATIN) eq.add(s,t);
|
||||
} else {
|
||||
if (indicScripts[j] == UScript.LATIN) {
|
||||
latinFail.add(s + " - " + t + " - " + r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// collect equivalents
|
||||
pw.println("<table border='1' cellspacing='0'><tr>");
|
||||
for (int i = 0; i < indicScripts.length; ++i) {
|
||||
pw.print("<th width='10%'>" + names[i].substring(0,3) + "</th>");
|
||||
}
|
||||
pw.println("</tr>");
|
||||
|
||||
Iterator rit = eq.getSetIterator(new MyComparator());
|
||||
while(rit.hasNext()) {
|
||||
Set equivs = (Set)rit.next();
|
||||
pw.print("<tr>");
|
||||
Iterator sit = equivs.iterator();
|
||||
String source = (String)sit.next();
|
||||
String item = anyToLatin.transliterate(source);
|
||||
if (item.equals("") || source.equals(item)) item = " ";
|
||||
pw.print("<td>" + item + "</td>");
|
||||
for (int i = 1; i < indicScripts.length; ++i) {
|
||||
sit = equivs.iterator();
|
||||
item = "";
|
||||
while (sit.hasNext()) {
|
||||
String trial = (String)sit.next();
|
||||
if (!sets[i].containsAll(trial)) continue;
|
||||
item = trial;
|
||||
break;
|
||||
}
|
||||
String classString = "";
|
||||
if (item.equals("")) {
|
||||
classString = " class='miss'";
|
||||
String temp = fallbacks[i].transliterate(source);
|
||||
if (!temp.equals("") && !temp.equals(source)) item = temp;
|
||||
}
|
||||
String backup = item.equals("") ? " " : item;
|
||||
pw.print("<td" + classString + " title='" + getName(item, "; ") + "'>"
|
||||
+ backup + "<br><tt>" + Utility.hex(item) + "</tt></td>");
|
||||
}
|
||||
/*
|
||||
Iterator sit = equivs.iterator();
|
||||
while (sit.hasNext()) {
|
||||
String item = (String)sit.next();
|
||||
pw.print("<td>" + item + "</td>");
|
||||
}
|
||||
*/
|
||||
pw.println("</tr>");
|
||||
}
|
||||
pw.println("</table>");
|
||||
if (true) {
|
||||
pw.println("<h2>Failed Normalization</h2>");
|
||||
|
||||
UnicodeSetIterator it = new UnicodeSetIterator(failNorm);
|
||||
UnicodeSet pieces = new UnicodeSet();
|
||||
while (it.next()) {
|
||||
String s = UTF16.valueOf(it.codepoint);
|
||||
String d = Normalizer.normalize(s,Normalizer.NFD,0);
|
||||
pw.println("Norm:" + s + ", " + Utility.hex(s) + " " + UCharacter.getName(it.codepoint)
|
||||
+ "; " + d + ", " + Utility.hex(d) + ", ");
|
||||
pw.println(UCharacter.getName(d.charAt(1)) + "<br>");
|
||||
if (UCharacter.getName(d.charAt(1)).indexOf("LENGTH") >= 0) pieces.add(d.charAt(1));
|
||||
}
|
||||
pw.println(pieces);
|
||||
|
||||
pw.println("<h2>Failed Round-Trip</h2>");
|
||||
Iterator cit = latinFail.iterator();
|
||||
while (cit.hasNext()) {
|
||||
pw.println(cit.next() + "<br>");
|
||||
}
|
||||
}
|
||||
|
||||
pw.println("</table></body></html>");
|
||||
pw.close();
|
||||
System.out.println("Done");
|
||||
}
|
||||
|
||||
public static String fix(String s) {
|
||||
if (s.equals("\u0946\u093E")) return "\u094A";
|
||||
if (s.equals("\u0C46\u0C3E")) return "\u0C4A";
|
||||
if (s.equals("\u0CC6\u0CBE")) return "\u0CCA";
|
||||
|
||||
if (s.equals("\u0947\u093E")) return "\u094B";
|
||||
if (s.equals("\u0A47\u0A3E")) return "\u0A4B";
|
||||
if (s.equals("\u0AC7\u0ABE")) return "\u0ACB";
|
||||
if (s.equals("\u0C47\u0C3E")) return "\u0C4B";
|
||||
if (s.equals("\u0CC7\u0CBE")) return "\u0CCB";
|
||||
|
||||
//return Normalizer.normalize(s,Normalizer.NFD,0);
|
||||
return s;
|
||||
}
|
||||
|
||||
public static PrintWriter openPrintWriter(String fileName) throws IOException {
|
||||
File lf = new File(fileName);
|
||||
System.out.println("Creating file: " + lf.getAbsoluteFile());
|
||||
|
||||
return new PrintWriter(
|
||||
new BufferedWriter(
|
||||
new OutputStreamWriter(
|
||||
new FileOutputStream(fileName), "UTF8"), 4*1024));
|
||||
}
|
||||
|
||||
|
||||
public static String getName(String s, String separator) {
|
||||
int cp;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < s.length(); i += UTF16.getCharCount(cp)) {
|
||||
cp = UTF16.charAt(s,i);
|
||||
if (i != 0) sb.append(separator);
|
||||
sb.append(UCharacter.getName(cp));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static class MyComparator implements Comparator {
|
||||
public int compare(Object o1, Object o2) {
|
||||
Iterator i1 = ((TreeSet) o1).iterator();
|
||||
Iterator i2 = ((TreeSet) o2).iterator();
|
||||
while (i1.hasNext() && i2.hasNext()) {
|
||||
String a = (String)i1.next();
|
||||
String b = (String)i2.next();
|
||||
int result = a.compareTo(b);
|
||||
if (result != 0) return result;
|
||||
}
|
||||
if (i1.hasNext()) return 1;
|
||||
if (i2.hasNext()) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
static class ReverseComparator implements Comparator {
|
||||
public int compare(Object o1, Object o2) {
|
||||
String a = o1.toString();
|
||||
char a1 = a.charAt(0);
|
||||
String b = o2.toString();
|
||||
char b1 = b.charAt(0);
|
||||
if (a1 < 0x900 && b1 > 0x900) return -1;
|
||||
if (a1 > 0x900 && b1 < 0x900) return +1;
|
||||
return a.compareTo(b);
|
||||
}
|
||||
}
|
||||
|
||||
static class EquivClass {
|
||||
EquivClass(Comparator c) {
|
||||
comparator = c;
|
||||
}
|
||||
private HashMap itemToSet = new HashMap();
|
||||
private Comparator comparator;
|
||||
|
||||
void add(Object a, Object b) {
|
||||
Set sa = (Set)itemToSet.get(a);
|
||||
Set sb = (Set)itemToSet.get(b);
|
||||
if (sa == null && sb == null) { // new set!
|
||||
Set s = new TreeSet(comparator);
|
||||
s.add(a);
|
||||
s.add(b);
|
||||
itemToSet.put(a, s);
|
||||
itemToSet.put(b, s);
|
||||
} else if (sa == null) {
|
||||
sb.add(a);
|
||||
} else if (sb == null) {
|
||||
sa.add(b);
|
||||
} else { // merge sets, dumping sb
|
||||
sa.addAll(sb);
|
||||
Iterator it = sb.iterator();
|
||||
while (it.hasNext()) {
|
||||
itemToSet.put(it.next(), sa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyIterator implements Iterator {
|
||||
private Iterator it;
|
||||
MyIterator (Comparator comp) {
|
||||
TreeSet values = new TreeSet(comp);
|
||||
values.addAll(itemToSet.values());
|
||||
it = values.iterator();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
public Object next() {
|
||||
return it.next();
|
||||
}
|
||||
public void remove() {
|
||||
throw new IllegalArgumentException("can't remove");
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator getSetIterator (Comparator comp) {
|
||||
return new MyIterator(comp);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
13
demos/src/com/ibm/icu/dev/demo/translit/demo.bat
Executable file
13
demos/src/com/ibm/icu/dev/demo/translit/demo.bat
Executable file
|
@ -0,0 +1,13 @@
|
|||
REM /*
|
||||
REM *******************************************************************************
|
||||
REM * Copyright (C) 1996-2004, International Business Machines Corporation and *
|
||||
REM * others. All Rights Reserved. *
|
||||
REM *******************************************************************************
|
||||
REM */
|
||||
REM For best results, run the demo as an applet inside of Netscape
|
||||
REM with Bitstream Cyberbit installed.
|
||||
|
||||
REM setup your JDK 1.1.x path and classpath here:
|
||||
call JDK11
|
||||
set CLASSPATH=../translit.jar;%CLASSPATH%
|
||||
javaw Demo
|
34
demos/src/com/ibm/icu/dev/demo/translit/demo.html
Normal file
34
demos/src/com/ibm/icu/dev/demo/translit/demo.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
<!--
|
||||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1999-2004, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
-->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Transliteration Demo</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<APPLET CODE="com.ibm.demo.translit.DemoApplet.class" WIDTH=140 HEIGHT=33></APPLET>
|
||||
|
||||
<HR>
|
||||
|
||||
If you don't see a button above, then your browser is failing to
|
||||
locate the necessary Java class files.
|
||||
|
||||
<P>
|
||||
|
||||
One way to make this work is to copy this HTML file to
|
||||
<code>icu4j/src</code>, and make sure the Java files in the directories
|
||||
under <code>icu4j/src/com</code> are built. Then open this HTML file
|
||||
using a browser or appletviewer.
|
||||
|
||||
<P>
|
||||
|
||||
For best results, run this demo as an applet within Netscape with
|
||||
Bitstream Cyberbit installed.
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
12
demos/src/com/ibm/icu/dev/demo/translit/package.html
Normal file
12
demos/src/com/ibm/icu/dev/demo/translit/package.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<!-- Copyright (C) 2000-2004, International Business Machines Corporation and
|
||||
others. All Rights Reserved.
|
||||
|
||||
-->
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
Transliterator demo appliation.
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
55
demos/src/com/ibm/icu/dev/demo/translit/thai_test.txt
Normal file
55
demos/src/com/ibm/icu/dev/demo/translit/thai_test.txt
Normal file
|
@ -0,0 +1,55 @@
|
|||
#--------------------------------------------------------------------
|
||||
# Copyright (c) 1999-2004, International Business Machines
|
||||
# Corporation and others. All Rights Reserved.
|
||||
#--------------------------------------------------------------------
|
||||
@UPPERFILTER@
|
||||
Unicode คืออะไร?
|
||||
Unicode กำหนดหมายเลขเฉพาะสำหรับทุกอักขระ
|
||||
โดยไม่สนใจว่าเป็นแพล็ตฟอร์มใด
|
||||
ไม่ขึ้นกับว่าจะเป็นโปรแกรมใด
|
||||
และไม่ว่าจะเป็นภาษาใด
|
||||
|
||||
โดยพื้นฐานแล้ว, คอมพิวเตอร์จะเกี่ยวข้องกับเรื่องของตัวเลข. คอมพิวเตอร์จัดเก็บตัวอักษรและอักขระอื่นๆ โดยการกำหนดหมายเลขให้สำหรับแต่ละตัว. ก่อนหน้าที่๊ Unicode จะถูกสร้างขึ้น, ได้มีระบบ encoding อยู่หลายร้อยระบบสำหรับการกำหนดหมายเลขเหล่านี้. ไม่มี encoding ใดที่มีจำนวนตัวอักขระมากเพียงพอ: ยกตัวอย่างเช่น, เฉพาะในกลุ่มสหภาพยุโรปเพียงแห่งเดียว ก็ต้องการหลาย encoding ในการครอบคลุมทุกภาษาในกลุ่ม. หรือแม้แต่ในภาษาเดี่ยว เช่น ภาษาอังกฤษ ก็ไม่มี encoding ใดที่เพียงพอสำหรับทุกตัวอักษร, เครื่องหมายวรรคตอน และสัญลักษณ์ทางเทคนิคที่ใช้กันอยู่ทั่วไป.
|
||||
|
||||
ระบบ encoding เหล่านี้ยังขัดแย้งซึ่งกันและกัน. นั่นก็คือ, ในสอง encoding สามารถใช้หมายเลขเดียวกันสำหรับตัวอักขระสองตัวที่แตกต่างกัน,หรือใช้หมายเลขต่างกันสำหรับอักขระตัวเดียวกัน. ในระบบคอมพิวเตอร์ (โดยเฉพาะเซิร์ฟเวอร์) ต้องมีการสนับสนุนหลาย encoding; และเมื่อข้อมูลที่ผ่านไปมาระหว่างการเข้ารหัสหรือแพล็ตฟอร์มที่ต่างกัน, ข้อมูลนั้นจะเสี่ยงต่อการผิดพลาดเสียหาย.
|
||||
|
||||
Unicode จะเปลี่ยนแปลงสิ่งเหล่านั้นทั้งหมด!
|
||||
Unicode กำหนดหมายเลขเฉพาะสำหรับแต่ละอักขระ, โดยไม่สนใจว่าเป็นแพล็ตฟอร์มใด, ไม่ขึ้นกับว่าจะเป็นโปรแกรมใดและไม่ว่าจะเป็นภาษาใด. มาตรฐาน Unicode ได้ถูกนำไปใช้โดยผู้นำในอุตสาหกรรม เช่น Apple, HP, IBM, JustSystem, Microsoft, Oracle, SAP, Sun, Sybase, Unisys และอื่นๆ อีกมาก. Unicode เป็นสิ่งที่จำเป็นสำหรับมาตรฐานใหม่ๆ เช่น XML, Java, ECMAScript (JavaScript), LDAP, CORBA 3.0, WML ฯลฯ., และเป็นแนวทางอย่างเป็นทางการในการทำ ISO/IEC 10646. Unicode ได้รับการสนับสนุนในระบบปฏิบัติการจำนวนมาก, บราวเซอร์ใหม่ๆ ทกตัว, และผลิตภัณฑ์อื่นๆ อีกมาก. การเกิดขึ้นของ Unicode Standard และทูลส์ต่างๆ ที่มีในการสนับสนุน Unicode, เป็นหนึ่งในแนวโน้มทางเทคโนโลยีซอฟต์แวร์ระดับโลกที่มีความสำคัญที่สุด.
|
||||
|
||||
การรวม Unicode เข้าไปในระบบไคลเอ็นต์-เซิร์ฟเวอร์ หรือแอ็พพลิเคชันแบบ multi-tiered และเว็บไซต์ จะทำให้เกิดการประหยัดค่าใช้จ่ายมากกว่าการใช้ชุดอักขระแบบเดิม. Unicode ทำให้ผลิตภัณฑ์ซอฟต์แวร์หนึ่งเดียว หรือเว็บไซต์แห่งเดียว รองรับได้หลายแพล็ตฟอร์ม, หลายภาษาและหลายประเทศโดยไม่ต้องทำการรื้อปรับระบบ. Unicode ยังทำให้ข้อมูลสามารถเคลื่อนย้ายไปมาในหลายๆ ระบบโดยไม่เกิดความผิดพลาดเสียหาย.
|
||||
|
||||
เกี่ยวกับ Unicode Consortium
|
||||
Unicode Consortium เป็นองค์กรไม่แสวงหากำไรที่ก่อตั้งขึ้นเพื่อพัฒนา, ขยายและส่งเสริมการใช้ Unicode Standard, ซึ่งกำหนดรูปแบบการแทนค่าของข้อความในผลิตภัณฑ์ซอฟต์แวร์และมาตรฐานใหม่ๆ. สมาชิกของสมาคมเป็นตัวแทนจากบริษัทและองค์กรในอุตสาหกรรมคอมพิวเตอร์และการประมวลผลสารสนเทศ. สมาคมได้รับการสนับสนุนทางการเงินผ่านทางค่าธรรมเนียมของการเป็นสมาชิกเท่านั้น. สมาชิกภาพของ Unicode Consortium เปิดกว้างสำหรับองค์กรหรือบุคคลใดๆ ในโลกที่ต้องการสนับสนุน Unicode Standard และช่วยเหลือการขยายตัวและการนำ Unicode ไปใช้งาน.
|
||||
|
||||
สำหรับข้อมูลเพิ่มเติม, ให้ดูที่ Glossary, Sample Unicode-Enabled Products, Technical Introduction และ Useful Resources.
|
||||
@TITLECASE@
|
||||
ก๊กเฮง แซ่แต้
|
||||
กชกร ศราทธทัต
|
||||
กติกา อังคสุภณ
|
||||
กนก ธรรมประทีป
|
||||
กนก วงศ์ทองศรี
|
||||
กนกกร ช้างเย็นฉ่ำ
|
||||
กนกฉัตร์ ถาวรนันท์
|
||||
กนกนวล โปษยะนันทน์
|
||||
กนกพร คมคาย
|
||||
กนกพร ตีรเลิศพานิช
|
||||
กนกพร พันทร
|
||||
กนกพร ศรีบัณฑิต
|
||||
กนกพร อติวรรณาพัฒน์
|
||||
กนกพรรณ ศรีวนาภิรมย์
|
||||
กนกรัตน์ เกียรติยิ่งอังศุลี
|
||||
กนกรัตน์ สุธรรมพิทักษ์
|
||||
กนกวรรณ คงคาประเสริฐ
|
||||
กนกวรรณ แซ่เตียว
|
||||
กนกวรรณ บุญประเสริฐ
|
||||
กนกวรรณ รักทรัพย์
|
||||
กนกวรรณ สัจจพงษ์
|
||||
กนกวรรณ อุ้ยวงศ์ไพศาล
|
||||
กนกศักดิ์ ยิ่งยง
|
||||
กนกแก้ว กรสมิต
|
||||
กนิษฐา ทนุถนอมราษฎร์
|
||||
กนิษฐา หวังวิบูลย์กิจ
|
||||
กมล กาญจนโรจน์
|
||||
กมล คัมภีร์
|
||||
กมล เจตน์มงคลรัตน์
|
||||
กมล ชูตระกูลธรรม
|
7
main/classes/charset/.classpath
Normal file
7
main/classes/charset/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry excluding="**/.svn/" kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/icu4j-core"/>
|
||||
<classpathentry kind="output" path="out/bin"/>
|
||||
</classpath>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
|
||||
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AFTER_CLEAN_TARGETS" value="copy-data,"/>
|
||||
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="copy-data,"/>
|
||||
<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/icu4j-charset/build.xml"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="icu4j-charset"/>
|
||||
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTIES">
|
||||
<mapEntry key="eclipse.running" value="true"/>
|
||||
<mapEntry key="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTY_FILES" value="${workspace_loc:/icu4j-shared/build/locations-eclipse.properties},"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/icu4j-charset/build.xml}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
</launchConfiguration>
|
29
main/classes/charset/.project
Normal file
29
main/classes/charset/.project
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>icu4j-charset</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>icu4j-core</project>
|
||||
<project>icu4j-shared</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/copy-data-charset.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
343
main/classes/charset/.settings/org.eclipse.jdt.core.prefs
Normal file
343
main/classes/charset/.settings/org.eclipse.jdt.core.prefs
Normal file
|
@ -0,0 +1,343 @@
|
|||
#Thu Aug 27 17:46:17 EDT 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=120
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=120
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
10
main/classes/charset/.settings/org.eclipse.jdt.ui.prefs
Normal file
10
main/classes/charset/.settings/org.eclipse.jdt.ui.prefs
Normal file
File diff suppressed because one or more lines are too long
6
main/classes/charset/build.properties
Normal file
6
main/classes/charset/build.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
#*******************************************************************************
|
||||
#* Copyright (C) 2009, International Business Machines Corporation and *
|
||||
#* others. All Rights Reserved. *
|
||||
#*******************************************************************************
|
||||
shared.dir = ../../shared
|
||||
javac.compilerarg = -Xlint:all,-deprecation,-dep-ann
|
38
main/classes/charset/build.xml
Normal file
38
main/classes/charset/build.xml
Normal file
|
@ -0,0 +1,38 @@
|
|||
<!--
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
-->
|
||||
<project name="charset" default="build" basedir=".">
|
||||
<property file="build-local.properties"/>
|
||||
<property file="build.properties"/>
|
||||
<import file="${shared.dir}/build/common-targets.xml"/>
|
||||
|
||||
<path id="javac.classpathref">
|
||||
<path refid="javac.classpathref.${ant.project.name}"/>
|
||||
</path>
|
||||
<property name="jar.file" value="${icu4j.charset.jar}"/>
|
||||
|
||||
<target name="build" depends="compile, copy, jar" description="Build the project"/>
|
||||
|
||||
<target name="build-all" depends="@build-all" description="Build the project including all dependencies"/>
|
||||
|
||||
<target name="clean" depends="@clean" description="Clean up the build outputs"/>
|
||||
|
||||
<target name="compile" depends="@compile" description="Compile java source files"/>
|
||||
|
||||
<target name="copy" depends="@copy, copy-data" description="Copy non-java runtime files to the project's binary directory"/>
|
||||
|
||||
<target name="jar" depends="compile, copy, @jar" description="Create the project's jar file"/>
|
||||
|
||||
<target name="copy-data" description="Extract pre-built ICU core data files and copy them to the project's binary directory">
|
||||
<unjar src="${icu4j.data.jar}" dest="${bin.dir}">
|
||||
<patternset>
|
||||
<include name="**/*.cnv"/>
|
||||
<include name="**/cnvalias.icu"/>
|
||||
</patternset>
|
||||
</unjar>
|
||||
</target>
|
||||
|
||||
</project>
|
21
main/classes/charset/charset-build.launch
Normal file
21
main/classes/charset/charset-build.launch
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ant.AntLaunchConfigurationType">
|
||||
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/icu4j-charset/build.xml"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="icu4j-charset"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
|
||||
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTIES">
|
||||
<mapEntry key="eclipse.running" value="true"/>
|
||||
<mapEntry key="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTY_FILES" value="${workspace_loc:/icu4j-shared/build/locations-eclipse.properties},"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_TARGETS" value="build-all,"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/icu4j-charset/build.xml}"/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/>
|
||||
</launchConfiguration>
|
11
main/classes/charset/manifest.stub
Normal file
11
main/classes/charset/manifest.stub
Normal file
|
@ -0,0 +1,11 @@
|
|||
Manifest-Version: 1.0
|
||||
|
||||
Name: com/ibm/icu/charset
|
||||
Specification-Title: ICU4J Charset
|
||||
Specification-Version: @SPECVERSION@
|
||||
Specification-Vendor: ICU
|
||||
Implementation-Title: ICU for Java Charset
|
||||
Implementation-Version: @IMPLVERSION@
|
||||
Implementation-Vendor: IBM Corporation
|
||||
Implementation-Vendor-Id: com.ibm
|
||||
Copyright-Info: @COPYRIGHT@
|
|
@ -0,0 +1,3 @@
|
|||
# Copyright (C) 2006, International Business Machines Corporation and others. All Rights Reserved.
|
||||
# icu4j converters
|
||||
com.ibm.icu.charset.CharsetProviderICU
|
128
main/classes/charset/src/com/ibm/icu/charset/Charset88591.java
Normal file
128
main/classes/charset/src/com/ibm/icu/charset/Charset88591.java
Normal file
|
@ -0,0 +1,128 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
class Charset88591 extends CharsetASCII {
|
||||
public Charset88591(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
}
|
||||
|
||||
class CharsetDecoder88591 extends CharsetDecoderASCII {
|
||||
public CharsetDecoder88591(CharsetICU cs) {
|
||||
super(cs);
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoopCoreOptimized(ByteBuffer source, CharBuffer target,
|
||||
byte[] sourceArray, char[] targetArray, int oldSource, int offset, int limit) {
|
||||
|
||||
/*
|
||||
* perform 88591 conversion from the source array to the target array. no range check is
|
||||
* necessary.
|
||||
*/
|
||||
for (int i = oldSource; i < limit; i++)
|
||||
targetArray[i + offset] = (char) (sourceArray[i] & 0xff);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoopCoreUnoptimized(ByteBuffer source, CharBuffer target)
|
||||
throws BufferUnderflowException, BufferOverflowException {
|
||||
|
||||
/*
|
||||
* perform 88591 conversion from the source buffer to the target buffer. no range check
|
||||
* is necessary (an exception will be generated to end the loop).
|
||||
*/
|
||||
while (true)
|
||||
target.put((char) (source.get() & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
class CharsetEncoder88591 extends CharsetEncoderASCII {
|
||||
public CharsetEncoder88591(CharsetICU cs) {
|
||||
super(cs);
|
||||
}
|
||||
|
||||
protected final CoderResult encodeLoopCoreOptimized(CharBuffer source, ByteBuffer target,
|
||||
char[] sourceArray, byte[] targetArray, int oldSource, int offset, int limit,
|
||||
boolean flush) {
|
||||
int i, ch = 0;
|
||||
|
||||
/*
|
||||
* perform 88591 conversion from the source array to the target array, making sure each
|
||||
* char in the source is within the correct range
|
||||
*/
|
||||
for (i = oldSource; i < limit; i++) {
|
||||
ch = (int) sourceArray[i];
|
||||
if ((ch & 0xff00) == 0) {
|
||||
targetArray[i + offset] = (byte) ch;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if some byte was not in the correct range, we need to deal with this byte by calling
|
||||
* encodeMalformedOrUnmappable and move the source and target positions to reflect the
|
||||
* early termination of the loop
|
||||
*/
|
||||
if ((ch & 0xff00) != 0) {
|
||||
source.position(i + 1);
|
||||
target.position(i + offset);
|
||||
return encodeMalformedOrUnmappable(source, ch, flush);
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
protected final CoderResult encodeLoopCoreUnoptimized(CharBuffer source, ByteBuffer target,
|
||||
boolean flush) throws BufferUnderflowException, BufferOverflowException {
|
||||
int ch;
|
||||
|
||||
/*
|
||||
* perform 88591 conversion from the source buffer to the target buffer, making sure
|
||||
* each char in the source is within the correct range
|
||||
*/
|
||||
|
||||
while (true) {
|
||||
ch = (int) source.get();
|
||||
if ((ch & 0xff00) == 0) {
|
||||
target.put((byte) ch);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* if we reach here, it's because a character was not in the correct range, and we need
|
||||
* to deak with this by calling encodeMalformedOrUnmappable.
|
||||
*/
|
||||
return encodeMalformedOrUnmappable(source, ch, flush);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new CharsetDecoder88591(this);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new CharsetEncoder88591(this);
|
||||
}
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
setFillIn.add(0,0xff);
|
||||
}
|
||||
}
|
357
main/classes/charset/src/com/ibm/icu/charset/CharsetASCII.java
Normal file
357
main/classes/charset/src/com/ibm/icu/charset/CharsetASCII.java
Normal file
|
@ -0,0 +1,357 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
class CharsetASCII extends CharsetICU {
|
||||
protected byte[] fromUSubstitution = new byte[] { (byte) 0x1a };
|
||||
|
||||
public CharsetASCII(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
maxBytesPerChar = 1;
|
||||
minBytesPerChar = 1;
|
||||
maxCharsPerByte = 1;
|
||||
}
|
||||
|
||||
class CharsetDecoderASCII extends CharsetDecoderICU {
|
||||
|
||||
public CharsetDecoderASCII(CharsetICU cs) {
|
||||
super(cs);
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets,
|
||||
boolean flush) {
|
||||
if (!source.hasRemaining()) {
|
||||
/* no input, nothing to do */
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
if (!target.hasRemaining()) {
|
||||
/* no output available, can't do anything */
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
CoderResult cr;
|
||||
int oldSource = source.position();
|
||||
int oldTarget = target.position();
|
||||
|
||||
if (source.hasArray() && target.hasArray()) {
|
||||
/* optimized loop */
|
||||
|
||||
/*
|
||||
* extract arrays from the buffers and obtain various constant values that will be
|
||||
* necessary in the core loop
|
||||
*/
|
||||
byte[] sourceArray = source.array();
|
||||
int sourceOffset = source.arrayOffset();
|
||||
int sourceIndex = oldSource + sourceOffset;
|
||||
int sourceLength = source.limit() - oldSource;
|
||||
|
||||
char[] targetArray = target.array();
|
||||
int targetOffset = target.arrayOffset();
|
||||
int targetIndex = oldTarget + targetOffset;
|
||||
int targetLength = target.limit() - oldTarget;
|
||||
|
||||
int limit = ((sourceLength < targetLength) ? sourceLength : targetLength)
|
||||
+ sourceIndex;
|
||||
int offset = targetIndex - sourceIndex;
|
||||
|
||||
/*
|
||||
* perform the core loop... if it returns null, it must be due to an overflow or
|
||||
* underflow
|
||||
*/
|
||||
cr = decodeLoopCoreOptimized(source, target, sourceArray, targetArray, sourceIndex, offset, limit);
|
||||
if (cr == null) {
|
||||
if (sourceLength <= targetLength) {
|
||||
source.position(oldSource + sourceLength);
|
||||
target.position(oldTarget + sourceLength);
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
} else {
|
||||
source.position(oldSource + targetLength);
|
||||
target.position(oldTarget + targetLength);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* unoptimized loop */
|
||||
|
||||
try {
|
||||
/*
|
||||
* perform the core loop... if it throws an exception, it must be due to an
|
||||
* overflow or underflow
|
||||
*/
|
||||
cr = decodeLoopCoreUnoptimized(source, target);
|
||||
|
||||
} catch (BufferUnderflowException ex) {
|
||||
/* all of the source has been read */
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
} catch (BufferOverflowException ex) {
|
||||
/* the target is full */
|
||||
source.position(source.position() - 1); /* rewind by 1 */
|
||||
cr = CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
/* set offsets since the start */
|
||||
if (offsets != null) {
|
||||
int count = target.position() - oldTarget;
|
||||
int sourceIndex = -1;
|
||||
while (--count >= 0) offsets.put(++sourceIndex);
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoopCoreOptimized(ByteBuffer source, CharBuffer target,
|
||||
byte[] sourceArray, char[] targetArray, int oldSource, int offset, int limit) {
|
||||
int i, ch = 0;
|
||||
|
||||
/*
|
||||
* perform ascii conversion from the source array to the target array, making sure each
|
||||
* byte in the source is within the correct range
|
||||
*/
|
||||
for (i = oldSource; i < limit && (((ch = (sourceArray[i] & 0xff)) & 0x80) == 0); i++)
|
||||
targetArray[i + offset] = (char) ch;
|
||||
|
||||
/*
|
||||
* if some byte was not in the correct range, we need to deal with this byte by calling
|
||||
* decodeMalformedOrUnmappable and move the source and target positions to reflect the
|
||||
* early termination of the loop
|
||||
*/
|
||||
if ((ch & 0x80) != 0) {
|
||||
source.position(i + 1);
|
||||
target.position(i + offset);
|
||||
return decodeMalformedOrUnmappable(ch);
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoopCoreUnoptimized(ByteBuffer source, CharBuffer target)
|
||||
throws BufferUnderflowException, BufferOverflowException {
|
||||
int ch = 0;
|
||||
|
||||
/*
|
||||
* perform ascii conversion from the source buffer to the target buffer, making sure
|
||||
* each byte in the source is within the correct range
|
||||
*/
|
||||
while (((ch = (source.get() & 0xff)) & 0x80) == 0)
|
||||
target.put((char) ch);
|
||||
|
||||
/*
|
||||
* if we reach here, it's because a character was not in the correct range, and we need
|
||||
* to deak with this by calling decodeMalformedOrUnmappable
|
||||
*/
|
||||
return decodeMalformedOrUnmappable(ch);
|
||||
}
|
||||
|
||||
protected CoderResult decodeMalformedOrUnmappable(int ch) {
|
||||
/*
|
||||
* put the guilty character into toUBytesArray and return a message saying that the
|
||||
* character was malformed and of length 1.
|
||||
*/
|
||||
toUBytesArray[0] = (byte) ch;
|
||||
toULength = 1;
|
||||
return CoderResult.malformedForLength(1);
|
||||
}
|
||||
}
|
||||
|
||||
class CharsetEncoderASCII extends CharsetEncoderICU {
|
||||
|
||||
public CharsetEncoderASCII(CharsetICU cs) {
|
||||
super(cs, fromUSubstitution);
|
||||
implReset();
|
||||
}
|
||||
|
||||
private final static int NEED_TO_WRITE_BOM = 1;
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
fromUnicodeStatus = NEED_TO_WRITE_BOM;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
boolean flush) {
|
||||
if (!source.hasRemaining()) {
|
||||
/* no input, nothing to do */
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
if (!target.hasRemaining()) {
|
||||
/* no output available, can't do anything */
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
CoderResult cr;
|
||||
int oldSource = source.position();
|
||||
int oldTarget = target.position();
|
||||
|
||||
if (fromUChar32 != 0) {
|
||||
/*
|
||||
* if we have a leading character in fromUChar32 that needs to be dealt with, we
|
||||
* need to check for a matching trail character and taking the appropriate action as
|
||||
* dictated by encodeTrail.
|
||||
*/
|
||||
cr = encodeTrail(source, (char) fromUChar32, flush);
|
||||
} else {
|
||||
if (source.hasArray() && target.hasArray()) {
|
||||
/* optimized loop */
|
||||
|
||||
/*
|
||||
* extract arrays from the buffers and obtain various constant values that will
|
||||
* be necessary in the core loop
|
||||
*/
|
||||
char[] sourceArray = source.array();
|
||||
int sourceOffset = source.arrayOffset();
|
||||
int sourceIndex = oldSource + sourceOffset;
|
||||
int sourceLength = source.limit() - oldSource;
|
||||
|
||||
byte[] targetArray = target.array();
|
||||
int targetOffset = target.arrayOffset();
|
||||
int targetIndex = oldTarget + targetOffset;
|
||||
int targetLength = target.limit() - oldTarget;
|
||||
|
||||
int limit = ((sourceLength < targetLength) ? sourceLength : targetLength)
|
||||
+ sourceIndex;
|
||||
int offset = targetIndex - sourceIndex;
|
||||
|
||||
/*
|
||||
* perform the core loop... if it returns null, it must be due to an overflow or
|
||||
* underflow
|
||||
*/
|
||||
cr = encodeLoopCoreOptimized(source, target, sourceArray, targetArray, sourceIndex, offset, limit, flush);
|
||||
if (cr == null) {
|
||||
if (sourceLength <= targetLength) {
|
||||
source.position(oldSource + sourceLength);
|
||||
target.position(oldTarget + sourceLength);
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
} else {
|
||||
source.position(oldSource + targetLength);
|
||||
target.position(oldTarget + targetLength);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* unoptimized loop */
|
||||
|
||||
try {
|
||||
/*
|
||||
* perform the core loop... if it throws an exception, it must be due to an
|
||||
* overflow or underflow
|
||||
*/
|
||||
cr = encodeLoopCoreUnoptimized(source, target, flush);
|
||||
|
||||
} catch (BufferUnderflowException ex) {
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
} catch (BufferOverflowException ex) {
|
||||
source.position(source.position() - 1); /* rewind by 1 */
|
||||
cr = CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set offsets since the start */
|
||||
if (offsets != null) {
|
||||
int count = target.position() - oldTarget;
|
||||
int sourceIndex = -1;
|
||||
while (--count >= 0) offsets.put(++sourceIndex);
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoopCoreOptimized(CharBuffer source, ByteBuffer target,
|
||||
char[] sourceArray, byte[] targetArray, int oldSource, int offset, int limit,
|
||||
boolean flush) {
|
||||
int i, ch = 0;
|
||||
|
||||
/*
|
||||
* perform ascii conversion from the source array to the target array, making sure each
|
||||
* char in the source is within the correct range
|
||||
*/
|
||||
for (i = oldSource; i < limit && (((ch = (int) sourceArray[i]) & 0xff80) == 0); i++)
|
||||
targetArray[i + offset] = (byte) ch;
|
||||
|
||||
/*
|
||||
* if some byte was not in the correct range, we need to deal with this byte by calling
|
||||
* encodeMalformedOrUnmappable and move the source and target positions to reflect the
|
||||
* early termination of the loop
|
||||
*/
|
||||
if ((ch & 0xff80) != 0) {
|
||||
source.position(i + 1);
|
||||
target.position(i + offset);
|
||||
return encodeMalformedOrUnmappable(source, ch, flush);
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoopCoreUnoptimized(CharBuffer source, ByteBuffer target,
|
||||
boolean flush) throws BufferUnderflowException, BufferOverflowException {
|
||||
int ch;
|
||||
|
||||
/*
|
||||
* perform ascii conversion from the source buffer to the target buffer, making sure
|
||||
* each char in the source is within the correct range
|
||||
*/
|
||||
while (((ch = (int) source.get()) & 0xff80) == 0)
|
||||
target.put((byte) ch);
|
||||
|
||||
/*
|
||||
* if we reach here, it's because a character was not in the correct range, and we need
|
||||
* to deak with this by calling encodeMalformedOrUnmappable.
|
||||
*/
|
||||
return encodeMalformedOrUnmappable(source, ch, flush);
|
||||
}
|
||||
|
||||
protected final CoderResult encodeMalformedOrUnmappable(CharBuffer source, int ch, boolean flush) {
|
||||
/*
|
||||
* if the character is a lead surrogate, we need to call encodeTrail to attempt to match
|
||||
* it up with a trail surrogate. if not, the character is unmappable.
|
||||
*/
|
||||
return (UTF16.isSurrogate((char) ch))
|
||||
? encodeTrail(source, (char) ch, flush)
|
||||
: CoderResult.unmappableForLength(1);
|
||||
}
|
||||
|
||||
private final CoderResult encodeTrail(CharBuffer source, char lead, boolean flush) {
|
||||
/*
|
||||
* ASCII doesn't support characters in the BMP, so if handleSurrogates returns null,
|
||||
* we leave fromUChar32 alone (it should store a new codepoint) and call it unmappable.
|
||||
*/
|
||||
CoderResult cr = handleSurrogates(source, lead);
|
||||
if (cr != null) {
|
||||
return cr;
|
||||
} else {
|
||||
//source.position(source.position() - 2);
|
||||
return CoderResult.unmappableForLength(2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new CharsetDecoderASCII(this);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new CharsetEncoderASCII(this);
|
||||
}
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
setFillIn.add(0,0x7f);
|
||||
}
|
||||
}
|
1063
main/classes/charset/src/com/ibm/icu/charset/CharsetBOCU1.java
Normal file
1063
main/classes/charset/src/com/ibm/icu/charset/CharsetBOCU1.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* The purpose of this class is to set isCESU8 to true in the super class, and to allow the Charset framework to open
|
||||
* the variant UTF-8 converter without extra setup work. CESU-8 encodes/decodes supplementary characters as 6 bytes
|
||||
* instead of the proper 4 bytes.
|
||||
*/
|
||||
class CharsetCESU8 extends CharsetUTF8 {
|
||||
public CharsetCESU8(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
}
|
||||
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
getCompleteUnicodeSet(setFillIn);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,408 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
/**
|
||||
* <h2> Callback API for CharsetICU API </h2>
|
||||
*
|
||||
* CharsetCallback class defines some error behaviour functions called
|
||||
* by CharsetDecoderICU and CharsetEncoderICU. The class also provides
|
||||
* the facility by which clients can write their own callbacks.
|
||||
*
|
||||
* These functions, although public, should NEVER be called directly.
|
||||
* They should be used as parameters to the onUmappableCharacter() and
|
||||
* onMalformedInput() methods, to set the behaviour of a converter
|
||||
* when it encounters UNMAPPED/INVALID sequences.
|
||||
* Currently the only way to set callbacks is by using CodingErrorAction.
|
||||
* In the future we will provide set methods on CharsetEncoder and CharsetDecoder
|
||||
* that will accept CharsetCallback fields.
|
||||
*
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
|
||||
public class CharsetCallback {
|
||||
/*
|
||||
* FROM_U, TO_U context options for sub callback
|
||||
*/
|
||||
private static final String SUB_STOP_ON_ILLEGAL = "i";
|
||||
|
||||
// /*
|
||||
// * FROM_U, TO_U context options for skip callback
|
||||
// */
|
||||
// private static final String SKIP_STOP_ON_ILLEGAL = "i";
|
||||
|
||||
// /*
|
||||
// * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to ICU (%UXXXX)
|
||||
// */
|
||||
// private static final String ESCAPE_ICU = null;
|
||||
|
||||
/*
|
||||
* FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to JAVA (\\uXXXX)
|
||||
*/
|
||||
private static final String ESCAPE_JAVA = "J";
|
||||
|
||||
/*
|
||||
* FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to C (\\uXXXX \\UXXXXXXXX)
|
||||
* TO_U_CALLBACK_ESCAPE option to escape the character value accoding to C (\\xXXXX)
|
||||
*/
|
||||
private static final String ESCAPE_C = "C";
|
||||
|
||||
/*
|
||||
* FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly
|
||||
* TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly
|
||||
*/
|
||||
private static final String ESCAPE_XML_DEC = "D";
|
||||
|
||||
/*
|
||||
* FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly
|
||||
* TO_U_CALLBACK_ESCAPE context option to escape the character value according to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly
|
||||
*/
|
||||
private static final String ESCAPE_XML_HEX = "X";
|
||||
|
||||
/*
|
||||
* FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to Unicode (U+XXXXX)
|
||||
*/
|
||||
private static final String ESCAPE_UNICODE = "U";
|
||||
|
||||
/*
|
||||
* FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to Unicode (U+XXXXX)
|
||||
*/
|
||||
private static final String ESCAPE_CSS2 = "S";
|
||||
|
||||
/**
|
||||
* Decoder Callback interface
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public interface Decoder {
|
||||
/**
|
||||
* This function is called when the bytes in the source cannot be handled,
|
||||
* and this function is meant to handle or fix the error if possible.
|
||||
*
|
||||
* @return Result of decoding action. This returned object is set to an error
|
||||
* if this function could not handle the conversion.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public CoderResult call(CharsetDecoderICU decoder, Object context,
|
||||
ByteBuffer source, CharBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, CoderResult cr);
|
||||
}
|
||||
/**
|
||||
* Encoder Callback interface
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public interface Encoder {
|
||||
/**
|
||||
* This function is called when the Unicode characters in the source cannot be handled,
|
||||
* and this function is meant to handle or fix the error if possible.
|
||||
* @return Result of decoding action. This returned object is set to an error
|
||||
* if this function could not handle the conversion.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public CoderResult call(CharsetEncoderICU encoder, Object context,
|
||||
CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, int cp, CoderResult cr);
|
||||
}
|
||||
/**
|
||||
* Skip callback
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public static final Encoder FROM_U_CALLBACK_SKIP = new Encoder() {
|
||||
public CoderResult call(CharsetEncoderICU encoder, Object context,
|
||||
CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, int cp, CoderResult cr){
|
||||
if(context==null){
|
||||
return CoderResult.UNDERFLOW;
|
||||
}else if(((String)context).equals(SUB_STOP_ON_ILLEGAL)){
|
||||
if(!cr.isUnmappable()){
|
||||
return cr;
|
||||
}else{
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Skip callback
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public static final Decoder TO_U_CALLBACK_SKIP = new Decoder() {
|
||||
public CoderResult call(CharsetDecoderICU decoder, Object context,
|
||||
ByteBuffer source, CharBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, CoderResult cr){
|
||||
if(context==null){
|
||||
return CoderResult.UNDERFLOW;
|
||||
}else if(((String)context).equals(SUB_STOP_ON_ILLEGAL)){
|
||||
if(!cr.isUnmappable()){
|
||||
return cr;
|
||||
}else{
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Write substitute callback
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public static final Encoder FROM_U_CALLBACK_SUBSTITUTE = new Encoder(){
|
||||
public CoderResult call(CharsetEncoderICU encoder, Object context,
|
||||
CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, int cp, CoderResult cr){
|
||||
if(context==null){
|
||||
return encoder.cbFromUWriteSub(encoder, source, target, offsets);
|
||||
}else if(((String)context).equals(SUB_STOP_ON_ILLEGAL)){
|
||||
if(!cr.isUnmappable()){
|
||||
return cr;
|
||||
}else{
|
||||
return encoder.cbFromUWriteSub(encoder, source, target, offsets);
|
||||
}
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
};
|
||||
private static final char[] kSubstituteChar1 = new char[]{0x1A};
|
||||
private static final char[] kSubstituteChar = new char[] {0xFFFD};
|
||||
/**
|
||||
* Write substitute callback
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public static final Decoder TO_U_CALLBACK_SUBSTITUTE = new Decoder() {
|
||||
public CoderResult call(CharsetDecoderICU decoder, Object context,
|
||||
ByteBuffer source, CharBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, CoderResult cr){
|
||||
|
||||
CharsetICU cs = (CharsetICU) decoder.charset();
|
||||
/* could optimize this case, just one uchar */
|
||||
if(decoder.invalidCharLength == 1 && cs.subChar1 != 0) {
|
||||
return CharsetDecoderICU.toUWriteUChars(decoder, kSubstituteChar1, 0, 1, target, offsets, source.position());
|
||||
} else {
|
||||
return CharsetDecoderICU.toUWriteUChars(decoder, kSubstituteChar, 0, 1, target, offsets, source.position());
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Stop callback
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public static final Encoder FROM_U_CALLBACK_STOP = new Encoder() {
|
||||
public CoderResult call(CharsetEncoderICU encoder, Object context,
|
||||
CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, int cp, CoderResult cr){
|
||||
return cr;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Stop callback
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public static final Decoder TO_U_CALLBACK_STOP = new Decoder() {
|
||||
public CoderResult call(CharsetDecoderICU decoder, Object context,
|
||||
ByteBuffer source, CharBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, CoderResult cr){
|
||||
return cr;
|
||||
}
|
||||
};
|
||||
private static final int VALUE_STRING_LENGTH = 32;
|
||||
private static final char UNICODE_PERCENT_SIGN_CODEPOINT = 0x0025;
|
||||
private static final char UNICODE_U_CODEPOINT = 0x0055;
|
||||
private static final char UNICODE_X_CODEPOINT = 0x0058;
|
||||
private static final char UNICODE_RS_CODEPOINT = 0x005C;
|
||||
private static final char UNICODE_U_LOW_CODEPOINT = 0x0075;
|
||||
private static final char UNICODE_X_LOW_CODEPOINT = 0x0078;
|
||||
private static final char UNICODE_AMP_CODEPOINT = 0x0026;
|
||||
private static final char UNICODE_HASH_CODEPOINT = 0x0023;
|
||||
private static final char UNICODE_SEMICOLON_CODEPOINT = 0x003B;
|
||||
private static final char UNICODE_PLUS_CODEPOINT = 0x002B;
|
||||
private static final char UNICODE_LEFT_CURLY_CODEPOINT = 0x007B;
|
||||
private static final char UNICODE_RIGHT_CURLY_CODEPOINT = 0x007D;
|
||||
private static final char UNICODE_SPACE_CODEPOINT = 0x0020;
|
||||
/**
|
||||
* Write escape callback
|
||||
* @stable ICU 4.0
|
||||
*/
|
||||
public static final Encoder FROM_U_CALLBACK_ESCAPE = new Encoder() {
|
||||
public CoderResult call(CharsetEncoderICU encoder, Object context,
|
||||
CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, int cp, CoderResult cr){
|
||||
char[] valueString = new char[VALUE_STRING_LENGTH];
|
||||
int valueStringLength = 0;
|
||||
int i = 0;
|
||||
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
|
||||
if (context == null || !(context instanceof String)) {
|
||||
while (i < length) {
|
||||
valueString[valueStringLength++] = UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */
|
||||
valueString[valueStringLength++] = UNICODE_U_CODEPOINT; /* adding U */
|
||||
valueStringLength += itou(valueString, valueStringLength, (int)buffer[i++] & UConverterConstants.UNSIGNED_SHORT_MASK, 16, 4);
|
||||
}
|
||||
} else {
|
||||
if (((String)context).equals(ESCAPE_JAVA)) {
|
||||
while (i < length) {
|
||||
valueString[valueStringLength++] = UNICODE_RS_CODEPOINT; /* adding \ */
|
||||
valueString[valueStringLength++] = UNICODE_U_LOW_CODEPOINT; /* adding u */
|
||||
valueStringLength += itou(valueString, valueStringLength, (int)buffer[i++] & UConverterConstants.UNSIGNED_SHORT_MASK, 16, 4);
|
||||
}
|
||||
} else if (((String)context).equals(ESCAPE_C)) {
|
||||
valueString[valueStringLength++] = UNICODE_RS_CODEPOINT; /* adding \ */
|
||||
|
||||
if (length == 2) {
|
||||
valueString[valueStringLength++] = UNICODE_U_CODEPOINT; /* adding U */
|
||||
valueStringLength = itou(valueString, valueStringLength, cp, 16, 8);
|
||||
} else {
|
||||
valueString[valueStringLength++] = UNICODE_U_LOW_CODEPOINT; /* adding u */
|
||||
valueStringLength += itou(valueString, valueStringLength, (int)buffer[0] & UConverterConstants.UNSIGNED_SHORT_MASK, 16, 4);
|
||||
}
|
||||
} else if (((String)context).equals(ESCAPE_XML_DEC)) {
|
||||
valueString[valueStringLength++] = UNICODE_AMP_CODEPOINT; /* adding & */
|
||||
valueString[valueStringLength++] = UNICODE_HASH_CODEPOINT; /* adding # */
|
||||
if (length == 2) {
|
||||
valueStringLength += itou(valueString, valueStringLength, cp, 10, 0);
|
||||
} else {
|
||||
valueStringLength += itou(valueString, valueStringLength, (int)buffer[0] & UConverterConstants.UNSIGNED_SHORT_MASK, 10, 0);
|
||||
}
|
||||
valueString[valueStringLength++] = UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
|
||||
} else if (((String)context).equals(ESCAPE_XML_HEX)) {
|
||||
valueString[valueStringLength++] = UNICODE_AMP_CODEPOINT; /* adding & */
|
||||
valueString[valueStringLength++] = UNICODE_HASH_CODEPOINT; /* adding # */
|
||||
valueString[valueStringLength++] = UNICODE_X_LOW_CODEPOINT; /* adding x */
|
||||
if (length == 2) {
|
||||
valueStringLength += itou(valueString, valueStringLength, cp, 16, 0);
|
||||
} else {
|
||||
valueStringLength += itou(valueString, valueStringLength, (int)buffer[0] & UConverterConstants.UNSIGNED_SHORT_MASK, 16, 0);
|
||||
}
|
||||
valueString[valueStringLength++] = UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
|
||||
} else if (((String)context).equals(ESCAPE_UNICODE)) {
|
||||
valueString[valueStringLength++] = UNICODE_LEFT_CURLY_CODEPOINT; /* adding { */
|
||||
valueString[valueStringLength++] = UNICODE_U_CODEPOINT; /* adding U */
|
||||
valueString[valueStringLength++] = UNICODE_PLUS_CODEPOINT; /* adding + */
|
||||
if (length == 2) {
|
||||
valueStringLength += itou(valueString, valueStringLength,cp, 16, 4);
|
||||
} else {
|
||||
valueStringLength += itou(valueString, valueStringLength, (int)buffer[0] & UConverterConstants.UNSIGNED_SHORT_MASK, 16, 4);
|
||||
}
|
||||
valueString[valueStringLength++] = UNICODE_RIGHT_CURLY_CODEPOINT; /* adding } */
|
||||
} else if (((String)context).equals(ESCAPE_CSS2)) {
|
||||
valueString[valueStringLength++] = UNICODE_RS_CODEPOINT; /* adding \ */
|
||||
valueStringLength += itou(valueString, valueStringLength, cp, 16, 0);
|
||||
/* Always add space character, because the next character might be whitespace,
|
||||
which would erroneously be considered the termination of the escape sequence. */
|
||||
valueString[valueStringLength++] = UNICODE_SPACE_CODEPOINT;
|
||||
} else {
|
||||
while (i < length) {
|
||||
valueString[valueStringLength++] = UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */
|
||||
valueString[valueStringLength++] = UNICODE_U_CODEPOINT; /* adding U */
|
||||
valueStringLength += itou(valueString, valueStringLength, (int)buffer[i++] & UConverterConstants.UNSIGNED_SHORT_MASK, 16, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cr = encoder.cbFromUWriteUChars(encoder, CharBuffer.wrap(valueString, 0, valueStringLength), target, offsets);
|
||||
return cr;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Write escape callback
|
||||
* @stable ICU 4.0
|
||||
*/
|
||||
public static final Decoder TO_U_CALLBACK_ESCAPE = new Decoder() {
|
||||
public CoderResult call(CharsetDecoderICU decoder, Object context,
|
||||
ByteBuffer source, CharBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, CoderResult cr){
|
||||
char[] uniValueString = new char[VALUE_STRING_LENGTH];
|
||||
int valueStringLength = 0;
|
||||
int i = 0;
|
||||
|
||||
if (context == null || !(context instanceof String)) {
|
||||
while (i < length) {
|
||||
uniValueString[valueStringLength++] = UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */
|
||||
uniValueString[valueStringLength++] = UNICODE_X_CODEPOINT; /* adding U */
|
||||
valueStringLength += itou(uniValueString, valueStringLength, buffer[i++] & UConverterConstants.UNSIGNED_BYTE_MASK, 16, 2);
|
||||
}
|
||||
} else {
|
||||
if (((String)context).equals(ESCAPE_XML_DEC)) {
|
||||
while (i < length) {
|
||||
uniValueString[valueStringLength++] = UNICODE_AMP_CODEPOINT; /* adding & */
|
||||
uniValueString[valueStringLength++] = UNICODE_HASH_CODEPOINT; /* adding # */
|
||||
valueStringLength += itou(uniValueString, valueStringLength, buffer[i++] & UConverterConstants.UNSIGNED_BYTE_MASK, 10, 0);
|
||||
uniValueString[valueStringLength++] = UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
|
||||
}
|
||||
} else if (((String)context).equals(ESCAPE_XML_HEX)) {
|
||||
while (i < length) {
|
||||
uniValueString[valueStringLength++] = UNICODE_AMP_CODEPOINT; /* adding & */
|
||||
uniValueString[valueStringLength++] = UNICODE_HASH_CODEPOINT; /* adding # */
|
||||
uniValueString[valueStringLength++] = UNICODE_X_LOW_CODEPOINT; /* adding x */
|
||||
valueStringLength += itou(uniValueString, valueStringLength, buffer[i++] & UConverterConstants.UNSIGNED_BYTE_MASK, 16, 0);
|
||||
uniValueString[valueStringLength++] = UNICODE_SEMICOLON_CODEPOINT; /* adding ; */
|
||||
}
|
||||
} else if (((String)context).equals(ESCAPE_C)) {
|
||||
while (i < length) {
|
||||
uniValueString[valueStringLength++] = UNICODE_RS_CODEPOINT; /* adding \ */
|
||||
uniValueString[valueStringLength++] = UNICODE_X_LOW_CODEPOINT; /* adding x */
|
||||
valueStringLength += itou(uniValueString, valueStringLength, buffer[i++] & UConverterConstants.UNSIGNED_BYTE_MASK, 16, 2);
|
||||
}
|
||||
} else {
|
||||
while (i < length) {
|
||||
uniValueString[valueStringLength++] = UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */
|
||||
uniValueString[valueStringLength++] = UNICODE_X_CODEPOINT; /* adding X */
|
||||
itou(uniValueString, valueStringLength, buffer[i++] & UConverterConstants.UNSIGNED_BYTE_MASK, 16, 2);
|
||||
valueStringLength += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cr = CharsetDecoderICU.toUWriteUChars(decoder, uniValueString, 0, valueStringLength, target, offsets, 0);
|
||||
|
||||
return cr;
|
||||
}
|
||||
};
|
||||
/***
|
||||
* Java port of uprv_itou() in ICU4C used by TO_U_CALLBACK_ESCAPE and FROM_U_CALLBACK_ESCAPE.
|
||||
* Fills in a char string with the radix-based representation of a number padded with zeroes
|
||||
* to minwidth.
|
||||
*/
|
||||
private static final int itou(char[] buffer, int sourceIndex, int i, int radix, int minwidth) {
|
||||
int length = 0;
|
||||
int digit;
|
||||
int j;
|
||||
char temp;
|
||||
|
||||
do {
|
||||
digit = i % radix;
|
||||
buffer[sourceIndex + length++] = (char)(digit <= 9 ? (0x0030+digit) : (0x0030+digit+7));
|
||||
i = i/radix;
|
||||
} while (i != 0 && (sourceIndex + length) < buffer.length);
|
||||
|
||||
while (length < minwidth) {
|
||||
buffer[sourceIndex + length++] = (char)0x0030; /* zero padding */
|
||||
}
|
||||
/* reverses the string */
|
||||
for (j = 0; j < (length / 2); j++) {
|
||||
temp = buffer[(sourceIndex + length - 1) - j];
|
||||
buffer[(sourceIndex + length-1) -j] = buffer[sourceIndex + j];
|
||||
buffer[sourceIndex + j] = temp;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* No need to create an instance
|
||||
*/
|
||||
private CharsetCallback() {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,725 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
|
||||
import com.ibm.icu.impl.Assert;
|
||||
|
||||
/**
|
||||
* An abstract class that provides framework methods of decoding operations for concrete
|
||||
* subclasses.
|
||||
* In the future this class will contain API that will implement converter sematics of ICU4C.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public abstract class CharsetDecoderICU extends CharsetDecoder{
|
||||
|
||||
int toUnicodeStatus;
|
||||
byte[] toUBytesArray = new byte[128];
|
||||
int toUBytesBegin = 0;
|
||||
int toULength;
|
||||
char[] charErrorBufferArray = new char[128];
|
||||
int charErrorBufferLength;
|
||||
int charErrorBufferBegin;
|
||||
char[] invalidCharBuffer = new char[128];
|
||||
int invalidCharLength;
|
||||
|
||||
/**
|
||||
* Maximum number of indexed bytes
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
protected static final int EXT_MAX_BYTES = 0x1f;
|
||||
|
||||
/* store previous UChars/chars to continue partial matches */
|
||||
byte[] preToUArray = new byte[EXT_MAX_BYTES];
|
||||
int preToUBegin;
|
||||
int preToULength; /* negative: replay */
|
||||
int preToUFirstLength; /* length of first character */
|
||||
int mode;
|
||||
|
||||
Object toUContext = null;
|
||||
private CharsetCallback.Decoder onUnmappableCharacter = CharsetCallback.TO_U_CALLBACK_STOP;
|
||||
private CharsetCallback.Decoder onMalformedInput = CharsetCallback.TO_U_CALLBACK_STOP;
|
||||
CharsetCallback.Decoder toCharErrorBehaviour = new CharsetCallback.Decoder() {
|
||||
public CoderResult call(CharsetDecoderICU decoder, Object context, ByteBuffer source,
|
||||
CharBuffer target, IntBuffer offsets, char[] buffer, int length, CoderResult cr) {
|
||||
if (cr.isUnmappable()) {
|
||||
return onUnmappableCharacter.call(decoder, context, source, target, offsets, buffer,
|
||||
length, cr);
|
||||
} else /* if (cr.isMalformed()) */ {
|
||||
return onMalformedInput.call(decoder, context, source, target, offsets, buffer,
|
||||
length, cr);
|
||||
}
|
||||
// return CharsetCallback.TO_U_CALLBACK_STOP.call(decoder, context, source, target, offsets, buffer, length, cr);
|
||||
}
|
||||
};
|
||||
|
||||
// exist to keep implOnMalformedInput and implOnUnmappableInput from being too recursive
|
||||
private boolean malformedInputCalled = false;
|
||||
private boolean unmappableCharacterCalled = false;
|
||||
|
||||
/*
|
||||
* Construct a CharsetDecorderICU based on the information provided from a CharsetICU object.
|
||||
*
|
||||
* @param cs The CharsetICU object containing information about how to charset to decode.
|
||||
*/
|
||||
CharsetDecoderICU(CharsetICU cs) {
|
||||
super(cs, (1/cs.maxCharsPerByte), cs.maxCharsPerByte);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this Decoder allowed to use fallbacks? A fallback mapping is a mapping
|
||||
* that will convert a byte sequence to a Unicode codepoint sequence, but
|
||||
* the encoded Unicode codepoint sequence will round trip convert to a different
|
||||
* byte sequence. In ICU, this is can be called a reverse fallback.
|
||||
* @return A boolean
|
||||
*/
|
||||
final boolean isFallbackUsed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback is currently always used by icu4j decoders.
|
||||
*/
|
||||
static final boolean isToUUseFallback() {
|
||||
return isToUUseFallback(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback is currently always used by icu4j decoders.
|
||||
*/
|
||||
static final boolean isToUUseFallback(boolean iUseFallback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action to be taken if an illegal sequence is encountered
|
||||
*
|
||||
* @param newAction action to be taken
|
||||
* @exception IllegalArgumentException
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected final void implOnMalformedInput(CodingErrorAction newAction) {
|
||||
// don't run infinitely
|
||||
if (malformedInputCalled)
|
||||
return;
|
||||
|
||||
// if we get a replace, do not let the nio replace
|
||||
if (newAction == CodingErrorAction.REPLACE) {
|
||||
malformedInputCalled = true;
|
||||
super.onMalformedInput(CodingErrorAction.IGNORE);
|
||||
malformedInputCalled = false;
|
||||
}
|
||||
|
||||
onMalformedInput = getCallback(newAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action to be taken if an illegal sequence is encountered
|
||||
*
|
||||
* @param newAction action to be taken
|
||||
* @exception IllegalArgumentException
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected final void implOnUnmappableCharacter(CodingErrorAction newAction) {
|
||||
// dont run infinitely
|
||||
if (unmappableCharacterCalled)
|
||||
return;
|
||||
|
||||
// if we get a replace, do not let the nio replace
|
||||
if (newAction == CodingErrorAction.REPLACE) {
|
||||
unmappableCharacterCalled = true;
|
||||
super.onUnmappableCharacter(CodingErrorAction.IGNORE);
|
||||
unmappableCharacterCalled = false;
|
||||
}
|
||||
|
||||
onUnmappableCharacter = getCallback(newAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the callback encoder method and context to be used if an illegal sequence is encounterd.
|
||||
* You would normally call this twice to set both the malform and unmappable error. In this case,
|
||||
* newContext should remain the same since using a different newContext each time will negate the last
|
||||
* one used.
|
||||
* @param err CoderResult
|
||||
* @param newCallback CharsetCallback.Encoder
|
||||
* @param newContext Object
|
||||
* @stable ICU 4.0
|
||||
*/
|
||||
public final void setToUCallback(CoderResult err, CharsetCallback.Decoder newCallback, Object newContext) {
|
||||
if (err.isMalformed()) {
|
||||
onMalformedInput = newCallback;
|
||||
} else if (err.isUnmappable()) {
|
||||
onUnmappableCharacter = newCallback;
|
||||
} else {
|
||||
/* Error: Only malformed and unmappable are handled. */
|
||||
}
|
||||
|
||||
if (toUContext == null || !toUContext.equals(newContext)) {
|
||||
toUContext = newContext;
|
||||
}
|
||||
}
|
||||
|
||||
private static CharsetCallback.Decoder getCallback(CodingErrorAction action){
|
||||
if(action==CodingErrorAction.REPLACE){
|
||||
return CharsetCallback.TO_U_CALLBACK_SUBSTITUTE;
|
||||
}else if(action==CodingErrorAction.IGNORE){
|
||||
return CharsetCallback.TO_U_CALLBACK_SKIP;
|
||||
}else /* if(action==CodingErrorAction.REPORT) */ {
|
||||
return CharsetCallback.TO_U_CALLBACK_STOP;
|
||||
}
|
||||
}
|
||||
private final ByteBuffer EMPTY = ByteBuffer.allocate(0);
|
||||
/**
|
||||
* Flushes any characters saved in the converter's internal buffer and
|
||||
* resets the converter.
|
||||
* @param out action to be taken
|
||||
* @return result of flushing action and completes the decoding all input.
|
||||
* Returns CoderResult.UNDERFLOW if the action succeeds.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected final CoderResult implFlush(CharBuffer out) {
|
||||
return decode(EMPTY, out, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the to Unicode mode of converter
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected void implReset() {
|
||||
toUnicodeStatus = 0 ;
|
||||
toULength = 0;
|
||||
charErrorBufferLength = 0;
|
||||
charErrorBufferBegin = 0;
|
||||
|
||||
/* store previous UChars/chars to continue partial matches */
|
||||
preToUBegin = 0;
|
||||
preToULength = 0; /* negative: replay */
|
||||
preToUFirstLength = 0;
|
||||
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes one or more bytes. The default behaviour of the converter
|
||||
* is stop and report if an error in input stream is encountered.
|
||||
* To set different behaviour use @see CharsetDecoder.onMalformedInput()
|
||||
* This method allows a buffer by buffer conversion of a data stream.
|
||||
* The state of the conversion is saved between calls to convert.
|
||||
* Among other things, this means multibyte input sequences can be
|
||||
* split between calls. If a call to convert results in an Error, the
|
||||
* conversion may be continued by calling convert again with suitably
|
||||
* modified parameters.All conversions should be finished with a call to
|
||||
* the flush method.
|
||||
* @param in buffer to decode
|
||||
* @param out buffer to populate with decoded result
|
||||
* @return Result of decoding action. Returns CoderResult.UNDERFLOW if the decoding
|
||||
* action succeeds or more input is needed for completing the decoding action.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected CoderResult decodeLoop(ByteBuffer in,CharBuffer out){
|
||||
if(in.remaining() < toUCountPending()){
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
// if (!in.hasRemaining()) {
|
||||
// toULength = 0;
|
||||
// return CoderResult.UNDERFLOW;
|
||||
// }
|
||||
|
||||
in.position(in.position() + toUCountPending());
|
||||
|
||||
/* do the conversion */
|
||||
CoderResult ret = decode(in, out, null, false);
|
||||
|
||||
// ok was there input held in the previous invocation of decodeLoop
|
||||
// that resulted in output in this invocation?
|
||||
in.position(in.position() - toUCountPending());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements the ICU semantic for decode operation
|
||||
* @param in The input byte buffer
|
||||
* @param out The output character buffer
|
||||
* @return Result of decoding action. Returns CoderResult.UNDERFLOW if the decoding
|
||||
* action succeeds or more input is needed for completing the decoding action.
|
||||
*/
|
||||
abstract CoderResult decodeLoop(ByteBuffer in, CharBuffer out, IntBuffer offsets, boolean flush);
|
||||
|
||||
/*
|
||||
* Implements the ICU semantic for decode operation
|
||||
* @param source The input byte buffer
|
||||
* @param target The output character buffer
|
||||
* @param offsets
|
||||
* @param flush true if, and only if, the invoker can provide no
|
||||
* additional input bytes beyond those in the given buffer.
|
||||
* @return Result of decoding action. Returns CoderResult.UNDERFLOW if the decoding
|
||||
* action succeeds or more input is needed for completing the decoding action.
|
||||
*/
|
||||
final CoderResult decode(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
|
||||
|
||||
/* check parameters */
|
||||
if (target == null || source == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the buffer sizes do not exceed the number range for
|
||||
* int32_t because some functions use the size (in units or bytes)
|
||||
* rather than comparing pointers, and because offsets are int32_t values.
|
||||
*
|
||||
* size_t is guaranteed to be unsigned and large enough for the job.
|
||||
*
|
||||
* Return with an error instead of adjusting the limits because we would
|
||||
* not be able to maintain the semantics that either the source must be
|
||||
* consumed or the target filled (unless an error occurs).
|
||||
* An adjustment would be sourceLimit=t+0x7fffffff; for example.
|
||||
*/
|
||||
/*agljport:fix
|
||||
if(
|
||||
((size_t)(sourceLimit-s)>(size_t)0x7fffffff && sourceLimit>s) ||
|
||||
((size_t)(targetLimit-t)>(size_t)0x3fffffff && targetLimit>t)
|
||||
) {
|
||||
*err=U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
/* flush the target overflow buffer */
|
||||
if (charErrorBufferLength > 0) {
|
||||
int i = 0;
|
||||
do {
|
||||
if (!target.hasRemaining()) {
|
||||
/* the overflow buffer contains too much, keep the rest */
|
||||
int j = 0;
|
||||
|
||||
do {
|
||||
charErrorBufferArray[j++] = charErrorBufferArray[i++];
|
||||
} while (i < charErrorBufferLength);
|
||||
|
||||
charErrorBufferLength = (byte) j;
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
/* copy the overflow contents to the target */
|
||||
target.put(charErrorBufferArray[i++]);
|
||||
if (offsets != null) {
|
||||
offsets.put(-1); /* no source index available for old output */
|
||||
}
|
||||
} while (i < charErrorBufferLength);
|
||||
|
||||
/* the overflow buffer is completely copied to the target */
|
||||
charErrorBufferLength = 0;
|
||||
}
|
||||
|
||||
if (!flush && !source.hasRemaining() && preToULength >= 0) {
|
||||
/* the overflow buffer is emptied and there is no new input: we are done */
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not simply return with a buffer overflow error if
|
||||
* !flush && t==targetLimit
|
||||
* because it is possible that the source will not generate any output.
|
||||
* For example, the skip callback may be called;
|
||||
* it does not output anything.
|
||||
*/
|
||||
|
||||
return toUnicodeWithCallback(source, target, offsets, flush);
|
||||
}
|
||||
|
||||
/* Currently, we are not using offsets in ICU4J. */
|
||||
/* private void updateOffsets(IntBuffer offsets,int length, int sourceIndex, int errorInputLength) {
|
||||
int limit;
|
||||
int delta, offset;
|
||||
|
||||
if(sourceIndex>=0) {
|
||||
/*
|
||||
* adjust each offset by adding the previous sourceIndex
|
||||
* minus the length of the input sequence that caused an
|
||||
* error, if any
|
||||
*/
|
||||
/* delta=sourceIndex-errorInputLength;
|
||||
} else {
|
||||
/*
|
||||
* set each offset to -1 because this conversion function
|
||||
* does not handle offsets
|
||||
*/
|
||||
/* delta=-1;
|
||||
}
|
||||
limit=offsets.position()+length;
|
||||
if(delta==0) {
|
||||
/* most common case, nothing to do */
|
||||
/* } else if(delta>0) {
|
||||
/* add the delta to each offset (but not if the offset is <0) */
|
||||
/* while(offsets.position()<limit) {
|
||||
offset=offsets.get(offsets.position());
|
||||
if(offset>=0) {
|
||||
offsets.put(offset+delta);
|
||||
}
|
||||
//FIXME: ++offsets;
|
||||
}
|
||||
} else /* delta<0 */ /* {
|
||||
/*
|
||||
* set each offset to -1 because this conversion function
|
||||
* does not handle offsets
|
||||
* or the error input sequence started in a previous buffer
|
||||
*/
|
||||
/* while(offsets.position()<limit) {
|
||||
offsets.put(-1);
|
||||
}
|
||||
}
|
||||
} */
|
||||
final CoderResult toUnicodeWithCallback(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush){
|
||||
|
||||
int sourceIndex;
|
||||
int errorInputLength;
|
||||
boolean converterSawEndOfInput, calledCallback;
|
||||
//int t=target.position();
|
||||
int s=source.position();
|
||||
/* variables for m:n conversion */
|
||||
ByteBuffer replayArray = ByteBuffer.allocate(EXT_MAX_BYTES);
|
||||
int replayArrayIndex = 0;
|
||||
|
||||
ByteBuffer realSource=null;
|
||||
boolean realFlush=false;
|
||||
int realSourceIndex=0;
|
||||
|
||||
|
||||
CoderResult cr = CoderResult.UNDERFLOW;
|
||||
|
||||
/* get the converter implementation function */
|
||||
sourceIndex=0;
|
||||
|
||||
if(preToULength>=0) {
|
||||
/* normal mode */
|
||||
} else {
|
||||
/*
|
||||
* Previous m:n conversion stored source units from a partial match
|
||||
* and failed to consume all of them.
|
||||
* We need to "replay" them from a temporary buffer and convert them first.
|
||||
*/
|
||||
realSource=source;
|
||||
realFlush=flush;
|
||||
realSourceIndex=sourceIndex;
|
||||
//UConverterUtility.uprv_memcpy(replayArray, replayBegin, preToUArray, preToUBegin, -preToULength);
|
||||
replayArray.put(preToUArray,0, -preToULength);
|
||||
source=replayArray;
|
||||
source.position(0);
|
||||
source.limit(replayArrayIndex-preToULength);
|
||||
flush=false;
|
||||
sourceIndex=-1;
|
||||
preToULength=0;
|
||||
}
|
||||
|
||||
/*
|
||||
* loop for conversion and error handling
|
||||
*
|
||||
* loop {
|
||||
* convert
|
||||
* loop {
|
||||
* update offsets
|
||||
* handle end of input
|
||||
* handle errors/call callback
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
for(;;) {
|
||||
|
||||
/* convert */
|
||||
cr = decodeLoop(source, target, offsets, flush);
|
||||
|
||||
/*
|
||||
* set a flag for whether the converter
|
||||
* successfully processed the end of the input
|
||||
*
|
||||
* need not check cnv->preToULength==0 because a replay (<0) will cause
|
||||
* s<sourceLimit before converterSawEndOfInput is checked
|
||||
*/
|
||||
converterSawEndOfInput= (cr.isUnderflow() && flush && source.remaining()==0 && toULength == 0);
|
||||
|
||||
/* no callback called yet for this iteration */
|
||||
calledCallback=false;
|
||||
|
||||
/* no sourceIndex adjustment for conversion, only for callback output */
|
||||
errorInputLength=0;
|
||||
|
||||
/*
|
||||
* loop for offsets and error handling
|
||||
*
|
||||
* iterates at most 3 times:
|
||||
* 1. to clean up after the conversion function
|
||||
* 2. after the callback
|
||||
* 3. after the callback again if there was truncated input
|
||||
*/
|
||||
for(;;) {
|
||||
/* update offsets if we write any */
|
||||
/* Currently offsets are not being used in ICU4J */
|
||||
/* if(offsets!=null) {
|
||||
|
||||
int length=(target.position()-t);
|
||||
if(length>0) {
|
||||
updateOffsets(offsets, length, sourceIndex, errorInputLength);
|
||||
|
||||
|
||||
/*
|
||||
* if a converter handles offsets and updates the offsets
|
||||
* pointer at the end, then pArgs->offset should not change
|
||||
* here;
|
||||
* however, some converters do not handle offsets at all
|
||||
* (sourceIndex<0) or may not update the offsets pointer
|
||||
*/
|
||||
//TODO: pArgs->offsets=offsets+=length;
|
||||
/* }
|
||||
|
||||
if(sourceIndex>=0) {
|
||||
sourceIndex+=(source.position()-s);
|
||||
}
|
||||
|
||||
} */
|
||||
|
||||
if(preToULength<0) {
|
||||
/*
|
||||
* switch the source to new replay units (cannot occur while replaying)
|
||||
* after offset handling and before end-of-input and callback handling
|
||||
*/
|
||||
if(realSource==null)
|
||||
{
|
||||
realSource=source;
|
||||
realFlush=flush;
|
||||
realSourceIndex=sourceIndex;
|
||||
|
||||
//UConverterUtility.uprv_memcpy(replayArray, replayBegin, preToUArray, preToUBegin, -preToULength);
|
||||
replayArray.put(preToUArray,0, -preToULength);
|
||||
// reset position
|
||||
replayArray.position(0);
|
||||
|
||||
source=replayArray;
|
||||
source.limit(replayArrayIndex-preToULength);
|
||||
flush=false;
|
||||
if((sourceIndex+=preToULength)<0) {
|
||||
sourceIndex=-1;
|
||||
}
|
||||
|
||||
preToULength=0;
|
||||
} else {
|
||||
/* see implementation note before _fromUnicodeWithCallback() */
|
||||
//agljport:todo U_ASSERT(realSource==NULL);
|
||||
Assert.assrt(realSource==null);
|
||||
}
|
||||
}
|
||||
|
||||
/* update pointers */
|
||||
s=source.position();
|
||||
//t=target.position();
|
||||
|
||||
if(cr.isUnderflow()) {
|
||||
if(s<source.limit())
|
||||
{
|
||||
/*
|
||||
* continue with the conversion loop while there is still input left
|
||||
* (continue converting by breaking out of only the inner loop)
|
||||
*/
|
||||
break;
|
||||
} else if(realSource!=null) {
|
||||
/* switch back from replaying to the real source and continue */
|
||||
source = realSource;
|
||||
flush=realFlush;
|
||||
sourceIndex=realSourceIndex;
|
||||
realSource=null;
|
||||
break;
|
||||
} else if(flush && toULength>0) {
|
||||
/*
|
||||
* the entire input stream is consumed
|
||||
* and there is a partial, truncated input sequence left
|
||||
*/
|
||||
|
||||
/* inject an error and continue with callback handling */
|
||||
cr = CoderResult.malformedForLength(toULength);
|
||||
calledCallback=false; /* new error condition */
|
||||
} else {
|
||||
/* input consumed */
|
||||
if(flush) {
|
||||
/*
|
||||
* return to the conversion loop once more if the flush
|
||||
* flag is set and the conversion function has not
|
||||
* successfully processed the end of the input yet
|
||||
*
|
||||
* (continue converting by breaking out of only the inner loop)
|
||||
*/
|
||||
if(!converterSawEndOfInput) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* reset the converter without calling the callback function */
|
||||
implReset();
|
||||
}
|
||||
|
||||
/* done successfully */
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
/* U_FAILURE(*err) */
|
||||
{
|
||||
|
||||
if( calledCallback || cr.isOverflow() ||
|
||||
(cr.isMalformed() && cr.isUnmappable())
|
||||
) {
|
||||
/*
|
||||
* the callback did not or cannot resolve the error:
|
||||
* set output pointers and return
|
||||
*
|
||||
* the check for buffer overflow is redundant but it is
|
||||
* a high-runner case and hopefully documents the intent
|
||||
* well
|
||||
*
|
||||
* if we were replaying, then the replay buffer must be
|
||||
* copied back into the UConverter
|
||||
* and the real arguments must be restored
|
||||
*/
|
||||
if(realSource!=null) {
|
||||
int length;
|
||||
Assert.assrt(preToULength==0);
|
||||
length = source.limit() - source.position();
|
||||
if(length>0) {
|
||||
//UConverterUtility.uprv_memcpy(preToUArray, preToUBegin, pArgs.sourceArray, pArgs.sourceBegin, length);
|
||||
source.get(preToUArray, preToUBegin, length);
|
||||
preToULength=(byte)-length;
|
||||
}
|
||||
|
||||
source=realSource;
|
||||
flush=realFlush;
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy toUBytes[] to invalidCharBuffer[] */
|
||||
errorInputLength=invalidCharLength=toULength;
|
||||
if(errorInputLength>0) {
|
||||
copy(toUBytesArray, 0, invalidCharBuffer, 0, errorInputLength);
|
||||
}
|
||||
|
||||
/* set the converter state to deal with the next character */
|
||||
toULength=0;
|
||||
|
||||
/* call the callback function */
|
||||
cr = toCharErrorBehaviour.call(this, toUContext, source, target, offsets, invalidCharBuffer, errorInputLength, cr);
|
||||
/*
|
||||
* loop back to the offset handling
|
||||
*
|
||||
* this flag will indicate after offset handling
|
||||
* that a callback was called;
|
||||
* if the callback did not resolve the error, then we return
|
||||
*/
|
||||
calledCallback=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of chars held in the converter's internal state
|
||||
* because more input is needed for completing the conversion. This function is
|
||||
* useful for mapping semantics of ICU's converter interface to those of iconv,
|
||||
* and this information is not needed for normal conversion.
|
||||
* @return The number of chars in the state. -1 if an error is encountered.
|
||||
*/
|
||||
/*public*/ int toUCountPending() {
|
||||
if(preToULength > 0){
|
||||
return preToULength ;
|
||||
} else if(preToULength < 0){
|
||||
return -preToULength;
|
||||
} else if(toULength > 0){
|
||||
return toULength;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void copy(byte[] src, int srcOffset, char[] dst, int dstOffset, int length) {
|
||||
for(int i=srcOffset; i<length; i++){
|
||||
dst[dstOffset++]=(char)(src[srcOffset++] & UConverterConstants.UNSIGNED_BYTE_MASK);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* ONLY used by ToU callback functions.
|
||||
* This function will write out the specified characters to the target
|
||||
* character buffer.
|
||||
* @return A CoderResult object that contains the error result when an error occurs.
|
||||
*/
|
||||
static final CoderResult toUWriteUChars( CharsetDecoderICU cnv,
|
||||
char[] ucharsArray, int ucharsBegin, int length,
|
||||
CharBuffer target, IntBuffer offsets, int sourceIndex) {
|
||||
|
||||
CoderResult cr = CoderResult.UNDERFLOW;
|
||||
|
||||
/* write UChars */
|
||||
if(offsets==null) {
|
||||
while(length>0 && target.hasRemaining()) {
|
||||
target.put(ucharsArray[ucharsBegin++]);
|
||||
--length;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* output with offsets */
|
||||
while(length>0 && target.hasRemaining()) {
|
||||
target.put(ucharsArray[ucharsBegin++]);
|
||||
offsets.put(sourceIndex);
|
||||
--length;
|
||||
}
|
||||
}
|
||||
/* write overflow */
|
||||
if(length>0) {
|
||||
cnv.charErrorBufferLength= 0;
|
||||
cr = CoderResult.OVERFLOW;
|
||||
do {
|
||||
cnv.charErrorBufferArray[cnv.charErrorBufferLength++]=ucharsArray[ucharsBegin++];
|
||||
} while(--length>0);
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
/*
|
||||
* This function will write out the Unicode substitution character to the
|
||||
* target character buffer.
|
||||
* Sub classes to override this method if required
|
||||
* @param decoder
|
||||
* @param source
|
||||
* @param target
|
||||
* @param offsets
|
||||
* @return A CoderResult object that contains the error result when an error occurs.
|
||||
*/
|
||||
/* Note: Currently, this method is not being used because the callback method calls toUWriteUChars with
|
||||
* the substitution characters. Will leave in here for the time being. To be removed later. (4.0)
|
||||
*/
|
||||
/*CoderResult cbToUWriteSub(CharsetDecoderICU decoder,
|
||||
ByteBuffer source, CharBuffer target,
|
||||
IntBuffer offsets){
|
||||
String sub = decoder.replacement();
|
||||
CharsetICU cs = (CharsetICU) decoder.charset();
|
||||
if (decoder.invalidCharLength==1 && cs.subChar1 != 0x00) {
|
||||
char[] subArr = new char[] { 0x1a };
|
||||
return CharsetDecoderICU.toUWriteUChars(decoder, subArr, 0, sub
|
||||
.length(), target, offsets, source.position());
|
||||
} else {
|
||||
return CharsetDecoderICU.toUWriteUChars(decoder, sub.toCharArray(),
|
||||
0, sub.length(), target, offsets, source.position());
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
|
@ -0,0 +1,920 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.nio.charset.CodingErrorAction;
|
||||
|
||||
import com.ibm.icu.impl.Assert;
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.text.UTF16;
|
||||
|
||||
/**
|
||||
* An abstract class that provides framework methods of decoding operations for concrete
|
||||
* subclasses.
|
||||
* In the future this class will contain API that will implement converter semantics of ICU4C.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public abstract class CharsetEncoderICU extends CharsetEncoder {
|
||||
|
||||
/* this is used in fromUnicode DBCS tables as an "unassigned" marker */
|
||||
static final char MISSING_CHAR_MARKER = '\uFFFF';
|
||||
|
||||
byte[] errorBuffer = new byte[30];
|
||||
|
||||
int errorBufferLength = 0;
|
||||
|
||||
/** these are for encodeLoopICU */
|
||||
int fromUnicodeStatus;
|
||||
|
||||
int fromUChar32;
|
||||
|
||||
boolean useSubChar1;
|
||||
|
||||
boolean useFallback;
|
||||
|
||||
/* maximum number of indexed UChars */
|
||||
static final int EXT_MAX_UCHARS = 19;
|
||||
|
||||
/* store previous UChars/chars to continue partial matches */
|
||||
int preFromUFirstCP; /* >=0: partial match */
|
||||
|
||||
char[] preFromUArray = new char[EXT_MAX_UCHARS];
|
||||
|
||||
int preFromUBegin;
|
||||
|
||||
int preFromULength; /* negative: replay */
|
||||
|
||||
char[] invalidUCharBuffer = new char[2];
|
||||
|
||||
int invalidUCharLength;
|
||||
|
||||
Object fromUContext;
|
||||
|
||||
private CharsetCallback.Encoder onUnmappableInput = CharsetCallback.FROM_U_CALLBACK_STOP;
|
||||
|
||||
private CharsetCallback.Encoder onMalformedInput = CharsetCallback.FROM_U_CALLBACK_STOP;
|
||||
|
||||
CharsetCallback.Encoder fromCharErrorBehaviour = new CharsetCallback.Encoder() {
|
||||
public CoderResult call(CharsetEncoderICU encoder, Object context,
|
||||
CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
char[] buffer, int length, int cp, CoderResult cr) {
|
||||
if (cr.isUnmappable()) {
|
||||
return onUnmappableInput.call(encoder, context, source, target,
|
||||
offsets, buffer, length, cp, cr);
|
||||
} else /* if (cr.isMalformed()) */ {
|
||||
return onMalformedInput.call(encoder, context, source, target,
|
||||
offsets, buffer, length, cp, cr);
|
||||
}
|
||||
// return CharsetCallback.FROM_U_CALLBACK_STOP.call(encoder, context, source, target, offsets, buffer, length, cp, cr);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Construcs a new encoder for the given charset
|
||||
*
|
||||
* @param cs
|
||||
* for which the decoder is created
|
||||
* @param replacement
|
||||
* the substitution bytes
|
||||
*/
|
||||
CharsetEncoderICU(CharsetICU cs, byte[] replacement) {
|
||||
super(cs, (cs.minBytesPerChar + cs.maxBytesPerChar) / 2,
|
||||
cs.maxBytesPerChar, replacement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this Encoder allowed to use fallbacks? A fallback mapping is a mapping
|
||||
* that will convert a Unicode codepoint sequence to a byte sequence, but
|
||||
* the encoded byte sequence will round trip convert to a different
|
||||
* Unicode codepoint sequence.
|
||||
* @return true if the converter uses fallback, false otherwise.
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public boolean isFallbackUsed() {
|
||||
return useFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this Encoder can use fallbacks?
|
||||
* @param usesFallback true if the user wants the converter to take
|
||||
* advantage of the fallback mapping, false otherwise.
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public void setFallbackUsed(boolean usesFallback) {
|
||||
useFallback = usesFallback;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use fallbacks from Unicode to codepage when useFallback or for private-use code points
|
||||
* @param c A codepoint
|
||||
*/
|
||||
final boolean isFromUUseFallback(int c) {
|
||||
return (useFallback)
|
||||
|| (UCharacter.getType(c) == UCharacter.PRIVATE_USE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use fallbacks from Unicode to codepage when useFallback or for private-use code points
|
||||
*/
|
||||
static final boolean isFromUUseFallback(boolean iUseFallback, int c) {
|
||||
return (iUseFallback)
|
||||
|| (UCharacter.getType(c) == UCharacter.PRIVATE_USE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action to be taken if an illegal sequence is encountered
|
||||
*
|
||||
* @param newAction
|
||||
* action to be taken
|
||||
* @exception IllegalArgumentException
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected void implOnMalformedInput(CodingErrorAction newAction) {
|
||||
onMalformedInput = getCallback(newAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action to be taken if an illegal sequence is encountered
|
||||
*
|
||||
* @param newAction
|
||||
* action to be taken
|
||||
* @exception IllegalArgumentException
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
|
||||
onUnmappableInput = getCallback(newAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the callback encoder method and context to be used if an illegal sequence is encountered.
|
||||
* You would normally call this twice to set both the malform and unmappable error. In this case,
|
||||
* newContext should remain the same since using a different newContext each time will negate the last
|
||||
* one used.
|
||||
* @param err CoderResult
|
||||
* @param newCallback CharsetCallback.Encoder
|
||||
* @param newContext Object
|
||||
* @stable ICU 4.0
|
||||
*/
|
||||
public final void setFromUCallback(CoderResult err, CharsetCallback.Encoder newCallback, Object newContext) {
|
||||
if (err.isMalformed()) {
|
||||
onMalformedInput = newCallback;
|
||||
} else if (err.isUnmappable()) {
|
||||
onUnmappableInput = newCallback;
|
||||
} else {
|
||||
/* Error: Only malformed and unmappable are handled. */
|
||||
}
|
||||
|
||||
if (fromUContext == null || !fromUContext.equals(newContext)) {
|
||||
setFromUContext(newContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets fromUContext used in callbacks.
|
||||
*
|
||||
* @param newContext Object
|
||||
* @exception IllegalArgumentException The object is an illegal argument for UContext.
|
||||
* @stable ICU 4.0
|
||||
*/
|
||||
public final void setFromUContext(Object newContext) {
|
||||
fromUContext = newContext;
|
||||
}
|
||||
|
||||
private static CharsetCallback.Encoder getCallback(CodingErrorAction action) {
|
||||
if (action == CodingErrorAction.REPLACE) {
|
||||
return CharsetCallback.FROM_U_CALLBACK_SUBSTITUTE;
|
||||
} else if (action == CodingErrorAction.IGNORE) {
|
||||
return CharsetCallback.FROM_U_CALLBACK_SKIP;
|
||||
} else /* if (action == CodingErrorAction.REPORT) */ {
|
||||
return CharsetCallback.FROM_U_CALLBACK_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
private static final CharBuffer EMPTY = CharBuffer.allocate(0);
|
||||
|
||||
/**
|
||||
* Flushes any characters saved in the converter's internal buffer and
|
||||
* resets the converter.
|
||||
* @param out action to be taken
|
||||
* @return result of flushing action and completes the decoding all input.
|
||||
* Returns CoderResult.UNDERFLOW if the action succeeds.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected CoderResult implFlush(ByteBuffer out) {
|
||||
return encode(EMPTY, out, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the from Unicode mode of converter
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected void implReset() {
|
||||
errorBufferLength = 0;
|
||||
fromUnicodeStatus = 0;
|
||||
fromUChar32 = 0;
|
||||
fromUnicodeReset();
|
||||
}
|
||||
|
||||
private void fromUnicodeReset() {
|
||||
preFromUBegin = 0;
|
||||
preFromUFirstCP = UConverterConstants.U_SENTINEL;
|
||||
preFromULength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes one or more chars. The default behaviour of the
|
||||
* converter is stop and report if an error in input stream is encountered.
|
||||
* To set different behaviour use @see CharsetEncoder.onMalformedInput()
|
||||
* @param in buffer to decode
|
||||
* @param out buffer to populate with decoded result
|
||||
* @return result of decoding action. Returns CoderResult.UNDERFLOW if the decoding
|
||||
* action succeeds or more input is needed for completing the decoding action.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
|
||||
if (!in.hasRemaining() && this.errorBufferLength == 0) { // make sure the errorBuffer is empty
|
||||
// The Java framework should have already substituted what was left.
|
||||
fromUChar32 = 0;
|
||||
//fromUnicodeReset();
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
in.position(in.position() + fromUCountPending());
|
||||
/* do the conversion */
|
||||
CoderResult ret = encode(in, out, null, false);
|
||||
setSourcePosition(in);
|
||||
/* No need to reset to keep the proper state of the encoder.
|
||||
if (ret.isUnderflow() && in.hasRemaining()) {
|
||||
// The Java framework is going to substitute what is left.
|
||||
//fromUnicodeReset();
|
||||
} */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements ICU semantics of buffer management
|
||||
* @param source
|
||||
* @param target
|
||||
* @param offsets
|
||||
* @return A CoderResult object that contains the error result when an error occurs.
|
||||
*/
|
||||
abstract CoderResult encodeLoop(CharBuffer source, ByteBuffer target,
|
||||
IntBuffer offsets, boolean flush);
|
||||
|
||||
/*
|
||||
* Implements ICU semantics for encoding the buffer
|
||||
* @param source The input character buffer
|
||||
* @param target The output byte buffer
|
||||
* @param offsets
|
||||
* @param flush true if, and only if, the invoker can provide no
|
||||
* additional input bytes beyond those in the given buffer.
|
||||
* @return A CoderResult object that contains the error result when an error occurs.
|
||||
*/
|
||||
final CoderResult encode(CharBuffer source, ByteBuffer target,
|
||||
IntBuffer offsets, boolean flush) {
|
||||
|
||||
/* check parameters */
|
||||
if (target == null || source == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the buffer sizes do not exceed the number range for
|
||||
* int32_t because some functions use the size (in units or bytes)
|
||||
* rather than comparing pointers, and because offsets are int32_t values.
|
||||
*
|
||||
* size_t is guaranteed to be unsigned and large enough for the job.
|
||||
*
|
||||
* Return with an error instead of adjusting the limits because we would
|
||||
* not be able to maintain the semantics that either the source must be
|
||||
* consumed or the target filled (unless an error occurs).
|
||||
* An adjustment would be targetLimit=t+0x7fffffff; for example.
|
||||
*/
|
||||
|
||||
/* flush the target overflow buffer */
|
||||
if (errorBufferLength > 0) {
|
||||
byte[] overflowArray;
|
||||
int i, length;
|
||||
|
||||
overflowArray = errorBuffer;
|
||||
length = errorBufferLength;
|
||||
i = 0;
|
||||
do {
|
||||
if (target.remaining() == 0) {
|
||||
/* the overflow buffer contains too much, keep the rest */
|
||||
int j = 0;
|
||||
|
||||
do {
|
||||
overflowArray[j++] = overflowArray[i++];
|
||||
} while (i < length);
|
||||
|
||||
errorBufferLength = (byte) j;
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
/* copy the overflow contents to the target */
|
||||
target.put(overflowArray[i++]);
|
||||
if (offsets != null) {
|
||||
offsets.put(-1); /* no source index available for old output */
|
||||
}
|
||||
} while (i < length);
|
||||
|
||||
/* the overflow buffer is completely copied to the target */
|
||||
errorBufferLength = 0;
|
||||
}
|
||||
|
||||
if (!flush && source.remaining() == 0 && preFromULength >= 0) {
|
||||
/* the overflow buffer is emptied and there is no new input: we are done */
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not simply return with a buffer overflow error if
|
||||
* !flush && t==targetLimit
|
||||
* because it is possible that the source will not generate any output.
|
||||
* For example, the skip callback may be called;
|
||||
* it does not output anything.
|
||||
*/
|
||||
|
||||
return fromUnicodeWithCallback(source, target, offsets, flush);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation note for m:n conversions
|
||||
*
|
||||
* While collecting source units to find the longest match for m:n conversion,
|
||||
* some source units may need to be stored for a partial match.
|
||||
* When a second buffer does not yield a match on all of the previously stored
|
||||
* source units, then they must be "replayed", i.e., fed back into the converter.
|
||||
*
|
||||
* The code relies on the fact that replaying will not nest -
|
||||
* converting a replay buffer will not result in a replay.
|
||||
* This is because a replay is necessary only after the _continuation_ of a
|
||||
* partial match failed, but a replay buffer is converted as a whole.
|
||||
* It may result in some of its units being stored again for a partial match,
|
||||
* but there will not be a continuation _during_ the replay which could fail.
|
||||
*
|
||||
* It is conceivable that a callback function could call the converter
|
||||
* recursively in a way that causes another replay to be stored, but that
|
||||
* would be an error in the callback function.
|
||||
* Such violations will cause assertion failures in a debug build,
|
||||
* and wrong output, but they will not cause a crash.
|
||||
*/
|
||||
final CoderResult fromUnicodeWithCallback(CharBuffer source,
|
||||
ByteBuffer target, IntBuffer offsets, boolean flush) {
|
||||
int sBufferIndex;
|
||||
int sourceIndex;
|
||||
int errorInputLength;
|
||||
boolean converterSawEndOfInput, calledCallback;
|
||||
|
||||
/* variables for m:n conversion */
|
||||
CharBuffer replayArray = CharBuffer.allocate(EXT_MAX_UCHARS);
|
||||
int replayArrayIndex = 0;
|
||||
CharBuffer realSource;
|
||||
boolean realFlush;
|
||||
|
||||
CoderResult cr = CoderResult.UNDERFLOW;
|
||||
|
||||
/* get the converter implementation function */
|
||||
sourceIndex = 0;
|
||||
|
||||
if (preFromULength >= 0) {
|
||||
/* normal mode */
|
||||
realSource = null;
|
||||
realFlush = false;
|
||||
} else {
|
||||
/*
|
||||
* Previous m:n conversion stored source units from a partial match
|
||||
* and failed to consume all of them.
|
||||
* We need to "replay" them from a temporary buffer and convert them first.
|
||||
*/
|
||||
realSource = source;
|
||||
realFlush = flush;
|
||||
|
||||
//UConverterUtility.uprv_memcpy(replayArray, replayArrayIndex, preFromUArray, 0, -preFromULength*UMachine.U_SIZEOF_UCHAR);
|
||||
replayArray.put(preFromUArray, 0, -preFromULength);
|
||||
source = replayArray;
|
||||
source.position(replayArrayIndex);
|
||||
source.limit(replayArrayIndex - preFromULength); //preFromULength is negative, see declaration
|
||||
flush = false;
|
||||
|
||||
preFromULength = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* loop for conversion and error handling
|
||||
*
|
||||
* loop {
|
||||
* convert
|
||||
* loop {
|
||||
* update offsets
|
||||
* handle end of input
|
||||
* handle errors/call callback
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
for (;;) {
|
||||
/* convert */
|
||||
cr = encodeLoop(source, target, offsets, flush);
|
||||
/*
|
||||
* set a flag for whether the converter
|
||||
* successfully processed the end of the input
|
||||
*
|
||||
* need not check cnv.preFromULength==0 because a replay (<0) will cause
|
||||
* s<sourceLimit before converterSawEndOfInput is checked
|
||||
*/
|
||||
converterSawEndOfInput = (cr.isUnderflow() && flush
|
||||
&& source.remaining() == 0 && fromUChar32 == 0);
|
||||
|
||||
/* no callback called yet for this iteration */
|
||||
calledCallback = false;
|
||||
|
||||
/* no sourceIndex adjustment for conversion, only for callback output */
|
||||
errorInputLength = 0;
|
||||
|
||||
/*
|
||||
* loop for offsets and error handling
|
||||
*
|
||||
* iterates at most 3 times:
|
||||
* 1. to clean up after the conversion function
|
||||
* 2. after the callback
|
||||
* 3. after the callback again if there was truncated input
|
||||
*/
|
||||
for (;;) {
|
||||
/* update offsets if we write any */
|
||||
/* Currently offsets are not being used in ICU4J */
|
||||
/* if (offsets != null) {
|
||||
int length = target.remaining();
|
||||
if (length > 0) {
|
||||
|
||||
/*
|
||||
* if a converter handles offsets and updates the offsets
|
||||
* pointer at the end, then offset should not change
|
||||
* here;
|
||||
* however, some converters do not handle offsets at all
|
||||
* (sourceIndex<0) or may not update the offsets pointer
|
||||
*/
|
||||
/* offsets.position(offsets.position() + length);
|
||||
}
|
||||
|
||||
if (sourceIndex >= 0) {
|
||||
sourceIndex += (int) (source.position());
|
||||
}
|
||||
} */
|
||||
|
||||
if (preFromULength < 0) {
|
||||
/*
|
||||
* switch the source to new replay units (cannot occur while replaying)
|
||||
* after offset handling and before end-of-input and callback handling
|
||||
*/
|
||||
if (realSource == null) {
|
||||
realSource = source;
|
||||
realFlush = flush;
|
||||
|
||||
//UConverterUtility.uprv_memcpy(replayArray, replayArrayIndex, preFromUArray, 0, -preFromULength*UMachine.U_SIZEOF_UCHAR);
|
||||
replayArray.put(preFromUArray, 0, -preFromULength);
|
||||
|
||||
source = replayArray;
|
||||
source.position(replayArrayIndex);
|
||||
source.limit(replayArrayIndex - preFromULength);
|
||||
flush = false;
|
||||
if ((sourceIndex += preFromULength) < 0) {
|
||||
sourceIndex = -1;
|
||||
}
|
||||
|
||||
preFromULength = 0;
|
||||
} else {
|
||||
/* see implementation note before _fromUnicodeWithCallback() */
|
||||
//agljport:todo U_ASSERT(realSource==NULL);
|
||||
Assert.assrt(realSource == null);
|
||||
}
|
||||
}
|
||||
|
||||
/* update pointers */
|
||||
sBufferIndex = source.position();
|
||||
if (cr.isUnderflow()) {
|
||||
if (sBufferIndex < source.limit()) {
|
||||
/*
|
||||
* continue with the conversion loop while there is still input left
|
||||
* (continue converting by breaking out of only the inner loop)
|
||||
*/
|
||||
break;
|
||||
} else if (realSource != null) {
|
||||
/* switch back from replaying to the real source and continue */
|
||||
source = realSource;
|
||||
flush = realFlush;
|
||||
sourceIndex = source.position();
|
||||
realSource = null;
|
||||
break;
|
||||
} else if (flush && fromUChar32 != 0) {
|
||||
/*
|
||||
* the entire input stream is consumed
|
||||
* and there is a partial, truncated input sequence left
|
||||
*/
|
||||
|
||||
/* inject an error and continue with callback handling */
|
||||
//err[0]=ErrorCode.U_TRUNCATED_CHAR_FOUND;
|
||||
cr = CoderResult.malformedForLength(1);
|
||||
calledCallback = false; /* new error condition */
|
||||
} else {
|
||||
/* input consumed */
|
||||
if (flush) {
|
||||
/*
|
||||
* return to the conversion loop once more if the flush
|
||||
* flag is set and the conversion function has not
|
||||
* successfully processed the end of the input yet
|
||||
*
|
||||
* (continue converting by breaking out of only the inner loop)
|
||||
*/
|
||||
if (!converterSawEndOfInput) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* reset the converter without calling the callback function */
|
||||
implReset();
|
||||
}
|
||||
|
||||
/* done successfully */
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
/*U_FAILURE(*err) */
|
||||
{
|
||||
|
||||
if (calledCallback || cr.isOverflow()
|
||||
|| (!cr.isMalformed() && !cr.isUnmappable())) {
|
||||
/*
|
||||
* the callback did not or cannot resolve the error:
|
||||
* set output pointers and return
|
||||
*
|
||||
* the check for buffer overflow is redundant but it is
|
||||
* a high-runner case and hopefully documents the intent
|
||||
* well
|
||||
*
|
||||
* if we were replaying, then the replay buffer must be
|
||||
* copied back into the UConverter
|
||||
* and the real arguments must be restored
|
||||
*/
|
||||
if (realSource != null) {
|
||||
int length;
|
||||
|
||||
//agljport:todo U_ASSERT(cnv.preFromULength==0);
|
||||
|
||||
length = source.remaining();
|
||||
if (length > 0) {
|
||||
//UConverterUtility.uprv_memcpy(preFromUArray, 0, sourceArray, pArgs.sourceBegin, length*UMachine.U_SIZEOF_UCHAR);
|
||||
source.get(preFromUArray, 0, length);
|
||||
preFromULength = (byte) -length;
|
||||
}
|
||||
source = realSource;
|
||||
flush = realFlush;
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
/* callback handling */
|
||||
{
|
||||
int codePoint;
|
||||
|
||||
/* get and write the code point */
|
||||
codePoint = fromUChar32;
|
||||
errorInputLength = UTF16.append(invalidUCharBuffer, 0,
|
||||
fromUChar32);
|
||||
invalidUCharLength = errorInputLength;
|
||||
|
||||
/* set the converter state to deal with the next character */
|
||||
fromUChar32 = 0;
|
||||
|
||||
/* call the callback function */
|
||||
cr = fromCharErrorBehaviour.call(this, fromUContext,
|
||||
source, target, offsets, invalidUCharBuffer,
|
||||
invalidUCharLength, codePoint, cr);
|
||||
}
|
||||
|
||||
/*
|
||||
* loop back to the offset handling
|
||||
*
|
||||
* this flag will indicate after offset handling
|
||||
* that a callback was called;
|
||||
* if the callback did not resolve the error, then we return
|
||||
*/
|
||||
calledCallback = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Ascertains if a given Unicode code point (32bit value for handling surrogates)
|
||||
* can be converted to the target encoding. If the caller wants to test if a
|
||||
* surrogate pair can be converted to target encoding then the
|
||||
* responsibility of assembling the int value lies with the caller.
|
||||
* For assembling a code point the caller can use UTF16 class of ICU4J and do something like:
|
||||
* <pre>
|
||||
* while(i<mySource.length){
|
||||
* if(UTF16.isLeadSurrogate(mySource[i])&& i+1< mySource.length){
|
||||
* if(UTF16.isTrailSurrogate(mySource[i+1])){
|
||||
* int temp = UTF16.charAt(mySource,i,i+1,0);
|
||||
* if(!((CharsetEncoderICU) myConv).canEncode(temp)){
|
||||
* passed=false;
|
||||
* }
|
||||
* i++;
|
||||
* i++;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* or
|
||||
* <pre>
|
||||
* String src = new String(mySource);
|
||||
* int i,codepoint;
|
||||
* boolean passed = false;
|
||||
* while(i<src.length()){
|
||||
* codepoint = UTF16.charAt(src,i);
|
||||
* i+= (codepoint>0xfff)? 2:1;
|
||||
* if(!(CharsetEncoderICU) myConv).canEncode(codepoint)){
|
||||
* passed = false;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param codepoint Unicode code point as int value
|
||||
* @return true if a character can be converted
|
||||
*/
|
||||
/* TODO This is different from Java's canEncode(char) API.
|
||||
* ICU's API should implement getUnicodeSet,
|
||||
* and override canEncode(char) which queries getUnicodeSet.
|
||||
* The getUnicodeSet should return a frozen UnicodeSet or use a fillin parameter, like ICU4C.
|
||||
*/
|
||||
/*public boolean canEncode(int codepoint) {
|
||||
return true;
|
||||
}*/
|
||||
/**
|
||||
* Overrides super class method
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public boolean isLegalReplacement(byte[] repl) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes out the specified output bytes to the target byte buffer or to converter internal buffers.
|
||||
* @param cnv
|
||||
* @param bytesArray
|
||||
* @param bytesBegin
|
||||
* @param bytesLength
|
||||
* @param out
|
||||
* @param offsets
|
||||
* @param sourceIndex
|
||||
* @return A CoderResult object that contains the error result when an error occurs.
|
||||
*/
|
||||
static final CoderResult fromUWriteBytes(CharsetEncoderICU cnv,
|
||||
byte[] bytesArray, int bytesBegin, int bytesLength, ByteBuffer out,
|
||||
IntBuffer offsets, int sourceIndex) {
|
||||
|
||||
//write bytes
|
||||
int obl = bytesLength;
|
||||
CoderResult cr = CoderResult.UNDERFLOW;
|
||||
int bytesLimit = bytesBegin + bytesLength;
|
||||
try {
|
||||
for (; bytesBegin < bytesLimit;) {
|
||||
out.put(bytesArray[bytesBegin]);
|
||||
bytesBegin++;
|
||||
}
|
||||
// success
|
||||
bytesLength = 0;
|
||||
} catch (BufferOverflowException ex) {
|
||||
cr = CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
if (offsets != null) {
|
||||
while (obl > bytesLength) {
|
||||
offsets.put(sourceIndex);
|
||||
--obl;
|
||||
}
|
||||
}
|
||||
//write overflow
|
||||
cnv.errorBufferLength = bytesLimit - bytesBegin;
|
||||
if (cnv.errorBufferLength > 0) {
|
||||
int index = 0;
|
||||
while (bytesBegin < bytesLimit) {
|
||||
cnv.errorBuffer[index++] = bytesArray[bytesBegin++];
|
||||
}
|
||||
cr = CoderResult.OVERFLOW;
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of chars held in the converter's internal state
|
||||
* because more input is needed for completing the conversion. This function is
|
||||
* useful for mapping semantics of ICU's converter interface to those of iconv,
|
||||
* and this information is not needed for normal conversion.
|
||||
* @return The number of chars in the state. -1 if an error is encountered.
|
||||
*/
|
||||
/*public*/int fromUCountPending() {
|
||||
if (preFromULength > 0) {
|
||||
return UTF16.getCharCount(preFromUFirstCP) + preFromULength;
|
||||
} else if (preFromULength < 0) {
|
||||
return -preFromULength;
|
||||
} else if (fromUChar32 > 0) {
|
||||
return 1;
|
||||
} else if (preFromUFirstCP > 0) {
|
||||
return UTF16.getCharCount(preFromUFirstCP);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
private final void setSourcePosition(CharBuffer source) {
|
||||
|
||||
// ok was there input held in the previous invocation of encodeLoop
|
||||
// that resulted in output in this invocation?
|
||||
source.position(source.position() - fromUCountPending());
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the codepage substitution character.
|
||||
* Subclasses to override this method.
|
||||
* For stateful converters, it is typically necessary to handle this
|
||||
* specificially for the converter in order to properly maintain the state.
|
||||
* @param source The input character buffer
|
||||
* @param target The output byte buffer
|
||||
* @param offsets
|
||||
* @return A CoderResult object that contains the error result when an error occurs.
|
||||
*/
|
||||
CoderResult cbFromUWriteSub(CharsetEncoderICU encoder, CharBuffer source,
|
||||
ByteBuffer target, IntBuffer offsets) {
|
||||
CharsetICU cs = (CharsetICU) encoder.charset();
|
||||
byte[] sub = encoder.replacement();
|
||||
if (cs.subChar1 != 0 && encoder.invalidUCharBuffer[0] <= 0xff) {
|
||||
return CharsetEncoderICU.fromUWriteBytes(encoder,
|
||||
new byte[] { cs.subChar1 }, 0, 1, target, offsets, source
|
||||
.position());
|
||||
} else {
|
||||
return CharsetEncoderICU.fromUWriteBytes(encoder, sub, 0,
|
||||
sub.length, target, offsets, source.position());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the characters to target.
|
||||
* @param source The input character buffer
|
||||
* @param target The output byte buffer
|
||||
* @param offsets
|
||||
* @return A CoderResult object that contains the error result when an error occurs.
|
||||
*/
|
||||
CoderResult cbFromUWriteUChars(CharsetEncoderICU encoder,
|
||||
CharBuffer source, ByteBuffer target, IntBuffer offsets) {
|
||||
CoderResult cr = CoderResult.UNDERFLOW;
|
||||
|
||||
/* This is a fun one. Recursion can occur - we're basically going to
|
||||
* just retry shoving data through the same converter. Note, if you got
|
||||
* here through some kind of invalid sequence, you maybe should emit a
|
||||
* reset sequence of some kind. Since this IS an actual conversion,
|
||||
* take care that you've changed the callback or the data, or you'll
|
||||
* get an infinite loop.
|
||||
*/
|
||||
|
||||
int oldTargetPosition = target.position();
|
||||
int offsetIndex = source.position();
|
||||
|
||||
cr = encoder.encode(source, target, null, false); /* no offsets and no flush */
|
||||
|
||||
if (offsets != null) {
|
||||
while (target.position() != oldTargetPosition) {
|
||||
offsets.put(offsetIndex);
|
||||
oldTargetPosition++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note, if you did something like used a stop subcallback, things would get interesting.
|
||||
* In fact, here's where we want to return the partially consumed in-source!
|
||||
*/
|
||||
if (cr.isOverflow()) {
|
||||
/* Overflowed target. Now, we'll write into the charErrorBuffer.
|
||||
* It's a fixed size. If we overflow it...Hm
|
||||
*/
|
||||
|
||||
/* start the new target at the first free slot in the error buffer */
|
||||
int errBuffLen = encoder.errorBufferLength;
|
||||
ByteBuffer newTarget = ByteBuffer.wrap(encoder.errorBuffer);
|
||||
newTarget.position(errBuffLen); /* set the position at the end of the error buffer */
|
||||
encoder.errorBufferLength = 0;
|
||||
|
||||
encoder.encode(source, newTarget, null, false);
|
||||
|
||||
encoder.errorBuffer = newTarget.array();
|
||||
encoder.errorBufferLength = newTarget.position();
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Handles a common situation where a character has been read and it may be
|
||||
* a lead surrogate followed by a trail surrogate. This method can change
|
||||
* the source position and will modify fromUChar32.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If <code>null</code> is returned, then there was success in reading a
|
||||
* surrogate pair, the codepoint is stored in <code>fromUChar32</code> and
|
||||
* <code>fromUChar32</code> should be reset (to 0) after being read.
|
||||
* </p>
|
||||
*
|
||||
* @param source
|
||||
* The encoding source.
|
||||
* @param lead
|
||||
* A character that may be the first in a surrogate pair.
|
||||
* @return <code>CoderResult.malformedForLength(1)</code> or
|
||||
* <code>CoderResult.UNDERFLOW</code> if there is a problem, or
|
||||
* <code>null</code> if there isn't.
|
||||
* @see #handleSurrogates(CharBuffer, char)
|
||||
* @see #handleSurrogates(CharBuffer, int, char)
|
||||
* @see #handleSurrogates(char[], int, int, char)
|
||||
*/
|
||||
final CoderResult handleSurrogates(CharBuffer source, char lead) {
|
||||
if (!UTF16.isLeadSurrogate(lead)) {
|
||||
fromUChar32 = lead;
|
||||
return CoderResult.malformedForLength(1);
|
||||
}
|
||||
|
||||
if (!source.hasRemaining()) {
|
||||
fromUChar32 = lead;
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
|
||||
char trail = source.get();
|
||||
|
||||
if (!UTF16.isTrailSurrogate(trail)) {
|
||||
fromUChar32 = lead;
|
||||
source.position(source.position() - 1);
|
||||
return CoderResult.malformedForLength(1);
|
||||
}
|
||||
|
||||
fromUChar32 = UCharacter.getCodePoint(lead, trail);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Same as <code>handleSurrogates(CharBuffer, char)</code>, but with arrays. As an added
|
||||
* requirement, the calling method must also increment the index if this method returns
|
||||
* <code>null</code>.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param source
|
||||
* The encoding source.
|
||||
* @param lead
|
||||
* A character that may be the first in a surrogate pair.
|
||||
* @return <code>CoderResult.malformedForLength(1)</code> or
|
||||
* <code>CoderResult.UNDERFLOW</code> if there is a problem, or <code>null</code> if
|
||||
* there isn't.
|
||||
* @see #handleSurrogates(CharBuffer, char)
|
||||
* @see #handleSurrogates(CharBuffer, int, char)
|
||||
* @see #handleSurrogates(char[], int, int, char)
|
||||
*/
|
||||
final CoderResult handleSurrogates(char[] sourceArray, int sourceIndex,
|
||||
int sourceLimit, char lead) {
|
||||
if (!UTF16.isLeadSurrogate(lead)) {
|
||||
fromUChar32 = lead;
|
||||
return CoderResult.malformedForLength(1);
|
||||
}
|
||||
|
||||
if (sourceIndex >= sourceLimit) {
|
||||
fromUChar32 = lead;
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
|
||||
char trail = sourceArray[sourceIndex];
|
||||
|
||||
if (!UTF16.isTrailSurrogate(trail)) {
|
||||
fromUChar32 = lead;
|
||||
return CoderResult.malformedForLength(1);
|
||||
}
|
||||
|
||||
fromUChar32 = UCharacter.getCodePoint(lead, trail);
|
||||
return null;
|
||||
}
|
||||
}
|
385
main/classes/charset/src/com/ibm/icu/charset/CharsetHZ.java
Normal file
385
main/classes/charset/src/com/ibm/icu/charset/CharsetHZ.java
Normal file
|
@ -0,0 +1,385 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2008-2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
class CharsetHZ extends CharsetICU {
|
||||
|
||||
private static final int UCNV_TILDE = 0x7E; /* ~ */
|
||||
private static final int UCNV_OPEN_BRACE = 0x7B; /* { */
|
||||
private static final int UCNV_CLOSE_BRACE = 0x7D; /* } */
|
||||
private static final byte[] SB_ESCAPE = new byte[] { 0x7E, 0x7D };
|
||||
private static final byte[] DB_ESCAPE = new byte[] { 0x7E, 0x7B };
|
||||
private static final byte[] TILDE_ESCAPE = new byte[] { 0x7E, 0x7E };
|
||||
private static final byte[] fromUSubstitution = new byte[] { (byte) 0x1A };
|
||||
|
||||
private CharsetMBCS gbCharset;
|
||||
private boolean isEmptySegment;
|
||||
|
||||
public CharsetHZ(String icuCanonicalName, String canonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, canonicalName, aliases);
|
||||
gbCharset = (CharsetMBCS) new CharsetProviderICU().charsetForName("GBK");
|
||||
|
||||
maxBytesPerChar = 4;
|
||||
minBytesPerChar = 1;
|
||||
maxCharsPerByte = 1;
|
||||
|
||||
isEmptySegment = false;
|
||||
}
|
||||
|
||||
class CharsetDecoderHZ extends CharsetDecoderICU {
|
||||
CharsetMBCS.CharsetDecoderMBCS gbDecoder;
|
||||
boolean isStateDBCS = false;
|
||||
|
||||
public CharsetDecoderHZ(CharsetICU cs) {
|
||||
super(cs);
|
||||
gbDecoder = (CharsetMBCS.CharsetDecoderMBCS) gbCharset.newDecoder();
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
gbDecoder.implReset();
|
||||
|
||||
isStateDBCS = false;
|
||||
isEmptySegment = false;
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
|
||||
CoderResult err = CoderResult.UNDERFLOW;
|
||||
byte[] tempBuf = new byte[2];
|
||||
int targetUniChar = 0;
|
||||
int mySourceChar = 0;
|
||||
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
else if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
while (source.hasRemaining()) {
|
||||
|
||||
if (target.hasRemaining()) {
|
||||
|
||||
// get the byte as unsigned
|
||||
mySourceChar = source.get() & 0xff;
|
||||
|
||||
if (mode == UCNV_TILDE) {
|
||||
/* second byte after ~ */
|
||||
mode = 0;
|
||||
switch (mySourceChar) {
|
||||
case 0x0A:
|
||||
/* no output for ~\n (line-continuation marker) */
|
||||
continue;
|
||||
case UCNV_TILDE:
|
||||
if (offsets != null) {
|
||||
offsets.put(source.position() - 2);
|
||||
}
|
||||
target.put((char) mySourceChar);
|
||||
continue;
|
||||
case UCNV_OPEN_BRACE:
|
||||
case UCNV_CLOSE_BRACE:
|
||||
isStateDBCS = (mySourceChar == UCNV_OPEN_BRACE);
|
||||
if (isEmptySegment) {
|
||||
isEmptySegment = false; /* we are handling it, reset to avoid future spurious errors */
|
||||
this.toUBytesArray[0] = UCNV_TILDE;
|
||||
this.toUBytesArray[1] = (byte)mySourceChar;
|
||||
this.toULength = 2;
|
||||
return CoderResult.malformedForLength(1);
|
||||
}
|
||||
isEmptySegment = true;
|
||||
continue;
|
||||
default:
|
||||
/*
|
||||
* if the first byte is equal to TILDE and the trail byte is not a valid byte then it is an
|
||||
* error condition
|
||||
*/
|
||||
/*
|
||||
* Ticket 5691: consistent illegal sequences:
|
||||
* - We include at least the first byte in the illegal sequence.
|
||||
* - If any of the non-initial bytes could be the start of a character,
|
||||
* we stop the illegal sequence before the first one of those.
|
||||
*/
|
||||
isEmptySegment = false; /* different error here, reset this to avoid spurious furture error */
|
||||
err = CoderResult.malformedForLength(1);
|
||||
toUBytesArray[0] = UCNV_TILDE;
|
||||
if (isStateDBCS ? (0x21 <= mySourceChar && mySourceChar <= 0x7e) : mySourceChar <= 0x7f) {
|
||||
/* The current byte could be the start of a character: Back it out. */
|
||||
toULength = 1;
|
||||
source.position(source.position() - 1);
|
||||
} else {
|
||||
/* Include the current byte in the illegal sequence. */
|
||||
toUBytesArray[1] = (byte)mySourceChar;
|
||||
toULength = 2;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
} else if (isStateDBCS) {
|
||||
if (toUnicodeStatus == 0) {
|
||||
/* lead byte */
|
||||
if (mySourceChar == UCNV_TILDE) {
|
||||
mode = UCNV_TILDE;
|
||||
} else {
|
||||
/*
|
||||
* add another bit to distinguish a 0 byte from not having seen a lead byte
|
||||
*/
|
||||
toUnicodeStatus = mySourceChar | 0x100;
|
||||
isEmptySegment = false; /* the segment has something, either valid or will produce a different error, so reset this */
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
/* trail byte */
|
||||
boolean leadIsOk, trailIsOk;
|
||||
int leadByte = toUnicodeStatus & 0xff;
|
||||
targetUniChar = 0xffff;
|
||||
/*
|
||||
* Ticket 5691: consistent illegal sequence
|
||||
* - We include at least the first byte in the illegal sequence.
|
||||
* - If any of the non-initial bytes could be the start of a character,
|
||||
* we stop the illegal sequence before the first one of those
|
||||
*
|
||||
* In HZ DBCS, if the second byte is in the 21..7e range,
|
||||
* we report ony the first byte as the illegal sequence.
|
||||
* Otherwise we convert of report the pair of bytes.
|
||||
*/
|
||||
leadIsOk = (short)(UConverterConstants.UNSIGNED_BYTE_MASK & (leadByte - 0x21)) <= (0x7d - 0x21);
|
||||
trailIsOk = (short)(UConverterConstants.UNSIGNED_BYTE_MASK & (mySourceChar - 0x21)) <= (0x7e - 0x21);
|
||||
if (leadIsOk && trailIsOk) {
|
||||
tempBuf[0] = (byte)(leadByte + 0x80);
|
||||
tempBuf[1] = (byte)(mySourceChar + 0x80);
|
||||
targetUniChar = gbDecoder.simpleGetNextUChar(ByteBuffer.wrap(tempBuf), super.isFallbackUsed());
|
||||
mySourceChar = (leadByte << 8) | mySourceChar;
|
||||
} else if (trailIsOk) {
|
||||
/* report a single illegal byte and continue with the following DBCS starter byte */
|
||||
source.position(source.position() - 1);
|
||||
mySourceChar = leadByte;
|
||||
} else {
|
||||
/* report a pair of illegal bytes if the second byte is not a DBCS starter */
|
||||
/* add another bit so that the code below writes 2 bytes in case of error */
|
||||
mySourceChar = 0x10000 | (leadByte << 8) | mySourceChar;
|
||||
}
|
||||
toUnicodeStatus = 0x00;
|
||||
}
|
||||
} else {
|
||||
if (mySourceChar == UCNV_TILDE) {
|
||||
mode = UCNV_TILDE;
|
||||
continue;
|
||||
} else if (mySourceChar <= 0x7f) {
|
||||
targetUniChar = mySourceChar; /* ASCII */
|
||||
isEmptySegment = false; /* the segment has something valid */
|
||||
} else {
|
||||
targetUniChar = 0xffff;
|
||||
isEmptySegment = false; /* different error here, reset this to avoid spurious future error */
|
||||
}
|
||||
}
|
||||
|
||||
if (targetUniChar < 0xfffe) {
|
||||
if (offsets != null) {
|
||||
offsets.put(source.position() - 1 - (isStateDBCS ? 1 : 0));
|
||||
}
|
||||
|
||||
target.put((char) targetUniChar);
|
||||
} else /* targetUniChar >= 0xfffe */{
|
||||
if (mySourceChar > 0xff) {
|
||||
toUBytesArray[toUBytesBegin + 0] = (byte) (mySourceChar >> 8);
|
||||
toUBytesArray[toUBytesBegin + 1] = (byte) mySourceChar;
|
||||
toULength = 2;
|
||||
} else {
|
||||
toUBytesArray[toUBytesBegin + 0] = (byte) mySourceChar;
|
||||
toULength = 1;
|
||||
}
|
||||
if (targetUniChar == 0xfffe) {
|
||||
return CoderResult.unmappableForLength(toULength);
|
||||
} else {
|
||||
return CoderResult.malformedForLength(toULength);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
class CharsetEncoderHZ extends CharsetEncoderICU {
|
||||
CharsetMBCS.CharsetEncoderMBCS gbEncoder;
|
||||
boolean isEscapeAppended = false;
|
||||
boolean isTargetUCharDBCS = false;
|
||||
|
||||
public CharsetEncoderHZ(CharsetICU cs) {
|
||||
super(cs, fromUSubstitution);
|
||||
gbEncoder = (CharsetMBCS.CharsetEncoderMBCS) gbCharset.newEncoder();
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
gbEncoder.implReset();
|
||||
|
||||
isEscapeAppended = false;
|
||||
isTargetUCharDBCS = false;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
|
||||
int length = 0;
|
||||
int[] targetUniChar = new int[] { 0 };
|
||||
int mySourceChar = 0;
|
||||
boolean oldIsTargetUCharDBCS = isTargetUCharDBCS;
|
||||
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
else if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
if (fromUChar32 != 0 && target.hasRemaining()) {
|
||||
CoderResult cr = handleSurrogates(source, (char) fromUChar32);
|
||||
return (cr != null) ? cr : CoderResult.unmappableForLength(2);
|
||||
}
|
||||
/* writing the char to the output stream */
|
||||
while (source.hasRemaining()) {
|
||||
targetUniChar[0] = MISSING_CHAR_MARKER;
|
||||
if (target.hasRemaining()) {
|
||||
|
||||
mySourceChar = source.get();
|
||||
|
||||
oldIsTargetUCharDBCS = isTargetUCharDBCS;
|
||||
if (mySourceChar == UCNV_TILDE) {
|
||||
/*
|
||||
* concatEscape(args, &myTargetIndex, &targetLength,"\x7E\x7E",err,2,&mySourceIndex);
|
||||
*/
|
||||
concatEscape(source, target, offsets, TILDE_ESCAPE);
|
||||
continue;
|
||||
} else if (mySourceChar <= 0x7f) {
|
||||
length = 1;
|
||||
targetUniChar[0] = mySourceChar;
|
||||
} else {
|
||||
length = gbEncoder.fromUChar32(mySourceChar, targetUniChar, super.isFallbackUsed());
|
||||
|
||||
/*
|
||||
* we can only use lead bytes 21..7D and trail bytes 21..7E
|
||||
*/
|
||||
if (length == 2 && 0xa1a1 <= targetUniChar[0] && targetUniChar[0] <= 0xfdfe
|
||||
&& 0xa1 <= (targetUniChar[0] & 0xff) && (targetUniChar[0] & 0xff) <= 0xfe) {
|
||||
targetUniChar[0] -= 0x8080;
|
||||
} else {
|
||||
targetUniChar[0] = MISSING_CHAR_MARKER;
|
||||
}
|
||||
}
|
||||
if (targetUniChar[0] != MISSING_CHAR_MARKER) {
|
||||
isTargetUCharDBCS = (targetUniChar[0] > 0x00FF);
|
||||
if (oldIsTargetUCharDBCS != isTargetUCharDBCS || !isEscapeAppended) {
|
||||
/* Shifting from a double byte to single byte mode */
|
||||
if (!isTargetUCharDBCS) {
|
||||
concatEscape(source, target, offsets, SB_ESCAPE);
|
||||
isEscapeAppended = true;
|
||||
} else { /*
|
||||
* Shifting from a single byte to double byte mode
|
||||
*/
|
||||
concatEscape(source, target, offsets, DB_ESCAPE);
|
||||
isEscapeAppended = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (isTargetUCharDBCS) {
|
||||
if (target.hasRemaining()) {
|
||||
target.put((byte) (targetUniChar[0] >> 8));
|
||||
if (offsets != null) {
|
||||
offsets.put(source.position() - 1);
|
||||
}
|
||||
if (target.hasRemaining()) {
|
||||
target.put((byte) targetUniChar[0]);
|
||||
if (offsets != null) {
|
||||
offsets.put(source.position() - 1);
|
||||
}
|
||||
} else {
|
||||
errorBuffer[errorBufferLength++] = (byte) targetUniChar[0];
|
||||
// *err = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
} else {
|
||||
errorBuffer[errorBufferLength++] = (byte) (targetUniChar[0] >> 8);
|
||||
errorBuffer[errorBufferLength++] = (byte) targetUniChar[0];
|
||||
// *err = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (target.hasRemaining()) {
|
||||
target.put((byte) targetUniChar[0]);
|
||||
if (offsets != null) {
|
||||
offsets.put(source.position() - 1);
|
||||
}
|
||||
|
||||
} else {
|
||||
errorBuffer[errorBufferLength++] = (byte) targetUniChar[0];
|
||||
// *err = U_BUFFER_OVERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* oops.. the code point is unassigned */
|
||||
/* Handle surrogates */
|
||||
/* check if the char is a First surrogate */
|
||||
|
||||
if (UTF16.isSurrogate((char) mySourceChar)) {
|
||||
// use that handy handleSurrogates method everyone's been talking about!
|
||||
CoderResult cr = handleSurrogates(source, (char) mySourceChar);
|
||||
return (cr != null) ? cr : CoderResult.unmappableForLength(2);
|
||||
} else {
|
||||
/* callback(unassigned) for a BMP code point */
|
||||
// *err = U_INVALID_CHAR_FOUND;
|
||||
fromUChar32 = mySourceChar;
|
||||
return CoderResult.unmappableForLength(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// *err = U_BUFFER_OVERFLOW_ERROR;
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
|
||||
private CoderResult concatEscape(CharBuffer source, ByteBuffer target, IntBuffer offsets, byte[] strToAppend) {
|
||||
CoderResult cr = null;
|
||||
for (int i=0; i<strToAppend.length; i++) {
|
||||
byte b = strToAppend[i];
|
||||
if (target.hasRemaining()) {
|
||||
target.put(b);
|
||||
if (offsets != null)
|
||||
offsets.put(source.position() - 1);
|
||||
} else {
|
||||
errorBuffer[errorBufferLength++] = b;
|
||||
cr = CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new CharsetDecoderHZ(this);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new CharsetEncoderHZ(this);
|
||||
}
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
setFillIn.add(0,0x7f);
|
||||
// CharsetMBCS mbcshz = (CharsetMBCS)CharsetICU.forNameICU("icu-internal-25546");
|
||||
gbCharset.MBCSGetFilteredUnicodeSetForUnicode(gbCharset.sharedData, setFillIn, which, CharsetMBCS.UCNV_SET_FILTER_HZ);
|
||||
}
|
||||
}
|
378
main/classes/charset/src/com/ibm/icu/charset/CharsetICU.java
Normal file
378
main/classes/charset/src/com/ibm/icu/charset/CharsetICU.java
Normal file
|
@ -0,0 +1,378 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* <p>A subclass of java.nio.Charset for providing implementation of ICU's charset converters.
|
||||
* This API is used to convert codepage or character encoded data to and
|
||||
* from UTF-16. You can open a converter with {@link Charset#forName } and {@link #forNameICU }. With that
|
||||
* converter, you can get its properties, set options, convert your data.</p>
|
||||
*
|
||||
* <p>Since many software programs recogize different converter names for
|
||||
* different types of converters, there are other functions in this API to
|
||||
* iterate over the converter aliases.
|
||||
*
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public abstract class CharsetICU extends Charset{
|
||||
|
||||
String icuCanonicalName;
|
||||
String javaCanonicalName;
|
||||
int options;
|
||||
|
||||
float maxCharsPerByte;
|
||||
|
||||
String name; /* +4: 60 internal name of the converter- invariant chars */
|
||||
|
||||
int codepage; /* +64: 4 codepage # (now IBM-$codepage) */
|
||||
|
||||
byte platform; /* +68: 1 platform of the converter (only IBM now) */
|
||||
byte conversionType; /* +69: 1 conversion type */
|
||||
|
||||
int minBytesPerChar; /* +70: 1 Minimum # bytes per char in this codepage */
|
||||
int maxBytesPerChar; /* +71: 1 Maximum # bytes output per UChar in this codepage */
|
||||
|
||||
byte subChar[/*UCNV_MAX_SUBCHAR_LEN*/]; /* +72: 4 [note: 4 and 8 byte boundary] */
|
||||
byte subCharLen; /* +76: 1 */
|
||||
|
||||
byte hasToUnicodeFallback; /* +77: 1 UBool needs to be changed to UBool to be consistent across platform */
|
||||
byte hasFromUnicodeFallback; /* +78: 1 */
|
||||
short unicodeMask; /* +79: 1 bit 0: has supplementary bit 1: has single surrogates */
|
||||
byte subChar1; /* +80: 1 single-byte substitution character for IBM MBCS (0 if none) */
|
||||
//byte reserved[/*19*/]; /* +81: 19 to round out the structure */
|
||||
|
||||
|
||||
// typedef enum UConverterUnicodeSet {
|
||||
/**
|
||||
* Parameter that select the set of roundtrippable Unicode code points.
|
||||
* @stable ICU 4.0
|
||||
*/
|
||||
public static final int ROUNDTRIP_SET=0;
|
||||
/**
|
||||
* Select the set of Unicode code points with roundtrip or fallback mappings.
|
||||
* Not supported at this point.
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
public static final int ROUNDTRIP_AND_FALLBACK_SET =1;
|
||||
|
||||
//} UConverterUnicodeSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param icuCanonicalName
|
||||
* @param canonicalName
|
||||
* @param aliases
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
protected CharsetICU(String icuCanonicalName, String canonicalName, String[] aliases) {
|
||||
super(canonicalName,aliases);
|
||||
if(canonicalName.length() == 0){
|
||||
throw new IllegalCharsetNameException(canonicalName);
|
||||
}
|
||||
this.javaCanonicalName = canonicalName;
|
||||
this.icuCanonicalName = icuCanonicalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains if a charset is a sub set of this charset
|
||||
* Implements the abstract method of super class.
|
||||
* @param cs charset to test
|
||||
* @return true if the given charset is a subset of this charset
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public boolean contains(Charset cs){
|
||||
if (null == cs) {
|
||||
return false;
|
||||
} else if (this.equals(cs)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static final HashMap<String, String> algorithmicCharsets = new HashMap<String, String>();
|
||||
static{
|
||||
algorithmicCharsets.put("LMBCS-1", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-2", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-3", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-4", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-5", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-6", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-8", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-11", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-16", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-17", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-18", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("LMBCS-19", "com.ibm.icu.charset.CharsetLMBCS");
|
||||
algorithmicCharsets.put("BOCU-1", "com.ibm.icu.charset.CharsetBOCU1" );
|
||||
algorithmicCharsets.put("SCSU", "com.ibm.icu.charset.CharsetSCSU" );
|
||||
algorithmicCharsets.put("US-ASCII", "com.ibm.icu.charset.CharsetASCII" );
|
||||
algorithmicCharsets.put("ISO-8859-1", "com.ibm.icu.charset.Charset88591" );
|
||||
algorithmicCharsets.put("UTF-16", "com.ibm.icu.charset.CharsetUTF16" );
|
||||
algorithmicCharsets.put("UTF-16BE", "com.ibm.icu.charset.CharsetUTF16BE" );
|
||||
algorithmicCharsets.put("UTF-16LE", "com.ibm.icu.charset.CharsetUTF16LE" );
|
||||
algorithmicCharsets.put("UTF16_OppositeEndian", "com.ibm.icu.charset.CharsetUTF16LE" );
|
||||
algorithmicCharsets.put("UTF16_PlatformEndian", "com.ibm.icu.charset.CharsetUTF16" );
|
||||
algorithmicCharsets.put("UTF-32", "com.ibm.icu.charset.CharsetUTF32" );
|
||||
algorithmicCharsets.put("UTF-32BE", "com.ibm.icu.charset.CharsetUTF32BE" );
|
||||
algorithmicCharsets.put("UTF-32LE", "com.ibm.icu.charset.CharsetUTF32LE" );
|
||||
algorithmicCharsets.put("UTF32_OppositeEndian", "com.ibm.icu.charset.CharsetUTF32LE" );
|
||||
algorithmicCharsets.put("UTF32_PlatformEndian", "com.ibm.icu.charset.CharsetUTF32" );
|
||||
algorithmicCharsets.put("UTF-8", "com.ibm.icu.charset.CharsetUTF8" );
|
||||
algorithmicCharsets.put("CESU-8", "com.ibm.icu.charset.CharsetCESU8" );
|
||||
algorithmicCharsets.put("UTF-7", "com.ibm.icu.charset.CharsetUTF7" );
|
||||
algorithmicCharsets.put("ISCII,version=0", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=1", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=2", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=3", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=4", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=5", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=6", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=7", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("ISCII,version=8", "com.ibm.icu.charset.CharsetISCII" );
|
||||
algorithmicCharsets.put("IMAP-mailbox-name", "com.ibm.icu.charset.CharsetUTF7" );
|
||||
algorithmicCharsets.put("HZ", "com.ibm.icu.charset.CharsetHZ" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=ja,version=0", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=ja,version=1", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=ja,version=2", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=ja,version=3", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=ja,version=4", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=zh,version=0", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=zh,version=1", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=ko,version=0", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
algorithmicCharsets.put("ISO_2022,locale=ko,version=1", "com.ibm.icu.charset.CharsetISO2022" );
|
||||
}
|
||||
|
||||
/*public*/ static final Charset getCharset(String icuCanonicalName, String javaCanonicalName, String[] aliases){
|
||||
String className = algorithmicCharsets.get(icuCanonicalName);
|
||||
if(className==null){
|
||||
//all the cnv files are loaded as MBCS
|
||||
className = "com.ibm.icu.charset.CharsetMBCS";
|
||||
}
|
||||
try{
|
||||
CharsetICU conv = null;
|
||||
Class<? extends CharsetICU> cs = Class.forName(className).asSubclass(CharsetICU.class);
|
||||
Class<?>[] paramTypes = new Class<?>[]{ String.class, String.class, String[].class};
|
||||
final Constructor<? extends CharsetICU> c = cs.getConstructor(paramTypes);
|
||||
Object[] params = new Object[]{ icuCanonicalName, javaCanonicalName, aliases};
|
||||
|
||||
// Run constructor
|
||||
try {
|
||||
conv = c.newInstance(params);
|
||||
if (conv != null) {
|
||||
return conv;
|
||||
}
|
||||
}catch (InvocationTargetException e) {
|
||||
throw new UnsupportedCharsetException( icuCanonicalName+": "+"Could not load " + className+ ". Exception:" + e.getTargetException());
|
||||
}
|
||||
}catch(ClassNotFoundException ex){
|
||||
}catch(NoSuchMethodException ex){
|
||||
}catch (IllegalAccessException ex){
|
||||
}catch (InstantiationException ex){
|
||||
}
|
||||
throw new UnsupportedCharsetException( icuCanonicalName+": "+"Could not load " + className);
|
||||
}
|
||||
|
||||
static final boolean isSurrogate(int c){
|
||||
return (((c)&0xfffff800)==0xd800);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default charset name
|
||||
*/
|
||||
// static final String getDefaultCharsetName(){
|
||||
// String defaultEncoding = new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding();
|
||||
// return defaultEncoding;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns a charset object for the named charset.
|
||||
* This method gurantee that ICU charset is returned when
|
||||
* available. If the ICU charset provider does not support
|
||||
* the specified charset, then try other charset providers
|
||||
* including the standard Java charset provider.
|
||||
*
|
||||
* @param charsetName The name of the requested charset,
|
||||
* may be either a canonical name or an alias
|
||||
* @return A charset object for the named charset
|
||||
* @throws IllegalCharsetNameException If the given charset name
|
||||
* is illegal
|
||||
* @throws UnsupportedCharsetException If no support for the
|
||||
* named charset is available in this instance of th Java
|
||||
* virtual machine
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public static Charset forNameICU(String charsetName) throws IllegalCharsetNameException, UnsupportedCharsetException {
|
||||
CharsetProviderICU icuProvider = new CharsetProviderICU();
|
||||
CharsetICU cs = (CharsetICU) icuProvider.charsetForName(charsetName);
|
||||
if (cs != null) {
|
||||
return cs;
|
||||
}
|
||||
return Charset.forName(charsetName);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @see java.lang.Comparable#compareTo(java.lang.Object)
|
||||
// * @stable 3.8
|
||||
// */
|
||||
// public int compareTo(Object otherObj) {
|
||||
// if (!(otherObj instanceof CharsetICU)) {
|
||||
// return -1;
|
||||
// }
|
||||
// return icuCanonicalName.compareTo(((CharsetICU)otherObj).icuCanonicalName);
|
||||
// }
|
||||
|
||||
/**
|
||||
* This follows ucnv.c method ucnv_detectUnicodeSignature() to detect the
|
||||
* start of the stream for example U+FEFF (the Unicode BOM/signature
|
||||
* character) that can be ignored.
|
||||
*
|
||||
* Detects Unicode signature byte sequences at the start of the byte stream
|
||||
* and returns number of bytes of the BOM of the indicated Unicode charset.
|
||||
* 0 is returned when no Unicode signature is recognized.
|
||||
*
|
||||
*/
|
||||
// TODO This should be proposed as CharsetDecoderICU API.
|
||||
// static String detectUnicodeSignature(ByteBuffer source) {
|
||||
// int signatureLength = 0; // number of bytes of the signature
|
||||
// final int SIG_MAX_LEN = 5;
|
||||
// String sigUniCharset = null; // states what unicode charset is the BOM
|
||||
// int i = 0;
|
||||
//
|
||||
// /*
|
||||
// * initial 0xa5 bytes: make sure that if we read <SIG_MAX_LEN bytes we
|
||||
// * don't misdetect something
|
||||
// */
|
||||
// byte start[] = { (byte) 0xa5, (byte) 0xa5, (byte) 0xa5, (byte) 0xa5,
|
||||
// (byte) 0xa5 };
|
||||
//
|
||||
// while (i < source.remaining() && i < SIG_MAX_LEN) {
|
||||
// start[i] = source.get(i);
|
||||
// i++;
|
||||
// }
|
||||
//
|
||||
// if (start[0] == (byte) 0xFE && start[1] == (byte) 0xFF) {
|
||||
// signatureLength = 2;
|
||||
// sigUniCharset = "UTF-16BE";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// } else if (start[0] == (byte) 0xFF && start[1] == (byte) 0xFE) {
|
||||
// if (start[2] == (byte) 0x00 && start[3] == (byte) 0x00) {
|
||||
// signatureLength = 4;
|
||||
// sigUniCharset = "UTF-32LE";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// } else {
|
||||
// signatureLength = 2;
|
||||
// sigUniCharset = "UTF-16LE";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// }
|
||||
// } else if (start[0] == (byte) 0xEF && start[1] == (byte) 0xBB
|
||||
// && start[2] == (byte) 0xBF) {
|
||||
// signatureLength = 3;
|
||||
// sigUniCharset = "UTF-8";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// } else if (start[0] == (byte) 0x00 && start[1] == (byte) 0x00
|
||||
// && start[2] == (byte) 0xFE && start[3] == (byte) 0xFF) {
|
||||
// signatureLength = 4;
|
||||
// sigUniCharset = "UTF-32BE";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// } else if (start[0] == (byte) 0x0E && start[1] == (byte) 0xFE
|
||||
// && start[2] == (byte) 0xFF) {
|
||||
// signatureLength = 3;
|
||||
// sigUniCharset = "SCSU";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// } else if (start[0] == (byte) 0xFB && start[1] == (byte) 0xEE
|
||||
// && start[2] == (byte) 0x28) {
|
||||
// signatureLength = 3;
|
||||
// sigUniCharset = "BOCU-1";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// } else if (start[0] == (byte) 0x2B && start[1] == (byte) 0x2F
|
||||
// && start[2] == (byte) 0x76) {
|
||||
//
|
||||
// if (start[3] == (byte) 0x38 && start[4] == (byte) 0x2D) {
|
||||
// signatureLength = 5;
|
||||
// sigUniCharset = "UTF-7";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// } else if (start[3] == (byte) 0x38 || start[3] == (byte) 0x39
|
||||
// || start[3] == (byte) 0x2B || start[3] == (byte) 0x2F) {
|
||||
// signatureLength = 4;
|
||||
// sigUniCharset = "UTF-7";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// }
|
||||
// } else if (start[0] == (byte) 0xDD && start[2] == (byte) 0x73
|
||||
// && start[2] == (byte) 0x66 && start[3] == (byte) 0x73) {
|
||||
// signatureLength = 4;
|
||||
// sigUniCharset = "UTF-EBCDIC";
|
||||
// source.position(signatureLength);
|
||||
// return sigUniCharset;
|
||||
// }
|
||||
//
|
||||
// /* no known Unicode signature byte sequence recognized */
|
||||
// return null;
|
||||
// }
|
||||
|
||||
|
||||
abstract void getUnicodeSetImpl(UnicodeSet setFillIn, int which);
|
||||
|
||||
/**
|
||||
* <p>Returns the set of Unicode code points that can be converted by an ICU Converter.
|
||||
* <p>
|
||||
* The current implementation returns only one kind of set (UCNV_ROUNDTRIP_SET): The set of all Unicode code points that can be
|
||||
* roundtrip-converted (converted without any data loss) with the converter This set will not include code points that have fallback
|
||||
* mappings or are only the result of reverse fallback mappings. See UTR #22 "Character Mapping Markup Language" at <a href="http://www.unicode.org/reports/tr22/">http://www.unicode.org/reports/tr22/</a>
|
||||
* <p>* In the future, there may be more UConverterUnicodeSet choices to select sets with different properties.
|
||||
* <p>
|
||||
* <p>This is useful for example for
|
||||
* <ul><li>checking that a string or document can be roundtrip-converted with a converter,
|
||||
* without/before actually performing the conversion</li>
|
||||
* <li>testing if a converter can be used for text for typical text for a certain locale,
|
||||
* by comparing its roundtrip set with the set of ExemplarCharacters from
|
||||
* ICU's locale data or other sources</li></ul>
|
||||
*
|
||||
* @param setFillIn A valid UnicodeSet. It will be cleared by this function before
|
||||
* the converter's specific set is filled in.
|
||||
* @param which A selector; currently ROUNDTRIP_SET is the only supported value.
|
||||
* @throws IllegalArgumentException if the parameters does not match.
|
||||
* @stable ICU 4.0
|
||||
*/
|
||||
public void getUnicodeSet(UnicodeSet setFillIn, int which){
|
||||
if( setFillIn == null || which != ROUNDTRIP_SET ){
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
setFillIn.clear();
|
||||
getUnicodeSetImpl(setFillIn, which);
|
||||
}
|
||||
|
||||
static void getNonSurrogateUnicodeSet(UnicodeSet setFillIn){
|
||||
setFillIn.add(0, 0xd7ff);
|
||||
setFillIn.add(0xe000, 0x10ffff);
|
||||
}
|
||||
|
||||
static void getCompleteUnicodeSet(UnicodeSet setFillIn){
|
||||
setFillIn.add(0, 0x10ffff);
|
||||
}
|
||||
|
||||
}
|
1458
main/classes/charset/src/com/ibm/icu/charset/CharsetISCII.java
Normal file
1458
main/classes/charset/src/com/ibm/icu/charset/CharsetISCII.java
Normal file
File diff suppressed because it is too large
Load diff
2992
main/classes/charset/src/com/ibm/icu/charset/CharsetISO2022.java
Normal file
2992
main/classes/charset/src/com/ibm/icu/charset/CharsetISO2022.java
Normal file
File diff suppressed because it is too large
Load diff
1109
main/classes/charset/src/com/ibm/icu/charset/CharsetLMBCS.java
Normal file
1109
main/classes/charset/src/com/ibm/icu/charset/CharsetLMBCS.java
Normal file
File diff suppressed because it is too large
Load diff
5126
main/classes/charset/src/com/ibm/icu/charset/CharsetMBCS.java
Normal file
5126
main/classes/charset/src/com/ibm/icu/charset/CharsetMBCS.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,334 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.nio.charset.spi.CharsetProvider;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.icu.impl.InvalidFormatException;
|
||||
|
||||
|
||||
/**
|
||||
* A concrete subclass of CharsetProvider for loading and providing charset converters
|
||||
* in ICU.
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public final class CharsetProviderICU extends CharsetProvider{
|
||||
private static String optionsString = null;
|
||||
private static boolean gettingJavaCanonicalName = false;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public CharsetProviderICU() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a charset for the given charset name.
|
||||
* Implements the abstract method of super class.
|
||||
* @param charsetName charset name
|
||||
* @return charset objet for the given charset name, null if unsupported
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public final Charset charsetForName(String charsetName){
|
||||
try{
|
||||
// extract the options from the charset name
|
||||
charsetName = processOptions(charsetName);
|
||||
// get the canonical name
|
||||
String icuCanonicalName = getICUCanonicalName(charsetName);
|
||||
|
||||
// create the converter object and return it
|
||||
if(icuCanonicalName==null || icuCanonicalName.length()==0){
|
||||
// Try the original name, may be something added and not in the alias table.
|
||||
// Will get an unsupported encoding exception if it doesn't work.
|
||||
return getCharset(charsetName);
|
||||
}
|
||||
return getCharset(icuCanonicalName);
|
||||
}catch(UnsupportedCharsetException ex){
|
||||
}catch(IOException ex){
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a charset for the given ICU conversion table from the specified class path.
|
||||
* Example use: <code>cnv = CharsetProviderICU.charsetForName("myConverter", "com/myCompany/myDataPackage");</code>.
|
||||
* In this example myConverter.cnv would exist in the com/myCompany/myDataPackage Java package.
|
||||
* Conversion tables can be made with ICU4C's makeconv tool.
|
||||
* This function allows you to allows you to load user defined conversion
|
||||
* tables that are outside of ICU's core data.
|
||||
* @param charsetName The name of the charset conversion table.
|
||||
* @param classPath The class path that contain the conversion table.
|
||||
* @return charset object for the given charset name, null if unsupported
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public final Charset charsetForName(String charsetName, String classPath) {
|
||||
return charsetForName(charsetName, classPath, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a charset for the given ICU conversion table from the specified class path.
|
||||
* This function is similar to {@link #charsetForName(String, String)}.
|
||||
* @param charsetName The name of the charset conversion table.
|
||||
* @param classPath The class path that contain the conversion table.
|
||||
* @param loader the class object from which to load the charset conversion table
|
||||
* @return charset object for the given charset name, null if unsupported
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public Charset charsetForName(String charsetName, String classPath, ClassLoader loader) {
|
||||
CharsetMBCS cs = null;
|
||||
try {
|
||||
cs = new CharsetMBCS(charsetName, charsetName, new String[0], classPath, loader);
|
||||
} catch (InvalidFormatException e) {
|
||||
// return null;
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the canonical name of the converter as defined by Java
|
||||
* @param enc converter name
|
||||
* @return canonical name of the converter
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
public static final String getICUCanonicalName(String enc)
|
||||
throws UnsupportedCharsetException{
|
||||
String canonicalName = null;
|
||||
String ret = null;
|
||||
try{
|
||||
if(enc!=null){
|
||||
if((canonicalName = UConverterAlias.getCanonicalName(enc, "MIME"))!=null){
|
||||
ret = canonicalName;
|
||||
} else if((canonicalName = UConverterAlias.getCanonicalName(enc, "IANA"))!=null){
|
||||
ret = canonicalName;
|
||||
} else if((canonicalName = UConverterAlias.getAlias(enc, 0))!=null){
|
||||
/* we have some aliases in the form x-blah .. match those */
|
||||
ret = canonicalName;
|
||||
}/*else if((canonicalName = UConverterAlias.getCanonicalName(enc, ""))!=null){
|
||||
ret = canonicalName;
|
||||
}*/else if(enc.indexOf("x-")==0){
|
||||
/* TODO: Match with getJavaCanonicalName method */
|
||||
/*
|
||||
char temp[ UCNV_MAX_CONVERTER_NAME_LENGTH] = {0};
|
||||
strcpy(temp, encName+2);
|
||||
*/
|
||||
// Remove the 'x-' and get the ICU canonical name
|
||||
if ((canonicalName = UConverterAlias.getAlias(enc.substring(2), 0))!=null) {
|
||||
ret = canonicalName;
|
||||
} else {
|
||||
ret = "";
|
||||
}
|
||||
|
||||
}else{
|
||||
/* unsupported encoding */
|
||||
ret = "";
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}catch(IOException ex){
|
||||
throw new UnsupportedCharsetException(enc);
|
||||
}
|
||||
}
|
||||
private static final Charset getCharset(String icuCanonicalName) throws IOException{
|
||||
String[] aliases = getAliases(icuCanonicalName);
|
||||
String canonicalName = getJavaCanonicalName(icuCanonicalName);
|
||||
|
||||
/* Concat the option string to the icuCanonicalName so that the options can be handled properly
|
||||
* by the actual charset.
|
||||
* Note: getJavaCanonicalName() may eventually call this method so skip the concatenation part
|
||||
* during getJavaCanonicalName() call.
|
||||
*/
|
||||
if (!gettingJavaCanonicalName && optionsString != null) {
|
||||
icuCanonicalName = icuCanonicalName.concat(optionsString);
|
||||
optionsString = null;
|
||||
}
|
||||
|
||||
return (CharsetICU.getCharset(icuCanonicalName,canonicalName, aliases));
|
||||
}
|
||||
/**
|
||||
* Gets the canonical name of the converter as defined by Java
|
||||
* @param charsetName converter name
|
||||
* @return canonical name of the converter
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
public static String getJavaCanonicalName(String charsetName){
|
||||
/*
|
||||
If a charset listed in the IANA Charset Registry is supported by an implementation
|
||||
of the Java platform then its canonical name must be the name listed in the registry.
|
||||
Many charsets are given more than one name in the registry, in which case the registry
|
||||
identifies one of the names as MIME-preferred. If a charset has more than one registry
|
||||
name then its canonical name must be the MIME-preferred name and the other names in
|
||||
the registry must be valid aliases. If a supported charset is not listed in the IANA
|
||||
registry then its canonical name must begin with one of the strings "X-" or "x-".
|
||||
*/
|
||||
if(charsetName==null ){
|
||||
return null;
|
||||
}
|
||||
try{
|
||||
String cName = null;
|
||||
/* find out the alias with MIME tag */
|
||||
if((cName=UConverterAlias.getStandardName(charsetName, "MIME"))!=null){
|
||||
/* find out the alias with IANA tag */
|
||||
}else if((cName=UConverterAlias.getStandardName(charsetName, "IANA"))!=null){
|
||||
}else {
|
||||
/*
|
||||
check to see if an alias already exists with x- prefix, if yes then
|
||||
make that the canonical name
|
||||
*/
|
||||
int aliasNum = UConverterAlias.countAliases(charsetName);
|
||||
String name;
|
||||
for(int i=0;i<aliasNum;i++){
|
||||
name = UConverterAlias.getAlias(charsetName, i);
|
||||
if(name!=null && name.indexOf("x-")==0){
|
||||
cName = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* last resort just append x- to any of the alias and
|
||||
make it the canonical name */
|
||||
if((cName==null || cName.length()==0)){
|
||||
name = UConverterAlias.getStandardName(charsetName, "UTR22");
|
||||
if(name==null && charsetName.indexOf(",")!=-1){
|
||||
name = UConverterAlias.getAlias(charsetName, 1);
|
||||
}
|
||||
/* if there is no UTR22 canonical name .. then just return itself*/
|
||||
if(name==null){
|
||||
name = charsetName;
|
||||
}
|
||||
cName = "x-"+ name;
|
||||
}
|
||||
}
|
||||
/* After getting the java canonical name from ICU alias table, get the
|
||||
* java canonical name from the current JDK. This is neccessary because
|
||||
* different versions of the JVM (Sun and IBM) may have a different
|
||||
* canonical name then the one given by ICU. So the java canonical name
|
||||
* will depend on the current JVM. Since java cannot use the ICU canonical
|
||||
* we have to try to use a java compatible name.
|
||||
*/
|
||||
if (cName != null) {
|
||||
if (!gettingJavaCanonicalName) {
|
||||
gettingJavaCanonicalName = true;
|
||||
if (Charset.isSupported(cName)) {
|
||||
cName = Charset.forName(cName).name();
|
||||
}
|
||||
gettingJavaCanonicalName = false;
|
||||
}
|
||||
}
|
||||
return cName;
|
||||
}catch (IOException ex){
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the aliases associated with the converter name
|
||||
* @param encName converter name
|
||||
* @return converter names as elements in an object array
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
private static final String[] getAliases(String encName)throws IOException{
|
||||
String[] ret = null;
|
||||
int aliasNum = 0;
|
||||
int i=0;
|
||||
int j=0;
|
||||
String aliasArray[/*50*/] = new String[50];
|
||||
|
||||
if(encName != null){
|
||||
aliasNum = UConverterAlias.countAliases(encName);
|
||||
for(i=0,j=0;i<aliasNum;i++){
|
||||
String name = UConverterAlias.getAlias(encName,i);
|
||||
if(name.indexOf('+')==-1 && name.indexOf(',')==-1){
|
||||
aliasArray[j++]= name;
|
||||
}
|
||||
}
|
||||
ret = new String[j];
|
||||
for(;--j>=0;) {
|
||||
ret[j] = aliasArray[j];
|
||||
}
|
||||
|
||||
}
|
||||
return (ret);
|
||||
|
||||
}
|
||||
|
||||
private static final void putCharsets(Map<Charset, String> map){
|
||||
int num = UConverterAlias.countAvailable();
|
||||
for(int i=0;i<num;i++) {
|
||||
String name = UConverterAlias.getAvailableName(i);
|
||||
try {
|
||||
Charset cs = getCharset(name);
|
||||
map.put(cs, getJavaCanonicalName(name));
|
||||
}catch(UnsupportedCharsetException ex){
|
||||
}catch (IOException e) {
|
||||
}
|
||||
// add only charsets that can be created!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator for the available charsets.
|
||||
* Implements the abstract method of super class.
|
||||
* @return Iterator the charset name iterator
|
||||
* @stable ICU 3.6
|
||||
*/
|
||||
public final Iterator<Charset> charsets(){
|
||||
HashMap<Charset, String> map = new HashMap<Charset, String>();
|
||||
putCharsets(map);
|
||||
return map.keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the canonical names of available converters
|
||||
* @return array of available converter names
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
public static final String[] getAvailableNames(){
|
||||
HashMap<Charset, String> map = new HashMap<Charset, String>();
|
||||
putCharsets(map);
|
||||
return map.values().toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all names available
|
||||
* @return String[] an array of all available names
|
||||
* @internal
|
||||
* @deprecated This API is ICU internal only.
|
||||
*/
|
||||
public static final String[] getAllNames(){
|
||||
int num = UConverterAlias.countAvailable();
|
||||
String[] names = new String[num];
|
||||
for(int i=0;i<num;i++) {
|
||||
names[i] = UConverterAlias.getAvailableName(i);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private static final String processOptions(String charsetName) {
|
||||
if (charsetName.indexOf(UConverterConstants.OPTION_SWAP_LFNL_STRING) > -1) {
|
||||
/* Remove and save the swap lfnl option string portion of the charset name. */
|
||||
optionsString = UConverterConstants.OPTION_SWAP_LFNL_STRING;
|
||||
|
||||
charsetName = charsetName.substring(0, charsetName.indexOf(UConverterConstants.OPTION_SWAP_LFNL_STRING));
|
||||
}
|
||||
|
||||
return charsetName;
|
||||
}
|
||||
}
|
1267
main/classes/charset/src/com/ibm/icu/charset/CharsetSCSU.java
Normal file
1267
main/classes/charset/src/com/ibm/icu/charset/CharsetSCSU.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1996-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a port of the C++ class UConverterSelector.
|
||||
*
|
||||
* Methods related to serialization are not ported in this version. In addition,
|
||||
* the selectForUTF8 method is not going to be ported, as UTF8 is seldom used
|
||||
* in Java.
|
||||
*
|
||||
* @author Shaopeng Jia
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.IllegalCharsetNameException;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.ibm.icu.impl.IntTrie;
|
||||
import com.ibm.icu.impl.PropsVectors;
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* Charset Selector
|
||||
*
|
||||
* A charset selector is built with a list of charset names and given an input
|
||||
* CharSequence returns the list of names the corresponding charsets which can
|
||||
* convert the CharSequence.
|
||||
*
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
public final class CharsetSelector {
|
||||
private IntTrie trie;
|
||||
private int[] pv; // table of bits
|
||||
private String[] encodings; // encodings users ask to use
|
||||
|
||||
private void generateSelectorData(PropsVectors pvec,
|
||||
UnicodeSet excludedCodePoints, int mappingTypes) {
|
||||
int columns = (encodings.length + 31) / 32;
|
||||
|
||||
// set errorValue to all-ones
|
||||
for (int col = 0; col < columns; ++col) {
|
||||
pvec.setValue(PropsVectors.ERROR_VALUE_CP,
|
||||
PropsVectors.ERROR_VALUE_CP, col, ~0, ~0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < encodings.length; ++i) {
|
||||
Charset testCharset = CharsetICU.forNameICU(encodings[i]);
|
||||
UnicodeSet unicodePointSet = new UnicodeSet(); // empty set
|
||||
((CharsetICU) testCharset).getUnicodeSet(unicodePointSet,
|
||||
mappingTypes);
|
||||
int column = i / 32;
|
||||
int mask = 1 << (i % 32);
|
||||
// now iterate over intervals on set i
|
||||
int itemCount = unicodePointSet.getRangeCount();
|
||||
for (int j = 0; j < itemCount; ++j) {
|
||||
int startChar = unicodePointSet.getRangeStart(j);
|
||||
int endChar = unicodePointSet.getRangeEnd(j);
|
||||
pvec.setValue(startChar, endChar, column, ~0, mask);
|
||||
}
|
||||
}
|
||||
|
||||
// handle excluded encodings
|
||||
// Simply set their values to all 1's in the pvec
|
||||
if (!excludedCodePoints.isEmpty()) {
|
||||
int itemCount = excludedCodePoints.getRangeCount();
|
||||
for (int j = 0; j < itemCount; ++j) {
|
||||
int startChar = excludedCodePoints.getRangeStart(j);
|
||||
int endChar = excludedCodePoints.getRangeEnd(j);
|
||||
for (int col = 0; col < columns; col++) {
|
||||
pvec.setValue(startChar, endChar, col, ~0, ~0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trie = pvec.compactToTrieWithRowIndexes();
|
||||
pv = pvec.getCompactedArray();
|
||||
}
|
||||
|
||||
// internal function to intersect two sets of masks
|
||||
// returns whether the mask has reduced to all zeros. The
|
||||
// second set of mask consists of len elements in pv starting from
|
||||
// pvIndex
|
||||
private boolean intersectMasks(int[] dest, int pvIndex, int len) {
|
||||
int oredDest = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
oredDest |= (dest[i] &= pv[pvIndex + i]);
|
||||
}
|
||||
return oredDest == 0;
|
||||
}
|
||||
|
||||
// internal function
|
||||
private List<String> selectForMask(int[] mask) {
|
||||
// this is the context we will use. Store a table of indices to which
|
||||
// encodings are legit
|
||||
|
||||
Vector<String> result = new Vector<String>();
|
||||
int columns = (encodings.length + 31) / 32;
|
||||
int numOnes = countOnes(mask, columns);
|
||||
|
||||
// now we know the exact space we need to index
|
||||
if (numOnes > 0) {
|
||||
int k = 0;
|
||||
for (int j = 0; j < columns; j++) {
|
||||
int v = mask[j];
|
||||
for (int i = 0; i < 32 && k < encodings.length; i++, k++) {
|
||||
if ((v & 1) != 0) {
|
||||
result.addElement(encodings[k]);
|
||||
}
|
||||
v >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise, index will remain NULL
|
||||
return result;
|
||||
}
|
||||
|
||||
// internal function to count how many 1's are there in a mask
|
||||
// algorithm taken from http://graphics.stanford.edu/~seander/bithacks.html
|
||||
private int countOnes(int[] mask, int len) {
|
||||
int totalOnes = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
int ent = mask[i];
|
||||
for (; ent != 0; totalOnes++) {
|
||||
ent &= ent - 1; // clear the least significant bit set
|
||||
}
|
||||
}
|
||||
return totalOnes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a CharsetSelector from a list of charset names.
|
||||
*
|
||||
* @param charsetList
|
||||
* a list of charset names in the form of strings. If charsetList
|
||||
* is empty, a selector for all available charset is constructed.
|
||||
* @param excludedCodePoints
|
||||
* a set of code points to be excluded from consideration.
|
||||
* Excluded code points appearing in the input CharSequence do
|
||||
* not change the selection result. It could be empty when no
|
||||
* code point should be excluded.
|
||||
* @param mappingTypes
|
||||
* an int which determines whether to consider only roundtrip
|
||||
* mappings or also fallbacks, e.g. CharsetICU.ROUNDTRIP_SET. See
|
||||
* CharsetICU.java for the constants that are currently
|
||||
* supported.
|
||||
* @throws IllegalArgumentException
|
||||
* if the parameters is invalid.
|
||||
* @throws IllegalCharsetNameException
|
||||
* If the given charset name is illegal.
|
||||
* @throws UnsupportedCharsetException
|
||||
* If no support for the named charset is available in this
|
||||
* instance of the Java virtual machine.
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
public CharsetSelector(List<String> charsetList, UnicodeSet excludedCodePoints,
|
||||
int mappingTypes) {
|
||||
if (mappingTypes != CharsetICU.ROUNDTRIP_AND_FALLBACK_SET
|
||||
&& mappingTypes != CharsetICU.ROUNDTRIP_SET) {
|
||||
throw new IllegalArgumentException("Unsupported mappingTypes");
|
||||
}
|
||||
|
||||
int encodingCount = charsetList.size();
|
||||
if (encodingCount > 0) {
|
||||
encodings = charsetList.toArray(new String[0]);
|
||||
} else {
|
||||
encodings = CharsetProviderICU.getAvailableNames();
|
||||
encodingCount = encodings.length;
|
||||
}
|
||||
|
||||
PropsVectors pvec = new PropsVectors((encodingCount + 31) / 32);
|
||||
generateSelectorData(pvec, excludedCodePoints, mappingTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select charsets that can map all characters in a CharSequence, ignoring
|
||||
* the excluded code points.
|
||||
*
|
||||
* @param unicodeText
|
||||
* a CharSequence. It could be empty.
|
||||
* @return a list that contains charset names in the form of strings. The
|
||||
* returned encoding names and their order will be the same as
|
||||
* supplied when building the selector.
|
||||
*
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
public List<String> selectForString(CharSequence unicodeText) {
|
||||
int columns = (encodings.length + 31) / 32;
|
||||
int[] mask = new int[columns];
|
||||
for (int i = 0; i < columns; i++) {
|
||||
mask[i] = - 1; // set each bit to 1
|
||||
// Note: All integers are signed in Java, assigning
|
||||
// 2 ^ 32 -1 to mask is wrong!
|
||||
}
|
||||
int index = 0;
|
||||
while (index < unicodeText.length()) {
|
||||
int c = UTF16.charAt(unicodeText, index);
|
||||
int pvIndex = trie.getCodePointValue(c);
|
||||
index += UTF16.getCharCount(c);
|
||||
if (intersectMasks(mask, pvIndex, columns)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return selectForMask(mask);
|
||||
}
|
||||
}
|
288
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF16.java
Normal file
288
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF16.java
Normal file
|
@ -0,0 +1,288 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* @author Niti Hantaweepant
|
||||
*/
|
||||
class CharsetUTF16 extends CharsetICU {
|
||||
|
||||
private static final int SIGNATURE_LENGTH = 2;
|
||||
private static final byte[] fromUSubstitution_BE = { (byte) 0xff, (byte) 0xfd };
|
||||
private static final byte[] fromUSubstitution_LE = { (byte) 0xfd, (byte) 0xff };
|
||||
private static final byte[] BOM_BE = { (byte) 0xfe, (byte) 0xff };
|
||||
private static final byte[] BOM_LE = { (byte) 0xff, (byte) 0xfe };
|
||||
private static final int ENDIAN_XOR_BE = 0;
|
||||
private static final int ENDIAN_XOR_LE = 1;
|
||||
private static final int NEED_TO_WRITE_BOM = 1;
|
||||
|
||||
private boolean isEndianSpecified;
|
||||
private boolean isBigEndian;
|
||||
private int endianXOR;
|
||||
private byte[] bom;
|
||||
private byte[] fromUSubstitution;
|
||||
|
||||
public CharsetUTF16(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
|
||||
this.isEndianSpecified = (this instanceof CharsetUTF16BE || this instanceof CharsetUTF16LE);
|
||||
this.isBigEndian = !(this instanceof CharsetUTF16LE);
|
||||
|
||||
if (isBigEndian) {
|
||||
this.bom = BOM_BE;
|
||||
this.fromUSubstitution = fromUSubstitution_BE;
|
||||
this.endianXOR = ENDIAN_XOR_BE;
|
||||
} else {
|
||||
this.bom = BOM_LE;
|
||||
this.fromUSubstitution = fromUSubstitution_LE;
|
||||
this.endianXOR = ENDIAN_XOR_LE;
|
||||
}
|
||||
|
||||
maxBytesPerChar = 2;
|
||||
minBytesPerChar = 2;
|
||||
maxCharsPerByte = 1;
|
||||
}
|
||||
|
||||
class CharsetDecoderUTF16 extends CharsetDecoderICU {
|
||||
|
||||
private boolean isBOMReadYet;
|
||||
private int actualEndianXOR;
|
||||
private byte[] actualBOM;
|
||||
|
||||
public CharsetDecoderUTF16(CharsetICU cs) {
|
||||
super(cs);
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
isBOMReadYet = false;
|
||||
actualBOM = null;
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
|
||||
/*
|
||||
* If we detect a BOM in this buffer, then we must add the BOM size to the offsets because the actual
|
||||
* converter function will not see and count the BOM. offsetDelta will have the number of the BOM bytes that
|
||||
* are in the current buffer.
|
||||
*/
|
||||
if (!isBOMReadYet) {
|
||||
while (true) {
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
|
||||
toUBytesArray[toULength++] = source.get();
|
||||
|
||||
if (toULength == 1) {
|
||||
// on the first byte, we haven't decided whether or not it's bigEndian yet
|
||||
if ((!isEndianSpecified || isBigEndian)
|
||||
&& toUBytesArray[toULength - 1] == BOM_BE[toULength - 1]) {
|
||||
actualBOM = BOM_BE;
|
||||
actualEndianXOR = ENDIAN_XOR_BE;
|
||||
} else if ((!isEndianSpecified || !isBigEndian)
|
||||
&& toUBytesArray[toULength - 1] == BOM_LE[toULength - 1]) {
|
||||
actualBOM = BOM_LE;
|
||||
actualEndianXOR = ENDIAN_XOR_LE;
|
||||
} else {
|
||||
// we do not have a BOM (and we have toULength==1 bytes)
|
||||
actualBOM = null;
|
||||
actualEndianXOR = endianXOR;
|
||||
break;
|
||||
}
|
||||
} else if (toUBytesArray[toULength - 1] != actualBOM[toULength - 1]) {
|
||||
// we do not have a BOM (and we have toULength bytes)
|
||||
actualBOM = null;
|
||||
actualEndianXOR = endianXOR;
|
||||
break;
|
||||
} else if (toULength == SIGNATURE_LENGTH) {
|
||||
// we found a BOM! at last!
|
||||
// too bad we have to get ignore it now (like it was unwanted or something)
|
||||
toULength = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
isBOMReadYet = true;
|
||||
}
|
||||
|
||||
// now that we no longer need to look for a BOM, let's do some work
|
||||
|
||||
// if we have unfinished business
|
||||
if (toUnicodeStatus != 0) {
|
||||
CoderResult cr = decodeTrail(source, target, offsets, (char) toUnicodeStatus);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
}
|
||||
|
||||
char char16;
|
||||
|
||||
while (true) {
|
||||
while (toULength < 2) {
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
toUBytesArray[toULength++] = source.get();
|
||||
}
|
||||
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
char16 = (char) (((toUBytesArray[0 ^ actualEndianXOR] & UConverterConstants.UNSIGNED_BYTE_MASK) << 8) | ((toUBytesArray[1 ^ actualEndianXOR] & UConverterConstants.UNSIGNED_BYTE_MASK)));
|
||||
|
||||
if (!UTF16.isSurrogate(char16)) {
|
||||
toULength = 0;
|
||||
target.put(char16);
|
||||
} else {
|
||||
CoderResult cr = decodeTrail(source, target, offsets, char16);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final CoderResult decodeTrail(ByteBuffer source, CharBuffer target, IntBuffer offsets, char lead) {
|
||||
if (!UTF16.isLeadSurrogate(lead)) {
|
||||
// 2 bytes, lead malformed
|
||||
toUnicodeStatus = 0;
|
||||
return CoderResult.malformedForLength(2);
|
||||
}
|
||||
|
||||
while (toULength < 4) {
|
||||
if (!source.hasRemaining()) {
|
||||
// let this be unfinished business
|
||||
toUnicodeStatus = lead;
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
toUBytesArray[toULength++] = source.get();
|
||||
}
|
||||
|
||||
char trail = (char) (((toUBytesArray[2 ^ actualEndianXOR] & UConverterConstants.UNSIGNED_BYTE_MASK) << 8) | ((toUBytesArray[3 ^ actualEndianXOR] & UConverterConstants.UNSIGNED_BYTE_MASK)));
|
||||
|
||||
if (!UTF16.isTrailSurrogate(trail)) {
|
||||
// pretend like we didnt read the last 2 bytes
|
||||
toULength = 2;
|
||||
source.position(source.position() - 2);
|
||||
|
||||
// 2 bytes, lead malformed
|
||||
toUnicodeStatus = 0;
|
||||
return CoderResult.malformedForLength(2);
|
||||
}
|
||||
|
||||
toUnicodeStatus = 0;
|
||||
toULength = 0;
|
||||
|
||||
target.put(lead);
|
||||
|
||||
if (target.hasRemaining()) {
|
||||
target.put(trail);
|
||||
return null;
|
||||
} else {
|
||||
/* Put in overflow buffer (not handled here) */
|
||||
charErrorBufferArray[0] = trail;
|
||||
charErrorBufferLength = 1;
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CharsetEncoderUTF16 extends CharsetEncoderICU {
|
||||
private final byte[] temp = new byte[4];
|
||||
|
||||
public CharsetEncoderUTF16(CharsetICU cs) {
|
||||
super(cs, fromUSubstitution);
|
||||
fromUnicodeStatus = isEndianSpecified ? 0 : NEED_TO_WRITE_BOM;
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
fromUnicodeStatus = isEndianSpecified ? 0 : NEED_TO_WRITE_BOM;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
|
||||
CoderResult cr;
|
||||
|
||||
/* write the BOM if necessary */
|
||||
if (fromUnicodeStatus == NEED_TO_WRITE_BOM) {
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
fromUnicodeStatus = 0;
|
||||
cr = fromUWriteBytes(this, bom, 0, bom.length, target, offsets, -1);
|
||||
if (cr.isOverflow())
|
||||
return cr;
|
||||
}
|
||||
|
||||
if (fromUChar32 != 0) {
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
// a note: fromUChar32 will either be 0 or a lead surrogate
|
||||
cr = encodeChar(source, target, offsets, (char) fromUChar32);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
cr = encodeChar(source, target, offsets, source.get());
|
||||
if (cr != null)
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
private final CoderResult encodeChar(CharBuffer source, ByteBuffer target, IntBuffer offsets, char ch) {
|
||||
int sourceIndex = source.position() - 1;
|
||||
CoderResult cr;
|
||||
|
||||
if (UTF16.isSurrogate(ch)) {
|
||||
cr = handleSurrogates(source, ch);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
|
||||
char trail = UTF16.getTrailSurrogate(fromUChar32);
|
||||
fromUChar32 = 0;
|
||||
|
||||
// 4 bytes
|
||||
temp[0 ^ endianXOR] = (byte) (ch >>> 8);
|
||||
temp[1 ^ endianXOR] = (byte) (ch);
|
||||
temp[2 ^ endianXOR] = (byte) (trail >>> 8);
|
||||
temp[3 ^ endianXOR] = (byte) (trail);
|
||||
cr = fromUWriteBytes(this, temp, 0, 4, target, offsets, sourceIndex);
|
||||
} else {
|
||||
// 2 bytes
|
||||
temp[0 ^ endianXOR] = (byte) (ch >>> 8);
|
||||
temp[1 ^ endianXOR] = (byte) (ch);
|
||||
cr = fromUWriteBytes(this, temp, 0, 2, target, offsets, sourceIndex);
|
||||
}
|
||||
return (cr.isUnderflow() ? null : cr);
|
||||
}
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new CharsetDecoderUTF16(this);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new CharsetEncoderUTF16(this);
|
||||
}
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
getNonSurrogateUnicodeSet(setFillIn);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
/**
|
||||
* The purpose of this class is to set isBigEndian to true and isEndianSpecified to true in the super class, and to
|
||||
* allow the Charset framework to open the variant UTF-16 converter without extra setup work.
|
||||
*/
|
||||
class CharsetUTF16BE extends CharsetUTF16 {
|
||||
public CharsetUTF16BE(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
/**
|
||||
* The purpose of this class is to set isBigEndian to false and isEndianSpecified to true in the super class, and to
|
||||
* allow the Charset framework to open the variant UTF-16 converter without extra setup work.
|
||||
*/
|
||||
class CharsetUTF16LE extends CharsetUTF16 {
|
||||
public CharsetUTF16LE(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
}
|
||||
}
|
251
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF32.java
Normal file
251
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF32.java
Normal file
|
@ -0,0 +1,251 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* @author Niti Hantaweepant
|
||||
*/
|
||||
class CharsetUTF32 extends CharsetICU {
|
||||
|
||||
private static final int SIGNATURE_LENGTH = 4;
|
||||
private static final byte[] fromUSubstitution_BE = { (byte) 0, (byte) 0, (byte) 0xff, (byte) 0xfd };
|
||||
private static final byte[] fromUSubstitution_LE = { (byte) 0xfd, (byte) 0xff, (byte) 0, (byte) 0 };
|
||||
private static final byte[] BOM_BE = { 0, 0, (byte) 0xfe, (byte) 0xff };
|
||||
private static final byte[] BOM_LE = { (byte) 0xff, (byte) 0xfe, 0, 0 };
|
||||
private static final int ENDIAN_XOR_BE = 0;
|
||||
private static final int ENDIAN_XOR_LE = 3;
|
||||
private static final int NEED_TO_WRITE_BOM = 1;
|
||||
|
||||
private boolean isEndianSpecified;
|
||||
private boolean isBigEndian;
|
||||
private int endianXOR;
|
||||
private byte[] bom;
|
||||
private byte[] fromUSubstitution;
|
||||
|
||||
public CharsetUTF32(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
|
||||
this.isEndianSpecified = (this instanceof CharsetUTF32BE || this instanceof CharsetUTF32LE);
|
||||
this.isBigEndian = !(this instanceof CharsetUTF32LE);
|
||||
|
||||
if (isBigEndian) {
|
||||
this.bom = BOM_BE;
|
||||
this.fromUSubstitution = fromUSubstitution_BE;
|
||||
this.endianXOR = ENDIAN_XOR_BE;
|
||||
} else {
|
||||
this.bom = BOM_LE;
|
||||
this.fromUSubstitution = fromUSubstitution_LE;
|
||||
this.endianXOR = ENDIAN_XOR_LE;
|
||||
}
|
||||
|
||||
maxBytesPerChar = 4;
|
||||
minBytesPerChar = 4;
|
||||
maxCharsPerByte = 1;
|
||||
}
|
||||
|
||||
class CharsetDecoderUTF32 extends CharsetDecoderICU {
|
||||
|
||||
private boolean isBOMReadYet;
|
||||
private int actualEndianXOR;
|
||||
private byte[] actualBOM;
|
||||
|
||||
public CharsetDecoderUTF32(CharsetICU cs) {
|
||||
super(cs);
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
isBOMReadYet = false;
|
||||
actualBOM = null;
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
|
||||
/*
|
||||
* If we detect a BOM in this buffer, then we must add the BOM size to the offsets because the actual
|
||||
* converter function will not see and count the BOM. offsetDelta will have the number of the BOM bytes that
|
||||
* are in the current buffer.
|
||||
*/
|
||||
if (!isBOMReadYet) {
|
||||
while (true) {
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
|
||||
toUBytesArray[toULength++] = source.get();
|
||||
|
||||
if (toULength == 1) {
|
||||
// on the first byte, we haven't decided whether or not it's bigEndian yet
|
||||
if ((!isEndianSpecified || isBigEndian)
|
||||
&& toUBytesArray[toULength - 1] == BOM_BE[toULength - 1]) {
|
||||
actualBOM = BOM_BE;
|
||||
actualEndianXOR = ENDIAN_XOR_BE;
|
||||
} else if ((!isEndianSpecified || !isBigEndian)
|
||||
&& toUBytesArray[toULength - 1] == BOM_LE[toULength - 1]) {
|
||||
actualBOM = BOM_LE;
|
||||
actualEndianXOR = ENDIAN_XOR_LE;
|
||||
} else {
|
||||
// we do not have a BOM (and we have toULength==1 bytes)
|
||||
actualBOM = null;
|
||||
actualEndianXOR = endianXOR;
|
||||
break;
|
||||
}
|
||||
} else if (toUBytesArray[toULength - 1] != actualBOM[toULength - 1]) {
|
||||
// we do not have a BOM (and we have toULength bytes)
|
||||
actualBOM = null;
|
||||
actualEndianXOR = endianXOR;
|
||||
break;
|
||||
} else if (toULength == SIGNATURE_LENGTH) {
|
||||
// we found a BOM! at last!
|
||||
// too bad we have to get ignore it now (like it was unwanted or something)
|
||||
toULength = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
isBOMReadYet = true;
|
||||
}
|
||||
|
||||
// now that we no longer need to look for a BOM, let's do some work
|
||||
int char32;
|
||||
|
||||
while (true) {
|
||||
while (toULength < 4) {
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
toUBytesArray[toULength++] = source.get();
|
||||
}
|
||||
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
char32 = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
char32 = (char32 << 8)
|
||||
| (toUBytesArray[i ^ actualEndianXOR] & UConverterConstants.UNSIGNED_BYTE_MASK);
|
||||
|
||||
if (0 <= char32 && char32 <= UConverterConstants.MAXIMUM_UTF && !isSurrogate(char32)) {
|
||||
toULength = 0;
|
||||
if (char32 <= UConverterConstants.MAXIMUM_UCS2) {
|
||||
/* fits in 16 bits */
|
||||
target.put((char) char32);
|
||||
} else {
|
||||
/* write out the surrogates */
|
||||
target.put(UTF16.getLeadSurrogate(char32));
|
||||
char32 = UTF16.getTrailSurrogate(char32);
|
||||
if (target.hasRemaining()) {
|
||||
target.put((char) char32);
|
||||
} else {
|
||||
/* Put in overflow buffer (not handled here) */
|
||||
charErrorBufferArray[0] = (char) char32;
|
||||
charErrorBufferLength = 1;
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return CoderResult.malformedForLength(toULength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CharsetEncoderUTF32 extends CharsetEncoderICU {
|
||||
private final byte[] temp = new byte[4];
|
||||
|
||||
public CharsetEncoderUTF32(CharsetICU cs) {
|
||||
super(cs, fromUSubstitution);
|
||||
fromUnicodeStatus = isEndianSpecified ? 0 : NEED_TO_WRITE_BOM;
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
fromUnicodeStatus = isEndianSpecified ? 0 : NEED_TO_WRITE_BOM;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
|
||||
CoderResult cr;
|
||||
|
||||
/* write the BOM if necessary */
|
||||
if (fromUnicodeStatus == NEED_TO_WRITE_BOM) {
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
fromUnicodeStatus = 0;
|
||||
cr = fromUWriteBytes(this, bom, 0, bom.length, target, offsets, -1);
|
||||
if (cr.isOverflow())
|
||||
return cr;
|
||||
}
|
||||
|
||||
if (fromUChar32 != 0) {
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
// a note: fromUChar32 will either be 0 or a lead surrogate
|
||||
cr = encodeChar(source, target, offsets, (char) fromUChar32);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (!source.hasRemaining())
|
||||
return CoderResult.UNDERFLOW;
|
||||
if (!target.hasRemaining())
|
||||
return CoderResult.OVERFLOW;
|
||||
|
||||
cr = encodeChar(source, target, offsets, source.get());
|
||||
if (cr != null)
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
private final CoderResult encodeChar(CharBuffer source, ByteBuffer target, IntBuffer offsets, char ch) {
|
||||
int sourceIndex = source.position() - 1;
|
||||
CoderResult cr;
|
||||
int char32;
|
||||
|
||||
if (UTF16.isSurrogate(ch)) {
|
||||
cr = handleSurrogates(source, ch);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
|
||||
char32 = fromUChar32;
|
||||
fromUChar32 = 0;
|
||||
} else {
|
||||
char32 = ch;
|
||||
}
|
||||
|
||||
/* We cannot get any larger than 10FFFF because we are coming from UTF-16 */
|
||||
// temp[0 ^ endianXOR] = (byte) (char32 >>> 24); // (always 0)
|
||||
temp[1 ^ endianXOR] = (byte) (char32 >>> 16); // same as (byte)((char32 >>> 16) & 0x1f)
|
||||
temp[2 ^ endianXOR] = (byte) (char32 >>> 8);
|
||||
temp[3 ^ endianXOR] = (byte) (char32);
|
||||
cr = fromUWriteBytes(this, temp, 0, 4, target, offsets, sourceIndex);
|
||||
return (cr.isUnderflow() ? null : cr);
|
||||
}
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new CharsetDecoderUTF32(this);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new CharsetEncoderUTF32(this);
|
||||
}
|
||||
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
getNonSurrogateUnicodeSet(setFillIn);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
/**
|
||||
* The purpose of this class is to set isBigEndian to true and isEndianSpecified to true in the super class, and to
|
||||
* allow the Charset framework to open the variant UTF-32 converter without extra setup work.
|
||||
*/
|
||||
class CharsetUTF32BE extends CharsetUTF32 {
|
||||
public CharsetUTF32BE(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
/**
|
||||
* The purpose of this class is to set isBigEndian to false and isEndianSpecified to true in the super class, and to
|
||||
* allow the Charset framework to open the variant UTF-32 converter without extra setup work.
|
||||
*/
|
||||
class CharsetUTF32LE extends CharsetUTF32 {
|
||||
public CharsetUTF32LE(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
}
|
||||
}
|
756
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF7.java
Normal file
756
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF7.java
Normal file
|
@ -0,0 +1,756 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007-2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* @author Michael Ow
|
||||
*
|
||||
*/
|
||||
class CharsetUTF7 extends CharsetICU {
|
||||
private final String IMAP_NAME="IMAP-mailbox-name";
|
||||
private boolean useIMAP;
|
||||
protected byte[] fromUSubstitution=new byte[]{0x3F};
|
||||
|
||||
public CharsetUTF7(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
maxBytesPerChar=4; /* max 3 bytes per code unit from UTF-7 (base64) */
|
||||
minBytesPerChar=1;
|
||||
maxCharsPerByte=1;
|
||||
|
||||
useIMAP=false;
|
||||
|
||||
if (icuCanonicalName.equals(IMAP_NAME)) {
|
||||
useIMAP=true;
|
||||
}
|
||||
}
|
||||
|
||||
//private static boolean inSetD(char c) {
|
||||
// return (
|
||||
// (char)(c - 97) < 26 || (char)(c - 65) < 26 || /* letters */
|
||||
// (char)(c - 48) < 10 || /* digits */
|
||||
// (char)(c - 39) < 3 || /* ' () */
|
||||
// (char)(c - 44) < 4 || /* ,-./ */
|
||||
// (c==58) || (c==63) /* :? */
|
||||
// );
|
||||
//}
|
||||
|
||||
//private static boolean inSetO(char c) {
|
||||
// return (
|
||||
// (char)(c - 33) < 6 || /* !"#$%& */
|
||||
// (char)(c - 59) < 4 || /* ;<=> */
|
||||
// (char)(c - 93) < 4 || /* ]^_` */
|
||||
// (char)(c - 123) < 3 || /* {|} */
|
||||
// (c==58) || (c==63) /* *@[ */
|
||||
// );
|
||||
//}
|
||||
|
||||
private static boolean isCRLFTAB(char c) {
|
||||
return (
|
||||
(c==13) || (c==10) || (c==9)
|
||||
);
|
||||
}
|
||||
|
||||
//private static boolean isCRLFSPTAB(char c) {
|
||||
// return (
|
||||
// (c==32) || (c==13) || (c==10) || (c==9)
|
||||
// );
|
||||
//}
|
||||
|
||||
private static final byte PLUS=43;
|
||||
private static final byte MINUS=45;
|
||||
private static final byte BACKSLASH=92;
|
||||
//private static final byte TILDE=126;
|
||||
private static final byte AMPERSAND=0x26;
|
||||
private static final byte COMMA=0x2c;
|
||||
private static final byte SLASH=0x2f;
|
||||
|
||||
// legal byte values: all US-ASCII graphic characters 0x20..0x7e
|
||||
private static boolean isLegal(char c, boolean useIMAP) {
|
||||
if (useIMAP) {
|
||||
return (
|
||||
(0x20 <= c) && (c <= 0x7e)
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
((char)(c - 32) < 94 && (c != BACKSLASH)) || isCRLFTAB(c)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// directly encode all of printable ASCII 0x20..0x7e except '&' 0x26
|
||||
private static boolean inSetDIMAP(char c) {
|
||||
return (
|
||||
(isLegal(c, true) && c != AMPERSAND)
|
||||
);
|
||||
}
|
||||
|
||||
private static byte TO_BASE64_IMAP(int n) {
|
||||
return (n < 63 ? TO_BASE_64[n] : COMMA);
|
||||
}
|
||||
|
||||
private static byte FROM_BASE64_IMAP(char c) {
|
||||
return (c==COMMA ? 63 : c==SLASH ? -1 : FROM_BASE_64[c]);
|
||||
}
|
||||
|
||||
/* encode directly sets D and O and CR LF SP TAB */
|
||||
private static final byte ENCODE_DIRECTLY_MAXIMUM[] =
|
||||
{
|
||||
/*0 1 2 3 4 5 6 7 8 9 a b c d e f*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
|
||||
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0
|
||||
};
|
||||
|
||||
/* encode directly set D and CR LF SP TAB but not set O */
|
||||
private static final byte ENCODE_DIRECTLY_RESTRICTED[] =
|
||||
{
|
||||
/*0 1 2 3 4 5 6 7 8 9 a b c d e f*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
|
||||
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
private static final byte TO_BASE_64[] =
|
||||
{
|
||||
/* A-Z */
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
|
||||
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
|
||||
/* a-z */
|
||||
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
|
||||
110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122,
|
||||
/* 0-9 */
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
|
||||
/* +/ */
|
||||
43, 47
|
||||
};
|
||||
|
||||
private static final byte FROM_BASE_64[] =
|
||||
{
|
||||
/* C0 controls, -1 for legal ones (CR LF TAB), -3 for illegal ones */
|
||||
-3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3,
|
||||
-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
|
||||
/* general punctuation with + and / and a special value (-2) for - */
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -2, -1, 63,
|
||||
/* digits */
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||
/* A-Z */
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -3, -1, -1, -1,
|
||||
/* a-z*/
|
||||
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -3, -3
|
||||
};
|
||||
|
||||
class CharsetDecoderUTF7 extends CharsetDecoderICU {
|
||||
public CharsetDecoderUTF7(CharsetICU cs) {
|
||||
super(cs);
|
||||
implReset();
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
toUnicodeStatus=(toUnicodeStatus & 0xf0000000) | 0x1000000;
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets, boolean flush) {
|
||||
CoderResult cr=CoderResult.UNDERFLOW;
|
||||
byte base64Value;
|
||||
byte base64Counter;
|
||||
byte inDirectMode;
|
||||
char bits;
|
||||
int byteIndex;
|
||||
int sourceIndex, nextSourceIndex;
|
||||
|
||||
int length;
|
||||
|
||||
char b;
|
||||
char c;
|
||||
|
||||
int sourceArrayIndex=source.position();
|
||||
|
||||
//get the state of the machine state
|
||||
{
|
||||
int status=toUnicodeStatus;
|
||||
inDirectMode=(byte)((status >> 24) & 1);
|
||||
base64Counter=(byte)(status >> 16);
|
||||
bits=(char)status;
|
||||
}
|
||||
byteIndex=toULength;
|
||||
/* sourceIndex=-1 if the current character began in the previous buffer */
|
||||
sourceIndex=byteIndex==0 ? 0 : -1;
|
||||
nextSourceIndex=0;
|
||||
|
||||
directMode: while (true) {
|
||||
if (inDirectMode==1) {
|
||||
/*
|
||||
* In Direct Mode, most US-ASCII characters are encoded directly, i.e.,
|
||||
* with their US-ASCII byte values.
|
||||
* Backslash and Tilde and most control characters are not alled in UTF-7.
|
||||
* A plus sign starts Unicode (or "escape") Mode.
|
||||
* An ampersand starts Unicode Mode for IMAP.
|
||||
*
|
||||
* In Direct Mode, only the sourceIndex is used.
|
||||
*/
|
||||
byteIndex=0;
|
||||
length=source.remaining();
|
||||
//targetCapacity=target.remaining();
|
||||
//Commented out because length of source may be larger than target when it comes to bytes
|
||||
/*if (useIMAP && length > targetCapacity) {
|
||||
length=targetCapacity;
|
||||
}*/
|
||||
while (length > 0) {
|
||||
b=(char)(source.get());
|
||||
sourceArrayIndex++;
|
||||
if (!isLegal(b, useIMAP)) {
|
||||
toUBytesArray[0]=(byte)b;
|
||||
byteIndex=1;
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
break;
|
||||
} else if ((!useIMAP && b!=PLUS) || (useIMAP && b!=AMPERSAND)) {
|
||||
// write directly encoded character
|
||||
if (target.hasRemaining()) { // Check to make sure that there is room in target.
|
||||
target.put(b);
|
||||
if (offsets!= null) {
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
} else { // Get out and set the CoderResult.
|
||||
break;
|
||||
}
|
||||
} else { /* PLUS or (AMPERSAND in IMAP)*/
|
||||
/* switch to Unicode mode */
|
||||
nextSourceIndex=++sourceIndex;
|
||||
inDirectMode=0;
|
||||
byteIndex=0;
|
||||
bits=0;
|
||||
base64Counter=-1;
|
||||
continue directMode;
|
||||
}
|
||||
--length;
|
||||
}//end of while
|
||||
if (source.hasRemaining() && target.position() >= target.limit()) {
|
||||
/* target is full */
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
break directMode;
|
||||
} else { /* Unicode Mode*/
|
||||
/*
|
||||
* In Unicode Mode, UTF-16BE is base64-encoded.
|
||||
* The base64 sequence ends with any character that is not in the base64 alphabet.
|
||||
* A terminating minus sign is consumed.
|
||||
*
|
||||
* In Unicode Mode, the sourceIndex has the index to the start of the current
|
||||
* base64 bytes, while nextSourceIndex is precisely parallel to source,
|
||||
* keeping the index to the following byte.
|
||||
*/
|
||||
while(source.hasRemaining()) {
|
||||
if (target.hasRemaining()) {
|
||||
b=(char)source.get();
|
||||
sourceArrayIndex++;
|
||||
toUBytesArray[byteIndex++]=(byte)b;
|
||||
if ((!useIMAP && b>=126) || (useIMAP && b>0x7e)) {
|
||||
/* illegal - test other illegal US-ASCII values by base64Value==-3 */
|
||||
inDirectMode=1;
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
break directMode;
|
||||
} else if (((base64Value=FROM_BASE_64[b])>=0 && !useIMAP) || ((base64Value=FROM_BASE64_IMAP(b))>=0) && useIMAP) {
|
||||
/* collect base64 bytes */
|
||||
switch (base64Counter) {
|
||||
case -1: /* -1 is immediately after the + */
|
||||
case 0:
|
||||
bits=(char)base64Value;
|
||||
base64Counter=1;
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
case 4:
|
||||
case 6:
|
||||
bits=(char)((bits<<6) | base64Value);
|
||||
++base64Counter;
|
||||
break;
|
||||
case 2:
|
||||
c=(char)((bits<<4) | (base64Value>>2));
|
||||
if (useIMAP && isLegal(c, useIMAP)) {
|
||||
// illegal
|
||||
inDirectMode=1;
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
// goto endloop;
|
||||
break directMode;
|
||||
}
|
||||
target.put(c);
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex);
|
||||
sourceIndex=nextSourceIndex - 1;
|
||||
}
|
||||
toUBytesArray[0]=(byte)b; /* keep this byte in case an error occurs */
|
||||
byteIndex=1;
|
||||
bits=(char)(base64Value&3);
|
||||
base64Counter=3;
|
||||
break;
|
||||
case 5:
|
||||
c=(char)((bits<<2) | (base64Value>>4));
|
||||
if(useIMAP && isLegal(c, useIMAP)) {
|
||||
// illegal
|
||||
inDirectMode=1;
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
// goto endloop;
|
||||
break directMode;
|
||||
}
|
||||
target.put(c);
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex);
|
||||
sourceIndex=nextSourceIndex - 1;
|
||||
}
|
||||
toUBytesArray[0]=(byte)b; /* keep this byte in case an error occurs */
|
||||
byteIndex=1;
|
||||
bits=(char)(base64Value&15);
|
||||
base64Counter=6;
|
||||
break;
|
||||
case 7:
|
||||
c=(char)((bits<<6) | base64Value);
|
||||
if (useIMAP && isLegal(c, useIMAP)) {
|
||||
// illegal
|
||||
inDirectMode=1;
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
// goto endloop;
|
||||
break directMode;
|
||||
}
|
||||
target.put(c);
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex);
|
||||
sourceIndex=nextSourceIndex;
|
||||
}
|
||||
byteIndex=0;
|
||||
bits=0;
|
||||
base64Counter=0;
|
||||
break;
|
||||
//default:
|
||||
/* will never occur */
|
||||
//break;
|
||||
}//end of switch
|
||||
} else if (base64Value==-2) {
|
||||
/* minus sign terminates the base64 sequence */
|
||||
inDirectMode=1;
|
||||
if (base64Counter==-1) {
|
||||
/* +- i.e. a minus immediately following a plus */
|
||||
target.put(useIMAP ? (char)AMPERSAND : (char)PLUS);
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex - 1);
|
||||
}
|
||||
} else {
|
||||
/* absorb the minus and leave the Unicode Mode */
|
||||
if (bits!=0 || (useIMAP && base64Counter!=0 && base64Counter!=3 && base64Counter!=6)) {
|
||||
/*bits are illegally left over, a unicode character is incomplete */
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sourceIndex=nextSourceIndex;
|
||||
continue directMode;
|
||||
} else if (!useIMAP && base64Value==-1) { /* for any legal character except base64 and minus sign */
|
||||
/* leave the Unicode Mode */
|
||||
inDirectMode=1;
|
||||
if (base64Counter==-1) {
|
||||
/* illegal: + immediately followed by something other than base64 minus sign */
|
||||
/* include the plus sign in the reported sequence */
|
||||
--sourceIndex;
|
||||
toUBytesArray[0]=PLUS;
|
||||
toUBytesArray[1]=(byte)b;
|
||||
byteIndex=2;
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
break;
|
||||
} else if (bits==0) {
|
||||
/* un-read the character in case it is a plus sign */
|
||||
source.position(--sourceArrayIndex);
|
||||
sourceIndex=nextSourceIndex - 1;
|
||||
continue directMode;
|
||||
} else {
|
||||
/* bits are illegally left over, a unicode character is incomplete */
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (useIMAP && base64Counter==-1) {
|
||||
// illegal: & immediately followed by something other than base64 or minus sign
|
||||
// include the ampersand in the reported sequence
|
||||
--sourceIndex;
|
||||
toUBytesArray[0]=AMPERSAND;
|
||||
toUBytesArray[1]=(byte)b;
|
||||
byteIndex=2;
|
||||
}
|
||||
/* base64Value==-3 for illegal characters */
|
||||
/* illegal */
|
||||
inDirectMode=1;
|
||||
cr=CoderResult.malformedForLength(sourceArrayIndex);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* target is full */
|
||||
cr=CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
} //end of while
|
||||
break directMode;
|
||||
}
|
||||
}//end of direct mode label
|
||||
if (useIMAP) {
|
||||
if (!cr.isError() && inDirectMode==0 && flush && byteIndex==0 && !source.hasRemaining()) {
|
||||
if (base64Counter==-1) {
|
||||
/* & at the very end of the input */
|
||||
/* make the ampersand the reported sequence */
|
||||
toUBytesArray[0]=AMPERSAND;
|
||||
byteIndex=1;
|
||||
}
|
||||
/* else if (base64Counter!=-1) byteIndex remains 0 because ther is no particular byte sequence */
|
||||
inDirectMode=1;
|
||||
cr=CoderResult.malformedForLength(sourceIndex);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!cr.isError() && flush && !source.hasRemaining() && bits ==0) {
|
||||
/*
|
||||
* if we are in Unicode Mode, then the byteIndex might not be 0,
|
||||
* but that is ok if bits -- 0
|
||||
* -> we set byteIndex=0 at the end of the stream to avoid a truncated error
|
||||
* (not true for IMAP-mailbox-name where we must end in direct mode)
|
||||
*/
|
||||
if (!cr.isOverflow()) {
|
||||
byteIndex=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* set the converter state */
|
||||
toUnicodeStatus=(inDirectMode<<24 | (((short)base64Counter & UConverterConstants.UNSIGNED_BYTE_MASK)<<16) | (int)bits);
|
||||
toULength=byteIndex;
|
||||
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
class CharsetEncoderUTF7 extends CharsetEncoderICU {
|
||||
public CharsetEncoderUTF7(CharsetICU cs) {
|
||||
super(cs, fromUSubstitution);
|
||||
implReset();
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
fromUnicodeStatus=(fromUnicodeStatus & 0xf0000000) | 0x1000000;
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets, boolean flush) {
|
||||
CoderResult cr=CoderResult.UNDERFLOW;
|
||||
byte inDirectMode;
|
||||
byte encodeDirectly[];
|
||||
int status;
|
||||
|
||||
int length, targetCapacity, sourceIndex;
|
||||
|
||||
byte base64Counter;
|
||||
char bits;
|
||||
char c;
|
||||
char b;
|
||||
/* get the state machine state */
|
||||
{
|
||||
status=fromUnicodeStatus;
|
||||
encodeDirectly=(((long)status) < 0x10000000) ? ENCODE_DIRECTLY_MAXIMUM : ENCODE_DIRECTLY_RESTRICTED;
|
||||
inDirectMode=(byte)((status >> 24) & 1);
|
||||
base64Counter=(byte)(status >> 16);
|
||||
bits=(char)((byte)status);
|
||||
}
|
||||
/* UTF-7 always encodes UTF-16 code units, therefore we need only a simple sourceIndex */
|
||||
sourceIndex=0;
|
||||
|
||||
directMode: while(true) {
|
||||
if(inDirectMode==1) {
|
||||
length=source.remaining();
|
||||
targetCapacity=target.remaining();
|
||||
if(length > targetCapacity) {
|
||||
length=targetCapacity;
|
||||
}
|
||||
while (length > 0) {
|
||||
c=source.get();
|
||||
/* UTF7: currently always encode CR LF SP TAB directly */
|
||||
/* IMAP: encode 0x20..0x7e except '&' directly */
|
||||
if ((!useIMAP && c<=127 && encodeDirectly[c]==1) || (useIMAP && inSetDIMAP(c))) {
|
||||
/* encode directly */
|
||||
target.put((byte)c);
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
} else if ((!useIMAP && c==PLUS) || (useIMAP && c==AMPERSAND)) {
|
||||
/* IMAP: output &- for & */
|
||||
/* UTF-7: output +- for + */
|
||||
target.put(useIMAP ? AMPERSAND : PLUS);
|
||||
if (target.hasRemaining()) {
|
||||
target.put(MINUS);
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
/* realign length and targetCapacity */
|
||||
continue directMode;
|
||||
} else {
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
errorBuffer[0]=MINUS;
|
||||
errorBufferLength=1;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* un-read this character and switch to unicode mode */
|
||||
source.position(source.position() - 1);
|
||||
target.put(useIMAP ? AMPERSAND : PLUS);
|
||||
if (offsets != null) {
|
||||
offsets.put(sourceIndex);
|
||||
}
|
||||
inDirectMode=0;
|
||||
base64Counter=0;
|
||||
continue directMode;
|
||||
}
|
||||
--length;
|
||||
} //end of while
|
||||
if (source.hasRemaining() && !target.hasRemaining()) {
|
||||
/* target is full */
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
break directMode;
|
||||
} else {
|
||||
/* Unicode Mode */
|
||||
while (source.hasRemaining()) {
|
||||
if (target.hasRemaining()) {
|
||||
c=source.get();
|
||||
if ((!useIMAP && c<=127 && encodeDirectly[c]==1) || (useIMAP && isLegal(c, useIMAP))) {
|
||||
/* encode directly */
|
||||
inDirectMode=1;
|
||||
|
||||
/* trick: back out this character to make this easier */
|
||||
source.position(source.position() - 1);
|
||||
|
||||
/* terminate the base64 sequence */
|
||||
if (base64Counter!=0) {
|
||||
/* write remaining bits for the previous character */
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits]);
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex-1);
|
||||
}
|
||||
}
|
||||
if (FROM_BASE_64[c]!=-1 || useIMAP) {
|
||||
/* need to terminate with a minus */
|
||||
if (target.hasRemaining()) {
|
||||
target.put(MINUS);
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex-1);
|
||||
}
|
||||
} else {
|
||||
errorBuffer[0]=MINUS;
|
||||
errorBufferLength=1;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue directMode;
|
||||
} else {
|
||||
/*
|
||||
* base64 this character:
|
||||
* Output 2 or 3 base64 bytres for the remaining bits of the previous character
|
||||
* and the bits of this character, each implicitly in UTF-16BE.
|
||||
*
|
||||
* Here, bits is an 8-bit variable because only 6 bits need to be kept from one
|
||||
* character to the next. The actual 2 or 4 bits are shifted to the left edge
|
||||
* of the 6-bits filed 5..0 to make the termination of the base64 sequence easier.
|
||||
*/
|
||||
switch (base64Counter) {
|
||||
case 0:
|
||||
b=(char)(c>>10);
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (target.hasRemaining()) {
|
||||
b=(char)((c>>4)&0x3f);
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
} else {
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
b=(char)((c>>4)&0x3f);
|
||||
errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
|
||||
errorBufferLength=1;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
bits=(char)((c&15)<<2);
|
||||
base64Counter=1;
|
||||
break;
|
||||
case 1:
|
||||
b=(char)(bits|(c>>14));
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (target.hasRemaining()) {
|
||||
b=(char)((c>>8)&0x3f);
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (target.hasRemaining()) {
|
||||
b=(char)((c>>2)&0x3f);
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
} else {
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
b=(char)((c>>2)&0x3f);
|
||||
errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
|
||||
errorBufferLength=1;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
} else {
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
b=(char)((c>>8)&0x3f);
|
||||
errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
|
||||
b=(char)((c>>2)&0x3f);
|
||||
errorBuffer[1]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
|
||||
errorBufferLength=2;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
bits=(char)((c&3)<<4);
|
||||
base64Counter=2;
|
||||
break;
|
||||
case 2:
|
||||
b=(char)(bits|(c>>12));
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (target.hasRemaining()) {
|
||||
b=(char)((c>>6)&0x3f);
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (target.hasRemaining()) {
|
||||
b=(char)(c&0x3f);
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b]);
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
} else {
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex);
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
b=(char)(c&0x3f);
|
||||
errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
|
||||
errorBufferLength=1;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
} else {
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex++);
|
||||
}
|
||||
b=(char)((c>>6)&0x3f);
|
||||
errorBuffer[0]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
|
||||
b=(char)(c&0x3f);
|
||||
errorBuffer[1]=useIMAP ? TO_BASE64_IMAP(b) : TO_BASE_64[b];
|
||||
errorBufferLength=2;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
bits=0;
|
||||
base64Counter=0;
|
||||
break;
|
||||
//default:
|
||||
/* will never occur */
|
||||
//break;
|
||||
} //end of switch
|
||||
}
|
||||
} else {
|
||||
/* target is full */
|
||||
cr=CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
} //end of while
|
||||
break directMode;
|
||||
}
|
||||
} //end of directMode label
|
||||
|
||||
if (flush && !source.hasRemaining()) {
|
||||
/* flush remaining bits to the target */
|
||||
if (inDirectMode==0) {
|
||||
if (base64Counter!=0) {
|
||||
if (target.hasRemaining()) {
|
||||
target.put(useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits]);
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex - 1);
|
||||
}
|
||||
} else {
|
||||
errorBuffer[errorBufferLength++]=useIMAP ? TO_BASE64_IMAP(bits) : TO_BASE_64[bits];
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
if (useIMAP) {
|
||||
/* IMAP: need to terminate with a minus */
|
||||
if (target.hasRemaining()) {
|
||||
target.put(MINUS);
|
||||
if (offsets!=null) {
|
||||
offsets.put(sourceIndex - 1);
|
||||
}
|
||||
} else {
|
||||
errorBuffer[errorBufferLength++]=MINUS;
|
||||
cr=CoderResult.OVERFLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*reset the state for the next conversion */
|
||||
fromUnicodeStatus=((status&0xf0000000) | 0x1000000); /* keep version, inDirectMode=TRUE */
|
||||
} else {
|
||||
/* set the converter state back */
|
||||
fromUnicodeStatus=((status&0xf0000000) | (inDirectMode<<24) | (((short)base64Counter & UConverterConstants.UNSIGNED_BYTE_MASK)<<16) | ((int)bits));
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new CharsetDecoderUTF7(this);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new CharsetEncoderUTF7(this);
|
||||
}
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
getCompleteUnicodeSet(setFillIn);
|
||||
}
|
||||
}
|
694
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF8.java
Normal file
694
main/classes/charset/src/com/ibm/icu/charset/CharsetUTF8.java
Normal file
|
@ -0,0 +1,694 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
|
||||
/**
|
||||
* @author Niti Hantaweepant
|
||||
*/
|
||||
class CharsetUTF8 extends CharsetICU {
|
||||
|
||||
private static final byte[] fromUSubstitution = new byte[] { (byte) 0xef, (byte) 0xbf, (byte) 0xbd };
|
||||
|
||||
public CharsetUTF8(String icuCanonicalName, String javaCanonicalName, String[] aliases) {
|
||||
super(icuCanonicalName, javaCanonicalName, aliases);
|
||||
/* max 3 bytes per code unit from UTF-8 (4 bytes from surrogate _pair_) */
|
||||
maxBytesPerChar = 3;
|
||||
minBytesPerChar = 1;
|
||||
maxCharsPerByte = 1;
|
||||
}
|
||||
|
||||
private static final int BITMASK_FROM_UTF8[] = { -1, 0x7f, 0x1f, 0xf, 0x7, 0x3, 0x1 };
|
||||
|
||||
private static final byte BYTES_FROM_UTF8[] = {
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Starting with Unicode 3.0.1: UTF-8 byte sequences of length N _must_ encode code points of or
|
||||
* above utf8_minChar32[N]; byte sequences with more than 4 bytes are illegal in UTF-8, which is
|
||||
* tested with impossible values for them
|
||||
*/
|
||||
private static final int UTF8_MIN_CHAR32[] = { 0, 0, 0x80, 0x800, 0x10000,
|
||||
Integer.MAX_VALUE, Integer.MAX_VALUE };
|
||||
|
||||
private final boolean isCESU8 = this instanceof CharsetCESU8;
|
||||
|
||||
class CharsetDecoderUTF8 extends CharsetDecoderICU {
|
||||
|
||||
public CharsetDecoderUTF8(CharsetICU cs) {
|
||||
super(cs);
|
||||
}
|
||||
|
||||
protected CoderResult decodeLoop(ByteBuffer source, CharBuffer target, IntBuffer offsets,
|
||||
boolean flush) {
|
||||
if (!source.hasRemaining()) {
|
||||
/* no input, nothing to do */
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
if (!target.hasRemaining()) {
|
||||
/* no output available, can't do anything */
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
if (source.hasArray() && target.hasArray()) {
|
||||
/* source and target are backed by arrays, so use the arrays for optimal performance */
|
||||
byte[] sourceArray = source.array();
|
||||
int sourceIndex = source.arrayOffset() + source.position();
|
||||
int sourceLimit = source.arrayOffset() + source.limit();
|
||||
char[] targetArray = target.array();
|
||||
int targetIndex = target.arrayOffset() + target.position();
|
||||
int targetLimit = target.arrayOffset() + target.limit();
|
||||
|
||||
byte ch;
|
||||
int char32, bytesExpected, bytesSoFar;
|
||||
CoderResult cr;
|
||||
|
||||
if (mode == 0) {
|
||||
/* nothing is stored in toUnicodeStatus, read a byte as input */
|
||||
char32 = (toUBytesArray[0] = sourceArray[sourceIndex++]) & 0xff;
|
||||
bytesExpected = BYTES_FROM_UTF8[char32];
|
||||
char32 &= BITMASK_FROM_UTF8[bytesExpected];
|
||||
bytesSoFar = 1;
|
||||
} else {
|
||||
/* a partially or fully built code point is stored in toUnicodeStatus */
|
||||
char32 = toUnicodeStatus;
|
||||
bytesExpected = mode;
|
||||
bytesSoFar = toULength;
|
||||
|
||||
toUnicodeStatus = 0;
|
||||
mode = 0;
|
||||
toULength = 0;
|
||||
}
|
||||
|
||||
outer: while (true) {
|
||||
if (bytesSoFar < bytesExpected) {
|
||||
/* read a trail byte and insert its relevant bits into char32 */
|
||||
if (sourceIndex >= sourceLimit) {
|
||||
/* no source left, save the state for later and break out of the loop */
|
||||
toUnicodeStatus = char32;
|
||||
mode = bytesExpected;
|
||||
toULength = bytesSoFar;
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break;
|
||||
}
|
||||
if (((ch = toUBytesArray[bytesSoFar] = sourceArray[sourceIndex++]) & 0xc0) != 0x80) {
|
||||
/* not a trail byte (is not of the form 10xxxxxx) */
|
||||
sourceIndex--;
|
||||
toULength = bytesSoFar;
|
||||
cr = CoderResult.malformedForLength(bytesSoFar);
|
||||
break;
|
||||
}
|
||||
char32 = (char32 << 6) | (ch & 0x3f);
|
||||
bytesSoFar++;
|
||||
} else if (bytesSoFar == bytesExpected && UTF8_MIN_CHAR32[bytesExpected] <= char32 && char32 <= 0x10ffff
|
||||
&& (isCESU8 ? bytesExpected <= 3 : !UTF16.isSurrogate((char) char32))) {
|
||||
/*
|
||||
* char32 is a valid code point and is composed of the correct number of
|
||||
* bytes ... we now need to output it in UTF-16
|
||||
*/
|
||||
|
||||
if (char32 <= UConverterConstants.MAXIMUM_UCS2) {
|
||||
/* fits in 16 bits */
|
||||
targetArray[targetIndex++] = (char) char32;
|
||||
} else {
|
||||
/* fit char32 into 20 bits */
|
||||
char32 -= UConverterConstants.HALF_BASE;
|
||||
|
||||
/* write out the surrogates */
|
||||
targetArray[targetIndex++] = (char) ((char32 >>> UConverterConstants.HALF_SHIFT) + UConverterConstants.SURROGATE_HIGH_START);
|
||||
|
||||
if (targetIndex >= targetLimit) {
|
||||
/* put in overflow buffer (not handled here) */
|
||||
charErrorBufferArray[charErrorBufferBegin++] = (char) char32;
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
targetArray[targetIndex++] = (char) ((char32 & UConverterConstants.HALF_MASK) + UConverterConstants.SURROGATE_LOW_START);
|
||||
}
|
||||
|
||||
/*
|
||||
* we're finished outputing, so now we need to read in the first byte of the
|
||||
* next byte sequence that could form a code point
|
||||
*/
|
||||
|
||||
if (sourceIndex >= sourceLimit) {
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break;
|
||||
}
|
||||
if (targetIndex >= targetLimit) {
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
|
||||
/* keep reading the next input (and writing it) while bytes == 1 */
|
||||
while ((bytesExpected = BYTES_FROM_UTF8[char32 = (toUBytesArray[0] = sourceArray[sourceIndex++]) & 0xff]) == 1) {
|
||||
targetArray[targetIndex++] = (char) char32;
|
||||
if (sourceIndex >= sourceLimit) {
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break outer;
|
||||
}
|
||||
if (targetIndex >= targetLimit) {
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove the bits that indicate the number of bytes */
|
||||
char32 &= BITMASK_FROM_UTF8[bytesExpected];
|
||||
bytesSoFar = 1;
|
||||
} else {
|
||||
/*
|
||||
* either the lead byte in the code sequence is invalid (bytes == 0) or the
|
||||
* lead byte combined with all the trail chars does not form a valid code
|
||||
* point
|
||||
*/
|
||||
toULength = bytesSoFar;
|
||||
cr = CoderResult.malformedForLength(bytesSoFar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
source.position(sourceIndex - source.arrayOffset());
|
||||
target.position(targetIndex - target.arrayOffset());
|
||||
return cr;
|
||||
|
||||
} else {
|
||||
|
||||
int sourceIndex = source.position();
|
||||
int sourceLimit = source.limit();
|
||||
int targetIndex = target.position();
|
||||
int targetLimit = target.limit();
|
||||
|
||||
byte ch;
|
||||
int char32, bytesExpected, bytesSoFar;
|
||||
CoderResult cr;
|
||||
|
||||
if (mode == 0) {
|
||||
/* nothing is stored in toUnicodeStatus, read a byte as input */
|
||||
char32 = (toUBytesArray[0] = source.get(sourceIndex++)) & 0xff;
|
||||
bytesExpected = BYTES_FROM_UTF8[char32];
|
||||
char32 &= BITMASK_FROM_UTF8[bytesExpected];
|
||||
bytesSoFar = 1;
|
||||
} else {
|
||||
/* a partially or fully built code point is stored in toUnicodeStatus */
|
||||
char32 = toUnicodeStatus;
|
||||
bytesExpected = mode;
|
||||
bytesSoFar = toULength;
|
||||
|
||||
toUnicodeStatus = 0;
|
||||
mode = 0;
|
||||
toULength = 0;
|
||||
}
|
||||
|
||||
outer: while (true) {
|
||||
if (bytesSoFar < bytesExpected) {
|
||||
/* read a trail byte and insert its relevant bits into char32 */
|
||||
if (sourceIndex >= sourceLimit) {
|
||||
/* no source left, save the state for later and break out of the loop */
|
||||
toUnicodeStatus = char32;
|
||||
mode = bytesExpected;
|
||||
toULength = bytesSoFar;
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break;
|
||||
}
|
||||
if (((ch = toUBytesArray[bytesSoFar] = source.get(sourceIndex++)) & 0xc0) != 0x80) {
|
||||
/* not a trail byte (is not of the form 10xxxxxx) */
|
||||
sourceIndex--;
|
||||
toULength = bytesSoFar;
|
||||
cr = CoderResult.malformedForLength(bytesSoFar);
|
||||
break;
|
||||
}
|
||||
char32 = (char32 << 6) | (ch & 0x3f);
|
||||
bytesSoFar++;
|
||||
}
|
||||
/*
|
||||
* Legal UTF-8 byte sequences in Unicode 3.0.1 and up:
|
||||
* - use only trail bytes after a lead byte (checked above)
|
||||
* - use the right number of trail bytes for a given lead byte
|
||||
* - encode a code point <= U+10ffff
|
||||
* - use the fewest possible number of bytes for their code points
|
||||
* - use at most 4 bytes (for i>=5 it is 0x10ffff<utf8_minChar32[])
|
||||
*
|
||||
* Starting with Unicode 3.2, surrogate code points must not be encoded in UTF-8.
|
||||
* There are no irregular sequences any more.
|
||||
* In CESU-8, only surrogates, not supplementary code points, are encoded directly.
|
||||
*/
|
||||
else if (bytesSoFar == bytesExpected && UTF8_MIN_CHAR32[bytesExpected] <= char32 && char32 <= 0x10ffff
|
||||
&& (isCESU8 ? bytesExpected <= 3 : !UTF16.isSurrogate((char) char32))) {
|
||||
/*
|
||||
* char32 is a valid code point and is composed of the correct number of
|
||||
* bytes ... we now need to output it in UTF-16
|
||||
*/
|
||||
|
||||
if (char32 <= UConverterConstants.MAXIMUM_UCS2) {
|
||||
/* fits in 16 bits */
|
||||
target.put(targetIndex++, (char) char32);
|
||||
} else {
|
||||
/* fit char32 into 20 bits */
|
||||
char32 -= UConverterConstants.HALF_BASE;
|
||||
|
||||
/* write out the surrogates */
|
||||
target.put(
|
||||
targetIndex++,
|
||||
(char) ((char32 >>> UConverterConstants.HALF_SHIFT) + UConverterConstants.SURROGATE_HIGH_START));
|
||||
|
||||
if (targetIndex >= targetLimit) {
|
||||
/* put in overflow buffer (not handled here) */
|
||||
charErrorBufferArray[charErrorBufferBegin++] = (char) char32;
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
target.put(
|
||||
targetIndex++,
|
||||
(char) ((char32 & UConverterConstants.HALF_MASK) + UConverterConstants.SURROGATE_LOW_START));
|
||||
}
|
||||
|
||||
/*
|
||||
* we're finished outputing, so now we need to read in the first byte of the
|
||||
* next byte sequence that could form a code point
|
||||
*/
|
||||
|
||||
if (sourceIndex >= sourceLimit) {
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break;
|
||||
}
|
||||
if (targetIndex >= targetLimit) {
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
|
||||
/* keep reading the next input (and writing it) while bytes == 1 */
|
||||
while ((bytesExpected = BYTES_FROM_UTF8[char32 = (toUBytesArray[0] = source.get(sourceIndex++)) & 0xff]) == 1) {
|
||||
target.put(targetIndex++, (char) char32);
|
||||
if (sourceIndex >= sourceLimit) {
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break outer;
|
||||
}
|
||||
if (targetIndex >= targetLimit) {
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
|
||||
/* remove the bits that indicate the number of bytes */
|
||||
char32 &= BITMASK_FROM_UTF8[bytesExpected];
|
||||
bytesSoFar = 1;
|
||||
} else {
|
||||
/*
|
||||
* either the lead byte in the code sequence is invalid (bytes == 0) or the
|
||||
* lead byte combined with all the trail chars does not form a valid code
|
||||
* point
|
||||
*/
|
||||
toULength = bytesSoFar;
|
||||
cr = CoderResult.malformedForLength(bytesSoFar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
source.position(sourceIndex);
|
||||
target.position(targetIndex);
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CharsetEncoderUTF8 extends CharsetEncoderICU {
|
||||
|
||||
public CharsetEncoderUTF8(CharsetICU cs) {
|
||||
super(cs, fromUSubstitution);
|
||||
implReset();
|
||||
}
|
||||
|
||||
protected void implReset() {
|
||||
super.implReset();
|
||||
}
|
||||
|
||||
protected CoderResult encodeLoop(CharBuffer source, ByteBuffer target, IntBuffer offsets,
|
||||
boolean flush) {
|
||||
if (!source.hasRemaining()) {
|
||||
/* no input, nothing to do */
|
||||
return CoderResult.UNDERFLOW;
|
||||
}
|
||||
if (!target.hasRemaining()) {
|
||||
/* no output available, can't do anything */
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
|
||||
if (source.hasArray() && target.hasArray()) {
|
||||
/* source and target are backed by arrays, so use the arrays for optimal performance */
|
||||
char[] sourceArray = source.array();
|
||||
int srcIdx = source.arrayOffset() + source.position();
|
||||
int sourceLimit = source.arrayOffset() + source.limit();
|
||||
byte[] targetArray = target.array();
|
||||
int tgtIdx = target.arrayOffset() + target.position();
|
||||
int targetLimit = target.arrayOffset() + target.limit();
|
||||
|
||||
int char32;
|
||||
CoderResult cr;
|
||||
|
||||
/* take care of the special condition of fromUChar32 not being 0 (it is a surrogate) */
|
||||
if (fromUChar32 != 0) {
|
||||
/* 4 bytes to encode from char32 and a following char in source */
|
||||
|
||||
sourceIndex = srcIdx;
|
||||
targetIndex = tgtIdx;
|
||||
cr = encodeFourBytes(sourceArray, targetArray, sourceLimit, targetLimit,
|
||||
fromUChar32);
|
||||
srcIdx = sourceIndex;
|
||||
tgtIdx = targetIndex;
|
||||
if (cr != null) {
|
||||
source.position(srcIdx - source.arrayOffset());
|
||||
target.position(tgtIdx - target.arrayOffset());
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (srcIdx >= sourceLimit) {
|
||||
/* nothing left to read */
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break;
|
||||
}
|
||||
if (tgtIdx >= targetLimit) {
|
||||
/* no space left to write */
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
|
||||
/* reach the next char into char32 */
|
||||
char32 = sourceArray[srcIdx++];
|
||||
|
||||
if (char32 <= 0x7f) {
|
||||
/* 1 byte to encode from char32 */
|
||||
|
||||
targetArray[tgtIdx++] = encodeHeadOf1(char32);
|
||||
|
||||
} else if (char32 <= 0x7ff) {
|
||||
/* 2 bytes to encode from char32 */
|
||||
|
||||
targetArray[tgtIdx++] = encodeHeadOf2(char32);
|
||||
|
||||
if (tgtIdx >= targetLimit) {
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
targetArray[tgtIdx++] = encodeLastTail(char32);
|
||||
|
||||
} else if (!UTF16.isSurrogate((char) char32) || isCESU8) {
|
||||
/* 3 bytes to encode from char32 */
|
||||
|
||||
targetArray[tgtIdx++] = encodeHeadOf3(char32);
|
||||
|
||||
if (tgtIdx >= targetLimit) {
|
||||
errorBuffer[errorBufferLength++] = encodeSecondToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
targetArray[tgtIdx++] = encodeSecondToLastTail(char32);
|
||||
|
||||
if (tgtIdx >= targetLimit) {
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
targetArray[tgtIdx++] = encodeLastTail(char32);
|
||||
|
||||
} else {
|
||||
/* 4 bytes to encode from char32 and a following char in source */
|
||||
|
||||
sourceIndex = srcIdx;
|
||||
targetIndex = tgtIdx;
|
||||
cr = encodeFourBytes(sourceArray, targetArray, sourceLimit, targetLimit,
|
||||
char32);
|
||||
srcIdx = sourceIndex;
|
||||
tgtIdx = targetIndex;
|
||||
if (cr != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the new source and target positions and return the CoderResult stored in cr */
|
||||
source.position(srcIdx - source.arrayOffset());
|
||||
target.position(tgtIdx - target.arrayOffset());
|
||||
return cr;
|
||||
|
||||
} else {
|
||||
int char32;
|
||||
CoderResult cr;
|
||||
|
||||
/* take care of the special condition of fromUChar32 not being 0 (it is a surrogate) */
|
||||
if (fromUChar32 != 0) {
|
||||
/* 4 bytes to encode from char32 and a following char in source */
|
||||
|
||||
cr = encodeFourBytes(source, target, fromUChar32);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (!source.hasRemaining()) {
|
||||
/* nothing left to read */
|
||||
cr = CoderResult.UNDERFLOW;
|
||||
break;
|
||||
}
|
||||
if (!target.hasRemaining()) {
|
||||
/* no space left to write */
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
|
||||
/* reach the next char into char32 */
|
||||
char32 = source.get();
|
||||
|
||||
if (char32 <= 0x7f) {
|
||||
/* 1 byte to encode from char32 */
|
||||
|
||||
target.put(encodeHeadOf1(char32));
|
||||
|
||||
} else if (char32 <= 0x7ff) {
|
||||
/* 2 bytes to encode from char32 */
|
||||
|
||||
target.put(encodeHeadOf2(char32));
|
||||
|
||||
if (!target.hasRemaining()) {
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
target.put(encodeLastTail(char32));
|
||||
|
||||
} else if (!UTF16.isSurrogate((char) char32) || isCESU8) {
|
||||
/* 3 bytes to encode from char32 */
|
||||
|
||||
target.put(encodeHeadOf3(char32));
|
||||
|
||||
if (!target.hasRemaining()) {
|
||||
errorBuffer[errorBufferLength++] = encodeSecondToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
target.put(encodeSecondToLastTail(char32));
|
||||
|
||||
if (!target.hasRemaining()) {
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
cr = CoderResult.OVERFLOW;
|
||||
break;
|
||||
}
|
||||
target.put(encodeLastTail(char32));
|
||||
|
||||
} else {
|
||||
/* 4 bytes to encode from char32 and a following char in source */
|
||||
|
||||
cr = encodeFourBytes(source, target, char32);
|
||||
if (cr != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the new source and target positions and return the CoderResult stored in cr */
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
private final CoderResult encodeFourBytes(char[] sourceArray, byte[] targetArray,
|
||||
int sourceLimit, int targetLimit, int char32) {
|
||||
|
||||
/* we need to read another char to match up the surrogate stored in char32 */
|
||||
/* handle the surrogate stuff, returning on a non-null CoderResult */
|
||||
CoderResult cr = handleSurrogates(sourceArray, sourceIndex, sourceLimit, (char)char32);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
|
||||
sourceIndex++;
|
||||
char32 = fromUChar32;
|
||||
fromUChar32 = 0;
|
||||
|
||||
/* the rest is routine -- encode four bytes, stopping on overflow */
|
||||
|
||||
targetArray[targetIndex++] = encodeHeadOf4(char32);
|
||||
|
||||
if (targetIndex >= targetLimit) {
|
||||
errorBuffer[errorBufferLength++] = encodeThirdToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeSecondToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
targetArray[targetIndex++] = encodeThirdToLastTail(char32);
|
||||
|
||||
if (targetIndex >= targetLimit) {
|
||||
errorBuffer[errorBufferLength++] = encodeSecondToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
targetArray[targetIndex++] = encodeSecondToLastTail(char32);
|
||||
|
||||
if (targetIndex >= targetLimit) {
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
targetArray[targetIndex++] = encodeLastTail(char32);
|
||||
|
||||
/* return null for success */
|
||||
return null;
|
||||
}
|
||||
|
||||
private final CoderResult encodeFourBytes(CharBuffer source, ByteBuffer target, int char32) {
|
||||
|
||||
/* handle the surrogate stuff, returning on a non-null CoderResult */
|
||||
CoderResult cr = handleSurrogates(source, (char)char32);
|
||||
if (cr != null)
|
||||
return cr;
|
||||
|
||||
char32 = fromUChar32;
|
||||
fromUChar32 = 0;
|
||||
|
||||
/* the rest is routine -- encode four bytes, stopping on overflow */
|
||||
|
||||
target.put(encodeHeadOf4(char32));
|
||||
|
||||
if (!target.hasRemaining()) {
|
||||
errorBuffer[errorBufferLength++] = encodeThirdToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeSecondToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
target.put(encodeThirdToLastTail(char32));
|
||||
|
||||
if (!target.hasRemaining()) {
|
||||
errorBuffer[errorBufferLength++] = encodeSecondToLastTail(char32);
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
target.put(encodeSecondToLastTail(char32));
|
||||
|
||||
if (!target.hasRemaining()) {
|
||||
errorBuffer[errorBufferLength++] = encodeLastTail(char32);
|
||||
return CoderResult.OVERFLOW;
|
||||
}
|
||||
target.put(encodeLastTail(char32));
|
||||
|
||||
/* return null for success */
|
||||
return null;
|
||||
}
|
||||
|
||||
private int sourceIndex;
|
||||
|
||||
private int targetIndex;
|
||||
|
||||
}
|
||||
|
||||
private static final byte encodeHeadOf1(int char32) {
|
||||
return (byte) char32;
|
||||
}
|
||||
|
||||
private static final byte encodeHeadOf2(int char32) {
|
||||
return (byte) (0xc0 | (char32 >>> 6));
|
||||
}
|
||||
|
||||
private static final byte encodeHeadOf3(int char32) {
|
||||
return (byte) (0xe0 | ((char32 >>> 12)));
|
||||
}
|
||||
|
||||
private static final byte encodeHeadOf4(int char32) {
|
||||
return (byte) (0xf0 | ((char32 >>> 18)));
|
||||
}
|
||||
|
||||
private static final byte encodeThirdToLastTail(int char32) {
|
||||
return (byte) (0x80 | ((char32 >>> 12) & 0x3f));
|
||||
}
|
||||
|
||||
private static final byte encodeSecondToLastTail(int char32) {
|
||||
return (byte) (0x80 | ((char32 >>> 6) & 0x3f));
|
||||
}
|
||||
|
||||
private static final byte encodeLastTail(int char32) {
|
||||
return (byte) (0x80 | (char32 & 0x3f));
|
||||
}
|
||||
|
||||
/* single-code point definitions -------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Does this code unit (byte) encode a code point by itself (US-ASCII 0..0x7f)?
|
||||
* @param c 8-bit code unit (byte)
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
// static final boolean isSingle(byte c) {return (((c)&0x80)==0);}
|
||||
/*
|
||||
* Is this code unit (byte) a UTF-8 lead byte?
|
||||
* @param c 8-bit code unit (byte)
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
// static final boolean isLead(byte c) {return ((((c)-0xc0) &
|
||||
// UConverterConstants.UNSIGNED_BYTE_MASK)<0x3e);}
|
||||
/*
|
||||
* Is this code unit (byte) a UTF-8 trail byte?
|
||||
*
|
||||
* @param c
|
||||
* 8-bit code unit (byte)
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
/*private static final boolean isTrail(byte c) {
|
||||
return (((c) & 0xc0) == 0x80);
|
||||
}*/
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new CharsetDecoderUTF8(this);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
return new CharsetEncoderUTF8(this);
|
||||
}
|
||||
|
||||
|
||||
void getUnicodeSetImpl( UnicodeSet setFillIn, int which){
|
||||
getNonSurrogateUnicodeSet(setFillIn);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,831 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.ibm.icu.impl.ICUData;
|
||||
import com.ibm.icu.impl.ICUResourceBundle;
|
||||
|
||||
final class UConverterAlias {
|
||||
static final int UNNORMALIZED = 0;
|
||||
|
||||
static final int STD_NORMALIZED = 1;
|
||||
|
||||
static final int AMBIGUOUS_ALIAS_MAP_BIT = 0x8000;
|
||||
|
||||
static final int CONTAINS_OPTION_BIT = 0x4000;
|
||||
|
||||
static final int CONVERTER_INDEX_MASK = 0xFFF;
|
||||
|
||||
static final int NUM_RESERVED_TAGS = 2;
|
||||
|
||||
static final int NUM_HIDDEN_TAGS = 1;
|
||||
|
||||
static int[] gConverterList = null;
|
||||
|
||||
static int[] gTagList = null;
|
||||
|
||||
static int[] gAliasList = null;
|
||||
|
||||
static int[] gUntaggedConvArray = null;
|
||||
|
||||
static int[] gTaggedAliasArray = null;
|
||||
|
||||
static int[] gTaggedAliasLists = null;
|
||||
|
||||
static int[] gOptionTable = null;
|
||||
|
||||
static byte[] gStringTable = null;
|
||||
|
||||
static byte[] gNormalizedStringTable = null;
|
||||
|
||||
static final String GET_STRING(int idx) {
|
||||
return new String(gStringTable, 2 * idx, strlen(gStringTable, 2 * idx));
|
||||
}
|
||||
|
||||
private static final String GET_NORMALIZED_STRING(int idx) {
|
||||
return new String(gNormalizedStringTable, 2 * idx, strlen(gNormalizedStringTable, 2 * idx));
|
||||
}
|
||||
|
||||
public static final int strlen(byte[] sArray, int sBegin)
|
||||
{
|
||||
int i = sBegin;
|
||||
while(i < sArray.length && sArray[i++] != 0) {}
|
||||
return i - sBegin - 1;
|
||||
}
|
||||
|
||||
/*private*/ static final int tocLengthIndex = 0;
|
||||
|
||||
private static final int converterListIndex = 1;
|
||||
|
||||
private static final int tagListIndex = 2;
|
||||
|
||||
private static final int aliasListIndex = 3;
|
||||
|
||||
private static final int untaggedConvArrayIndex = 4;
|
||||
|
||||
private static final int taggedAliasArrayIndex = 5;
|
||||
|
||||
private static final int taggedAliasListsIndex = 6;
|
||||
|
||||
private static final int optionTableIndex = 7;
|
||||
|
||||
private static final int stringTableIndex = 8;
|
||||
|
||||
private static final int normalizedStringTableIndex = 9;
|
||||
|
||||
private static final int minTocLength = 9; /*
|
||||
* min. tocLength in the file,
|
||||
* does not count the
|
||||
* tocLengthIndex!
|
||||
*/
|
||||
|
||||
private static final int offsetsCount = minTocLength + 1; /*
|
||||
* length of the
|
||||
* swapper's
|
||||
* temporary
|
||||
* offsets[]
|
||||
*/
|
||||
|
||||
static ByteBuffer gAliasData = null;
|
||||
|
||||
private static final boolean isAlias(String alias) {
|
||||
if (alias == null) {
|
||||
throw new IllegalArgumentException("Alias param is null!");
|
||||
}
|
||||
return (alias.length() != 0);
|
||||
}
|
||||
|
||||
private static final String CNVALIAS_DATA_FILE_NAME = ICUResourceBundle.ICU_BUNDLE + "/cnvalias.icu";
|
||||
|
||||
/**
|
||||
* Default buffer size of datafile
|
||||
*/
|
||||
private static final int CNVALIAS_DATA_BUFFER_SIZE = 25000;
|
||||
|
||||
private static final synchronized boolean haveAliasData()
|
||||
throws IOException{
|
||||
boolean needInit;
|
||||
|
||||
// agljport:todo umtx_lock(NULL);
|
||||
needInit = gAliasData == null;
|
||||
|
||||
/* load converter alias data from file if necessary */
|
||||
if (needInit) {
|
||||
ByteBuffer data = null;
|
||||
int[] tableArray = null;
|
||||
int tableStart;
|
||||
//byte[] reservedBytes = null;
|
||||
|
||||
InputStream i = ICUData.getRequiredStream(CNVALIAS_DATA_FILE_NAME);
|
||||
BufferedInputStream b = new BufferedInputStream(i, CNVALIAS_DATA_BUFFER_SIZE);
|
||||
UConverterAliasDataReader reader = new UConverterAliasDataReader(b);
|
||||
tableArray = reader.readToc(offsetsCount);
|
||||
|
||||
tableStart = tableArray[0];
|
||||
if (tableStart < minTocLength) {
|
||||
throw new IOException("Invalid data format.");
|
||||
}
|
||||
gConverterList = new int[tableArray[converterListIndex]];
|
||||
gTagList= new int[tableArray[tagListIndex]];
|
||||
gAliasList = new int[tableArray[aliasListIndex]];
|
||||
gUntaggedConvArray = new int[tableArray[untaggedConvArrayIndex]];
|
||||
gTaggedAliasArray = new int[tableArray[taggedAliasArrayIndex]];
|
||||
gTaggedAliasLists = new int[tableArray[taggedAliasListsIndex]];
|
||||
gOptionTable = new int[tableArray[optionTableIndex]];
|
||||
gStringTable = new byte[tableArray[stringTableIndex]*2];
|
||||
gNormalizedStringTable = new byte[tableArray[normalizedStringTableIndex]*2];
|
||||
|
||||
reader.read(gConverterList, gTagList,
|
||||
gAliasList, gUntaggedConvArray,
|
||||
gTaggedAliasArray, gTaggedAliasLists,
|
||||
gOptionTable, gStringTable, gNormalizedStringTable);
|
||||
data = ByteBuffer.allocate(0); // dummy UDataMemory object in absence
|
||||
// of memory mapping
|
||||
|
||||
if (gOptionTable[0] != STD_NORMALIZED) {
|
||||
throw new IOException("Unsupported alias normalization");
|
||||
}
|
||||
|
||||
// agljport:todo umtx_lock(NULL);
|
||||
if (gAliasData == null) {
|
||||
gAliasData = data;
|
||||
data = null;
|
||||
|
||||
// agljport:fix ucln_common_registerCleanup(UCLN_COMMON_IO,
|
||||
// io_cleanup);
|
||||
}
|
||||
// agljport:todo umtx_unlock(NULL);
|
||||
|
||||
/* if a different thread set it first, then close the extra data */
|
||||
if (data != null) {
|
||||
// agljport:fix udata_close(data); /* NULL if it was set
|
||||
// correctly */
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// U_CFUNC const char * io_getConverterName(const char *alias, UErrorCode
|
||||
// *pErrorCode)
|
||||
// public static final String io_getConverterName(String alias)
|
||||
// throws IOException{
|
||||
// if (haveAliasData() && isAlias(alias)) {
|
||||
// boolean[] isAmbigous = new boolean[1];
|
||||
// int convNum = findConverter(alias, isAmbigous);
|
||||
// if (convNum < gConverterList.length) {
|
||||
// return GET_STRING(gConverterList[(int) convNum]);
|
||||
// }
|
||||
// /* else converter not found */
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
/*
|
||||
* search for an alias return the converter number index for gConverterList
|
||||
*/
|
||||
// static U_INLINE uint32_t findConverter(const char *alias, UErrorCode
|
||||
// *pErrorCode)
|
||||
private static final int findConverter(String alias, boolean[] isAmbigous) {
|
||||
int mid, start, limit;
|
||||
int lastMid;
|
||||
int result;
|
||||
StringBuilder strippedName = new StringBuilder();
|
||||
String aliasToCompare;
|
||||
|
||||
stripForCompare(strippedName, alias);
|
||||
alias = strippedName.toString();
|
||||
|
||||
/* do a binary search for the alias */
|
||||
start = 0;
|
||||
limit = gUntaggedConvArray.length;
|
||||
mid = limit;
|
||||
lastMid = Integer.MAX_VALUE;
|
||||
|
||||
for (;;) {
|
||||
mid = (start + limit) / 2;
|
||||
if (lastMid == mid) { /* Have we moved? */
|
||||
break; /* We haven't moved, and it wasn't found. */
|
||||
}
|
||||
lastMid = mid;
|
||||
aliasToCompare = GET_NORMALIZED_STRING(gAliasList[mid]);
|
||||
result = alias.compareTo(aliasToCompare);
|
||||
|
||||
if (result < 0) {
|
||||
limit = mid;
|
||||
} else if (result > 0) {
|
||||
start = mid;
|
||||
} else {
|
||||
/*
|
||||
* Since the gencnval tool folds duplicates into one entry, this
|
||||
* alias in gAliasList is unique, but different standards may
|
||||
* map an alias to different converters.
|
||||
*/
|
||||
if ((gUntaggedConvArray[mid] & AMBIGUOUS_ALIAS_MAP_BIT) != 0) {
|
||||
isAmbigous[0]=true;
|
||||
}
|
||||
/* State whether the canonical converter name contains an option.
|
||||
This information is contained in this list in order to maintain backward & forward compatibility. */
|
||||
/*if (containsOption) {
|
||||
UBool containsCnvOptionInfo = (UBool)gMainTable.optionTable->containsCnvOptionInfo;
|
||||
*containsOption = (UBool)((containsCnvOptionInfo
|
||||
&& ((gMainTable.untaggedConvArray[mid] & UCNV_CONTAINS_OPTION_BIT) != 0))
|
||||
|| !containsCnvOptionInfo);
|
||||
}*/
|
||||
return gUntaggedConvArray[mid] & CONVERTER_INDEX_MASK;
|
||||
}
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* stripForCompare Remove the underscores, dashes and spaces from
|
||||
* the name, and convert the name to lower case.
|
||||
*
|
||||
* @param dst The destination buffer, which is <= the buffer of name.
|
||||
* @param name The alias to strip
|
||||
* @return the destination buffer.
|
||||
*/
|
||||
public static final StringBuilder stripForCompare(StringBuilder dst, String name) {
|
||||
return io_stripASCIIForCompare(dst, name);
|
||||
}
|
||||
|
||||
// enum {
|
||||
private static final byte IGNORE = 0;
|
||||
private static final byte ZERO = 1;
|
||||
private static final byte NONZERO = 2;
|
||||
static final byte MINLETTER = 3; /* any values from here on are lowercase letter mappings */
|
||||
// }
|
||||
|
||||
/* character types for ASCII 00..7F */
|
||||
static final byte asciiTypes[] = new byte[] {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0,
|
||||
0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0,
|
||||
0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
private static final char GET_CHAR_TYPE(char c) {
|
||||
return (char)((c < asciiTypes.length) ? asciiTypes[c] : (char)IGNORE);
|
||||
}
|
||||
|
||||
/** @see UConverterAlias#compareNames */
|
||||
private static final StringBuilder io_stripASCIIForCompare(StringBuilder dst, String name) {
|
||||
int nameIndex = 0;
|
||||
char type, nextType;
|
||||
char c1;
|
||||
boolean afterDigit = false;
|
||||
|
||||
while (nameIndex < name.length()) {
|
||||
c1 = name.charAt(nameIndex++);
|
||||
type = GET_CHAR_TYPE(c1);
|
||||
switch (type) {
|
||||
case IGNORE:
|
||||
afterDigit = false;
|
||||
continue; /* ignore all but letters and digits */
|
||||
case ZERO:
|
||||
if (!afterDigit && nameIndex < name.length()) {
|
||||
nextType = GET_CHAR_TYPE(name.charAt(nameIndex));
|
||||
if (nextType == ZERO || nextType == NONZERO) {
|
||||
continue; /* ignore leading zero before another digit */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NONZERO:
|
||||
afterDigit = true;
|
||||
break;
|
||||
default:
|
||||
c1 = type; /* lowercased letter */
|
||||
afterDigit = false;
|
||||
break;
|
||||
}
|
||||
dst.append(c1);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do a fuzzy compare of a two converter/alias names. The comparison is
|
||||
* case-insensitive. It also ignores the characters '-', '_', and ' ' (dash,
|
||||
* underscore, and space). Thus the strings "UTF-8", "utf_8", and "Utf 8"
|
||||
* are exactly equivalent.
|
||||
*
|
||||
* This is a symmetrical (commutative) operation; order of arguments is
|
||||
* insignificant. This is an important property for sorting the list (when
|
||||
* the list is preprocessed into binary form) and for performing binary
|
||||
* searches on it at run time.
|
||||
*
|
||||
* @param name1
|
||||
* a converter name or alias, zero-terminated
|
||||
* @param name2
|
||||
* a converter name or alias, zero-terminated
|
||||
* @return 0 if the names match, or a negative value if the name1 lexically
|
||||
* precedes name2, or a positive value if the name1 lexically
|
||||
* follows name2.
|
||||
*
|
||||
* @see UConverterAlias#stripForCompare
|
||||
*/
|
||||
static int compareNames(String name1, String name2){
|
||||
int rc, name1Index = 0, name2Index = 0;
|
||||
char type, nextType;
|
||||
char c1 = 0, c2 = 0;
|
||||
boolean afterDigit1 = false, afterDigit2 = false;
|
||||
|
||||
for (;;) {
|
||||
while (name1Index < name1.length()) {
|
||||
c1 = name1.charAt(name1Index++);
|
||||
type = GET_CHAR_TYPE(c1);
|
||||
switch (type) {
|
||||
case IGNORE:
|
||||
afterDigit1 = false;
|
||||
continue; /* ignore all but letters and digits */
|
||||
case ZERO:
|
||||
if (!afterDigit1 && name1Index < name1.length()) {
|
||||
nextType = GET_CHAR_TYPE(name1.charAt(name1Index));
|
||||
if (nextType == ZERO || nextType == NONZERO) {
|
||||
continue; /* ignore leading zero before another digit */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NONZERO:
|
||||
afterDigit1 = true;
|
||||
break;
|
||||
default:
|
||||
c1 = type; /* lowercased letter */
|
||||
afterDigit1 = false;
|
||||
break;
|
||||
}
|
||||
break; /* deliver c1 */
|
||||
}
|
||||
while (name2Index < name2.length()) {
|
||||
c2 = name2.charAt(name2Index++);
|
||||
type = GET_CHAR_TYPE(c2);
|
||||
switch (type) {
|
||||
case IGNORE:
|
||||
afterDigit2 = false;
|
||||
continue; /* ignore all but letters and digits */
|
||||
case ZERO:
|
||||
if (!afterDigit2 && name1Index < name1.length()) {
|
||||
nextType = GET_CHAR_TYPE(name2.charAt(name2Index));
|
||||
if (nextType == ZERO || nextType == NONZERO) {
|
||||
continue; /* ignore leading zero before another digit */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NONZERO:
|
||||
afterDigit2 = true;
|
||||
break;
|
||||
default:
|
||||
c2 = type; /* lowercased letter */
|
||||
afterDigit2 = false;
|
||||
break;
|
||||
}
|
||||
break; /* deliver c2 */
|
||||
}
|
||||
|
||||
/* If we reach the ends of both strings then they match */
|
||||
if (name1Index >= name1.length() && name2Index >= name2.length()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Case-insensitive comparison */
|
||||
rc = (int)c1 - (int)c2;
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int io_countAliases(String alias)
|
||||
throws IOException{
|
||||
if (haveAliasData() && isAlias(alias)) {
|
||||
boolean[] isAmbigous = new boolean[1];
|
||||
int convNum = findConverter(alias, isAmbigous);
|
||||
if (convNum < gConverterList.length) {
|
||||
/* tagListNum - 1 is the ALL tag */
|
||||
int listOffset = gTaggedAliasArray[(gTagList.length - 1)
|
||||
* gConverterList.length + convNum];
|
||||
|
||||
if (listOffset != 0) {
|
||||
return gTaggedAliasLists[listOffset];
|
||||
}
|
||||
/* else this shouldn't happen. internal program error */
|
||||
}
|
||||
/* else converter not found */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of all aliases (and converter names).
|
||||
*
|
||||
* @return the number of all aliases
|
||||
*/
|
||||
// U_CFUNC uint16_t io_countTotalAliases(UErrorCode *pErrorCode);
|
||||
// static int io_countTotalAliases() throws IOException{
|
||||
// if (haveAliasData()) {
|
||||
// return (int) gAliasList.length;
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// U_CFUNC const char * io_getAlias(const char *alias, uint16_t n,
|
||||
// UErrorCode *pErrorCode)
|
||||
static String io_getAlias(String alias, int n) throws IOException{
|
||||
if (haveAliasData() && isAlias(alias)) {
|
||||
boolean[] isAmbigous = new boolean[1];
|
||||
int convNum = findConverter(alias,isAmbigous);
|
||||
if (convNum < gConverterList.length) {
|
||||
/* tagListNum - 1 is the ALL tag */
|
||||
int listOffset = gTaggedAliasArray[(gTagList.length - 1)
|
||||
* gConverterList.length + convNum];
|
||||
|
||||
if (listOffset != 0) {
|
||||
//int listCount = gTaggedAliasListsArray[listOffset];
|
||||
/* +1 to skip listCount */
|
||||
int[] currListArray = gTaggedAliasLists;
|
||||
int currListArrayIndex = listOffset + 1;
|
||||
|
||||
return GET_STRING(currListArray[currListArrayIndex + n]);
|
||||
|
||||
}
|
||||
/* else this shouldn't happen. internal program error */
|
||||
}
|
||||
/* else converter not found */
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// U_CFUNC uint16_t io_countStandards(UErrorCode *pErrorCode) {
|
||||
// static int io_countStandards() throws IOException{
|
||||
// if (haveAliasData()) {
|
||||
// return (int) (gTagList.length - NUM_HIDDEN_TAGS);
|
||||
// }
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// U_CAPI const char * U_EXPORT2getStandard(uint16_t n, UErrorCode
|
||||
// *pErrorCode)
|
||||
// static String getStandard(int n) throws IOException{
|
||||
// if (haveAliasData()) {
|
||||
// return GET_STRING(gTagList[n]);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// U_CAPI const char * U_EXPORT2 getStandardName(const char *alias, const
|
||||
// char *standard, UErrorCode *pErrorCode)
|
||||
static final String getStandardName(String alias, String standard)throws IOException {
|
||||
if (haveAliasData() && isAlias(alias)) {
|
||||
int listOffset = findTaggedAliasListsOffset(alias, standard);
|
||||
|
||||
if (0 < listOffset && listOffset < gTaggedAliasLists.length) {
|
||||
int[] currListArray = gTaggedAliasLists;
|
||||
int currListArrayIndex = listOffset + 1;
|
||||
if (currListArray[0] != 0) {
|
||||
return GET_STRING(currListArray[currListArrayIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// U_CAPI uint16_t U_EXPORT2 countAliases(const char *alias, UErrorCode
|
||||
// *pErrorCode)
|
||||
static int countAliases(String alias) throws IOException{
|
||||
return io_countAliases(alias);
|
||||
}
|
||||
|
||||
// U_CAPI const char* U_EXPORT2 getAlias(const char *alias, uint16_t n,
|
||||
// UErrorCode *pErrorCode)
|
||||
static String getAlias(String alias, int n) throws IOException{
|
||||
return io_getAlias(alias, n);
|
||||
}
|
||||
|
||||
// U_CFUNC uint16_t countStandards(void)
|
||||
// static int countStandards()throws IOException{
|
||||
// return io_countStandards();
|
||||
// }
|
||||
|
||||
/*returns a single Name from the list, will return NULL if out of bounds
|
||||
*/
|
||||
static String getAvailableName (int n){
|
||||
try{
|
||||
if (0 <= n && n <= 0xffff) {
|
||||
String name = bld_getAvailableConverter(n);
|
||||
return name;
|
||||
}
|
||||
}catch(IOException ex){
|
||||
//throw away exception
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// U_CAPI const char * U_EXPORT2 getCanonicalName(const char *alias, const
|
||||
// char *standard, UErrorCode *pErrorCode) {
|
||||
static String getCanonicalName(String alias, String standard) throws IOException{
|
||||
if (haveAliasData() && isAlias(alias)) {
|
||||
int convNum = findTaggedConverterNum(alias, standard);
|
||||
|
||||
if (convNum < gConverterList.length) {
|
||||
return GET_STRING(gConverterList[convNum]);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
static int countAvailable (){
|
||||
try{
|
||||
return bld_countAvailableConverters();
|
||||
}catch(IOException ex){
|
||||
//throw away exception
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// U_CAPI UEnumeration * U_EXPORT2 openStandardNames(const char *convName,
|
||||
// const char *standard, UErrorCode *pErrorCode)
|
||||
/* static final UConverterAliasesEnumeration openStandardNames(String convName, String standard)throws IOException {
|
||||
UConverterAliasesEnumeration aliasEnum = null;
|
||||
if (haveAliasData() && isAlias(convName)) {
|
||||
int listOffset = findTaggedAliasListsOffset(convName, standard);
|
||||
|
||||
|
||||
* When listOffset == 0, we want to acknowledge that the converter
|
||||
* name and standard are okay, but there is nothing to enumerate.
|
||||
|
||||
if (listOffset < gTaggedAliasLists.length) {
|
||||
|
||||
UConverterAliasesEnumeration.UAliasContext context = new UConverterAliasesEnumeration.UAliasContext(listOffset, 0);
|
||||
aliasEnum = new UConverterAliasesEnumeration();
|
||||
aliasEnum.setContext(context);
|
||||
}
|
||||
else converter or tag not found
|
||||
}
|
||||
return aliasEnum;
|
||||
}*/
|
||||
|
||||
// static uint32_t getTagNumber(const char *tagname)
|
||||
private static int getTagNumber(String tagName) {
|
||||
if (gTagList != null) {
|
||||
int tagNum;
|
||||
for (tagNum = 0; tagNum < gTagList.length; tagNum++) {
|
||||
if (tagName.equals(GET_STRING(gTagList[tagNum]))) {
|
||||
return tagNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// static uint32_t findTaggedAliasListsOffset(const char *alias, const char
|
||||
// *standard, UErrorCode *pErrorCode)
|
||||
private static int findTaggedAliasListsOffset(String alias, String standard) {
|
||||
int idx;
|
||||
int listOffset;
|
||||
int convNum;
|
||||
int tagNum = getTagNumber(standard);
|
||||
boolean[] isAmbigous = new boolean[1];
|
||||
/* Make a quick guess. Hopefully they used a TR22 canonical alias. */
|
||||
convNum = findConverter(alias, isAmbigous);
|
||||
|
||||
if (tagNum < (gTagList.length - NUM_HIDDEN_TAGS)
|
||||
&& convNum < gConverterList.length) {
|
||||
listOffset = gTaggedAliasArray[tagNum
|
||||
* gConverterList.length + convNum];
|
||||
if (listOffset != 0
|
||||
&& gTaggedAliasLists[listOffset + 1] != 0) {
|
||||
return listOffset;
|
||||
}
|
||||
if (isAmbigous[0]==true) {
|
||||
/*
|
||||
* Uh Oh! They used an ambiguous alias. We have to search the
|
||||
* whole swiss cheese starting at the highest standard affinity.
|
||||
* This may take a while.
|
||||
*/
|
||||
|
||||
for (idx = 0; idx < gTaggedAliasArray.length; idx++) {
|
||||
listOffset = gTaggedAliasArray[idx];
|
||||
if (listOffset != 0 && isAliasInList(alias, listOffset)) {
|
||||
int currTagNum = idx / gConverterList.length;
|
||||
int currConvNum = (idx - currTagNum
|
||||
* gConverterList.length);
|
||||
int tempListOffset = gTaggedAliasArray[tagNum
|
||||
* gConverterList.length + currConvNum];
|
||||
if (tempListOffset != 0
|
||||
&& gTaggedAliasLists[tempListOffset + 1] != 0) {
|
||||
return tempListOffset;
|
||||
}
|
||||
/*
|
||||
* else keep on looking We could speed this up by
|
||||
* starting on the next row because an alias is unique
|
||||
* per row, right now. This would change if alias
|
||||
* versioning appears.
|
||||
*/
|
||||
}
|
||||
}
|
||||
/* The standard doesn't know about the alias */
|
||||
}
|
||||
/* else no default name */
|
||||
return 0;
|
||||
}
|
||||
/* else converter or tag not found */
|
||||
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/* Return the canonical name */
|
||||
// static uint32_t findTaggedConverterNum(const char *alias, const char
|
||||
// *standard, UErrorCode *pErrorCode)
|
||||
private static int findTaggedConverterNum(String alias, String standard) {
|
||||
int idx;
|
||||
int listOffset;
|
||||
int convNum;
|
||||
int tagNum = getTagNumber(standard);
|
||||
boolean[] isAmbigous = new boolean[1];
|
||||
|
||||
/* Make a quick guess. Hopefully they used a TR22 canonical alias. */
|
||||
convNum = findConverter(alias, isAmbigous);
|
||||
|
||||
if (tagNum < (gTagList.length - NUM_HIDDEN_TAGS)
|
||||
&& convNum < gConverterList.length) {
|
||||
listOffset = gTaggedAliasArray[tagNum
|
||||
* gConverterList.length + convNum];
|
||||
if (listOffset != 0 && isAliasInList(alias, listOffset)) {
|
||||
return convNum;
|
||||
}
|
||||
if (isAmbigous[0] == true) {
|
||||
/*
|
||||
* Uh Oh! They used an ambiguous alias. We have to search one
|
||||
* slice of the swiss cheese. We search only in the requested
|
||||
* tag, not the whole thing. This may take a while.
|
||||
*/
|
||||
int convStart = (tagNum) * gConverterList.length;
|
||||
int convLimit = (tagNum + 1) * gConverterList.length;
|
||||
for (idx = convStart; idx < convLimit; idx++) {
|
||||
listOffset = gTaggedAliasArray[idx];
|
||||
if (listOffset != 0 && isAliasInList(alias, listOffset)) {
|
||||
return idx - convStart;
|
||||
}
|
||||
}
|
||||
/* The standard doesn't know about the alias */
|
||||
}
|
||||
/* else no canonical name */
|
||||
}
|
||||
/* else converter or tag not found */
|
||||
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
// static U_INLINE UBool isAliasInList(const char *alias, uint32_t
|
||||
// listOffset)
|
||||
private static boolean isAliasInList(String alias, int listOffset) {
|
||||
if (listOffset != 0) {
|
||||
int currAlias;
|
||||
int listCount = gTaggedAliasLists[listOffset];
|
||||
/* +1 to skip listCount */
|
||||
int[] currList = gTaggedAliasLists;
|
||||
int currListArrayIndex = listOffset + 1;
|
||||
for (currAlias = 0; currAlias < listCount; currAlias++) {
|
||||
if (currList[currAlias + currListArrayIndex] != 0
|
||||
&& compareNames(
|
||||
alias,
|
||||
GET_STRING(currList[currAlias + currListArrayIndex])) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// begin bld.c
|
||||
static String[] gAvailableConverters = null;
|
||||
|
||||
static int gAvailableConverterCount = 0;
|
||||
|
||||
static byte[] gDefaultConverterNameBuffer; // [MAX_CONVERTER_NAME_LENGTH +
|
||||
// 1]; /* +1 for NULL */
|
||||
|
||||
static String gDefaultConverterName = null;
|
||||
|
||||
// static UBool haveAvailableConverterList(UErrorCode *pErrorCode)
|
||||
static boolean haveAvailableConverterList() throws IOException{
|
||||
if (gAvailableConverters == null) {
|
||||
int idx;
|
||||
int localConverterCount;
|
||||
String converterName;
|
||||
String[] localConverterList;
|
||||
|
||||
if (!haveAliasData()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We can't have more than "*converterTable" converters to open */
|
||||
localConverterList = new String[gConverterList.length];
|
||||
|
||||
localConverterCount = 0;
|
||||
|
||||
for (idx = 0; idx < gConverterList.length; idx++) {
|
||||
converterName = GET_STRING(gConverterList[idx]);
|
||||
//UConverter cnv = UConverter.open(converterName);
|
||||
//TODO: Fix me
|
||||
localConverterList[localConverterCount++] = converterName;
|
||||
|
||||
}
|
||||
|
||||
// agljport:todo umtx_lock(NULL);
|
||||
if (gAvailableConverters == null) {
|
||||
gAvailableConverters = localConverterList;
|
||||
gAvailableConverterCount = localConverterCount;
|
||||
/* haveData should have already registered the cleanup function */
|
||||
} else {
|
||||
// agljport:todo free((char **)localConverterList);
|
||||
}
|
||||
// agljport:todo umtx_unlock(NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// U_CFUNC uint16_t bld_countAvailableConverters(UErrorCode *pErrorCode)
|
||||
static int bld_countAvailableConverters() throws IOException{
|
||||
if (haveAvailableConverterList()) {
|
||||
return gAvailableConverterCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// U_CFUNC const char * bld_getAvailableConverter(uint16_t n, UErrorCode
|
||||
// *pErrorCode)
|
||||
static String bld_getAvailableConverter(int n) throws IOException{
|
||||
if (haveAvailableConverterList()) {
|
||||
if (n < gAvailableConverterCount) {
|
||||
return gAvailableConverters[n];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* default converter name --------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* In order to be really thread-safe, the get function would have to take
|
||||
* a buffer parameter and copy the current string inside a mutex block.
|
||||
* This implementation only tries to be really thread-safe while
|
||||
* setting the name.
|
||||
* It assumes that setting a pointer is atomic.
|
||||
*/
|
||||
|
||||
// U_CFUNC const char * getDefaultName()
|
||||
// static final synchronized String getDefaultName() {
|
||||
// /* local variable to be thread-safe */
|
||||
// String name;
|
||||
//
|
||||
// //agljport:todo umtx_lock(null);
|
||||
// name = gDefaultConverterName;
|
||||
// //agljport:todo umtx_unlock(null);
|
||||
//
|
||||
// if (name == null) {
|
||||
// //UConverter cnv = null;
|
||||
// int length = 0;
|
||||
//
|
||||
// name = CharsetICU.getDefaultCharsetName();
|
||||
//
|
||||
// /* if the name is there, test it out and get the canonical name with options */
|
||||
// if (name != null) {
|
||||
// // cnv = UConverter.open(name);
|
||||
// // name = cnv.getName(cnv);
|
||||
// // TODO: fix me
|
||||
// }
|
||||
//
|
||||
// if (name == null || name.length() == 0 ||/* cnv == null ||*/
|
||||
// length >= gDefaultConverterNameBuffer.length) {
|
||||
// /* Panic time, let's use a fallback. */
|
||||
// name = new String("US-ASCII");
|
||||
// }
|
||||
//
|
||||
// //length=(int32_t)(strlen(name));
|
||||
//
|
||||
// /* Copy the name before we close the converter. */
|
||||
// name = gDefaultConverterName;
|
||||
// }
|
||||
//
|
||||
// return name;
|
||||
// }
|
||||
|
||||
//end bld.c
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.ibm.icu.impl.ICUBinary;
|
||||
|
||||
|
||||
/* Format of cnvalias.icu -----------------------------------------------------
|
||||
*
|
||||
* cnvalias.icu is a binary, memory-mappable form of convrtrs.txt.
|
||||
* This binary form contains several tables. All indexes are to uint16_t
|
||||
* units, and not to the bytes (uint8_t units). Addressing everything on
|
||||
* 16-bit boundaries allows us to store more information with small index
|
||||
* numbers, which are also 16-bit in size. The majority of the table (except
|
||||
* the string table) are 16-bit numbers.
|
||||
*
|
||||
* First there is the size of the Table of Contents (TOC). The TOC
|
||||
* entries contain the size of each section. In order to find the offset
|
||||
* you just need to sum up the previous offsets.
|
||||
* The TOC length and entries are an array of uint32_t values.
|
||||
* The first section after the TOC starts immediately after the TOC.
|
||||
*
|
||||
* 1) This section contains a list of converters. This list contains indexes
|
||||
* into the string table for the converter name. The index of this list is
|
||||
* also used by other sections, which are mentioned later on.
|
||||
* This list is not sorted.
|
||||
*
|
||||
* 2) This section contains a list of tags. This list contains indexes
|
||||
* into the string table for the tag name. The index of this list is
|
||||
* also used by other sections, which are mentioned later on.
|
||||
* This list is in priority order of standards.
|
||||
*
|
||||
* 3) This section contains a list of sorted unique aliases. This
|
||||
* list contains indexes into the string table for the alias name. The
|
||||
* index of this list is also used by other sections, like the 4th section.
|
||||
* The index for the 3rd and 4th section is used to get the
|
||||
* alias -> converter name mapping. Section 3 and 4 form a two column table.
|
||||
*
|
||||
* 4) This section contains a list of mapped converter names. Consider this
|
||||
* as a table that maps the 3rd section to the 1st section. This list contains
|
||||
* indexes into the 1st section. The index of this list is the same index in
|
||||
* the 3rd section. There is also some extra information in the high bits of
|
||||
* each converter index in this table. Currently it's only used to say that
|
||||
* an alias mapped to this converter is ambiguous. See UCNV_CONVERTER_INDEX_MASK
|
||||
* and UCNV_AMBIGUOUS_ALIAS_MAP_BIT for more information. This section is
|
||||
* the predigested form of the 5th section so that an alias lookup can be fast.
|
||||
*
|
||||
* 5) This section contains a 2D array with indexes to the 6th section. This
|
||||
* section is the full form of all alias mappings. The column index is the
|
||||
* index into the converter list (column header). The row index is the index
|
||||
* to tag list (row header). This 2D array is the top part a 3D array. The
|
||||
* third dimension is in the 6th section.
|
||||
*
|
||||
* 6) This is blob of variable length arrays. Each array starts with a size,
|
||||
* and is followed by indexes to alias names in the string table. This is
|
||||
* the third dimension to the section 5. No other section should be referencing
|
||||
* this section.
|
||||
*
|
||||
* 7) Reserved at this time (There is no information). This _usually_ has a
|
||||
* size of 0. Future versions may add more information here.
|
||||
*
|
||||
* 8) This is the string table. All strings are indexed on an even address.
|
||||
* There are two reasons for this. First many chip architectures locate strings
|
||||
* faster on even address boundaries. Second, since all indexes are 16-bit
|
||||
* numbers, this string table can be 128KB in size instead of 64KB when we
|
||||
* only have strings starting on an even address.
|
||||
*
|
||||
*
|
||||
* Here is the concept of section 5 and 6. It's a 3D cube. Each tag
|
||||
* has a unique alias among all converters. That same alias can
|
||||
* be mentioned in other standards on different converters,
|
||||
* but only one alias per tag can be unique.
|
||||
*
|
||||
*
|
||||
* Converter Names (Usually in TR22 form)
|
||||
* -------------------------------------------.
|
||||
* T / /|
|
||||
* a / / |
|
||||
* g / / |
|
||||
* s / / |
|
||||
* / / |
|
||||
* ------------------------------------------/ |
|
||||
* A | | |
|
||||
* l | | |
|
||||
* i | | /
|
||||
* a | | /
|
||||
* s | | /
|
||||
* e | | /
|
||||
* s | |/
|
||||
* -------------------------------------------
|
||||
*
|
||||
*
|
||||
*
|
||||
* Here is what it really looks like. It's like swiss cheese.
|
||||
* There are holes. Some converters aren't recognized by
|
||||
* a standard, or they are really old converters that the
|
||||
* standard doesn't recognize anymore.
|
||||
*
|
||||
* Converter Names (Usually in TR22 form)
|
||||
* -------------------------------------------.
|
||||
* T /##########################################/|
|
||||
* a / # # /#
|
||||
* g / # ## ## ### # ### ### ### #/
|
||||
* s / # ##### #### ## ## #/#
|
||||
* / ### # # ## # # # ### # # #/##
|
||||
* ------------------------------------------/# #
|
||||
* A |### # # ## # # # ### # # #|# #
|
||||
* l |# # # # # ## # #|# #
|
||||
* i |# # # # # # #|#
|
||||
* a |# #|#
|
||||
* s | #|#
|
||||
* e
|
||||
* s
|
||||
*
|
||||
*/
|
||||
|
||||
final class UConverterAliasDataReader implements ICUBinary.Authenticate {
|
||||
// private final static boolean debug = ICUDebug.enabled("UConverterAliasDataReader");
|
||||
|
||||
/**
|
||||
* <p>Protected constructor.</p>
|
||||
* @param inputStream ICU uprop.dat file input stream
|
||||
* @exception IOException throw if data file fails authentication
|
||||
*/
|
||||
protected UConverterAliasDataReader(InputStream inputStream)
|
||||
throws IOException{
|
||||
//if(debug) System.out.println("Bytes in inputStream " + inputStream.available());
|
||||
|
||||
/*unicodeVersion = */ICUBinary.readHeader(inputStream, DATA_FORMAT_ID, this);
|
||||
|
||||
//if(debug) System.out.println("Bytes left in inputStream " +inputStream.available());
|
||||
|
||||
dataInputStream = new DataInputStream(inputStream);
|
||||
|
||||
//if(debug) System.out.println("Bytes left in dataInputStream " +dataInputStream.available());
|
||||
}
|
||||
|
||||
// protected methods -------------------------------------------------
|
||||
|
||||
protected int[] readToc(int n)throws IOException
|
||||
{
|
||||
int[] toc = new int[n];
|
||||
//Read the toc
|
||||
for (int i = 0; i < n ; ++i) {
|
||||
toc[i] = dataInputStream.readInt() & UNSIGNED_INT_MASK;
|
||||
}
|
||||
return toc;
|
||||
}
|
||||
|
||||
protected void read(int[] convList, int[] tagList, int[] aliasList, int[]untaggedConvArray, int[] taggedAliasArray, int[] taggedAliasLists, int[] optionTable, byte[] stringTable, byte[] normalizedStringTable) throws IOException{
|
||||
int i;
|
||||
//int listnum = 1;
|
||||
//long listsize;
|
||||
|
||||
for(i = 0; i < convList.length; ++i)
|
||||
convList[i] = dataInputStream.readUnsignedShort();
|
||||
|
||||
for(i = 0; i < tagList.length; ++i)
|
||||
tagList[i] = dataInputStream.readUnsignedShort();
|
||||
|
||||
for(i = 0; i < aliasList.length; ++i)
|
||||
aliasList[i] = dataInputStream.readUnsignedShort();
|
||||
|
||||
for(i = 0; i < untaggedConvArray.length; ++i)
|
||||
untaggedConvArray[i] = dataInputStream.readUnsignedShort();
|
||||
|
||||
for(i = 0; i < taggedAliasArray.length; ++i)
|
||||
taggedAliasArray[i] = dataInputStream.readUnsignedShort();
|
||||
|
||||
for(i = 0; i < taggedAliasLists.length; ++i)
|
||||
taggedAliasLists[i] = dataInputStream.readUnsignedShort();
|
||||
|
||||
for(i = 0; i < optionTable.length; ++i)
|
||||
optionTable[i] = dataInputStream.readUnsignedShort();
|
||||
|
||||
dataInputStream.readFully(stringTable);
|
||||
dataInputStream.readFully(normalizedStringTable);
|
||||
}
|
||||
|
||||
public boolean isDataVersionAcceptable(byte version[])
|
||||
{
|
||||
return version.length >= DATA_FORMAT_VERSION.length
|
||||
&& version[0] == DATA_FORMAT_VERSION[0]
|
||||
&& version[1] == DATA_FORMAT_VERSION[1]
|
||||
&& version[2] == DATA_FORMAT_VERSION[2];
|
||||
}
|
||||
|
||||
/*byte[] getUnicodeVersion(){
|
||||
return unicodeVersion;
|
||||
}*/
|
||||
// private data members -------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* ICU data file input stream
|
||||
*/
|
||||
private DataInputStream dataInputStream;
|
||||
|
||||
// private byte[] unicodeVersion;
|
||||
|
||||
/**
|
||||
* File format version that this class understands.
|
||||
* No guarantees are made if a older version is used
|
||||
* see store.c of gennorm for more information and values
|
||||
*/
|
||||
// DATA_FORMAT_ID_ values taken from icu4c isAcceptable (ucnv_io.c)
|
||||
private static final byte DATA_FORMAT_ID[] = {(byte)0x43, (byte)0x76, (byte)0x41, (byte)0x6c}; // dataFormat="CvAl"
|
||||
private static final byte DATA_FORMAT_VERSION[] = {3, 0, 1};
|
||||
|
||||
//private static final int UNSIGNED_SHORT_MASK = 0xffff;
|
||||
private static final int UNSIGNED_INT_MASK = 0xffffffff;
|
||||
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
interface UConverterConstants {
|
||||
|
||||
static final short UNSIGNED_BYTE_MASK = 0xff;
|
||||
static final int UNSIGNED_SHORT_MASK = 0xffff;
|
||||
static final long UNSIGNED_INT_MASK = 0xffffffffL;
|
||||
|
||||
static final int U_IS_BIG_ENDIAN = 0;
|
||||
|
||||
/**
|
||||
* Useful constant for the maximum size of the whole locale ID
|
||||
* (including the terminating NULL).
|
||||
*/
|
||||
static final int ULOC_FULLNAME_CAPACITY = 56;
|
||||
|
||||
/**
|
||||
* This value is intended for sentinel values for APIs that
|
||||
* (take or) return single code points (UChar32).
|
||||
* It is outside of the Unicode code point range 0..0x10ffff.
|
||||
*
|
||||
* For example, a "done" or "error" value in a new API
|
||||
* could be indicated with U_SENTINEL.
|
||||
*
|
||||
* ICU APIs designed before ICU 2.4 usually define service-specific "done"
|
||||
* values, mostly 0xffff.
|
||||
* Those may need to be distinguished from
|
||||
* actual U+ffff text contents by calling functions like
|
||||
* CharacterIterator::hasNext() or UnicodeString::length().
|
||||
*/
|
||||
static final int U_SENTINEL = -1;
|
||||
|
||||
//end utf.h
|
||||
|
||||
//begin ucnv.h
|
||||
/**
|
||||
* Character that separates converter names from options and options from each other.
|
||||
* @see CharsetICU#forNameICU(String)
|
||||
*/
|
||||
static final byte OPTION_SEP_CHAR = ',';
|
||||
|
||||
/** Maximum length of a converter name including the terminating NULL */
|
||||
static final int MAX_CONVERTER_NAME_LENGTH = 60;
|
||||
/** Maximum length of a converter name including path and terminating NULL */
|
||||
static final int MAX_FULL_FILE_NAME_LENGTH = (600+MAX_CONVERTER_NAME_LENGTH);
|
||||
|
||||
/** Shift in for EBDCDIC_STATEFUL and iso2022 states */
|
||||
static final int SI = 0x0F;
|
||||
/** Shift out for EBDCDIC_STATEFUL and iso2022 states */
|
||||
static final int SO = 0x0E;
|
||||
|
||||
//end ucnv.h
|
||||
|
||||
// begin bld.h
|
||||
/* size of the overflow buffers in UConverter, enough for escaping callbacks */
|
||||
//#define ERROR_BUFFER_LENGTH 32
|
||||
static final int ERROR_BUFFER_LENGTH = 32;
|
||||
|
||||
/* at most 4 bytes per substitution character (part of .cnv file format! see UConverterStaticData) */
|
||||
static final int MAX_SUBCHAR_LEN = 4;
|
||||
|
||||
/* at most 8 bytes per character in toUBytes[] (UTF-8 uses up to 6) */
|
||||
static final int MAX_CHAR_LEN = 8;
|
||||
|
||||
/* converter options bits */
|
||||
static final int OPTION_VERSION = 0xf;
|
||||
static final int OPTION_SWAP_LFNL = 0x10;
|
||||
static final int OPTION_MAC = 0x20; //agljport:comment added for Mac ISCII encodings
|
||||
|
||||
static final String OPTION_SWAP_LFNL_STRING = ",swaplfnl";
|
||||
|
||||
/** values for the unicodeMask */
|
||||
static final int HAS_SUPPLEMENTARY = 1;
|
||||
static final int HAS_SURROGATES = 2;
|
||||
// end bld.h
|
||||
|
||||
// begin cnv.h
|
||||
/* this is used in fromUnicode DBCS tables as an "unassigned" marker */
|
||||
static final int missingCharMarker = 0xFFFF;
|
||||
/**
|
||||
*
|
||||
* @author ram
|
||||
*/
|
||||
static interface UConverterResetChoice {
|
||||
static final int RESET_BOTH = 0;
|
||||
static final int RESET_TO_UNICODE = RESET_BOTH + 1;
|
||||
static final int RESET_FROM_UNICODE = RESET_TO_UNICODE + 1;
|
||||
}
|
||||
|
||||
// begin utf16.h
|
||||
/**
|
||||
* The maximum number of 16-bit code units per Unicode code point (U+0000..U+10ffff).
|
||||
*/
|
||||
static final int U16_MAX_LENGTH = 2;
|
||||
// end utf16.h
|
||||
|
||||
// begin err.h
|
||||
/**
|
||||
* FROM_U, TO_U context options for sub callback
|
||||
*/
|
||||
static byte[] SUB_STOP_ON_ILLEGAL = {'i'};
|
||||
|
||||
/**
|
||||
* FROM_U, TO_U context options for skip callback
|
||||
*/
|
||||
static byte[] SKIP_STOP_ON_ILLEGAL = {'i'};
|
||||
|
||||
/**
|
||||
* The process condition code to be used with the callbacks.
|
||||
* Codes which are greater than IRREGULAR should be
|
||||
* passed on to any chained callbacks.
|
||||
*/
|
||||
static interface UConverterCallbackReason {
|
||||
static final int UNASSIGNED = 0; /**< The code point is unassigned.
|
||||
The error code U_INVALID_CHAR_FOUND will be set. */
|
||||
static final int ILLEGAL = 1; /**< The code point is illegal. For example,
|
||||
\\x81\\x2E is illegal in SJIS because \\x2E
|
||||
is not a valid trail byte for the \\x81
|
||||
lead byte.
|
||||
Also, starting with Unicode 3.0.1, non-shortest byte sequences
|
||||
in UTF-8 (like \\xC1\\xA1 instead of \\x61 for U+0061)
|
||||
are also illegal, not just irregular.
|
||||
The error code U_ILLEGAL_CHAR_FOUND will be set. */
|
||||
static final int IRREGULAR = 2; /**< The codepoint is not a regular sequence in
|
||||
the encoding. For example, \\xED\\xA0\\x80..\\xED\\xBF\\xBF
|
||||
are irregular UTF-8 byte sequences for single surrogate
|
||||
code points.
|
||||
The error code U_INVALID_CHAR_FOUND will be set. */
|
||||
static final int RESET = 3; /**< The callback is called with this reason when a
|
||||
'reset' has occured. Callback should reset all
|
||||
state. */
|
||||
static final int CLOSE = 4; /**< Called when the converter is closed. The
|
||||
callback should release any allocated memory.*/
|
||||
static final int CLONE = 5; /**< Called when safeClone() is called on the
|
||||
converter. the pointer available as the
|
||||
'context' is an alias to the original converters'
|
||||
context pointer. If the context must be owned
|
||||
by the new converter, the callback must clone
|
||||
the data and call setFromUCallback
|
||||
(or setToUCallback) with the correct pointer.
|
||||
*/
|
||||
}
|
||||
//end err.h
|
||||
|
||||
|
||||
static final String DATA_TYPE = "cnv";
|
||||
static final int CNV_DATA_BUFFER_SIZE = 25000;
|
||||
static final int SIZE_OF_UCONVERTER_SHARED_DATA = 100;
|
||||
|
||||
static final int MAXIMUM_UCS2 = 0x0000FFFF;
|
||||
static final int MAXIMUM_UTF = 0x0010FFFF;
|
||||
//static final int MAXIMUM_UCS4 = 0x7FFFFFFF;
|
||||
static final int HALF_SHIFT = 10;
|
||||
static final int HALF_BASE = 0x0010000;
|
||||
static final int HALF_MASK = 0x3FF;
|
||||
static final int SURROGATE_HIGH_START = 0xD800;
|
||||
static final int SURROGATE_HIGH_END = 0xDBFF;
|
||||
static final int SURROGATE_LOW_START = 0xDC00;
|
||||
static final int SURROGATE_LOW_END = 0xDFFF;
|
||||
|
||||
/* -SURROGATE_LOW_START + HALF_BASE */
|
||||
static final int SURROGATE_LOW_BASE = 9216;
|
||||
}
|
|
@ -0,0 +1,612 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2010, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.ibm.icu.impl.ICUBinary;
|
||||
|
||||
/**
|
||||
* ucnvmbcs.h
|
||||
*
|
||||
* ICU conversion (.cnv) data file structure, following the usual UDataInfo
|
||||
* header.
|
||||
*
|
||||
* Format version: 6.2
|
||||
*
|
||||
* struct UConverterStaticData -- struct containing the converter name, IBM CCSID,
|
||||
* min/max bytes per character, etc.
|
||||
* see ucnv_bld.h
|
||||
*
|
||||
* --------------------
|
||||
*
|
||||
* The static data is followed by conversionType-specific data structures.
|
||||
* At the moment, there are only variations of MBCS converters. They all have
|
||||
* the same toUnicode structures, while the fromUnicode structures for SBCS
|
||||
* differ from those for other MBCS-style converters.
|
||||
*
|
||||
* _MBCSHeader.version 4.2 adds an optional conversion extension data structure.
|
||||
* If it is present, then an ICU version reading header versions 4.0 or 4.1
|
||||
* will be able to use the base table and ignore the extension.
|
||||
*
|
||||
* The unicodeMask in the static data is part of the base table data structure.
|
||||
* Especially, the UCNV_HAS_SUPPLEMENTARY flag determines the length of the
|
||||
* fromUnicode stage 1 array.
|
||||
* The static data unicodeMask refers only to the base table's properties if
|
||||
* a base table is included.
|
||||
* In an extension-only file, the static data unicodeMask is 0.
|
||||
* The extension data indexes have a separate field with the unicodeMask flags.
|
||||
*
|
||||
* MBCS-style data structure following the static data.
|
||||
* Offsets are counted in bytes from the beginning of the MBCS header structure.
|
||||
* Details about usage in comments in ucnvmbcs.c.
|
||||
*
|
||||
* struct _MBCSHeader (see the definition in this header file below)
|
||||
* contains 32-bit fields as follows:
|
||||
* 8 values:
|
||||
* 0 uint8_t[4] MBCS version in UVersionInfo format (currently 4.2.0.0)
|
||||
* 1 uint32_t countStates
|
||||
* 2 uint32_t countToUFallbacks
|
||||
* 3 uint32_t offsetToUCodeUnits
|
||||
* 4 uint32_t offsetFromUTable
|
||||
* 5 uint32_t offsetFromUBytes
|
||||
* 6 uint32_t flags, bits:
|
||||
* 31.. 8 offsetExtension -- _MBCSHeader.version 4.2 (ICU 2.8) and higher
|
||||
* 0 for older versions and if
|
||||
* there is not extension structure
|
||||
* 7.. 0 outputType
|
||||
* 7 uint32_t fromUBytesLength -- _MBCSHeader.version 4.1 (ICU 2.4) and higher
|
||||
* counts bytes in fromUBytes[]
|
||||
*
|
||||
* if(outputType==MBCS_OUTPUT_EXT_ONLY) {
|
||||
* -- base table name for extension-only table
|
||||
* char baseTableName[variable]; -- with NUL plus padding for 4-alignment
|
||||
*
|
||||
* -- all _MBCSHeader fields except for version and flags are 0
|
||||
* } else {
|
||||
* -- normal base table with optional extension
|
||||
*
|
||||
* int32_t stateTable[countStates][256];
|
||||
*
|
||||
* struct _MBCSToUFallback { (fallbacks are sorted by offset)
|
||||
* uint32_t offset;
|
||||
* UChar32 codePoint;
|
||||
* } toUFallbacks[countToUFallbacks];
|
||||
*
|
||||
* uint16_t unicodeCodeUnits[(offsetFromUTable-offsetToUCodeUnits)/2];
|
||||
* (padded to an even number of units)
|
||||
*
|
||||
* -- stage 1 tables
|
||||
* if(staticData.unicodeMask&UCNV_HAS_SUPPLEMENTARY) {
|
||||
* -- stage 1 table for all of Unicode
|
||||
* uint16_t fromUTable[0x440]; (32-bit-aligned)
|
||||
* } else {
|
||||
* -- BMP-only tables have a smaller stage 1 table
|
||||
* uint16_t fromUTable[0x40]; (32-bit-aligned)
|
||||
* }
|
||||
*
|
||||
* -- stage 2 tables
|
||||
* length determined by top of stage 1 and bottom of stage 3 tables
|
||||
* if(outputType==MBCS_OUTPUT_1) {
|
||||
* -- SBCS: pure indexes
|
||||
* uint16_t stage 2 indexes[?];
|
||||
* } else {
|
||||
* -- DBCS, MBCS, EBCDIC_STATEFUL, ...: roundtrip flags and indexes
|
||||
* uint32_t stage 2 flags and indexes[?];
|
||||
* }
|
||||
*
|
||||
* -- stage 3 tables with byte results
|
||||
* if(outputType==MBCS_OUTPUT_1) {
|
||||
* -- SBCS: each 16-bit result contains flags and the result byte, see ucnvmbcs.c
|
||||
* uint16_t fromUBytes[fromUBytesLength/2];
|
||||
* } else {
|
||||
* -- DBCS, MBCS, EBCDIC_STATEFUL, ... 2/3/4 bytes result, see ucnvmbcs.c
|
||||
* uint8_t fromUBytes[fromUBytesLength]; or
|
||||
* uint16_t fromUBytes[fromUBytesLength/2]; or
|
||||
* uint32_t fromUBytes[fromUBytesLength/4];
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* -- extension table, details see ucnv_ext.h
|
||||
* int32_t indexes[>=32]; ...
|
||||
*/
|
||||
/*
|
||||
* ucnv_ext.h
|
||||
*
|
||||
* See icuhtml/design/conversion/conversion_extensions.html
|
||||
*
|
||||
* Conversion extensions serve two purposes:
|
||||
* 1. They support m:n mappings.
|
||||
* 2. They support extension-only conversion files that are used together
|
||||
* with the regular conversion data in base files.
|
||||
*
|
||||
* A base file may contain an extension table (explicitly requested or
|
||||
* implicitly generated for m:n mappings), but its extension table is not
|
||||
* used when an extension-only file is used.
|
||||
*
|
||||
* It is an error if a base file contains any regular (not extension) mapping
|
||||
* from the same sequence as a mapping in the extension file
|
||||
* because the base mapping would hide the extension mapping.
|
||||
*
|
||||
*
|
||||
* Data for conversion extensions:
|
||||
*
|
||||
* One set of data structures per conversion direction (to/from Unicode).
|
||||
* The data structures are sorted by input units to allow for binary search.
|
||||
* Input sequences of more than one unit are handled like contraction tables
|
||||
* in collation:
|
||||
* The lookup value of a unit points to another table that is to be searched
|
||||
* for the next unit, recursively.
|
||||
*
|
||||
* For conversion from Unicode, the initial code point is looked up in
|
||||
* a 3-stage trie for speed,
|
||||
* with an additional table of unique results to save space.
|
||||
*
|
||||
* Long output strings are stored in separate arrays, with length and index
|
||||
* in the lookup tables.
|
||||
* Output results also include a flag distinguishing roundtrip from
|
||||
* (reverse) fallback mappings.
|
||||
*
|
||||
* Input Unicode strings must not begin or end with unpaired surrogates
|
||||
* to avoid problems with matches on parts of surrogate pairs.
|
||||
*
|
||||
* Mappings from multiple characters (code points or codepage state
|
||||
* table sequences) must be searched preferring the longest match.
|
||||
* For this to work and be efficient, the variable-width table must contain
|
||||
* all mappings that contain prefixes of the multiple characters.
|
||||
* If an extension table is built on top of a base table in another file
|
||||
* and a base table entry is a prefix of a multi-character mapping, then
|
||||
* this is an error.
|
||||
*
|
||||
*
|
||||
* Implementation note:
|
||||
*
|
||||
* Currently, the parser and several checks in the code limit the number
|
||||
* of UChars or bytes in a mapping to
|
||||
* UCNV_EXT_MAX_UCHARS and UCNV_EXT_MAX_BYTES, respectively,
|
||||
* which are output value limits in the data structure.
|
||||
*
|
||||
* For input, this is not strictly necessary - it is a hard limit only for the
|
||||
* buffers in UConverter that are used to store partial matches.
|
||||
*
|
||||
* Input sequences could otherwise be arbitrarily long if partial matches
|
||||
* need not be stored (i.e., if a sequence does not span several buffers with too
|
||||
* many units before the last buffer), although then results would differ
|
||||
* depending on whether partial matches exceed the limits or not,
|
||||
* which depends on the pattern of buffer sizes.
|
||||
*
|
||||
*
|
||||
* Data structure:
|
||||
*
|
||||
* int32_t indexes[>=32];
|
||||
*
|
||||
* Array of indexes and lengths etc. The length of the array is at least 32.
|
||||
* The actual length is stored in indexes[0] to be forward compatible.
|
||||
*
|
||||
* Each index to another array is the number of bytes from indexes[].
|
||||
* Each length of an array is the number of array base units in that array.
|
||||
*
|
||||
* Some of the structures may not be present, in which case their indexes
|
||||
* and lengths are 0.
|
||||
*
|
||||
* Usage of indexes[i]:
|
||||
* [0] length of indexes[]
|
||||
*
|
||||
* // to Unicode table
|
||||
* [1] index of toUTable[] (array of uint32_t)
|
||||
* [2] length of toUTable[]
|
||||
* [3] index of toUUChars[] (array of UChar)
|
||||
* [4] length of toUUChars[]
|
||||
*
|
||||
* // from Unicode table, not for the initial code point
|
||||
* [5] index of fromUTableUChars[] (array of UChar)
|
||||
* [6] index of fromUTableValues[] (array of uint32_t)
|
||||
* [7] length of fromUTableUChars[] and fromUTableValues[]
|
||||
* [8] index of fromUBytes[] (array of char)
|
||||
* [9] length of fromUBytes[]
|
||||
*
|
||||
* // from Unicode trie for initial-code point lookup
|
||||
* [10] index of fromUStage12[] (combined array of uint16_t for stages 1 & 2)
|
||||
* [11] length of stage 1 portion of fromUStage12[]
|
||||
* [12] length of fromUStage12[]
|
||||
* [13] index of fromUStage3[] (array of uint16_t indexes into fromUStage3b[])
|
||||
* [14] length of fromUStage3[]
|
||||
* [15] index of fromUStage3b[] (array of uint32_t like fromUTableValues[])
|
||||
* [16] length of fromUStage3b[]
|
||||
*
|
||||
* [17] Bit field containing numbers of bytes:
|
||||
* 31..24 reserved, 0
|
||||
* 23..16 maximum input bytes
|
||||
* 15.. 8 maximum output bytes
|
||||
* 7.. 0 maximum bytes per UChar
|
||||
*
|
||||
* [18] Bit field containing numbers of UChars:
|
||||
* 31..24 reserved, 0
|
||||
* 23..16 maximum input UChars
|
||||
* 15.. 8 maximum output UChars
|
||||
* 7.. 0 maximum UChars per byte
|
||||
*
|
||||
* [19] Bit field containing flags:
|
||||
* (extension table unicodeMask)
|
||||
* 1 UCNV_HAS_SURROGATES flag for the extension table
|
||||
* 0 UCNV_HAS_SUPPLEMENTARY flag for the extension table
|
||||
*
|
||||
* [20]..[30] reserved, 0
|
||||
* [31] number of bytes for the entire extension structure
|
||||
* [>31] reserved; there are indexes[0] indexes
|
||||
*
|
||||
*
|
||||
* uint32_t toUTable[];
|
||||
*
|
||||
* Array of byte/value pairs for lookups for toUnicode conversion.
|
||||
* The array is partitioned into sections like collation contraction tables.
|
||||
* Each section contains one word with the number of following words and
|
||||
* a default value for when the lookup in this section yields no match.
|
||||
*
|
||||
* A section is sorted in ascending order of input bytes,
|
||||
* allowing for fast linear or binary searches.
|
||||
* The builder may store entries for a contiguous range of byte values
|
||||
* (compare difference between the first and last one with count),
|
||||
* which then allows for direct array access.
|
||||
* The builder should always do this for the initial table section.
|
||||
*
|
||||
* Entries may have 0 values, see below.
|
||||
* No two entries in a section have the same byte values.
|
||||
*
|
||||
* Each uint32_t contains an input byte value in bits 31..24 and the
|
||||
* corresponding lookup value in bits 23..0.
|
||||
* Interpret the value as follows:
|
||||
* if(value==0) {
|
||||
* no match, see below
|
||||
* } else if(value<0x1f0000) {
|
||||
* partial match - use value as index to the next toUTable section
|
||||
* and match the next unit; (value indexes toUTable[value])
|
||||
* } else {
|
||||
* if(bit 23 set) {
|
||||
* roundtrip;
|
||||
* } else {
|
||||
* fallback;
|
||||
* }
|
||||
* unset value bit 23;
|
||||
* if(value<=0x2fffff) {
|
||||
* (value-0x1f0000) is a code point; (BMP: value<=0x1fffff)
|
||||
* } else {
|
||||
* bits 17..0 (value&0x3ffff) is an index to
|
||||
* the result UChars in toUUChars[]; (0 indexes toUUChars[0])
|
||||
* length of the result=((value>>18)-12); (length=0..19)
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* The first word in a section contains the number of following words in the
|
||||
* input byte position (bits 31..24, number=1..0xff).
|
||||
* The value of the initial word is used when the current byte is not found
|
||||
* in this section.
|
||||
* If the value is not 0, then it represents a result as above.
|
||||
* If the value is 0, then the search has to return a shorter match with an
|
||||
* earlier default value as the result, or result in "unmappable" even for the
|
||||
* initial bytes.
|
||||
* If the value is 0 for the initial toUTable entry, then the initial byte
|
||||
* does not start any mapping input.
|
||||
*
|
||||
*
|
||||
* UChar toUUChars[];
|
||||
*
|
||||
* Contains toUnicode mapping results, stored as sequences of UChars.
|
||||
* Indexes and lengths stored in the toUTable[].
|
||||
*
|
||||
*
|
||||
* UChar fromUTableUChars[];
|
||||
* uint32_t fromUTableValues[];
|
||||
*
|
||||
* The fromUTable is split into two arrays, but works otherwise much like
|
||||
* the toUTable. The array is partitioned into sections like collation
|
||||
* contraction tables and toUTable.
|
||||
* A row in the table consists of same-index entries in fromUTableUChars[]
|
||||
* and fromUTableValues[].
|
||||
*
|
||||
* Interpret a value as follows:
|
||||
* if(value==0) {
|
||||
* no match, see below
|
||||
* } else if(value<=0xffffff) { (bits 31..24 are 0)
|
||||
* partial match - use value as index to the next fromUTable section
|
||||
* and match the next unit; (value indexes fromUTable[value])
|
||||
* } else {
|
||||
* if(value==0x80000001) {
|
||||
* return no mapping, but request for <subchar1>;
|
||||
* }
|
||||
* if(bit 31 set) {
|
||||
* roundtrip;
|
||||
* } else {
|
||||
* fallback;
|
||||
* }
|
||||
* // bits 30..29 reserved, 0
|
||||
* length=(value>>24)&0x1f; (bits 28..24)
|
||||
* if(length==1..3) {
|
||||
* bits 23..0 contain 1..3 bytes, padded with 00s on the left;
|
||||
* } else {
|
||||
* bits 23..0 (value&0xffffff) is an index to
|
||||
* the result bytes in fromUBytes[]; (0 indexes fromUBytes[0])
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* The first pair in a section contains the number of following pairs in the
|
||||
* UChar position (16 bits, number=1..0xffff).
|
||||
* The value of the initial pair is used when the current UChar is not found
|
||||
* in this section.
|
||||
* If the value is not 0, then it represents a result as above.
|
||||
* If the value is 0, then the search has to return a shorter match with an
|
||||
* earlier default value as the result, or result in "unmappable" even for the
|
||||
* initial UChars.
|
||||
*
|
||||
* If the from Unicode trie is present, then the from Unicode search tables
|
||||
* are not used for initial code points.
|
||||
* In this case, the first entries (index 0) in the tables are not used
|
||||
* (reserved, set to 0) because a value of 0 is used in trie results
|
||||
* to indicate no mapping.
|
||||
*
|
||||
*
|
||||
* uint16_t fromUStage12[];
|
||||
*
|
||||
* Stages 1 & 2 of a trie that maps an initial code point.
|
||||
* Indexes in stage 1 are all offset by the length of stage 1 so that the
|
||||
* same array pointer can be used for both stages.
|
||||
* If (c>>10)>=(length of stage 1) then c does not start any mapping.
|
||||
* Same bit distribution as for regular conversion tries.
|
||||
*
|
||||
*
|
||||
* uint16_t fromUStage3[];
|
||||
* uint32_t fromUStage3b[];
|
||||
*
|
||||
* Stage 3 of the trie. The first array simply contains indexes to the second,
|
||||
* which contains words in the same format as fromUTableValues[].
|
||||
* Use a stage 3 granularity of 4, which allows for 256k stage 3 entries,
|
||||
* and 16-bit entries in stage 3 allow for 64k stage 3b entries.
|
||||
* The stage 3 granularity means that the stage 2 entry needs to be left-shifted.
|
||||
*
|
||||
* Two arrays are used because it is expected that more than half of the stage 3
|
||||
* entries will be zero. The 16-bit index stage 3 array saves space even
|
||||
* considering storing a total of 6 bytes per non-zero entry in both arrays
|
||||
* together.
|
||||
* Using a stage 3 granularity of >1 diminishes the compactability in that stage
|
||||
* but provides a larger effective addressing space in stage 2.
|
||||
* All but the final result stage use 16-bit entries to save space.
|
||||
*
|
||||
* fromUStage3b[] contains a zero for "no mapping" at its index 0,
|
||||
* and may contain UCNV_EXT_FROM_U_SUBCHAR1 at index 1 for "<subchar1> SUB mapping"
|
||||
* (i.e., "no mapping" with preference for <subchar1> rather than <subchar>),
|
||||
* and all other items are unique non-zero results.
|
||||
*
|
||||
* The default value of a fromUTableValues[] section that is referenced
|
||||
* _directly_ from a fromUStage3b[] item may also be UCNV_EXT_FROM_U_SUBCHAR1,
|
||||
* but this value must not occur anywhere else in fromUTableValues[]
|
||||
* because "no mapping" is always a property of a single code point,
|
||||
* never of multiple.
|
||||
*
|
||||
*
|
||||
* char fromUBytes[];
|
||||
*
|
||||
* Contains fromUnicode mapping results, stored as sequences of chars.
|
||||
* Indexes and lengths stored in the fromUTableValues[].
|
||||
*/
|
||||
|
||||
final class UConverterDataReader implements ICUBinary.Authenticate {
|
||||
//private final static boolean debug = ICUDebug.enabled("UConverterDataReader");
|
||||
|
||||
/*
|
||||
* UConverterDataReader(UConverterDataReader r)
|
||||
{
|
||||
dataInputStream = new DataInputStream(r.dataInputStream);
|
||||
unicodeVersion = r.unicodeVersion;
|
||||
}
|
||||
*/
|
||||
/* the number bytes read from the stream */
|
||||
int bytesRead = 0;
|
||||
/* the number of bytes read for static data */
|
||||
int staticDataBytesRead = 0;
|
||||
/**
|
||||
* <p>Protected constructor.</p>
|
||||
* @param inputStream ICU uprop.dat file input stream
|
||||
* @exception IOException throw if data file fails authentication
|
||||
*/
|
||||
protected UConverterDataReader(InputStream inputStream)
|
||||
throws IOException{
|
||||
//if(debug) System.out.println("Bytes in inputStream " + inputStream.available());
|
||||
|
||||
/*unicodeVersion = */ICUBinary.readHeader(inputStream, DATA_FORMAT_ID, this);
|
||||
|
||||
//if(debug) System.out.println("Bytes left in inputStream " +inputStream.available());
|
||||
|
||||
dataInputStream = new DataInputStream(inputStream);
|
||||
|
||||
//if(debug) System.out.println("Bytes left in dataInputStream " +dataInputStream.available());
|
||||
}
|
||||
|
||||
// protected methods -------------------------------------------------
|
||||
|
||||
protected void readStaticData(UConverterStaticData sd) throws IOException
|
||||
{
|
||||
int bRead = 0;
|
||||
sd.structSize = dataInputStream.readInt();
|
||||
bRead +=4;
|
||||
byte[] name = new byte[UConverterConstants.MAX_CONVERTER_NAME_LENGTH];
|
||||
dataInputStream.readFully(name);
|
||||
bRead +=name.length;
|
||||
sd.name = new String(name, 0, name.length);
|
||||
sd.codepage = dataInputStream.readInt();
|
||||
bRead +=4;
|
||||
sd.platform = dataInputStream.readByte();
|
||||
bRead++;
|
||||
sd.conversionType = dataInputStream.readByte();
|
||||
bRead++;
|
||||
sd.minBytesPerChar = dataInputStream.readByte();
|
||||
bRead++;
|
||||
sd.maxBytesPerChar = dataInputStream.readByte();
|
||||
bRead++;
|
||||
dataInputStream.readFully(sd.subChar);
|
||||
bRead += sd.subChar.length;
|
||||
sd.subCharLen = dataInputStream.readByte();
|
||||
bRead++;
|
||||
sd.hasToUnicodeFallback = dataInputStream.readByte();
|
||||
bRead++;
|
||||
sd.hasFromUnicodeFallback = dataInputStream.readByte();
|
||||
bRead++;
|
||||
sd.unicodeMask = (short)dataInputStream.readUnsignedByte();
|
||||
bRead++;
|
||||
sd.subChar1 = dataInputStream.readByte();
|
||||
bRead++;
|
||||
dataInputStream.readFully(sd.reserved);
|
||||
bRead += sd.reserved.length;
|
||||
staticDataBytesRead = bRead;
|
||||
bytesRead += bRead;
|
||||
}
|
||||
|
||||
protected void readMBCSHeader(CharsetMBCS.MBCSHeader h) throws IOException
|
||||
{
|
||||
dataInputStream.readFully(h.version);
|
||||
bytesRead += h.version.length;
|
||||
h.countStates = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
h.countToUFallbacks = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
h.offsetToUCodeUnits = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
h.offsetFromUTable = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
h.offsetFromUBytes = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
h.flags = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
h.fromUBytesLength = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
if (h.version[0] == 5 && h.version[1] >= 3) {
|
||||
h.options = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
if ((h.options & CharsetMBCS.MBCS_OPT_NO_FROM_U) != 0) {
|
||||
h.fullStage2Length = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void readMBCSTable(int[][] stateTableArray, CharsetMBCS.MBCSToUFallback[] toUFallbacksArray, char[] unicodeCodeUnitsArray, char[] fromUnicodeTableArray, byte[] fromUnicodeBytesArray) throws IOException
|
||||
{
|
||||
int i, j;
|
||||
for(i = 0; i < stateTableArray.length; ++i){
|
||||
for(j = 0; j < stateTableArray[i].length; ++j){
|
||||
stateTableArray[i][j] = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
}
|
||||
}
|
||||
for(i = 0; i < toUFallbacksArray.length; ++i) {
|
||||
toUFallbacksArray[i].offset = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
toUFallbacksArray[i].codePoint = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
}
|
||||
for(i = 0; i < unicodeCodeUnitsArray.length; ++i){
|
||||
unicodeCodeUnitsArray[i] = dataInputStream.readChar();
|
||||
bytesRead+=2;
|
||||
}
|
||||
for(i = 0; i < fromUnicodeTableArray.length; ++i){
|
||||
fromUnicodeTableArray[i] = dataInputStream.readChar();
|
||||
bytesRead+=2;
|
||||
}
|
||||
for(i = 0; i < fromUnicodeBytesArray.length; ++i){
|
||||
fromUnicodeBytesArray[i] = dataInputStream.readByte();
|
||||
bytesRead++;
|
||||
}
|
||||
}
|
||||
|
||||
protected String readBaseTableName() throws IOException
|
||||
{
|
||||
char c;
|
||||
StringBuilder name = new StringBuilder();
|
||||
while((c = (char)dataInputStream.readByte()) != 0){
|
||||
name.append(c);
|
||||
bytesRead++;
|
||||
}
|
||||
bytesRead++/*for null terminator*/;
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
//protected int[] readExtIndexes(int skip) throws IOException
|
||||
protected ByteBuffer readExtIndexes(int skip) throws IOException
|
||||
{
|
||||
int skipped = dataInputStream.skipBytes(skip);
|
||||
if(skipped != skip){
|
||||
throw new IOException("could not skip "+ skip +" bytes");
|
||||
}
|
||||
int n = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
int[] indexes = new int[n];
|
||||
indexes[0] = n;
|
||||
for(int i = 1; i < n; ++i) {
|
||||
indexes[i] = dataInputStream.readInt();
|
||||
bytesRead+=4;
|
||||
}
|
||||
//return indexes;
|
||||
|
||||
ByteBuffer b = ByteBuffer.allocate(indexes[31]);
|
||||
for(int i = 0; i < n; ++i) {
|
||||
b.putInt(indexes[i]);
|
||||
}
|
||||
int len = dataInputStream.read(b.array(), b.position(), b.remaining());
|
||||
if(len==-1){
|
||||
throw new IOException("Read failed");
|
||||
}
|
||||
bytesRead += len;
|
||||
return b;
|
||||
}
|
||||
|
||||
/*protected byte[] readExtTables(int n) throws IOException
|
||||
{
|
||||
byte[] tables = new byte[n];
|
||||
int len =dataInputStream.read(tables);
|
||||
if(len==-1){
|
||||
throw new IOException("Read failed");
|
||||
}
|
||||
bytesRead += len;
|
||||
return tables;
|
||||
}*/
|
||||
|
||||
byte[] getDataFormatVersion(){
|
||||
return DATA_FORMAT_VERSION;
|
||||
}
|
||||
/**
|
||||
* Inherited method
|
||||
*/
|
||||
public boolean isDataVersionAcceptable(byte version[]){
|
||||
return version[0] == DATA_FORMAT_VERSION[0];
|
||||
}
|
||||
|
||||
/* byte[] getUnicodeVersion(){
|
||||
return unicodeVersion;
|
||||
}*/
|
||||
// private data members -------------------------------------------------
|
||||
|
||||
/**
|
||||
* ICU data file input stream
|
||||
*/
|
||||
DataInputStream dataInputStream;
|
||||
|
||||
// private byte[] unicodeVersion;
|
||||
|
||||
/**
|
||||
* File format version that this class understands.
|
||||
* No guarantees are made if a older version is used
|
||||
* see store.c of gennorm for more information and values
|
||||
*/
|
||||
// DATA_FORMAT_ID_ values taken from icu4c isCnvAcceptable (ucnv_bld.c)
|
||||
private static final byte DATA_FORMAT_ID[] = {(byte)0x63, (byte)0x6e, (byte)0x76, (byte)0x74}; // dataFormat="cnvt"
|
||||
private static final byte DATA_FORMAT_VERSION[] = {(byte)0x6};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2008, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
/**
|
||||
* Defines the UConverterSharedData struct, the immutable, shared part of
|
||||
* UConverter.
|
||||
*/
|
||||
final class UConverterSharedData {
|
||||
// uint32_t structSize; /* Size of this structure */
|
||||
// int structSize; /* Size of this structure */
|
||||
/**
|
||||
* used to count number of clients, 0xffffffff for static SharedData
|
||||
*/
|
||||
int referenceCounter;
|
||||
|
||||
// agljport:todo const void *dataMemory; /* from udata_openChoice() - for cleanup */
|
||||
// agljport:todo void *table; /* Unused. This used to be a UConverterTable - Pointer to conversion data - see mbcs below */
|
||||
|
||||
// const UConverterStaticData *staticData; /* pointer to the static (non changing) data. */
|
||||
/**
|
||||
* pointer to the static (non changing)
|
||||
* data.
|
||||
*/
|
||||
UConverterStaticData staticData;
|
||||
|
||||
// UBool sharedDataCached; /* TRUE: shared data is in cache, don't destroy
|
||||
// on close() if 0 ref. FALSE: shared data isn't in the cache, do attempt to
|
||||
// clean it up if the ref is 0 */
|
||||
|
||||
/**
|
||||
* TRUE: shared data is in cache, don't destroy
|
||||
* on close() if 0 ref. FALSE: shared data isn't
|
||||
* in the cache, do attempt to clean it up if
|
||||
* the ref is 0
|
||||
*/
|
||||
boolean sharedDataCached;
|
||||
|
||||
/*
|
||||
* UBool staticDataOwned; TRUE if static data owned by shared data & should
|
||||
* be freed with it, NEVER true for udata() loaded statics. This ignored
|
||||
* variable was removed to make space for sharedDataCached.
|
||||
*/
|
||||
|
||||
// const UConverterImpl *impl; /* vtable-style struct of mostly function pointers */
|
||||
// UConverterImpl impl; /* vtable-style struct of mostly function pointers */
|
||||
/** initial values of some members of the mutable part of object */
|
||||
long toUnicodeStatus;
|
||||
|
||||
/**
|
||||
* Shared data structures currently come in two flavors:
|
||||
* - readonly for built-in algorithmic converters
|
||||
* - allocated for MBCS, with a pointer to an allocated UConverterTable
|
||||
* which always has a UConverterMBCSTable
|
||||
*
|
||||
* To eliminate one allocation, I am making the UConverterMBCSTable a member
|
||||
* of the shared data. It is the last member so that static definitions of
|
||||
* UConverterSharedData work as before. The table field above also remains
|
||||
* to avoid updating all static definitions, but is now unused.
|
||||
*
|
||||
*/
|
||||
CharsetMBCS.UConverterMBCSTable mbcs;
|
||||
|
||||
UConverterSharedData() {
|
||||
mbcs = new CharsetMBCS.UConverterMBCSTable();
|
||||
}
|
||||
|
||||
UConverterSharedData(int referenceCounter_, UConverterStaticData staticData_, boolean sharedDataCached_, long toUnicodeStatus_)
|
||||
{
|
||||
this();
|
||||
referenceCounter = referenceCounter_;
|
||||
staticData = staticData_;
|
||||
sharedDataCached = sharedDataCached_;
|
||||
// impl = impl_;
|
||||
toUnicodeStatus = toUnicodeStatus_;
|
||||
}
|
||||
|
||||
/**
|
||||
* UConverterImpl contains all the data and functions for a converter type.
|
||||
* Its function pointers work much like a C++ vtable. Many converter types
|
||||
* need to define only a subset of the functions; when a function pointer is
|
||||
* NULL, then a default action will be performed.
|
||||
*
|
||||
* Every converter type must implement toUnicode, fromUnicode, and
|
||||
* getNextUChar, otherwise the converter may crash. Every converter type
|
||||
* that has variable-length codepage sequences should also implement
|
||||
* toUnicodeWithOffsets and fromUnicodeWithOffsets for correct offset
|
||||
* handling. All other functions may or may not be implemented - it depends
|
||||
* only on whether the converter type needs them.
|
||||
*
|
||||
* When open() fails, then close() will be called, if present.
|
||||
*/
|
||||
/* class UConverterImpl {
|
||||
UConverterType type;
|
||||
UConverterToUnicode toUnicode;
|
||||
protected void doToUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
final void toUnicode(UConverterToUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
doToUnicode(args, pErrorCode);
|
||||
}
|
||||
|
||||
//UConverterFromUnicode fromUnicode;
|
||||
protected void doFromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
final void fromUnicode(UConverterFromUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
doFromUnicode(args, pErrorCode);
|
||||
}
|
||||
|
||||
protected int doGetNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//UConverterGetNextUChar getNextUChar;
|
||||
final int getNextUChar(UConverterToUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
return doGetNextUChar(args, pErrorCode);
|
||||
}
|
||||
|
||||
// interface UConverterImplLoadable extends UConverterImpl
|
||||
protected void doLoad(UConverterLoadArgs pArgs, short[] raw, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
protected void doUnload()
|
||||
{
|
||||
}
|
||||
|
||||
// interface UConverterImplOpenable extends UConverterImpl
|
||||
protected void doOpen(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
//UConverterOpen open;
|
||||
final void open(UConverter cnv, String name, String locale, long options, int[] pErrorCode)
|
||||
{
|
||||
doOpen(cnv, name, locale, options, pErrorCode);
|
||||
}
|
||||
|
||||
protected void doClose(UConverter cnv)
|
||||
{
|
||||
}
|
||||
|
||||
//UConverterClose close;
|
||||
final void close(UConverter cnv)
|
||||
{
|
||||
doClose(cnv);
|
||||
}
|
||||
|
||||
protected void doReset(UConverter cnv, int choice)
|
||||
{
|
||||
}
|
||||
|
||||
//typedef void (*UConverterReset) (UConverter *cnv, UConverterResetChoice choice);
|
||||
//UConverterReset reset;
|
||||
final void reset(UConverter cnv, int choice)
|
||||
{
|
||||
doReset(cnv, choice);
|
||||
}
|
||||
|
||||
// interface UConverterImplVariableLength extends UConverterImpl
|
||||
protected void doToUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
//UConverterToUnicode toUnicodeWithOffsets;
|
||||
final void toUnicodeWithOffsets(UConverterToUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
doToUnicodeWithOffsets(args, pErrorCode);
|
||||
}
|
||||
|
||||
protected void doFromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
//UConverterFromUnicode fromUnicodeWithOffsets;
|
||||
final void fromUnicodeWithOffsets(UConverterFromUnicodeArgs args, int[] pErrorCode)
|
||||
{
|
||||
doFromUnicodeWithOffsets(args, pErrorCode);
|
||||
}
|
||||
|
||||
// interface UConverterImplMisc extends UConverterImpl
|
||||
protected void doGetStarters(UConverter converter, boolean starters[], int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
//UConverterGetStarters getStarters;
|
||||
final void getStarters(UConverter converter, boolean starters[], int[] pErrorCode)
|
||||
{
|
||||
doGetStarters(converter, starters, pErrorCode);
|
||||
}
|
||||
|
||||
protected String doGetName(UConverter cnv)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
//UConverterGetName getName;
|
||||
final String getName(UConverter cnv)
|
||||
{
|
||||
return doGetName(cnv);
|
||||
}
|
||||
|
||||
protected void doWriteSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
//UConverterWriteSub writeSub;
|
||||
final void writeSub(UConverterFromUnicodeArgs pArgs, long offsetIndex, int[] pErrorCode)
|
||||
{
|
||||
doWriteSub(pArgs, offsetIndex, pErrorCode);
|
||||
}
|
||||
|
||||
protected UConverter doSafeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
|
||||
{
|
||||
return new UConverter();
|
||||
}
|
||||
|
||||
//UConverterSafeClone safeClone;
|
||||
final UConverter safeClone(UConverter cnv, byte[] stackBuffer, int[] pBufferSize, int[] status)
|
||||
{
|
||||
return doSafeClone(cnv, stackBuffer, pBufferSize, status);
|
||||
}
|
||||
|
||||
protected void doGetUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
//UConverterGetUnicodeSet getUnicodeSet;
|
||||
// final void getUnicodeSet(UConverter cnv, UnicodeSet /*USetAdder* / sa, int /*UConverterUnicodeSet* / which, int[] pErrorCode)
|
||||
//{
|
||||
// doGetUnicodeSet(cnv, sa, which, pErrorCode);
|
||||
//}
|
||||
|
||||
//}
|
||||
|
||||
static final String DATA_TYPE = "cnv";
|
||||
private static final int CNV_DATA_BUFFER_SIZE = 25000;
|
||||
static final int sizeofUConverterSharedData = 100;
|
||||
|
||||
//static UDataMemoryIsAcceptable isCnvAcceptable;
|
||||
|
||||
/**
|
||||
* Load a non-algorithmic converter.
|
||||
* If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex).
|
||||
|
||||
// UConverterSharedData * load(UConverterLoadArgs *pArgs, UErrorCode *err)
|
||||
static final UConverterSharedData load(UConverterLoadArgs pArgs, int[] err)
|
||||
{
|
||||
UConverterSharedData mySharedConverterData = null;
|
||||
|
||||
if(err == null || ErrorCode.isFailure(err[0])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(pArgs.pkg != null && pArgs.pkg.length() != 0) {
|
||||
application-provided converters are not currently cached
|
||||
return UConverterSharedData.createConverterFromFile(pArgs, err);
|
||||
}
|
||||
|
||||
//agljport:fix mySharedConverterData = getSharedConverterData(pArgs.name);
|
||||
if (mySharedConverterData == null)
|
||||
{
|
||||
Not cached, we need to stream it in from file
|
||||
mySharedConverterData = UConverterSharedData.createConverterFromFile(pArgs, err);
|
||||
if (ErrorCode.isFailure(err[0]) || (mySharedConverterData == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
share it with other library clients
|
||||
//agljport:fix shareConverterData(mySharedConverterData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
The data for this converter was already in the cache.
|
||||
Update the reference counter on the shared data: one more client
|
||||
mySharedConverterData.referenceCounter++;
|
||||
}
|
||||
|
||||
return mySharedConverterData;
|
||||
}
|
||||
|
||||
Takes an alias name gets an actual converter file name
|
||||
*goes to disk and opens it.
|
||||
*allocates the memory and returns a new UConverter object
|
||||
|
||||
//static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs, UErrorCode * err)
|
||||
static final UConverterSharedData createConverterFromFile(UConverterLoadArgs pArgs, int[] err)
|
||||
{
|
||||
UDataMemory data = null;
|
||||
UConverterSharedData sharedData = null;
|
||||
|
||||
//agljport:todo UTRACE_ENTRY_OC(UTRACE_LOAD);
|
||||
|
||||
if (err == null || ErrorCode.isFailure(err[0])) {
|
||||
//agljport:todo UTRACE_EXIT_STATUS(*err);
|
||||
return null;
|
||||
}
|
||||
|
||||
//agljport:todo UTRACE_DATA2(UTRACE_OPEN_CLOSE, "load converter %s from package %s", pArgs->name, pArgs->pkg);
|
||||
|
||||
//agljport:fix data = udata_openChoice(pArgs.pkgArray, DATA_TYPE.getBytes(), pArgs.name, isCnvAcceptable, null, err);
|
||||
if(ErrorCode.isFailure(err[0]))
|
||||
{
|
||||
//agljport:todo UTRACE_EXIT_STATUS(*err);
|
||||
return null;
|
||||
}
|
||||
|
||||
sharedData = data_unFlattenClone(pArgs, data, err);
|
||||
if(ErrorCode.isFailure(err[0]))
|
||||
{
|
||||
//agljport:fix udata_close(data);
|
||||
//agljport:todo UTRACE_EXIT_STATUS(*err);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
* TODO Store pkg in a field in the shared data so that delta-only converters
|
||||
* can load base converters from the same package.
|
||||
* If the pkg name is longer than the field, then either do not load the converter
|
||||
* in the first place, or just set the pkg field to "".
|
||||
|
||||
|
||||
return sharedData;
|
||||
}
|
||||
*/
|
||||
UConverterDataReader dataReader = null;
|
||||
|
||||
/*
|
||||
* returns a converter type from a string
|
||||
*/
|
||||
/* static final UConverterSharedData getAlgorithmicTypeFromName(String realName)
|
||||
{
|
||||
long mid, start, limit;
|
||||
long lastMid;
|
||||
int result;
|
||||
StringBuffer strippedName = new StringBuffer(UConverterConstants.MAX_CONVERTER_NAME_LENGTH);
|
||||
|
||||
// Lower case and remove ignoreable characters.
|
||||
UConverterAlias.stripForCompare(strippedName, realName);
|
||||
|
||||
// do a binary search for the alias
|
||||
start = 0;
|
||||
limit = cnvNameType.length;
|
||||
mid = limit;
|
||||
lastMid = -1;
|
||||
|
||||
for (;;) {
|
||||
mid = (long)((start + limit) / 2);
|
||||
if (lastMid == mid) { // Have we moved?
|
||||
break; // We haven't moved, and it wasn't found.
|
||||
}
|
||||
lastMid = mid;
|
||||
result = strippedName.substring(0).compareTo(cnvNameType[(int)mid].name);
|
||||
|
||||
if (result < 0) {
|
||||
limit = mid;
|
||||
} else if (result > 0) {
|
||||
start = mid;
|
||||
} else {
|
||||
return converterData[cnvNameType[(int)mid].type];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}*/
|
||||
|
||||
/*
|
||||
* Enum for specifying basic types of converters
|
||||
*/
|
||||
static final class UConverterType {
|
||||
static final int UNSUPPORTED_CONVERTER = -1;
|
||||
static final int SBCS = 0;
|
||||
static final int DBCS = 1;
|
||||
static final int MBCS = 2;
|
||||
static final int LATIN_1 = 3;
|
||||
static final int UTF8 = 4;
|
||||
static final int UTF16_BigEndian = 5;
|
||||
static final int UTF16_LittleEndian = 6;
|
||||
static final int UTF32_BigEndian = 7;
|
||||
static final int UTF32_LittleEndian = 8;
|
||||
static final int EBCDIC_STATEFUL = 9;
|
||||
static final int ISO_2022 = 10;
|
||||
static final int LMBCS_1 = 11;
|
||||
static final int LMBCS_2 = LMBCS_1 + 1; // 12
|
||||
static final int LMBCS_3 = LMBCS_2 + 1; // 13
|
||||
static final int LMBCS_4 = LMBCS_3 + 1; // 14
|
||||
static final int LMBCS_5 = LMBCS_4 + 1; // 15
|
||||
static final int LMBCS_6 = LMBCS_5 + 1; // 16
|
||||
static final int LMBCS_8 = LMBCS_6 + 1; // 17
|
||||
static final int LMBCS_11 = LMBCS_8 + 1; // 18
|
||||
static final int LMBCS_16 = LMBCS_11 + 1; // 19
|
||||
static final int LMBCS_17 = LMBCS_16 + 1; // 20
|
||||
static final int LMBCS_18 = LMBCS_17 + 1; // 21
|
||||
static final int LMBCS_19 = LMBCS_18 + 1; // 22
|
||||
static final int LMBCS_LAST = LMBCS_19; // 22
|
||||
static final int HZ = LMBCS_LAST + 1; // 23
|
||||
static final int SCSU = HZ + 1; // 24
|
||||
static final int ISCII = SCSU + 1; // 25
|
||||
static final int US_ASCII = ISCII + 1; // 26
|
||||
static final int UTF7 = US_ASCII + 1; // 27
|
||||
static final int BOCU1 = UTF7 + 1; // 28
|
||||
static final int UTF16 = BOCU1 + 1; // 29
|
||||
static final int UTF32 = UTF16 + 1; // 30
|
||||
static final int CESU8 = UTF32 + 1; // 31
|
||||
static final int IMAP_MAILBOX = CESU8 + 1; // 32
|
||||
|
||||
// Number of converter types for which we have conversion routines.
|
||||
static final int NUMBER_OF_SUPPORTED_CONVERTER_TYPES = IMAP_MAILBOX + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum for specifying which platform a converter ID refers to. The use of
|
||||
* platform/CCSID is not recommended. See openCCSID().
|
||||
*/
|
||||
static final class UConverterPlatform {
|
||||
static final int UNKNOWN = -1;
|
||||
static final int IBM = 0;
|
||||
}
|
||||
|
||||
// static UConverterSharedData[] converterData;
|
||||
/* static class cnvNameTypeClass {
|
||||
String name;
|
||||
int type;
|
||||
cnvNameTypeClass(String name_, int type_) { name = name_; type = type_; }
|
||||
}
|
||||
|
||||
static cnvNameTypeClass cnvNameType[];*/
|
||||
|
||||
|
||||
static final String DATA_TYPE = "cnv";
|
||||
//static final int CNV_DATA_BUFFER_SIZE = 25000;
|
||||
//static final int SIZE_OF_UCONVERTER_SHARED_DATA = 228;
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2006-2007, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.charset;
|
||||
|
||||
final class UConverterStaticData { /* +offset: size */
|
||||
int structSize; /* +0: 4 Size of this structure */
|
||||
|
||||
String name; /* +4: 60 internal name of the converter- invariant chars */
|
||||
|
||||
int codepage; /* +64: 4 codepage # (now IBM-$codepage) */
|
||||
|
||||
byte platform; /* +68: 1 platform of the converter (only IBM now) */
|
||||
byte conversionType; /* +69: 1 conversion type */
|
||||
|
||||
byte minBytesPerChar; /* +70: 1 Minimum # bytes per char in this codepage */
|
||||
byte maxBytesPerChar; /* +71: 1 Maximum # bytes output per UChar in this codepage */
|
||||
|
||||
byte subChar[/*UCNV_MAX_SUBCHAR_LEN*/]; /* +72: 4 [note: 4 and 8 byte boundary] */
|
||||
byte subCharLen; /* +76: 1 */
|
||||
|
||||
byte hasToUnicodeFallback; /* +77: 1 UBool needs to be changed to UBool to be consistent across platform */
|
||||
byte hasFromUnicodeFallback; /* +78: 1 */
|
||||
short unicodeMask; /* +79: 1 bit 0: has supplementary bit 1: has single surrogates */
|
||||
byte subChar1; /* +80: 1 single-byte substitution character for IBM MBCS (0 if none) */
|
||||
byte reserved[/*19*/]; /* +81: 19 to round out the structure */
|
||||
/* total size: 100 */
|
||||
public UConverterStaticData()
|
||||
{
|
||||
subChar = new byte[UConverterConstants.MAX_SUBCHAR_LEN];
|
||||
reserved = new byte[19];
|
||||
}
|
||||
|
||||
/* public UConverterStaticData(int structSize_, String name_, int codepage_, byte platform_, byte conversionType_, byte minBytesPerChar_, byte maxBytesPerChar_, byte[] subChar_, byte subCharLen_, byte hasToUnicodeFallback_, byte hasFromUnicodeFallback_, short unicodeMask_, byte subChar1_, byte[] reserved_)
|
||||
{
|
||||
structSize = structSize_;
|
||||
name = name_;
|
||||
codepage = codepage_;
|
||||
platform = platform_;
|
||||
conversionType = conversionType_;
|
||||
minBytesPerChar = minBytesPerChar_;
|
||||
maxBytesPerChar = maxBytesPerChar_;
|
||||
subChar = new byte[UConverterConstants.MAX_SUBCHAR_LEN];
|
||||
System.arraycopy(subChar_, 0, subChar, 0, (subChar.length < subChar_.length? subChar.length : subChar_.length));
|
||||
subCharLen = subCharLen_;
|
||||
hasToUnicodeFallback = hasToUnicodeFallback_;
|
||||
hasFromUnicodeFallback = hasFromUnicodeFallback_;
|
||||
unicodeMask = unicodeMask_;
|
||||
subChar1 = subChar1_;
|
||||
reserved = new byte[19];
|
||||
System.arraycopy(reserved_, 0, reserved, 0, (reserved.length < reserved_.length? reserved.length : reserved_.length));
|
||||
}*/
|
||||
|
||||
public static final int SIZE_OF_UCONVERTER_STATIC_DATA = 100;
|
||||
}
|
||||
|
15
main/classes/charset/src/com/ibm/icu/charset/package.html
Normal file
15
main/classes/charset/src/com/ibm/icu/charset/package.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head><!-- Copyright (C) 2006, International Business Machines Corporation and
|
||||
others. All Rights Reserved.
|
||||
-->
|
||||
|
||||
<title>C:ICU4J .charset Package Overview</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="white">
|
||||
|
||||
<p>Enhanced charset conversion support.</p>
|
||||
CharsetICU, CharsetProviderICU, CharsetEncoderICU and CharsetDecoderICU provide conversion services for many charsets.
|
||||
</body>
|
||||
</html>
|
7
main/classes/collate/.classpath
Normal file
7
main/classes/collate/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry excluding="**/.svn/" kind="src" path="src"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/icu4j-core"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||
<classpathentry kind="output" path="out/bin"/>
|
||||
</classpath>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
|
||||
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AFTER_CLEAN_TARGETS" value="copy-data,"/>
|
||||
<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="copy-data,"/>
|
||||
<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/icu4j-collate/build.xml"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="1"/>
|
||||
</listAttribute>
|
||||
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="icu4j-collate"/>
|
||||
<mapAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTIES">
|
||||
<mapEntry key="eclipse.running" value="true"/>
|
||||
<mapEntry key="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
|
||||
</mapAttribute>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_PROPERTY_FILES" value="${workspace_loc:/icu4j-shared/build/locations-eclipse.properties},"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/icu4j-collate/build.xml}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/>
|
||||
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
|
||||
</launchConfiguration>
|
29
main/classes/collate/.project
Normal file
29
main/classes/collate/.project
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>icu4j-collate</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
<project>icu4j-core</project>
|
||||
<project>icu4j-shared</project>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>LaunchConfigHandle</key>
|
||||
<value><project>/.externalToolBuilders/copy-data-collate.launch</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
345
main/classes/collate/.settings/org.eclipse.jdt.core.prefs
Normal file
345
main/classes/collate/.settings/org.eclipse.jdt.core.prefs
Normal file
|
@ -0,0 +1,345 @@
|
|||
#Thu Aug 27 17:46:56 EDT 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=120
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=120
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue