diff options
| author | Dan Engelbrecht <[email protected]> | 2022-04-07 18:22:26 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-04-07 18:22:26 +0200 |
| commit | 487352bb3e1de5a96268616bb335f9ef857cd629 (patch) | |
| tree | 4b03eb73f02bf03d1b4671775c1c5277a7d7341a /zenstore/basicfile.cpp | |
| parent | Add pre-commit config (#69) (diff) | |
| parent | clean up variable naming (diff) | |
| download | zen-487352bb3e1de5a96268616bb335f9ef857cd629.tar.xz zen-487352bb3e1de5a96268616bb335f9ef857cd629.zip | |
Merge pull request #58 from EpicGames/de/cas-store-with-block-store
de/cas store with block store
Diffstat (limited to 'zenstore/basicfile.cpp')
| -rw-r--r-- | zenstore/basicfile.cpp | 177 |
1 files changed, 155 insertions, 22 deletions
diff --git a/zenstore/basicfile.cpp b/zenstore/basicfile.cpp index 895db6cee..e795b67eb 100644 --- a/zenstore/basicfile.cpp +++ b/zenstore/basicfile.cpp @@ -29,10 +29,10 @@ BasicFile::~BasicFile() } void -BasicFile::Open(std::filesystem::path FileName, bool IsCreate) +BasicFile::Open(const std::filesystem::path& FileName, Mode Mode) { std::error_code Ec; - Open(FileName, IsCreate, Ec); + Open(FileName, Mode, Ec); if (Ec) { @@ -41,22 +41,41 @@ BasicFile::Open(std::filesystem::path FileName, bool IsCreate) } void -BasicFile::Open(std::filesystem::path FileName, bool IsCreate, std::error_code& Ec) +BasicFile::Open(const std::filesystem::path& FileName, Mode Mode, std::error_code& Ec) { Ec.clear(); #if ZEN_PLATFORM_WINDOWS - const DWORD dwCreationDisposition = IsCreate ? CREATE_ALWAYS : OPEN_EXISTING; - DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; - const DWORD dwShareMode = FILE_SHARE_READ; - const DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; - HANDLE hTemplateFile = nullptr; - - if (IsCreate) + DWORD dwCreationDisposition = 0; + DWORD dwDesiredAccess = 0; + switch (Mode) { - dwDesiredAccess |= DELETE; + case Mode::kRead: + dwCreationDisposition |= OPEN_EXISTING; + dwDesiredAccess |= GENERIC_READ; + break; + case Mode::kWrite: + dwCreationDisposition |= OPEN_ALWAYS; + dwDesiredAccess |= (GENERIC_READ | GENERIC_WRITE); + break; + case Mode::kDelete: + dwCreationDisposition |= OPEN_ALWAYS; + dwDesiredAccess |= (GENERIC_READ | GENERIC_WRITE | DELETE); + break; + case Mode::kTruncate: + dwCreationDisposition |= CREATE_ALWAYS; + dwDesiredAccess |= (GENERIC_READ | GENERIC_WRITE); + break; + case Mode::kTruncateDelete: + dwCreationDisposition |= CREATE_ALWAYS; + dwDesiredAccess |= (GENERIC_READ | GENERIC_WRITE | DELETE); + break; } + const DWORD dwShareMode = FILE_SHARE_READ; + const DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; + HANDLE hTemplateFile = nullptr; + HANDLE FileHandle = CreateFile(FileName.c_str(), dwDesiredAccess, dwShareMode, @@ -67,21 +86,34 @@ BasicFile::Open(std::filesystem::path FileName, bool IsCreate, std::error_code& if (FileHandle == INVALID_HANDLE_VALUE) { - Ec = zen::MakeErrorCodeFromLastError(); + Ec = MakeErrorCodeFromLastError(); return; } #else - int OpenFlags = O_RDWR | O_CLOEXEC; - OpenFlags |= IsCreate ? O_CREAT | O_TRUNC : 0; + int OpenFlags = O_CLOEXEC; + switch (Mode) + { + case Mode::kRead: + OpenFlags |= O_RDONLY; + break; + case Mode::kWrite: + case Mode::kDelete: + OpenFlags |= (O_RDWR | O_CREAT); + break; + case Mode::kTruncate: + case Mode::kTruncateDelete: + OpenFlags |= (O_RDWR | O_CREAT | O_TRUNC); + break; + } int Fd = open(FileName.c_str(), OpenFlags, 0666); if (Fd < 0) { - Ec = zen::MakeErrorCodeFromLastError(); + Ec = MakeErrorCodeFromLastError(); return; } - if (IsCreate) + if (Mode != Mode::kRead) { fchmod(Fd, 0666); } @@ -268,7 +300,14 @@ BasicFile::FileSize() #if ZEN_PLATFORM_WINDOWS ULARGE_INTEGER liFileSize; liFileSize.LowPart = ::GetFileSize(m_FileHandle, &liFileSize.HighPart); - + if (liFileSize.LowPart == INVALID_FILE_SIZE) + { + int Error = zen::GetLastError(); + if (Error) + { + ThrowSystemError(Error, fmt::format("Failed to get file size from file '{}'", PathFromHandle(m_FileHandle))); + } + } return uint64_t(liFileSize.QuadPart); #else int Fd = int(uintptr_t(m_FileHandle)); @@ -279,6 +318,102 @@ BasicFile::FileSize() #endif } +void +BasicFile::SetFileSize(uint64_t FileSize) +{ +#if ZEN_PLATFORM_WINDOWS + LARGE_INTEGER liFileSize; + liFileSize.QuadPart = FileSize; + BOOL OK = ::SetFilePointerEx(m_FileHandle, liFileSize, 0, FILE_BEGIN); + if (OK == FALSE) + { + int Error = zen::GetLastError(); + if (Error) + { + ThrowSystemError(Error, fmt::format("Failed to set file pointer to {} for file {}", FileSize, PathFromHandle(m_FileHandle))); + } + } + OK = ::SetEndOfFile(m_FileHandle); + if (OK == FALSE) + { + int Error = zen::GetLastError(); + if (Error) + { + ThrowSystemError(Error, fmt::format("Failed to set end of file to {} for file {}", FileSize, PathFromHandle(m_FileHandle))); + } + } +#elif ZEN_PLATFORM_MAC + int Fd = int(intptr_t(m_FileHandle)); + if (ftruncate(Fd, (off_t)FileSize) < 0) + { + int Error = zen::GetLastError(); + if (Error) + { + ThrowSystemError(Error, fmt::format("Failed to set truncate file to {} for file {}", FileSize, PathFromHandle(m_FileHandle))); + } + } + if (FileSize > 0) + { + int Error = posix_fallocate(Fd, 0, (off_t)FileSize); + if (Error) + { + ThrowSystemError(Error, fmt::format("Failed to allocate space of {} for file {}", FileSize, PathFromHandle(m_FileHandle))); + } + } +#else + int Fd = int(intptr_t(m_FileHandle)); + if (ftruncate64(Fd, (off64_t)FileSize) < 0) + { + int Error = zen::GetLastError(); + if (Error) + { + ThrowSystemError(Error, fmt::format("Failed to set truncate file to {} for file {}", FileSize, PathFromHandle(m_FileHandle))); + } + } + if (FileSize > 0) + { + int Error = posix_fallocate64(Fd, 0, (off64_t)FileSize); + if (Error) + { + ThrowSystemError(Error, fmt::format("Failed to allocate space of {} for file {}", FileSize, PathFromHandle(m_FileHandle))); + } + } +#endif +} + +void +BasicFile::MarkAsDeleteOnClose(std::error_code& Ec) +{ + Ec.clear(); +#if ZEN_PLATFORM_WINDOWS + FILE_DISPOSITION_INFO Fdi{}; + Fdi.DeleteFile = TRUE; + BOOL Success = SetFileInformationByHandle(m_FileHandle, FileDispositionInfo, &Fdi, sizeof Fdi); + if (!Success) + { + Ec = MakeErrorCodeFromLastError(); + } +#elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + std::filesystem::path SourcePath = PathFromHandle(m_FileHandle); + if (unlink(SourcePath.c_str()) < 0) + { + int UnlinkError = zen::GetLastError(); + if (UnlinkError != ENOENT) + { + Ec = MakeErrorCode(UnlinkError); + } + } +#endif +} + +void* +BasicFile::Detach() +{ + void* FileHandle = m_FileHandle; + m_FileHandle = 0; + return FileHandle; +} + ////////////////////////////////////////////////////////////////////////// TemporaryFile::~TemporaryFile() @@ -314,9 +449,7 @@ TemporaryFile::CreateTemporary(std::filesystem::path TempDirName, std::error_cod m_TempPath = TempDirName / TempName.c_str(); - const bool IsCreate = true; - - Open(m_TempPath, IsCreate, Ec); + Open(m_TempPath, BasicFile::Mode::kTruncateDelete, Ec); } void @@ -416,8 +549,8 @@ TEST_CASE("BasicFile") ScopedCurrentDirectoryChange _; BasicFile File1; - CHECK_THROWS(File1.Open("zonk", false)); - CHECK_NOTHROW(File1.Open("zonk", true)); + CHECK_THROWS(File1.Open("zonk", BasicFile::Mode::kRead)); + CHECK_NOTHROW(File1.Open("zonk", BasicFile::Mode::kTruncate)); CHECK_NOTHROW(File1.Write("abcd", 4, 0)); CHECK(File1.FileSize() == 4); { |