Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: source/common/normalizer2.cpp

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/common/norm2allmodes.h ('k') | source/common/normalizer2impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ******************************************************************************* 2 *******************************************************************************
3 * 3 *
4 * Copyright (C) 2009-2013, International Business Machines 4 * Copyright (C) 2009-2014, International Business Machines
5 * Corporation and others. All Rights Reserved. 5 * Corporation and others. All Rights Reserved.
6 * 6 *
7 ******************************************************************************* 7 *******************************************************************************
8 * file name: normalizer2.cpp 8 * file name: normalizer2.cpp
9 * encoding: US-ASCII 9 * encoding: US-ASCII
10 * tab size: 8 (not used) 10 * tab size: 8 (not used)
11 * indentation:4 11 * indentation:4
12 * 12 *
13 * created on: 2009nov22 13 * created on: 2009nov22
14 * created by: Markus W. Scherer 14 * created by: Markus W. Scherer
15 */ 15 */
16 16
17 #include "unicode/utypes.h" 17 #include "unicode/utypes.h"
18 18
19 #if !UCONFIG_NO_NORMALIZATION 19 #if !UCONFIG_NO_NORMALIZATION
20 20
21 #include "unicode/localpointer.h"
22 #include "unicode/normalizer2.h" 21 #include "unicode/normalizer2.h"
23 #include "unicode/unistr.h" 22 #include "unicode/unistr.h"
24 #include "unicode/unorm.h" 23 #include "unicode/unorm.h"
25 #include "cpputils.h"
26 #include "cstring.h" 24 #include "cstring.h"
27 #include "mutex.h" 25 #include "mutex.h"
26 #include "norm2allmodes.h"
28 #include "normalizer2impl.h" 27 #include "normalizer2impl.h"
29 #include "uassert.h" 28 #include "uassert.h"
30 #include "ucln_cmn.h" 29 #include "ucln_cmn.h"
31 #include "uhash.h" 30
31 using icu::Normalizer2Impl;
32
33 // NFC/NFD data machine-generated by gennorm2 --csource
34 #include "norm2_nfc_data.h"
32 35
33 U_NAMESPACE_BEGIN 36 U_NAMESPACE_BEGIN
34 37
35 // Public API dispatch via Normalizer2 subclasses -------------------------- *** 38 // Public API dispatch via Normalizer2 subclasses -------------------------- ***
36 39
37 Normalizer2::~Normalizer2() {} 40 Normalizer2::~Normalizer2() {}
38 41
39 UBool 42 UBool
40 Normalizer2::getRawDecomposition(UChar32, UnicodeString &) const { 43 Normalizer2::getRawDecomposition(UChar32, UnicodeString &) const {
41 return FALSE; 44 return FALSE;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 spanQuickCheckYes(const UnicodeString &s, UErrorCode &) const { 114 spanQuickCheckYes(const UnicodeString &s, UErrorCode &) const {
112 return s.length(); 115 return s.length();
113 } 116 }
114 virtual UBool hasBoundaryBefore(UChar32) const { return TRUE; } 117 virtual UBool hasBoundaryBefore(UChar32) const { return TRUE; }
115 virtual UBool hasBoundaryAfter(UChar32) const { return TRUE; } 118 virtual UBool hasBoundaryAfter(UChar32) const { return TRUE; }
116 virtual UBool isInert(UChar32) const { return TRUE; } 119 virtual UBool isInert(UChar32) const { return TRUE; }
117 }; 120 };
118 121
119 NoopNormalizer2::~NoopNormalizer2() {} 122 NoopNormalizer2::~NoopNormalizer2() {}
120 123
121 // Intermediate class:
122 // Has Normalizer2Impl and does boilerplate argument checking and setup.
123 class Normalizer2WithImpl : public Normalizer2 {
124 public:
125 Normalizer2WithImpl(const Normalizer2Impl &ni) : impl(ni) {}
126 virtual ~Normalizer2WithImpl();
127
128 // normalize
129 virtual UnicodeString &
130 normalize(const UnicodeString &src,
131 UnicodeString &dest,
132 UErrorCode &errorCode) const {
133 if(U_FAILURE(errorCode)) {
134 dest.setToBogus();
135 return dest;
136 }
137 const UChar *sArray=src.getBuffer();
138 if(&dest==&src || sArray==NULL) {
139 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
140 dest.setToBogus();
141 return dest;
142 }
143 dest.remove();
144 ReorderingBuffer buffer(impl, dest);
145 if(buffer.init(src.length(), errorCode)) {
146 normalize(sArray, sArray+src.length(), buffer, errorCode);
147 }
148 return dest;
149 }
150 virtual void
151 normalize(const UChar *src, const UChar *limit,
152 ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
153
154 // normalize and append
155 virtual UnicodeString &
156 normalizeSecondAndAppend(UnicodeString &first,
157 const UnicodeString &second,
158 UErrorCode &errorCode) const {
159 return normalizeSecondAndAppend(first, second, TRUE, errorCode);
160 }
161 virtual UnicodeString &
162 append(UnicodeString &first,
163 const UnicodeString &second,
164 UErrorCode &errorCode) const {
165 return normalizeSecondAndAppend(first, second, FALSE, errorCode);
166 }
167 UnicodeString &
168 normalizeSecondAndAppend(UnicodeString &first,
169 const UnicodeString &second,
170 UBool doNormalize,
171 UErrorCode &errorCode) const {
172 uprv_checkCanGetBuffer(first, errorCode);
173 if(U_FAILURE(errorCode)) {
174 return first;
175 }
176 const UChar *secondArray=second.getBuffer();
177 if(&first==&second || secondArray==NULL) {
178 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
179 return first;
180 }
181 int32_t firstLength=first.length();
182 UnicodeString safeMiddle;
183 {
184 ReorderingBuffer buffer(impl, first);
185 if(buffer.init(firstLength+second.length(), errorCode)) {
186 normalizeAndAppend(secondArray, secondArray+second.length(), doN ormalize,
187 safeMiddle, buffer, errorCode);
188 }
189 } // The ReorderingBuffer destructor finalizes the first string.
190 if(U_FAILURE(errorCode)) {
191 // Restore the modified suffix of the first string.
192 first.replace(firstLength-safeMiddle.length(), 0x7fffffff, safeMiddl e);
193 }
194 return first;
195 }
196 virtual void
197 normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
198 UnicodeString &safeMiddle,
199 ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
200 virtual UBool
201 getDecomposition(UChar32 c, UnicodeString &decomposition) const {
202 UChar buffer[4];
203 int32_t length;
204 const UChar *d=impl.getDecomposition(c, buffer, length);
205 if(d==NULL) {
206 return FALSE;
207 }
208 if(d==buffer) {
209 decomposition.setTo(buffer, length); // copy the string (Jamos from Hangul syllable c)
210 } else {
211 decomposition.setTo(FALSE, d, length); // read-only alias
212 }
213 return TRUE;
214 }
215 virtual UBool
216 getRawDecomposition(UChar32 c, UnicodeString &decomposition) const {
217 UChar buffer[30];
218 int32_t length;
219 const UChar *d=impl.getRawDecomposition(c, buffer, length);
220 if(d==NULL) {
221 return FALSE;
222 }
223 if(d==buffer) {
224 decomposition.setTo(buffer, length); // copy the string (algorithmi c decomposition)
225 } else {
226 decomposition.setTo(FALSE, d, length); // read-only alias
227 }
228 return TRUE;
229 }
230 virtual UChar32
231 composePair(UChar32 a, UChar32 b) const {
232 return impl.composePair(a, b);
233 }
234
235 virtual uint8_t
236 getCombiningClass(UChar32 c) const {
237 return impl.getCC(impl.getNorm16(c));
238 }
239
240 // quick checks
241 virtual UBool
242 isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
243 if(U_FAILURE(errorCode)) {
244 return FALSE;
245 }
246 const UChar *sArray=s.getBuffer();
247 if(sArray==NULL) {
248 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
249 return FALSE;
250 }
251 const UChar *sLimit=sArray+s.length();
252 return sLimit==spanQuickCheckYes(sArray, sLimit, errorCode);
253 }
254 virtual UNormalizationCheckResult
255 quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
256 return Normalizer2WithImpl::isNormalized(s, errorCode) ? UNORM_YES : UNO RM_NO;
257 }
258 virtual int32_t
259 spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const {
260 if(U_FAILURE(errorCode)) {
261 return 0;
262 }
263 const UChar *sArray=s.getBuffer();
264 if(sArray==NULL) {
265 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
266 return 0;
267 }
268 return (int32_t)(spanQuickCheckYes(sArray, sArray+s.length(), errorCode) -sArray);
269 }
270 virtual const UChar *
271 spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCod e) const = 0;
272
273 virtual UNormalizationCheckResult getQuickCheck(UChar32) const {
274 return UNORM_YES;
275 }
276
277 const Normalizer2Impl &impl;
278 };
279
280 Normalizer2WithImpl::~Normalizer2WithImpl() {} 124 Normalizer2WithImpl::~Normalizer2WithImpl() {}
281 125
282 class DecomposeNormalizer2 : public Normalizer2WithImpl {
283 public:
284 DecomposeNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
285 virtual ~DecomposeNormalizer2();
286
287 private:
288 virtual void
289 normalize(const UChar *src, const UChar *limit,
290 ReorderingBuffer &buffer, UErrorCode &errorCode) const {
291 impl.decompose(src, limit, &buffer, errorCode);
292 }
293 using Normalizer2WithImpl::normalize; // Avoid warning about hiding base cl ass function.
294 virtual void
295 normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
296 UnicodeString &safeMiddle,
297 ReorderingBuffer &buffer, UErrorCode &errorCode) const {
298 impl.decomposeAndAppend(src, limit, doNormalize, safeMiddle, buffer, err orCode);
299 }
300 virtual const UChar *
301 spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCod e) const {
302 return impl.decompose(src, limit, NULL, errorCode);
303 }
304 using Normalizer2WithImpl::spanQuickCheckYes; // Avoid warning about hiding base class function.
305 virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
306 return impl.isDecompYes(impl.getNorm16(c)) ? UNORM_YES : UNORM_NO;
307 }
308 virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasDecompBoun dary(c, TRUE); }
309 virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasDecompBound ary(c, FALSE); }
310 virtual UBool isInert(UChar32 c) const { return impl.isDecompInert(c); }
311 };
312
313 DecomposeNormalizer2::~DecomposeNormalizer2() {} 126 DecomposeNormalizer2::~DecomposeNormalizer2() {}
314 127
315 class ComposeNormalizer2 : public Normalizer2WithImpl {
316 public:
317 ComposeNormalizer2(const Normalizer2Impl &ni, UBool fcc) :
318 Normalizer2WithImpl(ni), onlyContiguous(fcc) {}
319 virtual ~ComposeNormalizer2();
320
321 private:
322 virtual void
323 normalize(const UChar *src, const UChar *limit,
324 ReorderingBuffer &buffer, UErrorCode &errorCode) const {
325 impl.compose(src, limit, onlyContiguous, TRUE, buffer, errorCode);
326 }
327 using Normalizer2WithImpl::normalize; // Avoid warning about hiding base cl ass function.
328 virtual void
329 normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
330 UnicodeString &safeMiddle,
331 ReorderingBuffer &buffer, UErrorCode &errorCode) const {
332 impl.composeAndAppend(src, limit, doNormalize, onlyContiguous, safeMiddl e, buffer, errorCode);
333 }
334
335 virtual UBool
336 isNormalized(const UnicodeString &s, UErrorCode &errorCode) const {
337 if(U_FAILURE(errorCode)) {
338 return FALSE;
339 }
340 const UChar *sArray=s.getBuffer();
341 if(sArray==NULL) {
342 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
343 return FALSE;
344 }
345 UnicodeString temp;
346 ReorderingBuffer buffer(impl, temp);
347 if(!buffer.init(5, errorCode)) { // small destCapacity for substring no rmalization
348 return FALSE;
349 }
350 return impl.compose(sArray, sArray+s.length(), onlyContiguous, FALSE, bu ffer, errorCode);
351 }
352 virtual UNormalizationCheckResult
353 quickCheck(const UnicodeString &s, UErrorCode &errorCode) const {
354 if(U_FAILURE(errorCode)) {
355 return UNORM_MAYBE;
356 }
357 const UChar *sArray=s.getBuffer();
358 if(sArray==NULL) {
359 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
360 return UNORM_MAYBE;
361 }
362 UNormalizationCheckResult qcResult=UNORM_YES;
363 impl.composeQuickCheck(sArray, sArray+s.length(), onlyContiguous, &qcRes ult);
364 return qcResult;
365 }
366 virtual const UChar *
367 spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &) const {
368 return impl.composeQuickCheck(src, limit, onlyContiguous, NULL);
369 }
370 using Normalizer2WithImpl::spanQuickCheckYes; // Avoid warning about hiding base class function.
371 virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const {
372 return impl.getCompQuickCheck(impl.getNorm16(c));
373 }
374 virtual UBool hasBoundaryBefore(UChar32 c) const {
375 return impl.hasCompBoundaryBefore(c);
376 }
377 virtual UBool hasBoundaryAfter(UChar32 c) const {
378 return impl.hasCompBoundaryAfter(c, onlyContiguous, FALSE);
379 }
380 virtual UBool isInert(UChar32 c) const {
381 return impl.hasCompBoundaryAfter(c, onlyContiguous, TRUE);
382 }
383
384 const UBool onlyContiguous;
385 };
386
387 ComposeNormalizer2::~ComposeNormalizer2() {} 128 ComposeNormalizer2::~ComposeNormalizer2() {}
388 129
389 class FCDNormalizer2 : public Normalizer2WithImpl {
390 public:
391 FCDNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
392 virtual ~FCDNormalizer2();
393
394 private:
395 virtual void
396 normalize(const UChar *src, const UChar *limit,
397 ReorderingBuffer &buffer, UErrorCode &errorCode) const {
398 impl.makeFCD(src, limit, &buffer, errorCode);
399 }
400 using Normalizer2WithImpl::normalize; // Avoid warning about hiding base cl ass function.
401 virtual void
402 normalizeAndAppend(const UChar *src, const UChar *limit, UBool doNormalize,
403 UnicodeString &safeMiddle,
404 ReorderingBuffer &buffer, UErrorCode &errorCode) const {
405 impl.makeFCDAndAppend(src, limit, doNormalize, safeMiddle, buffer, error Code);
406 }
407 virtual const UChar *
408 spanQuickCheckYes(const UChar *src, const UChar *limit, UErrorCode &errorCod e) const {
409 return impl.makeFCD(src, limit, NULL, errorCode);
410 }
411 using Normalizer2WithImpl::spanQuickCheckYes; // Avoid warning about hiding base class function.
412 virtual UBool hasBoundaryBefore(UChar32 c) const { return impl.hasFCDBoundar yBefore(c); }
413 virtual UBool hasBoundaryAfter(UChar32 c) const { return impl.hasFCDBoundary After(c); }
414 virtual UBool isInert(UChar32 c) const { return impl.isFCDInert(c); }
415 };
416
417 FCDNormalizer2::~FCDNormalizer2() {} 130 FCDNormalizer2::~FCDNormalizer2() {}
418 131
419 // instance cache ---------------------------------------------------------- *** 132 // instance cache ---------------------------------------------------------- ***
420 133
421 struct Norm2AllModes : public UMemory { 134 Norm2AllModes::~Norm2AllModes() {
422 static Norm2AllModes *createInstance(const char *packageName, 135 delete impl;
423 const char *name, 136 }
424 UErrorCode &errorCode);
425 Norm2AllModes() : comp(impl, FALSE), decomp(impl), fcd(impl), fcc(impl, TRUE ) {}
426
427 Normalizer2Impl impl;
428 ComposeNormalizer2 comp;
429 DecomposeNormalizer2 decomp;
430 FCDNormalizer2 fcd;
431 ComposeNormalizer2 fcc;
432 };
433 137
434 Norm2AllModes * 138 Norm2AllModes *
435 Norm2AllModes::createInstance(const char *packageName, 139 Norm2AllModes::createInstance(Normalizer2Impl *impl, UErrorCode &errorCode) {
436 const char *name, 140 if(U_FAILURE(errorCode)) {
437 UErrorCode &errorCode) { 141 delete impl;
142 return NULL;
143 }
144 Norm2AllModes *allModes=new Norm2AllModes(impl);
145 if(allModes==NULL) {
146 errorCode=U_MEMORY_ALLOCATION_ERROR;
147 delete impl;
148 return NULL;
149 }
150 return allModes;
151 }
152
153 Norm2AllModes *
154 Norm2AllModes::createNFCInstance(UErrorCode &errorCode) {
438 if(U_FAILURE(errorCode)) { 155 if(U_FAILURE(errorCode)) {
439 return NULL; 156 return NULL;
440 } 157 }
441 LocalPointer<Norm2AllModes> allModes(new Norm2AllModes); 158 Normalizer2Impl *impl=new Normalizer2Impl;
442 if(allModes.isNull()) { 159 if(impl==NULL) {
443 errorCode=U_MEMORY_ALLOCATION_ERROR; 160 errorCode=U_MEMORY_ALLOCATION_ERROR;
444 return NULL; 161 return NULL;
445 } 162 }
446 allModes->impl.load(packageName, name, errorCode); 163 impl->init(norm2_nfc_data_indexes, &norm2_nfc_data_trie,
447 return U_SUCCESS(errorCode) ? allModes.orphan() : NULL; 164 norm2_nfc_data_extraData, norm2_nfc_data_smallFCD);
165 return createInstance(impl, errorCode);
448 } 166 }
449 167
450 U_CDECL_BEGIN 168 U_CDECL_BEGIN
451 static UBool U_CALLCONV uprv_normalizer2_cleanup(); 169 static UBool U_CALLCONV uprv_normalizer2_cleanup();
452 U_CDECL_END 170 U_CDECL_END
453 171
454
455 static Norm2AllModes *nfcSingleton; 172 static Norm2AllModes *nfcSingleton;
456 static Norm2AllModes *nfkcSingleton;
457 static Norm2AllModes *nfkc_cfSingleton;
458 static Normalizer2 *noopSingleton; 173 static Normalizer2 *noopSingleton;
459 static UHashtable *cache=NULL;
460 174
461 static icu::UInitOnce nfcInitOnce = U_INITONCE_INITIALIZER; 175 static icu::UInitOnce nfcInitOnce = U_INITONCE_INITIALIZER;
462 static icu::UInitOnce nfkcInitOnce = U_INITONCE_INITIALIZER;
463 static icu::UInitOnce nfkc_cfInitOnce = U_INITONCE_INITIALIZER;
464 static icu::UInitOnce noopInitOnce = U_INITONCE_INITIALIZER; 176 static icu::UInitOnce noopInitOnce = U_INITONCE_INITIALIZER;
465 177
466 // UInitOnce singleton initialization function 178 // UInitOnce singleton initialization functions
467 static void U_CALLCONV initSingletons(const char *what, UErrorCode &errorCode) { 179 static void U_CALLCONV initNFCSingleton(UErrorCode &errorCode) {
468 if (uprv_strcmp(what, "nfc") == 0) { 180 nfcSingleton=Norm2AllModes::createNFCInstance(errorCode);
469 nfcSingleton = Norm2AllModes::createInstance(NULL, "nfc", errorCode) ; 181 ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanu p);
470 } else if (uprv_strcmp(what, "nfkc") == 0) { 182 }
471 nfkcSingleton = Norm2AllModes::createInstance(NULL, "nfkc", errorCode ); 183
472 } else if (uprv_strcmp(what, "nfkc_cf") == 0) { 184 static void U_CALLCONV initNoopSingleton(UErrorCode &errorCode) {
473 nfkc_cfSingleton = Norm2AllModes::createInstance(NULL, "nfkc_cf", errorC ode); 185 if(U_FAILURE(errorCode)) {
474 } else if (uprv_strcmp(what, "noop") == 0) { 186 return;
475 noopSingleton = new NoopNormalizer2; 187 }
476 } else { 188 noopSingleton=new NoopNormalizer2;
477 U_ASSERT(FALSE); // Unknown singleton 189 if(noopSingleton==NULL) {
190 errorCode=U_MEMORY_ALLOCATION_ERROR;
191 return;
478 } 192 }
479 ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanu p); 193 ucln_common_registerCleanup(UCLN_COMMON_NORMALIZER2, uprv_normalizer2_cleanu p);
480 } 194 }
481 195
482 U_CDECL_BEGIN 196 U_CDECL_BEGIN
483 197
484 static void U_CALLCONV deleteNorm2AllModes(void *allModes) {
485 delete (Norm2AllModes *)allModes;
486 }
487
488 static UBool U_CALLCONV uprv_normalizer2_cleanup() { 198 static UBool U_CALLCONV uprv_normalizer2_cleanup() {
489 delete nfcSingleton; 199 delete nfcSingleton;
490 nfcSingleton = NULL; 200 nfcSingleton = NULL;
491 delete nfkcSingleton;
492 nfkcSingleton = NULL;
493 delete nfkc_cfSingleton;
494 nfkc_cfSingleton = NULL;
495 delete noopSingleton; 201 delete noopSingleton;
496 noopSingleton = NULL; 202 noopSingleton = NULL;
497 uhash_close(cache);
498 cache=NULL;
499 nfcInitOnce.reset(); 203 nfcInitOnce.reset();
500 nfkcInitOnce.reset();
501 nfkc_cfInitOnce.reset();
502 noopInitOnce.reset(); 204 noopInitOnce.reset();
503 return TRUE; 205 return TRUE;
504 } 206 }
505 207
506 U_CDECL_END 208 U_CDECL_END
507 209
508 const Normalizer2 *Normalizer2Factory::getNFCInstance(UErrorCode &errorCode) { 210 const Norm2AllModes *
509 umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode); 211 Norm2AllModes::getNFCInstance(UErrorCode &errorCode) {
510 return nfcSingleton!=NULL ? &nfcSingleton->comp : NULL; 212 if(U_FAILURE(errorCode)) { return NULL; }
213 umtx_initOnce(nfcInitOnce, &initNFCSingleton, errorCode);
214 return nfcSingleton;
511 } 215 }
512 216
513 const Normalizer2 *Normalizer2Factory::getNFDInstance(UErrorCode &errorCode) { 217 const Normalizer2 *
514 umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode); 218 Normalizer2::getNFCInstance(UErrorCode &errorCode) {
515 return nfcSingleton!=NULL ? &nfcSingleton->decomp : NULL; 219 const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
220 return allModes!=NULL ? &allModes->comp : NULL;
221 }
222
223 const Normalizer2 *
224 Normalizer2::getNFDInstance(UErrorCode &errorCode) {
225 const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
226 return allModes!=NULL ? &allModes->decomp : NULL;
516 } 227 }
517 228
518 const Normalizer2 *Normalizer2Factory::getFCDInstance(UErrorCode &errorCode) { 229 const Normalizer2 *Normalizer2Factory::getFCDInstance(UErrorCode &errorCode) {
519 umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode); 230 const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
520 return nfcSingleton!=NULL ? &nfcSingleton->fcd : NULL; 231 return allModes!=NULL ? &allModes->fcd : NULL;
521 } 232 }
522 233
523 const Normalizer2 *Normalizer2Factory::getFCCInstance(UErrorCode &errorCode) { 234 const Normalizer2 *Normalizer2Factory::getFCCInstance(UErrorCode &errorCode) {
524 umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode); 235 const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
525 return nfcSingleton!=NULL ? &nfcSingleton->fcc : NULL; 236 return allModes!=NULL ? &allModes->fcc : NULL;
526 }
527
528 const Normalizer2 *Normalizer2Factory::getNFKCInstance(UErrorCode &errorCode) {
529 umtx_initOnce(nfkcInitOnce, &initSingletons, "nfkc", errorCode);
530 return nfkcSingleton!=NULL ? &nfkcSingleton->comp : NULL;
531 }
532
533 const Normalizer2 *Normalizer2Factory::getNFKDInstance(UErrorCode &errorCode) {
534 umtx_initOnce(nfkcInitOnce, &initSingletons, "nfkc", errorCode);
535 return nfkcSingleton!=NULL ? &nfkcSingleton->decomp : NULL;
536 }
537
538 const Normalizer2 *Normalizer2Factory::getNFKC_CFInstance(UErrorCode &errorCode) {
539 umtx_initOnce(nfkc_cfInitOnce, &initSingletons, "nfkc_cf", errorCode);
540 return nfkc_cfSingleton!=NULL ? &nfkc_cfSingleton->comp : NULL;
541 } 237 }
542 238
543 const Normalizer2 *Normalizer2Factory::getNoopInstance(UErrorCode &errorCode) { 239 const Normalizer2 *Normalizer2Factory::getNoopInstance(UErrorCode &errorCode) {
544 umtx_initOnce(noopInitOnce, &initSingletons, "noop", errorCode); 240 if(U_FAILURE(errorCode)) { return NULL; }
241 umtx_initOnce(noopInitOnce, &initNoopSingleton, errorCode);
545 return noopSingleton; 242 return noopSingleton;
546 } 243 }
547 244
548 const Normalizer2 *
549 Normalizer2Factory::getInstance(UNormalizationMode mode, UErrorCode &errorCode) {
550 if(U_FAILURE(errorCode)) {
551 return NULL;
552 }
553 switch(mode) {
554 case UNORM_NFD:
555 return getNFDInstance(errorCode);
556 case UNORM_NFKD:
557 return getNFKDInstance(errorCode);
558 case UNORM_NFC:
559 return getNFCInstance(errorCode);
560 case UNORM_NFKC:
561 return getNFKCInstance(errorCode);
562 case UNORM_FCD:
563 return getFCDInstance(errorCode);
564 default: // UNORM_NONE
565 return getNoopInstance(errorCode);
566 }
567 }
568
569 const Normalizer2Impl * 245 const Normalizer2Impl *
570 Normalizer2Factory::getNFCImpl(UErrorCode &errorCode) { 246 Normalizer2Factory::getNFCImpl(UErrorCode &errorCode) {
571 umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode); 247 const Norm2AllModes *allModes=Norm2AllModes::getNFCInstance(errorCode);
572 return nfcSingleton!=NULL ? &nfcSingleton->impl : NULL; 248 return allModes!=NULL ? allModes->impl : NULL;
573 } 249 }
574 250
575 const Normalizer2Impl * 251 const Normalizer2Impl *
576 Normalizer2Factory::getNFKCImpl(UErrorCode &errorCode) {
577 umtx_initOnce(nfkcInitOnce, &initSingletons, "nfkc", errorCode);
578 return nfkcSingleton!=NULL ? &nfkcSingleton->impl : NULL;
579 }
580
581 const Normalizer2Impl *
582 Normalizer2Factory::getNFKC_CFImpl(UErrorCode &errorCode) {
583 umtx_initOnce(nfkc_cfInitOnce, &initSingletons, "nfkc_cf", errorCode);
584 return nfkc_cfSingleton!=NULL ? &nfkc_cfSingleton->impl : NULL;
585 }
586
587 const Normalizer2Impl *
588 Normalizer2Factory::getImpl(const Normalizer2 *norm2) { 252 Normalizer2Factory::getImpl(const Normalizer2 *norm2) {
589 return &((Normalizer2WithImpl *)norm2)->impl; 253 return &((Normalizer2WithImpl *)norm2)->impl;
590 } 254 }
591 255
592 const Normalizer2 *
593 Normalizer2::getNFCInstance(UErrorCode &errorCode) {
594 return Normalizer2Factory::getNFCInstance(errorCode);
595 }
596
597 const Normalizer2 *
598 Normalizer2::getNFDInstance(UErrorCode &errorCode) {
599 return Normalizer2Factory::getNFDInstance(errorCode);
600 }
601
602 const Normalizer2 *
603 Normalizer2::getNFKCInstance(UErrorCode &errorCode) {
604 return Normalizer2Factory::getNFKCInstance(errorCode);
605 }
606
607 const Normalizer2 *
608 Normalizer2::getNFKDInstance(UErrorCode &errorCode) {
609 return Normalizer2Factory::getNFKDInstance(errorCode);
610 }
611
612 const Normalizer2 *
613 Normalizer2::getNFKCCasefoldInstance(UErrorCode &errorCode) {
614 return Normalizer2Factory::getNFKC_CFInstance(errorCode);
615 }
616
617 const Normalizer2 *
618 Normalizer2::getInstance(const char *packageName,
619 const char *name,
620 UNormalization2Mode mode,
621 UErrorCode &errorCode) {
622 if(U_FAILURE(errorCode)) {
623 return NULL;
624 }
625 if(name==NULL || *name==0) {
626 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
627 return NULL;
628 }
629 Norm2AllModes *allModes=NULL;
630 if(packageName==NULL) {
631 if(0==uprv_strcmp(name, "nfc")) {
632 umtx_initOnce(nfcInitOnce, &initSingletons, "nfc", errorCode);
633 allModes=nfcSingleton;
634 } else if(0==uprv_strcmp(name, "nfkc")) {
635 umtx_initOnce(nfkcInitOnce, &initSingletons, "nfkc", errorCode);
636 allModes=nfkcSingleton;
637 } else if(0==uprv_strcmp(name, "nfkc_cf")) {
638 umtx_initOnce(nfkc_cfInitOnce, &initSingletons, "nfkc_cf", errorCode );
639 allModes=nfkc_cfSingleton;
640 }
641 }
642 if(allModes==NULL && U_SUCCESS(errorCode)) {
643 {
644 Mutex lock;
645 if(cache!=NULL) {
646 allModes=(Norm2AllModes *)uhash_get(cache, name);
647 }
648 }
649 if(allModes==NULL) {
650 LocalPointer<Norm2AllModes> localAllModes(
651 Norm2AllModes::createInstance(packageName, name, errorCode));
652 if(U_SUCCESS(errorCode)) {
653 Mutex lock;
654 if(cache==NULL) {
655 cache=uhash_open(uhash_hashChars, uhash_compareChars, NULL, &errorCode);
656 if(U_FAILURE(errorCode)) {
657 return NULL;
658 }
659 uhash_setKeyDeleter(cache, uprv_free);
660 uhash_setValueDeleter(cache, deleteNorm2AllModes);
661 }
662 void *temp=uhash_get(cache, name);
663 if(temp==NULL) {
664 int32_t keyLength=uprv_strlen(name)+1;
665 char *nameCopy=(char *)uprv_malloc(keyLength);
666 if(nameCopy==NULL) {
667 errorCode=U_MEMORY_ALLOCATION_ERROR;
668 return NULL;
669 }
670 uprv_memcpy(nameCopy, name, keyLength);
671 uhash_put(cache, nameCopy, allModes=localAllModes.orphan(), &errorCode);
672 } else {
673 // race condition
674 allModes=(Norm2AllModes *)temp;
675 }
676 }
677 }
678 }
679 if(allModes!=NULL && U_SUCCESS(errorCode)) {
680 switch(mode) {
681 case UNORM2_COMPOSE:
682 return &allModes->comp;
683 case UNORM2_DECOMPOSE:
684 return &allModes->decomp;
685 case UNORM2_FCD:
686 return &allModes->fcd;
687 case UNORM2_COMPOSE_CONTIGUOUS:
688 return &allModes->fcc;
689 default:
690 break; // do nothing
691 }
692 }
693 return NULL;
694 }
695
696 U_NAMESPACE_END 256 U_NAMESPACE_END
697 257
698 // C API ------------------------------------------------------------------- *** 258 // C API ------------------------------------------------------------------- ***
699 259
700 U_NAMESPACE_USE 260 U_NAMESPACE_USE
701 261
702 U_CAPI const UNormalizer2 * U_EXPORT2 262 U_CAPI const UNormalizer2 * U_EXPORT2
703 unorm2_getNFCInstance(UErrorCode *pErrorCode) { 263 unorm2_getNFCInstance(UErrorCode *pErrorCode) {
704 return (const UNormalizer2 *)Normalizer2::getNFCInstance(*pErrorCode); 264 return (const UNormalizer2 *)Normalizer2::getNFCInstance(*pErrorCode);
705 } 265 }
706 266
707 U_CAPI const UNormalizer2 * U_EXPORT2 267 U_CAPI const UNormalizer2 * U_EXPORT2
708 unorm2_getNFDInstance(UErrorCode *pErrorCode) { 268 unorm2_getNFDInstance(UErrorCode *pErrorCode) {
709 return (const UNormalizer2 *)Normalizer2::getNFDInstance(*pErrorCode); 269 return (const UNormalizer2 *)Normalizer2::getNFDInstance(*pErrorCode);
710 } 270 }
711 271
712 U_CAPI const UNormalizer2 * U_EXPORT2
713 unorm2_getNFKCInstance(UErrorCode *pErrorCode) {
714 return (const UNormalizer2 *)Normalizer2::getNFKCInstance(*pErrorCode);
715 }
716
717 U_CAPI const UNormalizer2 * U_EXPORT2
718 unorm2_getNFKDInstance(UErrorCode *pErrorCode) {
719 return (const UNormalizer2 *)Normalizer2::getNFKDInstance(*pErrorCode);
720 }
721
722 U_CAPI const UNormalizer2 * U_EXPORT2
723 unorm2_getNFKCCasefoldInstance(UErrorCode *pErrorCode) {
724 return (const UNormalizer2 *)Normalizer2::getNFKCCasefoldInstance(*pErrorCod e);
725 }
726
727 U_CAPI const UNormalizer2 * U_EXPORT2
728 unorm2_getInstance(const char *packageName,
729 const char *name,
730 UNormalization2Mode mode,
731 UErrorCode *pErrorCode) {
732 return (const UNormalizer2 *)Normalizer2::getInstance(packageName, name, mod e, *pErrorCode);
733 }
734
735 U_CAPI void U_EXPORT2 272 U_CAPI void U_EXPORT2
736 unorm2_close(UNormalizer2 *norm2) { 273 unorm2_close(UNormalizer2 *norm2) {
737 delete (Normalizer2 *)norm2; 274 delete (Normalizer2 *)norm2;
738 } 275 }
739 276
740 U_CAPI int32_t U_EXPORT2 277 U_CAPI int32_t U_EXPORT2
741 unorm2_normalize(const UNormalizer2 *norm2, 278 unorm2_normalize(const UNormalizer2 *norm2,
742 const UChar *src, int32_t length, 279 const UChar *src, int32_t length,
743 UChar *dest, int32_t capacity, 280 UChar *dest, int32_t capacity,
744 UErrorCode *pErrorCode) { 281 UErrorCode *pErrorCode) {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 U_CAPI UBool U_EXPORT2 492 U_CAPI UBool U_EXPORT2
956 unorm2_isInert(const UNormalizer2 *norm2, UChar32 c) { 493 unorm2_isInert(const UNormalizer2 *norm2, UChar32 c) {
957 return ((const Normalizer2 *)norm2)->isInert(c); 494 return ((const Normalizer2 *)norm2)->isInert(c);
958 } 495 }
959 496
960 // Some properties APIs ---------------------------------------------------- *** 497 // Some properties APIs ---------------------------------------------------- ***
961 498
962 U_CAPI uint8_t U_EXPORT2 499 U_CAPI uint8_t U_EXPORT2
963 u_getCombiningClass(UChar32 c) { 500 u_getCombiningClass(UChar32 c) {
964 UErrorCode errorCode=U_ZERO_ERROR; 501 UErrorCode errorCode=U_ZERO_ERROR;
965 const Normalizer2 *nfd=Normalizer2Factory::getNFDInstance(errorCode); 502 const Normalizer2 *nfd=Normalizer2::getNFDInstance(errorCode);
966 if(U_SUCCESS(errorCode)) { 503 if(U_SUCCESS(errorCode)) {
967 return nfd->getCombiningClass(c); 504 return nfd->getCombiningClass(c);
968 } else { 505 } else {
969 return 0; 506 return 0;
970 } 507 }
971 } 508 }
972 509
973 U_CFUNC UNormalizationCheckResult
974 unorm_getQuickCheck(UChar32 c, UNormalizationMode mode) {
975 if(mode<=UNORM_NONE || UNORM_FCD<=mode) {
976 return UNORM_YES;
977 }
978 UErrorCode errorCode=U_ZERO_ERROR;
979 const Normalizer2 *norm2=Normalizer2Factory::getInstance(mode, errorCode);
980 if(U_SUCCESS(errorCode)) {
981 return ((const Normalizer2WithImpl *)norm2)->getQuickCheck(c);
982 } else {
983 return UNORM_MAYBE;
984 }
985 }
986
987 U_CFUNC uint16_t 510 U_CFUNC uint16_t
988 unorm_getFCD16(UChar32 c) { 511 unorm_getFCD16(UChar32 c) {
989 UErrorCode errorCode=U_ZERO_ERROR; 512 UErrorCode errorCode=U_ZERO_ERROR;
990 const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode); 513 const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(errorCode);
991 if(U_SUCCESS(errorCode)) { 514 if(U_SUCCESS(errorCode)) {
992 return impl->getFCD16(c); 515 return impl->getFCD16(c);
993 } else { 516 } else {
994 return 0; 517 return 0;
995 } 518 }
996 } 519 }
997 520
998 #endif // !UCONFIG_NO_NORMALIZATION 521 #endif // !UCONFIG_NO_NORMALIZATION
OLDNEW
« no previous file with comments | « source/common/norm2allmodes.h ('k') | source/common/normalizer2impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698