Add slices, make returned bufs are null terminated
This commit is contained in:
parent
b0217483db
commit
7f2950b3dd
116
dqn.h
116
dqn.h
@ -34,6 +34,7 @@
|
|||||||
// #DqnMemAPI Custom memory API for Dqn Data Structures
|
// #DqnMemAPI Custom memory API for Dqn Data Structures
|
||||||
// #DqnArray Dynamic Array using Templates
|
// #DqnArray Dynamic Array using Templates
|
||||||
// #DqnMemStack Memory Allocator, Push, Pop Style
|
// #DqnMemStack Memory Allocator, Push, Pop Style
|
||||||
|
// #DqnSlice Slices
|
||||||
// #DqnHash Hashing using Murmur
|
// #DqnHash Hashing using Murmur
|
||||||
// #DqnMath Simple Math Helpers (Lerp etc.)
|
// #DqnMath Simple Math Helpers (Lerp etc.)
|
||||||
// #DqnV2 2D Math Vectors
|
// #DqnV2 2D Math Vectors
|
||||||
@ -138,6 +139,8 @@ using f32 = float;
|
|||||||
#define DQN_MEGABYTE(val) (DQN_KILOBYTE(val) * 1024LL)
|
#define DQN_MEGABYTE(val) (DQN_KILOBYTE(val) * 1024LL)
|
||||||
#define DQN_KILOBYTE(val) ((val) * 1024LL)
|
#define DQN_KILOBYTE(val) ((val) * 1024LL)
|
||||||
|
|
||||||
|
#define DQN_MINUTE(val) ((val) * 60LL)
|
||||||
|
|
||||||
#define DQN_ALIGN_POW_N(val, align) ((((usize)val) + ((usize)align-1)) & (~(usize)(align-1)))
|
#define DQN_ALIGN_POW_N(val, align) ((((usize)val) + ((usize)align-1)) & (~(usize)(align-1)))
|
||||||
#define DQN_ALIGN_POW_4(val) DQN_ALIGN_POW_N(val, 4)
|
#define DQN_ALIGN_POW_4(val) DQN_ALIGN_POW_N(val, 4)
|
||||||
|
|
||||||
@ -857,6 +860,15 @@ void DqnArray<T>::RemoveStable(isize *indexList, isize numIndexes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #DqnSlice API
|
||||||
|
// =================================================================================================
|
||||||
|
template <typename T>
|
||||||
|
struct DqnSlice
|
||||||
|
{
|
||||||
|
T *data;
|
||||||
|
i32 len;
|
||||||
|
};
|
||||||
|
|
||||||
// #DqnHash API
|
// #DqnHash API
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
DQN_FILE_SCOPE u32 DqnHash_Murmur32Seed(void const *data, usize len, u32 seed);
|
DQN_FILE_SCOPE u32 DqnHash_Murmur32Seed(void const *data, usize len, u32 seed);
|
||||||
@ -1796,6 +1808,13 @@ DQN_FILE_SCOPE DqnRndPCG DqnRndPCG_(u32 seed);
|
|||||||
// #Dqn_ API
|
// #Dqn_ API
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
|
||||||
|
// return: The number of splits in the array. If array is null this returns the required size of the array.
|
||||||
|
i32 Dqn_SplitString(char const *src, i32 srcLen, char splitChar, DqnSlice<char> *array = nullptr, i32 size = 0);
|
||||||
|
|
||||||
|
// Util function that uses Dqn_SplitString
|
||||||
|
// return: The number of splits, splitting by "splitChar" would generate.
|
||||||
|
i32 Dqn_GetNumSplits(char const *src, i32 srcLen, char splitChar);
|
||||||
|
|
||||||
inline bool Dqn_BitIsSet(u32 const bits, u32 const flag)
|
inline bool Dqn_BitIsSet(u32 const bits, u32 const flag)
|
||||||
{
|
{
|
||||||
bool result = ((bits & flag) == flag);
|
bool result = ((bits & flag) == flag);
|
||||||
@ -2123,12 +2142,13 @@ struct DqnFile
|
|||||||
// Static API
|
// Static API
|
||||||
// ==============================================================================================
|
// ==============================================================================================
|
||||||
// Read entire file into the given buffer. To determine required bufSize size, use GetFileSize.
|
// Read entire file into the given buffer. To determine required bufSize size, use GetFileSize.
|
||||||
|
// NOTE: You want size + 1 and add the null-terminator yourself if you want a null terminated buffer.
|
||||||
// bytesRead: Pass in to get how many bytes of the buf was used. Basically the return value of Read
|
// bytesRead: Pass in to get how many bytes of the buf was used. Basically the return value of Read
|
||||||
// return: False if insufficient bufSize OR file access failure OR nullptr arguments.
|
// return: False if insufficient bufSize OR file access failure OR nullptr arguments.
|
||||||
static bool ReadEntireFile(char const *const path, u8 *const buf, usize const bufSize, usize *const bytesRead);
|
static bool ReadEntireFile(char const *const path, u8 *const buf, usize const bufSize, usize *const bytesRead);
|
||||||
static bool ReadEntireFile(wchar_t const *const path, u8 *const buf, usize const bufSize, usize *const bytesRead);
|
static bool ReadEntireFile(wchar_t const *const path, u8 *const buf, usize const bufSize, usize *const bytesRead);
|
||||||
|
|
||||||
// Buffer should be freed when done with.
|
// Buffer is null-terminated and should be freed when done with.
|
||||||
// return: False if file access failure OR nullptr arguments.
|
// return: False if file access failure OR nullptr arguments.
|
||||||
static u8 *ReadEntireFile(char const *const path, usize *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
|
static u8 *ReadEntireFile(char const *const path, usize *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
|
||||||
static u8 *ReadEntireFile(wchar_t const *const path, usize *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
|
static u8 *ReadEntireFile(wchar_t const *const path, usize *const bufSize, DqnMemAPI *const api = &DQN_DEFAULT_HEAP_ALLOCATOR);
|
||||||
@ -3010,6 +3030,7 @@ DQN_FILE_SCOPE void *DqnMem_Set64(void *const dest, u8 const value, i64 const nu
|
|||||||
usize const numU8ToCopy = numBytesToCopy & (remainingMask);
|
usize const numU8ToCopy = numBytesToCopy & (remainingMask);
|
||||||
__stosb(destU8, valueU8, numU8ToCopy);
|
__stosb(destU8, valueU8, numU8ToCopy);
|
||||||
#else
|
#else
|
||||||
|
(void)dest; (void)value; (void)numBytesToCopy;
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH)
|
DQN_ASSERT(DQN_INVALID_CODE_PATH)
|
||||||
#endif
|
#endif
|
||||||
return dest;
|
return dest;
|
||||||
@ -5087,7 +5108,7 @@ DQN_FILE_SCOPE char *DqnChar_GetNextLine (char *ptr, i32 *lineLength)
|
|||||||
|
|
||||||
// #DqnStr Implementation
|
// #DqnStr Implementation
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
DQN_FILE_SCOPE i32 DqnStr_Cmp(const char *const a, const char *const b, i32 numBytesToCompare, bool ignoreCase)
|
DQN_FILE_SCOPE i32 DqnStr_Cmp(char const *a, char const *b, i32 numBytesToCompare, bool ignoreCase)
|
||||||
{
|
{
|
||||||
if (!a && !b) return -1;
|
if (!a && !b) return -1;
|
||||||
if (!a) return -1;
|
if (!a) return -1;
|
||||||
@ -5095,35 +5116,22 @@ DQN_FILE_SCOPE i32 DqnStr_Cmp(const char *const a, const char *const b, i32 numB
|
|||||||
if (numBytesToCompare == 0) return -1;
|
if (numBytesToCompare == 0) return -1;
|
||||||
|
|
||||||
i32 bytesCompared = 0;
|
i32 bytesCompared = 0;
|
||||||
char const *aPtr = a;
|
|
||||||
char const *bPtr = b;
|
|
||||||
|
|
||||||
if (ignoreCase)
|
if (ignoreCase)
|
||||||
{
|
{
|
||||||
while (DqnChar_ToLower((*aPtr)) == DqnChar_ToLower((*bPtr)))
|
while (a[0] && DqnChar_ToLower((*a++)) == DqnChar_ToLower((*b++)))
|
||||||
{
|
{
|
||||||
if (!(*aPtr)) return 0;
|
if (++bytesCompared == numBytesToCompare) return 0;
|
||||||
bytesCompared++;
|
|
||||||
aPtr++;
|
|
||||||
bPtr++;
|
|
||||||
|
|
||||||
if (bytesCompared == numBytesToCompare) return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while ((*aPtr) == (*bPtr))
|
while (a[0] && (*a++) == (*b++))
|
||||||
{
|
{
|
||||||
if (!(*aPtr)) return 0;
|
if (++bytesCompared == numBytesToCompare) return 0;
|
||||||
bytesCompared++;
|
|
||||||
aPtr++;
|
|
||||||
bPtr++;
|
|
||||||
|
|
||||||
if (bytesCompared == numBytesToCompare) return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (((*aPtr) < (*bPtr)) ? -1 : 1);
|
return (*a - *b);
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE char *DqnStr_GetPtrToLastSlash(char const *str, i32 strLen)
|
DQN_FILE_SCOPE char *DqnStr_GetPtrToLastSlash(char const *str, i32 strLen)
|
||||||
@ -5318,7 +5326,12 @@ DQN_FILE_SCOPE i32 Dqn_I64ToStr(i64 const value, char *const buf, i32 const bufS
|
|||||||
|
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
if (validBuffer) buf[0] = '0';
|
if (validBuffer)
|
||||||
|
{
|
||||||
|
buf[0] = '0';
|
||||||
|
buf[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5381,6 +5394,7 @@ DQN_FILE_SCOPE i32 Dqn_I64ToStr(i64 const value, char *const buf, i32 const bufS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf[charIndex] = 0;
|
||||||
return charIndex;
|
return charIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5768,7 +5782,7 @@ DQN_FILE_SCOPE i32 DqnWStr_Cmp(const wchar_t *const a, const wchar_t *const b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE i32 DqnWStr_FindFirstOccurence(const wchar_t *const src, const i32 srcLen,
|
DQN_FILE_SCOPE i32 DqnWStr_FindFirstOccurence(const wchar_t *const src, const i32 srcLen,
|
||||||
const wchar_t *const find, const i32 findLen)
|
const wchar_t *const find, const i32 findLen)
|
||||||
{
|
{
|
||||||
if (!src || !find) return -1;
|
if (!src || !find) return -1;
|
||||||
if (srcLen == 0 || findLen == 0) return -1;
|
if (srcLen == 0 || findLen == 0) return -1;
|
||||||
@ -6069,6 +6083,7 @@ bool DqnString::InitLiteral(wchar_t const *const cstr, DqnMemAPI *const api)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
(void)cstr; (void)api;
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -6286,6 +6301,7 @@ i32 DqnString::ToWChar(wchar_t *const buf, i32 const bufSize) const
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
(void)buf; (void)bufSize;
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
@ -6308,6 +6324,7 @@ wchar_t *DqnString::ToWChar(DqnMemAPI *const api) const
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
(void)api;
|
||||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@ -6425,6 +6442,56 @@ i32 DqnRndPCG::Range(i32 min, i32 max)
|
|||||||
|
|
||||||
// #Dqn
|
// #Dqn
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
i32 Dqn_GetNumSplits(char const *src, i32 srcLen, char splitChar)
|
||||||
|
{
|
||||||
|
auto result = Dqn_SplitString(src, srcLen, splitChar, nullptr, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 Dqn_SplitString(char const *src, i32 srcLen, char splitChar, DqnSlice<char> *array, i32 size)
|
||||||
|
{
|
||||||
|
// TODO(doyle): Const correctness
|
||||||
|
i32 sliceLen = 0;
|
||||||
|
i32 arrayIndex = 0;
|
||||||
|
for (auto i = 0; i < srcLen; i++)
|
||||||
|
{
|
||||||
|
char *c = (char *)(src + i);
|
||||||
|
if (*c == splitChar)
|
||||||
|
{
|
||||||
|
DqnSlice<char> slice = {c - sliceLen, sliceLen};
|
||||||
|
if (array)
|
||||||
|
{
|
||||||
|
if (arrayIndex < size)
|
||||||
|
{
|
||||||
|
array[arrayIndex] = slice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arrayIndex++;
|
||||||
|
sliceLen = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sliceLen++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DqnSlice<char> lastSlice = {(char *)src + srcLen - sliceLen, sliceLen};
|
||||||
|
if (lastSlice.len > 0)
|
||||||
|
{
|
||||||
|
if (array)
|
||||||
|
{
|
||||||
|
if (arrayIndex < size)
|
||||||
|
{
|
||||||
|
array[arrayIndex] = lastSlice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return arrayIndex;
|
||||||
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE i64 Dqn_BSearch(i64 *const array, i64 const size, i64 const find,
|
DQN_FILE_SCOPE i64 Dqn_BSearch(i64 *const array, i64 const size, i64 const find,
|
||||||
Dqn_BSearchBound const bound)
|
Dqn_BSearchBound const bound)
|
||||||
{
|
{
|
||||||
@ -8613,7 +8680,7 @@ u8 *DqnFile::ReadEntireFile(wchar_t const *const path, usize *const bufSize, Dqn
|
|||||||
usize bytesRead = 0;
|
usize bytesRead = 0;
|
||||||
if (DqnFile::ReadEntireFile(path, buf, requiredSize, &bytesRead))
|
if (DqnFile::ReadEntireFile(path, buf, requiredSize, &bytesRead))
|
||||||
{
|
{
|
||||||
*bufSize = requiredSize;
|
*bufSize = requiredSize;
|
||||||
DQN_ASSERT(bytesRead == requiredSize);
|
DQN_ASSERT(bytesRead == requiredSize);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -8669,8 +8736,7 @@ cleanup:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DqnFile::ReadEntireFile(const char *const path, u8 *const buf, usize const bufSize,
|
bool DqnFile::ReadEntireFile(const char *const path, u8 *const buf, usize const bufSize, usize *const bytesRead)
|
||||||
usize *const bytesRead)
|
|
||||||
{
|
{
|
||||||
if (!path || !buf || !bytesRead) return false;
|
if (!path || !buf || !bytesRead) return false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user