static unsigned Utf32ToUtf8()

in src/LttngHelpers.c [300:391]


static unsigned Utf32ToUtf8(
    char32_t const *pch32,
    unsigned cch32,
    unsigned char *pch8,
    unsigned cch8)
    lttng_ust_notrace;
static unsigned Utf32ToUtf8(
    char32_t const *pch32,
    unsigned cch32,
    unsigned char *pch8,
    unsigned cch8)
{
    unsigned ich8 = 0;
    unsigned ich32 = 0;

    // Since we never get cch32 > 65535, we can safely skip testing for overflow of ich8.
    assert(cch32 <= (0xFFFFFFFF / 7));

    while (ich32 != cch32)
    {
        // Note that this algorithm accepts unmatched surrogate pairs.
        // That's probably the right decision for logging - we want to preserve
        // them so they can be noticed and fixed.
        unsigned val32 = pch32[ich32];
        ich32 += 1;
        if (caa_likely(val32 < 0x80))
        {
            if (caa_unlikely(ich8 == cch8))
                break;
            pch8[ich8++] = (unsigned char)val32;
        }
        else if (caa_likely(val32 < 0x800))
        {
            if (caa_unlikely(ich8 + 1 >= cch8))
                break;
            pch8[ich8++] = (unsigned char)(((val32 >> 6)) | 0xc0);
            pch8[ich8++] = (unsigned char)(((val32)&0x3f) | 0x80);
        }
        else if (caa_likely(val32 < 0x10000))
        {
            if (caa_unlikely(ich8 + 2 >= cch8))
                break;
            pch8[ich8++] = (unsigned char)(((val32 >> 12)) | 0xe0);
            pch8[ich8++] = (unsigned char)(((val32 >> 6) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32)&0x3f) | 0x80);
        }
        else if (caa_likely(val32 < 0x200000))
        {
            if (caa_unlikely(ich8 + 3 >= cch8))
                break;
            pch8[ich8++] = (unsigned char)(((val32 >> 18)) | 0xf0);
            pch8[ich8++] = (unsigned char)(((val32 >> 12) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 6) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32)&0x3f) | 0x80);
        }
        else if (caa_likely(val32 < 0x4000000))
        {
            if (caa_unlikely(ich8 + 4 >= cch8))
                break;
            pch8[ich8++] = (unsigned char)(((val32 >> 24)) | 0xf8);
            pch8[ich8++] = (unsigned char)(((val32 >> 18) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 12) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 6) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32)&0x3f) | 0x80);
        }
        else if (caa_likely(val32 < 0x80000000))
        {
            if (caa_unlikely(ich8 + 5 >= cch8))
                break;
            pch8[ich8++] = (unsigned char)(((val32 >> 30)) | 0xfc);
            pch8[ich8++] = (unsigned char)(((val32 >> 24) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 18) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 12) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 6) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32)&0x3f) | 0x80);
        }
        else
        {
            if (caa_unlikely(ich8 + 6 >= cch8))
                break;
            pch8[ich8++] = (unsigned char)0xfe;
            pch8[ich8++] = (unsigned char)(((val32 >> 30) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 24) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 18) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 12) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32 >> 6) & 0x3f) | 0x80);
            pch8[ich8++] = (unsigned char)(((val32)&0x3f) | 0x80);
        }
    }

    return ich8;
}