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