feat(file): implement filesystem utilities

This commit is contained in:
phaneron 2023-08-09 21:34:43 -04:00
parent 5e6af0ea70
commit bd65df59e9
26 changed files with 4163 additions and 5 deletions

146
bc/os/File.cpp Normal file
View file

@ -0,0 +1,146 @@
#include "bc/os/File.hpp"
#include "bc/file/Defines.hpp"
#include "bc/Debug.hpp"
HOSFILE OsCreateFile(const char* fileName, uint32_t desiredAccess, uint32_t shareMode, uint32_t createDisposition, uint32_t flagsAndAttributes, uint32_t extendedFileType) {
// Ensure sanity
BLIZZARD_VALIDATE(fileName, "invalid filename", nullptr);
BLIZZARD_VALIDATE(desiredAccess != 0, "invalid desired access");
BLIZZARD_VALIDATE(createDisposition <= OS_TRUNCATE_EXISTING, "invalid create disposition", nullptr);
// Read/write flags
if (desiredAccess & OS_GENERIC_READ) {
flags |= BC_FILE_OPEN_READ;
}
if (desiredAccess & OS_GENERIC_WRITE) {
flags |= BC_FILE_OPEN_WRITE;
}
// Allow other users to access the file in read and/or write mode
if (shareMode & OS_FILE_SHARE_READ) {
flags |= BC_FILE_OPEN_SHARE_READ;
}
if (shareMode & OS_FILE_SHARE_WRITE) {
flags |= BC_FILE_OPEN_SHARE_WRITE;
}
// Convert createDisposition into BC flags
switch (createDisposition) {
case OS_CREATE_NEW:
// flags |= 0xC00;
flags |= BC_FILE_OPEN_CREATE | BC_FILE_OPEN_MUST_NOT_EXIST;
break;
case OS_CREATE_ALWAYS:
// flags |= 0x400;
flags |= BC_FILE_OPEN_CREATE;
break;
case OS_OPEN_EXISTING:
// flags |= 0x1000
flags |= BC_FILE_OPEN_MUST_EXIST;
break;
case OS_OPEN_ALWAYS:
// flags |= 0x200;
flags |= BC_FILE_OPEN_ALWAYS;
break;
case OS_TRUNCATE_EXISTING:
// flags |= 0x100;
flags |= BC_FILE_OPEN_TRUNCATE;
break;
}
// Open file
Blizzard::File::StreamRecord* stream;
bool success = Blizzard::File::Open(fileName, flags, &stream);
if (!success) {
return nullptr;
}
// Set attributes
OsSetFileAttributes(fileName, flagsAndAttributes);
return stream;
}
int32_t OsSetFileAttributes(const char* fileName, uint32_t attributes) {
BLIZZARD_ASSERT(fileName);
// Translate OS file attribute bits into BlizzardCore attribute bits.
uint32_t flags = 0;
if (attributes & OS_FILE_ATTRIBUTE_READONLY) {
// flags |= 1;
flags |= BC_FILE_ATTRIBUTE_READONLY;
}
if (attributes & OS_FILE_ATTRIBUTE_HIDDEN) {
// flags |= 2;
flags |= BC_FILE_ATTRIBUTE_HIDDEN;
}
if (attributes & OS_FILE_ATTRIBUTE_SYSTEM) {
// flags |= 4
flags |= BC_FILE_ATTRIBUTE_SYSTEM;
}
if (attributes & OS_FILE_ATTRIBUTE_ARCHIVE) {
// flags |= 8;
flags |= BC_FILE_ATTRIBUTE_ARCHIVE;
}
if (attributes & OS_FILE_ATTRIBUTE_TEMPORARY) {
// flags |= 0x10;
flags |= BC_FILE_ATTRIBUTE_TEMPORARY;
}
if (attributes & OS_FILE_ATTRIBUTE_NORMAL) {
// flags |= 0x20;
flags |= BC_FILE_ATTRIBUTE_NORMAL;
}
if (attributes & OS_FILE_ATTRIBUTE_DIRECTORY) {
// flags |= 0x40;
flags |= BC_FILE_ATTRIBUTE_DIRECTORY;
}
return Blizzard::File::SetAttributes(fileName, flags);
}
uint64_t OsGetFileSize(HOSFILE fileHandle) {
auto info = Blizzard::File::GetInfo(reinterpret_cast<Blizzard::File::StreamRecord*>(fileHandle));
return info->size;
}
int32_t OsReadFile(HOSFILE fileHandle, void* buffer, size_t bytesToRead, size_t* bytesRead) {
BLIZZARD_ASSERT(buffer);
BLIZZARD_ASSERT(bytesToRead);
return Blizzard::File::Read(fileHandle, buffer, bytesToRead, bytesRead);
}
int32_t OsWriteFile(HOSFILE fileHandle, void* buffer, size_t bytesToWrite, size_t* bytesWritten) {
if (buffer != nullptr && bytesToWrite != 0) {
return Blizzard::File::Write(fileHandle, buffer, bytesToWrite, bytesWritten);
}
return 0;
}
int64_t OsSetFilePointer(HOSFILE fileHandle, int64_t distanceToMove, uint32_t moveMethod) {
BLIZZARD_ASSERT(moveMethod <= BC_FILE_SEEK_END);
int64_t position;
if (moveMethod != 0 && !Blizzard::File::GetPos(fileHandle, position)) {
return -1;
}
uint32_t seeks[3] = {
BC_FILE_SEEK_START,
BC_FILE_SEEK_CURRENT,
BC_FILE_SEEK_END
};
if (!Blizzard::File::SetPos(fileHandle, position, seeks[moveMethod])) {
return -1;
}
return position + distanceToMove;
}
void OsCloseFile(HOSFILE fileHandle) {
Blizzard::File::Close(static_cast<Blizzard::File::StreamRecord*>(fileHandle));
}

