xref: /aosp_15_r20/external/icu/libicu/cts_headers/norm2allmodes.h (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1*0e209d39SAndroid Build Coastguard Worker // © 2016 and later: Unicode, Inc. and others.
2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html
3*0e209d39SAndroid Build Coastguard Worker /*
4*0e209d39SAndroid Build Coastguard Worker *******************************************************************************
5*0e209d39SAndroid Build Coastguard Worker * Copyright (C) 2014, International Business Machines
6*0e209d39SAndroid Build Coastguard Worker * Corporation and others.  All Rights Reserved.
7*0e209d39SAndroid Build Coastguard Worker *******************************************************************************
8*0e209d39SAndroid Build Coastguard Worker * norm2allmodes.h
9*0e209d39SAndroid Build Coastguard Worker *
10*0e209d39SAndroid Build Coastguard Worker * created on: 2014sep07
11*0e209d39SAndroid Build Coastguard Worker * created by: Markus W. Scherer
12*0e209d39SAndroid Build Coastguard Worker */
13*0e209d39SAndroid Build Coastguard Worker 
14*0e209d39SAndroid Build Coastguard Worker #ifndef __NORM2ALLMODES_H__
15*0e209d39SAndroid Build Coastguard Worker #define __NORM2ALLMODES_H__
16*0e209d39SAndroid Build Coastguard Worker 
17*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h"
18*0e209d39SAndroid Build Coastguard Worker 
19*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_NORMALIZATION
20*0e209d39SAndroid Build Coastguard Worker 
21*0e209d39SAndroid Build Coastguard Worker #include "unicode/edits.h"
22*0e209d39SAndroid Build Coastguard Worker #include "unicode/normalizer2.h"
23*0e209d39SAndroid Build Coastguard Worker #include "unicode/stringoptions.h"
24*0e209d39SAndroid Build Coastguard Worker #include "unicode/unistr.h"
25*0e209d39SAndroid Build Coastguard Worker #include "cpputils.h"
26*0e209d39SAndroid Build Coastguard Worker #include "normalizer2impl.h"
27*0e209d39SAndroid Build Coastguard Worker 
28*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN
29*0e209d39SAndroid Build Coastguard Worker 
30*0e209d39SAndroid Build Coastguard Worker // Intermediate class:
31*0e209d39SAndroid Build Coastguard Worker // Has Normalizer2Impl and does boilerplate argument checking and setup.
32*0e209d39SAndroid Build Coastguard Worker class Normalizer2WithImpl : public Normalizer2 {
33*0e209d39SAndroid Build Coastguard Worker public:
Normalizer2WithImpl(const Normalizer2Impl & ni)34*0e209d39SAndroid Build Coastguard Worker     Normalizer2WithImpl(const Normalizer2Impl &ni) : impl(ni) {}
35*0e209d39SAndroid Build Coastguard Worker     virtual ~Normalizer2WithImpl();
36*0e209d39SAndroid Build Coastguard Worker 
37*0e209d39SAndroid Build Coastguard Worker     // normalize
38*0e209d39SAndroid Build Coastguard Worker     virtual UnicodeString &
normalize(const UnicodeString & src,UnicodeString & dest,UErrorCode & errorCode)39*0e209d39SAndroid Build Coastguard Worker     normalize(const UnicodeString &src,
40*0e209d39SAndroid Build Coastguard Worker               UnicodeString &dest,
41*0e209d39SAndroid Build Coastguard Worker               UErrorCode &errorCode) const override {
42*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
43*0e209d39SAndroid Build Coastguard Worker             dest.setToBogus();
44*0e209d39SAndroid Build Coastguard Worker             return dest;
45*0e209d39SAndroid Build Coastguard Worker         }
46*0e209d39SAndroid Build Coastguard Worker         const char16_t *sArray=src.getBuffer();
47*0e209d39SAndroid Build Coastguard Worker         if(&dest==&src || sArray==nullptr) {
48*0e209d39SAndroid Build Coastguard Worker             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
49*0e209d39SAndroid Build Coastguard Worker             dest.setToBogus();
50*0e209d39SAndroid Build Coastguard Worker             return dest;
51*0e209d39SAndroid Build Coastguard Worker         }
52*0e209d39SAndroid Build Coastguard Worker         dest.remove();
53*0e209d39SAndroid Build Coastguard Worker         ReorderingBuffer buffer(impl, dest);
54*0e209d39SAndroid Build Coastguard Worker         if(buffer.init(src.length(), errorCode)) {
55*0e209d39SAndroid Build Coastguard Worker             normalize(sArray, sArray+src.length(), buffer, errorCode);
56*0e209d39SAndroid Build Coastguard Worker         }
57*0e209d39SAndroid Build Coastguard Worker         return dest;
58*0e209d39SAndroid Build Coastguard Worker     }
59*0e209d39SAndroid Build Coastguard Worker     virtual void
60*0e209d39SAndroid Build Coastguard Worker     normalize(const char16_t *src, const char16_t *limit,
61*0e209d39SAndroid Build Coastguard Worker               ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
62*0e209d39SAndroid Build Coastguard Worker 
63*0e209d39SAndroid Build Coastguard Worker     // normalize and append
64*0e209d39SAndroid Build Coastguard Worker     virtual UnicodeString &
normalizeSecondAndAppend(UnicodeString & first,const UnicodeString & second,UErrorCode & errorCode)65*0e209d39SAndroid Build Coastguard Worker     normalizeSecondAndAppend(UnicodeString &first,
66*0e209d39SAndroid Build Coastguard Worker                              const UnicodeString &second,
67*0e209d39SAndroid Build Coastguard Worker                              UErrorCode &errorCode) const override {
68*0e209d39SAndroid Build Coastguard Worker         return normalizeSecondAndAppend(first, second, true, errorCode);
69*0e209d39SAndroid Build Coastguard Worker     }
70*0e209d39SAndroid Build Coastguard Worker     virtual UnicodeString &
append(UnicodeString & first,const UnicodeString & second,UErrorCode & errorCode)71*0e209d39SAndroid Build Coastguard Worker     append(UnicodeString &first,
72*0e209d39SAndroid Build Coastguard Worker            const UnicodeString &second,
73*0e209d39SAndroid Build Coastguard Worker            UErrorCode &errorCode) const override {
74*0e209d39SAndroid Build Coastguard Worker         return normalizeSecondAndAppend(first, second, false, errorCode);
75*0e209d39SAndroid Build Coastguard Worker     }
76*0e209d39SAndroid Build Coastguard Worker     UnicodeString &
normalizeSecondAndAppend(UnicodeString & first,const UnicodeString & second,UBool doNormalize,UErrorCode & errorCode)77*0e209d39SAndroid Build Coastguard Worker     normalizeSecondAndAppend(UnicodeString &first,
78*0e209d39SAndroid Build Coastguard Worker                              const UnicodeString &second,
79*0e209d39SAndroid Build Coastguard Worker                              UBool doNormalize,
80*0e209d39SAndroid Build Coastguard Worker                              UErrorCode &errorCode) const {
81*0e209d39SAndroid Build Coastguard Worker         uprv_checkCanGetBuffer(first, errorCode);
82*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
83*0e209d39SAndroid Build Coastguard Worker             return first;
84*0e209d39SAndroid Build Coastguard Worker         }
85*0e209d39SAndroid Build Coastguard Worker         const char16_t *secondArray=second.getBuffer();
86*0e209d39SAndroid Build Coastguard Worker         if(&first==&second || secondArray==nullptr) {
87*0e209d39SAndroid Build Coastguard Worker             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
88*0e209d39SAndroid Build Coastguard Worker             return first;
89*0e209d39SAndroid Build Coastguard Worker         }
90*0e209d39SAndroid Build Coastguard Worker         int32_t firstLength=first.length();
91*0e209d39SAndroid Build Coastguard Worker         UnicodeString safeMiddle;
92*0e209d39SAndroid Build Coastguard Worker         {
93*0e209d39SAndroid Build Coastguard Worker             ReorderingBuffer buffer(impl, first);
94*0e209d39SAndroid Build Coastguard Worker             if(buffer.init(firstLength+second.length(), errorCode)) {
95*0e209d39SAndroid Build Coastguard Worker                 normalizeAndAppend(secondArray, secondArray+second.length(), doNormalize,
96*0e209d39SAndroid Build Coastguard Worker                                    safeMiddle, buffer, errorCode);
97*0e209d39SAndroid Build Coastguard Worker             }
98*0e209d39SAndroid Build Coastguard Worker         }  // The ReorderingBuffer destructor finalizes the first string.
99*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
100*0e209d39SAndroid Build Coastguard Worker             // Restore the modified suffix of the first string.
101*0e209d39SAndroid Build Coastguard Worker             first.replace(firstLength-safeMiddle.length(), 0x7fffffff, safeMiddle);
102*0e209d39SAndroid Build Coastguard Worker         }
103*0e209d39SAndroid Build Coastguard Worker         return first;
104*0e209d39SAndroid Build Coastguard Worker     }
105*0e209d39SAndroid Build Coastguard Worker     virtual void
106*0e209d39SAndroid Build Coastguard Worker     normalizeAndAppend(const char16_t *src, const char16_t *limit, UBool doNormalize,
107*0e209d39SAndroid Build Coastguard Worker                        UnicodeString &safeMiddle,
108*0e209d39SAndroid Build Coastguard Worker                        ReorderingBuffer &buffer, UErrorCode &errorCode) const = 0;
109*0e209d39SAndroid Build Coastguard Worker     virtual UBool
getDecomposition(UChar32 c,UnicodeString & decomposition)110*0e209d39SAndroid Build Coastguard Worker     getDecomposition(UChar32 c, UnicodeString &decomposition) const override {
111*0e209d39SAndroid Build Coastguard Worker         char16_t buffer[4];
112*0e209d39SAndroid Build Coastguard Worker         int32_t length;
113*0e209d39SAndroid Build Coastguard Worker         const char16_t *d=impl.getDecomposition(c, buffer, length);
114*0e209d39SAndroid Build Coastguard Worker         if(d==nullptr) {
115*0e209d39SAndroid Build Coastguard Worker             return false;
116*0e209d39SAndroid Build Coastguard Worker         }
117*0e209d39SAndroid Build Coastguard Worker         if(d==buffer) {
118*0e209d39SAndroid Build Coastguard Worker             decomposition.setTo(buffer, length);  // copy the string (Jamos from Hangul syllable c)
119*0e209d39SAndroid Build Coastguard Worker         } else {
120*0e209d39SAndroid Build Coastguard Worker             decomposition.setTo(false, d, length);  // read-only alias
121*0e209d39SAndroid Build Coastguard Worker         }
122*0e209d39SAndroid Build Coastguard Worker         return true;
123*0e209d39SAndroid Build Coastguard Worker     }
124*0e209d39SAndroid Build Coastguard Worker     virtual UBool
getRawDecomposition(UChar32 c,UnicodeString & decomposition)125*0e209d39SAndroid Build Coastguard Worker     getRawDecomposition(UChar32 c, UnicodeString &decomposition) const override {
126*0e209d39SAndroid Build Coastguard Worker         char16_t buffer[30];
127*0e209d39SAndroid Build Coastguard Worker         int32_t length;
128*0e209d39SAndroid Build Coastguard Worker         const char16_t *d=impl.getRawDecomposition(c, buffer, length);
129*0e209d39SAndroid Build Coastguard Worker         if(d==nullptr) {
130*0e209d39SAndroid Build Coastguard Worker             return false;
131*0e209d39SAndroid Build Coastguard Worker         }
132*0e209d39SAndroid Build Coastguard Worker         if(d==buffer) {
133*0e209d39SAndroid Build Coastguard Worker             decomposition.setTo(buffer, length);  // copy the string (algorithmic decomposition)
134*0e209d39SAndroid Build Coastguard Worker         } else {
135*0e209d39SAndroid Build Coastguard Worker             decomposition.setTo(false, d, length);  // read-only alias
136*0e209d39SAndroid Build Coastguard Worker         }
137*0e209d39SAndroid Build Coastguard Worker         return true;
138*0e209d39SAndroid Build Coastguard Worker     }
139*0e209d39SAndroid Build Coastguard Worker     virtual UChar32
composePair(UChar32 a,UChar32 b)140*0e209d39SAndroid Build Coastguard Worker     composePair(UChar32 a, UChar32 b) const override {
141*0e209d39SAndroid Build Coastguard Worker         return impl.composePair(a, b);
142*0e209d39SAndroid Build Coastguard Worker     }
143*0e209d39SAndroid Build Coastguard Worker 
144*0e209d39SAndroid Build Coastguard Worker     virtual uint8_t
getCombiningClass(UChar32 c)145*0e209d39SAndroid Build Coastguard Worker     getCombiningClass(UChar32 c) const override {
146*0e209d39SAndroid Build Coastguard Worker         return impl.getCC(impl.getNorm16(c));
147*0e209d39SAndroid Build Coastguard Worker     }
148*0e209d39SAndroid Build Coastguard Worker 
149*0e209d39SAndroid Build Coastguard Worker     // quick checks
150*0e209d39SAndroid Build Coastguard Worker     virtual UBool
isNormalized(const UnicodeString & s,UErrorCode & errorCode)151*0e209d39SAndroid Build Coastguard Worker     isNormalized(const UnicodeString &s, UErrorCode &errorCode) const override {
152*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
153*0e209d39SAndroid Build Coastguard Worker             return false;
154*0e209d39SAndroid Build Coastguard Worker         }
155*0e209d39SAndroid Build Coastguard Worker         const char16_t *sArray=s.getBuffer();
156*0e209d39SAndroid Build Coastguard Worker         if(sArray==nullptr) {
157*0e209d39SAndroid Build Coastguard Worker             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
158*0e209d39SAndroid Build Coastguard Worker             return false;
159*0e209d39SAndroid Build Coastguard Worker         }
160*0e209d39SAndroid Build Coastguard Worker         const char16_t *sLimit=sArray+s.length();
161*0e209d39SAndroid Build Coastguard Worker         return sLimit==spanQuickCheckYes(sArray, sLimit, errorCode);
162*0e209d39SAndroid Build Coastguard Worker     }
163*0e209d39SAndroid Build Coastguard Worker     virtual UNormalizationCheckResult
quickCheck(const UnicodeString & s,UErrorCode & errorCode)164*0e209d39SAndroid Build Coastguard Worker     quickCheck(const UnicodeString &s, UErrorCode &errorCode) const override {
165*0e209d39SAndroid Build Coastguard Worker         return Normalizer2WithImpl::isNormalized(s, errorCode) ? UNORM_YES : UNORM_NO;
166*0e209d39SAndroid Build Coastguard Worker     }
167*0e209d39SAndroid Build Coastguard Worker     virtual int32_t
spanQuickCheckYes(const UnicodeString & s,UErrorCode & errorCode)168*0e209d39SAndroid Build Coastguard Worker     spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const override {
169*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
170*0e209d39SAndroid Build Coastguard Worker             return 0;
171*0e209d39SAndroid Build Coastguard Worker         }
172*0e209d39SAndroid Build Coastguard Worker         const char16_t *sArray=s.getBuffer();
173*0e209d39SAndroid Build Coastguard Worker         if(sArray==nullptr) {
174*0e209d39SAndroid Build Coastguard Worker             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
175*0e209d39SAndroid Build Coastguard Worker             return 0;
176*0e209d39SAndroid Build Coastguard Worker         }
177*0e209d39SAndroid Build Coastguard Worker         return (int32_t)(spanQuickCheckYes(sArray, sArray+s.length(), errorCode)-sArray);
178*0e209d39SAndroid Build Coastguard Worker     }
179*0e209d39SAndroid Build Coastguard Worker     virtual const char16_t *
180*0e209d39SAndroid Build Coastguard Worker     spanQuickCheckYes(const char16_t *src, const char16_t *limit, UErrorCode &errorCode) const = 0;
181*0e209d39SAndroid Build Coastguard Worker 
getQuickCheck(UChar32)182*0e209d39SAndroid Build Coastguard Worker     virtual UNormalizationCheckResult getQuickCheck(UChar32) const {
183*0e209d39SAndroid Build Coastguard Worker         return UNORM_YES;
184*0e209d39SAndroid Build Coastguard Worker     }
185*0e209d39SAndroid Build Coastguard Worker 
186*0e209d39SAndroid Build Coastguard Worker     const Normalizer2Impl &impl;
187*0e209d39SAndroid Build Coastguard Worker };
188*0e209d39SAndroid Build Coastguard Worker 
189*0e209d39SAndroid Build Coastguard Worker class DecomposeNormalizer2 : public Normalizer2WithImpl {
190*0e209d39SAndroid Build Coastguard Worker public:
DecomposeNormalizer2(const Normalizer2Impl & ni)191*0e209d39SAndroid Build Coastguard Worker     DecomposeNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
192*0e209d39SAndroid Build Coastguard Worker     virtual ~DecomposeNormalizer2();
193*0e209d39SAndroid Build Coastguard Worker 
194*0e209d39SAndroid Build Coastguard Worker private:
195*0e209d39SAndroid Build Coastguard Worker     virtual void
normalize(const char16_t * src,const char16_t * limit,ReorderingBuffer & buffer,UErrorCode & errorCode)196*0e209d39SAndroid Build Coastguard Worker     normalize(const char16_t *src, const char16_t *limit,
197*0e209d39SAndroid Build Coastguard Worker               ReorderingBuffer &buffer, UErrorCode &errorCode) const override {
198*0e209d39SAndroid Build Coastguard Worker         impl.decompose(src, limit, &buffer, errorCode);
199*0e209d39SAndroid Build Coastguard Worker     }
200*0e209d39SAndroid Build Coastguard Worker     using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
201*0e209d39SAndroid Build Coastguard Worker     virtual void
normalizeAndAppend(const char16_t * src,const char16_t * limit,UBool doNormalize,UnicodeString & safeMiddle,ReorderingBuffer & buffer,UErrorCode & errorCode)202*0e209d39SAndroid Build Coastguard Worker     normalizeAndAppend(const char16_t *src, const char16_t *limit, UBool doNormalize,
203*0e209d39SAndroid Build Coastguard Worker                        UnicodeString &safeMiddle,
204*0e209d39SAndroid Build Coastguard Worker                        ReorderingBuffer &buffer, UErrorCode &errorCode) const override {
205*0e209d39SAndroid Build Coastguard Worker         impl.decomposeAndAppend(src, limit, doNormalize, safeMiddle, buffer, errorCode);
206*0e209d39SAndroid Build Coastguard Worker     }
207*0e209d39SAndroid Build Coastguard Worker 
208*0e209d39SAndroid Build Coastguard Worker     void
normalizeUTF8(uint32_t options,StringPiece src,ByteSink & sink,Edits * edits,UErrorCode & errorCode)209*0e209d39SAndroid Build Coastguard Worker     normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink,
210*0e209d39SAndroid Build Coastguard Worker                   Edits *edits, UErrorCode &errorCode) const override {
211*0e209d39SAndroid Build Coastguard Worker         if (U_FAILURE(errorCode)) {
212*0e209d39SAndroid Build Coastguard Worker             return;
213*0e209d39SAndroid Build Coastguard Worker         }
214*0e209d39SAndroid Build Coastguard Worker         if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
215*0e209d39SAndroid Build Coastguard Worker             edits->reset();
216*0e209d39SAndroid Build Coastguard Worker         }
217*0e209d39SAndroid Build Coastguard Worker         const uint8_t *s = reinterpret_cast<const uint8_t *>(src.data());
218*0e209d39SAndroid Build Coastguard Worker         impl.decomposeUTF8(options, s, s + src.length(), &sink, edits, errorCode);
219*0e209d39SAndroid Build Coastguard Worker         sink.Flush();
220*0e209d39SAndroid Build Coastguard Worker     }
221*0e209d39SAndroid Build Coastguard Worker     virtual UBool
isNormalizedUTF8(StringPiece sp,UErrorCode & errorCode)222*0e209d39SAndroid Build Coastguard Worker     isNormalizedUTF8(StringPiece sp, UErrorCode &errorCode) const override {
223*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
224*0e209d39SAndroid Build Coastguard Worker             return false;
225*0e209d39SAndroid Build Coastguard Worker         }
226*0e209d39SAndroid Build Coastguard Worker         const uint8_t *s = reinterpret_cast<const uint8_t *>(sp.data());
227*0e209d39SAndroid Build Coastguard Worker         const uint8_t *sLimit = s + sp.length();
228*0e209d39SAndroid Build Coastguard Worker         return sLimit == impl.decomposeUTF8(0, s, sLimit, nullptr, nullptr, errorCode);
229*0e209d39SAndroid Build Coastguard Worker     }
230*0e209d39SAndroid Build Coastguard Worker 
231*0e209d39SAndroid Build Coastguard Worker     virtual const char16_t *
spanQuickCheckYes(const char16_t * src,const char16_t * limit,UErrorCode & errorCode)232*0e209d39SAndroid Build Coastguard Worker     spanQuickCheckYes(const char16_t *src, const char16_t *limit, UErrorCode &errorCode) const override {
233*0e209d39SAndroid Build Coastguard Worker         return impl.decompose(src, limit, nullptr, errorCode);
234*0e209d39SAndroid Build Coastguard Worker     }
235*0e209d39SAndroid Build Coastguard Worker     using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
getQuickCheck(UChar32 c)236*0e209d39SAndroid Build Coastguard Worker     virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const override {
237*0e209d39SAndroid Build Coastguard Worker         return impl.isDecompYes(impl.getNorm16(c)) ? UNORM_YES : UNORM_NO;
238*0e209d39SAndroid Build Coastguard Worker     }
hasBoundaryBefore(UChar32 c)239*0e209d39SAndroid Build Coastguard Worker     virtual UBool hasBoundaryBefore(UChar32 c) const override {
240*0e209d39SAndroid Build Coastguard Worker         return impl.hasDecompBoundaryBefore(c);
241*0e209d39SAndroid Build Coastguard Worker     }
hasBoundaryAfter(UChar32 c)242*0e209d39SAndroid Build Coastguard Worker     virtual UBool hasBoundaryAfter(UChar32 c) const override {
243*0e209d39SAndroid Build Coastguard Worker         return impl.hasDecompBoundaryAfter(c);
244*0e209d39SAndroid Build Coastguard Worker     }
isInert(UChar32 c)245*0e209d39SAndroid Build Coastguard Worker     virtual UBool isInert(UChar32 c) const override {
246*0e209d39SAndroid Build Coastguard Worker         return impl.isDecompInert(c);
247*0e209d39SAndroid Build Coastguard Worker     }
248*0e209d39SAndroid Build Coastguard Worker };
249*0e209d39SAndroid Build Coastguard Worker 
250*0e209d39SAndroid Build Coastguard Worker class ComposeNormalizer2 : public Normalizer2WithImpl {
251*0e209d39SAndroid Build Coastguard Worker public:
ComposeNormalizer2(const Normalizer2Impl & ni,UBool fcc)252*0e209d39SAndroid Build Coastguard Worker     ComposeNormalizer2(const Normalizer2Impl &ni, UBool fcc) :
253*0e209d39SAndroid Build Coastguard Worker         Normalizer2WithImpl(ni), onlyContiguous(fcc) {}
254*0e209d39SAndroid Build Coastguard Worker     virtual ~ComposeNormalizer2();
255*0e209d39SAndroid Build Coastguard Worker 
256*0e209d39SAndroid Build Coastguard Worker private:
257*0e209d39SAndroid Build Coastguard Worker     virtual void
normalize(const char16_t * src,const char16_t * limit,ReorderingBuffer & buffer,UErrorCode & errorCode)258*0e209d39SAndroid Build Coastguard Worker     normalize(const char16_t *src, const char16_t *limit,
259*0e209d39SAndroid Build Coastguard Worker               ReorderingBuffer &buffer, UErrorCode &errorCode) const override {
260*0e209d39SAndroid Build Coastguard Worker         impl.compose(src, limit, onlyContiguous, true, buffer, errorCode);
261*0e209d39SAndroid Build Coastguard Worker     }
262*0e209d39SAndroid Build Coastguard Worker     using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
263*0e209d39SAndroid Build Coastguard Worker 
264*0e209d39SAndroid Build Coastguard Worker     void
normalizeUTF8(uint32_t options,StringPiece src,ByteSink & sink,Edits * edits,UErrorCode & errorCode)265*0e209d39SAndroid Build Coastguard Worker     normalizeUTF8(uint32_t options, StringPiece src, ByteSink &sink,
266*0e209d39SAndroid Build Coastguard Worker                   Edits *edits, UErrorCode &errorCode) const override {
267*0e209d39SAndroid Build Coastguard Worker         if (U_FAILURE(errorCode)) {
268*0e209d39SAndroid Build Coastguard Worker             return;
269*0e209d39SAndroid Build Coastguard Worker         }
270*0e209d39SAndroid Build Coastguard Worker         if (edits != nullptr && (options & U_EDITS_NO_RESET) == 0) {
271*0e209d39SAndroid Build Coastguard Worker             edits->reset();
272*0e209d39SAndroid Build Coastguard Worker         }
273*0e209d39SAndroid Build Coastguard Worker         const uint8_t *s = reinterpret_cast<const uint8_t *>(src.data());
274*0e209d39SAndroid Build Coastguard Worker         impl.composeUTF8(options, onlyContiguous, s, s + src.length(),
275*0e209d39SAndroid Build Coastguard Worker                          &sink, edits, errorCode);
276*0e209d39SAndroid Build Coastguard Worker         sink.Flush();
277*0e209d39SAndroid Build Coastguard Worker     }
278*0e209d39SAndroid Build Coastguard Worker 
279*0e209d39SAndroid Build Coastguard Worker     virtual void
normalizeAndAppend(const char16_t * src,const char16_t * limit,UBool doNormalize,UnicodeString & safeMiddle,ReorderingBuffer & buffer,UErrorCode & errorCode)280*0e209d39SAndroid Build Coastguard Worker     normalizeAndAppend(const char16_t *src, const char16_t *limit, UBool doNormalize,
281*0e209d39SAndroid Build Coastguard Worker                        UnicodeString &safeMiddle,
282*0e209d39SAndroid Build Coastguard Worker                        ReorderingBuffer &buffer, UErrorCode &errorCode) const override {
283*0e209d39SAndroid Build Coastguard Worker         impl.composeAndAppend(src, limit, doNormalize, onlyContiguous, safeMiddle, buffer, errorCode);
284*0e209d39SAndroid Build Coastguard Worker     }
285*0e209d39SAndroid Build Coastguard Worker 
286*0e209d39SAndroid Build Coastguard Worker     virtual UBool
isNormalized(const UnicodeString & s,UErrorCode & errorCode)287*0e209d39SAndroid Build Coastguard Worker     isNormalized(const UnicodeString &s, UErrorCode &errorCode) const override {
288*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
289*0e209d39SAndroid Build Coastguard Worker             return false;
290*0e209d39SAndroid Build Coastguard Worker         }
291*0e209d39SAndroid Build Coastguard Worker         const char16_t *sArray=s.getBuffer();
292*0e209d39SAndroid Build Coastguard Worker         if(sArray==nullptr) {
293*0e209d39SAndroid Build Coastguard Worker             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
294*0e209d39SAndroid Build Coastguard Worker             return false;
295*0e209d39SAndroid Build Coastguard Worker         }
296*0e209d39SAndroid Build Coastguard Worker         UnicodeString temp;
297*0e209d39SAndroid Build Coastguard Worker         ReorderingBuffer buffer(impl, temp);
298*0e209d39SAndroid Build Coastguard Worker         if(!buffer.init(5, errorCode)) {  // small destCapacity for substring normalization
299*0e209d39SAndroid Build Coastguard Worker             return false;
300*0e209d39SAndroid Build Coastguard Worker         }
301*0e209d39SAndroid Build Coastguard Worker         return impl.compose(sArray, sArray+s.length(), onlyContiguous, false, buffer, errorCode);
302*0e209d39SAndroid Build Coastguard Worker     }
303*0e209d39SAndroid Build Coastguard Worker     virtual UBool
isNormalizedUTF8(StringPiece sp,UErrorCode & errorCode)304*0e209d39SAndroid Build Coastguard Worker     isNormalizedUTF8(StringPiece sp, UErrorCode &errorCode) const override {
305*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
306*0e209d39SAndroid Build Coastguard Worker             return false;
307*0e209d39SAndroid Build Coastguard Worker         }
308*0e209d39SAndroid Build Coastguard Worker         const uint8_t *s = reinterpret_cast<const uint8_t *>(sp.data());
309*0e209d39SAndroid Build Coastguard Worker         return impl.composeUTF8(0, onlyContiguous, s, s + sp.length(), nullptr, nullptr, errorCode);
310*0e209d39SAndroid Build Coastguard Worker     }
311*0e209d39SAndroid Build Coastguard Worker     virtual UNormalizationCheckResult
quickCheck(const UnicodeString & s,UErrorCode & errorCode)312*0e209d39SAndroid Build Coastguard Worker     quickCheck(const UnicodeString &s, UErrorCode &errorCode) const override {
313*0e209d39SAndroid Build Coastguard Worker         if(U_FAILURE(errorCode)) {
314*0e209d39SAndroid Build Coastguard Worker             return UNORM_MAYBE;
315*0e209d39SAndroid Build Coastguard Worker         }
316*0e209d39SAndroid Build Coastguard Worker         const char16_t *sArray=s.getBuffer();
317*0e209d39SAndroid Build Coastguard Worker         if(sArray==nullptr) {
318*0e209d39SAndroid Build Coastguard Worker             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
319*0e209d39SAndroid Build Coastguard Worker             return UNORM_MAYBE;
320*0e209d39SAndroid Build Coastguard Worker         }
321*0e209d39SAndroid Build Coastguard Worker         UNormalizationCheckResult qcResult=UNORM_YES;
322*0e209d39SAndroid Build Coastguard Worker         impl.composeQuickCheck(sArray, sArray+s.length(), onlyContiguous, &qcResult);
323*0e209d39SAndroid Build Coastguard Worker         return qcResult;
324*0e209d39SAndroid Build Coastguard Worker     }
325*0e209d39SAndroid Build Coastguard Worker     virtual const char16_t *
spanQuickCheckYes(const char16_t * src,const char16_t * limit,UErrorCode &)326*0e209d39SAndroid Build Coastguard Worker     spanQuickCheckYes(const char16_t *src, const char16_t *limit, UErrorCode &) const override {
327*0e209d39SAndroid Build Coastguard Worker         return impl.composeQuickCheck(src, limit, onlyContiguous, nullptr);
328*0e209d39SAndroid Build Coastguard Worker     }
329*0e209d39SAndroid Build Coastguard Worker     using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
getQuickCheck(UChar32 c)330*0e209d39SAndroid Build Coastguard Worker     virtual UNormalizationCheckResult getQuickCheck(UChar32 c) const override {
331*0e209d39SAndroid Build Coastguard Worker         return impl.getCompQuickCheck(impl.getNorm16(c));
332*0e209d39SAndroid Build Coastguard Worker     }
hasBoundaryBefore(UChar32 c)333*0e209d39SAndroid Build Coastguard Worker     virtual UBool hasBoundaryBefore(UChar32 c) const override {
334*0e209d39SAndroid Build Coastguard Worker         return impl.hasCompBoundaryBefore(c);
335*0e209d39SAndroid Build Coastguard Worker     }
hasBoundaryAfter(UChar32 c)336*0e209d39SAndroid Build Coastguard Worker     virtual UBool hasBoundaryAfter(UChar32 c) const override {
337*0e209d39SAndroid Build Coastguard Worker         return impl.hasCompBoundaryAfter(c, onlyContiguous);
338*0e209d39SAndroid Build Coastguard Worker     }
isInert(UChar32 c)339*0e209d39SAndroid Build Coastguard Worker     virtual UBool isInert(UChar32 c) const override {
340*0e209d39SAndroid Build Coastguard Worker         return impl.isCompInert(c, onlyContiguous);
341*0e209d39SAndroid Build Coastguard Worker     }
342*0e209d39SAndroid Build Coastguard Worker 
343*0e209d39SAndroid Build Coastguard Worker     const UBool onlyContiguous;
344*0e209d39SAndroid Build Coastguard Worker };
345*0e209d39SAndroid Build Coastguard Worker 
346*0e209d39SAndroid Build Coastguard Worker class FCDNormalizer2 : public Normalizer2WithImpl {
347*0e209d39SAndroid Build Coastguard Worker public:
FCDNormalizer2(const Normalizer2Impl & ni)348*0e209d39SAndroid Build Coastguard Worker     FCDNormalizer2(const Normalizer2Impl &ni) : Normalizer2WithImpl(ni) {}
349*0e209d39SAndroid Build Coastguard Worker     virtual ~FCDNormalizer2();
350*0e209d39SAndroid Build Coastguard Worker 
351*0e209d39SAndroid Build Coastguard Worker private:
352*0e209d39SAndroid Build Coastguard Worker     virtual void
normalize(const char16_t * src,const char16_t * limit,ReorderingBuffer & buffer,UErrorCode & errorCode)353*0e209d39SAndroid Build Coastguard Worker     normalize(const char16_t *src, const char16_t *limit,
354*0e209d39SAndroid Build Coastguard Worker               ReorderingBuffer &buffer, UErrorCode &errorCode) const override {
355*0e209d39SAndroid Build Coastguard Worker         impl.makeFCD(src, limit, &buffer, errorCode);
356*0e209d39SAndroid Build Coastguard Worker     }
357*0e209d39SAndroid Build Coastguard Worker     using Normalizer2WithImpl::normalize;  // Avoid warning about hiding base class function.
358*0e209d39SAndroid Build Coastguard Worker     virtual void
normalizeAndAppend(const char16_t * src,const char16_t * limit,UBool doNormalize,UnicodeString & safeMiddle,ReorderingBuffer & buffer,UErrorCode & errorCode)359*0e209d39SAndroid Build Coastguard Worker     normalizeAndAppend(const char16_t *src, const char16_t *limit, UBool doNormalize,
360*0e209d39SAndroid Build Coastguard Worker                        UnicodeString &safeMiddle,
361*0e209d39SAndroid Build Coastguard Worker                        ReorderingBuffer &buffer, UErrorCode &errorCode) const override {
362*0e209d39SAndroid Build Coastguard Worker         impl.makeFCDAndAppend(src, limit, doNormalize, safeMiddle, buffer, errorCode);
363*0e209d39SAndroid Build Coastguard Worker     }
364*0e209d39SAndroid Build Coastguard Worker     virtual const char16_t *
spanQuickCheckYes(const char16_t * src,const char16_t * limit,UErrorCode & errorCode)365*0e209d39SAndroid Build Coastguard Worker     spanQuickCheckYes(const char16_t *src, const char16_t *limit, UErrorCode &errorCode) const override {
366*0e209d39SAndroid Build Coastguard Worker         return impl.makeFCD(src, limit, nullptr, errorCode);
367*0e209d39SAndroid Build Coastguard Worker     }
368*0e209d39SAndroid Build Coastguard Worker     using Normalizer2WithImpl::spanQuickCheckYes;  // Avoid warning about hiding base class function.
hasBoundaryBefore(UChar32 c)369*0e209d39SAndroid Build Coastguard Worker     virtual UBool hasBoundaryBefore(UChar32 c) const override {
370*0e209d39SAndroid Build Coastguard Worker         return impl.hasFCDBoundaryBefore(c);
371*0e209d39SAndroid Build Coastguard Worker     }
hasBoundaryAfter(UChar32 c)372*0e209d39SAndroid Build Coastguard Worker     virtual UBool hasBoundaryAfter(UChar32 c) const override {
373*0e209d39SAndroid Build Coastguard Worker         return impl.hasFCDBoundaryAfter(c);
374*0e209d39SAndroid Build Coastguard Worker     }
isInert(UChar32 c)375*0e209d39SAndroid Build Coastguard Worker     virtual UBool isInert(UChar32 c) const override {
376*0e209d39SAndroid Build Coastguard Worker         return impl.isFCDInert(c);
377*0e209d39SAndroid Build Coastguard Worker     }
378*0e209d39SAndroid Build Coastguard Worker };
379*0e209d39SAndroid Build Coastguard Worker 
380*0e209d39SAndroid Build Coastguard Worker struct Norm2AllModes : public UMemory {
Norm2AllModesNorm2AllModes381*0e209d39SAndroid Build Coastguard Worker     Norm2AllModes(Normalizer2Impl *i)
382*0e209d39SAndroid Build Coastguard Worker             : impl(i), comp(*i, false), decomp(*i), fcd(*i), fcc(*i, true) {}
383*0e209d39SAndroid Build Coastguard Worker     ~Norm2AllModes();
384*0e209d39SAndroid Build Coastguard Worker 
385*0e209d39SAndroid Build Coastguard Worker     static Norm2AllModes *createInstance(Normalizer2Impl *impl, UErrorCode &errorCode);
386*0e209d39SAndroid Build Coastguard Worker     static Norm2AllModes *createNFCInstance(UErrorCode &errorCode);
387*0e209d39SAndroid Build Coastguard Worker     static Norm2AllModes *createInstance(const char *packageName,
388*0e209d39SAndroid Build Coastguard Worker                                          const char *name,
389*0e209d39SAndroid Build Coastguard Worker                                          UErrorCode &errorCode);
390*0e209d39SAndroid Build Coastguard Worker 
391*0e209d39SAndroid Build Coastguard Worker     static const Norm2AllModes *getNFCInstance(UErrorCode &errorCode);
392*0e209d39SAndroid Build Coastguard Worker     static const Norm2AllModes *getNFKCInstance(UErrorCode &errorCode);
393*0e209d39SAndroid Build Coastguard Worker     static const Norm2AllModes *getNFKC_CFInstance(UErrorCode &errorCode);
394*0e209d39SAndroid Build Coastguard Worker     static const Norm2AllModes *getNFKC_SCFInstance(UErrorCode &errorCode);
395*0e209d39SAndroid Build Coastguard Worker 
396*0e209d39SAndroid Build Coastguard Worker     Normalizer2Impl *impl;
397*0e209d39SAndroid Build Coastguard Worker     ComposeNormalizer2 comp;
398*0e209d39SAndroid Build Coastguard Worker     DecomposeNormalizer2 decomp;
399*0e209d39SAndroid Build Coastguard Worker     FCDNormalizer2 fcd;
400*0e209d39SAndroid Build Coastguard Worker     ComposeNormalizer2 fcc;
401*0e209d39SAndroid Build Coastguard Worker };
402*0e209d39SAndroid Build Coastguard Worker 
403*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END
404*0e209d39SAndroid Build Coastguard Worker 
405*0e209d39SAndroid Build Coastguard Worker #endif  // !UCONFIG_NO_NORMALIZATION
406*0e209d39SAndroid Build Coastguard Worker #endif  // __NORM2ALLMODES_H__
407