| 1753 | } |
| 1754 | |
| 1755 | bool FileSystem::IsReadableFile(StringView path) |
| 1756 | { |
| 1757 | if (path.empty()) return false; |
| 1758 | |
| 1759 | #if defined(DEATH_TARGET_WINDOWS_RT) |
| 1760 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1761 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1762 | WIN32_FILE_ATTRIBUTE_DATA lpFileInfo; |
| 1763 | return (::GetFileAttributesExFromAppW(pathW.data(), GetFileExInfoStandard, &lpFileInfo) && (lpFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY); |
| 1764 | #elif defined(DEATH_TARGET_WINDOWS) |
| 1765 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1766 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1767 | const DWORD attrs = ::GetFileAttributesW(pathW.data()); |
| 1768 | return (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY); |
| 1769 | #else |
| 1770 | auto nullTerminatedPath = String::nullTerminatedView(path); |
| 1771 | # if defined(DEATH_TARGET_ANDROID) |
| 1772 | if (auto strippedPath = AndroidAssetStream::TryGetAssetPath(nullTerminatedPath)) { |
| 1773 | return AndroidAssetStream::TryOpenFile(strippedPath); |
| 1774 | } |
| 1775 | # endif |
| 1776 | struct stat sb; |
| 1777 | if (::stat(nullTerminatedPath.data(), &sb) == 0) { |
| 1778 | return ((sb.st_mode & S_IFMT) == S_IFREG && (sb.st_mode & S_IRUSR) != 0); |
| 1779 | } |
| 1780 | #endif |
| 1781 | return false; |
| 1782 | } |
| 1783 | |
| 1784 | bool FileSystem::IsWritableFile(StringView path) |
| 1785 | { |