2 *******************************************************************************
\r
3 * Copyright (C) 1996-2007, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.text;
\r
9 import java.io.IOException;
\r
11 import com.ibm.icu.impl.UCaseProps;
\r
13 import com.ibm.icu.util.ULocale;
\r
15 import com.ibm.icu.text.ReplaceableContextIterator;
\r
18 * A transliterator that performs locale-sensitive toLower()
\r
21 class LowercaseTransliterator extends Transliterator{
\r
24 * Package accessible ID.
\r
26 static final String _ID = "Any-Lower";
\r
28 // TODO: Add variants for tr, az, lt, default = default locale
\r
31 * System registration hook.
\r
33 static void register() {
\r
34 Transliterator.registerFactory(_ID, new Transliterator.Factory() {
\r
35 public Transliterator getInstance(String ID) {
\r
36 return new LowercaseTransliterator(ULocale.US);
\r
40 Transliterator.registerSpecialInverse("Lower", "Upper", true);
\r
43 private ULocale locale;
\r
45 private UCaseProps csp;
\r
46 private ReplaceableContextIterator iter;
\r
47 private StringBuffer result;
\r
48 private int[] locCache;
\r
51 * Constructs a transliterator.
\r
54 public LowercaseTransliterator(ULocale loc) {
\r
58 csp=UCaseProps.getSingleton();
\r
59 } catch (IOException e) {
\r
62 iter=new ReplaceableContextIterator();
\r
63 result = new StringBuffer();
\r
64 locCache = new int[1];
\r
69 * Implements {@link Transliterator#handleTransliterate}.
\r
71 protected void handleTransliterate(Replaceable text,
\r
72 Position offsets, boolean isIncremental) {
\r
77 if(offsets.start >= offsets.limit) {
\r
82 result.setLength(0);
\r
85 // Walk through original string
\r
86 // If there is a case change, modify corresponding position in replaceable
\r
88 iter.setIndex(offsets.start);
\r
89 iter.setLimit(offsets.limit);
\r
90 iter.setContextLimits(offsets.contextStart, offsets.contextLimit);
\r
91 while((c=iter.nextCaseMapCP())>=0) {
\r
92 c=csp.toFullLower(c, iter, result, locale, locCache);
\r
94 if(iter.didReachLimit() && isIncremental) {
\r
95 // the case mapping function tried to look beyond the context limit
\r
96 // wait for more input
\r
97 offsets.start=iter.getCaseMapCPStart();
\r
101 /* decode the result */
\r
103 /* c mapped to itself, no change */
\r
105 } else if(c<=UCaseProps.MAX_STRING_LENGTH) {
\r
106 /* replace by the mapping string */
\r
107 delta=iter.replace(result.toString());
\r
108 result.setLength(0);
\r
110 /* replace by single-code point mapping */
\r
111 delta=iter.replace(UTF16.valueOf(c));
\r
115 offsets.limit += delta;
\r
116 offsets.contextLimit += delta;
\r
119 offsets.start = offsets.limit;
\r