dqn: Add improved binary split and find routines for strings
This commit is contained in:
parent
eac4eaefe1
commit
807c65a253
244
dqn.h
244
dqn.h
@ -935,9 +935,6 @@ DQN_API Dqn_usize Dqn_CString16_Size (wcha
|
|||||||
// @param[in] size The size of the slice
|
// @param[in] size The size of the slice
|
||||||
// @return The sliced string
|
// @return The sliced string
|
||||||
|
|
||||||
// @proc Dqn_String8_BinarySplitStringChars
|
|
||||||
// @desc TODO(doyle): Write description
|
|
||||||
|
|
||||||
// @proc Dqn_String8_BinarySplit
|
// @proc Dqn_String8_BinarySplit
|
||||||
// @desc Split a string into the substring occuring prior and after the first
|
// @desc Split a string into the substring occuring prior and after the first
|
||||||
// occurence of the `delimiter`. Neither strings include the `delimiter`.
|
// occurence of the `delimiter`. Neither strings include the `delimiter`.
|
||||||
@ -1129,6 +1126,20 @@ struct Dqn_String16 /// A pointer and length style string that holds slices to U
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Dqn_String8BinarySplitResult
|
||||||
|
{
|
||||||
|
Dqn_String8 lhs;
|
||||||
|
Dqn_String8 rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Dqn_String8FindResult
|
||||||
|
{
|
||||||
|
bool found;
|
||||||
|
Dqn_usize index;
|
||||||
|
Dqn_String8 match;
|
||||||
|
Dqn_String8 match_to_end_of_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: Macros ====================================================================================
|
// NOTE: Macros ====================================================================================
|
||||||
#define DQN_STRING8(string) Dqn_String8{(char *)(string), sizeof(string) - 1}
|
#define DQN_STRING8(string) Dqn_String8{(char *)(string), sizeof(string) - 1}
|
||||||
#define DQN_STRING16(string) Dqn_String16{(wchar_t *)(string), (sizeof(string)/sizeof(string[0])) - 1}
|
#define DQN_STRING16(string) Dqn_String16{(wchar_t *)(string), (sizeof(string)/sizeof(string[0])) - 1}
|
||||||
@ -1159,51 +1170,56 @@ enum Dqn_String8EqCase
|
|||||||
Dqn_String8EqCase_Insensitive,
|
Dqn_String8EqCase_Insensitive,
|
||||||
};
|
};
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_InitCString8 (char const *src);
|
enum Dqn_String8FindFlag
|
||||||
DQN_API bool Dqn_String8_IsValid (Dqn_String8 string);
|
|
||||||
DQN_API bool Dqn_String8_IsAll (Dqn_String8 string, Dqn_String8IsAll is_all);
|
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_Slice (Dqn_String8 string, Dqn_usize offset, Dqn_usize size);
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_BinarySplitStringChars(Dqn_String8 string, Dqn_String8 delimiter_chars, Dqn_String8 *rhs);
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_BinarySplit (Dqn_String8 string, char delimiter, Dqn_String8 *rhs);
|
|
||||||
DQN_API Dqn_usize Dqn_String8_Split (Dqn_String8 string, Dqn_String8 delimiter, Dqn_String8 *splits, Dqn_usize splits_count);
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_Segment (Dqn_Allocator allocator, Dqn_String8 src, Dqn_usize segment_size, char segment_char);
|
|
||||||
|
|
||||||
DQN_API bool Dqn_String8_Eq (Dqn_String8 lhs, Dqn_String8 rhs, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
|
||||||
DQN_API bool Dqn_String8_EqInsensitive (Dqn_String8 lhs, Dqn_String8 rhs);
|
|
||||||
DQN_API bool Dqn_String8_StartsWith (Dqn_String8 string, Dqn_String8 prefix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
|
||||||
DQN_API bool Dqn_String8_StartsWithInsensitive (Dqn_String8 string, Dqn_String8 prefix);
|
|
||||||
DQN_API bool Dqn_String8_EndsWith (Dqn_String8 string, Dqn_String8 prefix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
|
||||||
DQN_API bool Dqn_String8_EndsWithInsensitive (Dqn_String8 string, Dqn_String8 prefix);
|
|
||||||
DQN_API bool Dqn_String8_HasChar (Dqn_String8 string, char ch);
|
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_TrimPrefix (Dqn_String8 string, Dqn_String8 prefix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_TrimSuffix (Dqn_String8 string, Dqn_String8 suffix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_TrimWhitespaceAround (Dqn_String8 string);
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_TrimByteOrderMark (Dqn_String8 string);
|
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_FileNameFromPath (Dqn_String8 path);
|
|
||||||
|
|
||||||
DQN_API bool Dqn_String8_ToU64Checked (Dqn_String8 string, char separator, uint64_t *output);
|
|
||||||
DQN_API uint64_t Dqn_String8_ToU64 (Dqn_String8 string, char separator);
|
|
||||||
DQN_API bool Dqn_String8_ToI64Checked (Dqn_String8 string, char separator, int64_t *output);
|
|
||||||
DQN_API int64_t Dqn_String8_ToI64 (Dqn_String8 string, char separator);
|
|
||||||
|
|
||||||
struct Dqn_String8FindResult
|
|
||||||
{
|
{
|
||||||
bool found;
|
Dqn_String8FindFlag_Digit = 1 << 0, // 0-9
|
||||||
Dqn_usize offset;
|
Dqn_String8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' '
|
||||||
Dqn_String8 string;
|
Dqn_String8FindFlag_Alphabet = 1 << 2, // A-Z, a-z
|
||||||
|
Dqn_String8FindFlag_Plus = 1 << 3, // +
|
||||||
|
Dqn_String8FindFlag_Minus = 1 << 4, // -
|
||||||
|
Dqn_String8FindFlag_AlphaNum = Dqn_String8FindFlag_Alphabet | Dqn_String8FindFlag_Digit,
|
||||||
};
|
};
|
||||||
|
|
||||||
DQN_API Dqn_String8FindResult Dqn_String8_Find (Dqn_String8 string, Dqn_String8 find, Dqn_usize start_index, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
DQN_API Dqn_String8 Dqn_String8_InitCString8 (char const *src);
|
||||||
DQN_API Dqn_String8 Dqn_String8_Replace (Dqn_String8 string, Dqn_String8 find, Dqn_String8 replace, Dqn_usize start_index, Dqn_Allocator allocator, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
DQN_API bool Dqn_String8_IsValid (Dqn_String8 string);
|
||||||
DQN_API Dqn_String8 Dqn_String8_ReplaceInsensitive (Dqn_String8 string, Dqn_String8 find, Dqn_String8 replace, Dqn_usize start_index, Dqn_Allocator allocator);
|
DQN_API bool Dqn_String8_IsAll (Dqn_String8 string, Dqn_String8IsAll is_all);
|
||||||
DQN_API void Dqn_String8_Remove (Dqn_String8 *string, Dqn_usize offset, Dqn_usize size);
|
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_Slice (Dqn_String8 string, Dqn_usize offset, Dqn_usize size);
|
||||||
|
DQN_API Dqn_String8BinarySplitResult Dqn_String8_BinarySplitArray (Dqn_String8 string, Dqn_String8 const *find, Dqn_usize find_size);
|
||||||
|
DQN_API Dqn_String8BinarySplitResult Dqn_String8_BinarySplit (Dqn_String8 string, Dqn_String8 find);
|
||||||
|
DQN_API Dqn_usize Dqn_String8_Split (Dqn_String8 string, Dqn_String8 delimiter, Dqn_String8 *splits, Dqn_usize splits_count);
|
||||||
|
DQN_API Dqn_String8FindResult Dqn_String8_FindFirstStringArray (Dqn_String8 string, Dqn_String8 const *find, Dqn_usize find_size);
|
||||||
|
DQN_API Dqn_String8FindResult Dqn_String8_FindFirstString (Dqn_String8 string, Dqn_String8 find);
|
||||||
|
DQN_API Dqn_String8FindResult Dqn_String8_FindFirst (Dqn_String8 string, uint32_t flags);
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_Segment (Dqn_Allocator allocator, Dqn_String8 src, Dqn_usize segment_size, char segment_char);
|
||||||
|
|
||||||
|
DQN_API bool Dqn_String8_Eq (Dqn_String8 lhs, Dqn_String8 rhs, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
||||||
|
DQN_API bool Dqn_String8_EqInsensitive (Dqn_String8 lhs, Dqn_String8 rhs);
|
||||||
|
DQN_API bool Dqn_String8_StartsWith (Dqn_String8 string, Dqn_String8 prefix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
||||||
|
DQN_API bool Dqn_String8_StartsWithInsensitive (Dqn_String8 string, Dqn_String8 prefix);
|
||||||
|
DQN_API bool Dqn_String8_EndsWith (Dqn_String8 string, Dqn_String8 prefix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
||||||
|
DQN_API bool Dqn_String8_EndsWithInsensitive (Dqn_String8 string, Dqn_String8 prefix);
|
||||||
|
DQN_API bool Dqn_String8_HasChar (Dqn_String8 string, char ch);
|
||||||
|
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_TrimPrefix (Dqn_String8 string, Dqn_String8 prefix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_TrimSuffix (Dqn_String8 string, Dqn_String8 suffix, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_TrimWhitespaceAround (Dqn_String8 string);
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_TrimByteOrderMark (Dqn_String8 string);
|
||||||
|
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_FileNameFromPath (Dqn_String8 path);
|
||||||
|
|
||||||
|
DQN_API bool Dqn_String8_ToU64Checked (Dqn_String8 string, char separator, uint64_t *output);
|
||||||
|
DQN_API uint64_t Dqn_String8_ToU64 (Dqn_String8 string, char separator);
|
||||||
|
DQN_API bool Dqn_String8_ToI64Checked (Dqn_String8 string, char separator, int64_t *output);
|
||||||
|
DQN_API int64_t Dqn_String8_ToI64 (Dqn_String8 string, char separator);
|
||||||
|
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_Replace (Dqn_String8 string, Dqn_String8 find, Dqn_String8 replace, Dqn_usize start_index, Dqn_Allocator allocator, Dqn_String8EqCase eq_case = Dqn_String8EqCase_Sensitive);
|
||||||
|
DQN_API Dqn_String8 Dqn_String8_ReplaceInsensitive (Dqn_String8 string, Dqn_String8 find, Dqn_String8 replace, Dqn_usize start_index, Dqn_Allocator allocator);
|
||||||
|
DQN_API void Dqn_String8_Remove (Dqn_String8 *string, Dqn_usize offset, Dqn_usize size);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
DQN_API bool operator== (Dqn_String8 const &lhs, Dqn_String8 const &rhs);
|
DQN_API bool operator== (Dqn_String8 const &lhs, Dqn_String8 const &rhs);
|
||||||
DQN_API bool operator!= (Dqn_String8 const &lhs, Dqn_String8 const &rhs);
|
DQN_API bool operator!= (Dqn_String8 const &lhs, Dqn_String8 const &rhs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE: Internal ==================================================================================
|
// NOTE: Internal ==================================================================================
|
||||||
@ -2714,7 +2730,7 @@ DQN_API uint64_t Dqn_Safe_SaturateCastIntToU64(int val);
|
|||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
// [$CHAR] Dqn_Char | | Character ascii/digit.. helpers
|
// [$CHAR] Dqn_Char | | Character ascii/digit.. helpers
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
DQN_API bool Dqn_Char_IsAlpha (char ch);
|
DQN_API bool Dqn_Char_IsAlphabet (char ch);
|
||||||
DQN_API bool Dqn_Char_IsDigit (char ch);
|
DQN_API bool Dqn_Char_IsDigit (char ch);
|
||||||
DQN_API bool Dqn_Char_IsAlphaNum (char ch);
|
DQN_API bool Dqn_Char_IsAlphaNum (char ch);
|
||||||
DQN_API bool Dqn_Char_IsWhitespace (char ch);
|
DQN_API bool Dqn_Char_IsWhitespace (char ch);
|
||||||
@ -5288,46 +5304,32 @@ DQN_API Dqn_String8 Dqn_String8_Slice(Dqn_String8 string, Dqn_usize offset, Dqn_
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_BinarySplitStringChars(Dqn_String8 string, Dqn_String8 delimiter_chars, Dqn_String8 *rhs)
|
DQN_API Dqn_String8BinarySplitResult Dqn_String8_BinarySplitArray(Dqn_String8 string, Dqn_String8 const *find, Dqn_usize find_size)
|
||||||
{
|
{
|
||||||
Dqn_String8 result = string;
|
Dqn_String8BinarySplitResult result = {};
|
||||||
if (rhs)
|
if (!Dqn_String8_IsValid(string) || !find || find_size == 0)
|
||||||
*rhs = {};
|
|
||||||
|
|
||||||
if (!Dqn_String8_IsValid(string))
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
Dqn_usize offset = 0;
|
result.lhs = string;
|
||||||
for (bool hit_delimiter = false; !hit_delimiter && offset < string.size; ) {
|
for (size_t index = 0; index <= string.size; index++) {
|
||||||
for (Dqn_usize index = 0; !hit_delimiter && index < delimiter_chars.size; index++) {
|
for (Dqn_usize find_index = 0; find_index < find_size; find_index++) {
|
||||||
char delimiter = delimiter_chars.data[index];
|
Dqn_String8 find_item = find[find_index];
|
||||||
hit_delimiter = string.data[offset] == delimiter;
|
Dqn_String8 string_slice = Dqn_String8_Slice(string, index, find_item.size);
|
||||||
}
|
if (Dqn_String8_Eq(string_slice, find_item)) {
|
||||||
|
result.lhs.size = index;
|
||||||
if (!hit_delimiter)
|
result.rhs.data = string_slice.data + find_item.size;
|
||||||
offset++;
|
result.rhs.size = string.size - (index + find_item.size);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
// NOTE: LHS, the string before the delimiter
|
|
||||||
result = Dqn_String8_Init(string.data, offset);
|
|
||||||
|
|
||||||
// NOTE: RHS, the string after the delimiter
|
|
||||||
if (rhs) {
|
|
||||||
char *end = string.data + string.size;
|
|
||||||
char *next = DQN_MIN((string.data + offset + 1), end);
|
|
||||||
if (next != end) {
|
|
||||||
rhs->data = next;
|
|
||||||
rhs->size = end - rhs->data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_BinarySplit(Dqn_String8 string, char delimiter, Dqn_String8 *rhs)
|
DQN_API Dqn_String8BinarySplitResult Dqn_String8_BinarySplit(Dqn_String8 string, Dqn_String8 find)
|
||||||
{
|
{
|
||||||
Dqn_String8 delimiter_chars = Dqn_String8_Init(&delimiter, 1);
|
Dqn_String8BinarySplitResult result = Dqn_String8_BinarySplitArray(string, &find, 1);
|
||||||
Dqn_String8 result = Dqn_String8_BinarySplitStringChars(string, delimiter_chars, rhs);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5361,6 +5363,52 @@ DQN_API Dqn_usize Dqn_String8_Split(Dqn_String8 string, Dqn_String8 delimiter, D
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DQN_API Dqn_String8FindResult Dqn_String8_FindFirstStringArray(Dqn_String8 string, Dqn_String8 const *find, Dqn_usize find_size)
|
||||||
|
{
|
||||||
|
Dqn_String8FindResult result = {};
|
||||||
|
if (!Dqn_String8_IsValid(string) || !find || find_size == 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
for (Dqn_usize index = 0; !result.found && index < string.size; index++) {
|
||||||
|
for (Dqn_usize find_index = 0; find_index < find_size; find_index++) {
|
||||||
|
Dqn_String8 find_item = find[find_index];
|
||||||
|
Dqn_String8 string_slice = Dqn_String8_Slice(string, index, find_item.size);
|
||||||
|
if (Dqn_String8_Eq(string_slice, find_item)) {
|
||||||
|
result.found = true;
|
||||||
|
result.index = index;
|
||||||
|
result.match = Dqn_String8_Init(string.data + index, find_item.size);
|
||||||
|
result.match_to_end_of_buffer = Dqn_String8_Init(result.match.data, string.size - index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_API Dqn_String8FindResult Dqn_String8_FindFirstString(Dqn_String8 string, Dqn_String8 find)
|
||||||
|
{
|
||||||
|
Dqn_String8FindResult result = Dqn_String8_FindFirstStringArray(string, &find, 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_API Dqn_String8FindResult Dqn_String8_FindFirst(Dqn_String8 string, uint32_t flags)
|
||||||
|
{
|
||||||
|
Dqn_String8FindResult result = {};
|
||||||
|
for (size_t index = 0; !result.found && index < string.size; index++) {
|
||||||
|
result.found |= ((flags & Dqn_String8FindFlag_Digit) && Dqn_Char_IsDigit(string.data[index]));
|
||||||
|
result.found |= ((flags & Dqn_String8FindFlag_Alphabet) && Dqn_Char_IsAlphabet(string.data[index]));
|
||||||
|
result.found |= ((flags & Dqn_String8FindFlag_Whitespace) && Dqn_Char_IsWhitespace(string.data[index]));
|
||||||
|
result.found |= ((flags & Dqn_String8FindFlag_Plus) && string.data[index] == '+');
|
||||||
|
result.found |= ((flags & Dqn_String8FindFlag_Minus) && string.data[index] == '-');
|
||||||
|
if (result.found) {
|
||||||
|
result.index = index;
|
||||||
|
result.match = Dqn_String8_Init(string.data + index, 1);
|
||||||
|
result.match_to_end_of_buffer = Dqn_String8_Init(result.match.data, string.size - index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_Segment(Dqn_Allocator allocator, Dqn_String8 src, Dqn_usize segment_size, char segment_char)
|
DQN_API Dqn_String8 Dqn_String8_Segment(Dqn_Allocator allocator, Dqn_String8 src, Dqn_usize segment_size, char segment_char)
|
||||||
{
|
{
|
||||||
Dqn_usize result_size = src.size;
|
Dqn_usize result_size = src.size;
|
||||||
@ -5380,6 +5428,7 @@ DQN_API Dqn_String8 Dqn_String8_Segment(Dqn_Allocator allocator, Dqn_String8 src
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DQN_API bool Dqn_String8_Eq(Dqn_String8 lhs, Dqn_String8 rhs, Dqn_String8EqCase eq_case)
|
DQN_API bool Dqn_String8_Eq(Dqn_String8 lhs, Dqn_String8 rhs, Dqn_String8EqCase eq_case)
|
||||||
{
|
{
|
||||||
if (lhs.size != rhs.size)
|
if (lhs.size != rhs.size)
|
||||||
@ -5615,25 +5664,6 @@ DQN_API int64_t Dqn_String8_ToI64(Dqn_String8 string, char separator)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_API Dqn_String8FindResult Dqn_String8_Find(Dqn_String8 string, Dqn_String8 find, Dqn_usize offset, Dqn_String8EqCase eq_case)
|
|
||||||
{
|
|
||||||
Dqn_String8FindResult result = {};
|
|
||||||
if (!Dqn_String8_IsValid(string) || !Dqn_String8_IsValid(find) || find.size > string.size)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
Dqn_usize start_index = DQN_MIN(offset, string.size);
|
|
||||||
Dqn_usize end = string.size - find.size + 1;
|
|
||||||
for (Dqn_usize index = start_index; !result.found && index < end; index++) {
|
|
||||||
Dqn_String8 check = Dqn_String8_Slice(string, index, find.size);
|
|
||||||
if (Dqn_String8_Eq(check, find, eq_case)) {
|
|
||||||
result.found = true;
|
|
||||||
result.offset = index;
|
|
||||||
result.string = check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DQN_API Dqn_String8 Dqn_String8_Replace(Dqn_String8 string,
|
DQN_API Dqn_String8 Dqn_String8_Replace(Dqn_String8 string,
|
||||||
Dqn_String8 find,
|
Dqn_String8 find,
|
||||||
Dqn_String8 replace,
|
Dqn_String8 replace,
|
||||||
@ -7525,7 +7555,7 @@ DQN_API uint64_t Dqn_Safe_SaturateCastIntToU64(int val)
|
|||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
// [$CHAR] Dqn_Char | | Character ascii/digit.. helpers
|
// [$CHAR] Dqn_Char | | Character ascii/digit.. helpers
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
DQN_API bool Dqn_Char_IsAlpha(char ch)
|
DQN_API bool Dqn_Char_IsAlphabet(char ch)
|
||||||
{
|
{
|
||||||
bool result = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
bool result = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||||
return result;
|
return result;
|
||||||
@ -7539,7 +7569,7 @@ DQN_API bool Dqn_Char_IsDigit(char ch)
|
|||||||
|
|
||||||
DQN_API bool Dqn_Char_IsAlphaNum(char ch)
|
DQN_API bool Dqn_Char_IsAlphaNum(char ch)
|
||||||
{
|
{
|
||||||
bool result = Dqn_Char_IsAlpha(ch) || Dqn_Char_IsDigit(ch);
|
bool result = Dqn_Char_IsAlphabet(ch) || Dqn_Char_IsDigit(ch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8551,8 +8581,10 @@ DQN_API Dqn_WinNetHandleResponse Dqn_Win_NetHandleSendRequest(Dqn_WinNetHandle *
|
|||||||
bool found_content_length = false;
|
bool found_content_length = false;
|
||||||
for (Dqn_usize header_index = 0; header_index < result.headers_size; header_index++) {
|
for (Dqn_usize header_index = 0; header_index < result.headers_size; header_index++) {
|
||||||
Dqn_String8 header = result.headers[header_index];
|
Dqn_String8 header = result.headers[header_index];
|
||||||
Dqn_String8 value = {};
|
|
||||||
Dqn_String8 key = Dqn_String8_BinarySplit(header, ':', &value);
|
Dqn_String8BinarySplitResult key_value_split = Dqn_String8_BinarySplit(header, DQN_STRING8(":"));
|
||||||
|
Dqn_String8 value = key_value_split.lhs;
|
||||||
|
Dqn_String8 key = key_value_split.rhs;
|
||||||
|
|
||||||
key = Dqn_String8_TrimWhitespaceAround(key);
|
key = Dqn_String8_TrimWhitespaceAround(key);
|
||||||
value = Dqn_String8_TrimWhitespaceAround(value);
|
value = Dqn_String8_TrimWhitespaceAround(value);
|
||||||
@ -9676,19 +9708,21 @@ DQN_API bool Dqn_FsPath_AddRef(Dqn_Arena *arena, Dqn_FsPath *fs_path, Dqn_String
|
|||||||
if (path.size <= 0)
|
if (path.size <= 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Dqn_String8 delimiter_chars = DQN_STRING8("/\\");
|
Dqn_String8 const delimiter_array[] = {
|
||||||
|
DQN_STRING8("\\"),
|
||||||
|
DQN_STRING8("/")
|
||||||
|
};
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Dqn_String8 rhs = {};
|
Dqn_String8BinarySplitResult delimiter = Dqn_String8_BinarySplitArray(path, delimiter_array, DQN_ARRAY_UCOUNT(delimiter_array));
|
||||||
Dqn_String8 lhs = Dqn_String8_BinarySplitStringChars(path, delimiter_chars, &rhs);
|
for (; delimiter.lhs.data; delimiter = Dqn_String8_BinarySplitArray(delimiter.rhs, delimiter_array, DQN_ARRAY_UCOUNT(delimiter_array))) {
|
||||||
for (; lhs.data; lhs = Dqn_String8_BinarySplitStringChars(rhs, delimiter_chars, &rhs)) {
|
if (delimiter.lhs.size <= 0)
|
||||||
if (lhs.size <= 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Dqn_FsPathLink *link = Dqn_Arena_New(arena, Dqn_FsPathLink, Dqn_ZeroMem_Yes);
|
Dqn_FsPathLink *link = Dqn_Arena_New(arena, Dqn_FsPathLink, Dqn_ZeroMem_Yes);
|
||||||
if (!link)
|
if (!link)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
link->string = lhs;
|
link->string = delimiter.lhs;
|
||||||
link->prev = fs_path->tail;
|
link->prev = fs_path->tail;
|
||||||
if (fs_path->tail) {
|
if (fs_path->tail) {
|
||||||
fs_path->tail->next = link;
|
fs_path->tail->next = link;
|
||||||
@ -9697,10 +9731,10 @@ DQN_API bool Dqn_FsPath_AddRef(Dqn_Arena *arena, Dqn_FsPath *fs_path, Dqn_String
|
|||||||
}
|
}
|
||||||
fs_path->tail = link;
|
fs_path->tail = link;
|
||||||
fs_path->links_size += 1;
|
fs_path->links_size += 1;
|
||||||
fs_path->string_size += lhs.size;
|
fs_path->string_size += delimiter.lhs.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lhs.data)
|
if (!delimiter.lhs.data)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1377,32 +1377,39 @@ Dqn_UTest TestString8()
|
|||||||
// NOTE: Dqn_String8_BinarySplit
|
// NOTE: Dqn_String8_BinarySplit
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
char const *TEST_FMT = "Dqn_String8_BinarySplit \"%s\" with 'c'";
|
{
|
||||||
|
char const *TEST_FMT = "Binary split \"%.*s\" with \"%.*s\"";
|
||||||
|
Dqn_String8 delimiter = DQN_STRING8("/");
|
||||||
|
Dqn_String8 input = DQN_STRING8("abcdef");
|
||||||
|
DQN_UTEST_TEST(TEST_FMT, DQN_STRING_FMT(input), DQN_STRING_FMT(delimiter)) {
|
||||||
|
Dqn_String8BinarySplitResult split = Dqn_String8_BinarySplit(input, delimiter);
|
||||||
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.lhs, DQN_STRING8("abcdef")), "[lhs=%.*s]", DQN_STRING_FMT(split.lhs));
|
||||||
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.rhs, DQN_STRING8("")), "[rhs=%.*s]", DQN_STRING_FMT(split.rhs));
|
||||||
|
}
|
||||||
|
|
||||||
char delimiter = '/';
|
input = DQN_STRING8("abc/def");
|
||||||
Dqn_String8 input = DQN_STRING8("abcdef");
|
DQN_UTEST_TEST(TEST_FMT, DQN_STRING_FMT(input), DQN_STRING_FMT(delimiter)) {
|
||||||
DQN_UTEST_TEST(TEST_FMT, input.data, delimiter) {
|
Dqn_String8BinarySplitResult split = Dqn_String8_BinarySplit(input, delimiter);
|
||||||
Dqn_String8 rhs = {};
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.lhs, DQN_STRING8("abc")), "[lhs=%.*s]", DQN_STRING_FMT(split.lhs));
|
||||||
Dqn_String8 lhs = Dqn_String8_BinarySplit(input, delimiter, &rhs);
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.rhs, DQN_STRING8("def")), "[rhs=%.*s]", DQN_STRING_FMT(split.rhs));
|
||||||
|
}
|
||||||
|
|
||||||
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(lhs, DQN_STRING8("abcdef")), "[lhs=%.*s]", DQN_STRING_FMT(lhs));
|
input = DQN_STRING8("/abcdef");
|
||||||
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(rhs, DQN_STRING8("")), "[rhs=%.*s]", DQN_STRING_FMT(rhs));
|
DQN_UTEST_TEST(TEST_FMT, DQN_STRING_FMT(input), DQN_STRING_FMT(delimiter)) {
|
||||||
|
Dqn_String8BinarySplitResult split = Dqn_String8_BinarySplit(input, delimiter);
|
||||||
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.lhs, DQN_STRING8("")), "[lhs=%.*s]", DQN_STRING_FMT(split.lhs));
|
||||||
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.rhs, DQN_STRING8("abcdef")), "[rhs=%.*s]", DQN_STRING_FMT(split.rhs));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input = DQN_STRING8("abc/def");
|
{
|
||||||
DQN_UTEST_TEST(TEST_FMT, input.data, delimiter) {
|
Dqn_String8 delimiter = DQN_STRING8("-=-");
|
||||||
Dqn_String8 rhs = {};
|
Dqn_String8 input = DQN_STRING8("123-=-456");
|
||||||
Dqn_String8 lhs = Dqn_String8_BinarySplit(input, delimiter, &rhs);
|
DQN_UTEST_TEST("Binary split \"%.*s\" with \"%.*s\"", DQN_STRING_FMT(input), DQN_STRING_FMT(delimiter)) {
|
||||||
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(lhs, DQN_STRING8("abc")), "[lhs=%.*s]", DQN_STRING_FMT(lhs));
|
Dqn_String8BinarySplitResult split = Dqn_String8_BinarySplit(input, delimiter);
|
||||||
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(rhs, DQN_STRING8("def")), "[rhs=%.*s]", DQN_STRING_FMT(rhs));
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.lhs, DQN_STRING8("123")), "[lhs=%.*s]", DQN_STRING_FMT(split.lhs));
|
||||||
}
|
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(split.rhs, DQN_STRING8("456")), "[rhs=%.*s]", DQN_STRING_FMT(split.rhs));
|
||||||
|
}
|
||||||
input = DQN_STRING8("/abcdef");
|
|
||||||
DQN_UTEST_TEST(TEST_FMT, input.data, delimiter) {
|
|
||||||
Dqn_String8 rhs = {};
|
|
||||||
Dqn_String8 lhs = Dqn_String8_BinarySplit(input, delimiter, &rhs);
|
|
||||||
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(lhs, DQN_STRING8("")), "[lhs=%.*s]", DQN_STRING_FMT(lhs));
|
|
||||||
DQN_UTEST_ASSERTF(&test, Dqn_String8_Eq(rhs, DQN_STRING8("abcdef")), "[rhs=%.*s]", DQN_STRING_FMT(rhs));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1505,20 +1512,20 @@ Dqn_UTest TestString8()
|
|||||||
DQN_UTEST_TEST("Find: String (char) is not in buffer") {
|
DQN_UTEST_TEST("Find: String (char) is not in buffer") {
|
||||||
Dqn_String8 buf = DQN_STRING8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
Dqn_String8 buf = DQN_STRING8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
||||||
Dqn_String8 find = DQN_STRING8("2");
|
Dqn_String8 find = DQN_STRING8("2");
|
||||||
Dqn_String8FindResult result = Dqn_String8_Find(buf, find, 0);
|
Dqn_String8FindResult result = Dqn_String8_FindFirstString(buf, find);
|
||||||
DQN_UTEST_ASSERT(&test, !result.found);
|
DQN_UTEST_ASSERT(&test, !result.found);
|
||||||
DQN_UTEST_ASSERT(&test, result.offset == 0);
|
DQN_UTEST_ASSERT(&test, result.index == 0);
|
||||||
DQN_UTEST_ASSERT(&test, result.string.data == nullptr);
|
DQN_UTEST_ASSERT(&test, result.match.data == nullptr);
|
||||||
DQN_UTEST_ASSERT(&test, result.string.size == 0);
|
DQN_UTEST_ASSERT(&test, result.match.size == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_UTEST_TEST("Find: String (char) is in buffer") {
|
DQN_UTEST_TEST("Find: String (char) is in buffer") {
|
||||||
Dqn_String8 buf = DQN_STRING8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
Dqn_String8 buf = DQN_STRING8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
||||||
Dqn_String8 find = DQN_STRING8("6");
|
Dqn_String8 find = DQN_STRING8("6");
|
||||||
Dqn_String8FindResult result = Dqn_String8_Find(buf, find, 0);
|
Dqn_String8FindResult result = Dqn_String8_FindFirstString(buf, find);
|
||||||
DQN_UTEST_ASSERT(&test, result.found);
|
DQN_UTEST_ASSERT(&test, result.found);
|
||||||
DQN_UTEST_ASSERT(&test, result.offset == 2);
|
DQN_UTEST_ASSERT(&test, result.index == 2);
|
||||||
DQN_UTEST_ASSERT(&test, result.string.data[0] == '6');
|
DQN_UTEST_ASSERT(&test, result.match.data[0] == '6');
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Dqn_String8_FileNameFromPath
|
// NOTE: Dqn_String8_FileNameFromPath
|
||||||
|
Loading…
Reference in New Issue
Block a user