示例#1
0
文件: shared.c 项目: tidatida/parrot
PARROT_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
STRING *
encoding_to_encoding(PARROT_INTERP, ARGIN(const STRING *src),
        ARGIN(const STR_VTABLE *encoding), double avg_bytes)
{
    ASSERT_ARGS(encoding_to_encoding)
    STRING           *result;
    String_iter       src_iter, dest_iter;
    UINTVAL           src_len, alloc_bytes;
    UINTVAL           max_bytes = encoding->max_bytes_per_codepoint;

    if (src->encoding == encoding)
        return Parrot_str_clone(interp, src);

    src_len          = src->strlen;
    result           = Parrot_gc_new_string_header(interp, 0);
    result->encoding = encoding;
    result->strlen   = src_len;

    if (!src_len)
        return result;

    alloc_bytes = (UINTVAL)(src_len * avg_bytes);
    if (alloc_bytes < max_bytes)
        alloc_bytes = max_bytes;
    Parrot_gc_allocate_string_storage(interp, result, alloc_bytes);
    result->bufused = alloc_bytes;

    STRING_ITER_INIT(interp, &src_iter);
    STRING_ITER_INIT(interp, &dest_iter);

    while (src_iter.charpos < src_len) {
        const UINTVAL c      = STRING_iter_get_and_advance(interp, src, &src_iter);
        const UINTVAL needed = dest_iter.bytepos + max_bytes;

        if (needed > result->bufused) {
            alloc_bytes  = src_len - src_iter.charpos;
            alloc_bytes  = (UINTVAL)(alloc_bytes * avg_bytes);
            alloc_bytes += needed;
            Parrot_gc_reallocate_string_storage(interp, result, alloc_bytes);
            result->bufused = alloc_bytes;
        }

        STRING_iter_set_and_advance(interp, result, &dest_iter, c);
    }

    result->bufused = dest_iter.bytepos;

    return result;
}
示例#2
0
文件: utf16.c 项目: Cristofor/parrot
PARROT_WARN_UNUSED_RESULT
PARROT_CANNOT_RETURN_NULL
static STRING *
utf16_to_encoding(PARROT_INTERP, ARGIN(const STRING *src))
{
    ASSERT_ARGS(utf16_to_encoding)
    STRING  *result;
    UINTVAL  src_len;

    src_len = STRING_length(src);

    if (STRING_max_bytes_per_codepoint(src) == 1) {
        result           = Parrot_gc_new_string_header(interp, 0);
        result->encoding = Parrot_ucs2_encoding_ptr;
        result->bufused  = 2 * src_len;
        result->strlen   = src_len;

        if (src_len) {
            UINTVAL       i;
            Parrot_UInt2 *p;

            Parrot_gc_allocate_string_storage(interp, result, 2 * src_len);
            p = (Parrot_UInt2 *)result->strstart;

            for (i = 0; i < src_len; ++i) {
                p[i] = (unsigned char)src->strstart[i];
            }
        }
    }
    else if (src->encoding == Parrot_utf16_encoding_ptr
         ||  src->encoding == Parrot_ucs2_encoding_ptr) {
        /* we have to use clone instead of copy because the Unicode upcase
         * and downcase functions assume to get an unshared buffer */
        result = Parrot_str_clone(interp, src);
    }
    else {
        result = encoding_to_encoding(interp, src, Parrot_utf16_encoding_ptr, 2.2);

        /* downgrade if possible */
        if (result->bufused == result->strlen << 1)
            result->encoding = Parrot_ucs2_encoding_ptr;
    }

    return result;
}