aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-06-30 10:36:27 +0200
committerStefan Boberg <[email protected]>2023-06-30 10:36:27 +0200
commit5a0f7888f368330fa80e5cd648a576c0a4eb04f7 (patch)
tree6903c287d39bdf6e57ce03d89a2c85fa0c2e0b73 /src
parentREADME.md update - merge from sb/proto (diff)
downloadzen-5a0f7888f368330fa80e5cd648a576c0a4eb04f7.tar.xz
zen-5a0f7888f368330fa80e5cd648a576c0a4eb04f7.zip
* added file sharing control to BasicFile (required to implement lockfiles)
* added delete-on-close support to BasicFile * added BasicFile::ReadRange()
Diffstat (limited to 'src')
-rw-r--r--src/zenutil/basicfile.cpp55
-rw-r--r--src/zenutil/include/zenutil/basicfile.h24
2 files changed, 60 insertions, 19 deletions
diff --git a/src/zenutil/basicfile.cpp b/src/zenutil/basicfile.cpp
index 22acc346f..f91a54222 100644
--- a/src/zenutil/basicfile.cpp
+++ b/src/zenutil/basicfile.cpp
@@ -36,15 +36,17 @@ BasicFile::Open(const std::filesystem::path& FileName, Mode Mode)
if (Ec)
{
- throw std::system_error(Ec, fmt::format("failed to open file '{}'", FileName));
+ throw std::system_error(Ec, fmt::format("failed to open file '{}', mode: {:x}", FileName, uint32_t(Mode)));
}
}
void
-BasicFile::Open(const std::filesystem::path& FileName, Mode Mode, std::error_code& Ec)
+BasicFile::Open(const std::filesystem::path& FileName, Mode InMode, std::error_code& Ec)
{
Ec.clear();
+ Mode Mode = InMode & Mode::kModeMask;
+
#if ZEN_PLATFORM_WINDOWS
DWORD dwCreationDisposition = 0;
DWORD dwDesiredAccess = 0;
@@ -72,17 +74,18 @@ BasicFile::Open(const std::filesystem::path& FileName, Mode Mode, std::error_cod
break;
}
- const DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- const DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
- HANDLE hTemplateFile = nullptr;
-
- HANDLE FileHandle = CreateFile(FileName.c_str(),
- dwDesiredAccess,
- dwShareMode,
- /* lpSecurityAttributes */ nullptr,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- hTemplateFile);
+ const DWORD dwShareMode = FILE_SHARE_READ | (EnumHasAllFlags(InMode, Mode::kPreventWrite) ? 0 : FILE_SHARE_WRITE) |
+ (EnumHasAllFlags(InMode, Mode::kPreventDelete) ? 0 : FILE_SHARE_DELETE);
+ const DWORD dwFlagsAndAttributes =
+ FILE_ATTRIBUTE_NORMAL | (EnumHasAllFlags(InMode, Mode::kDeleteOnClose) ? FILE_FLAG_DELETE_ON_CLOSE : 0);
+ const HANDLE hTemplateFile = nullptr;
+ const HANDLE FileHandle = CreateFile(FileName.c_str(),
+ dwDesiredAccess,
+ dwShareMode,
+ /* lpSecurityAttributes */ nullptr,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ hTemplateFile);
if (FileHandle == INVALID_HANDLE_VALUE)
{
@@ -139,6 +142,12 @@ BasicFile::Close()
}
}
+IoBuffer
+BasicFile::ReadRange(uint64_t FileOffset, uint64_t ByteCount)
+{
+ return IoBufferBuilder::MakeFromFileHandle(m_FileHandle, FileOffset, ByteCount);
+}
+
void
BasicFile::Read(void* Data, uint64_t BytesToRead, uint64_t FileOffset)
{
@@ -220,6 +229,26 @@ BasicFile::StreamByteRange(uint64_t FileOffset, uint64_t Size, std::function<voi
}
}
+uint64_t
+BasicFile::Write(CompositeBuffer Data, uint64_t FileOffset, std::error_code& Ec)
+{
+ uint64_t WrittenBytes = 0;
+ for (const SharedBuffer& Buffer : Data.GetSegments())
+ {
+ MemoryView BlockView = Buffer.GetView();
+ Write(BlockView, FileOffset, Ec);
+
+ if (Ec)
+ {
+ return WrittenBytes;
+ }
+
+ WrittenBytes += BlockView.GetSize();
+ }
+
+ return WrittenBytes;
+}
+
void
BasicFile::Write(MemoryView Data, uint64_t FileOffset, std::error_code& Ec)
{
diff --git a/src/zenutil/include/zenutil/basicfile.h b/src/zenutil/include/zenutil/basicfile.h
index 877df0f92..1c5a31c5c 100644
--- a/src/zenutil/include/zenutil/basicfile.h
+++ b/src/zenutil/include/zenutil/basicfile.h
@@ -2,6 +2,10 @@
#pragma once
+#include <zencore/zencore.h>
+
+#include <zencore/compositebuffer.h>
+#include <zencore/enumflags.h>
#include <zencore/iobuffer.h>
#include <filesystem>
@@ -36,25 +40,31 @@ public:
kTruncate = 2, // Opens (or creates) a file for read and write and sets the size to zero
kDelete = 3, // Opens (or creates) a file for read and write allowing .DeleteFile file disposition to be set
kTruncateDelete =
- 4 // Opens (or creates) a file for read and write and sets the size to zero allowing .DeleteFile file disposition to be set
+ 4, // Opens (or creates) a file for read and write and sets the size to zero allowing .DeleteFile file disposition to be set
+ kModeMask = 0x0007,
+ kPreventDelete = 0x1000'0000, // Do not open with delete sharing mode (prevent other processes from deleting file while open)
+ kPreventWrite = 0x2000'0000, // Do not open with write sharing mode (prevent other processes from writing to file while open)
+ kDeleteOnClose = 0x4000'0000, // File should be deleted when the last handle is closed
};
void Open(const std::filesystem::path& FileName, Mode Mode);
void Open(const std::filesystem::path& FileName, Mode Mode, std::error_code& Ec);
void Close();
void Read(void* Data, uint64_t Size, uint64_t FileOffset);
+ IoBuffer ReadRange(uint64_t FileOffset, uint64_t ByteCount);
void StreamFile(std::function<void(const void* Data, uint64_t Size)>&& ChunkFun);
void StreamByteRange(uint64_t FileOffset, uint64_t Size, std::function<void(const void* Data, uint64_t Size)>&& ChunkFun);
void Write(MemoryView Data, uint64_t FileOffset);
void Write(MemoryView Data, uint64_t FileOffset, std::error_code& Ec);
+ uint64_t Write(CompositeBuffer Data, uint64_t FileOffset, std::error_code& Ec);
void Write(const void* Data, uint64_t Size, uint64_t FileOffset);
void Write(const void* Data, uint64_t Size, uint64_t FileOffset, std::error_code& Ec);
void Flush();
- uint64_t FileSize();
- void SetFileSize(uint64_t FileSize);
- IoBuffer ReadAll();
- void WriteAll(IoBuffer Data, std::error_code& Ec);
- void* Detach();
+ [[nodiscard]] uint64_t FileSize();
+ void SetFileSize(uint64_t FileSize);
+ IoBuffer ReadAll();
+ void WriteAll(IoBuffer Data, std::error_code& Ec);
+ void* Detach();
inline void* Handle() { return m_FileHandle; }
@@ -63,6 +73,8 @@ protected:
private:
};
+ENUM_CLASS_FLAGS(BasicFile::Mode);
+
/**
* Simple abstraction for a temporary file
*