• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) 2001-2014, International Business Machines
7  *   Corporation and others.  All Rights Reserved.
8  **********************************************************************
9  *   Date        Name        Description
10  *   06/08/01    aliu        Creation.
11  **********************************************************************
12  */
13 
14 package ohos.global.icu.text;
15 import java.util.HashMap;
16 import java.util.Map;
17 
18 import ohos.global.icu.impl.Norm2AllModes;
19 import ohos.global.icu.impl.Normalizer2Impl;
20 
21 /**
22  * @author Alan Liu, Markus Scherer
23  */
24 final class NormalizationTransliterator extends Transliterator {
25     private final Normalizer2 norm2;
26 
27     /**
28      * System registration hook.
29      */
register()30     static void register() {
31         Transliterator.registerFactory("Any-NFC", new Transliterator.Factory() {
32             @Override
33             public Transliterator getInstance(String ID) {
34                 return new NormalizationTransliterator("NFC", Normalizer2.getNFCInstance());
35             }
36         });
37         Transliterator.registerFactory("Any-NFD", new Transliterator.Factory() {
38             @Override
39             public Transliterator getInstance(String ID) {
40                 return new NormalizationTransliterator("NFD", Normalizer2.getNFDInstance());
41             }
42         });
43         Transliterator.registerFactory("Any-NFKC", new Transliterator.Factory() {
44             @Override
45             public Transliterator getInstance(String ID) {
46                 return new NormalizationTransliterator("NFKC", Normalizer2.getNFKCInstance());
47             }
48         });
49         Transliterator.registerFactory("Any-NFKD", new Transliterator.Factory() {
50             @Override
51             public Transliterator getInstance(String ID) {
52                 return new NormalizationTransliterator("NFKD", Normalizer2.getNFKDInstance());
53             }
54         });
55         Transliterator.registerFactory("Any-FCD", new Transliterator.Factory() {
56             @Override
57             public Transliterator getInstance(String ID) {
58                 return new NormalizationTransliterator("FCD", Norm2AllModes.getFCDNormalizer2());
59             }
60         });
61         Transliterator.registerFactory("Any-FCC", new Transliterator.Factory() {
62             @Override
63             public Transliterator getInstance(String ID) {
64                 return new NormalizationTransliterator("FCC", Norm2AllModes.getNFCInstance().fcc);
65             }
66         });
67         Transliterator.registerSpecialInverse("NFC", "NFD", true);
68         Transliterator.registerSpecialInverse("NFKC", "NFKD", true);
69         Transliterator.registerSpecialInverse("FCC", "NFD", false);
70         Transliterator.registerSpecialInverse("FCD", "FCD", false);
71     }
72 
73     /**
74      * Constructs a transliterator.
75      */
NormalizationTransliterator(String id, Normalizer2 n2)76     private NormalizationTransliterator(String id, Normalizer2 n2) {
77         super(id, null);
78         norm2 = n2;
79     }
80 
81     /**
82      * Implements {@link Transliterator#handleTransliterate}.
83      */
84     @Override
handleTransliterate(Replaceable text, Position offsets, boolean isIncremental)85     protected void handleTransliterate(Replaceable text,
86             Position offsets, boolean isIncremental) {
87         // start and limit of the input range
88         int start = offsets.start;
89         int limit = offsets.limit;
90         if(start >= limit) {
91             return;
92         }
93 
94         /*
95          * Normalize as short chunks at a time as possible even in
96          * bulk mode, so that styled text is minimally disrupted.
97          * In incremental mode, a chunk that ends with offsets.limit
98          * must not be normalized.
99          *
100          * If it was known that the input text is not styled, then
101          * a bulk mode normalization could be used.
102          * (For details, see the comment in the C++ version.)
103          */
104         StringBuilder segment = new StringBuilder();
105         StringBuilder normalized = new StringBuilder();
106         int c = text.char32At(start);
107         do {
108             int prev = start;
109             // Skip at least one character so we make progress.
110             // c holds the character at start.
111             segment.setLength(0);
112             do {
113                 segment.appendCodePoint(c);
114                 start += Character.charCount(c);
115             } while(start < limit && !norm2.hasBoundaryBefore(c = text.char32At(start)));
116             if(start == limit && isIncremental && !norm2.hasBoundaryAfter(c)) {
117                 // stop in incremental mode when we reach the input limit
118                 // in case there are additional characters that could change the
119                 // normalization result
120                 start=prev;
121                 break;
122             }
123             norm2.normalize(segment, normalized);
124             if(!Normalizer2Impl.UTF16Plus.equal(segment, normalized)) {
125                 // replace the input chunk with its normalized form
126                 text.replace(prev, start, normalized.toString());
127 
128                 // update all necessary indexes accordingly
129                 int delta = normalized.length() - (start - prev);
130                 start += delta;
131                 limit += delta;
132             }
133         } while(start < limit);
134 
135         offsets.start = start;
136         offsets.contextLimit += limit - offsets.limit;
137         offsets.limit = limit;
138     }
139 
140     static final Map<Normalizer2, SourceTargetUtility> SOURCE_CACHE = new HashMap<Normalizer2, SourceTargetUtility>();
141 
142     // TODO Get rid of this if Normalizer2 becomes a Transform
143     static class NormalizingTransform implements Transform<String,String> {
144         final Normalizer2 norm2;
NormalizingTransform(Normalizer2 norm2)145         public NormalizingTransform(Normalizer2 norm2) {
146             this.norm2 = norm2;
147         }
148         @Override
transform(String source)149         public String transform(String source) {
150             return norm2.normalize(source);
151         }
152     }
153 
154     /* (non-Javadoc)
155      * @see ohos.global.icu.text.Transliterator#addSourceTargetSet(ohos.global.icu.text.UnicodeSet, ohos.global.icu.text.UnicodeSet, ohos.global.icu.text.UnicodeSet)
156      */
157     @Override
addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet)158     public void addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet) {
159         SourceTargetUtility cache;
160         synchronized (SOURCE_CACHE) {
161             //String id = getID();
162             cache = SOURCE_CACHE.get(norm2);
163             if (cache == null) {
164                 cache = new SourceTargetUtility(new NormalizingTransform(norm2), norm2);
165                 SOURCE_CACHE.put(norm2, cache);
166             }
167         }
168         cache.addSourceTargetSet(this, inputFilter, sourceSet, targetSet);
169     }
170 }
171