diff --git a/AK/CMakeLists.txt b/AK/CMakeLists.txt index 8ce72a78c92..1188c0f9161 100644 --- a/AK/CMakeLists.txt +++ b/AK/CMakeLists.txt @@ -4,6 +4,7 @@ set(AK_SOURCES CircularBuffer.cpp DeprecatedFlyString.cpp DeprecatedString.cpp + DOSPackedTime.cpp Error.cpp FloatingPointStringConversions.cpp FlyString.cpp diff --git a/AK/DOSPackedTime.cpp b/AK/DOSPackedTime.cpp new file mode 100644 index 00000000000..28d869f444b --- /dev/null +++ b/AK/DOSPackedTime.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022, Undefine + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace AK { + +Time time_from_packed_dos(DOSPackedDate date, DOSPackedTime time) +{ + if (date.value == 0) + return Time(); + + return Time::from_timestamp(first_dos_year + date.year, date.month, date.day, time.hour, time.minute, time.second * 2, 0); +} + +DOSPackedDate to_packed_dos_date(unsigned year, unsigned month, unsigned day) +{ + DOSPackedDate date; + date.year = year - first_dos_year; + date.month = month; + date.day = day; + + return date; +} + +DOSPackedTime to_packed_dos_time(unsigned hour, unsigned minute, unsigned second) +{ + DOSPackedTime time; + time.hour = hour; + time.minute = minute; + time.second = second / 2; + + return time; +} + +} diff --git a/AK/DOSPackedTime.h b/AK/DOSPackedTime.h new file mode 100644 index 00000000000..3dd46aa10e4 --- /dev/null +++ b/AK/DOSPackedTime.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022, Undefine + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace AK { + +union DOSPackedTime { + u16 value; + struct { + u16 second : 5; + u16 minute : 6; + u16 hour : 5; + }; +}; +static_assert(sizeof(DOSPackedTime) == 2); + +union DOSPackedDate { + u16 value; + struct { + u16 day : 5; + u16 month : 4; + u16 year : 7; + }; +}; +static_assert(sizeof(DOSPackedDate) == 2); + +inline constexpr u16 first_dos_year = 1980; + +Time time_from_packed_dos(DOSPackedDate, DOSPackedTime); +DOSPackedDate to_packed_dos_date(unsigned year, unsigned month, unsigned day); +DOSPackedTime to_packed_dos_time(unsigned hour, unsigned minute, unsigned second); + +} + +#if USING_AK_GLOBALLY +using AK::DOSPackedDate; +using AK::DOSPackedTime; +using AK::time_from_packed_dos; +using AK::to_packed_dos_date; +using AK::to_packed_dos_time; +#endif diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index 7236baa0212..036c84f7d66 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -480,6 +480,7 @@ elseif("${SERENITY_ARCH}" STREQUAL "aarch64") endif() set(AK_SOURCES + ../AK/DOSPackedTime.cpp ../AK/GenericLexer.cpp ../AK/Hex.cpp ../AK/MemoryStream.cpp diff --git a/Kernel/FileSystem/FATFS/Definitions.h b/Kernel/FileSystem/FATFS/Definitions.h index d0f47c57f56..938fc064b3a 100644 --- a/Kernel/FileSystem/FATFS/Definitions.h +++ b/Kernel/FileSystem/FATFS/Definitions.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -54,38 +55,18 @@ enum class FATAttributes : u8 { AK_ENUM_BITWISE_OPERATORS(FATAttributes); -union FATPackedTime { - u16 value; - struct { - u16 second : 5; - u16 minute : 6; - u16 hour : 5; - }; -}; -static_assert(sizeof(FATPackedTime) == 2); - -union FATPackedDate { - u16 value; - struct { - u16 day : 5; - u16 month : 4; - u16 year : 7; - }; -}; -static_assert(sizeof(FATPackedDate) == 2); - struct [[gnu::packed]] FATEntry { char filename[8]; char extension[3]; FATAttributes attributes; u8 unused1; u8 creation_time_seconds; - FATPackedTime creation_time; - FATPackedDate creation_date; - FATPackedDate last_accessed_date; + DOSPackedTime creation_time; + DOSPackedDate creation_date; + DOSPackedDate last_accessed_date; u16 first_cluster_high; - FATPackedTime modification_time; - FATPackedDate modification_date; + DOSPackedTime modification_time; + DOSPackedDate modification_date; u16 first_cluster_low; u32 file_size; }; diff --git a/Kernel/FileSystem/FATFS/Inode.cpp b/Kernel/FileSystem/FATFS/Inode.cpp index 65358de1199..0dcd95468c0 100644 --- a/Kernel/FileSystem/FATFS/Inode.cpp +++ b/Kernel/FileSystem/FATFS/Inode.cpp @@ -31,9 +31,9 @@ FATInode::FATInode(FATFS& fs, FATEntry entry, NonnullOwnPtr filename) .uid = 0, .gid = 0, .link_count = 0, - .atime = fat_date_time(m_entry.last_accessed_date, { 0 }), - .ctime = fat_date_time(m_entry.creation_date, m_entry.creation_time), - .mtime = fat_date_time(m_entry.modification_date, m_entry.modification_time), + .atime = time_from_packed_dos(m_entry.last_accessed_date, { 0 }), + .ctime = time_from_packed_dos(m_entry.creation_date, m_entry.creation_time), + .mtime = time_from_packed_dos(m_entry.modification_date, m_entry.modification_time), .dtime = {}, .block_count = 0, .block_size = 0, @@ -186,14 +186,6 @@ ErrorOr> FATInode::compute_filename(FATEntry& entry, Vect VERIFY_NOT_REACHED(); } -Time FATInode::fat_date_time(FATPackedDate date, FATPackedTime time) -{ - if (date.value == 0) - return Time(); - - return Time::from_timestamp(first_fat_year + date.year, date.month, date.day, time.hour, time.minute, time.second * 2, 0); -} - StringView FATInode::byte_terminated_string(StringView string, u8 fill_byte) { if (auto index = string.find_last_not(fill_byte); index.has_value()) diff --git a/Kernel/FileSystem/FATFS/Inode.h b/Kernel/FileSystem/FATFS/Inode.h index 699df808bbf..f2505470bef 100644 --- a/Kernel/FileSystem/FATFS/Inode.h +++ b/Kernel/FileSystem/FATFS/Inode.h @@ -39,14 +39,11 @@ private: static constexpr u8 lfn_entry_character_termination = 0x00; static constexpr u8 lfn_entry_unused_byte = 0xFF; - static constexpr u16 first_fat_year = 1980; - static constexpr u8 normal_filename_length = 8; static constexpr u8 normal_extension_length = 3; static ErrorOr> compute_filename(FATEntry&, Vector const& = {}); static StringView byte_terminated_string(StringView, u8); - static Time fat_date_time(FATPackedDate, FATPackedTime); ErrorOr> compute_block_list(); ErrorOr> read_block_list();