Compare commits
5 Commits
80914f0bb9
...
ae7c841fff
Author | SHA1 | Date | |
---|---|---|---|
ae7c841fff | |||
b34f2149ee | |||
c5a867d81c | |||
15dcd6ad15 | |||
b4a5aff071 |
@ -20,6 +20,7 @@ extern "C"
|
||||
char* strtok(char* str, const char* delim);
|
||||
|
||||
usize wcslen(const wchar_t* str);
|
||||
int wcscmp(const wchar_t* a, const wchar_t* b);
|
||||
|
||||
char* strdup(const char* str);
|
||||
char* strndup(const char* str, usize max);
|
||||
|
@ -64,6 +64,16 @@ extern "C"
|
||||
return *(const u8*)a - *(const u8*)b;
|
||||
}
|
||||
|
||||
int wcscmp(const wchar_t* a, const wchar_t* b)
|
||||
{
|
||||
while (*a && (*a == *b))
|
||||
{
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return *(const u8*)a - *(const u8*)b;
|
||||
}
|
||||
|
||||
int strncmp(const char* a, const char* b, usize max)
|
||||
{
|
||||
const char* s = a;
|
||||
|
@ -35,6 +35,7 @@ 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));
|
||||
|
||||
if (utf8_len > len) { return false; } // Not enough space
|
||||
len = utf8_len;
|
||||
|
||||
u8* buf = (u8*)result;
|
||||
|
||||
@ -137,9 +138,9 @@ Result<usize> Utf8StringDecoder::code_points() const
|
||||
|
||||
while ((usize)(it - m_str) < m_byte_length)
|
||||
{
|
||||
const usize utf8_len = TRY(utf8_char_length(*it));
|
||||
if ((usize)(it - m_str) + utf8_len > m_byte_length) return err(EILSEQ);
|
||||
it += utf8_len;
|
||||
usize mb_len = m_byte_length - (usize)(it - m_str); // Remaining space
|
||||
TRY(encode_utf8_as_wide_char(it, mb_len));
|
||||
it += mb_len;
|
||||
len++;
|
||||
}
|
||||
|
||||
|
@ -16,5 +16,8 @@ function(luna_test SOURCE_FILE APP_NAME SETUID)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if(BUILD_TESTS)
|
||||
luna_test(libluna/TestVector.cpp TestVector OFF)
|
||||
luna_test(libluna/TestBase64.cpp TestBase64 OFF)
|
||||
luna_test(libluna/TestUtf8.cpp TestUtf8 OFF)
|
||||
endif()
|
||||
|
141
tests/libluna/TestUtf8.cpp
Normal file
141
tests/libluna/TestUtf8.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
#include <luna/CString.h>
|
||||
#include <luna/Utf8.h>
|
||||
#include <test.h>
|
||||
|
||||
TestResult test_basic_utf8_ascii_decoding()
|
||||
{
|
||||
wchar_t buf[20];
|
||||
|
||||
Utf8StringDecoder decoder("hello, world!");
|
||||
validate(!decoder.decode(buf, sizeof(buf)).has_error());
|
||||
|
||||
validate(!wcscmp(buf, L"hello, world!"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_basic_utf8_ascii_encoding()
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
Utf8StringEncoder encoder(L"hello, world!");
|
||||
validate(!encoder.encode(buf, sizeof(buf)).has_error());
|
||||
|
||||
validate(!strcmp(buf, "hello, world!"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_decoding_with_non_ascii_chars()
|
||||
{
|
||||
wchar_t buf[20];
|
||||
|
||||
Utf8StringDecoder decoder("¿ñ?");
|
||||
validate(!decoder.decode(buf, sizeof(buf)).has_error());
|
||||
|
||||
validate(!wcscmp(buf, L"¿ñ?"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_encoding_with_non_ascii_chars()
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
Utf8StringEncoder encoder(L"¿ñ?");
|
||||
validate(!encoder.encode(buf, sizeof(buf)).has_error());
|
||||
|
||||
validate(!strcmp(buf, "¿ñ?"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_decoding_invalid_continuation_byte_at_start()
|
||||
{
|
||||
Utf8StringDecoder decoder("\x83");
|
||||
validate(decoder.code_points().has_error());
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_decoding_invalid_start_byte_at_continuation()
|
||||
{
|
||||
Utf8StringDecoder decoder("\xc2\x7f");
|
||||
validate(decoder.code_points().has_error());
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_decoding_unfinished_sequence()
|
||||
{
|
||||
Utf8StringDecoder decoder("\xe0\x83");
|
||||
validate(decoder.code_points().has_error());
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_decoding_invalid_bytes()
|
||||
{
|
||||
Utf8StringDecoder decoder("\xf5\xf7");
|
||||
validate(decoder.code_points().has_error());
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_decoding_overlong_encoding()
|
||||
{
|
||||
Utf8StringDecoder decoder("\xe0\x80\x80");
|
||||
validate(decoder.code_points().has_error());
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_decoder_calculate_code_points()
|
||||
{
|
||||
Utf8StringDecoder decoder("¿ñ? ✨");
|
||||
auto rc = decoder.code_points();
|
||||
validate(!rc.has_error());
|
||||
validate(rc.value() == 5);
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_encoder_calculate_byte_length()
|
||||
{
|
||||
Utf8StringEncoder encoder(L"¿ñ? ✨");
|
||||
auto rc = encoder.byte_length();
|
||||
validate(!rc.has_error());
|
||||
validate(rc.value() == 9);
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_utf8_encoder_code_points_outside_unicode()
|
||||
{
|
||||
const wchar_t buf[] = { 0x120000, 0x000000 };
|
||||
|
||||
Utf8StringEncoder encoder(buf);
|
||||
validate(encoder.byte_length().has_error());
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
Result<void> test_main()
|
||||
{
|
||||
test_prelude;
|
||||
|
||||
run_test(test_basic_utf8_ascii_decoding);
|
||||
run_test(test_basic_utf8_ascii_encoding);
|
||||
run_test(test_utf8_decoding_with_non_ascii_chars);
|
||||
run_test(test_utf8_encoding_with_non_ascii_chars);
|
||||
run_test(test_utf8_decoding_invalid_continuation_byte_at_start);
|
||||
run_test(test_utf8_decoding_invalid_start_byte_at_continuation);
|
||||
run_test(test_utf8_decoding_unfinished_sequence);
|
||||
run_test(test_utf8_decoding_invalid_bytes);
|
||||
run_test(test_utf8_decoding_overlong_encoding);
|
||||
run_test(test_utf8_decoder_calculate_code_points);
|
||||
run_test(test_utf8_encoder_calculate_byte_length);
|
||||
run_test(test_utf8_encoder_code_points_outside_unicode);
|
||||
|
||||
return {};
|
||||
}
|
Loading…
Reference in New Issue
Block a user