AK: Add conversion functions for packed DOS time format

This also adjusts the FATFS code to use the new functions and removes
the now redundant old conversion functions.
This commit is contained in:
Ollrogge 2023-02-06 20:15:30 +01:00 committed by Andrew Kaster
parent 7e915b145b
commit 361df6eff8
Notes: sideshowbarker 2024-07-17 10:10:18 +09:00
7 changed files with 98 additions and 39 deletions

View file

@ -4,6 +4,7 @@ set(AK_SOURCES
CircularBuffer.cpp CircularBuffer.cpp
DeprecatedFlyString.cpp DeprecatedFlyString.cpp
DeprecatedString.cpp DeprecatedString.cpp
DOSPackedTime.cpp
Error.cpp Error.cpp
FloatingPointStringConversions.cpp FloatingPointStringConversions.cpp
FlyString.cpp FlyString.cpp

39
AK/DOSPackedTime.cpp Normal file
View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2022, Undefine <undefine@undefine.pl>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/DOSPackedTime.h>
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;
}
}

48
AK/DOSPackedTime.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022, Undefine <undefine@undefine.pl>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Time.h>
#include <AK/Types.h>
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

View file

@ -480,6 +480,7 @@ elseif("${SERENITY_ARCH}" STREQUAL "aarch64")
endif() endif()
set(AK_SOURCES set(AK_SOURCES
../AK/DOSPackedTime.cpp
../AK/GenericLexer.cpp ../AK/GenericLexer.cpp
../AK/Hex.cpp ../AK/Hex.cpp
../AK/MemoryStream.cpp ../AK/MemoryStream.cpp

View file

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <AK/DOSPackedTime.h>
#include <AK/EnumBits.h> #include <AK/EnumBits.h>
#include <AK/Types.h> #include <AK/Types.h>
@ -54,38 +55,18 @@ enum class FATAttributes : u8 {
AK_ENUM_BITWISE_OPERATORS(FATAttributes); 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 { struct [[gnu::packed]] FATEntry {
char filename[8]; char filename[8];
char extension[3]; char extension[3];
FATAttributes attributes; FATAttributes attributes;
u8 unused1; u8 unused1;
u8 creation_time_seconds; u8 creation_time_seconds;
FATPackedTime creation_time; DOSPackedTime creation_time;
FATPackedDate creation_date; DOSPackedDate creation_date;
FATPackedDate last_accessed_date; DOSPackedDate last_accessed_date;
u16 first_cluster_high; u16 first_cluster_high;
FATPackedTime modification_time; DOSPackedTime modification_time;
FATPackedDate modification_date; DOSPackedDate modification_date;
u16 first_cluster_low; u16 first_cluster_low;
u32 file_size; u32 file_size;
}; };

View file

@ -31,9 +31,9 @@ FATInode::FATInode(FATFS& fs, FATEntry entry, NonnullOwnPtr<KString> filename)
.uid = 0, .uid = 0,
.gid = 0, .gid = 0,
.link_count = 0, .link_count = 0,
.atime = fat_date_time(m_entry.last_accessed_date, { 0 }), .atime = time_from_packed_dos(m_entry.last_accessed_date, { 0 }),
.ctime = fat_date_time(m_entry.creation_date, m_entry.creation_time), .ctime = time_from_packed_dos(m_entry.creation_date, m_entry.creation_time),
.mtime = fat_date_time(m_entry.modification_date, m_entry.modification_time), .mtime = time_from_packed_dos(m_entry.modification_date, m_entry.modification_time),
.dtime = {}, .dtime = {},
.block_count = 0, .block_count = 0,
.block_size = 0, .block_size = 0,
@ -186,14 +186,6 @@ ErrorOr<NonnullOwnPtr<KString>> FATInode::compute_filename(FATEntry& entry, Vect
VERIFY_NOT_REACHED(); 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) StringView FATInode::byte_terminated_string(StringView string, u8 fill_byte)
{ {
if (auto index = string.find_last_not(fill_byte); index.has_value()) if (auto index = string.find_last_not(fill_byte); index.has_value())

View file

@ -39,14 +39,11 @@ private:
static constexpr u8 lfn_entry_character_termination = 0x00; static constexpr u8 lfn_entry_character_termination = 0x00;
static constexpr u8 lfn_entry_unused_byte = 0xFF; 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_filename_length = 8;
static constexpr u8 normal_extension_length = 3; static constexpr u8 normal_extension_length = 3;
static ErrorOr<NonnullOwnPtr<KString>> compute_filename(FATEntry&, Vector<FATLongFileNameEntry> const& = {}); static ErrorOr<NonnullOwnPtr<KString>> compute_filename(FATEntry&, Vector<FATLongFileNameEntry> const& = {});
static StringView byte_terminated_string(StringView, u8); static StringView byte_terminated_string(StringView, u8);
static Time fat_date_time(FATPackedDate, FATPackedTime);
ErrorOr<Vector<BlockBasedFileSystem::BlockIndex>> compute_block_list(); ErrorOr<Vector<BlockBasedFileSystem::BlockIndex>> compute_block_list();
ErrorOr<NonnullOwnPtr<KBuffer>> read_block_list(); ErrorOr<NonnullOwnPtr<KBuffer>> read_block_list();