summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-01-28 20:21:40 +0200
committerIdan Horowitz <idan.horowitz@gmail.com>2022-01-29 13:35:54 +0200
commit308e54bc19615fb0fcb9ec71d6f02cca8c4b75d9 (patch)
tree7d27d27be3c0ca97775633e68b53c71ba659a790 /AK
parent2d67d141e6c2ed76e8510e1838c600004803a9cf (diff)
downloadserenity-308e54bc19615fb0fcb9ec71d6f02cca8c4b75d9.zip
AK+Kernel: Implement UUID mixed endianness support
This is being used by GUID partitions so the first three dash-delimited fields of the GUID are stored in little endian order but the last two fields are stored in big endian order, hence it's a representation which is mixed.
Diffstat (limited to 'AK')
-rw-r--r--AK/UUID.cpp41
-rw-r--r--AK/UUID.h10
2 files changed, 46 insertions, 5 deletions
diff --git a/AK/UUID.cpp b/AK/UUID.cpp
index 4b30f33830..ac76da1464 100644
--- a/AK/UUID.cpp
+++ b/AK/UUID.cpp
@@ -16,7 +16,7 @@ UUID::UUID(Array<u8, 16> uuid_buffer)
uuid_buffer.span().copy_to(m_uuid_buffer);
}
-void UUID::convert_string_view_to_uuid(StringView uuid_string_view)
+void UUID::convert_string_view_to_little_endian_uuid(StringView uuid_string_view)
{
VERIFY(uuid_string_view.length() == 36);
auto first_unit = MUST(decode_hex(uuid_string_view.substring_view(0, 8)));
@@ -36,9 +36,44 @@ void UUID::convert_string_view_to_uuid(StringView uuid_string_view)
m_uuid_buffer.span().overwrite(10, fifth_unit.data(), fifth_unit.size());
}
-UUID::UUID(StringView uuid_string_view)
+void UUID::convert_string_view_to_mixed_endian_uuid(StringView uuid_string_view)
{
- convert_string_view_to_uuid(uuid_string_view);
+ VERIFY(uuid_string_view.length() == 36);
+ auto first_unit = MUST(decode_hex(uuid_string_view.substring_view(0, 8)));
+ auto second_unit = MUST(decode_hex(uuid_string_view.substring_view(9, 4)));
+ auto third_unit = MUST(decode_hex(uuid_string_view.substring_view(14, 4)));
+ auto fourth_unit = MUST(decode_hex(uuid_string_view.substring_view(19, 4)));
+ auto fifth_unit = MUST(decode_hex(uuid_string_view.substring_view(24, 12)));
+
+ VERIFY(first_unit.size() == 4 && second_unit.size() == 2
+ && third_unit.size() == 2 && fourth_unit.size() == 2
+ && fifth_unit.size() == 6);
+
+ // Revert endianness for first 4 bytes
+ for (size_t index = 0; index < 4; index++) {
+ m_uuid_buffer[3 - index] = first_unit[index];
+ }
+
+ // Revert endianness for second 2 bytes and again for 2 bytes
+ for (size_t index = 0; index < 2; index++) {
+ m_uuid_buffer[3 + 2 - index] = second_unit[index];
+ m_uuid_buffer[5 + 2 - index] = third_unit[index];
+ }
+
+ m_uuid_buffer.span().overwrite(8, fourth_unit.data(), fourth_unit.size());
+ m_uuid_buffer.span().overwrite(10, fifth_unit.data(), fifth_unit.size());
+}
+
+UUID::UUID(StringView uuid_string_view, Endianness endianness)
+{
+ if (endianness == Endianness::Little) {
+ convert_string_view_to_little_endian_uuid(uuid_string_view);
+ return;
+ } else if (endianness == Endianness::Mixed) {
+ convert_string_view_to_mixed_endian_uuid(uuid_string_view);
+ return;
+ }
+ VERIFY_NOT_REACHED();
}
String UUID::to_string() const
diff --git a/AK/UUID.h b/AK/UUID.h
index 3d69414346..066d301091 100644
--- a/AK/UUID.h
+++ b/AK/UUID.h
@@ -15,9 +15,14 @@ namespace AK {
class UUID {
public:
+ enum class Endianness {
+ Mixed,
+ Little
+ };
+
UUID() = default;
UUID(Array<u8, 16> uuid_buffer);
- UUID(StringView);
+ UUID(StringView, Endianness endianness = Endianness::Little);
~UUID() = default;
bool operator==(const UUID&) const;
@@ -31,7 +36,8 @@ public:
bool is_zero() const;
private:
- void convert_string_view_to_uuid(StringView);
+ void convert_string_view_to_little_endian_uuid(StringView);
+ void convert_string_view_to_mixed_endian_uuid(StringView);
Array<u8, 16> m_uuid_buffer {};
};