Beispiel #1
0
/**
 * Compares two strings using case insensitive natural sort.
 *
 * @param s1 First string to compare.
 * @param s2 Second string to compare.
 * @param ignore_garbage_at_front Skip punctuation characters in the front
 * @return Less than zero if s1 < s2, zero if s1 == s2, greater than zero if s1 > s2.
 */
int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front)
{
	if (ignore_garbage_at_front) {
		s1 = SkipGarbage(s1);
		s2 = SkipGarbage(s2);
	}
#ifdef WITH_ICU
	if (_current_collator != NULL) {
		UErrorCode status = U_ZERO_ERROR;
		int result;

		/* We want to use the new faster method for ICU 4.2 and higher. */
#if U_ICU_VERSION_MAJOR_NUM > 4 || (U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM >= 2)
		/* The StringPiece parameter gets implicitly constructed from the char *. */
		result = _current_collator->compareUTF8(s1, s2, status);
#else /* The following for 4.0 and lower. */
		UChar buffer1[DRAW_STRING_BUFFER];
		u_strFromUTF8Lenient(buffer1, lengthof(buffer1), NULL, s1, -1, &status);
		UChar buffer2[DRAW_STRING_BUFFER];
		u_strFromUTF8Lenient(buffer2, lengthof(buffer2), NULL, s2, -1, &status);

		result = _current_collator->compare(buffer1, buffer2, status);
#endif /* ICU version check. */
		if (U_SUCCESS(status)) return result;
	}

#endif /* WITH_ICU */

	/* Do a normal comparison if ICU is missing or if we cannot create a collator. */
	return strcasecmp(s1, s2);
}
Beispiel #2
0
void fts_icu_utf8_to_utf16(buffer_t *dest_utf16, const char *src_utf8)
{
    UErrorCode err = U_ZERO_ERROR;
    unsigned int src_bytes = strlen(src_utf8);
    int32_t utf16_len;
    UChar *dest_data, *retp = NULL;
    int32_t avail_uchars = 0;

    /* try to encode with the current buffer size */
    avail_uchars = buffer_get_writable_size(dest_utf16) / sizeof(UChar);
    dest_data = buffer_get_space_unsafe(dest_utf16, 0,
                                        buffer_get_writable_size(dest_utf16));
    retp = u_strFromUTF8Lenient(dest_data, avail_uchars,
                                &utf16_len, src_utf8, src_bytes, &err);
    if (err == U_BUFFER_OVERFLOW_ERROR) {
        /* try again with a larger buffer */
        dest_data = buffer_get_space_unsafe(dest_utf16, 0,
                                            utf16_len * sizeof(UChar));
        err = U_ZERO_ERROR;
        retp = u_strFromUTF8Lenient(dest_data, utf16_len,
                                    &utf16_len, src_utf8,
                                    src_bytes, &err);
    }
    if (U_FAILURE(err)) {
        i_panic("LibICU u_strFromUTF8Lenient() failed: %s",
                u_errorName(err));
    }
    buffer_set_used_size(dest_utf16, utf16_len * sizeof(UChar));
    i_assert(retp == dest_data);
}