uint32_t RuleBasedCollator::setVariableTop(const UnicodeString varTop, UErrorCode &status) { checkOwned(); return ucol_setVariableTop(ucollator, varTop.getBuffer(), varTop.length(), &status); }
U_CAPI UCollator* U_EXPORT2 ucol_openFromShortString( const char *definition, UBool forceDefaults, UParseError *parseError, UErrorCode *status) { UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN_FROM_SHORT_STRING); UTRACE_DATA1(UTRACE_INFO, "short string = \"%s\"", definition); if(U_FAILURE(*status)) return 0; UParseError internalParseError; if(!parseError) { parseError = &internalParseError; } parseError->line = 0; parseError->offset = 0; parseError->preContext[0] = 0; parseError->postContext[0] = 0; // first we want to pick stuff out of short string. // we'll end up with an UCA version, locale and a bunch of // settings // analyse the string in order to get everything we need. const char *string = definition; CollatorSpec s; ucol_sit_initCollatorSpecs(&s); string = ucol_sit_readSpecs(&s, definition, parseError, status); ucol_sit_calculateWholeLocale(&s); char buffer[internalBufferSize]; uprv_memset(buffer, 0, internalBufferSize); uloc_canonicalize(s.locale, buffer, internalBufferSize, status); UCollator *result = ucol_open(buffer, status); int32_t i = 0; for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) { if(s.options[i] != UCOL_DEFAULT) { if(forceDefaults || ucol_getAttribute(result, (UColAttribute)i, status) != s.options[i]) { ucol_setAttribute(result, (UColAttribute)i, s.options[i], status); } if(U_FAILURE(*status)) { parseError->offset = (int32_t)(string - definition); ucol_close(result); return NULL; } } } if(s.variableTopSet) { if(s.variableTopString[0]) { ucol_setVariableTop(result, s.variableTopString, s.variableTopStringLen, status); } else { // we set by value, using 'B' ucol_restoreVariableTop(result, s.variableTopValue, status); } } if(U_FAILURE(*status)) { // here it can only be a bogus value ucol_close(result); result = NULL; } UTRACE_EXIT_PTR_STATUS(result, *status); return result; }
uint32_t RuleBasedCollator::setVariableTop(const UChar *varTop, int32_t len, UErrorCode &status) { checkOwned(); return ucol_setVariableTop(ucollator, varTop, len, &status); }
/* * The collator returned by this function is owned by the callee and must be * closed when this method returns with a U_SUCCESS UErrorCode. * * On error, the return value is undefined. */ UCollator* CloneCollatorWithOptions(const UCollator* pCollator, int32_t options, UErrorCode* pErr) { UColAttributeValue strength = ucol_getStrength(pCollator); bool isIgnoreCase = (options & CompareOptionsIgnoreCase) == CompareOptionsIgnoreCase; bool isIgnoreNonSpace = (options & CompareOptionsIgnoreNonSpace) == CompareOptionsIgnoreNonSpace; bool isIgnoreSymbols = (options & CompareOptionsIgnoreSymbols) == CompareOptionsIgnoreSymbols; if (isIgnoreCase) { strength = UCOL_SECONDARY; } if (isIgnoreNonSpace) { strength = UCOL_PRIMARY; } UCollator* pClonedCollator; std::vector<UChar> customRules = GetCustomRules(options, strength, isIgnoreSymbols); if (customRules.empty()) { pClonedCollator = ucol_safeClone(pCollator, nullptr, nullptr, pErr); } else { int32_t customRuleLength = customRules.size(); int32_t localeRulesLength; const UChar* localeRules = ucol_getRules(pCollator, &localeRulesLength); std::vector<UChar> completeRules(localeRulesLength + customRuleLength + 1, '\0'); for (int i = 0; i < localeRulesLength; i++) { completeRules[i] = localeRules[i]; } for (int i = 0; i < customRuleLength; i++) { completeRules[localeRulesLength + i] = customRules[i]; } pClonedCollator = ucol_openRules(completeRules.data(), completeRules.size(), UCOL_DEFAULT, strength, NULL, pErr); } if (isIgnoreSymbols) { ucol_setAttribute(pClonedCollator, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, pErr); // by default, ICU alternate shifted handling only ignores punctuation, but // IgnoreSymbols needs symbols and currency as well, so change the "variable top" // to include all symbols and currency #if HAVE_SET_MAX_VARIABLE ucol_setMaxVariable(pClonedCollator, UCOL_REORDER_CODE_CURRENCY, pErr); #else // 0xfdfc is the last currency character before the first digit character // in http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source/data/unidata/FractionalUCA.txt const UChar ignoreSymbolsVariableTop[] = { 0xfdfc }; ucol_setVariableTop(pClonedCollator, ignoreSymbolsVariableTop, 1, pErr); #endif } ucol_setAttribute(pClonedCollator, UCOL_STRENGTH, strength, pErr); // casing differs at the tertiary level. // if strength is less than tertiary, but we are not ignoring case, then we need to flip CASE_LEVEL On if (strength < UCOL_TERTIARY && !isIgnoreCase) { ucol_setAttribute(pClonedCollator, UCOL_CASE_LEVEL, UCOL_ON, pErr); } return pClonedCollator; }