1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/*
5 *******************************************************************************
6 * Copyright (C) 2009-2011, Google, International Business Machines Corporation
7 * and others. All Rights Reserved.
8 *******************************************************************************
9 */
10package android.icu.text;
11
12import android.icu.impl.UCaseProps;
13import android.icu.lang.UCharacter;
14
15/**
16 * A transliterator that performs locale-sensitive toLower()
17 * case mapping.
18 */
19class CaseFoldTransliterator extends Transliterator{
20
21    /**
22     * Package accessible ID.
23     */
24    static final String _ID = "Any-CaseFold";
25
26    // TODO: Add variants for tr, az, lt, default = default locale
27
28    /**
29     * System registration hook.
30     */
31    static void register() {
32        Transliterator.registerFactory(_ID, new Transliterator.Factory() {
33            @Override
34            public Transliterator getInstance(String ID) {
35                return new CaseFoldTransliterator();
36            }
37        });
38
39        Transliterator.registerSpecialInverse("CaseFold", "Upper", false);
40    }
41
42    private final UCaseProps csp;
43    private ReplaceableContextIterator iter;
44    private StringBuilder result;
45
46    /**
47     * Constructs a transliterator.
48     */
49
50    public CaseFoldTransliterator() {
51        super(_ID, null);
52        csp=UCaseProps.INSTANCE;
53        iter=new ReplaceableContextIterator();
54        result = new StringBuilder();
55    }
56
57    /**
58     * Implements {@link Transliterator#handleTransliterate}.
59     */
60    @Override
61    protected synchronized void handleTransliterate(Replaceable text,
62                                       Position offsets, boolean isIncremental) {
63        if(csp==null) {
64            return;
65        }
66
67        if(offsets.start >= offsets.limit) {
68            return;
69        }
70
71        iter.setText(text);
72        result.setLength(0);
73        int c, delta;
74
75        // Walk through original string
76        // If there is a case change, modify corresponding position in replaceable
77
78        iter.setIndex(offsets.start);
79        iter.setLimit(offsets.limit);
80        iter.setContextLimits(offsets.contextStart, offsets.contextLimit);
81        while((c=iter.nextCaseMapCP())>=0) {
82            c=csp.toFullFolding(c, result, 0); // toFullFolding(int c, StringBuffer out, int options)
83
84            if(iter.didReachLimit() && isIncremental) {
85                // the case mapping function tried to look beyond the context limit
86                // wait for more input
87                offsets.start=iter.getCaseMapCPStart();
88                return;
89            }
90
91            /* decode the result */
92            if(c<0) {
93                /* c mapped to itself, no change */
94                continue;
95            } else if(c<=UCaseProps.MAX_STRING_LENGTH) {
96                /* replace by the mapping string */
97                delta=iter.replace(result.toString());
98                result.setLength(0);
99            } else {
100                /* replace by single-code point mapping */
101                delta=iter.replace(UTF16.valueOf(c));
102            }
103
104            if(delta!=0) {
105                offsets.limit += delta;
106                offsets.contextLimit += delta;
107            }
108        }
109        offsets.start = offsets.limit;
110    }
111
112    static SourceTargetUtility sourceTargetUtility = null;
113
114    /* (non-Javadoc)
115     * @see android.icu.text.Transliterator#addSourceTargetSet(android.icu.text.UnicodeSet, android.icu.text.UnicodeSet, android.icu.text.UnicodeSet)
116     */
117    @Override
118    public void addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet) {
119        synchronized (UppercaseTransliterator.class) {
120            if (sourceTargetUtility == null) {
121                sourceTargetUtility = new SourceTargetUtility(new Transform<String,String>() {
122                    @Override
123                    public String transform(String source) {
124                        return UCharacter.foldCase(source, true);
125                    }
126                });
127            }
128        }
129        sourceTargetUtility.addSourceTargetSet(this, inputFilter, sourceSet, targetSet);
130    }
131}
132