1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 2014, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * loadednormalizer2impl.h
10 * created on: 2014sep07
11 * created by: Markus W. Scherer
14 #ifndef __NORM2ALLMODES_H__
15 #define __NORM2ALLMODES_H__
17 #include "unicode/utypes.h"
19 #if !UCONFIG_NO_NORMALIZATION
21 #include "unicode/normalizer2.h"
22 #include "unicode/unistr.h"
24 #include "normalizer2impl.h"
28 // Intermediate class:
29 // Has Normalizer2Impl and does boilerplate argument checking and setup.
30 class Normalizer2WithImpl
: public Normalizer2
{
32 Normalizer2WithImpl(const Normalizer2Impl
&ni
) : impl(ni
) {}
33 virtual ~Normalizer2WithImpl();
36 virtual UnicodeString
&
37 normalize(const UnicodeString
&src
,
39 UErrorCode
&errorCode
) const {
40 if(U_FAILURE(errorCode
)) {
44 const UChar
*sArray
=src
.getBuffer();
45 if(&dest
==&src
|| sArray
==NULL
) {
46 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
51 ReorderingBuffer
buffer(impl
, dest
);
52 if(buffer
.init(src
.length(), errorCode
)) {
53 normalize(sArray
, sArray
+src
.length(), buffer
, errorCode
);
58 normalize(const UChar
*src
, const UChar
*limit
,
59 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const = 0;
61 // normalize and append
62 virtual UnicodeString
&
63 normalizeSecondAndAppend(UnicodeString
&first
,
64 const UnicodeString
&second
,
65 UErrorCode
&errorCode
) const {
66 return normalizeSecondAndAppend(first
, second
, TRUE
, errorCode
);
68 virtual UnicodeString
&
69 append(UnicodeString
&first
,
70 const UnicodeString
&second
,
71 UErrorCode
&errorCode
) const {
72 return normalizeSecondAndAppend(first
, second
, FALSE
, errorCode
);
75 normalizeSecondAndAppend(UnicodeString
&first
,
76 const UnicodeString
&second
,
78 UErrorCode
&errorCode
) const {
79 uprv_checkCanGetBuffer(first
, errorCode
);
80 if(U_FAILURE(errorCode
)) {
83 const UChar
*secondArray
=second
.getBuffer();
84 if(&first
==&second
|| secondArray
==NULL
) {
85 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
88 int32_t firstLength
=first
.length();
89 UnicodeString safeMiddle
;
91 ReorderingBuffer
buffer(impl
, first
);
92 if(buffer
.init(firstLength
+second
.length(), errorCode
)) {
93 normalizeAndAppend(secondArray
, secondArray
+second
.length(), doNormalize
,
94 safeMiddle
, buffer
, errorCode
);
96 } // The ReorderingBuffer destructor finalizes the first string.
97 if(U_FAILURE(errorCode
)) {
98 // Restore the modified suffix of the first string.
99 first
.replace(firstLength
-safeMiddle
.length(), 0x7fffffff, safeMiddle
);
104 normalizeAndAppend(const UChar
*src
, const UChar
*limit
, UBool doNormalize
,
105 UnicodeString
&safeMiddle
,
106 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const = 0;
108 getDecomposition(UChar32 c
, UnicodeString
&decomposition
) const {
111 const UChar
*d
=impl
.getDecomposition(c
, buffer
, length
);
116 decomposition
.setTo(buffer
, length
); // copy the string (Jamos from Hangul syllable c)
118 decomposition
.setTo(FALSE
, d
, length
); // read-only alias
123 getRawDecomposition(UChar32 c
, UnicodeString
&decomposition
) const {
126 const UChar
*d
=impl
.getRawDecomposition(c
, buffer
, length
);
131 decomposition
.setTo(buffer
, length
); // copy the string (algorithmic decomposition)
133 decomposition
.setTo(FALSE
, d
, length
); // read-only alias
138 composePair(UChar32 a
, UChar32 b
) const {
139 return impl
.composePair(a
, b
);
143 getCombiningClass(UChar32 c
) const {
144 return impl
.getCC(impl
.getNorm16(c
));
149 isNormalized(const UnicodeString
&s
, UErrorCode
&errorCode
) const {
150 if(U_FAILURE(errorCode
)) {
153 const UChar
*sArray
=s
.getBuffer();
155 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
158 const UChar
*sLimit
=sArray
+s
.length();
159 return sLimit
==spanQuickCheckYes(sArray
, sLimit
, errorCode
);
161 virtual UNormalizationCheckResult
162 quickCheck(const UnicodeString
&s
, UErrorCode
&errorCode
) const {
163 return Normalizer2WithImpl::isNormalized(s
, errorCode
) ? UNORM_YES
: UNORM_NO
;
166 spanQuickCheckYes(const UnicodeString
&s
, UErrorCode
&errorCode
) const {
167 if(U_FAILURE(errorCode
)) {
170 const UChar
*sArray
=s
.getBuffer();
172 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
175 return (int32_t)(spanQuickCheckYes(sArray
, sArray
+s
.length(), errorCode
)-sArray
);
177 virtual const UChar
*
178 spanQuickCheckYes(const UChar
*src
, const UChar
*limit
, UErrorCode
&errorCode
) const = 0;
180 virtual UNormalizationCheckResult
getQuickCheck(UChar32
) const {
184 const Normalizer2Impl
&impl
;
187 class DecomposeNormalizer2
: public Normalizer2WithImpl
{
189 DecomposeNormalizer2(const Normalizer2Impl
&ni
) : Normalizer2WithImpl(ni
) {}
190 virtual ~DecomposeNormalizer2();
194 normalize(const UChar
*src
, const UChar
*limit
,
195 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const {
196 impl
.decompose(src
, limit
, &buffer
, errorCode
);
198 using Normalizer2WithImpl::normalize
; // Avoid warning about hiding base class function.
200 normalizeAndAppend(const UChar
*src
, const UChar
*limit
, UBool doNormalize
,
201 UnicodeString
&safeMiddle
,
202 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const {
203 impl
.decomposeAndAppend(src
, limit
, doNormalize
, safeMiddle
, buffer
, errorCode
);
205 virtual const UChar
*
206 spanQuickCheckYes(const UChar
*src
, const UChar
*limit
, UErrorCode
&errorCode
) const {
207 return impl
.decompose(src
, limit
, NULL
, errorCode
);
209 using Normalizer2WithImpl::spanQuickCheckYes
; // Avoid warning about hiding base class function.
210 virtual UNormalizationCheckResult
getQuickCheck(UChar32 c
) const {
211 return impl
.isDecompYes(impl
.getNorm16(c
)) ? UNORM_YES
: UNORM_NO
;
213 virtual UBool
hasBoundaryBefore(UChar32 c
) const { return impl
.hasDecompBoundary(c
, TRUE
); }
214 virtual UBool
hasBoundaryAfter(UChar32 c
) const { return impl
.hasDecompBoundary(c
, FALSE
); }
215 virtual UBool
isInert(UChar32 c
) const { return impl
.isDecompInert(c
); }
218 class ComposeNormalizer2
: public Normalizer2WithImpl
{
220 ComposeNormalizer2(const Normalizer2Impl
&ni
, UBool fcc
) :
221 Normalizer2WithImpl(ni
), onlyContiguous(fcc
) {}
222 virtual ~ComposeNormalizer2();
226 normalize(const UChar
*src
, const UChar
*limit
,
227 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const {
228 impl
.compose(src
, limit
, onlyContiguous
, TRUE
, buffer
, errorCode
);
230 using Normalizer2WithImpl::normalize
; // Avoid warning about hiding base class function.
232 normalizeAndAppend(const UChar
*src
, const UChar
*limit
, UBool doNormalize
,
233 UnicodeString
&safeMiddle
,
234 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const {
235 impl
.composeAndAppend(src
, limit
, doNormalize
, onlyContiguous
, safeMiddle
, buffer
, errorCode
);
239 isNormalized(const UnicodeString
&s
, UErrorCode
&errorCode
) const {
240 if(U_FAILURE(errorCode
)) {
243 const UChar
*sArray
=s
.getBuffer();
245 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
249 ReorderingBuffer
buffer(impl
, temp
);
250 if(!buffer
.init(5, errorCode
)) { // small destCapacity for substring normalization
253 return impl
.compose(sArray
, sArray
+s
.length(), onlyContiguous
, FALSE
, buffer
, errorCode
);
255 virtual UNormalizationCheckResult
256 quickCheck(const UnicodeString
&s
, UErrorCode
&errorCode
) const {
257 if(U_FAILURE(errorCode
)) {
260 const UChar
*sArray
=s
.getBuffer();
262 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
265 UNormalizationCheckResult qcResult
=UNORM_YES
;
266 impl
.composeQuickCheck(sArray
, sArray
+s
.length(), onlyContiguous
, &qcResult
);
269 virtual const UChar
*
270 spanQuickCheckYes(const UChar
*src
, const UChar
*limit
, UErrorCode
&) const {
271 return impl
.composeQuickCheck(src
, limit
, onlyContiguous
, NULL
);
273 using Normalizer2WithImpl::spanQuickCheckYes
; // Avoid warning about hiding base class function.
274 virtual UNormalizationCheckResult
getQuickCheck(UChar32 c
) const {
275 return impl
.getCompQuickCheck(impl
.getNorm16(c
));
277 virtual UBool
hasBoundaryBefore(UChar32 c
) const {
278 return impl
.hasCompBoundaryBefore(c
);
280 virtual UBool
hasBoundaryAfter(UChar32 c
) const {
281 return impl
.hasCompBoundaryAfter(c
, onlyContiguous
, FALSE
);
283 virtual UBool
isInert(UChar32 c
) const {
284 return impl
.hasCompBoundaryAfter(c
, onlyContiguous
, TRUE
);
287 const UBool onlyContiguous
;
290 class FCDNormalizer2
: public Normalizer2WithImpl
{
292 FCDNormalizer2(const Normalizer2Impl
&ni
) : Normalizer2WithImpl(ni
) {}
293 virtual ~FCDNormalizer2();
297 normalize(const UChar
*src
, const UChar
*limit
,
298 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const {
299 impl
.makeFCD(src
, limit
, &buffer
, errorCode
);
301 using Normalizer2WithImpl::normalize
; // Avoid warning about hiding base class function.
303 normalizeAndAppend(const UChar
*src
, const UChar
*limit
, UBool doNormalize
,
304 UnicodeString
&safeMiddle
,
305 ReorderingBuffer
&buffer
, UErrorCode
&errorCode
) const {
306 impl
.makeFCDAndAppend(src
, limit
, doNormalize
, safeMiddle
, buffer
, errorCode
);
308 virtual const UChar
*
309 spanQuickCheckYes(const UChar
*src
, const UChar
*limit
, UErrorCode
&errorCode
) const {
310 return impl
.makeFCD(src
, limit
, NULL
, errorCode
);
312 using Normalizer2WithImpl::spanQuickCheckYes
; // Avoid warning about hiding base class function.
313 virtual UBool
hasBoundaryBefore(UChar32 c
) const { return impl
.hasFCDBoundaryBefore(c
); }
314 virtual UBool
hasBoundaryAfter(UChar32 c
) const { return impl
.hasFCDBoundaryAfter(c
); }
315 virtual UBool
isInert(UChar32 c
) const { return impl
.isFCDInert(c
); }
318 struct Norm2AllModes
: public UMemory
{
319 Norm2AllModes(Normalizer2Impl
*i
)
320 : impl(i
), comp(*i
, FALSE
), decomp(*i
), fcd(*i
), fcc(*i
, TRUE
) {}
323 static Norm2AllModes
*createInstance(Normalizer2Impl
*impl
, UErrorCode
&errorCode
);
324 static Norm2AllModes
*createNFCInstance(UErrorCode
&errorCode
);
325 static Norm2AllModes
*createInstance(const char *packageName
,
327 UErrorCode
&errorCode
);
329 static const Norm2AllModes
*getNFCInstance(UErrorCode
&errorCode
);
330 static const Norm2AllModes
*getNFKCInstance(UErrorCode
&errorCode
);
331 static const Norm2AllModes
*getNFKC_CFInstance(UErrorCode
&errorCode
);
333 Normalizer2Impl
*impl
;
334 ComposeNormalizer2 comp
;
335 DecomposeNormalizer2 decomp
;
337 ComposeNormalizer2 fcc
;
342 #endif // !UCONFIG_NO_NORMALIZATION
343 #endif // __NORM2ALLMODES_H__