luna: Make Utf8StringEncoder short-circuit instead of failing when hitting the length limit
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
e3ef29e80d
commit
d0600f5714
@ -2,8 +2,6 @@
|
|||||||
#include <luna/CString.h>
|
#include <luna/CString.h>
|
||||||
#include <luna/Utf8.h>
|
#include <luna/Utf8.h>
|
||||||
|
|
||||||
// FIXME: Not enough space for a sequence is not an error. (mbstowcs(3) and wcstombs(3), case 2 when buf is not NULL)
|
|
||||||
|
|
||||||
static_assert(WCHAR_MAX > 0x10ffff);
|
static_assert(WCHAR_MAX > 0x10ffff);
|
||||||
|
|
||||||
static Result<usize> utf8_char_length(char c)
|
static Result<usize> utf8_char_length(char c)
|
||||||
@ -32,31 +30,31 @@ static inline usize wide_char_length_as_utf8_unchecked(wchar_t c)
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<void> encode_wide_char_as_utf8(wchar_t c, char* result, usize& len)
|
static Result<bool> encode_wide_char_as_utf8(wchar_t c, char* result, usize& len)
|
||||||
{
|
{
|
||||||
const usize utf8_len = TRY(wide_char_length_as_utf8(c));
|
const usize utf8_len = TRY(wide_char_length_as_utf8(c));
|
||||||
|
|
||||||
if (utf8_len > len) { return err(EILSEQ); }
|
if (utf8_len > len) { return false; } // Not enough space
|
||||||
|
|
||||||
u8* buf = (u8*)result;
|
u8* buf = (u8*)result;
|
||||||
|
|
||||||
if (len == 1)
|
if (len == 1)
|
||||||
{
|
{
|
||||||
buf[0] = c & 0x7f;
|
buf[0] = c & 0x7f;
|
||||||
return {};
|
return true;
|
||||||
}
|
}
|
||||||
if (len == 2)
|
if (len == 2)
|
||||||
{
|
{
|
||||||
buf[0] = 0b11000000 | ((c & 0x7c0) >> 6);
|
buf[0] = 0b11000000 | ((c & 0x7c0) >> 6);
|
||||||
buf[1] = 0b10000000 | (c & 0x3f);
|
buf[1] = 0b10000000 | (c & 0x3f);
|
||||||
return {};
|
return true;
|
||||||
}
|
}
|
||||||
if (len == 3)
|
if (len == 3)
|
||||||
{
|
{
|
||||||
buf[0] = 0b11100000 | ((c & 0xf000) >> 12);
|
buf[0] = 0b11100000 | ((c & 0xf000) >> 12);
|
||||||
buf[1] = 0b10000000 | ((c & 0xfc0) >> 6);
|
buf[1] = 0b10000000 | ((c & 0xfc0) >> 6);
|
||||||
buf[2] = 0b10000000 | (c & 0x3f);
|
buf[2] = 0b10000000 | (c & 0x3f);
|
||||||
return {};
|
return true;
|
||||||
}
|
}
|
||||||
if (len == 4)
|
if (len == 4)
|
||||||
{
|
{
|
||||||
@ -64,7 +62,7 @@ static Result<void> encode_wide_char_as_utf8(wchar_t c, char* result, usize& len
|
|||||||
buf[1] = 0b10000000 | ((c & 0x3f000) >> 12);
|
buf[1] = 0b10000000 | ((c & 0x3f000) >> 12);
|
||||||
buf[2] = 0b10000000 | ((c & 0xfc0) >> 6);
|
buf[2] = 0b10000000 | ((c & 0xfc0) >> 6);
|
||||||
buf[3] = 0b10000000 | (c & 0x3f);
|
buf[3] = 0b10000000 | (c & 0x3f);
|
||||||
return {};
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable();
|
unreachable();
|
||||||
@ -197,7 +195,8 @@ Result<usize> Utf8StringEncoder::encode(char* buf, usize max) const
|
|||||||
while (*it && max > 1)
|
while (*it && max > 1)
|
||||||
{
|
{
|
||||||
usize len = max - 1;
|
usize len = max - 1;
|
||||||
TRY(encode_wide_char_as_utf8(*it, buf, len));
|
bool ok = TRY(encode_wide_char_as_utf8(*it, buf, len));
|
||||||
|
if (!ok) break;
|
||||||
buf += len;
|
buf += len;
|
||||||
max -= len;
|
max -= len;
|
||||||
it++;
|
it++;
|
||||||
|
Loading…
Reference in New Issue
Block a user