Add wchar operations

This commit is contained in:
Doyle Thai 2017-04-25 17:37:40 +10:00
parent 8d471a1502
commit c3ebef2ea1

190
dqn.h
View File

@ -355,7 +355,7 @@ DQN_FILE_SCOPE DqnRect dqn_rect_move (DqnRect rect, DqnV2 shift);
DQN_FILE_SCOPE bool dqn_rect_contains_p (DqnRect rect, DqnV2 p); DQN_FILE_SCOPE bool dqn_rect_contains_p (DqnRect rect, DqnV2 p);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// String Ops // char String Operations
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE char dqn_char_to_lower (char c); DQN_FILE_SCOPE char dqn_char_to_lower (char c);
DQN_FILE_SCOPE char dqn_char_to_upper (char c); DQN_FILE_SCOPE char dqn_char_to_upper (char c);
@ -369,9 +369,6 @@ 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,
@ -385,6 +382,20 @@ DQN_FILE_SCOPE i32 dqn_i32_to_str(i32 value, char *buf, i32 bufSize);
DQN_FILE_SCOPE u32 dqn_ucs_to_utf8(u32 *dest, u32 character); DQN_FILE_SCOPE u32 dqn_ucs_to_utf8(u32 *dest, u32 character);
DQN_FILE_SCOPE u32 dqn_utf8_to_ucs(u32 *dest, u32 character); DQN_FILE_SCOPE u32 dqn_utf8_to_ucs(u32 *dest, u32 character);
////////////////////////////////////////////////////////////////////////////////
// wchar String Operations
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE bool dqn_wchar_is_digit(const wchar_t c);
DQN_FILE_SCOPE wchar_t dqn_wchar_to_lower(const wchar_t c);
DQN_FILE_SCOPE i32 dqn_wstrlen (const wchar_t *a);
DQN_FILE_SCOPE i32 dqn_wstrcmp (const wchar_t *a, const wchar_t *b);
DQN_FILE_SCOPE bool dqn_wstr_reverse (wchar_t *buf, const i32 bufSize);
DQN_FILE_SCOPE i32 dqn_wstr_to_i32 (const wchar_t *const buf, const i32 bufSize);
DQN_FILE_SCOPE i32 dqn_i32_to_wstr (i32 value, wchar_t *buf, i32 bufSize);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Win32 Specific // Win32 Specific
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -437,7 +448,7 @@ typedef struct DqnFile
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, DQN_FILE_SCOPE bool dqn_file_openw(const wchar_t *const path, DqnFile *const file,
const u32 permissionFlags, const u32 permissionFlags,
const enum DqnFileAction action); const enum DqnFileAction action);
@ -840,8 +851,7 @@ dqn_ini_property_add
void dqn_ini_property_add( DqnIni* ini, int section, char const* name, int name_length, char const* value, int value_length ) void dqn_ini_property_add( DqnIni* ini, int section, char const* name, int name_length, char const* value, int value_length )
Adds a property with the specified name and value to the specified section, and Adds a property with the specified name and value to the specified section, and returns the index it was added at. There is no check done to see if a property
returns the index it was added at. There is no check done to see if a property
with the specified name already exists - multiple properties of the same name with the specified name already exists - multiple properties of the same name
are allowed. `name_length` and `value_length` specifies the number of characters are allowed. `name_length` and `value_length` specifies the number of characters
in `name` and `value`, which does not have to be zero-terminated. If in `name` and `value`, which does not have to be zero-terminated. If
@ -1594,7 +1604,7 @@ DQN_FILE_SCOPE bool dqn_rect_contains_p(DqnRect rect, DqnV2 p)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// String Operations // char String Operations
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE char dqn_char_to_lower(char c) DQN_FILE_SCOPE char dqn_char_to_lower(char c)
{ {
@ -1679,30 +1689,6 @@ 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;
@ -2013,6 +1999,137 @@ DQN_FILE_SCOPE u32 dqn_utf8_to_ucs(u32 *dest, u32 character)
return 0; return 0;
} }
////////////////////////////////////////////////////////////////////////////////
// wchar String Operations
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE bool dqn_wchar_is_digit(const wchar_t c)
{
if (c >= L'0' && c <= L'9') return true;
return false;
}
DQN_FILE_SCOPE wchar_t dqn_wchar_to_lower(const wchar_t c)
{
if (c >= L'A' && c <= L'Z')
{
i32 shiftOffset = L'a' - L'A';
return (c + (wchar_t)shiftOffset);
}
return c;
}
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_wstr_reverse(wchar_t *buf, const i32 bufSize)
{
if (!buf) return false;
i32 mid = bufSize / 2;
for (i32 i = 0; i < mid; i++)
{
wchar_t tmp = buf[i];
buf[i] = buf[(bufSize - 1) - i];
buf[(bufSize - 1) - i] = tmp;
}
return true;
}
DQN_FILE_SCOPE i32 dqn_wstr_to_i32(const wchar_t *const buf, const i32 bufSize)
{
if (!buf || bufSize == 0) return 0;
i32 index = 0;
bool isNegative = false;
if (buf[index] == L'-' || buf[index] == L'+')
{
if (buf[index] == L'-') isNegative = true;
index++;
}
else if (!dqn_wchar_is_digit(buf[index]))
{
return 0;
}
i32 result = 0;
for (i32 i = index; i < bufSize; i++)
{
if (dqn_wchar_is_digit(buf[i]))
{
result *= 10;
result += (buf[i] - L'0');
}
else
{
break;
}
}
if (isNegative) result *= -1;
return result;
}
DQN_FILE_SCOPE i32 dqn_i32_to_wstr(i32 value, wchar_t *buf, i32 bufSize)
{
if (!buf || bufSize == 0) return 0;
if (value == 0)
{
buf[0] = L'0';
return 0;
}
// NOTE(doyle): Max 32bit integer (+-)2147483647
i32 charIndex = 0;
bool negative = false;
if (value < 0) negative = true;
if (negative) buf[charIndex++] = L'-';
i32 val = DQN_ABS(value);
while (val != 0 && charIndex < bufSize)
{
i32 rem = val % 10;
buf[charIndex++] = (u8)rem + '0';
val /= 10;
}
// NOTE(doyle): If string is negative, we only want to reverse starting
// from the second character, so we don't put the negative sign at the end
if (negative)
{
dqn_wstr_reverse(buf + 1, charIndex - 1);
}
else
{
dqn_wstr_reverse(buf, charIndex);
}
return charIndex;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// File Operations // File Operations
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -2144,18 +2261,15 @@ FILE_SCOPE bool dqn_file_open_internal(const wchar_t *const path,
} }
DQN_FILE_SCOPE DQN_FILE_SCOPE
bool dqn_file_open_wide(const wchar_t *const path, DqnFile *const file, bool dqn_file_openw(const wchar_t *const path, DqnFile *const file,
const u32 permissionFlags, const u32 permissionFlags, const enum DqnFileAction action)
const enum DqnFileAction action)
{ {
if (!file || !path) return false; if (!file || !path) return false;
#ifdef DQN_WIN32 #ifdef DQN_WIN32
dqn_file_open_internal(path, file, permissionFlags, action); return dqn_file_open_internal(path, file, permissionFlags, action);
#else #else
return false; return false;
#endif #endif
return true;
} }
DQN_FILE_SCOPE DQN_FILE_SCOPE