2 *******************************************************************************
3 * Copyright (C) 2009-2011, Google, International Business Machines Corporation
4 * and 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;
13 * A transliterator that performs locale-sensitive toLower()
16 class CaseFoldTransliterator extends Transliterator{
19 * Package accessible ID.
21 static final String _ID = "Any-CaseFold";
23 // TODO: Add variants for tr, az, lt, default = default locale
26 * System registration hook.
28 static void register() {
29 Transliterator.registerFactory(_ID, new Transliterator.Factory() {
30 public Transliterator getInstance(String ID) {
31 return new CaseFoldTransliterator();
35 Transliterator.registerSpecialInverse("CaseFold", "Upper", false);
38 private UCaseProps csp;
39 private ReplaceableContextIterator iter;
40 private StringBuilder result;
43 * Constructs a transliterator.
46 public CaseFoldTransliterator() {
48 csp=UCaseProps.INSTANCE;
49 iter=new ReplaceableContextIterator();
50 result = new StringBuilder();
54 * Implements {@link Transliterator#handleTransliterate}.
56 protected synchronized void handleTransliterate(Replaceable text,
57 Position offsets, boolean isIncremental) {
62 if(offsets.start >= offsets.limit) {
70 // Walk through original string
71 // If there is a case change, modify corresponding position in replaceable
73 iter.setIndex(offsets.start);
74 iter.setLimit(offsets.limit);
75 iter.setContextLimits(offsets.contextStart, offsets.contextLimit);
76 while((c=iter.nextCaseMapCP())>=0) {
77 c=csp.toFullFolding(c, result, 0); // toFullFolding(int c, StringBuffer out, int options)
79 if(iter.didReachLimit() && isIncremental) {
80 // the case mapping function tried to look beyond the context limit
81 // wait for more input
82 offsets.start=iter.getCaseMapCPStart();
86 /* decode the result */
88 /* c mapped to itself, no change */
90 } else if(c<=UCaseProps.MAX_STRING_LENGTH) {
91 /* replace by the mapping string */
92 delta=iter.replace(result.toString());
95 /* replace by single-code point mapping */
96 delta=iter.replace(UTF16.valueOf(c));
100 offsets.limit += delta;
101 offsets.contextLimit += delta;
104 offsets.start = offsets.limit;
107 static SourceTargetUtility sourceTargetUtility = null;
110 * @see com.ibm.icu.text.Transliterator#addSourceTargetSet(com.ibm.icu.text.UnicodeSet, com.ibm.icu.text.UnicodeSet, com.ibm.icu.text.UnicodeSet)
113 public void addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet) {
114 synchronized (UppercaseTransliterator.class) {
115 if (sourceTargetUtility == null) {
116 sourceTargetUtility = new SourceTargetUtility(new Transform<String,String>() {
117 public String transform(String source) {
118 return UCharacter.foldCase(source, true);
123 sourceTargetUtility.addSourceTargetSet(this, inputFilter, sourceSet, targetSet);