Add some wide len, win32 error code display

This commit is contained in:
Doyle Thai 2017-04-20 22:43:58 +10:00
parent a4bc798a6f
commit 8d471a1502

174
dqn.h
View File

@ -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 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 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 #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_reverse (char *buf, const i32 bufSize);
DQN_FILE_SCOPE bool dqn_str_has_substring(const char *const a, const i32 lenA, 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_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_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_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 */ #endif /* DQN_WIN32 */
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -424,25 +428,28 @@ enum DqnFileAction
typedef struct DqnFile typedef struct DqnFile
{ {
void *handle; void *handle;
u64 size; size_t size;
u32 permissionFlags; u32 permissionFlags;
} DqnFile; } DqnFile;
// Open a handle to the file // Open a handle to the file
DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file, DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file,
const u32 permissionFlags, const u32 permissionFlags,
const enum DqnFileAction action); 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 // 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 u8 *const buffer,
const u32 numBytesToWrite, const size_t numBytesToWrite,
const u32 fileOffset); const size_t fileOffset);
// Return the number of bytes read // Return the number of bytes read
DQN_FILE_SCOPE u32 dqn_file_read(const DqnFile file, const u8 *const buffer, DQN_FILE_SCOPE size_t dqn_file_read(const DqnFile file, const u8 *const buffer,
const u32 numBytesToRead); const size_t numBytesToRead);
DQN_FILE_SCOPE void dqn_file_close(DqnFile *const file); 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 // Return an array of strings of the files in the directory in UTF-8. numFiles
@ -507,9 +514,10 @@ typedef struct DqnTempBuffer
} DqnTempBuffer; } DqnTempBuffer;
DQN_FILE_SCOPE bool dqn_push_buffer_init (DqnPushBuffer *buffer, size_t size, u32 alignment); 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_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_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 DqnTempBuffer dqn_push_buffer_begin_temp_region(DqnPushBuffer *buffer);
DQN_FILE_SCOPE void dqn_push_buffer_end_temp_region (DqnTempBuffer tempBuffer); 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; 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) DQN_FILE_SCOPE bool dqn_str_reverse(char *buf, const i32 bufSize)
{ {
if (!buf) return false; 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_sprintf(formattedError, "%s: %s", errorPrefix, errorMsg);
DQN_WIN32_ERROR_BOX(formattedError, NULL); 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 #endif
DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file, FILE_SCOPE bool dqn_file_open_internal(const wchar_t *const path,
const u32 permissionFlags, DqnFile *const file,
const enum DqnFileAction action) const u32 permissionFlags,
const enum DqnFileAction action)
{ {
if (!file || !path) return false; if (!file || !path) return false;
#ifdef DQN_WIN32 #ifdef DQN_WIN32
wchar_t widePath[MAX_PATH] = {};
dqn_win32_utf8_to_wchar(path, widePath, DQN_ARRAY_COUNT(widePath));
DWORD win32Permission = 0; DWORD win32Permission = 0;
if (permissionFlags & dqnfilepermissionflag_all) 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; 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); FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) 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->handle = handle;
file->size = size.QuadPart; file->size = (size_t)size.QuadPart;
file->permissionFlags = permissionFlags; file->permissionFlags = permissionFlags;
#else #else
@ -2102,10 +2143,42 @@ DQN_FILE_SCOPE bool dqn_file_open(const char *const path, DqnFile *const file,
return true; return true;
} }
DQN_FILE_SCOPE u32 dqn_file_read(const DqnFile file, const u8 *const buffer, DQN_FILE_SCOPE
const u32 numBytesToRead) 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 #ifdef DQN_WIN32
if (file.handle && buffer) 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, BOOL result = ReadFile(win32Handle, (void *)buffer, numBytesToRead,
&bytesRead, NULL); &bytesRead, NULL);
numBytesRead = (size_t)bytesRead;
// TODO(doyle): 0 also means it is completing async, but still valid // TODO(doyle): 0 also means it is completing async, but still valid
if (result == 0) if (result == 0)
{ {
DQN_WIN32_ERROR_BOX("ReadFile() failed.", NULL); DQN_WIN32_ERROR_BOX("ReadFile() failed.", NULL);
} }
numBytesRead = (u32)bytesRead;
} }
#endif #endif
return numBytesRead; return numBytesRead;
} }
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 u8 *const buffer,
const u32 numBytesToWrite, const size_t numBytesToWrite,
const u32 fileOffset) const size_t fileOffset)
{ {
u32 numBytesWritten = 0; size_t numBytesWritten = 0;
// TODO(doyle): Implement when it's needed // TODO(doyle): Implement when it's needed
DQN_ASSERT(fileOffset == 0); DQN_ASSERT(fileOffset == 0);
@ -2145,14 +2218,16 @@ DQN_FILE_SCOPE u32 dqn_file_write(const DqnFile *const file,
BOOL result = BOOL result =
WriteFile(file->handle, buffer, numBytesToWrite, &bytesWritten, NULL); WriteFile(file->handle, buffer, numBytesToWrite, &bytesWritten, NULL);
numBytesWritten = (size_t)bytesWritten;
// TODO(doyle): Better logging system // TODO(doyle): Better logging system
if (result == 0) if (result == 0)
{ {
DQN_WIN32_ERROR_BOX("ReadFile() failed.", NULL); DQN_WIN32_ERROR_BOX("ReadFile() failed.", NULL);
} }
#endif #endif
return numBytesToWrite; return numBytesWritten;
} }
@ -2188,12 +2263,34 @@ DQN_FILE_SCOPE char **dqn_dir_read(char *dir, u32 *numFiles)
return NULL; return NULL;
} }
while (FindNextFileW(findHandle, &findData) != 0) bool stayInLoop = true;
currNumFiles++; 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); FindClose(findHandle);
} }
if (currNumFiles == 0) return NULL; if (currNumFiles == 0)
{
*numFiles = 0;
return NULL;
}
{ {
WIN32_FIND_DATAW initFind = {}; 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) DQN_FILE_SCOPE bool dqn_push_buffer_init(DqnPushBuffer *buffer, size_t size, u32 alignment)
{ {
if (!buffer || size <= 0) return false; if (!buffer || size <= 0) return false;
DQN_ASSERT(!buffer->block);
buffer->block = dqn_push_buffer_alloc_block_internal(alignment, size); buffer->block = dqn_push_buffer_alloc_block_internal(alignment, size);
if (!buffer->block) return false; 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) 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); 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); size_t newBlockSize = DQN_MAX(alignedSize, buffer->block->size);
DqnPushBufferBlock *newBlock = dqn_push_buffer_alloc_block_internal( 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); 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) DQN_FILE_SCOPE DqnTempBuffer dqn_push_buffer_begin_temp_region(DqnPushBuffer *buffer)
{ {
DqnTempBuffer result = {}; DqnTempBuffer result = {};