diff --git a/DqnUnitTest.cpp b/DqnUnitTest.cpp index 43c226c..de311b5 100644 --- a/DqnUnitTest.cpp +++ b/DqnUnitTest.cpp @@ -1697,9 +1697,8 @@ void DqnFile_Test() } DqnFile file = {}; - DQN_ASSERT(file.Open(".clang-format", - (DqnFile::Permission::FileWrite | DqnFile::Permission::FileRead), - DqnFile::Action::OpenOnly)); + DQN_ASSERT(file.Open( + ".clang-format", DqnFile::Flag::FileReadWrite, DqnFile::Action::OpenOnly)); DQN_ASSERTM(file.size == expectedSize, "DqnFileOpen() failed: file.size: %d, expected:%d\n", file.size, @@ -1715,9 +1714,8 @@ void DqnFile_Test() if (1) { DqnSmartFile raiiFile = {}; - if (raiiFile.Open(FILE_TO_OPEN, - DqnFile::Permission::FileWrite | DqnFile::Permission::FileRead, - DqnFile::Action::OpenOnly)) + if (raiiFile.Open( + FILE_TO_OPEN, DqnFile::Flag::FileReadWrite, DqnFile::Action::OpenOnly)) { i32 breakHereToTestRaii = 0; (void)breakHereToTestRaii; @@ -1731,9 +1729,8 @@ void DqnFile_Test() if (1) { DqnFile file = {}; - DQN_ASSERT(!file.Open("asdljasdnel;kajdf", (DqnFile::Permission::FileWrite | - DqnFile::Permission::FileRead), - DqnFile::Action::OpenOnly)); + DQN_ASSERT(!file.Open( + "asdljasdnel;kajdf", DqnFile::Flag::FileReadWrite, DqnFile::Action::OpenOnly)); DQN_ASSERT(file.size == 0); DQN_ASSERT(file.flags == 0); DQN_ASSERT(!file.handle); @@ -1751,8 +1748,8 @@ void DqnFile_Test() // Write data out to some files for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++) { - u32 permissions = DqnFile::Permission::FileRead | DqnFile::Permission::FileWrite; - DqnFile *file = files + i; + u32 permissions = DqnFile::Flag::FileReadWrite; + DqnFile *file = files + i; if (!file->Open(fileNames[i], permissions, DqnFile::Action::ClearIfExist)) { bool result = @@ -1773,7 +1770,7 @@ void DqnFile_Test() { // Manual read the file contents { - u32 permissions = DqnFile::Permission::FileRead; + u32 permissions = DqnFile::Flag::FileRead; DqnFile *file = files + i; bool result = file->Open(fileNames[i], permissions, DqnFile::Action::OpenOnly); DQN_ASSERT(result); @@ -1816,7 +1813,7 @@ void DqnFile_Test() for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++) { DqnFile dummy = {}; - u32 permissions = DqnFile::Permission::FileRead; + u32 permissions = DqnFile::Flag::FileRead; bool fileExists = dummy.Open(fileNames[i], permissions, DqnFile::Action::OpenOnly); DQN_ASSERT(!fileExists); } @@ -2357,10 +2354,9 @@ void DqnCatalog_Test() // Write file A and check we are able to open it up in the catalog { - DQN_ASSERTM(file.Open(testFile.str, - DqnFile::Permission::FileRead | DqnFile::Permission::FileWrite, - DqnFile::Action::ForceCreate), - "Could not create testing file for DqnCatalog"); + DQN_ASSERTM( + file.Open(testFile.str, DqnFile::Flag::FileReadWrite, DqnFile::Action::ForceCreate), + "Could not create testing file for DqnCatalog"); file.Write(reinterpret_cast(bufA), DQN_CHAR_COUNT(bufA), 0); file.Close(); @@ -2372,10 +2368,9 @@ void DqnCatalog_Test() // Write file B check that it has been updated { file = {}; - DQN_ASSERTM(file.Open(testFile.str, - DqnFile::Permission::FileRead | DqnFile::Permission::FileWrite, - DqnFile::Action::ForceCreate), - "Could not create testing file for DqnCatalog"); + DQN_ASSERTM( + file.Open(testFile.str, DqnFile::Flag::FileReadWrite, DqnFile::Action::ForceCreate), + "Could not create testing file for DqnCatalog"); file.Write(reinterpret_cast(bufX), DQN_CHAR_COUNT(bufX), 0); file.Close(); diff --git a/dqn.h b/dqn.h index a8c50ac..40db474 100644 --- a/dqn.h +++ b/dqn.h @@ -2838,12 +2838,13 @@ DQN_VHASH_TABLE_TEMPLATE void DQN_VHASH_TABLE_DECL::Erase(Key const &key) // ================================================================================================= struct DqnFile { - enum Permission + enum Flag { - FileRead = (1 << 0), - FileWrite = (1 << 1), - Execute = (1 << 2), - All = (1 << 3) + FileRead = (1 << 0), + FileWrite = (1 << 1), + Execute = (1 << 2), + All = (1 << 3), + FileReadWrite = FileRead | FileWrite }; enum struct Action @@ -2864,7 +2865,7 @@ struct DqnFile // Open a handle for file read and writing. Deleting files does not need a handle. Handles should be // closed before deleting files otherwise the OS may not be able to delete the file. - // return: FALSE if invalid args or failed to get handle (i.e. insufficient permissions) + // return: FALSE if invalid args or failed to get handle (i.e. insufficient permission) bool Open(char const *path, u32 const flags_, Action const action); bool Open(wchar_t const *path, u32 const flags_, Action const action); @@ -2900,6 +2901,9 @@ DQN_FILE_SCOPE bool DqnFile_ReadAll(wchar_t const *path, u8 *buf, usize const 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); +DQN_FILE_SCOPE bool DqnFile_WriteAll(char const *path, u8 const *buf, usize const bufSize); +DQN_FILE_SCOPE bool DqnFile_WriteAll(wchar_t const *path, u8 const *buf, usize const bufSize); + // 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); @@ -8484,16 +8488,16 @@ DqnFile__Win32Open(wchar_t const *path, DqnFile *file, u32 flags, DqnFile::Actio u32 const WIN32_FILE_ATTRIBUTE_NORMAL = 0x00000080; - DWORD win32Permission = 0; - if (flags & DqnFile::Permission::All) + DWORD win32Flag = 0; + if (flags & DqnFile::Flag::All) { - win32Permission = WIN32_GENERIC_ALL; + win32Flag = WIN32_GENERIC_ALL; } else { - if (flags & DqnFile::Permission::FileRead) win32Permission |= WIN32_GENERIC_READ; - if (flags & DqnFile::Permission::FileWrite) win32Permission |= WIN32_GENERIC_WRITE; - if (flags & DqnFile::Permission::Execute) win32Permission |= WIN32_GENERIC_EXECUTE; + if (flags & DqnFile::Flag::FileRead) win32Flag |= WIN32_GENERIC_READ; + if (flags & DqnFile::Flag::FileWrite) win32Flag |= WIN32_GENERIC_WRITE; + if (flags & DqnFile::Flag::Execute) win32Flag |= WIN32_GENERIC_EXECUTE; } DWORD win32Action = 0; @@ -8507,7 +8511,7 @@ DqnFile__Win32Open(wchar_t const *path, DqnFile *file, u32 flags, DqnFile::Actio case DqnFile::Action::ForceCreate: win32Action = WIN32_CREATE_ALWAYS; break; } - HANDLE handle = CreateFileW(path, win32Permission, 0, nullptr, win32Action, + HANDLE handle = CreateFileW(path, win32Flag, 0, nullptr, win32Action, WIN32_FILE_ATTRIBUTE_NORMAL, nullptr); if (handle == INVALID_HANDLE_VALUE) @@ -8656,7 +8660,7 @@ DqnFile__UnixOpen(char const *path, DqnFile *file, u32 flags, DqnFile::Action ac char operation = 0; bool updateFlag = false; - if (flags & DqnFile::Permission::FileWrite) + if (flags & DqnFile::Flag::FileWrite) { updateFlag = true; switch (action) @@ -8677,10 +8681,10 @@ DqnFile__UnixOpen(char const *path, DqnFile *file, u32 flags, DqnFile::Action ac break; } } - else if ((flags & DqnFile::Permission::FileRead) || - (flags & DqnFile::Permission::Execute)) + else if ((flags & DqnFile::Flag::FileRead) || + (flags & DqnFile::Flag::Execute)) { - if (flags & DqnFile::Permission::Execute) + if (flags & DqnFile::Flag::Execute) { // TODO(doyle): Logging, UNIX doesn't have execute param for file // handles. Execution goes through system() @@ -8924,10 +8928,50 @@ u8 *DqnFile_ReadAll(char const *path, usize *bufSize, DqnMemAPI *api) return nullptr; } +DQN_FILE_SCOPE bool DqnFile_WriteAll(char const *path, u8 const *buf, usize const bufSize) +{ + DqnFile file = {}; + if (!file.Open(path, DqnFile::Flag::FileReadWrite, DqnFile::Action::ForceCreate)) + { + DQN_LOGE("Could not open file at: %s", path); + return false; + } + + DQN_DEFER(file.Close()); + usize bytesWritten = file.Write(buf, bufSize, 0); + if (bytesWritten != bufSize) + { + DQN_LOGE("Bytes written did not match the buffer size, %zu != %zu", bytesWritten, bufSize); + return false; + } + + return true; +} + +DQN_FILE_SCOPE bool DqnFile_WriteAll(wchar_t const *path, u8 const *buf, usize const bufSize) +{ + DqnFile file = {}; + if (!file.Open(path, DqnFile::Flag::FileReadWrite, DqnFile::Action::ForceCreate)) + { + DQN_LOGE("Could not open file at: %s", path); + return false; + } + + DQN_DEFER(file.Close()); + usize bytesWritten = file.Write(buf, bufSize, 0); + if (bytesWritten != bufSize) + { + DQN_LOGE("Bytes written did not match the buffer size, %zu != %zu", bytesWritten, bufSize); + return false; + } + + return true; +} + bool DqnFile_ReadAll(wchar_t const *path, u8 *buf, usize bufSize, usize *bytesRead) { DqnFile file = {}; - bool result = file.Open(path, DqnFile::Permission::FileRead, DqnFile::Action::OpenOnly); + bool result = file.Open(path, DqnFile::Flag::FileRead, DqnFile::Action::OpenOnly); DQN_DEFER(file.Close()); // TODO(doyle): Logging @@ -8945,7 +8989,7 @@ bool DqnFile_ReadAll(wchar_t const *path, u8 *buf, usize bufSize, usize *bytesRe bool DqnFile_ReadAll(const char *path, u8 *buf, usize bufSize, usize *bytesRead) { DqnFile file = {}; - bool result = file.Open(path, DqnFile::Permission::FileRead, DqnFile::Action::OpenOnly); + bool result = file.Open(path, DqnFile::Flag::FileRead, DqnFile::Action::OpenOnly); DQN_DEFER(file.Close()); if (!result || file.size > bufSize)