UnicodeString & FilteredNormalizer2::normalizeSecondAndAppend(UnicodeString &first, const UnicodeString &second, UBool doNormalize, UErrorCode &errorCode) const { uprv_checkCanGetBuffer(first, errorCode); uprv_checkCanGetBuffer(second, errorCode); if(U_FAILURE(errorCode)) { return first; } if(&first==&second) { errorCode=U_ILLEGAL_ARGUMENT_ERROR; return first; } if(first.isEmpty()) { if(doNormalize) { return normalize(second, first, errorCode); } else { return first=second; } } // merge the in-filter suffix of the first string with the in-filter prefix of the second int32_t prefixLimit=set.span(second, 0, USET_SPAN_SIMPLE); if(prefixLimit!=0) { UnicodeString prefix(second.tempSubString(0, prefixLimit)); int32_t suffixStart=set.spanBack(first, INT32_MAX, USET_SPAN_SIMPLE); if(suffixStart==0) { if(doNormalize) { norm2.normalizeSecondAndAppend(first, prefix, errorCode); } else { norm2.append(first, prefix, errorCode); } } else { UnicodeString middle(first, suffixStart, INT32_MAX); if(doNormalize) { norm2.normalizeSecondAndAppend(middle, prefix, errorCode); } else { norm2.append(middle, prefix, errorCode); } first.replace(suffixStart, INT32_MAX, middle); } } if(prefixLimit<second.length()) { UnicodeString rest(second.tempSubString(prefixLimit, INT32_MAX)); if(doNormalize) { normalize(rest, first, USET_SPAN_NOT_CONTAINED, errorCode); } else { first.append(rest); } } return first; }
UNormalizationCheckResult FilteredNormalizer2::quickCheck(const UnicodeString &s, UErrorCode &errorCode) const { uprv_checkCanGetBuffer(s, errorCode); if(U_FAILURE(errorCode)) { return UNORM_MAYBE; } UNormalizationCheckResult result=UNORM_YES; USetSpanCondition spanCondition=USET_SPAN_SIMPLE; for(int32_t prevSpanLimit=0; prevSpanLimit<s.length();) { int32_t spanLimit=set.span(s, prevSpanLimit, spanCondition); if(spanCondition==USET_SPAN_NOT_CONTAINED) { spanCondition=USET_SPAN_SIMPLE; } else { UNormalizationCheckResult qcResult= norm2.quickCheck(s.tempSubStringBetween(prevSpanLimit, spanLimit), errorCode); if(U_FAILURE(errorCode) || qcResult==UNORM_NO) { return qcResult; } else if(qcResult==UNORM_MAYBE) { result=qcResult; } spanCondition=USET_SPAN_NOT_CONTAINED; } prevSpanLimit=spanLimit; } return result; }
int32_t FilteredNormalizer2::spanQuickCheckYes(const UnicodeString &s, UErrorCode &errorCode) const { uprv_checkCanGetBuffer(s, errorCode); if(U_FAILURE(errorCode)) { return 0; } USetSpanCondition spanCondition=USET_SPAN_SIMPLE; for(int32_t prevSpanLimit=0; prevSpanLimit<s.length();) { int32_t spanLimit=set.span(s, prevSpanLimit, spanCondition); if(spanCondition==USET_SPAN_NOT_CONTAINED) { spanCondition=USET_SPAN_SIMPLE; } else { int32_t yesLimit= prevSpanLimit+ norm2.spanQuickCheckYes( s.tempSubStringBetween(prevSpanLimit, spanLimit), errorCode); if(U_FAILURE(errorCode) || yesLimit<spanLimit) { return yesLimit; } spanCondition=USET_SPAN_NOT_CONTAINED; } prevSpanLimit=spanLimit; } return s.length(); }
UBool FilteredNormalizer2::isNormalized(const UnicodeString & s, UErrorCode & errorCode) const { uprv_checkCanGetBuffer(s, errorCode); if (U_FAILURE(errorCode)) { return FALSE; } USetSpanCondition spanCondition = USET_SPAN_SIMPLE; for (int32_t prevSpanLimit = 0; prevSpanLimit < s.length();) { int32_t spanLimit = set.span(s, prevSpanLimit, spanCondition); if (spanCondition == USET_SPAN_NOT_CONTAINED) { spanCondition = USET_SPAN_SIMPLE; } else { if (!norm2.isNormalized(s.tempSubStringBetween(prevSpanLimit, spanLimit), errorCode) || U_FAILURE(errorCode) ) { return FALSE; } spanCondition = USET_SPAN_NOT_CONTAINED; } prevSpanLimit = spanLimit; } return TRUE; }
UnicodeString & FilteredNormalizer2::normalize(const UnicodeString &src, UnicodeString &dest, UErrorCode &errorCode) const { uprv_checkCanGetBuffer(src, errorCode); if(U_FAILURE(errorCode)) { dest.setToBogus(); return dest; } if(&dest==&src) { errorCode=U_ILLEGAL_ARGUMENT_ERROR; return dest; } dest.remove(); return normalize(src, dest, USET_SPAN_SIMPLE, errorCode); }