• 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  * Copyright (C) 1996-2011, International Business Machines Corporation and
6  * others. All Rights Reserved.
7  */
8 package ohos.global.icu.text;
9 import ohos.global.icu.impl.PatternProps;
10 import ohos.global.icu.impl.UCharacterName;
11 import ohos.global.icu.impl.Utility;
12 import ohos.global.icu.lang.UCharacter;
13 
14 /**
15  * A transliterator that performs name to character mapping.
16  * @author Alan Liu
17  */
18 class NameUnicodeTransliterator extends Transliterator {
19 
20     static final String _ID = "Name-Any";
21 
22     static final String OPEN_PAT    = "\\N~{~";
23     static final char   OPEN_DELIM  = '\\'; // first char of OPEN_PAT
24     static final char   CLOSE_DELIM = '}';
25     static final char   SPACE       = ' ';
26 
27 
28     /**
29      * System registration hook.
30      */
register()31     static void register() {
32         Transliterator.registerFactory(_ID, new Transliterator.Factory() {
33             @Override
34             public Transliterator getInstance(String ID) {
35                 return new NameUnicodeTransliterator(null);
36             }
37         });
38     }
39 
40     /**
41      * Constructs a transliterator.
42      */
NameUnicodeTransliterator(UnicodeFilter filter)43     public NameUnicodeTransliterator(UnicodeFilter filter) {
44         super(_ID, filter);
45     }
46 
47     /**
48      * Implements {@link Transliterator#handleTransliterate}.
49      */
50     @Override
handleTransliterate(Replaceable text, Position offsets, boolean isIncremental)51     protected void handleTransliterate(Replaceable text,
52                                        Position offsets, boolean isIncremental) {
53 
54         int maxLen = UCharacterName.INSTANCE.getMaxCharNameLength() + 1; // allow for temporary trailing space
55 
56         StringBuffer name = new StringBuffer(maxLen);
57 
58         // Get the legal character set
59         UnicodeSet legal = new UnicodeSet();
60         UCharacterName.INSTANCE.getCharNameCharacters(legal);
61 
62         int cursor = offsets.start;
63         int limit = offsets.limit;
64 
65         // Modes:
66         // 0 - looking for open delimiter
67         // 1 - after open delimiter
68         int mode = 0;
69         int openPos = -1; // open delim candidate pos
70 
71         int c;
72         while (cursor < limit) {
73             c = text.char32At(cursor);
74 
75             switch (mode) {
76             case 0: // looking for open delimiter
77                 if (c == OPEN_DELIM) { // quick check first
78                     openPos = cursor;
79                     int i = Utility.parsePattern(OPEN_PAT, text, cursor, limit);
80                     if (i >= 0 && i < limit) {
81                         mode = 1;
82                         name.setLength(0);
83                         cursor = i;
84                         continue; // *** reprocess char32At(cursor)
85                     }
86                 }
87                 break;
88 
89             case 1: // after open delimiter
90                 // Look for legal chars.  If \s+ is found, convert it
91                 // to a single space.  If closeDelimiter is found, exit
92                 // the loop.  If any other character is found, exit the
93                 // loop.  If the limit is reached, exit the loop.
94 
95                 // Convert \s+ => SPACE.  This assumes there are no
96                 // runs of >1 space characters in names.
97                 if (PatternProps.isWhiteSpace(c)) {
98                     // Ignore leading whitespace
99                     if (name.length() > 0 &&
100                         name.charAt(name.length()-1) != SPACE) {
101                         name.append(SPACE);
102                         // If we are too long then abort.  maxLen includes
103                         // temporary trailing space, so use '>'.
104                         if (name.length() > maxLen) {
105                             mode = 0;
106                         }
107                     }
108                     break;
109                 }
110 
111                 if (c == CLOSE_DELIM) {
112 
113                     int len = name.length();
114 
115                     // Delete trailing space, if any
116                     if (len > 0 &&
117                         name.charAt(len-1) == SPACE) {
118                         name.setLength(--len);
119                     }
120 
121                     c = UCharacter.getCharFromExtendedName(name.toString());
122                     if (c != -1) {
123                         // Lookup succeeded
124 
125                         // assert(UTF16.getCharCount(CLOSE_DELIM) == 1);
126                         cursor++; // advance over CLOSE_DELIM
127 
128                         String str = UTF16.valueOf(c);
129                         text.replace(openPos, cursor, str);
130 
131                         // Adjust indices for the change in the length of
132                         // the string.  Do not assume that str.length() ==
133                         // 1, in case of surrogates.
134                         int delta = cursor - openPos - str.length();
135                         cursor -= delta;
136                         limit -= delta;
137                         // assert(cursor == openPos + str.length());
138                     }
139                     // If the lookup failed, we leave things as-is and
140                     // still switch to mode 0 and continue.
141                     mode = 0;
142                     openPos = -1; // close off candidate
143                     continue; // *** reprocess char32At(cursor)
144                 }
145 
146                 if (legal.contains(c)) {
147                     UTF16.append(name, c);
148                     // If we go past the longest possible name then abort.
149                     // maxLen includes temporary trailing space, so use '>='.
150                     if (name.length() >= maxLen) {
151                         mode = 0;
152                     }
153                 }
154 
155                 // Invalid character
156                 else {
157                     --cursor; // Backup and reprocess this character
158                     mode = 0;
159                 }
160 
161                 break;
162             }
163 
164             cursor += UTF16.getCharCount(c);
165         }
166 
167         offsets.contextLimit += limit - offsets.limit;
168         offsets.limit = limit;
169         // In incremental mode, only advance the cursor up to the last
170         // open delimiter candidate.
171         offsets.start = (isIncremental && openPos >= 0) ? openPos : cursor;
172     }
173 
174     /* (non-Javadoc)
175      * @see ohos.global.icu.text.Transliterator#addSourceTargetSet(ohos.global.icu.text.UnicodeSet, ohos.global.icu.text.UnicodeSet, ohos.global.icu.text.UnicodeSet)
176      */
177     @Override
addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet)178     public void addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet) {
179         UnicodeSet myFilter = getFilterAsUnicodeSet(inputFilter);
180         if (!myFilter.containsAll(UnicodeNameTransliterator.OPEN_DELIM) || !myFilter.contains(CLOSE_DELIM)) {
181             return; // we have to contain both prefix and suffix
182         }
183         UnicodeSet items = new UnicodeSet()
184         .addAll('0', '9')
185         .addAll('A', 'F')
186         .addAll('a', 'z') // for controls
187         .add('<').add('>') // for controls
188         .add('(').add(')') // for controls
189         .add('-')
190         .add(' ')
191         .addAll(UnicodeNameTransliterator.OPEN_DELIM)
192         .add(CLOSE_DELIM);
193         items.retainAll(myFilter);
194         if (items.size() > 0) {
195             sourceSet.addAll(items);
196             // could produce any character
197             targetSet.addAll(0, 0x10FFFF);
198         }
199     }
200 }
201