Yuni::IO::NodeType TypeOf(const AnyString& filename) { if (filename.empty()) return Yuni::IO::typeUnknown; # ifdef YUNI_OS_WINDOWS const char* p = filename.c_str(); unsigned int len = filename.size(); if (p[len - 1] == '\\' or p[len - 1] == '/') { if (!--len) { # ifdef YUNI_OS_WINDOWS return Yuni::IO::typeUnknown; # else // On Unixes, `/` is a valid folder return Yuni::IO::typeFolder; # endif } } // Driver letters if (len == 2 and p[1] == ':') return Yuni::IO::typeFolder; String norm; Yuni::IO::Normalize(norm, AnyString(p, len)); // Conversion into wchar_t Private::WString<true> wstr(norm); if (wstr.empty()) return Yuni::IO::typeUnknown; WIN32_FILE_ATTRIBUTE_DATA infoFile; if (!GetFileAttributesExW(wstr.c_str(), GetFileExInfoStandard, &infoFile)) return Yuni::IO::typeUnknown; return ((infoFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) ? Yuni::IO::typeFolder : Yuni::IO::typeFile; # else // WINDOWS struct stat s; if (stat(filename.c_str(), &s) != 0) return Yuni::IO::typeUnknown; return (S_ISDIR(s.st_mode)) ? Yuni::IO::typeFolder : Yuni::IO::typeFile; # endif }
bool Size(const AnyString& filename, uint64& value) { uint len = filename.size(); if (!len) { value = 0u; return false; } const char* const p = filename.c_str(); if (p[len - 1] == '\\' or p[len - 1] == '/') --len; // Driver letters if (len == 2 and p[1] == ':') { value = 0u; return true; } String norm; Yuni::IO::Normalize(norm, AnyString(p, len)); // Conversion into wchar_t WString wstr(norm, true); if (wstr.empty()) { value = 0u; return false; } HANDLE hndl = CreateFileW(wstr.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hndl == INVALID_HANDLE_VALUE) { value = 0u; return false; } LARGE_INTEGER v; if (!GetFileSizeEx(hndl, &v)) { CloseHandle(hndl); value = 0u; return false; } value = (uint64) v.QuadPart; CloseHandle(hndl); return true; }
Yuni::IO::Error Delete(const AnyString& filename) { // DeleteFile is actually a macro and will be replaced by DeleteFileW // with Visual Studio. Consequently we can not use the word DeleteFile..... if (filename.empty()) return Yuni::IO::errUnknown; # ifndef YUNI_OS_WINDOWS return (unlink(filename.c_str())) ? Yuni::IO::errUnknown : Yuni::IO::errNone; # else const char* const p = filename.c_str(); uint len = filename.size(); if (p[len - 1] == '\\' or p[len - 1] == '/') --len; // Driver letters if (len == 2 and p[1] == ':') return Yuni::IO::errBadFilename; String norm; Yuni::IO::Normalize(norm, AnyString(p, len)); // Conversion into wchar_t WString wstr(norm, true); if (wstr.empty()) return Yuni::IO::errUnknown; wstr.replace('/', '\\'); return (DeleteFileW(wstr.c_str())) ? Yuni::IO::errNone : Yuni::IO::errUnknown; # endif }