Serenity Operating System
at master 122 lines 4.7 kB view raw
1/* 2 * Copyright (c) 2020, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/AllOf.h> 8#include <AK/Hex.h> 9#include <AK/StringBuilder.h> 10#include <AK/UUID.h> 11 12namespace AK { 13 14UUID::UUID(Array<u8, 16> uuid_buffer) 15{ 16 uuid_buffer.span().copy_to(m_uuid_buffer); 17} 18 19void UUID::convert_string_view_to_little_endian_uuid(StringView uuid_string_view) 20{ 21 VERIFY(uuid_string_view.length() == 36); 22 auto first_unit = MUST(decode_hex(uuid_string_view.substring_view(0, 8))); 23 auto second_unit = MUST(decode_hex(uuid_string_view.substring_view(9, 4))); 24 auto third_unit = MUST(decode_hex(uuid_string_view.substring_view(14, 4))); 25 auto fourth_unit = MUST(decode_hex(uuid_string_view.substring_view(19, 4))); 26 auto fifth_unit = MUST(decode_hex(uuid_string_view.substring_view(24, 12))); 27 28 VERIFY(first_unit.size() == 4 && second_unit.size() == 2 29 && third_unit.size() == 2 && fourth_unit.size() == 2 30 && fifth_unit.size() == 6); 31 32 m_uuid_buffer.span().overwrite(0, first_unit.data(), first_unit.size()); 33 m_uuid_buffer.span().overwrite(4, second_unit.data(), second_unit.size()); 34 m_uuid_buffer.span().overwrite(6, third_unit.data(), third_unit.size()); 35 m_uuid_buffer.span().overwrite(8, fourth_unit.data(), fourth_unit.size()); 36 m_uuid_buffer.span().overwrite(10, fifth_unit.data(), fifth_unit.size()); 37} 38 39void UUID::convert_string_view_to_mixed_endian_uuid(StringView uuid_string_view) 40{ 41 VERIFY(uuid_string_view.length() == 36); 42 auto first_unit = MUST(decode_hex(uuid_string_view.substring_view(0, 8))); 43 auto second_unit = MUST(decode_hex(uuid_string_view.substring_view(9, 4))); 44 auto third_unit = MUST(decode_hex(uuid_string_view.substring_view(14, 4))); 45 auto fourth_unit = MUST(decode_hex(uuid_string_view.substring_view(19, 4))); 46 auto fifth_unit = MUST(decode_hex(uuid_string_view.substring_view(24, 12))); 47 48 VERIFY(first_unit.size() == 4 && second_unit.size() == 2 49 && third_unit.size() == 2 && fourth_unit.size() == 2 50 && fifth_unit.size() == 6); 51 52 // Revert endianness for first 4 bytes 53 for (size_t index = 0; index < 4; index++) { 54 m_uuid_buffer[3 - index] = first_unit[index]; 55 } 56 57 // Revert endianness for second 2 bytes and again for 2 bytes 58 for (size_t index = 0; index < 2; index++) { 59 m_uuid_buffer[3 + 2 - index] = second_unit[index]; 60 m_uuid_buffer[5 + 2 - index] = third_unit[index]; 61 } 62 63 m_uuid_buffer.span().overwrite(8, fourth_unit.data(), fourth_unit.size()); 64 m_uuid_buffer.span().overwrite(10, fifth_unit.data(), fifth_unit.size()); 65} 66 67UUID::UUID(StringView uuid_string_view, Endianness endianness) 68{ 69 if (endianness == Endianness::Little) { 70 convert_string_view_to_little_endian_uuid(uuid_string_view); 71 return; 72 } else if (endianness == Endianness::Mixed) { 73 convert_string_view_to_mixed_endian_uuid(uuid_string_view); 74 return; 75 } 76 VERIFY_NOT_REACHED(); 77} 78 79#ifdef KERNEL 80ErrorOr<NonnullOwnPtr<Kernel::KString>> UUID::to_string() const 81{ 82 StringBuilder builder(36); 83 auto nibble0 = TRY(encode_hex(m_uuid_buffer.span().trim(4))); 84 TRY(builder.try_append(nibble0->view())); 85 TRY(builder.try_append('-')); 86 auto nibble1 = TRY(encode_hex(m_uuid_buffer.span().slice(4).trim(2))); 87 TRY(builder.try_append(nibble1->view())); 88 TRY(builder.try_append('-')); 89 auto nibble2 = TRY(encode_hex(m_uuid_buffer.span().slice(6).trim(2))); 90 TRY(builder.try_append(nibble2->view())); 91 TRY(builder.try_append('-')); 92 auto nibble3 = TRY(encode_hex(m_uuid_buffer.span().slice(8).trim(2))); 93 TRY(builder.try_append(nibble3->view())); 94 TRY(builder.try_append('-')); 95 auto nibble4 = TRY(encode_hex(m_uuid_buffer.span().slice(10).trim(6))); 96 TRY(builder.try_append(nibble4->view())); 97 return Kernel::KString::try_create(builder.string_view()); 98} 99#else 100ErrorOr<String> UUID::to_string() const 101{ 102 auto buffer_span = m_uuid_buffer.span(); 103 StringBuilder builder(36); 104 TRY(builder.try_append(encode_hex(buffer_span.trim(4)).view())); 105 TRY(builder.try_append('-')); 106 TRY(builder.try_append(encode_hex(buffer_span.slice(4, 2)).view())); 107 TRY(builder.try_append('-')); 108 TRY(builder.try_append(encode_hex(buffer_span.slice(6, 2)).view())); 109 TRY(builder.try_append('-')); 110 TRY(builder.try_append(encode_hex(buffer_span.slice(8, 2)).view())); 111 TRY(builder.try_append('-')); 112 TRY(builder.try_append(encode_hex(buffer_span.slice(10, 6)).view())); 113 return builder.to_string(); 114} 115#endif 116 117bool UUID::is_zero() const 118{ 119 return all_of(m_uuid_buffer, [](auto const octet) { return octet == 0; }); 120} 121 122}