mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 05:25:32 +03:00
AK: Implement ShortString for big-endian
This commit is contained in:
parent
b4d13d060a
commit
b54a1c6284
Notes:
sideshowbarker
2024-07-17 06:39:26 +09:00
Author: https://github.com/sideeffect42 Commit: https://github.com/LadybirdBrowser/ladybird/commit/b54a1c6284 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/416 Reviewed-by: https://github.com/ADKaster ✅
@ -14,26 +14,29 @@ namespace AK::Detail {
|
||||
|
||||
class StringData;
|
||||
|
||||
static constexpr size_t MAX_SHORT_STRING_BYTE_COUNT = sizeof(StringData*) - 1;
|
||||
static constexpr size_t MAX_SHORT_STRING_BYTE_COUNT = sizeof(StringData*) - sizeof(u8);
|
||||
|
||||
struct ShortString {
|
||||
ReadonlyBytes bytes() const;
|
||||
size_t byte_count() const;
|
||||
|
||||
// NOTE: This is the byte count shifted left 1 step and or'ed with a 1 (the SHORT_STRING_FLAG)
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
u8 byte_count_and_short_string_flag { 0 };
|
||||
u8 storage[MAX_SHORT_STRING_BYTE_COUNT] = { 0 };
|
||||
#else
|
||||
u8 storage[MAX_SHORT_STRING_BYTE_COUNT] = { 0 };
|
||||
u8 byte_count_and_short_string_flag { 0 };
|
||||
#endif
|
||||
};
|
||||
|
||||
static_assert(HostIsLittleEndian, "Order of fields in ShortString assumes LE.");
|
||||
static_assert(sizeof(ShortString) >= sizeof(StringData*));
|
||||
static_assert(__builtin_offsetof(ShortString, byte_count_and_short_string_flag) == 0);
|
||||
static_assert(sizeof(ShortString) == sizeof(StringData*));
|
||||
|
||||
class StringBase {
|
||||
public:
|
||||
// Creates an empty (zero-length) String.
|
||||
constexpr StringBase()
|
||||
: StringBase(ShortString { SHORT_STRING_FLAG, {} })
|
||||
: StringBase(ShortString { .byte_count_and_short_string_flag = SHORT_STRING_FLAG })
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,27 +63,37 @@ TEST_CASE(copy_assignment)
|
||||
|
||||
TEST_CASE(short_strings)
|
||||
{
|
||||
/** NOTE: make sure that the test strings' first character has an even ASCII code.
|
||||
* This is important for the odd pointer address checks (this is to
|
||||
* test if the ShortString structs are endian agnostic). */
|
||||
#ifdef AK_ARCH_64_BIT
|
||||
auto string1 = MUST(String::from_utf8("abcdefg"sv));
|
||||
auto string1 = MUST(String::from_utf8("foo bar"sv));
|
||||
EXPECT_EQ(string1.is_short_string(), true);
|
||||
EXPECT_EQ(string1.bytes().size(), 7u);
|
||||
EXPECT_EQ(string1.bytes_as_string_view(), "abcdefg"sv);
|
||||
EXPECT_EQ(string1.bytes_as_string_view(), "foo bar"sv);
|
||||
// check for odd "pointer" value, i.e. short string flag
|
||||
EXPECT_EQ(*((uintptr_t*)&string1) % 2UL, 1U);
|
||||
|
||||
auto string2 = "abcdefg"_string;
|
||||
auto string2 = "foo bar"_string;
|
||||
EXPECT_EQ(string2.is_short_string(), true);
|
||||
EXPECT_EQ(string2.bytes().size(), 7u);
|
||||
EXPECT_EQ(string2, string1);
|
||||
|
||||
// check for odd "pointer" value, i.e. short string flag
|
||||
EXPECT_EQ(*((uintptr_t*)&string2) % 2UL, 1U);
|
||||
#else
|
||||
auto string1 = MUST(String::from_utf8("abc"sv));
|
||||
auto string1 = MUST(String::from_utf8("foo"sv));
|
||||
EXPECT_EQ(string1.is_short_string(), true);
|
||||
EXPECT_EQ(string1.bytes().size(), 3u);
|
||||
EXPECT_EQ(string1.bytes_as_string_view(), "abc"sv);
|
||||
EXPECT_EQ(string1.bytes_as_string_view(), "foo"sv);
|
||||
// check for odd "pointer" value, i.e. short string flag
|
||||
EXPECT_EQ(*((uintptr_t*)&string1) % 2U, 1U);
|
||||
|
||||
auto string2 = "abc"_string;
|
||||
auto string2 = "foo"_string;
|
||||
EXPECT_EQ(string2.is_short_string(), true);
|
||||
EXPECT_EQ(string2.bytes().size(), 3u);
|
||||
EXPECT_EQ(string2, string1);
|
||||
// check for odd "pointer" value, i.e. short string flag
|
||||
EXPECT_EQ(*((uintptr_t*)&string2) % 2U, 1U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user