65
bc/os/File.hpp Normal file
View file

@ -0,0 +1,65 @@
#ifndef BC_OS_FILE_HPP
#define BC_OS_FILE_HPP
#include "bc/file/Types.hpp"
#include <cstdint>
enum EOSFileDisposition {
OS_CREATE_NEW = 1,
OS_CREATE_ALWAYS = 2,
OS_OPEN_EXISTING = 3,
OS_OPEN_ALWAYS = 4,
OS_TRUNCATE_EXISTING = 5
};
enum EOSFileAccess {
OS_GENERIC_ALL = 0x10000000,
OS_GENERIC_EXECUTE = 0x20000000,
OS_GENERIC_WRITE = 0x40000000,
OS_GENERIC_READ = 0x80000000
};
enum EOSFileShare {
OS_FILE_SHARE_READ = 0x00000001,
OS_FILE_SHARE_WRITE = 0x00000002
};
enum EOSFileFlagsAndAttributes {
OS_FILE_ATTRIBUTE_READONLY = 0x1,
OS_FILE_ATTRIBUTE_HIDDEN = 0x2,
OS_FILE_ATTRIBUTE_SYSTEM = 0x4,
OS_FILE_ATTRIBUTE_DIRECTORY = 0x10,
OS_FILE_ATTRIBUTE_ARCHIVE = 0x20,
OS_FILE_ATTRIBUTE_NORMAL = 0x80,
OS_FILE_ATTRIBUTE_TEMPORARY = 0x100,
OS_FILE_ATTRIBUTE_OFFLINE = 0x1000,
OS_FILE_ATTRIBUTE_ENCRYPTED = 0x4000,
OS_FILE_FLAG_OPEN_NO_RECALL = 0x00100000,
OS_FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000,
OS_FILE_FLAG_POSIX_SEMANTICS = 0x01000000,
OS_FILE_FLAG_BACKUP_SEMANTICS = 0x02000000,
OS_FILE_FLAG_DELETE_ON_CLOSE = 0x04000000,
OS_FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000,
OS_FILE_FLAG_RANDOM_ACCESS = 0x10000000,
OS_FILE_FLAG_NO_BUFFERING = 0x20000000,
OS_FILE_FLAG_OVERLAPPED = 0x40000000,
OS_FILE_FLAG_WRITE_THROUGH = 0x80000000
};
typedef Blizzard::File::StreamRecord* HOSFILE;
HOSFILE OsCreateFile(const char* fileName, uint32_t desiredAccess, uint32_t shareMode, uint32_t createDisposition, uint32_t flagsAndAttributes, uint32_t extendedFileType);
int32_t OsSetFileAttributes(const char* fileName, uint32_t attributes);
uint64_t OsGetFileSize(HOSFILE fileHandle);
int32_t OsReadFile(HOSFILE fileHandle, void* buffer, uint32_t bytesToRead, uint32_t* bytesRead);
void OsCloseFile(HOSFILE fileHandle);
int64_t OsSetFilePointer(HOSFILE fileHandle, int64_t distanceToMove, uint32_t moveMethod);
#endif