2 *******************************************************************************
3 * Copyright (C) 1996-2011, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.text;
9 import com.ibm.icu.impl.UCaseProps;
10 import com.ibm.icu.lang.UCharacter;
11 import com.ibm.icu.util.ULocale;
14 * A transliterator that performs locale-sensitive toLower()
17 class LowercaseTransliterator extends Transliterator{
20 * Package accessible ID.
22 static final String _ID = "Any-Lower";
24 // TODO: Add variants for tr, az, lt, default = default locale
27 * System registration hook.
29 static void register() {
30 Transliterator.registerFactory(_ID, new Transliterator.Factory() {
31 public Transliterator getInstance(String ID) {
32 return new LowercaseTransliterator(ULocale.US);
36 Transliterator.registerSpecialInverse("Lower", "Upper", true);
39 private ULocale locale;
41 private UCaseProps csp;
42 private ReplaceableContextIterator iter;
43 private StringBuilder result;
44 private int[] locCache;
47 * Constructs a transliterator.
50 public LowercaseTransliterator(ULocale loc) {
53 csp=UCaseProps.INSTANCE;
54 iter=new ReplaceableContextIterator();
55 result = new StringBuilder();
56 locCache = new int[1];
61 * Implements {@link Transliterator#handleTransliterate}.
63 protected synchronized void handleTransliterate(Replaceable text,
64 Position offsets, boolean isIncremental) {
69 if(offsets.start >= offsets.limit) {
77 // Walk through original string
78 // If there is a case change, modify corresponding position in replaceable
80 iter.setIndex(offsets.start);
81 iter.setLimit(offsets.limit);
82 iter.setContextLimits(offsets.contextStart, offsets.contextLimit);
83 while((c=iter.nextCaseMapCP())>=0) {
84 c=csp.toFullLower(c, iter, result, locale, locCache);
86 if(iter.didReachLimit() && isIncremental) {
87 // the case mapping function tried to look beyond the context limit
88 // wait for more input
89 offsets.start=iter.getCaseMapCPStart();
93 /* decode the result */
95 /* c mapped to itself, no change */
97 } else if(c<=UCaseProps.MAX_STRING_LENGTH) {
98 /* replace by the mapping string */
99 delta=iter.replace(result.toString());
102 /* replace by single-code point mapping */
103 delta=iter.replace(UTF16.valueOf(c));
107 offsets.limit += delta;
108 offsets.contextLimit += delta;
111 offsets.start = offsets.limit;
114 // NOTE: normally this would be static, but because the results vary by locale....
115 SourceTargetUtility sourceTargetUtility = null;
118 * @see com.ibm.icu.text.Transliterator#addSourceTargetSet(com.ibm.icu.text.UnicodeSet, com.ibm.icu.text.UnicodeSet, com.ibm.icu.text.UnicodeSet)
121 public void addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet) {
122 synchronized (this) {
123 if (sourceTargetUtility == null) {
124 sourceTargetUtility = new SourceTargetUtility(new Transform<String,String>() {
125 public String transform(String source) {
126 return UCharacter.toLowerCase(locale, source);
131 sourceTargetUtility.addSourceTargetSet(this, inputFilter, sourceSet, targetSet);