From 8d471a1502cadad6f634427ea6d65d57472114e7 Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Thu, 20 Apr 2017 22:43:58 +1000 Subject: [PATCH] Add some wide len, win32 error code display --- dqn.h | 174 +++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 142 insertions(+), 32 deletions(-) diff --git a/dqn.h b/dqn.h index b896689..38c1e88 100644 --- a/dqn.h +++ b/dqn.h @@ -369,6 +369,9 @@ DQN_FILE_SCOPE i32 dqn_strlen (const char *a); DQN_FILE_SCOPE i32 dqn_strlen_delimit_with(const char *a, const char delimiter); DQN_FILE_SCOPE char *dqn_strncpy (char *dest, const char *src, i32 numChars); +DQN_FILE_SCOPE i32 dqn_wstrlen(const wchar_t *a); +DQN_FILE_SCOPE i32 dqn_wstrcmp(const wchar_t *a, const wchar_t *b); + #define DQN_I32_TO_STR_MAX_BUF_SIZE 11 DQN_FILE_SCOPE bool dqn_str_reverse (char *buf, const i32 bufSize); DQN_FILE_SCOPE bool dqn_str_has_substring(const char *const a, const i32 lenA, @@ -394,6 +397,7 @@ DQN_FILE_SCOPE bool dqn_win32_wchar_to_utf8 (const wchar_t *const in, char *cons DQN_FILE_SCOPE void dqn_win32_get_client_dim (const HWND window, LONG *width, LONG *height); DQN_FILE_SCOPE void dqn_win32_get_rect_dim (RECT rect, LONG *width, LONG *height); DQN_FILE_SCOPE void dqn_win32_display_last_error(const char *const errorPrefix); +DQN_FILE_SCOPE void dqn_win32_display_error_code(const DWORD error, const char *const errorPrefix); #endif /* DQN_WIN32 */ //////////////////////////////////////////////////////////////////////////////// @@ -424,25 +428,28 @@ enum DqnFileAction typedef struct DqnFile { - void *handle; - u64 size; - u32 permissionFlags; + void *handle; + size_t size; + u32 permissionFlags; } DqnFile; // Open a handle to the file DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file, const u32 permissionFlags, const enum DqnFileAction action); +DQN_FILE_SCOPE bool dqn_file_open_wide(const wchar_t *const path, DqnFile *const file, + const u32 permissionFlags, + const enum DqnFileAction action); // File offset is the byte offset to starting writing from -DQN_FILE_SCOPE u32 dqn_file_write(const DqnFile *const file, +DQN_FILE_SCOPE size_t dqn_file_write(const DqnFile *const file, const u8 *const buffer, - const u32 numBytesToWrite, - const u32 fileOffset); + const size_t numBytesToWrite, + const size_t fileOffset); // Return the number of bytes read -DQN_FILE_SCOPE u32 dqn_file_read(const DqnFile file, const u8 *const buffer, - const u32 numBytesToRead); +DQN_FILE_SCOPE size_t dqn_file_read(const DqnFile file, const u8 *const buffer, + const size_t numBytesToRead); DQN_FILE_SCOPE void dqn_file_close(DqnFile *const file); // Return an array of strings of the files in the directory in UTF-8. numFiles @@ -507,9 +514,10 @@ typedef struct DqnTempBuffer } DqnTempBuffer; -DQN_FILE_SCOPE bool dqn_push_buffer_init (DqnPushBuffer *buffer, size_t size, u32 alignment); -DQN_FILE_SCOPE void *dqn_push_buffer_allocate(DqnPushBuffer *buffer, size_t size); +DQN_FILE_SCOPE bool dqn_push_buffer_init (DqnPushBuffer *buffer, size_t size, u32 alignment); +DQN_FILE_SCOPE void *dqn_push_buffer_allocate (DqnPushBuffer *buffer, size_t size); DQN_FILE_SCOPE void dqn_push_buffer_free_last_buffer(DqnPushBuffer *buffer); +DQN_FILE_SCOPE void dqn_push_buffer_free (DqnPushBuffer *buffer); DQN_FILE_SCOPE DqnTempBuffer dqn_push_buffer_begin_temp_region(DqnPushBuffer *buffer); DQN_FILE_SCOPE void dqn_push_buffer_end_temp_region (DqnTempBuffer tempBuffer); @@ -1671,6 +1679,30 @@ DQN_FILE_SCOPE char *dqn_strncpy(char *dest, const char *src, i32 numChars) return dest; } +DQN_FILE_SCOPE i32 dqn_wstrlen(const wchar_t *a) +{ + i32 result = 0; + while (a && a[result]) result++; + return result; +} + +DQN_FILE_SCOPE i32 dqn_wstrcmp(const wchar_t *a, const wchar_t *b) +{ + if (!a && !b) return -1; + if (!a) return -1; + if (!b) return -1; + + while ((*a) == (*b)) + { + if (!(*a)) return 0; + a++; + b++; + } + + return (((*a) < (*b)) ? -1 : 1); +} + + DQN_FILE_SCOPE bool dqn_str_reverse(char *buf, const i32 bufSize) { if (!buf) return false; @@ -2042,18 +2074,27 @@ DQN_FILE_SCOPE void dqn_win32_display_last_error(const char *const errorPrefix) dqn_sprintf(formattedError, "%s: %s", errorPrefix, errorMsg); DQN_WIN32_ERROR_BOX(formattedError, NULL); } + +DQN_FILE_SCOPE void dqn_win32_display_error_code(const DWORD error, const char *const errorPrefix) +{ + char errorMsg[1024] = {}; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error, 0, errorMsg, DQN_ARRAY_COUNT(errorMsg), NULL); + + char formattedError[2048] = {}; + dqn_sprintf(formattedError, "%s: %s", errorPrefix, errorMsg); + DQN_WIN32_ERROR_BOX(formattedError, NULL); +} #endif -DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file, - const u32 permissionFlags, - const enum DqnFileAction action) +FILE_SCOPE bool dqn_file_open_internal(const wchar_t *const path, + DqnFile *const file, + const u32 permissionFlags, + const enum DqnFileAction action) { if (!file || !path) return false; #ifdef DQN_WIN32 - wchar_t widePath[MAX_PATH] = {}; - dqn_win32_utf8_to_wchar(path, widePath, DQN_ARRAY_COUNT(widePath)); - DWORD win32Permission = 0; if (permissionFlags & dqnfilepermissionflag_all) { @@ -2076,7 +2117,7 @@ DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file, case dqnfileaction_create_if_not_exist: win32Action = CREATE_NEW; break; } - HANDLE handle = CreateFileW(widePath, win32Permission, 0, NULL, win32Action, + HANDLE handle = CreateFileW(path, win32Permission, 0, NULL, win32Action, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) @@ -2092,7 +2133,7 @@ DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file, } file->handle = handle; - file->size = size.QuadPart; + file->size = (size_t)size.QuadPart; file->permissionFlags = permissionFlags; #else @@ -2102,10 +2143,42 @@ DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file, return true; } -DQN_FILE_SCOPE u32 dqn_file_read(const DqnFile file, const u8 *const buffer, - const u32 numBytesToRead) +DQN_FILE_SCOPE +bool dqn_file_open_wide(const wchar_t *const path, DqnFile *const file, + const u32 permissionFlags, + const enum DqnFileAction action) { - u32 numBytesRead = 0; + if (!file || !path) return false; +#ifdef DQN_WIN32 + dqn_file_open_internal(path, file, permissionFlags, action); +#else + return false; +#endif + + return true; +} + +DQN_FILE_SCOPE +bool dqn_file_open(const char *const path, DqnFile *const file, + const u32 permissionFlags, const enum DqnFileAction action) +{ + if (!file || !path) return false; + +#ifdef DQN_WIN32 + wchar_t widePath[MAX_PATH] = {}; + dqn_win32_utf8_to_wchar(path, widePath, DQN_ARRAY_COUNT(widePath)); + dqn_file_open_internal(widePath, file, permissionFlags, action); +#else + return false; +#endif + + return true; +} + +DQN_FILE_SCOPE size_t dqn_file_read(const DqnFile file, const u8 *const buffer, + const size_t numBytesToRead) +{ + size_t numBytesRead = 0; #ifdef DQN_WIN32 if (file.handle && buffer) { @@ -2115,24 +2188,24 @@ DQN_FILE_SCOPE u32 dqn_file_read(const DqnFile file, const u8 *const buffer, BOOL result = ReadFile(win32Handle, (void *)buffer, numBytesToRead, &bytesRead, NULL); + numBytesRead = (size_t)bytesRead; // TODO(doyle): 0 also means it is completing async, but still valid if (result == 0) { DQN_WIN32_ERROR_BOX("ReadFile() failed.", NULL); } - numBytesRead = (u32)bytesRead; } #endif return numBytesRead; } -DQN_FILE_SCOPE u32 dqn_file_write(const DqnFile *const file, - const u8 *const buffer, - const u32 numBytesToWrite, - const u32 fileOffset) +DQN_FILE_SCOPE size_t dqn_file_write(const DqnFile *const file, + const u8 *const buffer, + const size_t numBytesToWrite, + const size_t fileOffset) { - u32 numBytesWritten = 0; + size_t numBytesWritten = 0; // TODO(doyle): Implement when it's needed DQN_ASSERT(fileOffset == 0); @@ -2145,14 +2218,16 @@ DQN_FILE_SCOPE u32 dqn_file_write(const DqnFile *const file, BOOL result = WriteFile(file->handle, buffer, numBytesToWrite, &bytesWritten, NULL); + numBytesWritten = (size_t)bytesWritten; // TODO(doyle): Better logging system if (result == 0) { DQN_WIN32_ERROR_BOX("ReadFile() failed.", NULL); } + #endif - return numBytesToWrite; + return numBytesWritten; } @@ -2188,12 +2263,34 @@ DQN_FILE_SCOPE char **dqn_dir_read(char *dir, u32 *numFiles) return NULL; } - while (FindNextFileW(findHandle, &findData) != 0) - currNumFiles++; + bool stayInLoop = true; + while (stayInLoop) + { + BOOL result = FindNextFileW(findHandle, &findData); + if (result == 0) + { + DWORD error = GetLastError(); + if (error != ERROR_NO_MORE_FILES) + { + dqn_win32_display_error_code(error, + "FindNextFileW() failed"); + } + + stayInLoop = false; + } + else + { + currNumFiles++; + } + } FindClose(findHandle); } - if (currNumFiles == 0) return NULL; + if (currNumFiles == 0) + { + *numFiles = 0; + return NULL; + } { WIN32_FIND_DATAW initFind = {}; @@ -2400,6 +2497,7 @@ dqn_push_buffer_alloc_block_internal(u32 alignment, size_t size) DQN_FILE_SCOPE bool dqn_push_buffer_init(DqnPushBuffer *buffer, size_t size, u32 alignment) { if (!buffer || size <= 0) return false; + DQN_ASSERT(!buffer->block); buffer->block = dqn_push_buffer_alloc_block_internal(alignment, size); if (!buffer->block) return false; @@ -2411,8 +2509,11 @@ DQN_FILE_SCOPE bool dqn_push_buffer_init(DqnPushBuffer *buffer, size_t size, u32 DQN_FILE_SCOPE void *dqn_push_buffer_allocate(DqnPushBuffer *buffer, size_t size) { + if (!buffer || size == 0) return NULL; + size_t alignedSize = dqn_size_alignment_internal(buffer->alignment, size); - if ((buffer->block->used + alignedSize) > buffer->block->size) + if (!buffer->block || + (buffer->block->used + alignedSize) > buffer->block->size) { size_t newBlockSize = DQN_MAX(alignedSize, buffer->block->size); DqnPushBufferBlock *newBlock = dqn_push_buffer_alloc_block_internal( @@ -2443,6 +2544,15 @@ DQN_FILE_SCOPE void dqn_push_buffer_free_last_buffer(DqnPushBuffer *buffer) if (!buffer->block) DQN_ASSERT(buffer->tempBufferCount == 0); } +DQN_FILE_SCOPE void dqn_push_buffer_free(DqnPushBuffer *buffer) +{ + if (!buffer) return; + while (buffer->block) + { + dqn_push_buffer_free_last_buffer(buffer); + } +} + DQN_FILE_SCOPE DqnTempBuffer dqn_push_buffer_begin_temp_region(DqnPushBuffer *buffer) { DqnTempBuffer result = {};