001: /*
002: *******************************************************************************
003: * Copyright (C) 1996-2005, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */
007: package com.ibm.icu.text;
008:
009: import java.io.IOException;
010:
011: import com.ibm.icu.impl.UCaseProps;
012:
013: import com.ibm.icu.util.ULocale;
014:
015: import com.ibm.icu.text.ReplaceableContextIterator;
016:
017: /**
018: * A transliterator that performs locale-sensitive toUpper()
019: * case mapping.
020: */
021: class UppercaseTransliterator extends Transliterator {
022:
023: /**
024: * Package accessible ID.
025: */
026: static final String _ID = "Any-Upper";
027:
028: // TODO: Add variants for tr, az, lt, default = default locale
029:
030: /**
031: * System registration hook.
032: */
033: static void register() {
034: Transliterator.registerFactory(_ID,
035: new Transliterator.Factory() {
036: public Transliterator getInstance(String ID) {
037: return new UppercaseTransliterator(ULocale.US);
038: }
039: });
040: }
041:
042: private ULocale locale;
043:
044: private UCaseProps csp;
045: private ReplaceableContextIterator iter;
046: private StringBuffer result;
047: private int[] locCache;
048:
049: /**
050: * Constructs a transliterator.
051: */
052: public UppercaseTransliterator(ULocale loc) {
053: super (_ID, null);
054: locale = loc;
055: try {
056: csp = UCaseProps.getSingleton();
057: } catch (IOException e) {
058: csp = null;
059: }
060: iter = new ReplaceableContextIterator();
061: result = new StringBuffer();
062: int[] locCache = new int[1];
063: locCache[0] = 0;
064: }
065:
066: /**
067: * Implements {@link Transliterator#handleTransliterate}.
068: */
069: protected void handleTransliterate(Replaceable text,
070: Position offsets, boolean isIncremental) {
071: if (csp == null) {
072: return;
073: }
074:
075: if (offsets.start >= offsets.limit) {
076: return;
077: }
078:
079: iter.setText(text);
080: result.setLength(0);
081: int c, delta;
082:
083: // Walk through original string
084: // If there is a case change, modify corresponding position in replaceable
085:
086: iter.setIndex(offsets.start);
087: iter.setLimit(offsets.limit);
088: iter.setContextLimits(offsets.contextStart,
089: offsets.contextLimit);
090: while ((c = iter.nextCaseMapCP()) >= 0) {
091: c = csp.toFullUpper(c, iter, result, locale, locCache);
092:
093: if (iter.didReachLimit() && isIncremental) {
094: // the case mapping function tried to look beyond the context limit
095: // wait for more input
096: offsets.start = iter.getCaseMapCPStart();
097: return;
098: }
099:
100: /* decode the result */
101: if (c < 0) {
102: /* c mapped to itself, no change */
103: continue;
104: } else if (c <= UCaseProps.MAX_STRING_LENGTH) {
105: /* replace by the mapping string */
106: delta = iter.replace(result.toString());
107: result.setLength(0);
108: } else {
109: /* replace by single-code point mapping */
110: delta = iter.replace(UTF16.valueOf(c));
111: }
112:
113: if (delta != 0) {
114: offsets.limit += delta;
115: offsets.contextLimit += delta;
116: }
117: }
118: offsets.start = offsets.limit;
119: }
120: }
|