123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- diff --git a/include/__filesystem/directory_entry.h b/include/__filesystem/directory_entry.h
- index 016ad94..90e44f5 100644
- --- a/include/__filesystem/directory_entry.h
- +++ b/include/__filesystem/directory_entry.h
- @@ -202,7 +202,9 @@ private:
- _IterNonSymlink,
- _RefreshSymlink,
- _RefreshSymlinkUnresolved,
- - _RefreshNonSymlink
- + _RefreshNonSymlink,
- + _IterCachedSymlink,
- + _IterCachedNonSymlink
- };
-
- struct __cached_data {
- @@ -241,6 +243,29 @@ private:
- return __data;
- }
-
- + _LIBCPP_HIDE_FROM_ABI static __cached_data
- + __create_iter_cached_result(file_type __ft, uintmax_t __size, perms __perm, file_time_type __write_time) {
- + __cached_data __data;
- + __data.__type_ = __ft;
- + __data.__size_ = __size;
- + __data.__write_time_ = __write_time;
- + if (__ft == file_type::symlink)
- + __data.__sym_perms_ = __perm;
- + else
- + __data.__non_sym_perms_ = __perm;
- + __data.__cache_type_ = [&]() {
- + switch (__ft) {
- + case file_type::none:
- + return _Empty;
- + case file_type::symlink:
- + return _IterCachedSymlink;
- + default:
- + return _IterCachedNonSymlink;
- + }
- + }();
- + return __data;
- + }
- +
- _LIBCPP_HIDE_FROM_ABI void __assign_iter_entry(_Path&& __p, __cached_data __dt) {
- __p_ = std::move(__p);
- __data_ = __dt;
- @@ -282,13 +307,15 @@ private:
- case _Empty:
- return __symlink_status(__p_, __ec).type();
- case _IterSymlink:
- + case _IterCachedSymlink:
- case _RefreshSymlink:
- case _RefreshSymlinkUnresolved:
- if (__ec)
- __ec->clear();
- return file_type::symlink;
- + case _IterCachedNonSymlink:
- case _IterNonSymlink:
- - case _RefreshNonSymlink:
- + case _RefreshNonSymlink: {
- file_status __st(__data_.__type_);
- if (__ec && !filesystem::exists(__st))
- *__ec = make_error_code(errc::no_such_file_or_directory);
- @@ -296,6 +323,7 @@ private:
- __ec->clear();
- return __data_.__type_;
- }
- + }
- __libcpp_unreachable();
- }
-
- @@ -303,8 +331,10 @@ private:
- switch (__data_.__cache_type_) {
- case _Empty:
- case _IterSymlink:
- + case _IterCachedSymlink:
- case _RefreshSymlinkUnresolved:
- return __status(__p_, __ec).type();
- + case _IterCachedNonSymlink:
- case _IterNonSymlink:
- case _RefreshNonSymlink:
- case _RefreshSymlink: {
- @@ -324,8 +354,10 @@ private:
- case _Empty:
- case _IterNonSymlink:
- case _IterSymlink:
- + case _IterCachedSymlink:
- case _RefreshSymlinkUnresolved:
- return __status(__p_, __ec);
- + case _IterCachedNonSymlink:
- case _RefreshNonSymlink:
- case _RefreshSymlink:
- return file_status(__get_ft(__ec), __data_.__non_sym_perms_);
- @@ -339,8 +371,10 @@ private:
- case _IterNonSymlink:
- case _IterSymlink:
- return __symlink_status(__p_, __ec);
- + case _IterCachedNonSymlink:
- case _RefreshNonSymlink:
- return file_status(__get_sym_ft(__ec), __data_.__non_sym_perms_);
- + case _IterCachedSymlink:
- case _RefreshSymlink:
- case _RefreshSymlinkUnresolved:
- return file_status(__get_sym_ft(__ec), __data_.__sym_perms_);
- @@ -353,8 +387,10 @@ private:
- case _Empty:
- case _IterNonSymlink:
- case _IterSymlink:
- + case _IterCachedSymlink:
- case _RefreshSymlinkUnresolved:
- return filesystem::__file_size(__p_, __ec);
- + case _IterCachedNonSymlink:
- case _RefreshSymlink:
- case _RefreshNonSymlink: {
- error_code __m_ec;
- @@ -375,6 +411,8 @@ private:
- case _Empty:
- case _IterNonSymlink:
- case _IterSymlink:
- + case _IterCachedNonSymlink:
- + case _IterCachedSymlink:
- case _RefreshSymlinkUnresolved:
- return filesystem::__hard_link_count(__p_, __ec);
- case _RefreshSymlink:
- @@ -393,8 +431,10 @@ private:
- case _Empty:
- case _IterNonSymlink:
- case _IterSymlink:
- + case _IterCachedSymlink:
- case _RefreshSymlinkUnresolved:
- return filesystem::__last_write_time(__p_, __ec);
- + case _IterCachedNonSymlink:
- case _RefreshSymlink:
- case _RefreshNonSymlink: {
- error_code __m_ec;
- diff --git a/src/filesystem/directory_iterator.cpp b/src/filesystem/directory_iterator.cpp
- index dceb348..d7ed9a3 100644
- --- a/src/filesystem/directory_iterator.cpp
- +++ b/src/filesystem/directory_iterator.cpp
- @@ -77,13 +77,13 @@ public:
- bool assign() {
- if (!wcscmp(__data_.cFileName, L".") || !wcscmp(__data_.cFileName, L".."))
- return false;
- - // FIXME: Cache more of this
- - // directory_entry::__cached_data cdata;
- - // cdata.__type_ = get_file_type(__data_);
- - // cdata.__size_ = get_file_size(__data_);
- - // cdata.__write_time_ = get_write_time(__data_);
- __entry_.__assign_iter_entry(
- - __root_ / __data_.cFileName, directory_entry::__create_iter_result(detail::get_file_type(__data_)));
- + __root_ / __data_.cFileName,
- + directory_entry::__create_iter_cached_result(
- + detail::get_file_type(__data_),
- + detail::get_file_size(__data_),
- + detail::get_file_perm(__data_),
- + detail::get_write_time(__data_)));
- return true;
- }
-
- diff --git a/src/filesystem/file_descriptor.h b/src/filesystem/file_descriptor.h
- index 50178ff..2c9e0d7 100644
- --- a/src/filesystem/file_descriptor.h
- +++ b/src/filesystem/file_descriptor.h
- @@ -97,11 +97,18 @@ inline uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
- return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
- }
- inline file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
- - ULARGE_INTEGER tmp;
- + using detail::fs_time;
- const FILETIME& time = data.ftLastWriteTime;
- - tmp.u.LowPart = time.dwLowDateTime;
- - tmp.u.HighPart = time.dwHighDateTime;
- - return file_time_type(file_time_type::duration(tmp.QuadPart));
- + auto ts = filetime_to_timespec(time);
- + if (!fs_time::is_representable(ts))
- + return file_time_type::min();
- + return fs_time::convert_from_timespec(ts);
- +}
- +inline perms get_file_perm(const WIN32_FIND_DATAW& data) {
- + unsigned st_mode = 0555; // Read-only
- + if (!(data.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
- + st_mode |= 0222; // Write
- + return static_cast<perms>(st_mode) & perms::mask;
- }
-
- #endif // !_LIBCPP_WIN32API
|