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;
}