Skip to content

Commit

Permalink
Refactor filesystem code for clarity
Browse files Browse the repository at this point in the history
This makes the code more readable as well as lowers operations to code paths that actually need them.
  • Loading branch information
AZero13 committed Jun 9, 2022
1 parent 17fde2c commit 6734d90
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 121 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
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
Expand Down
2 changes: 1 addition & 1 deletion stl/inc/experimental/filesystem
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,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 @@ -3526,12 +3526,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 another 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 another file (such as a junction)
return _STD filesystem::is_other(_STD filesystem::status(_Path, _Ec));
}

Expand Down
121 changes: 60 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) != 0) {
if (_Dentry.cFileName[0] != L'.'
|| (_Dentry.cFileName[1] != L'\0'
&& (_Dentry.cFileName[1] != L'.'
Expand All @@ -74,13 +67,16 @@ _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
#if defined(_ONECORE)
return CP_ACP;
#else // defined(_ONECORE)
if (AreFileApisANSI()) {
if (AreFileApisANSI() != 0) {
return CP_ACP;
} else {
return CP_OEMCP;
Expand Down Expand Up @@ -122,13 +118,12 @@ _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
Expand Down Expand Up @@ -158,7 +153,7 @@ _FS_DLL bool __CLRCALL_PURE_OR_CDECL _Current_set(const wchar_t* _Dirname) {
#endif // _CRT_APP
}

_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Symlink_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME], const wchar_t*) {
_FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Symlink_get(wchar_t (&_Dest)[_MAX_FILESYS_NAME], const wchar_t* /*unused*/) {
// get symlink -- DUMMY
_Dest[0] = L'\0';
return &_Dest[0];
Expand All @@ -173,9 +168,7 @@ _FS_DLL wchar_t* __CLRCALL_PURE_OR_CDECL _Temp_get(wchar_t (&_Dest)[_MAX_FILESYS

_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) != 0) {
return 1;
} else if (GetLastError() == ERROR_ALREADY_EXISTS) {
return 0;
Expand All @@ -191,26 +184,29 @@ _FS_DLL bool __CLRCALL_PURE_OR_CDECL _Remove_dir(const wchar_t* _Fname) { // rem
_FS_DLL file_type __CLRCALL_PURE_OR_CDECL _Stat(const wchar_t* _Fname, perms* _Pmode) { // get file status
WIN32_FILE_ATTRIBUTE_DATA _Data;

if (GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
if (GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data) != 0) {
// get file type and return permissions
if (_Pmode != nullptr) {
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,43 @@ _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);

#ifdef _CRT_APP
if (_Handle == INVALID_HANDLE_VALUE) {
return static_cast<unsigned long long>(-1);
}

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 != 0 ? _Info.NumberOfLinks : static_cast<unsigned long long>(-1);
#else // _CRT_APP
if (_Handle == INVALID_HANDLE_VALUE) {
return static_cast<uintmax_t>(-1);
}

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) != 0;
CloseHandle(_Handle);
return (_Ok != 0) ? _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) != 0) {
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 @@ -274,13 +274,13 @@ constexpr uint64_t _Win_ticks_from_epoch = ((1970 - 1601) * 365 + 3 * 24 + 17) *
_FS_DLL int64_t __CLRCALL_PURE_OR_CDECL _Last_write_time(const wchar_t* _Fname) { // get last write time
WIN32_FILE_ATTRIBUTE_DATA _Data;

if (!GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
if (GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data) == 0) {
return -1;
}

// 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 +294,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); // intentionally discard upper bits
_Ft.dwHighDateTime = static_cast<DWORD>(_Wtime >> 32);
int _Result = SetFileTime(_Handle, nullptr, nullptr, &_Ft);
CloseHandle(_Handle);
Expand All @@ -317,7 +317,7 @@ _FS_DLL space_info __CLRCALL_PURE_OR_CDECL _Statvfs(const wchar_t* _Fname) {
_ULARGE_INTEGER _Capacity;
_ULARGE_INTEGER _Free;

if (GetDiskFreeSpaceExW(_Devname.c_str(), &_Available, &_Capacity, &_Free)) { // convert values
if (GetDiskFreeSpaceExW(_Devname.c_str(), &_Available, &_Capacity, &_Free) != 0) { // convert values
_Ans.capacity = _Capacity.QuadPart;
_Ans.free = _Free.QuadPart;
_Ans.available = _Available.QuadPart;
Expand Down Expand Up @@ -351,10 +351,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 +376,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 Down Expand Up @@ -458,20 +455,22 @@ _FS_DLL int __CLRCALL_PURE_OR_CDECL _Chmod(const wchar_t* _Fname, perms _Newmode
// change file mode to _Newmode
WIN32_FILE_ATTRIBUTE_DATA _Data;

if (!GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data)) {
if (GetFileAttributesExW(_Fname, GetFileExInfoStandard, &_Data) == 0) {
return -1;
}

// 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 ? 0 : -1;
}
_FS_END
Loading

0 comments on commit 6734d90

Please sign in to comment.