Move static functions outside of DqnFile
This commit is contained in:
parent
25410c7aac
commit
33cf476d29
@ -1,10 +1,3 @@
|
|||||||
#if defined(DQN_IS_WIN32)
|
|
||||||
#define WIN32_MEAN_AND_LEAN
|
|
||||||
#include <Winsock2.h>
|
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <Windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
#define HANDMADE_MATH_NO_SSE
|
#define HANDMADE_MATH_NO_SSE
|
||||||
#endif
|
#endif
|
||||||
@ -14,6 +7,13 @@
|
|||||||
#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
|
#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define WIN32_MEAN_AND_LEAN
|
||||||
|
#include <Winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <Windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DQN_PLATFORM_HEADER
|
#define DQN_PLATFORM_HEADER
|
||||||
#define DQN_PLATFORM_IMPLEMENTATION
|
#define DQN_PLATFORM_IMPLEMENTATION
|
||||||
#define DQN_IMPLEMENTATION
|
#define DQN_IMPLEMENTATION
|
||||||
@ -1557,7 +1557,7 @@ void DqnArray_TestRealDataInternal(DqnArray<char> *array)
|
|||||||
(void)array;
|
(void)array;
|
||||||
#ifdef DQN_PLATFORM_HEADER
|
#ifdef DQN_PLATFORM_HEADER
|
||||||
size_t bufSize = 0;
|
size_t bufSize = 0;
|
||||||
u8 *buf = DqnFile::ReadEntireFile("tests/google-10000-english.txt", &bufSize);
|
u8 *buf = DqnFile_ReadAll("tests/google-10000-english.txt", &bufSize);
|
||||||
DQN_ASSERT(buf);
|
DQN_ASSERT(buf);
|
||||||
|
|
||||||
for (usize i = 0; i < bufSize; i++)
|
for (usize i = 0; i < bufSize; i++)
|
||||||
@ -1663,7 +1663,7 @@ void DqnFile_Test()
|
|||||||
// should give us zero, but we fall back to manual byte checking
|
// should give us zero, but we fall back to manual byte checking
|
||||||
// which should give us the proper size.
|
// which should give us the proper size.
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
DQN_ASSERT(DqnFile::GetFileSize("/proc/cpuinfo", &size));
|
DQN_ASSERT(DqnFile_Size("/proc/cpuinfo", &size));
|
||||||
DQN_ASSERT(size > 0);
|
DQN_ASSERT(size > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1688,13 +1688,13 @@ void DqnFile_Test()
|
|||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
DQN_ASSERT(DqnFile::GetFileSize(FILE_TO_OPEN, &size));
|
DQN_ASSERT(DqnFile_Size(FILE_TO_OPEN, &size));
|
||||||
DQN_ASSERT(size == expectedSize);
|
DQN_ASSERT(size == expectedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
DqnFile file = {};
|
DqnFile file = {};
|
||||||
DQN_ASSERT(file.Open(".clang-format",
|
DQN_ASSERT(file.Open(".clang-format",
|
||||||
(DqnFile::PermissionFlag::FileWrite | DqnFile::PermissionFlag::FileRead),
|
(DqnFile::Permission::FileWrite | DqnFile::Permission::FileRead),
|
||||||
DqnFile::Action::OpenOnly));
|
DqnFile::Action::OpenOnly));
|
||||||
|
|
||||||
DQN_ASSERTM(file.size == expectedSize,
|
DQN_ASSERTM(file.size == expectedSize,
|
||||||
@ -1712,7 +1712,7 @@ void DqnFile_Test()
|
|||||||
{
|
{
|
||||||
DqnSmartFile raiiFile = {};
|
DqnSmartFile raiiFile = {};
|
||||||
if (raiiFile.Open(FILE_TO_OPEN,
|
if (raiiFile.Open(FILE_TO_OPEN,
|
||||||
DqnFile::PermissionFlag::FileWrite | DqnFile::PermissionFlag::FileRead,
|
DqnFile::Permission::FileWrite | DqnFile::Permission::FileRead,
|
||||||
DqnFile::Action::OpenOnly))
|
DqnFile::Action::OpenOnly))
|
||||||
{
|
{
|
||||||
i32 breakHereToTestRaii = 0;
|
i32 breakHereToTestRaii = 0;
|
||||||
@ -1727,8 +1727,8 @@ void DqnFile_Test()
|
|||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
DqnFile file = {};
|
DqnFile file = {};
|
||||||
DQN_ASSERT(!file.Open("asdljasdnel;kajdf", (DqnFile::PermissionFlag::FileWrite |
|
DQN_ASSERT(!file.Open("asdljasdnel;kajdf", (DqnFile::Permission::FileWrite |
|
||||||
DqnFile::PermissionFlag::FileRead),
|
DqnFile::Permission::FileRead),
|
||||||
DqnFile::Action::OpenOnly));
|
DqnFile::Action::OpenOnly));
|
||||||
DQN_ASSERT(file.size == 0);
|
DQN_ASSERT(file.size == 0);
|
||||||
DQN_ASSERT(file.flags == 0);
|
DQN_ASSERT(file.flags == 0);
|
||||||
@ -1747,7 +1747,7 @@ void DqnFile_Test()
|
|||||||
// Write data out to some files
|
// Write data out to some files
|
||||||
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
|
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
|
||||||
{
|
{
|
||||||
u32 permissions = DqnFile::PermissionFlag::FileRead | DqnFile::PermissionFlag::FileWrite;
|
u32 permissions = DqnFile::Permission::FileRead | DqnFile::Permission::FileWrite;
|
||||||
DqnFile *file = files + i;
|
DqnFile *file = files + i;
|
||||||
if (!file->Open(fileNames[i], permissions, DqnFile::Action::ClearIfExist))
|
if (!file->Open(fileNames[i], permissions, DqnFile::Action::ClearIfExist))
|
||||||
{
|
{
|
||||||
@ -1770,7 +1770,7 @@ void DqnFile_Test()
|
|||||||
{
|
{
|
||||||
// Manual read the file contents
|
// Manual read the file contents
|
||||||
{
|
{
|
||||||
u32 permissions = DqnFile::PermissionFlag::FileRead;
|
u32 permissions = DqnFile::Permission::FileRead;
|
||||||
DqnFile *file = files + i;
|
DqnFile *file = files + i;
|
||||||
bool result = file->Open(fileNames[i], permissions, DqnFile::Action::OpenOnly);
|
bool result = file->Open(fileNames[i], permissions, DqnFile::Action::OpenOnly);
|
||||||
DQN_ASSERT(result);
|
DQN_ASSERT(result);
|
||||||
@ -1792,13 +1792,13 @@ void DqnFile_Test()
|
|||||||
// Read using the ReadEntireFile api which doesn't need a file handle as an argument
|
// Read using the ReadEntireFile api which doesn't need a file handle as an argument
|
||||||
{
|
{
|
||||||
size_t reqSize = 0;
|
size_t reqSize = 0;
|
||||||
DQN_ASSERT(DqnFile::GetFileSize(fileNames[i], &reqSize));
|
DQN_ASSERT(DqnFile_Size(fileNames[i], &reqSize));
|
||||||
|
|
||||||
u8 *buffer = (u8 *)memStack.Push(reqSize);
|
u8 *buffer = (u8 *)memStack.Push(reqSize);
|
||||||
DQN_ASSERT(buffer);
|
DQN_ASSERT(buffer);
|
||||||
|
|
||||||
size_t bytesRead = 0;
|
size_t bytesRead = 0;
|
||||||
DQN_ASSERT(DqnFile::ReadEntireFile(fileNames[i], buffer, reqSize, &bytesRead));
|
DQN_ASSERT(DqnFile_ReadAll(fileNames[i], buffer, reqSize, &bytesRead));
|
||||||
DQN_ASSERT(bytesRead == reqSize);
|
DQN_ASSERT(bytesRead == reqSize);
|
||||||
|
|
||||||
// Verify the data is the same as we wrote out
|
// Verify the data is the same as we wrote out
|
||||||
@ -1806,14 +1806,14 @@ void DqnFile_Test()
|
|||||||
memStack.Pop(buffer);
|
memStack.Pop(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_ASSERT(DqnFile::Delete(fileNames[i]));
|
DQN_ASSERT(DqnFile_Delete(fileNames[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then check delete actually worked, files should not exist.
|
// Then check delete actually worked, files should not exist.
|
||||||
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
|
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
|
||||||
{
|
{
|
||||||
DqnFile dummy = {};
|
DqnFile dummy = {};
|
||||||
u32 permissions = DqnFile::PermissionFlag::FileRead;
|
u32 permissions = DqnFile::Permission::FileRead;
|
||||||
bool fileExists = dummy.Open(fileNames[i], permissions, DqnFile::Action::OpenOnly);
|
bool fileExists = dummy.Open(fileNames[i], permissions, DqnFile::Action::OpenOnly);
|
||||||
DQN_ASSERT(!fileExists);
|
DQN_ASSERT(!fileExists);
|
||||||
}
|
}
|
||||||
@ -1827,9 +1827,9 @@ void DqnFile_Test()
|
|||||||
{
|
{
|
||||||
i32 numFiles;
|
i32 numFiles;
|
||||||
#if defined(DQN___IS_UNIX)
|
#if defined(DQN___IS_UNIX)
|
||||||
char **filelist = DqnFile::ListDir(".", &numFiles);
|
char **filelist = DqnFile_ListDir(".", &numFiles);
|
||||||
#else
|
#else
|
||||||
char **filelist = DqnFile::ListDir("*", &numFiles);
|
char **filelist = DqnFile_ListDir("*", &numFiles);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Log("Test directory listing");
|
Log("Test directory listing");
|
||||||
@ -1837,7 +1837,7 @@ void DqnFile_Test()
|
|||||||
for (auto i = 0; i < numFiles; i++)
|
for (auto i = 0; i < numFiles; i++)
|
||||||
Log("%02d: %s", i, filelist[i]);
|
Log("%02d: %s", i, filelist[i]);
|
||||||
|
|
||||||
DqnFile::ListDirFree(filelist, numFiles);
|
DqnFile_ListDirFree(filelist, numFiles);
|
||||||
globalIndent--;
|
globalIndent--;
|
||||||
Log(Status::Ok, "List directory files");
|
Log(Status::Ok, "List directory files");
|
||||||
}
|
}
|
||||||
|
291
dqn.h
291
dqn.h
@ -215,6 +215,16 @@ u32 const MEM_RESERVE = 0x00002000;
|
|||||||
u32 const PAGE_READWRITE = 0x04;
|
u32 const PAGE_READWRITE = 0x04;
|
||||||
u32 const MEM_DECOMMIT = 0x4000;
|
u32 const MEM_DECOMMIT = 0x4000;
|
||||||
u32 const MEM_RELEASE = 0x8000;
|
u32 const MEM_RELEASE = 0x8000;
|
||||||
|
u32 const GENERIC_READ = 0x80000000L;
|
||||||
|
u32 const GENERIC_WRITE = 0x40000000L;
|
||||||
|
u32 const GENERIC_EXECUTE = 0x20000000L;
|
||||||
|
u32 const GENERIC_ALL = 0x10000000L;
|
||||||
|
u32 const CREATE_NEW = 1;
|
||||||
|
u32 const CREATE_ALWAYS = 2;
|
||||||
|
u32 const OPEN_EXISTING = 3;
|
||||||
|
u32 const OPEN_ALWAYS = 4;
|
||||||
|
u32 const TRUNCATE_EXISTING = 5;
|
||||||
|
u32 const FILE_ATTRIBUTE_NORMAL = 0x00000080;
|
||||||
|
|
||||||
struct RECT
|
struct RECT
|
||||||
{
|
{
|
||||||
@ -2930,7 +2940,7 @@ template <typename T> void DqnVArray<T>::EraseStable(isize index)
|
|||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
struct DqnFile
|
struct DqnFile
|
||||||
{
|
{
|
||||||
enum PermissionFlag
|
enum Permission
|
||||||
{
|
{
|
||||||
FileRead = (1 << 0),
|
FileRead = (1 << 0),
|
||||||
FileWrite = (1 << 1),
|
FileWrite = (1 << 1),
|
||||||
@ -2938,7 +2948,7 @@ struct DqnFile
|
|||||||
All = (1 << 3)
|
All = (1 << 3)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Action
|
enum struct Action
|
||||||
{
|
{
|
||||||
OpenOnly, // Only open file if it exists. Fails and returns false if file did not exist or could not open.
|
OpenOnly, // Only open file if it exists. Fails and returns false if file did not exist or could not open.
|
||||||
CreateIfNotExist, // Try and create file. Return true if it was able to create. If it already exists, this fails.
|
CreateIfNotExist, // Try and create file. Return true if it was able to create. If it already exists, this fails.
|
||||||
@ -2946,14 +2956,6 @@ struct DqnFile
|
|||||||
ForceCreate, // Always create, even if it exists
|
ForceCreate, // Always create, even if it exists
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Info
|
|
||||||
{
|
|
||||||
usize size;
|
|
||||||
u64 createTimeInS;
|
|
||||||
u64 lastWriteTimeInS;
|
|
||||||
u64 lastAccessTimeInS;
|
|
||||||
};
|
|
||||||
|
|
||||||
u32 flags;
|
u32 flags;
|
||||||
void *handle;
|
void *handle;
|
||||||
usize size;
|
usize size;
|
||||||
@ -2972,52 +2974,57 @@ struct DqnFile
|
|||||||
// return: The number of bytes written. 0 if invalid args or it failed to write.
|
// return: The number of bytes written. 0 if invalid args or it failed to write.
|
||||||
usize Write(u8 const *buf, usize const numBytesToWrite, usize const fileOffset);
|
usize Write(u8 const *buf, usize const numBytesToWrite, usize const fileOffset);
|
||||||
|
|
||||||
// IMPORTANT: You may want to allocate size+1 for null-terminating the file contents when
|
// IMPORTANT: You may want to allocate size+1 for null-terminating the file contents when reading into a buffer.
|
||||||
// reading into a buffer.
|
|
||||||
// return: The number of bytes read. 0 if invalid args or it failed to read.
|
// return: The number of bytes read. 0 if invalid args or it failed to read.
|
||||||
usize Read (u8 *buf, usize const numBytesToRead);
|
usize Read (u8 *buf, usize const numBytesToRead);
|
||||||
|
|
||||||
// File close invalidates the handle after it is called.
|
// File close invalidates the handle after it is called.
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
// Static API
|
|
||||||
// ==============================================================================================
|
|
||||||
// Read entire file into the given buffer. To determine required bufSize size, use GetFileSize.
|
|
||||||
// NOTE: You want size + 1 and add the null-terminator yourself if you want a null terminated buffer.
|
|
||||||
// bytesRead: Pass in to get how many bytes of the buf was used. Basically the return value of Read
|
|
||||||
// return: False if insufficient bufSize OR file access failure OR nullptr arguments.
|
|
||||||
static bool ReadEntireFile(char const *path, u8 *buf, usize const bufSize, usize *bytesRead);
|
|
||||||
static bool ReadEntireFile(wchar_t const *path, u8 *buf, usize const bufSize, usize *bytesRead);
|
|
||||||
|
|
||||||
// Buffer is null-terminated and should be freed when done with.
|
|
||||||
// return: False if file access failure OR nullptr arguments.
|
|
||||||
static u8 *ReadEntireFile(char const *path, usize *bufSize, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
|
||||||
static u8 *ReadEntireFile(wchar_t const *path, usize *bufSize, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
|
||||||
|
|
||||||
// return: False if file access failure OR nullptr arguments.
|
|
||||||
static bool GetFileSize (char const *path, usize *size);
|
|
||||||
static bool GetFileSize (wchar_t const *path, usize *size);
|
|
||||||
|
|
||||||
// info: Pass in to fill with file attributes.
|
|
||||||
// return: False if file access failure OR nullptr arguments.
|
|
||||||
static bool GetInfo (char const *path, Info *info);
|
|
||||||
static bool GetInfo (wchar_t const *path, Info *info);
|
|
||||||
|
|
||||||
// NOTE: You can't delete a file unless the handle has been closed to it on Win32.
|
|
||||||
// return: False if file access failure OR nullptr arguments.
|
|
||||||
static bool Delete (char const *path);
|
|
||||||
static bool Delete (wchar_t const *path);
|
|
||||||
static bool Copy (char const *src, char const *dest);
|
|
||||||
static bool Copy (wchar_t const *src, wchar_t const *dest);
|
|
||||||
|
|
||||||
// NOTE: Win32: Current directory is "*", Unix: "."
|
|
||||||
// numFiles: Pass in a ref to a i32. The function fills it out with the number of entries.
|
|
||||||
// return: An array of strings of the files in the directory in UTF-8. The directory lisiting is
|
|
||||||
// allocated with malloc and must be freed using free() or the helper function ListDirFree()
|
|
||||||
static char **ListDir (char const *dir, i32 *numFiles, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
|
||||||
static void ListDirFree (char **fileList, i32 numFiles, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DqnFileInfo
|
||||||
|
{
|
||||||
|
usize size;
|
||||||
|
u64 createTimeInS;
|
||||||
|
u64 lastWriteTimeInS;
|
||||||
|
u64 lastAccessTimeInS;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Read entire file into the given buffer. To determine required bufSize size, use GetFileSize.
|
||||||
|
// NOTE: You want size + 1 and add the null-terminator yourself if you want a null terminated buffer.
|
||||||
|
// bytesRead: Pass in to get how many bytes of the buf was used. Basically the return value of Read
|
||||||
|
// return: False if insufficient bufSize OR file access failure OR nullptr arguments.
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_ReadAll(char const *path, u8 *buf, usize const bufSize, usize *bytesRead);
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_ReadAll(wchar_t const *path, u8 *buf, usize const bufSize, usize *bytesRead);
|
||||||
|
|
||||||
|
// Buffer is null-terminated and should be freed when done with.
|
||||||
|
// return: False if file access failure OR nullptr arguments.
|
||||||
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *bufSize, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
||||||
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *bufSize, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
||||||
|
|
||||||
|
// return: False if file access failure
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_Size(char const *path, usize *size);
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_Size(wchar_t const *path, usize *size);
|
||||||
|
|
||||||
|
// info: Pass in to fill with file attributes.
|
||||||
|
// return: False if file access failure
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_GetInfo(char const *path, DqnFileInfo *info);
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_GetInfo(wchar_t const *path, DqnFileInfo *info);
|
||||||
|
|
||||||
|
// NOTE: You can't delete a file unless the handle has been closed to it on Win32.
|
||||||
|
// return: False if file access failure
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_Delete (char const *path);
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_Delete (wchar_t const *path);
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_Copy (char const *src, char const *dest);
|
||||||
|
DQN_FILE_SCOPE bool DqnFile_Copy (wchar_t const *src, wchar_t const *dest);
|
||||||
|
|
||||||
|
// NOTE: Win32: Current directory is "*", Unix: "."
|
||||||
|
// numFiles: Pass in a ref to a i32. The function fills it out with the number of entries.
|
||||||
|
// return: An array of strings of the files in the directory in UTF-8. The directory lisiting is
|
||||||
|
// allocated with malloc and must be freed using free() or the helper function ListDirFree()
|
||||||
|
DQN_FILE_SCOPE char **DqnFile_ListDir (char const *dir, i32 *numFiles, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
||||||
|
DQN_FILE_SCOPE void DqnFile_ListDirFree (char **fileList, i32 numFiles, DqnMemAPI *api = DQN_DEFAULT_HEAP_ALLOCATOR);
|
||||||
|
|
||||||
struct DqnSmartFile : public DqnFile
|
struct DqnSmartFile : public DqnFile
|
||||||
{
|
{
|
||||||
~DqnSmartFile() { this->Close(); }
|
~DqnSmartFile() { this->Close(); }
|
||||||
@ -8621,15 +8628,15 @@ DqnFile__Win32Open(wchar_t const *path, DqnFile *file, u32 flags, DqnFile::Actio
|
|||||||
u32 const WIN32_FILE_ATTRIBUTE_NORMAL = 0x00000080;
|
u32 const WIN32_FILE_ATTRIBUTE_NORMAL = 0x00000080;
|
||||||
|
|
||||||
DWORD win32Permission = 0;
|
DWORD win32Permission = 0;
|
||||||
if (flags & DqnFile::PermissionFlag::All)
|
if (flags & DqnFile::Permission::All)
|
||||||
{
|
{
|
||||||
win32Permission = WIN32_GENERIC_ALL;
|
win32Permission = WIN32_GENERIC_ALL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (flags & DqnFile::PermissionFlag::FileRead) win32Permission |= WIN32_GENERIC_READ;
|
if (flags & DqnFile::Permission::FileRead) win32Permission |= WIN32_GENERIC_READ;
|
||||||
if (flags & DqnFile::PermissionFlag::FileWrite) win32Permission |= WIN32_GENERIC_WRITE;
|
if (flags & DqnFile::Permission::FileWrite) win32Permission |= WIN32_GENERIC_WRITE;
|
||||||
if (flags & DqnFile::PermissionFlag::Execute) win32Permission |= WIN32_GENERIC_EXECUTE;
|
if (flags & DqnFile::Permission::Execute) win32Permission |= WIN32_GENERIC_EXECUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD win32Action = 0;
|
DWORD win32Action = 0;
|
||||||
@ -8790,7 +8797,7 @@ DqnFile__UnixOpen(char const *path, DqnFile *file, u32 flags, DqnFile::Action ac
|
|||||||
char operation = 0;
|
char operation = 0;
|
||||||
bool updateFlag = false;
|
bool updateFlag = false;
|
||||||
|
|
||||||
if (flags & DqnFile::PermissionFlag::FileWrite)
|
if (flags & DqnFile::Permission::FileWrite)
|
||||||
{
|
{
|
||||||
updateFlag = true;
|
updateFlag = true;
|
||||||
switch (action)
|
switch (action)
|
||||||
@ -8811,10 +8818,10 @@ DqnFile__UnixOpen(char const *path, DqnFile *file, u32 flags, DqnFile::Action ac
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((flags & DqnFile::PermissionFlag::FileRead) ||
|
else if ((flags & DqnFile::Permission::FileRead) ||
|
||||||
(flags & DqnFile::PermissionFlag::Execute))
|
(flags & DqnFile::Permission::Execute))
|
||||||
{
|
{
|
||||||
if (flags & DqnFile::PermissionFlag::Execute)
|
if (flags & DqnFile::Permission::Execute)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Logging, UNIX doesn't have execute param for file
|
// TODO(doyle): Logging, UNIX doesn't have execute param for file
|
||||||
// handles. Execution goes through system()
|
// handles. Execution goes through system()
|
||||||
@ -9004,16 +9011,11 @@ usize DqnFile::Read(u8 *buf, usize numBytesToRead)
|
|||||||
return numBytesRead;
|
return numBytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *DqnFile::ReadEntireFile(wchar_t const *path, usize *bufSize, DqnMemAPI *api)
|
u8 *DqnFile_ReadAll(wchar_t const *path, usize *bufSize, DqnMemAPI *api)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Logging
|
// TODO(doyle): Logging
|
||||||
if (!path || !bufSize)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
usize requiredSize = 0;
|
usize requiredSize = 0;
|
||||||
if (!DqnFile::GetFileSize(path, &requiredSize) || requiredSize == 0)
|
if (!DqnFile_Size(path, &requiredSize) || requiredSize == 0)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -9025,29 +9027,7 @@ u8 *DqnFile::ReadEntireFile(wchar_t const *path, usize *bufSize, DqnMemAPI *api)
|
|||||||
}
|
}
|
||||||
|
|
||||||
usize bytesRead = 0;
|
usize bytesRead = 0;
|
||||||
if (DqnFile::ReadEntireFile(path, buf, requiredSize, &bytesRead))
|
if (DqnFile_ReadAll(path, buf, requiredSize, &bytesRead))
|
||||||
{
|
|
||||||
*bufSize = requiredSize;
|
|
||||||
DQN_ASSERT(bytesRead == requiredSize);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
api->Free(buf, requiredSize);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 *DqnFile::ReadEntireFile(char const *path, usize *bufSize, DqnMemAPI *api)
|
|
||||||
{
|
|
||||||
// TODO(doyle): Logging
|
|
||||||
|
|
||||||
usize requiredSize = 0;
|
|
||||||
if (!DqnFile::GetFileSize(path, &requiredSize) || requiredSize == 0) return nullptr;
|
|
||||||
|
|
||||||
auto *buf = (u8 *)api->Alloc(requiredSize, Dqn::ZeroClear::No);
|
|
||||||
if (!buf) return nullptr;
|
|
||||||
|
|
||||||
usize bytesRead = 0;
|
|
||||||
if (DqnFile::ReadEntireFile(path, buf, requiredSize, &bytesRead))
|
|
||||||
{
|
{
|
||||||
*bufSize = requiredSize;
|
*bufSize = requiredSize;
|
||||||
DQN_ASSERTM(bytesRead == requiredSize, "%zu != %zu", bytesRead, requiredSize);
|
DQN_ASSERTM(bytesRead == requiredSize, "%zu != %zu", bytesRead, requiredSize);
|
||||||
@ -9058,52 +9038,64 @@ u8 *DqnFile::ReadEntireFile(char const *path, usize *bufSize, DqnMemAPI *api)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::ReadEntireFile(wchar_t const *path, u8 *buf, usize bufSize,
|
u8 *DqnFile_ReadAll(char const *path, usize *bufSize, DqnMemAPI *api)
|
||||||
usize *bytesRead)
|
|
||||||
{
|
{
|
||||||
if (!path || !buf || !bytesRead) return false;
|
// TODO(doyle): Logging
|
||||||
|
usize requiredSize = 0;
|
||||||
|
if (!DqnFile_Size(path, &requiredSize) || requiredSize == 0)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *buf = (u8 *)api->Alloc(requiredSize, Dqn::ZeroClear::No);
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize bytesRead = 0;
|
||||||
|
if (DqnFile_ReadAll(path, buf, requiredSize, &bytesRead))
|
||||||
|
{
|
||||||
|
*bufSize = requiredSize;
|
||||||
|
DQN_ASSERTM(bytesRead == requiredSize, "%zu != %zu", bytesRead, requiredSize);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
api->Free(buf, requiredSize);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DqnFile_ReadAll(wchar_t const *path, u8 *buf, usize bufSize, usize *bytesRead)
|
||||||
|
{
|
||||||
DqnFile file = {};
|
DqnFile file = {};
|
||||||
bool result = file.Open(path, DqnFile::PermissionFlag::FileRead, DqnFile::Action::OpenOnly);
|
bool result = file.Open(path, DqnFile::Permission::FileRead, DqnFile::Action::OpenOnly);
|
||||||
|
DQN_DEFER(file.Close());
|
||||||
|
|
||||||
// TODO(doyle): Logging
|
// TODO(doyle): Logging
|
||||||
if (!result) goto cleanup;
|
if (file.size > bufSize || !result)
|
||||||
|
|
||||||
if (file.size > bufSize)
|
|
||||||
{
|
{
|
||||||
result = false;
|
DQN_LOGE("Insufficient buffer size given: %zu, required: %zu\n", bufSize, file.size);
|
||||||
goto cleanup;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*bytesRead = file.Read(buf, file.size);
|
*bytesRead = file.Read(buf, file.size);
|
||||||
DQN_ASSERT(*bytesRead == file.size);
|
DQN_ASSERT(*bytesRead == file.size);
|
||||||
|
|
||||||
cleanup:
|
|
||||||
file.Close();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::ReadEntireFile(const char *path, u8 *buf, usize bufSize, usize *bytesRead)
|
bool DqnFile_ReadAll(const char *path, u8 *buf, usize bufSize, usize *bytesRead)
|
||||||
{
|
{
|
||||||
if (!path || !buf || !bytesRead) return false;
|
|
||||||
|
|
||||||
DqnFile file = {};
|
DqnFile file = {};
|
||||||
bool result = file.Open(path, DqnFile::PermissionFlag::FileRead, DqnFile::Action::OpenOnly);
|
bool result = file.Open(path, DqnFile::Permission::FileRead, DqnFile::Action::OpenOnly);
|
||||||
|
DQN_DEFER(file.Close());
|
||||||
|
|
||||||
// TODO(doyle): Logging
|
if (!result || file.size > bufSize)
|
||||||
if (!result) goto cleanup;
|
|
||||||
|
|
||||||
if (file.size > bufSize)
|
|
||||||
{
|
{
|
||||||
result = false;
|
return false;
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*bytesRead = file.Read(buf, file.size);
|
*bytesRead = file.Read(buf, file.size);
|
||||||
DQN_ASSERTM(*bytesRead == file.size, "%zu != %zu", *bytesRead, file.size);
|
DQN_ASSERTM(*bytesRead == file.size, "%zu != %zu", *bytesRead, file.size);
|
||||||
|
|
||||||
cleanup:
|
|
||||||
file.Close();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9126,12 +9118,11 @@ void DqnFile::Close()
|
|||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
DQN_COMPILE_ASSERT(sizeof(DWORD) == sizeof(u32));
|
DQN_COMPILE_ASSERT(sizeof(DWORD) == sizeof(u32));
|
||||||
#endif
|
#endif
|
||||||
bool DqnFile::GetFileSize(wchar_t const *path, usize *size)
|
|
||||||
{
|
|
||||||
if (!size || !path) return false;
|
|
||||||
|
|
||||||
Info info = {};
|
bool DqnFile_Size(wchar_t const *path, usize *size)
|
||||||
if (GetInfo(path, &info))
|
{
|
||||||
|
DqnFileInfo info = {};
|
||||||
|
if (DqnFile_GetInfo(path, &info))
|
||||||
{
|
{
|
||||||
*size = info.size;
|
*size = info.size;
|
||||||
return true;
|
return true;
|
||||||
@ -9140,16 +9131,14 @@ bool DqnFile::GetFileSize(wchar_t const *path, usize *size)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::GetFileSize(char const *path, usize *size)
|
bool DqnFile_Size(char const *path, usize *size)
|
||||||
{
|
{
|
||||||
if (!path || !size) return false;
|
|
||||||
|
|
||||||
// TODO(doyle): Logging
|
// TODO(doyle): Logging
|
||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
// TODO(doyle): MAX PATH is baad
|
// TODO(doyle): MAX PATH is baad
|
||||||
wchar_t widePath[MAX_PATH] = {0};
|
wchar_t widePath[MAX_PATH] = {0};
|
||||||
DqnWin32_UTF8ToWChar(path, widePath, DQN_ARRAY_COUNT(widePath));
|
DqnWin32_UTF8ToWChar(path, widePath, DQN_ARRAY_COUNT(widePath));
|
||||||
return DqnFile::GetFileSize(widePath, size);
|
return DqnFile_Size(widePath, size);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// TODO(doyle): Error logging
|
// TODO(doyle): Error logging
|
||||||
@ -9158,10 +9147,8 @@ bool DqnFile::GetFileSize(char const *path, usize *size)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::GetInfo(wchar_t const *path, Info *info)
|
bool DqnFile_GetInfo(wchar_t const *path, DqnFileInfo *info)
|
||||||
{
|
{
|
||||||
if (!path || !info) return false;
|
|
||||||
|
|
||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
auto FileTimeToSeconds = [](FILETIME const *time) -> i64 {
|
auto FileTimeToSeconds = [](FILETIME const *time) -> i64 {
|
||||||
ULARGE_INTEGER timeLargeInt = {};
|
ULARGE_INTEGER timeLargeInt = {};
|
||||||
@ -9197,19 +9184,13 @@ bool DqnFile::GetInfo(wchar_t const *path, Info *info)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::GetInfo(char const *path, Info *info)
|
bool DqnFile_GetInfo(char const *path, DqnFileInfo *info)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Logging
|
|
||||||
if (!path || !info)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
// TODO(doyle): MAX PATH is baad
|
// TODO(doyle): MAX PATH is baad
|
||||||
wchar_t widePath[MAX_PATH] = {};
|
wchar_t widePath[MAX_PATH] = {};
|
||||||
DqnWin32_UTF8ToWChar(path, widePath, DQN_ARRAY_COUNT(widePath));
|
DqnWin32_UTF8ToWChar(path, widePath, DQN_ARRAY_COUNT(widePath));
|
||||||
return DqnFile::GetInfo(widePath, info);
|
return DqnFile_GetInfo(widePath, info);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
struct stat fileStat = {};
|
struct stat fileStat = {};
|
||||||
@ -9228,66 +9209,52 @@ bool DqnFile::GetInfo(char const *path, Info *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DqnFile::Delete(char const *path)
|
bool DqnFile_Delete(char const *path)
|
||||||
{
|
{
|
||||||
if (!path) return false;
|
|
||||||
|
|
||||||
// TODO(doyle): Logging
|
|
||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
return DeleteFileA(path);
|
bool result = DeleteFileA(path);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
i32 result = unlink(path);
|
bool result = (unlink(path) == 0);
|
||||||
|
|
||||||
if (result == 0) return true;
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::Delete(wchar_t const *path)
|
bool DqnFile_Delete(wchar_t const *path)
|
||||||
{
|
{
|
||||||
if (!path) return false;
|
|
||||||
|
|
||||||
// TODO(doyle): Logging
|
|
||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
return DeleteFileW(path);
|
bool result = DeleteFileW(path);
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::Copy(char const *src, char const *dest)
|
bool DqnFile_Copy(char const *src, char const *dest)
|
||||||
{
|
{
|
||||||
if (!src || !dest) return false;
|
|
||||||
|
|
||||||
// TODO(doyle): Logging
|
// TODO(doyle): Logging
|
||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
BOOL result = (CopyFileA(src, dest, /*FailIfExist*/false) != 0);
|
BOOL result = (CopyFileA(src, dest, /*FailIfExist*/false) != 0);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
|
||||||
DqnWin32_DisplayLastError("CopyFile failed: ");
|
DqnWin32_DisplayLastError("CopyFile failed: ");
|
||||||
}
|
|
||||||
return (result != 0);
|
return (result != 0);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::Copy(wchar_t const *src, wchar_t const *dest)
|
bool DqnFile_Copy(wchar_t const *src, wchar_t const *dest)
|
||||||
{
|
{
|
||||||
if (!src || !dest) return false;
|
|
||||||
|
|
||||||
// TODO(doyle): Logging
|
// TODO(doyle): Logging
|
||||||
#if defined(DQN_IS_WIN32)
|
#if defined(DQN_IS_WIN32)
|
||||||
return (CopyFileW(src, dest, /*FailIfExist*/false) != 0);
|
BOOL result = (CopyFileW(src, dest, /*FailIfExist*/false) != 0);
|
||||||
|
if (result == 0)
|
||||||
|
DqnWin32_DisplayLastError("CopyFile failed: ");
|
||||||
|
|
||||||
|
return result;
|
||||||
#else
|
#else
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
return false;
|
return false;
|
||||||
@ -9295,13 +9262,13 @@ bool DqnFile::Copy(wchar_t const *src, wchar_t const *dest)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char **DqnFile::ListDir(char const *dir, i32 *numFiles, DqnMemAPI *api)
|
char **DqnFile_ListDir(char const *dir, i32 *numFiles, DqnMemAPI *api)
|
||||||
{
|
{
|
||||||
char **result = DqnFile__PlatformListDir(dir, numFiles, api);
|
char **result = DqnFile__PlatformListDir(dir, numFiles, api);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DqnFile::ListDirFree(char **fileList, i32 numFiles, DqnMemAPI *api)
|
void DqnFile_ListDirFree(char **fileList, i32 numFiles, DqnMemAPI *api)
|
||||||
{
|
{
|
||||||
if (fileList)
|
if (fileList)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user