Skip to content

Commit

Permalink
Refactor Filesystem Code for Clarity (microsoft#2766)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephan T. Lavavej <[email protected]>
Co-authored-by: nicole mazzuca <[email protected]>
  • Loading branch information
3 people authored and fsb4000 committed Aug 13, 2022
1 parent 2fb43a5 commit e4f1462
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 107 deletions.
2 changes: 1 addition & 1 deletion stl/inc/cvt/one_one
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace stdext {
using _Statype = _CSTD mbstate_t;

_STL_DISABLE_DEPRECATED_WARNING
template <class _Elem, unsigned long _Maxcode = 0xffffffff, _STD codecvt_mode _Mode = _STD codecvt_mode{},
template <class _Elem, unsigned long _Maxcode = 0xFFFFFFFFUL, _STD codecvt_mode _Mode = _STD codecvt_mode{},
size_t _Bytes_per_word = sizeof(_Elem)>
class codecvt_one_one : public _STD codecvt<_Elem, char, _Statype> {
// facet for converting between _Elem and serialized byte sequences
Expand Down
2 changes: 1 addition & 1 deletion stl/inc/cvt/utf8
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace stdext {
using _Statype = _CSTD mbstate_t;

_STL_DISABLE_DEPRECATED_WARNING
template <class _Elem, unsigned long _Maxcode = 0xffffffff, _STD codecvt_mode _Mode = _STD codecvt_mode{}>
template <class _Elem, unsigned long _Maxcode = 0xFFFFFFFFUL, _STD codecvt_mode _Mode = _STD codecvt_mode{}>
class codecvt_utf8 : public _STD codecvt<_Elem, char, _Statype> {
// facet for converting between _Elem and UTF-8 byte sequences
public:
Expand Down
12 changes: 6 additions & 6 deletions stl/inc/experimental/filesystem
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ struct _Path_cvt<char, wchar_t, _Outtraits,
_Xinvalid_argument("invalid char filename argument");
}

return _STD move(_Str.append(&_Fname_wide[0]));
return _STD move(_Str.append(_Fname_wide));
}

static _Outstr&& _Cvt(_Outstr& _Str, const _Inchar* _First, size_t _Size,
Expand All @@ -307,7 +307,7 @@ struct _Path_cvt<wchar_t, char, _Outtraits,
_Xinvalid_argument("invalid wchar_t filename argument");
}

return _STD move(_Str.append(&_Fname_byte[0]));
return _STD move(_Str.append(_Fname_byte));
}

static _Outstr&& _Cvt(_Outstr& _Str, const _Inchar* _First, size_t _Size,
Expand All @@ -334,12 +334,12 @@ struct _Path_cvt<char, _Char8_t, char_traits<char>,
}

wstring_convert<codecvt_utf8<wchar_t>, wchar_t> _Wcvt;
wchar_t* _Last1 = &_Fname_wide[0];
wchar_t* _Last1 = _Fname_wide;
while (*_Last1 != L'\0') {
++_Last1;
}

return _STD move(_Str.append(_Wcvt.to_bytes(&_Fname_wide[0], _Last1)));
return _STD move(_Str.append(_Wcvt.to_bytes(_Fname_wide, _Last1)));
}
};

Expand All @@ -359,7 +359,7 @@ struct _Path_cvt<_Char8_t, char, _Outtraits,
_Xinvalid_argument("invalid UTF8 filename argument");
}

return _STD move(_Str.append(&_Fname_byte[0]));
return _STD move(_Str.append(_Fname_byte));
}
};

Expand Down Expand Up @@ -1636,7 +1636,7 @@ public:
}

