Add some wide len, win32 error code display
This commit is contained in:
parent
a4bc798a6f
commit
8d471a1502
174
dqn.h
174
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 = {};
|
||||
|
Loading…
Reference in New Issue
Block a user