Esempio n. 1
0
int32_t String8::getUtf32At(size_t index, size_t *next_index) const
{
    return utf32_at(mString, length(), index, next_index);
}
static bool GetExpectedString(
    const char *src, char **dst, size_t *dst_len,
    int (*get_codepoint_function)(char32_t, char32_t, bool*)) {
    if (dst == NULL || dst_len == NULL) {
        return false;
    }

    if (src == NULL || *src == '\0') {
        src = STR_FOR_NULL_STR;
    }

    char32_t codepoints[MAX_CODEPOINTS]; // if array size is changed the for loop needs to be changed

    size_t src_len = utf8_length(src);
    if (src_len == 0) {
        return false;
    }
    bool next_is_consumed;
    size_t j = 0;
    for (size_t i = 0; i < src_len && j < MAX_CODEPOINTS;) {
        int32_t ret = utf32_at(src, src_len, i, &i);
        if (ret < 0) {
            // failed to parse UTF-8
            return false;
        }
        ret = get_codepoint_function(
                static_cast<char32_t>(ret),
                i + 1 < src_len ? src[i + 1] : 0,
                &next_is_consumed);
        if (ret > 0) {
            codepoints[j] = static_cast<char32_t>(ret);
            j++;
        }
        if (next_is_consumed) {
            i++;
        }
    }
    size_t length = j;

    if (length == 0) {
        // If all of codepoints are invalid, we place the string at the end of
        // the list.
        codepoints[0] = 0x10000 + CODEPOINT_FOR_NULL_STR;
        length = 1;
    }

    size_t new_len = utf8_length_from_utf32(codepoints, length);
    *dst = static_cast<char *>(malloc(new_len + 1));
    if (*dst == NULL) {
        return false;
    }

    if (utf32_to_utf8(codepoints, length, *dst, new_len + 1) != new_len) {
        free(*dst);
        *dst = NULL;
        return false;
    }

    *dst_len = new_len;
    return true;
}