void pop() { // pop a level
if (1 < _Mylist.size()) {
if (_Mylist.size() > 1) {
_Mylist.pop_front(); // something to pop, do it
}
}
Expand Down
4 changes: 2 additions & 2 deletions stl/inc/filesystem
Original file line number Diff line number Diff line change
Expand Up @@ -3542,12 +3542,12 @@ namespace filesystem {
}

_NODISCARD inline bool is_other(const path& _Path) {
// tests whether _Path is an other file (such as a junction)
// tests whether _Path is an "other" file (such as a junction)
return _STD filesystem::is_other(_STD filesystem::status(_Path));
}

_NODISCARD inline bool is_other(const path& _Path, error_code& _Ec) noexcept {
// tests whether _Path is an other file (such as a junction)
// tests whether _Path is an "other" file (such as a junction)
return _STD filesystem::is_other(_STD filesystem::status(_Path, _Ec));
}

Expand Down
117 changes: 56 additions & 61 deletions stl/src/filesys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@

#include <Windows.h>

#include "awint.hpp"

_FS_BEGIN
static file_type _Map_mode(int _Mode) { // map Windows file attributes to file_status
constexpr int _File_attribute_regular =
Expand Down Expand Up @@ -60,12 +58,7 @@ _FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Read_dir(
wchar_t (&_Dest)[_MAX_FILESYS_NAME], void* _Handle, file_type& _Ftype) { // read a directory entry
WIN32_FIND_DATAW _Dentry;

for (;;) {
if (FindNextFileW(_Handle, &_Dentry) == 0) { // fail
_Ftype = file_type::unknown;
return _Strcpy(_Dest, L"");
}

while (FindNextFileW(_Handle, &_Dentry)) {
if (_Dentry.cFileName[0] != L'.'
|| (_Dentry.cFileName[1] != L'\0'
&& (_Dentry.cFileName[1] != L'.'
Expand All @@ -74,6 +67,9 @@ _FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Read_dir(
return _Strcpy(_Dest, &_Dentry.cFileName[0]);
}
}

_Ftype = file_type::unknown;
return _Strcpy(_Dest, L"");
}

static unsigned int _Filesys_code_page() { // determine appropriate code page
Expand Down Expand Up @@ -122,17 +118,16 @@ _FS_DLL void* __CLRCALL_PURE_OR_CDECL _Open_dir(
&& (_Dentry.cFileName[1] == L'\0'
|| _Dentry.cFileName[1] == L'.' && _Dentry.cFileName[2] == L'\0')) { // skip "." and ".."
_Read_dir(_Dest, _Handle, _Ftype);
if (_Dest[0] != L'\0') {
return _Handle;
if (_Dest[0] == L'\0') {
// no entries, release handle
_Close_dir(_Handle);
return nullptr;
}

// no entries, release handle
_Close_dir(_Handle);
return nullptr;
return _Handle;
}

// get file type and return handle
_Strcpy(_Dest, &_Dentry.cFileName[0]);
_Strcpy(_Dest, _Dentry.cFileName);
_Ftype = _Map_mode(_Dentry.dwFileAttributes);
return _Handle;
}
Expand Down Expand Up @@ -161,21 +156,19 @@ _FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_set(const wchar_t* _Dirname) {
_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Symlink_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME], const wchar_t*) {
// get symlink -- DUMMY
_Dest[0] = L'\0';
return &_Dest[0];
return _Dest;
}

_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Temp_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME]) {
// get temp directory
wchar_t _Dentry[MAX_PATH];
return _Strcpy(_Dest, GetTempPathW(MAX_PATH, &_Dentry[0]) == 0 ? L"." : &_Dentry[0]);
return _Strcpy(_Dest, GetTempPathW(MAX_PATH, _Dentry) != 0 ? _Dentry : L".");
}


_FS_DLL int __CLRCALL_PURE_OR_CDECL _Make_dir(const wchar_t* _Fname, const wchar_t*) {
// make a new directory (ignore attributes)
int _Ans = CreateDirectoryW(_Fname, nullptr);

if (_Ans != 0) {
if (CreateDirectoryW(_Fname, nullptr)) {
return 1;
} else if (GetLastError() == ERROR_ALREADY_EXISTS) {
return 0;
Expand All @@ -197,20 +190,23 @@ _FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Stat(const wchar_t* _Fname, perms* _P
constexpr perms _Write_perms = perms::owner_write | perms::group_write | perms::others_write;
constexpr perms _Readonly_perms = perms::all & ~_Write_perms;

*_Pmode = _Data.dwFileAttributes & FILE_ATTRIBUTE_READONLY ? _Readonly_perms : perms::all;
*_Pmode = (_Data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0u ? _Readonly_perms : perms::all;
}

return _Map_mode(_Data.dwFileAttributes);
}

// invalid, get error code
int _Errno = GetLastError();

if (_Errno == ERROR_BAD_NETPATH || _Errno == ERROR_BAD_PATHNAME || _Errno == ERROR_FILE_NOT_FOUND
|| _Errno == ERROR_INVALID_DRIVE || _Errno == ERROR_INVALID_NAME || _Errno == ERROR_INVALID_PARAMETER
|| _Errno == ERROR_PATH_NOT_FOUND) {
switch (GetLastError()) {
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_NAME:
case ERROR_INVALID_DRIVE:
case ERROR_INVALID_PARAMETER:
case ERROR_BAD_NETPATH:
case ERROR_BAD_PATHNAME:
return file_type::not_found;
} else {
default:
return file_type::unknown;
}
}
Expand All @@ -221,39 +217,39 @@ _FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Lstat(const wchar_t* _Fname, perms* _
return _Stat(_Fname, _Pmode); // symlink not supported
}

_FS_DLL unsigned long long __CLRCALL_PURE_OR_CDECL _Hard_links(const wchar_t* _Fname) {
_FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _Hard_links(const wchar_t* _Fname) {
// get hard link count
HANDLE _Handle = _FilesysOpenFile(_Fname, FILE_READ_ATTRIBUTES, FILE_FLAG_BACKUP_SEMANTICS);

if (_Handle == INVALID_HANDLE_VALUE) {
return static_cast<uintmax_t>(-1);
}

#ifdef _CRT_APP
FILE_STANDARD_INFO _Info = {0};
bool _Ok = false;

if (_Handle != INVALID_HANDLE_VALUE) { // get file info
_Ok = GetFileInformationByHandleEx(_Handle, FileStandardInfo, &_Info, sizeof(_Info)) != 0;
CloseHandle(_Handle);
}
return _Ok ? _Info.NumberOfLinks : static_cast<unsigned long long>(-1);
// get file info
const auto _Ok = GetFileInformationByHandleEx(_Handle, FileStandardInfo, &_Info, sizeof(_Info));
CloseHandle(_Handle);
return _Ok ? _Info.NumberOfLinks : static_cast<uintmax_t>(-1);
#else // _CRT_APP
BY_HANDLE_FILE_INFORMATION _Info = {0};
bool _Ok = false;

if (_Handle != INVALID_HANDLE_VALUE) { // get file info
_Ok = GetFileInformationByHandle(_Handle, &_Info) != 0;
CloseHandle(_Handle);
}
return _Ok ? _Info.nNumberOfLinks : static_cast<unsigned long long>(-1);
// get file info
const auto _Ok = GetFileInformationByHandle(_Handle, &_Info);
CloseHandle(_Handle);
return _Ok ? _Info.nNumberOfLinks : static_cast<uintmax_t>(-1);
#endif // _CRT_APP
}


_FS_DLL unsigned long long __CLRCALL_PURE_OR_CDECL _File_size(const wchar_t* _Fname) { // get file size
_FS_DLL uintmax_t __CLRCALL_PURE_OR_CDECL _File_size(const wchar_t* _Fname) { // get file size
WIN32_FILE_ATTRIBUTE_DATA _Data;

if (!GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
return static_cast<unsigned long long>(-1);
if (GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
return static_cast<uintmax_t>(_Data.nFileSizeHigh) << 32 | _Data.nFileSizeLow;
} else {
return static_cast<unsigned long long>(_Data.nFileSizeHigh) << 32 | _Data.nFileSizeLow;
return static_cast<uintmax_t>(-1);
}
}

Expand All @@ -279,8 +275,8 @@ _FS_DLL int64_t __CLRCALL_PURE_OR_CDECL _Last_write_time(const wchar_t* _Fname)
}

// success, convert time
unsigned long long _Wtime = static_cast<unsigned long long>(_Data.ftLastWriteTime.dwHighDateTime) << 32
| _Data.ftLastWriteTime.dwLowDateTime;
uint64_t _Wtime =
static_cast<uint64_t>(_Data.ftLastWriteTime.dwHighDateTime) << 32 | _Data.ftLastWriteTime.dwLowDateTime;
return static_cast<int64_t>(_Wtime - _Win_ticks_from_epoch);
}

Expand All @@ -294,9 +290,9 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Set_last_write_time(const wchar_t* _Fname,
}

// convert to FILETIME and set
unsigned long long _Wtime = static_cast<unsigned long long>(_When) + _Win_ticks_from_epoch;
uint64_t _Wtime = static_cast<uint64_t>(_When) + _Win_ticks_from_epoch;
FILETIME _Ft;
_Ft.dwLowDateTime = static_cast<DWORD>(_Wtime); // intentionally discard upper bits
_Ft.dwLowDateTime = static_cast<DWORD>(_Wtime & 0xFFFFFFFFUL);
_Ft.dwHighDateTime = static_cast<DWORD>(_Wtime >> 32);
int _Result = SetFileTime(_Handle, nullptr, nullptr, &_Ft);
CloseHandle(_Handle);
Expand Down Expand Up @@ -351,10 +347,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Equivalent(
} else if (!_Ok1 || !_Ok2) {
return 0;
} else { // test existing files for equivalence
return _Info1.VolumeSerialNumber != _Info2.VolumeSerialNumber
|| memcmp(&_Info1.FileId, &_Info2.FileId, sizeof(_Info1.FileId)) != 0
? 0
: 1;
return memcmp(&_Info1, &_Info2, sizeof(_FILE_ID_INFO)) == 0 ? 1 : 0;
}
#else // _CRT_APP
BY_HANDLE_FILE_INFORMATION _Info1 = {0};
Expand All @@ -379,10 +372,10 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Equivalent(
} else if (!_Ok1 || !_Ok2) {
return 0;
} else { // test existing files for equivalence
return _Info1.dwVolumeSerialNumber != _Info2.dwVolumeSerialNumber
|| _Info1.nFileIndexHigh != _Info2.nFileIndexHigh || _Info1.nFileIndexLow != _Info2.nFileIndexLow
? 0
: 1;
return _Info1.dwVolumeSerialNumber == _Info2.dwVolumeSerialNumber
&& _Info1.nFileIndexHigh == _Info2.nFileIndexHigh && _Info1.nFileIndexLow == _Info2.nFileIndexLow
? 1
: 0;
}
#endif // _CRT_APP
}
Expand All @@ -395,7 +388,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Link(const wchar_t* _Fname1, const wchar_t*
(void) _Fname2;
return errno = EDOM; // hardlinks not supported
#else // _CRT_APP
return CreateHardLinkW(_Fname2, _Fname1, nullptr) != 0 ? 0 : GetLastError();
return CreateHardLinkW(_Fname2, _Fname1, nullptr) ? 0 : GetLastError();
#endif // _CRT_APP
}

Expand All @@ -406,7 +399,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Symlink(const wchar_t* _Fname1, const wchar
(void) _Fname2;
return errno = EDOM; // symlinks not supported
#else // _CRT_APP
return CreateSymbolicLinkW(_Fname2, _Fname1, 0) != 0 ? 0 : GetLastError();
return CreateSymbolicLinkW(_Fname2, _Fname1, 0) ? 0 : GetLastError();
#endif // _CRT_APP
}

Expand Down Expand Up @@ -449,7 +442,7 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Copy_file(const wchar_t* _Fname1, const wch
// take lower bits to undo HRESULT_FROM_WIN32
return _Copy_result & 0x0000FFFFU;
#else // defined(_ONECORE)
return CopyFileW(_Fname1, _Fname2, 0) != 0 ? 0 : GetLastError();
return CopyFileW(_Fname1, _Fname2, 0) ? 0 : GetLastError();
#endif // defined(_ONECORE)
}

Expand All @@ -464,14 +457,16 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Chmod(const wchar_t* _Fname, perms _Newmode

// got mode, alter readonly bit
DWORD _Oldmode = _Data.dwFileAttributes;
DWORD _Mode = _Oldmode & ~FILE_ATTRIBUTE_READONLY;
DWORD _Mode = _Oldmode;

constexpr perms _Write_perms = perms::owner_write | perms::group_write | perms::others_write;

if ((_Newmode & _Write_perms) == perms::none) {
_Mode |= FILE_ATTRIBUTE_READONLY;
} else {
_Mode &= ~FILE_ATTRIBUTE_READONLY;
}

return _Mode == _Oldmode ? 0 : SetFileAttributesW(_Fname, _Mode) != 0 ? 0 : -1;
return _Mode == _Oldmode || SetFileAttributesW(_Fname, _Mode) ? 0 : -1;
}
_FS_END
Loading

0 comments on commit e4f1462

Please sign in to comment.