Unicode module

character_utf8_to_utf32

procedure · 1 overloadSource

Decodes the character that starts at s, where source_length bytes are available. Returns the code point, the number of bytes it took and how it went. A call with bytes available always takes at least one.

character_utf8_to_utf32 :: (
    s: *u8,
    source_length: s64,
    $strict := false
) -> (u32, s64, Unicode_Result)

Input that ends early gives UNI_REPLACEMENT_CHAR, all source_length bytes consumed and SOURCE_EXHAUSTED; no bytes at all gives 0 consumed.

A broken byte structure is an error in both modes: a continuation byte (0x80 to 0xBF) where a character should start, or a byte that is not a continuation byte inside a character. The result is UNI_REPLACEMENT_CHAR with SOURCE_ILLEGAL, and the bytes consumed are the lead byte and the continuation bytes that were fine, so decoding can resume at the offending byte (a stray continuation byte takes just itself).

A well-formed sequence with no character behind it (an overlong encoding, a surrogate from 0xD800 to 0xDFFF, or a value above UNI_MAX_UTF16) gives UNI_REPLACEMENT_CHAR and takes the whole sequence. With strict the result is SOURCE_ILLEGAL; without it, which is the default, the sequence is replaced quietly with CONVERSION_OK, so the result is always a Unicode scalar value.

Parameters

s: *u8
source_length: s64
$strict := false

Returns

u32
s64
ExampleOpen in playground ↗
code, size, status := character_utf8_to_utf32("\xe2\x82\xac".data, 3);
assert(status == .CONVERSION_OK && code == 0x20ac && size == 3);

bad := "\xc0\x80";
code, size, status = character_utf8_to_utf32(bad.data, bad.count, true);
assert(status == .SOURCE_ILLEGAL && code == UNI_REPLACEMENT_CHAR && size == 2);

stray := "\x80";
code, size, status = character_utf8_to_utf32(stray.data, stray.count);
assert(status == .SOURCE_ILLEGAL && code == UNI_REPLACEMENT_CHAR && size == 1);

code, size, status = character_utf8_to_utf32(bad.data, bad.count);
assert(status == .CONVERSION_OK && code == UNI_REPLACEMENT_CHAR && size == 2);

See also