2 * Copyright (C) 1996-2004, International Business Machines Corporation and
\r
3 * others. All Rights Reserved.
\r
6 package com.ibm.icu.text;
\r
7 //import java.util.*;
\r
9 abstract class TransformTransliterator {
\r
14 // * An abstract class for transliterators based on a transform
\r
15 // * operation. To create a transliterator that implements a
\r
16 // * transformation, create a subclass of this class and implement the
\r
17 // * abstract <code>transform()</code> and <code>hasTransform()</code>
\r
19 // * @author Alan Liu
\r
21 //abstract class TransformTransliterator extends Transliterator {
\r
24 // * Constructs a transliterator. For use by subclasses.
\r
26 // protected TransformTransliterator(String id, UnicodeFilter f) {
\r
31 // * Implements {@link Transliterator#handleTransliterate}.
\r
33 // protected void handleTransliterate(Replaceable text,
\r
34 // Position offsets, boolean incremental) {
\r
37 // for (start = offsets.start; start < offsets.limit; ++start) {
\r
38 // // Scan for the first character that is != its transform.
\r
39 // // If there are none, we fall out without doing anything.
\r
40 // char c = text.charAt(start);
\r
41 // if (hasTransform(c)) {
\r
42 // // There is a transforming character at start. Break
\r
43 // // up the remaining string, from start to
\r
44 // // offsets.limit, into segments of unfiltered and
\r
45 // // filtered characters. Only transform the unfiltered
\r
46 // // characters. As always, minimize the number of
\r
47 // // calls to Replaceable.replace().
\r
49 // int len = offsets.limit - start;
\r
50 // // assert(len >= 1);
\r
52 // char[] buf = new char[len];
\r
53 // text.getChars(start, offsets.limit, buf, 0);
\r
55 // int segStart = 0;
\r
57 // UnicodeFilter filt = getFilter();
\r
59 // // lenDelta is the accumulated length difference for
\r
60 // // all transformed segments. It is new length - old
\r
62 // int lenDelta = 0;
\r
64 // // Set segStart, segLimit to the unfiltered segment
\r
65 // // starting with start. If the filter is null, then
\r
66 // // segStart/Limit will be set to the whole string,
\r
67 // // that is, 0/len.
\r
69 // // Set segLimit to the first filtered char at or
\r
70 // // after segStart.
\r
72 // if (filt != null) {
\r
73 // segLimit = segStart;
\r
74 // while (segLimit < len && filt.contains(buf[segLimit])) {
\r
79 // // Transform the unfiltered chars between segStart
\r
81 // int segLen = segLimit - segStart;
\r
82 // if (segLen != 0) {
\r
83 // String newStr = transform(
\r
84 // new String(buf, segStart, segLen));
\r
85 // text.replace(start, start + segLen, newStr);
\r
86 // start += newStr.length();
\r
87 // lenDelta += newStr.length() - segLen;
\r
90 // // Set segStart to the first unfiltered char at or
\r
91 // // after segLimit.
\r
92 // segStart = segLimit;
\r
93 // if (filt != null) {
\r
94 // while (segStart < len && !filt.contains(buf[segStart])) {
\r
98 // start += segStart - segLimit;
\r
100 // } while (segStart < len);
\r
102 // offsets.limit += lenDelta;
\r
103 // offsets.contextLimit += lenDelta;
\r
104 // offsets.start = offsets.limit;
\r
108 // // assert(start == offsets.limit);
\r
109 // offsets.start = start;
\r
113 // * Subclasses must implement this method to determine whether a
\r
114 // * given character has a transform that is not equal to itself.
\r
115 // * This is approximately equivalent to <code>c !=
\r
116 // * transform(String.valueOf(c))</code>, where
\r
117 // * <code>String.valueOf(c)</code> returns a String containing the
\r
118 // * single character (not integer) <code>c</code>. Subclasses that
\r
119 // * transform all their input can simply return <code>true</code>.
\r
121 // protected abstract boolean hasTransform(int c);
\r
124 // * Subclasses must implement this method to transform a string.
\r
126 // protected abstract String transform(String s);
\r