Skip to content

Commit

Permalink
Merge pull request #15 from MacroModel/trcrsired-master
Browse files Browse the repository at this point in the history
update
  • Loading branch information
MacroModel authored Nov 8, 2024
2 parents 828db91 + 6e1812e commit 5dd54ab
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 49 deletions.
2 changes: 1 addition & 1 deletion include/fast_io_hosted/filesystem/nt.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ inline nt_dirent *set_nt_dirent(nt_dirent *entry, bool start)
}
auto id_ful_dir_info{d_info.IdFullDirInfo};

entry->d_ino = static_cast<::std::uint_least64_t>(id_ful_dir_info->FileId.QuadPart);
entry->d_ino = static_cast<::std::uint_least64_t>(id_ful_dir_info->FileId);

entry->native_d_namlen = id_ful_dir_info->FileNameLength / sizeof(char16_t);

Expand Down
225 changes: 211 additions & 14 deletions include/fast_io_hosted/platforms/nt.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,9 @@ inline ::std::uint_least64_t nt_calculate_current_file_offset(void *__restrict h
{
::fast_io::win32::nt::io_status_block block;
::std::uint_least64_t fps{};
auto status{::fast_io::win32::nt::nt_query_information_file < family == ::fast_io::nt_family::zw > (handle, __builtin_addressof(block), __builtin_addressof(fps),
static_cast<::std::uint_least32_t>(sizeof(::std::uint_least64_t)),
::fast_io::win32::nt::file_information_class::FilePositionInformation)};
auto status{::fast_io::win32::nt::nt_query_information_file<family == ::fast_io::nt_family::zw>(handle, __builtin_addressof(block), __builtin_addressof(fps),
static_cast<::std::uint_least32_t>(sizeof(::std::uint_least64_t)),
::fast_io::win32::nt::file_information_class::FilePositionInformation)};
if (status)
{
throw_nt_error(status);
Expand Down Expand Up @@ -502,8 +502,8 @@ inline ::std::byte *nt_read_pread_some_bytes_common_impl(void *__restrict handle
{
// some poeple in zwclose7 forum said we do not need to initialize io_status_block
::fast_io::win32::nt::io_status_block block;
auto const status{::fast_io::win32::nt::nt_read_file < family == ::fast_io::nt_family::zw > (handle, nullptr, nullptr, nullptr, __builtin_addressof(block), first,
::fast_io::details::read_write_bytes_compute<::std::uint_least32_t>(first, last), pbyteoffset, nullptr)};
auto const status{::fast_io::win32::nt::nt_read_file<family == ::fast_io::nt_family::zw>(handle, nullptr, nullptr, nullptr, __builtin_addressof(block), first,
::fast_io::details::read_write_bytes_compute<::std::uint_least32_t>(first, last), pbyteoffset, nullptr)};
if (status)
{
throw_nt_error(status);
Expand Down Expand Up @@ -532,8 +532,8 @@ inline ::std::byte const *nt_write_pwrite_some_bytes_common_impl(void *__restric
::std::int_least64_t *pbyteoffset)
{
::fast_io::win32::nt::io_status_block block;
auto const status{::fast_io::win32::nt::nt_write_file < family == ::fast_io::nt_family::zw > (handle, nullptr, nullptr, nullptr, __builtin_addressof(block), first,
::fast_io::details::read_write_bytes_compute<::std::uint_least32_t>(first, last), pbyteoffset, nullptr)};
auto const status{::fast_io::win32::nt::nt_write_file<family == ::fast_io::nt_family::zw>(handle, nullptr, nullptr, nullptr, __builtin_addressof(block), first,
::fast_io::details::read_write_bytes_compute<::std::uint_least32_t>(first, last), pbyteoffset, nullptr)};
if (status)
{
throw_nt_error(status);
Expand Down Expand Up @@ -1025,7 +1025,7 @@ template <nt_family family, ::std::integral ch_type>
inline ::fast_io::intfpos_t io_stream_seek_bytes_define(basic_nt_family_io_observer<family, ch_type> handle,
::fast_io::intfpos_t offset, seekdir s)
{
return ::fast_io::win32::nt::details::nt_seek_impl < family == nt_family::zw > (handle.handle, offset, s);
return ::fast_io::win32::nt::details::nt_seek_impl<family == nt_family::zw>(handle.handle, offset, s);
}

template <nt_family family, ::std::integral ch_type>
Expand Down Expand Up @@ -1061,7 +1061,7 @@ struct nt_family_file_lock
requires(sizeof(int_type) >= sizeof(::std::int_least64_t))
inline bool try_lock(basic_flock_request<int_type> &__restrict t) noexcept
{
return ::fast_io::win32::nt::details::nt_family_file_try_lock_impl < family == nt_family::zw > (this->handle, t);
return ::fast_io::win32::nt::details::nt_family_file_try_lock_impl<family == nt_family::zw>(this->handle, t);
}
};

Expand Down Expand Up @@ -1126,12 +1126,12 @@ class basic_nt_family_file : public basic_nt_family_io_observer<family, ch_type>
}
explicit basic_nt_family_file(io_dup_t, basic_nt_family_io_observer<family, ch_type> wiob)
: basic_nt_family_io_observer<family, ch_type>{
::fast_io::win32::nt::details::nt_dup_impl < family == nt_family::zw > (wiob.handle)}
::fast_io::win32::nt::details::nt_dup_impl<family == nt_family::zw>(wiob.handle)}
{
}
explicit basic_nt_family_file(nt_fs_dirent fsdirent, open_mode om, perms pm = static_cast<perms>(436))
: basic_nt_family_io_observer<family, char_type>{
::fast_io::win32::nt::details::nt_family_create_file_fs_dirent_impl < family == nt_family::zw > (fsdirent.handle, fsdirent.filename.c_str(), fsdirent.filename.size(), {om, pm})}
::fast_io::win32::nt::details::nt_family_create_file_fs_dirent_impl<family == nt_family::zw>(fsdirent.handle, fsdirent.filename.c_str(), fsdirent.filename.size(), {om, pm})}
{
}
template <::fast_io::constructible_to_os_c_str T>
Expand Down Expand Up @@ -1166,7 +1166,7 @@ class basic_nt_family_file : public basic_nt_family_io_observer<family, ch_type>
{
if (this->handle) [[likely]]
{
auto status{::fast_io::win32::nt::nt_close < family == nt_family::zw > (this->handle)};
auto status{::fast_io::win32::nt::nt_close<family == nt_family::zw>(this->handle)};
this->handle = nullptr; // POSIX standard says we should never call close(2) again even close syscall fails
if (status) [[unlikely]]
{
Expand All @@ -1184,12 +1184,12 @@ class basic_nt_family_file : public basic_nt_family_io_observer<family, ch_type>
}
basic_nt_family_file(basic_nt_family_file const &other)
: basic_nt_family_io_observer<family, ch_type>(
::fast_io::win32::nt::details::nt_dup_impl < family == nt_family::zw > (other.handle))
::fast_io::win32::nt::details::nt_dup_impl<family == nt_family::zw>(other.handle))
{
}
basic_nt_family_file &operator=(basic_nt_family_file const &other)
{
this->handle = ::fast_io::win32::nt::details::nt_dup2_impl < family == nt_family::zw > (other.handle, this->handle);
this->handle = ::fast_io::win32::nt::details::nt_dup2_impl<family == nt_family::zw>(other.handle, this->handle);
return *this;
}
constexpr basic_nt_family_file(basic_nt_family_file &&__restrict other) noexcept
Expand All @@ -1216,6 +1216,203 @@ class basic_nt_family_file : public basic_nt_family_io_observer<family, ch_type>
}
};

namespace win32::nt::details
{
inline constexpr unix_timestamp to_unix_timestamp(::std::uint_least64_t date_time) noexcept
{
/*
116444736000000000
18446744073709551616
999999999
1000000000
*/

constexpr ::std::uint_least64_t gap{11644473600000ULL * 10000ULL};
constexpr ::std::uint_least64_t mul_factor{uint_least64_subseconds_per_second / 10000000u};
::std::uint_least64_t unix_time{date_time - gap};
if (date_time < gap) [[unlikely]]
{
unix_time = 0;
}
return {static_cast<::std::int_least64_t>(unix_time / 10000000ULL),
static_cast<::std::uint_least64_t>(unix_time % 10000000ULL) * mul_factor};
}

inline file_type file_type_impl(::std::uint_least32_t DeviceType)
{
if (DeviceType > 0x2B)
{
if (DeviceType != 80) [[unlikely]]
{
return file_type::unknown;
}
return file_type::character;
}
if (DeviceType == 43 || DeviceType == 21)
{
return file_type::character;
}
if (DeviceType > 0x15)
{
if (DeviceType > 0x1D)
{
if (DeviceType != 31 && DeviceType != 32 && DeviceType != 33 && DeviceType != 34 && DeviceType == 36) [[likely]]
{
return file_type::regular;
}
return file_type::unknown;
}
switch (DeviceType)
{
case 0x1D:
[[fallthrough]];
case 0x16:
return file_type::character;
case 0x17:
[[unlikely]] return file_type::unknown;
case 0x18:
[[fallthrough]];
case 0x1B:
[[fallthrough]];
case 0x28:
return file_type::character;
default:
[[unlikely]] return file_type::unknown;
}
}
if (DeviceType > 8)
{
if (DeviceType != 11 && DeviceType != 15)
{
if (DeviceType == 17) [[likely]]
{
return file_type::fifo;
}
return file_type::unknown;
}
return file_type::character;
}
return file_type::regular;
}


template <nt_family family>
inline posix_file_status nt_status_impl(void *__restrict handle)
{
::fast_io::win32::nt::io_status_block isb{};

::fast_io::win32::nt::file_fs_device_type ffdt{};
auto status{::fast_io::win32::nt::nt_query_volume_information_file<family == ::fast_io::nt_family::zw>(handle, __builtin_addressof(isb), __builtin_addressof(ffdt), sizeof(ffdt),
::fast_io::win32::nt::fs_information_class::FileFsDeviceInformation)};
if (status) [[unlikely]]
{
throw_nt_error(status);
}

auto ft{file_type_impl(ffdt.DeviceType)};

if (ft == file_type::fifo || ft == file_type::character)
{
return posix_file_status{0,
0,
static_cast<perms>(436),
ft,
1,
0,
0,
static_cast<::std::uintmax_t>(reinterpret_cast<::std::size_t>(handle)),
0,
131072,
0,
{},
{},
{},
{},
0,
0};
}

::fast_io::win32::nt::file_basic_information fbi{};
status = ::fast_io::win32::nt::nt_query_information_file<family == ::fast_io::nt_family::zw>(handle, __builtin_addressof(isb), __builtin_addressof(fbi), sizeof(fbi),
::fast_io::win32::nt::file_information_class::FileBasicInformation);

if (status) [[unlikely]]
{
throw_nt_error(status);
}

::fast_io::win32::nt::file_internal_information fii{};
status = ::fast_io::win32::nt::nt_query_information_file<family == ::fast_io::nt_family::zw>(handle, __builtin_addressof(isb), __builtin_addressof(fii), sizeof(fii),
::fast_io::win32::nt::file_information_class::FileInternalInformation);

if (status) [[unlikely]]
{
throw_nt_error(status);
}

struct
{
::fast_io::win32::nt::file_fs_volume_information FileFsVolume;
char16_t Name[255];
} ffvi;

status = ::fast_io::win32::nt::nt_query_volume_information_file<family == ::fast_io::nt_family::zw>(handle, __builtin_addressof(isb), __builtin_addressof(ffvi), sizeof(ffvi),
::fast_io::win32::nt::fs_information_class::FileFsVolumeInformation);
if (status) [[unlikely]]
{
throw_nt_error(status);
}

::fast_io::win32::nt::file_standard_information fsi{};
status = ::fast_io::win32::nt::nt_query_information_file<family == ::fast_io::nt_family::zw>(handle, __builtin_addressof(isb), __builtin_addressof(fsi), sizeof(fsi),
::fast_io::win32::nt::file_information_class::FileStandardInformation);

if (status) [[unlikely]]
{
throw_nt_error(status);
}

::std::uintmax_t file_size{static_cast<::std::uintmax_t>(fsi.end_of_file)};
::std::underlying_type_t<perms> pm{0444};
if ((fbi.FileAttributes & 0x1) == 0x0)
{
pm |= 0222;
}
if ((fbi.FileAttributes & 0x400) == 0x400)
{
ft = file_type::symlink;
}
else if ((fbi.FileAttributes & 0x10) == 0x10)
{
ft = file_type::directory;
}
return posix_file_status{static_cast<::std::uintmax_t>(ffvi.FileFsVolume.VolumeSerialNumber),
static_cast<::std::uintmax_t>(fii.IndexNumber),
static_cast<perms>(pm),
ft,
static_cast<::std::uintmax_t>(fsi.number_of_links),
0,
0,
0,
file_size,
131072,
file_size >> 9,
to_unix_timestamp(fbi.LastAccessTime),
to_unix_timestamp(fbi.LastWriteTime),
to_unix_timestamp(fbi.ChangeTime),
to_unix_timestamp(fbi.CreationTime),
0,
0};
}

} // namespace win32::nt::details

template <nt_family family, ::std::integral ch_type>
inline posix_file_status status(basic_nt_family_io_observer<family, ch_type> wiob)
{
return win32::nt::details::nt_status_impl<family>(wiob.handle);
}

template <::std::integral char_type>
using basic_nt_io_observer = basic_nt_family_io_observer<nt_family::nt, char_type>;

Expand Down
Loading

0 comments on commit 5dd54ab

Please sign in to comment.