#include "path.hpp"
#include <limits.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <windows.h>
char sprawl::path::Separator()
{
return '\\';
}
char sprawl::path::AltSeparator()
{
return '/';
}
char sprawl::path::ExtSeparator()
{
return '.';
}
char sprawl::path::PathSeparator()
{
return ';';
}
char sprawl::path::DriveSeparator()
{
return ':';
}
bool sprawl::path::LinkExists(String const& path)
{
return GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES;
}
sprawl::String sprawl::path::ExpandPath(String const& path)
{
char out[MAX_PATH];
ExpandEnvironmentStringsA(path.c_str(), out, MAX_PATH);
return sprawl::String(out);
}
sprawl::String sprawl::path::RealPath(String const& path)
{
HANDLE fileHandle = CreateFileA(
path.c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (fileHandle == INVALID_HANDLE_VALUE)
{
return "";
}
char buf[MAX_PATH];
GetFinalPathNameByHandleA(fileHandle, buf, MAX_PATH, FILE_NAME_NORMALIZED);
CloseHandle(fileHandle);
}
int64_t sprawl::path::GetAccessTime(String const& path)
{
HANDLE fileHandle = CreateFileA(
path.c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (fileHandle == INVALID_HANDLE_VALUE)
{
return 0;
}
FILETIME out;
GetFileTime(fileHandle, nullptr, &out, nullptr);
CloseHandle(fileHandle);
uint64_t tt = out.dwHighDateTime;
tt <<= 32;
tt |= out.dwLowDateTime;
tt -= 116444736000000000ULL;
tt *= 100;
return int64_t(tt);
}
int64_t sprawl::path::GetModificationTime(String const& path)
{
HANDLE fileHandle = CreateFileA(
path.c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr
);
if (fileHandle == INVALID_HANDLE_VALUE)
{
return 0;
}
FILETIME out;
GetFileTime(fileHandle, nullptr, nullptr, &out);
CloseHandle(fileHandle);
uint64_t tt = out.dwHighDateTime;
tt <<= 32;
tt |= out.dwLowDateTime;
tt -= 116444736000000000ULL;
tt *= 100;
return int64_t(tt);
}
int64_t sprawl::path::GetSize(String const& path)
{
struct _stat attrib;
_stat(path.c_str(), &attrib);
return attrib.st_size;
}
bool sprawl::path::IsFile(String const& path)
{
return (GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_NORMAL) != 0;
}
bool sprawl::path::IsDirectory(String const& path)
{
return (GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
bool sprawl::path::IsLink(String const& path)
{
return (GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
}
bool sprawl::path::IsMountPoint(String const& path)
{
if((GetFileAttributesA(path.c_str()) & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
{
return false;
}
struct _stat attrib;
if(_stat(path.c_str(), &attrib) != 0)
{
return false;
}
struct _stat attrib2;
if(_stat(Join(path, "..").c_str(), &attrib2) != 0)
{
return false;
}
if(attrib.st_dev != attrib2.st_dev)
{
return true;
}
if(attrib.st_ino == attrib2.st_ino)
{
return true;
}
return false;
}
bool sprawl::path::SameFile(String const& path1, String const& path2)
{
struct _stat attrib;
_stat(path1.c_str(), &attrib);
struct _stat attrib2;
_stat(path2.c_str(), &attrib2);
return attrib.st_ino == attrib2.st_ino && attrib.st_dev == attrib2.st_dev;
}
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #3 | 14822 | ShadauxCat |
Last batch of filesystem code for now, added MakeSymlink and GetPid, removed other todo functions for the time being. Also fixed some bugs: -Linux IsLink() implementation not using lstat = broken -File::IsClosed() would crash if file were created via default constructor or null handle -Remove() and RmDir() on Windows were inconsistent with Linux - in Linux all symlinks are removed with Remove() even if they point to directories. Forced windows to work the same way. -Asked RmTree to please not descend into symbolic links to directories, but just to remove them, thanks. -Removed starting \\?\ from result of RealPath() on Windows -Fixed IsFile() on Windows just not working - assuming anything that's not a directory is a file now. -Fixed StringBuilder only printing the first character if you passed it type char* instead of type char const* #review-14823 |
||
| #2 | 14816 | ShadauxCat |
Filled in some more filesystem functions, added appropriate unit tests. Only a few remain. #review-14817 |
||
| #1 | 14761 | ShadauxCat |
First drop of code for sprawl::filesystem and sprawl::path. Library will continue to grow. Also fixed a warning on linux. #review-14762 |