static int collator_regular_compare_function(CVarRef v1, CVarRef v2, const void *data, bool ascending) { Variant str1 = collator_convert_object_to_string(v1); Variant str2 = collator_convert_object_to_string(v2); Variant num1; Variant num2; Variant norm1; Variant norm2; /* If both args are strings AND either of args is not numeric string * then use ICU-compare. Otherwise PHP-compare. */ if (str1.isString() && str2.isString()) { num1 = collator_convert_string_to_number_if_possible(str1); if (!same(num1, false)) { num2 = collator_convert_string_to_number_if_possible(str2); } if (same(num1, false) || same(num2, false)) { assert(data); int ret = ucol_strcoll((const UCollator *)data, (UChar*)(str1.toString().data()), UCHARS(str1.toString().length()), (UChar*)(str2.toString().data()), UCHARS(str2.toString().length())); return ascending ? ret : (-ret); } } /* num1 is set if str1 and str2 are strings. */ if (!num1.isNull()) { if (same(num1, false)) { /* str1 is string but not numeric string just convert it to utf8. */ UErrorCode status; norm1 = intl_convert_str_utf16_to_utf8(str1, &status); if (U_FAILURE(status)) { raise_warning("Error converting utf16 to utf8 in " "collator_regular_compare_function()"); } /* num2 is not set but str2 is string => do normalization. */ norm2 = collator_normalize_sort_argument(str2); } else { /* str1 is numeric strings => passthru to PHP-compare. */ norm1 = num1; norm2 = num2; } } else { /* str1 or str2 is not a string => do normalization. */ norm1 = collator_normalize_sort_argument(str1); norm2 = collator_normalize_sort_argument(str2); } if (ascending) { if (norm1.less(norm2)) return -1; if (norm1.equal(norm2)) return 0; return 1; } if (norm1.less(norm2)) return 1; if (norm1.equal(norm2)) return 0; return -1; }
static void collator_convert_array_from_utf16_to_utf8(Array &array, UErrorCode * status) { for (ArrayIter iter(array); iter; ++iter) { CVarRef value = iter.secondRef(); /* Process string values only. */ if (!value.isString()) continue; String str = intl_convert_str_utf16_to_utf8(value, status); if (U_FAILURE(*status)) { return; } /* Update current value with the converted value. */ const_cast<Variant&>(value) = str; } }
static Variant collator_normalize_sort_argument(CVarRef arg) { if (!arg.isString()) return arg; Variant n_arg = collator_convert_string_to_number_if_possible(arg); if (same(n_arg, false)) { /* Conversion to number failed. */ UErrorCode status; n_arg = intl_convert_str_utf16_to_utf8(arg, &status); if (U_FAILURE(status)) { raise_warning("Error converting utf16 to utf8 in " "collator_normalize_sort_argument()"); } } return n_arg; }
static void collator_convert_array_from_utf16_to_utf8(Array &array, UErrorCode * status) { for (ArrayIter iter(array); iter; ++iter) { const Variant& value = iter.secondRef(); /* Process string values only. */ if (!value.isString()) continue; String str = intl_convert_str_utf16_to_utf8(value.toString(), status); if (U_FAILURE(*status)) { return; } /* Update current value with the converted value. */ Variant key = iter.first(); array.set(key, str); } }