Cleanup base layer
This commit is contained in:
parent
fd7a543e34
commit
fff3fe1988
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
||||
#define DN_ForIndexI(index, size) DN_ISize index = 0; index < size; index++
|
||||
#define DN_ForItSize(it, T, array, size) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < (size); it.index++, it.data = (array) + it.index
|
||||
#define DN_ForIt(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)->data[0]}; it.index < (array)->size; it.index++, it.data = ((array)->data) + it.index
|
||||
#define DN_ForLinkedListIt(it, T, list) struct { DN_USize index; T *data; } it = {0, list}; it.data; it.index++, it.data = ((it).data->next)
|
||||
#define DN_ForItCArray(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < DN_ArrayCountU(array); it.index++, it.data = (array) + it.index
|
||||
|
||||
#define DN_AlignUpPowerOfTwo(value, pot) (((uintptr_t)(value) + ((uintptr_t)(pot) - 1)) & ~((uintptr_t)(pot) - 1))
|
||||
@ -83,7 +84,7 @@
|
||||
} while (0)
|
||||
|
||||
// NOTE: Size
|
||||
#define DN_SizeOfI(val) DN_CAST(ptrdiff_t)sizeof(val)
|
||||
#define DN_SizeOfI(val) DN_Cast(ptrdiff_t)sizeof(val)
|
||||
#define DN_ArrayCountU(array) (sizeof(array)/(sizeof((array)[0])))
|
||||
#define DN_ArrayCountI(array) (DN_ISize)DN_ArrayCountU(array)
|
||||
#define DN_CharCountU(string) (sizeof(string) - 1)
|
||||
@ -95,12 +96,12 @@
|
||||
#define DN_Gigabytes(val) ((DN_U64)1024 * DN_Megabytes(val))
|
||||
|
||||
// NOTE: Time
|
||||
#define DN_SecondsToMs(val) ((val) * 1000)
|
||||
#define DN_MinutesToSec(val) ((val) * 60ULL)
|
||||
#define DN_HoursToSec(val) (DN_MinutesToSec(val) * 60ULL)
|
||||
#define DN_DaysToSec(val) (DN_HoursToSec(val) * 24ULL)
|
||||
#define DN_WeeksToSec(val) (DN_DaysToSec(val) * 7ULL)
|
||||
#define DN_YearsToSec(val) (DN_WeeksToSec(val) * 52ULL)
|
||||
#define DN_MsFromSec(val) ((val) * 1000ULL)
|
||||
#define DN_SecFromMins(val) ((val) * 60ULL)
|
||||
#define DN_SecFromHours(val) (DN_SecFromMins(val) * 60ULL)
|
||||
#define DN_SecFromDays(val) (DN_SecFromHours(val) * 24ULL)
|
||||
#define DN_SecFromWeeks(val) (DN_SecFromDays(val) * 7ULL)
|
||||
#define DN_SecFromYears(val) (DN_SecFromWeeks(val) * 52ULL)
|
||||
|
||||
// NOTE: Debug Break
|
||||
#if !defined(DN_DebugBreak)
|
||||
@ -161,10 +162,10 @@ typedef DN_I32 DN_B32;
|
||||
#define DN_ISIZE_MAX INTPTR_MAX
|
||||
#define DN_ISIZE_MIN INTPTR_MIN
|
||||
|
||||
enum DN_ZeroMem
|
||||
enum DN_ZMem
|
||||
{
|
||||
DN_ZeroMem_No, // Memory can be handed out without zero-ing it out
|
||||
DN_ZeroMem_Yes, // Memory should be zero-ed out before giving to the callee
|
||||
DN_ZMem_No, // Memory can be handed out without zero-ing it out
|
||||
DN_ZMem_Yes, // Memory should be zero-ed out before giving to the callee
|
||||
};
|
||||
|
||||
struct DN_Str8
|
||||
@ -173,21 +174,36 @@ struct DN_Str8
|
||||
DN_USize size; // The number of bytes in the string
|
||||
};
|
||||
|
||||
struct DN_Str8x32 { char data[32]; DN_USize size; };
|
||||
struct DN_Str8x64 { char data[64]; DN_USize size; };
|
||||
struct DN_Str8x128 { char data[128]; DN_USize size; };
|
||||
struct DN_Str8x256 { char data[256]; DN_USize size; };
|
||||
|
||||
struct DN_Hex32 { char data[32]; };
|
||||
struct DN_Hex64 { char data[64]; };
|
||||
struct DN_Hex128 { char data[128]; };
|
||||
|
||||
struct DN_HexU64Str8
|
||||
{
|
||||
char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/];
|
||||
DN_U8 size;
|
||||
};
|
||||
|
||||
enum DN_HexFromU64Type
|
||||
{
|
||||
DN_HexFromU64Type_Nil,
|
||||
DN_HexFromU64Type_Uppercase,
|
||||
};
|
||||
|
||||
struct DN_Str16 // A pointer and length style string that holds slices to UTF16 bytes.
|
||||
{
|
||||
wchar_t *data; // The UTF16 bytes of the string
|
||||
DN_USize size; // The number of characters in the string
|
||||
};
|
||||
|
||||
struct DN_U8x32
|
||||
{
|
||||
DN_U8 data[32];
|
||||
};
|
||||
|
||||
struct DN_U8x64
|
||||
{
|
||||
DN_U8 data[64];
|
||||
};
|
||||
struct DN_U8x16 { DN_U8 data[16]; };
|
||||
struct DN_U8x32 { DN_U8 data[32]; };
|
||||
struct DN_U8x64 { DN_U8 data[64]; };
|
||||
|
||||
template <typename T>
|
||||
struct DN_Slice // A pointer and length container of data
|
||||
@ -208,7 +224,7 @@ struct DN_CallSite
|
||||
DN_U32 line;
|
||||
};
|
||||
|
||||
#define DN_CALL_SITE DN_CallSite { DN_STR8(__FILE__), DN_STR8(__func__), __LINE__ }
|
||||
#define DN_CALL_SITE DN_CallSite { DN_Str8Lit(__FILE__), DN_Str8Lit(__func__), __LINE__ }
|
||||
|
||||
// NOTE: Defer Macro
|
||||
#if defined(__cplusplus)
|
||||
@ -247,7 +263,7 @@ struct DN_DeferHelper
|
||||
#define DN_AtomicLoadU32(target) *(target)
|
||||
#define DN_AtomicAddU32(target, value) _InterlockedExchangeAdd((long volatile *)target, value)
|
||||
#define DN_AtomicAddU64(target, value) _InterlockedExchangeAdd64((__int64 volatile *)target, value)
|
||||
#define DN_AtomicSubU32(target, value) DN_AtomicAddU32(DN_CAST(long volatile *) target, (long)-value)
|
||||
#define DN_AtomicSubU32(target, value) DN_AtomicAddU32(DN_Cast(long volatile *) target, (long)-value)
|
||||
#define DN_AtomicSubU64(target, value) DN_AtomicAddU64(target, (DN_U64) - value)
|
||||
|
||||
#define DN_CountLeadingZerosU64(value) __lzcnt64(value)
|
||||
@ -404,92 +420,638 @@ struct DN_TicketMutex
|
||||
unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned
|
||||
};
|
||||
|
||||
DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value);
|
||||
DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value);
|
||||
struct DN_U64FromResult
|
||||
{
|
||||
bool success;
|
||||
DN_U64 value;
|
||||
};
|
||||
|
||||
DN_API DN_CPUIDResult DN_CPUID (DN_CPUIDArgs args);
|
||||
DN_API DN_USize DN_CPUHasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size);
|
||||
DN_API bool DN_CPUHasFeature (DN_CPUReport const *report, DN_CPUFeature feature);
|
||||
DN_API bool DN_CPUHasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size);
|
||||
DN_API void DN_CPUSetFeature (DN_CPUReport *report, DN_CPUFeature feature);
|
||||
DN_API DN_CPUReport DN_CPUGetReport ();
|
||||
struct DN_I64FromResult
|
||||
{
|
||||
bool success;
|
||||
DN_I64 value;
|
||||
};
|
||||
|
||||
DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex);
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_BeginTicket (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
enum DN_MemCommit
|
||||
{
|
||||
DN_MemCommit_No,
|
||||
DN_MemCommit_Yes,
|
||||
};
|
||||
|
||||
DN_API void DN_BitUnsetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API void DN_BitSetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API bool DN_BitIsSet (DN_USize bits, DN_USize bits_to_set);
|
||||
DN_API bool DN_BitIsNotSet (DN_USize bits, DN_USize bits_to_check);
|
||||
#define DN_BitClearNextLSB(value) (value) & ((value) - 1)
|
||||
typedef DN_U32 DN_MemPage;
|
||||
enum DN_MemPage_
|
||||
{
|
||||
// Exception on read/write with a page. This flag overrides the read/write
|
||||
// access.
|
||||
DN_MemPage_NoAccess = 1 << 0,
|
||||
|
||||
DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b);
|
||||
DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b);
|
||||
DN_MemPage_Read = 1 << 1, // Only read permitted on the page.
|
||||
|
||||
DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b);
|
||||
// Only write permitted on the page. On Windows this is not supported and
|
||||
// will be promoted to read+write permissions.
|
||||
DN_MemPage_Write = 1 << 2,
|
||||
|
||||
DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b);
|
||||
DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write,
|
||||
|
||||
DN_API int DN_SaturateCastUSizeToInt (DN_USize val);
|
||||
DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val);
|
||||
DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val);
|
||||
DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val);
|
||||
DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val);
|
||||
// Modifier used in conjunction with previous flags. Raises exception on
|
||||
// first access to the page, then, the underlying protection flags are
|
||||
// active. This is supported on Windows, on other OS's using this flag will
|
||||
// set the OS equivalent of DN_MemPage_NoAccess.
|
||||
// This flag must only be used in DN_Mem_Protect
|
||||
DN_MemPage_Guard = 1 << 3,
|
||||
|
||||
DN_API int DN_SaturateCastU64ToInt (DN_U64 val);
|
||||
DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val);
|
||||
DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val);
|
||||
DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val);
|
||||
DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val);
|
||||
DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val);
|
||||
DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val);
|
||||
DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val);
|
||||
DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val);
|
||||
// If leak tracing is enabled, this flag will allow the allocation recorded
|
||||
// from the reserve call to be leaked, e.g. not printed when leaks are
|
||||
// dumped to the console.
|
||||
DN_MemPage_AllocRecordLeakPermitted = 1 << 4,
|
||||
|
||||
DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val);
|
||||
DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val);
|
||||
DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val);
|
||||
DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val);
|
||||
// If leak tracing is enabled this flag will prevent any allocation record
|
||||
// from being created in the allocation table at all. If this flag is
|
||||
// enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the
|
||||
// record will never be created.
|
||||
DN_MemPage_NoAllocRecordEntry = 1 << 5,
|
||||
|
||||
DN_API int DN_SaturateCastISizeToInt (DN_ISize val);
|
||||
DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val);
|
||||
DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val);
|
||||
DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val);
|
||||
DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val);
|
||||
// [INTERNAL] Do not use. All flags together do not constitute a correct
|
||||
// configuration of pages.
|
||||
DN_MemPage_All = DN_MemPage_NoAccess |
|
||||
DN_MemPage_ReadWrite |
|
||||
DN_MemPage_Guard |
|
||||
DN_MemPage_AllocRecordLeakPermitted |
|
||||
DN_MemPage_NoAllocRecordEntry,
|
||||
};
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val);
|
||||
DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val);
|
||||
DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val);
|
||||
DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val);
|
||||
DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val);
|
||||
#if !defined(DN_ARENA_RESERVE_SIZE)
|
||||
#define DN_ARENA_RESERVE_SIZE DN_Megabytes(64)
|
||||
#endif
|
||||
|
||||
DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val);
|
||||
DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val);
|
||||
DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val);
|
||||
DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val);
|
||||
#if !defined(DN_ARENA_COMMIT_SIZE)
|
||||
#define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64)
|
||||
#endif
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val);
|
||||
DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val);
|
||||
DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val);
|
||||
DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val);
|
||||
DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val);
|
||||
DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val);
|
||||
enum DN_Allocator
|
||||
{
|
||||
DN_Allocator_Arena,
|
||||
DN_Allocator_Pool,
|
||||
};
|
||||
|
||||
DN_API DN_I8 DN_SaturateCastIntToI8 (int val);
|
||||
DN_API DN_I16 DN_SaturateCastIntToI16 (int val);
|
||||
DN_API DN_U8 DN_SaturateCastIntToU8 (int val);
|
||||
DN_API DN_U16 DN_SaturateCastIntToU16 (int val);
|
||||
DN_API DN_U32 DN_SaturateCastIntToU32 (int val);
|
||||
DN_API DN_U64 DN_SaturateCastIntToU64 (int val);
|
||||
struct DN_ArenaBlock
|
||||
{
|
||||
DN_ArenaBlock *prev;
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 reserve_sum;
|
||||
};
|
||||
|
||||
DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
DN_API void DN_ASanUnpoisonMemoryRegion(void const volatile *ptr, DN_USize size);
|
||||
typedef DN_U32 DN_ArenaFlags;
|
||||
enum DN_ArenaFlags_
|
||||
{
|
||||
DN_ArenaFlags_Nil = 0,
|
||||
DN_ArenaFlags_NoGrow = 1 << 0,
|
||||
DN_ArenaFlags_NoPoison = 1 << 1,
|
||||
DN_ArenaFlags_NoAllocTrack = 1 << 2,
|
||||
DN_ArenaFlags_AllocCanLeak = 1 << 3,
|
||||
|
||||
DN_API DN_F32 DN_EpsilonClampF32 (DN_F32 value, DN_F32 target, DN_F32 epsilon);
|
||||
// NOTE: Internal flags. Do not use
|
||||
DN_ArenaFlags_UserBuffer = 1 << 4,
|
||||
DN_ArenaFlags_MemFuncs = 1 << 5,
|
||||
};
|
||||
|
||||
struct DN_ArenaInfo
|
||||
{
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 blocks;
|
||||
};
|
||||
|
||||
struct DN_ArenaStats
|
||||
{
|
||||
DN_ArenaInfo info;
|
||||
DN_ArenaInfo hwm;
|
||||
};
|
||||
|
||||
enum DN_ArenaMemFuncType
|
||||
{
|
||||
DN_ArenaMemFuncType_Nil,
|
||||
DN_ArenaMemFuncType_Basic,
|
||||
DN_ArenaMemFuncType_VMem,
|
||||
};
|
||||
|
||||
typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size);
|
||||
typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr);
|
||||
typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags);
|
||||
typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags);
|
||||
typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size);
|
||||
struct DN_ArenaMemFuncs
|
||||
{
|
||||
DN_ArenaMemFuncType type;
|
||||
DN_ArenaMemBasicAllocFunc *basic_alloc;
|
||||
DN_ArenaMemBasicDeallocFunc *basic_dealloc;
|
||||
|
||||
DN_U32 vmem_page_size;
|
||||
DN_ArenaMemVMemReserveFunc *vmem_reserve;
|
||||
DN_ArenaMemVMemCommitFunc *vmem_commit;
|
||||
DN_ArenaMemVMemReleaseFunc *vmem_release;
|
||||
};
|
||||
|
||||
struct DN_Arena
|
||||
{
|
||||
DN_ArenaMemFuncs mem_funcs;
|
||||
DN_ArenaBlock *curr;
|
||||
DN_ArenaStats stats;
|
||||
DN_ArenaFlags flags;
|
||||
DN_Str8 label;
|
||||
DN_Arena *prev, *next;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMem
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_U64 used_sum;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMemScope
|
||||
{
|
||||
DN_ArenaTempMemScope(DN_Arena *arena);
|
||||
~DN_ArenaTempMemScope();
|
||||
DN_ArenaTempMem mem;
|
||||
};
|
||||
|
||||
DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64);
|
||||
|
||||
#if !defined(DN_POOL_DEFAULT_ALIGN)
|
||||
#define DN_POOL_DEFAULT_ALIGN 16
|
||||
#endif
|
||||
|
||||
struct DN_PoolSlot
|
||||
{
|
||||
void *data;
|
||||
DN_PoolSlot *next;
|
||||
};
|
||||
|
||||
enum DN_PoolSlotSize
|
||||
{
|
||||
DN_PoolSlotSize_32B,
|
||||
DN_PoolSlotSize_64B,
|
||||
DN_PoolSlotSize_128B,
|
||||
DN_PoolSlotSize_256B,
|
||||
DN_PoolSlotSize_512B,
|
||||
DN_PoolSlotSize_1KiB,
|
||||
DN_PoolSlotSize_2KiB,
|
||||
DN_PoolSlotSize_4KiB,
|
||||
DN_PoolSlotSize_8KiB,
|
||||
DN_PoolSlotSize_16KiB,
|
||||
DN_PoolSlotSize_32KiB,
|
||||
DN_PoolSlotSize_64KiB,
|
||||
DN_PoolSlotSize_128KiB,
|
||||
DN_PoolSlotSize_256KiB,
|
||||
DN_PoolSlotSize_512KiB,
|
||||
DN_PoolSlotSize_1MiB,
|
||||
DN_PoolSlotSize_2MiB,
|
||||
DN_PoolSlotSize_4MiB,
|
||||
DN_PoolSlotSize_8MiB,
|
||||
DN_PoolSlotSize_16MiB,
|
||||
DN_PoolSlotSize_32MiB,
|
||||
DN_PoolSlotSize_64MiB,
|
||||
DN_PoolSlotSize_128MiB,
|
||||
DN_PoolSlotSize_256MiB,
|
||||
DN_PoolSlotSize_512MiB,
|
||||
DN_PoolSlotSize_1GiB,
|
||||
DN_PoolSlotSize_2GiB,
|
||||
DN_PoolSlotSize_4GiB,
|
||||
DN_PoolSlotSize_8GiB,
|
||||
DN_PoolSlotSize_16GiB,
|
||||
DN_PoolSlotSize_32GiB,
|
||||
DN_PoolSlotSize_Count,
|
||||
};
|
||||
|
||||
struct DN_Pool
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_PoolSlot *slots[DN_PoolSlotSize_Count];
|
||||
DN_U8 align;
|
||||
};
|
||||
|
||||
struct DN_NibbleFromU8Result
|
||||
{
|
||||
char nibble0;
|
||||
char nibble1;
|
||||
};
|
||||
|
||||
enum DN_Str8EqCase
|
||||
{
|
||||
DN_Str8EqCase_Sensitive,
|
||||
DN_Str8EqCase_Insensitive,
|
||||
};
|
||||
|
||||
enum DN_Str8IsAllType
|
||||
{
|
||||
DN_Str8IsAllType_Digits,
|
||||
DN_Str8IsAllType_Hex,
|
||||
};
|
||||
|
||||
struct DN_Str8BSplitResult
|
||||
{
|
||||
DN_Str8 lhs;
|
||||
DN_Str8 rhs;
|
||||
};
|
||||
|
||||
struct DN_Str8FindResult
|
||||
{
|
||||
bool found; // True if string was found. If false, the subsequent fields below are not set.
|
||||
DN_USize index; // Index in the buffer where the found string starts
|
||||
DN_Str8 match; // Matching string in the buffer that was searched
|
||||
DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer
|
||||
DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer
|
||||
DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it
|
||||
};
|
||||
|
||||
enum DN_Str8FindFlag
|
||||
{
|
||||
DN_Str8FindFlag_Digit = 1 << 0, // 0-9
|
||||
DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' '
|
||||
DN_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z
|
||||
DN_Str8FindFlag_Plus = 1 << 3, // +
|
||||
DN_Str8FindFlag_Minus = 1 << 4, // -
|
||||
DN_Str8FindFlag_AlphaNum = DN_Str8FindFlag_Alphabet | DN_Str8FindFlag_Digit,
|
||||
};
|
||||
|
||||
enum DN_Str8SplitIncludeEmptyStrings
|
||||
{
|
||||
DN_Str8SplitIncludeEmptyStrings_No,
|
||||
DN_Str8SplitIncludeEmptyStrings_Yes,
|
||||
};
|
||||
|
||||
struct DN_Str8TruncateResult
|
||||
{
|
||||
bool truncated;
|
||||
DN_Str8 str8;
|
||||
};
|
||||
|
||||
struct DN_Str8SplitResult
|
||||
{
|
||||
DN_Str8 *data;
|
||||
DN_USize count;
|
||||
};
|
||||
|
||||
struct DN_Str8Link
|
||||
{
|
||||
DN_Str8 string; // The string
|
||||
DN_Str8Link *next; // The next string in the linked list
|
||||
DN_Str8Link *prev; // The prev string in the linked list
|
||||
};
|
||||
|
||||
struct DN_Str8Builder
|
||||
{
|
||||
DN_Arena *arena; // Allocator to use to back the string list
|
||||
DN_Str8Link *head; // First string in the linked list of strings
|
||||
DN_Str8Link *tail; // Last string in the linked list of strings
|
||||
DN_USize string_size; // The size in bytes necessary to construct the current string
|
||||
DN_USize count; // The number of links in the linked list of strings
|
||||
};
|
||||
|
||||
enum DN_Str8BuilderAdd
|
||||
{
|
||||
DN_Str8BuilderAdd_Append,
|
||||
DN_Str8BuilderAdd_Prepend,
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_AgeUnit;
|
||||
enum DN_AgeUnit_
|
||||
{
|
||||
DN_AgeUnit_Ms = 1 << 0,
|
||||
DN_AgeUnit_Sec = 1 << 1,
|
||||
DN_AgeUnit_Min = 1 << 2,
|
||||
DN_AgeUnit_Hr = 1 << 3,
|
||||
DN_AgeUnit_Day = 1 << 4,
|
||||
DN_AgeUnit_Week = 1 << 5,
|
||||
DN_AgeUnit_Year = 1 << 6,
|
||||
DN_AgeUnit_FractionalSec = 1 << 7,
|
||||
DN_AgeUnit_HMS = DN_AgeUnit_Sec | DN_AgeUnit_Min | DN_AgeUnit_Hr,
|
||||
DN_AgeUnit_All = DN_AgeUnit_Ms | DN_AgeUnit_HMS | DN_AgeUnit_Day | DN_AgeUnit_Week | DN_AgeUnit_Year,
|
||||
};
|
||||
|
||||
enum DN_ByteCountType
|
||||
{
|
||||
DN_ByteCountType_B,
|
||||
DN_ByteCountType_KiB,
|
||||
DN_ByteCountType_MiB,
|
||||
DN_ByteCountType_GiB,
|
||||
DN_ByteCountType_TiB,
|
||||
DN_ByteCountType_Count,
|
||||
DN_ByteCountType_Auto,
|
||||
};
|
||||
|
||||
struct DN_ByteCountResult
|
||||
{
|
||||
DN_ByteCountType type;
|
||||
DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c
|
||||
DN_F64 bytes;
|
||||
};
|
||||
|
||||
struct DN_FmtAppendResult
|
||||
{
|
||||
DN_USize size_req;
|
||||
DN_Str8 str8;
|
||||
bool truncated;
|
||||
};
|
||||
|
||||
#if !defined(DN_STB_SPRINTF_HEADER_ONLY)
|
||||
#define STB_SPRINTF_IMPLEMENTATION
|
||||
#define STB_SPRINTF_STATIC
|
||||
#endif
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(4505) // Unused function warning
|
||||
DN_GCC_WARNING_PUSH
|
||||
DN_GCC_WARNING_DISABLE(-Wunused-function)
|
||||
#include "../External/stb_sprintf.h"
|
||||
DN_GCC_WARNING_POP
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
#define DN_SPrintF(...) STB_SPRINTF_DECORATE(sprintf)(__VA_ARGS__)
|
||||
#define DN_SNPrintF(...) STB_SPRINTF_DECORATE(snprintf)(__VA_ARGS__)
|
||||
#define DN_VSPrintF(...) STB_SPRINTF_DECORATE(vsprintf)(__VA_ARGS__)
|
||||
#define DN_VSNPrintF(...) STB_SPRINTF_DECORATE(vsnprintf)(__VA_ARGS__)
|
||||
|
||||
DN_API bool DN_MemEq (void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size);
|
||||
|
||||
DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value);
|
||||
DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value);
|
||||
|
||||
DN_API DN_CPUIDResult DN_CPUID (DN_CPUIDArgs args);
|
||||
DN_API DN_USize DN_CPUHasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size);
|
||||
DN_API bool DN_CPUHasFeature (DN_CPUReport const *report, DN_CPUFeature feature);
|
||||
DN_API bool DN_CPUHasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size);
|
||||
DN_API void DN_CPUSetFeature (DN_CPUReport *report, DN_CPUFeature feature);
|
||||
DN_API DN_CPUReport DN_CPUGetReport ();
|
||||
|
||||
DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex);
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex);
|
||||
DN_API void DN_TicketMutex_BeginTicket (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket);
|
||||
|
||||
DN_API void DN_BitUnsetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API void DN_BitSetInplace (DN_USize *flags, DN_USize bitfield);
|
||||
DN_API bool DN_BitIsSet (DN_USize bits, DN_USize bits_to_set);
|
||||
DN_API bool DN_BitIsNotSet (DN_USize bits, DN_USize bits_to_check);
|
||||
#define DN_BitClearNextLSB(value) (value) & ((value) - 1)
|
||||
|
||||
DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b);
|
||||
DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b);
|
||||
|
||||
DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b);
|
||||
|
||||
DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b);
|
||||
DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b);
|
||||
|
||||
DN_API int DN_SaturateCastUSizeToInt (DN_USize val);
|
||||
DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val);
|
||||
DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val);
|
||||
DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val);
|
||||
DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val);
|
||||
|
||||
DN_API int DN_SaturateCastU64ToInt (DN_U64 val);
|
||||
DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val);
|
||||
DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val);
|
||||
DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val);
|
||||
DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val);
|
||||
DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val);
|
||||
DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val);
|
||||
DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val);
|
||||
DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val);
|
||||
|
||||
DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val);
|
||||
DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val);
|
||||
DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val);
|
||||
DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val);
|
||||
|
||||
DN_API int DN_SaturateCastISizeToInt (DN_ISize val);
|
||||
DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val);
|
||||
DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val);
|
||||
DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val);
|
||||
DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val);
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val);
|
||||
DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val);
|
||||
DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val);
|
||||
DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val);
|
||||
DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val);
|
||||
|
||||
DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val);
|
||||
DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val);
|
||||
DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val);
|
||||
DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val);
|
||||
|
||||
DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val);
|
||||
DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val);
|
||||
DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val);
|
||||
DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val);
|
||||
DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val);
|
||||
DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val);
|
||||
|
||||
DN_API DN_I8 DN_SaturateCastIntToI8 (int val);
|
||||
DN_API DN_I16 DN_SaturateCastIntToI16 (int val);
|
||||
DN_API DN_U8 DN_SaturateCastIntToU8 (int val);
|
||||
DN_API DN_U16 DN_SaturateCastIntToU16 (int val);
|
||||
DN_API DN_U32 DN_SaturateCastIntToU32 (int val);
|
||||
DN_API DN_U64 DN_SaturateCastIntToU64 (int val);
|
||||
|
||||
DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
DN_API void DN_ASanUnpoisonMemoryRegion (void const volatile *ptr, DN_USize size);
|
||||
|
||||
DN_API DN_F32 DN_EpsilonClampF32 (DN_F32 value, DN_F32 target, DN_F32 epsilon);
|
||||
|
||||
DN_API DN_Arena DN_ArenaFromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_ArenaFromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs);
|
||||
DN_API void DN_ArenaDeinit (DN_Arena *arena);
|
||||
DN_API bool DN_ArenaCommit (DN_Arena *arena, DN_U64 size);
|
||||
DN_API bool DN_ArenaCommitTo (DN_Arena *arena, DN_U64 pos);
|
||||
DN_API bool DN_ArenaGrow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit);
|
||||
DN_API void * DN_ArenaAlloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem);
|
||||
DN_API void * DN_ArenaAllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem);
|
||||
DN_API void * DN_ArenaCopy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align);
|
||||
DN_API void DN_ArenaPopTo (DN_Arena *arena, DN_U64 init_used);
|
||||
DN_API void DN_ArenaPop (DN_Arena *arena, DN_U64 amount);
|
||||
DN_API DN_U64 DN_ArenaPos (DN_Arena const *arena);
|
||||
DN_API void DN_ArenaClear (DN_Arena *arena);
|
||||
DN_API bool DN_ArenaOwnsPtr (DN_Arena const *arena, void *ptr);
|
||||
DN_API DN_ArenaStats DN_ArenaSumStatsArray (DN_ArenaStats const *array, DN_USize size);
|
||||
DN_API DN_ArenaStats DN_ArenaSumStats (DN_ArenaStats lhs, DN_ArenaStats rhs);
|
||||
DN_API DN_ArenaStats DN_ArenaSumArenaArrayToStats(DN_Arena const *array, DN_USize size);
|
||||
DN_API DN_ArenaTempMem DN_ArenaTempMemBegin (DN_Arena *arena);
|
||||
DN_API void DN_ArenaTempMemEnd (DN_ArenaTempMem mem);
|
||||
#define DN_ArenaNew(arena, T, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), zmem)
|
||||
#define DN_ArenaNewZ(arena, T) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), DN_ZMem_Yes)
|
||||
|
||||
#define DN_ArenaNewContiguous(arena, T, zmem) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), zmem)
|
||||
#define DN_ArenaNewContiguousZ(arena, T) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), DN_ZMem_Yes)
|
||||
|
||||
#define DN_ArenaNewArray(arena, T, count, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), zmem)
|
||||
#define DN_ArenaNewArrayZ(arena, T, count) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), DN_ZMem_Yes)
|
||||
|
||||
#define DN_ArenaNewCopy(arena, T, src) (T *)DN_ArenaCopy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_ArenaNewArrayCopy(arena, T, src, count) (T *)DN_ArenaCopy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
DN_API DN_Pool DN_PoolFromArena (DN_Arena *arena, DN_U8 align);
|
||||
DN_API bool DN_PoolIsValid (DN_Pool const *pool);
|
||||
DN_API void * DN_PoolAlloc (DN_Pool *pool, DN_USize size);
|
||||
DN_API void DN_PoolDealloc (DN_Pool *pool, void *ptr);
|
||||
DN_API void * DN_PoolCopy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align);
|
||||
#define DN_PoolNew(pool, T) (T *)DN_PoolAlloc(pool, sizeof(T))
|
||||
#define DN_PoolNewArray(pool, T, count) (T *)DN_PoolAlloc(pool, count * sizeof(T))
|
||||
#define DN_PoolNewCopy(pool, T, src) (T *)DN_PoolCopy (pool, (src), sizeof(T), alignof(T))
|
||||
#define DN_PoolNewArrayCopy(pool, T, src, count) (T *)DN_PoolCopy (pool, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
DN_API bool DN_CharIsAlphabet (char ch);
|
||||
DN_API bool DN_CharIsDigit (char ch);
|
||||
DN_API bool DN_CharIsAlphaNum (char ch);
|
||||
DN_API bool DN_CharIsWhitespace (char ch);
|
||||
DN_API bool DN_CharIsHex (char ch);
|
||||
DN_API char DN_CharToLower (char ch);
|
||||
DN_API char DN_CharToUpper (char ch);
|
||||
|
||||
DN_API DN_U64FromResult DN_U64FromStr8 (DN_Str8 string, char separator);
|
||||
DN_API DN_U64FromResult DN_U64FromPtr (void const *data, DN_USize size, char separator);
|
||||
DN_API DN_U64 DN_U64FromPtrUnsafe (void const *data, DN_USize size, char separator);
|
||||
DN_API DN_U64FromResult DN_U64FromHexPtr (void const *hex, DN_USize hex_count);
|
||||
DN_API DN_U64 DN_U64FromHexPtrUnsafe (void const *hex, DN_USize hex_count);
|
||||
DN_API DN_U64FromResult DN_U64FromHexStr8 (DN_Str8 hex);
|
||||
DN_API DN_U64 DN_U64FromHexStr8Unsafe (DN_Str8 hex);
|
||||
DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string, char separator);
|
||||
DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size, char separator);
|
||||
DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size, char separator);
|
||||
|
||||
DN_API DN_USize DN_FmtVSize (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_USize DN_FmtSize (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_FmtAppendResult DN_FmtVAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args);
|
||||
DN_API DN_FmtAppendResult DN_FmtAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...);
|
||||
DN_API DN_FmtAppendResult DN_FmtAppendTruncate (char *buf, DN_USize *buf_size, DN_USize buf_max, DN_Str8 truncator, char const *fmt, ...);
|
||||
DN_API DN_USize DN_CStr8Size (char const *src);
|
||||
DN_API DN_USize DN_CStr16Size (wchar_t const *src);
|
||||
|
||||
#define DN_Str16Lit(string) DN_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1}
|
||||
#define DN_Str8Lit(c_str) DN_Literal(DN_Str8){(char *)(c_str), sizeof(c_str) - 1}
|
||||
#define DN_Str8PrintFmt(string) (int)((string).size), (string).data
|
||||
#define DN_Str8FromPtr(data, size) DN_Literal(DN_Str8){(char *)(data), (DN_USize)(size)}
|
||||
#define DN_Str8FromStruct(ptr) DN_Str8FromPtr((ptr)->data, (ptr)->size)
|
||||
DN_API DN_Str8 DN_Str8FromCStr8 (char const *src);
|
||||
DN_API DN_Str8 DN_Str8FromArena (DN_Arena *arena, DN_USize size, DN_ZMem z_mem);
|
||||
DN_API DN_Str8 DN_Str8FromPool (DN_Pool *pool, DN_USize size);
|
||||
DN_API DN_Str8 DN_Str8FromStr8Arena (DN_Arena *pool, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FromStr8Pool (DN_Pool *pool, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type);
|
||||
DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8IsAll (DN_Str8 string, DN_Str8IsAllType is_all);
|
||||
DN_API char * DN_Str8End (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8Slice (DN_Str8 string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8 DN_Str8Advance (DN_Str8 string, DN_USize amount);
|
||||
DN_API DN_Str8 DN_Str8NextLine (DN_Str8 string);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplit (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitLast (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_USize DN_Str8Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8SplitResult DN_Str8SplitArena (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8FindResult DN_Str8FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8Find (DN_Str8 string, uint32_t flags);
|
||||
DN_API DN_Str8 DN_Str8Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API bool DN_Str8Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8EqInsensitive (DN_Str8 lhs, DN_Str8 rhs);
|
||||
DN_API bool DN_Str8StartsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8StartsWithInsensitive(DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8EndsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8EndsWithInsensitive (DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8HasChar (DN_Str8 string, char ch);
|
||||
DN_API DN_Str8 DN_Str8TrimPrefix (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8TrimHexPrefix (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimSuffix (DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8TrimAround (DN_Str8 string, DN_Str8 trim_string);
|
||||
DN_API DN_Str8 DN_Str8TrimHeadWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimTailWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimWhitespaceAround (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8TrimByteOrderMark (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FileNameFromPath (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FileNameNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FilePathNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FileExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8FileDirectoryFromPath(DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8AppendF (DN_Arena *arena, DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8AppendFV (DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8FillF (DN_Arena *arena, DN_USize count, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FillFV (DN_Arena *arena, DN_USize count, char const *fmt, va_list args);
|
||||
DN_API void DN_Str8Remove (DN_Str8 *string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8TruncateResult DN_Str8TruncateMiddle (DN_Arena *arena, DN_Str8 str8, DN_U32 side_size, DN_Str8 truncator);
|
||||
DN_API DN_Str8 DN_Str8Lower (DN_Arena *arena, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8Upper (DN_Arena *arena, DN_Str8 string);
|
||||
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromArena (DN_Arena *arena);
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromBuilder (DN_Arena *arena, DN_Str8Builder const *builder);
|
||||
DN_API bool DN_Str8BuilderAddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8BuilderAddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8BuilderAddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
#define DN_Str8BuilderAppendArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8BuilderAppendArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8BuilderAppendSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8BuilderAppendSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
DN_API bool DN_Str8BuilderAppendRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8BuilderAppendCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8BuilderAppendFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Append, fmt, args)
|
||||
DN_API bool DN_Str8BuilderAppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8BuilderAppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8BuilderAppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8BuilderAppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
DN_API bool DN_Str8BuilderAppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
#define DN_Str8BuilderPrependArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8BuilderPrependArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8BuilderPrependSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8BuilderPrependSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
DN_API bool DN_Str8BuilderPrependRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8BuilderPrependCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8BuilderPrependFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args)
|
||||
DN_API bool DN_Str8BuilderPrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8BuilderErase (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8BuilderBuild (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8BuilderBuildSlice (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
|
||||
DN_API int DN_EncodeUTF8Codepoint (uint8_t utf8[4], uint32_t codepoint);
|
||||
DN_API int DN_EncodeUTF16Codepoint (uint16_t utf16[2], uint32_t codepoint);
|
||||
|
||||
DN_API DN_U8 DN_U8FromHexNibble (char hex);
|
||||
DN_API DN_NibbleFromU8Result DN_NibbleFromU8 (DN_U8 u8);
|
||||
|
||||
DN_API DN_USize DN_BytesFromHexPtr (void const *hex, DN_USize hex_count, void *dest, DN_USize dest_count);
|
||||
DN_API DN_Str8 DN_BytesFromHexPtrArena (void const *hex, DN_USize hex_count, DN_Arena *arena);
|
||||
DN_API DN_USize DN_BytesFromHexStr8 (DN_Str8 hex, void *dest, DN_USize dest_count);
|
||||
DN_API DN_Str8 DN_BytesFromHexStr8Arena (DN_Str8 hex, DN_Arena *arena);
|
||||
DN_API DN_U8x16 DN_BytesFromHex32Ptr (void const *hex, DN_USize hex_count);
|
||||
DN_API DN_U8x32 DN_BytesFromHex64Ptr (void const *hex, DN_USize hex_count);
|
||||
|
||||
DN_API DN_HexU64Str8 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type);
|
||||
DN_API DN_USize DN_HexFromBytesPtr (void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count);
|
||||
DN_API DN_Str8 DN_HexFromBytesPtrArena (void const *bytes, DN_USize bytes_count, DN_Arena *arena);
|
||||
DN_API DN_Hex32 DN_HexFromBytes16Ptr (void const *bytes, DN_USize bytes_count);
|
||||
DN_API DN_Hex64 DN_HexFromBytes32Ptr (void const *bytes, DN_USize bytes_count);
|
||||
DN_API DN_Hex128 DN_HexFromBytes64Ptr (void const *bytes, DN_USize bytes_count);
|
||||
|
||||
DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
||||
DN_API DN_Str8x128 DN_AgeStr8FromSecU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
||||
DN_API DN_Str8x128 DN_AgeStr8FromSecF64 (DN_F64 sec, DN_AgeUnit units);
|
||||
|
||||
DN_API DN_ByteCountResult DN_ByteCountFromType (DN_U64 bytes, DN_ByteCountType type);
|
||||
#define DN_ByteCount(bytes) DN_ByteCountFromType(bytes, DN_ByteCountType_Auto)
|
||||
DN_API DN_Str8x32 DN_ByteCountStr8x32FromType (DN_U64 bytes, DN_ByteCountType type);
|
||||
#define DN_ByteCountStr8x32(bytes) DN_ByteCountStr8x32FromType(bytes, DN_ByteCountType_Auto)
|
||||
|
||||
#endif // !defined(DN_BASE_H)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
DN_Str8PrintFmt(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
@ -24,7 +24,7 @@
|
||||
if (!(expr)) { \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
DN_Str8PrintFmt(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
@ -37,7 +37,7 @@
|
||||
once = false; \
|
||||
DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
||||
DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
||||
DN_STR_FMT(stack_trace_), \
|
||||
DN_Str8PrintFmt(stack_trace_), \
|
||||
##__VA_ARGS__); \
|
||||
DN_DebugBreak; \
|
||||
} \
|
||||
|
||||
@ -130,7 +130,7 @@
|
||||
#endif
|
||||
|
||||
// NOTE: Type Cast /////////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_CAST(val) (val)
|
||||
#define DN_Cast(val) (val)
|
||||
|
||||
// NOTE: Zero initialisation macro /////////////////////////////////////////////////////////////////
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@ -10,14 +10,14 @@ DN_API void *DN_CArray2_InsertArray(void *data, DN_USize *size, DN_USize max, DN
|
||||
|
||||
DN_USize clamped_index = DN_Min(index, *size);
|
||||
if (clamped_index != *size) {
|
||||
char const *src = DN_CAST(char *)data + (clamped_index * elem_size);
|
||||
char const *dest = DN_CAST(char *)data + ((clamped_index + count) * elem_size);
|
||||
char const *end = DN_CAST(char *)data + (size[0] * elem_size);
|
||||
char const *src = DN_Cast(char *)data + (clamped_index * elem_size);
|
||||
char const *dest = DN_Cast(char *)data + ((clamped_index + count) * elem_size);
|
||||
char const *end = DN_Cast(char *)data + (size[0] * elem_size);
|
||||
DN_USize bytes_to_move = end - src;
|
||||
DN_Memmove(DN_CAST(void *) dest, src, bytes_to_move);
|
||||
DN_Memmove(DN_Cast(void *) dest, src, bytes_to_move);
|
||||
}
|
||||
|
||||
result = DN_CAST(char *)data + (clamped_index * elem_size);
|
||||
result = DN_Cast(char *)data + (clamped_index * elem_size);
|
||||
DN_Memcpy(result, items, elem_size * count);
|
||||
*size += count;
|
||||
return result;
|
||||
@ -66,14 +66,14 @@ DN_API DN_ArrayEraseResult DN_CArray2_EraseRange(void *data, DN_USize *size, DN_
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem)
|
||||
DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZMem z_mem)
|
||||
{
|
||||
void *result = nullptr;
|
||||
DN_USize new_size = *size + make_size;
|
||||
if (new_size <= max) {
|
||||
result = DN_CAST(char *) data + (data_size * size[0]);
|
||||
result = DN_Cast(char *) data + (data_size * size[0]);
|
||||
*size = new_size;
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(result, 0, data_size * make_size);
|
||||
}
|
||||
|
||||
@ -82,13 +82,13 @@ DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_U
|
||||
|
||||
DN_API void *DN_CArray2_AddArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add)
|
||||
{
|
||||
void *result = DN_CArray2_MakeArray(data, size, max, data_size, elems_count, DN_ZeroMem_No);
|
||||
void *result = DN_CArray2_MakeArray(data, size, max, data_size, elems_count, DN_ZMem_No);
|
||||
if (result) {
|
||||
if (add == DN_ArrayAdd_Append) {
|
||||
DN_Memcpy(result, elems, elems_count * data_size);
|
||||
} else {
|
||||
char *move_dest = DN_CAST(char *)data + (elems_count * data_size); // Shift elements forward
|
||||
char *move_src = DN_CAST(char *)data;
|
||||
char *move_dest = DN_Cast(char *)data + (elems_count * data_size); // Shift elements forward
|
||||
char *move_src = DN_Cast(char *)data;
|
||||
DN_Memmove(move_dest, move_src, data_size * size[0]);
|
||||
DN_Memcpy(data, elems, data_size * elems_count);
|
||||
}
|
||||
@ -101,11 +101,11 @@ DN_API bool DN_CArray2_ResizeFromPool(void **data, DN_USize *size, DN_USize *max
|
||||
bool result = true;
|
||||
if (new_max != *max) {
|
||||
DN_USize bytes_to_alloc = data_size * new_max;
|
||||
void *buffer = DN_Pool_NewArray(pool, DN_U8, bytes_to_alloc);
|
||||
void *buffer = DN_PoolNewArray(pool, DN_U8, bytes_to_alloc);
|
||||
if (buffer) {
|
||||
DN_USize bytes_to_copy = data_size * DN_Min(*size, new_max);
|
||||
DN_Memcpy(buffer, *data, bytes_to_copy);
|
||||
DN_Pool_Dealloc(pool, *data);
|
||||
DN_PoolDealloc(pool, *data);
|
||||
*data = buffer;
|
||||
*max = new_max;
|
||||
*size = DN_Min(*size, new_max);
|
||||
@ -243,7 +243,7 @@ DN_ArrayEraseResult DN_CArray_EraseRange(T *data, DN_USize *size, DN_USize begin
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZeroMem zero_mem)
|
||||
T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZMem z_mem)
|
||||
{
|
||||
if (!data || !size || count == 0)
|
||||
return nullptr;
|
||||
@ -254,7 +254,7 @@ T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN
|
||||
// TODO: Use placement new? Why doesn't this work?
|
||||
T *result = data + *size;
|
||||
*size += count;
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(result, 0, sizeof(*result) * count);
|
||||
return result;
|
||||
}
|
||||
@ -268,11 +268,11 @@ T *DN_CArray_InsertArray(T *data, DN_USize *size, DN_USize max, DN_USize index,
|
||||
|
||||
DN_USize clamped_index = DN_Min(index, *size);
|
||||
if (clamped_index != *size) {
|
||||
char const *src = DN_CAST(char *)(data + clamped_index);
|
||||
char const *dest = DN_CAST(char *)(data + (clamped_index + count));
|
||||
char const *end = DN_CAST(char *)(data + (*size));
|
||||
char const *src = DN_Cast(char *)(data + clamped_index);
|
||||
char const *dest = DN_Cast(char *)(data + (clamped_index + count));
|
||||
char const *end = DN_Cast(char *)(data + (*size));
|
||||
DN_USize bytes_to_move = end - src;
|
||||
DN_Memmove(DN_CAST(void *) dest, src, bytes_to_move);
|
||||
DN_Memmove(DN_Cast(void *) dest, src, bytes_to_move);
|
||||
}
|
||||
|
||||
result = data + clamped_index;
|
||||
@ -329,34 +329,34 @@ DN_ArrayFindResult<T> DN_CArray_Find(T *data, DN_USize size, T const &value)
|
||||
#if !defined(DN_NO_SARRAY)
|
||||
// NOTE: DN_SArray /////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
DN_SArray<T> DN_SArray_Init(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_SArray<T> DN_SArray_Init(DN_Arena *arena, DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_SArray<T> result = {};
|
||||
if (!arena || !size)
|
||||
return result;
|
||||
result.data = DN_Arena_NewArray(arena, T, size, zero_mem);
|
||||
result.data = DN_ArenaNewArray(arena, T, size, z_mem);
|
||||
if (result.data)
|
||||
result.max = size;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DN_SArray<T> DN_SArray_InitSlice(DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_SArray<T> DN_SArray_InitSlice(DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_USize max = DN_Max(slice.size, size);
|
||||
DN_SArray<T> result = DN_SArray_Init<T>(arena, max, DN_ZeroMem_No);
|
||||
DN_SArray<T> result = DN_SArray_Init<T>(arena, max, DN_ZMem_No);
|
||||
if (DN_SArray_IsValid(&result)) {
|
||||
DN_SArray_AddArray(&result, slice.data, slice.size);
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(result.data + result.size, 0, (result.max - result.size) * sizeof(T));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, size_t N>
|
||||
DN_SArray<T> DN_SArray_InitCArray(DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_SArray<T> DN_SArray_InitCArray(DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_SArray<T> result = DN_SArray_InitSlice(arena, DN_Slice_Init(DN_CAST(T *) array, N), size, zero_mem);
|
||||
DN_SArray<T> result = DN_SArray_InitSlice(arena, DN_Slice_Init(DN_Cast(T *) array, N), size, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -381,30 +381,30 @@ DN_Slice<T> DN_SArray_Slice(DN_SArray<T> const *array)
|
||||
{
|
||||
DN_Slice<T> result = {};
|
||||
if (array)
|
||||
result = DN_Slice_Init<T>(DN_CAST(T *) array->data, array->size);
|
||||
result = DN_Slice_Init<T>(DN_Cast(T *) array->data, array->size);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_SArray_MakeArray(DN_SArray<T> *array, DN_USize count, DN_ZeroMem zero_mem)
|
||||
T *DN_SArray_MakeArray(DN_SArray<T> *array, DN_USize count, DN_ZMem z_mem)
|
||||
{
|
||||
if (!DN_SArray_IsValid(array))
|
||||
return nullptr;
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, array->max, count, zero_mem);
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, array->max, count, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_SArray_Make(DN_SArray<T> *array, DN_ZeroMem zero_mem)
|
||||
T *DN_SArray_Make(DN_SArray<T> *array, DN_ZMem z_mem)
|
||||
{
|
||||
T *result = DN_SArray_MakeArray(array, 1, zero_mem);
|
||||
T *result = DN_SArray_MakeArray(array, 1, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_SArray_AddArray(DN_SArray<T> *array, T const *items, DN_USize count)
|
||||
{
|
||||
T *result = DN_SArray_MakeArray(array, count, DN_ZeroMem_No);
|
||||
T *result = DN_SArray_MakeArray(array, count, DN_ZMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, items, count * sizeof(T));
|
||||
return result;
|
||||
@ -517,14 +517,14 @@ DN_Slice<T> DN_FArray_Slice(DN_FArray<T, N> const *array)
|
||||
{
|
||||
DN_Slice<T> result = {};
|
||||
if (array)
|
||||
result = DN_Slice_Init<T>(DN_CAST(T *) array->data, array->size);
|
||||
result = DN_Slice_Init<T>(DN_Cast(T *) array->data, array->size);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, DN_USize N>
|
||||
T *DN_FArray_AddArray(DN_FArray<T, N> *array, T const *items, DN_USize count)
|
||||
{
|
||||
T *result = DN_FArray_MakeArray(array, count, DN_ZeroMem_No);
|
||||
T *result = DN_FArray_MakeArray(array, count, DN_ZMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, items, count * sizeof(T));
|
||||
return result;
|
||||
@ -533,7 +533,7 @@ T *DN_FArray_AddArray(DN_FArray<T, N> *array, T const *items, DN_USize count)
|
||||
template <typename T, DN_USize N, DN_USize K>
|
||||
T *DN_FArray_AddCArray(DN_FArray<T, N> *array, T const (&items)[K])
|
||||
{
|
||||
T *result = DN_FArray_MakeArray(array, K, DN_ZeroMem_No);
|
||||
T *result = DN_FArray_MakeArray(array, K, DN_ZMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, items, K * sizeof(T));
|
||||
return result;
|
||||
@ -547,18 +547,18 @@ T *DN_FArray_Add(DN_FArray<T, N> *array, T const &item)
|
||||
}
|
||||
|
||||
template <typename T, DN_USize N>
|
||||
T *DN_FArray_MakeArray(DN_FArray<T, N> *array, DN_USize count, DN_ZeroMem zero_mem)
|
||||
T *DN_FArray_MakeArray(DN_FArray<T, N> *array, DN_USize count, DN_ZMem z_mem)
|
||||
{
|
||||
if (!DN_FArray_IsValid(array))
|
||||
return nullptr;
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, N, count, zero_mem);
|
||||
T *result = DN_CArray_MakeArray(array->data, &array->size, N, count, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, DN_USize N>
|
||||
T *DN_FArray_Make(DN_FArray<T, N> *array, DN_ZeroMem zero_mem)
|
||||
T *DN_FArray_Make(DN_FArray<T, N> *array, DN_ZMem z_mem)
|
||||
{
|
||||
T *result = DN_FArray_MakeArray(array, 1, zero_mem);
|
||||
T *result = DN_FArray_MakeArray(array, 1, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -640,7 +640,7 @@ DN_Slice<T> DN_Slice_Init(T *const data, DN_USize size)
|
||||
template <typename T, DN_USize N>
|
||||
DN_Slice<T> DN_Slice_InitCArrayCopy(DN_Arena *arena, T const (&array)[N])
|
||||
{
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, N, DN_ZeroMem_No);
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, N, DN_ZMem_No);
|
||||
if (result.data)
|
||||
DN_Memcpy(result.data, array, sizeof(T) * N);
|
||||
return result;
|
||||
@ -649,7 +649,7 @@ DN_Slice<T> DN_Slice_InitCArrayCopy(DN_Arena *arena, T const (&array)[N])
|
||||
template <typename T>
|
||||
DN_Slice<T> DN_Slice_CopyPtr(DN_Arena *arena, T *const data, DN_USize size)
|
||||
{
|
||||
T *copy = DN_Arena_NewArrayCopy(arena, T, data, size);
|
||||
T *copy = DN_ArenaNewArrayCopy(arena, T, data, size);
|
||||
DN_Slice<T> result = DN_Slice_Init(copy, copy ? size : 0);
|
||||
return result;
|
||||
}
|
||||
@ -662,12 +662,12 @@ DN_Slice<T> DN_Slice_Copy(DN_Arena *arena, DN_Slice<T> slice)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DN_Slice<T> DN_Slice_Alloc(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_Slice<T> DN_Slice_Alloc(DN_Arena *arena, DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_Slice<T> result = {};
|
||||
if (!arena || size == 0)
|
||||
return result;
|
||||
result.data = DN_Arena_NewArray(arena, T, size, zero_mem);
|
||||
result.data = DN_ArenaNewArray(arena, T, size, z_mem);
|
||||
if (result.data)
|
||||
result.size = size;
|
||||
return result;
|
||||
@ -691,9 +691,9 @@ DN_DSMap<T> DN_DSMap_Init(DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags)
|
||||
if (!DN_Check(arena))
|
||||
return result;
|
||||
result.arena = arena;
|
||||
result.pool = DN_Pool_FromArena(arena, DN_POOL_DEFAULT_ALIGN);
|
||||
result.hash_to_slot = DN_Arena_NewArray(result.arena, DN_U32, size, DN_ZeroMem_Yes);
|
||||
result.slots = DN_Arena_NewArray(result.arena, DN_DSMapSlot<T>, size, DN_ZeroMem_Yes);
|
||||
result.pool = DN_PoolFromArena(arena, DN_POOL_DEFAULT_ALIGN);
|
||||
result.hash_to_slot = DN_ArenaNewArray(result.arena, DN_U32, size, DN_ZMem_Yes);
|
||||
result.slots = DN_ArenaNewArray(result.arena, DN_DSMapSlot<T>, size, DN_ZMem_Yes);
|
||||
result.occupied = 1; // For sentinel
|
||||
result.size = size;
|
||||
result.initial_size = size;
|
||||
@ -703,13 +703,13 @@ DN_DSMap<T> DN_DSMap_Init(DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DN_DSMap_Deinit(DN_DSMap<T> *map, DN_ZeroMem zero_mem)
|
||||
void DN_DSMap_Deinit(DN_DSMap<T> *map, DN_ZMem z_mem)
|
||||
{
|
||||
if (!map)
|
||||
return;
|
||||
// TODO(doyle): Use zero_mem
|
||||
(void)zero_mem;
|
||||
DN_Arena_Deinit(map->arena);
|
||||
// TODO(doyle): Use z_mem
|
||||
(void)z_mem;
|
||||
DN_ArenaDeinit(map->arena);
|
||||
*map = {};
|
||||
}
|
||||
|
||||
@ -733,7 +733,7 @@ DN_U32 DN_DSMap_Hash(DN_DSMap<T> const *map, DN_DSMapKey key)
|
||||
return result;
|
||||
|
||||
if (key.type == DN_DSMapKeyType_U64NoHash) {
|
||||
result = DN_CAST(DN_U32) key.u64;
|
||||
result = DN_Cast(DN_U32) key.u64;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -761,12 +761,12 @@ DN_U32 DN_DSMap_Hash(DN_DSMap<T> const *map, DN_DSMapKey key)
|
||||
case DN_DSMapKeyType_Invalid: break;
|
||||
|
||||
case DN_DSMapKeyType_Buffer:
|
||||
key_ptr = DN_CAST(char const *) key.buffer_data;
|
||||
key_ptr = DN_Cast(char const *) key.buffer_data;
|
||||
len = key.buffer_size;
|
||||
break;
|
||||
|
||||
case DN_DSMapKeyType_U64:
|
||||
key_ptr = DN_CAST(char const *) & key.u64;
|
||||
key_ptr = DN_Cast(char const *) & key.u64;
|
||||
len = sizeof(key.u64);
|
||||
break;
|
||||
}
|
||||
@ -870,7 +870,7 @@ DN_DSMapResult<T> DN_DSMap_Make(DN_DSMap<T> *map, DN_DSMapKey key)
|
||||
if ((key.type == DN_DSMapKeyType_Buffer ||
|
||||
key.type == DN_DSMapKeyType_BufferAsU64NoHash) &&
|
||||
!key.no_copy_buffer)
|
||||
result.slot->key.buffer_data = DN_Pool_NewArrayCopy(&map->pool, char, key.buffer_data, key.buffer_size);
|
||||
result.slot->key.buffer_data = DN_PoolNewArrayCopy(&map->pool, char, key.buffer_data, key.buffer_size);
|
||||
}
|
||||
} else {
|
||||
result.slot = map->slots + map->hash_to_slot[index];
|
||||
@ -970,7 +970,7 @@ bool DN_DSMap_Resize(DN_DSMap<T> *map, DN_U32 size)
|
||||
}
|
||||
|
||||
if ((map->flags & DN_DSMapFlags_DontFreeArenaOnResize) == 0)
|
||||
DN_DSMap_Deinit(map, DN_ZeroMem_No);
|
||||
DN_DSMap_Deinit(map, DN_ZMem_No);
|
||||
*map = new_map; // Update the map inplace
|
||||
map->arena = prev_arena; // Restore the previous arena pointer, it's been de-init-ed
|
||||
*map->arena = new_arena; // Re-init the old arena with the new data
|
||||
@ -997,7 +997,7 @@ bool DN_DSMap_Erase(DN_DSMap<T> *map, DN_DSMapKey key)
|
||||
|
||||
DN_DSMapSlot<T> *slot = map->slots + slot_index;
|
||||
if (!slot->key.no_copy_buffer)
|
||||
DN_Pool_Dealloc(&map->pool, DN_CAST(void *) slot->key.buffer_data);
|
||||
DN_PoolDealloc(&map->pool, DN_Cast(void *) slot->key.buffer_data);
|
||||
*slot = {}; // TODO: Optional?
|
||||
|
||||
if (map->occupied > 1 /*Sentinel*/) {
|
||||
@ -1074,7 +1074,7 @@ DN_DSMapKey DN_DSMap_KeyBuffer(DN_DSMap<T> const *map, void const *data, DN_USiz
|
||||
DN_DSMapKey result = {};
|
||||
result.type = DN_DSMapKeyType_Buffer;
|
||||
result.buffer_data = data;
|
||||
result.buffer_size = DN_CAST(DN_U32) size;
|
||||
result.buffer_size = DN_Cast(DN_U32) size;
|
||||
result.hash = DN_DSMap_Hash(map, result);
|
||||
return result;
|
||||
}
|
||||
@ -1085,7 +1085,7 @@ DN_DSMapKey DN_DSMap_KeyBufferAsU64NoHash(DN_DSMap<T> const *map, void const *da
|
||||
DN_DSMapKey result = {};
|
||||
result.type = DN_DSMapKeyType_BufferAsU64NoHash;
|
||||
result.buffer_data = data;
|
||||
result.buffer_size = DN_CAST(DN_U32) size;
|
||||
result.buffer_size = DN_Cast(DN_U32) size;
|
||||
DN_Assert(size >= sizeof(result.hash));
|
||||
DN_Memcpy(&result.hash, data, sizeof(result.hash));
|
||||
return result;
|
||||
@ -1158,16 +1158,16 @@ DN_API bool DN_List_AttachTail_(DN_List<T> *list, DN_ListChunk<T> *tail)
|
||||
template <typename T>
|
||||
DN_API DN_ListChunk<T> *DN_List_AllocArena_(DN_List<T> *list, DN_Arena *arena, DN_USize count)
|
||||
{
|
||||
auto *result = DN_Arena_New(arena, DN_ListChunk<T>, DN_ZeroMem_Yes);
|
||||
DN_ArenaTempMem tmem = DN_Arena_TempMemBegin(arena);
|
||||
auto *result = DN_ArenaNew(arena, DN_ListChunk<T>, DN_ZMem_Yes);
|
||||
DN_ArenaTempMem tmem = DN_ArenaTempMemBegin(arena);
|
||||
if (!result)
|
||||
return nullptr;
|
||||
|
||||
DN_USize items = DN_Max(list->chunk_size, count);
|
||||
result->data = DN_Arena_NewArray(arena, T, items, DN_ZeroMem_Yes);
|
||||
result->data = DN_ArenaNewArray(arena, T, items, DN_ZMem_Yes);
|
||||
result->size = items;
|
||||
if (!result->data) {
|
||||
DN_Arena_TempMemEnd(tmem);
|
||||
DN_ArenaTempMemEnd(tmem);
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
@ -1178,15 +1178,15 @@ DN_API DN_ListChunk<T> *DN_List_AllocArena_(DN_List<T> *list, DN_Arena *arena, D
|
||||
template <typename T>
|
||||
DN_API DN_ListChunk<T> *DN_List_AllocPool_(DN_List<T> *list, DN_Pool *pool, DN_USize count)
|
||||
{
|
||||
auto *result = DN_Pool_New(pool, DN_ListChunk<T>);
|
||||
auto *result = DN_PoolNew(pool, DN_ListChunk<T>);
|
||||
if (!result)
|
||||
return nullptr;
|
||||
|
||||
DN_USize items = DN_Max(list->chunk_size, count);
|
||||
result->data = DN_Pool_NewArray(pool, T, items);
|
||||
result->data = DN_PoolNewArray(pool, T, items);
|
||||
result->size = items;
|
||||
if (!result->data) {
|
||||
DN_Pool_Dealloc(result);
|
||||
DN_PoolDealloc(result);
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
@ -1349,12 +1349,12 @@ template <typename T>
|
||||
DN_Slice<T> DN_List_ToSliceCopy(DN_List<T> const *list, DN_Arena *arena)
|
||||
{
|
||||
// TODO(doyle): Chunk memcopies is much faster
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, list->count, DN_ZeroMem_No);
|
||||
DN_Slice<T> result = DN_Slice_Alloc<T>(arena, list->count, DN_ZMem_No);
|
||||
if (result.size) {
|
||||
DN_USize slice_index = 0;
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6011) // Dereferencing NULL pointer 'x'
|
||||
for (DN_ListIterator<T> it = {}; DN_List_Iterate<T>(DN_CAST(DN_List<T> *) list, &it, 0);)
|
||||
for (DN_ListIterator<T> it = {}; DN_List_Iterate<T>(DN_Cast(DN_List<T> *) list, &it, 0);)
|
||||
result.data[slice_index++] = *it.data;
|
||||
DN_MSVC_WARNING_POP
|
||||
DN_Assert(slice_index == result.size);
|
||||
@ -1378,7 +1378,7 @@ DN_API DN_Str8 DN_Slice_Str8Render(DN_Arena *arena, DN_Slice<DN_Str8> array, DN_
|
||||
total_size += item.size;
|
||||
}
|
||||
|
||||
result = DN_Str8_Alloc(arena, total_size, DN_ZeroMem_No);
|
||||
result = DN_Str8FromArena(arena, total_size, DN_ZMem_No);
|
||||
if (result.data) {
|
||||
DN_USize write_index = 0;
|
||||
for (DN_USize index = 0; index < array.size; index++) {
|
||||
@ -1397,7 +1397,7 @@ DN_API DN_Str8 DN_Slice_Str8Render(DN_Arena *arena, DN_Slice<DN_Str8> array, DN_
|
||||
|
||||
DN_API DN_Str8 DN_Slice_Str8RenderSpaceSeparated(DN_Arena *arena, DN_Slice<DN_Str8> array)
|
||||
{
|
||||
DN_Str8 result = DN_Slice_Str8Render(arena, array, DN_STR8(" "));
|
||||
DN_Str8 result = DN_Slice_Str8Render(arena, array, DN_Str8Lit(" "));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1415,7 +1415,7 @@ DN_API DN_Str16 DN_Slice_Str16Render(DN_Arena *arena, DN_Slice<DN_Str16> array,
|
||||
total_size += item.size;
|
||||
}
|
||||
|
||||
result = {DN_Arena_NewArray(arena, wchar_t, total_size + 1, DN_ZeroMem_No), total_size};
|
||||
result = {DN_ArenaNewArray(arena, wchar_t, total_size + 1, DN_ZMem_No), total_size};
|
||||
if (result.data) {
|
||||
DN_USize write_index = 0;
|
||||
for (DN_USize index = 0; index < array.size; index++) {
|
||||
@ -1435,7 +1435,7 @@ DN_API DN_Str16 DN_Slice_Str16Render(DN_Arena *arena, DN_Slice<DN_Str16> array,
|
||||
|
||||
DN_API DN_Str16 DN_Slice_Str16RenderSpaceSeparated(DN_Arena *arena, DN_Slice<DN_Str16> array)
|
||||
{
|
||||
DN_Str16 result = DN_Slice_Str16Render(arena, array, DN_STR16(L" "));
|
||||
DN_Str16 result = DN_Slice_Str16Render(arena, array, DN_Str16Lit(L" "));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1446,7 +1446,7 @@ DN_API DN_DSMapKey DN_DSMap_KeyU64NoHash(DN_U64 u64)
|
||||
DN_DSMapKey result = {};
|
||||
result.type = DN_DSMapKeyType_U64NoHash;
|
||||
result.u64 = u64;
|
||||
result.hash = DN_CAST(DN_U32) u64;
|
||||
result.hash = DN_Cast(DN_U32) u64;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -176,7 +176,7 @@ template <typename T> struct DN_List
|
||||
// ```
|
||||
// MyStruct buffer[TB_ASType_Count] = {};
|
||||
// DN_USize size = 0;
|
||||
// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZeroMem_No);
|
||||
// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZMem_No);
|
||||
// ```
|
||||
//
|
||||
// IArray => Intrusive Array
|
||||
@ -189,7 +189,7 @@ template <typename T> struct DN_List
|
||||
// DN_USize max;
|
||||
// } my_array = {};
|
||||
//
|
||||
// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZeroMem_No);
|
||||
// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZMem_No);
|
||||
// ```
|
||||
// ISLList => Intrusive Singly Linked List
|
||||
// Define a struct with the members 'next':
|
||||
@ -210,13 +210,13 @@ template <typename T> struct DN_List
|
||||
|
||||
#define DN_DLList_InitArena(list, T, arena) \
|
||||
do { \
|
||||
(list) = DN_Arena_New(arena, T, DN_ZeroMem_Yes); \
|
||||
(list) = DN_ArenaNew(arena, T, DN_ZMem_Yes); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
|
||||
#define DN_DLList_InitPool(list, T, pool) \
|
||||
do { \
|
||||
(list) = DN_Pool_New(pool, T); \
|
||||
(list) = DN_PoolNew(pool, T); \
|
||||
DN_DLList_Init(list); \
|
||||
} while (0)
|
||||
|
||||
@ -278,10 +278,10 @@ template <typename T> struct DN_List
|
||||
#define DN_LArray_ResizeFromPool(c_array, size, max, pool, new_max) DN_CArray2_ResizeFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max)
|
||||
#define DN_LArray_GrowFromPool(c_array, size, max, pool, new_max) DN_CArray2_GrowFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max)
|
||||
#define DN_LArray_GrowIfNeededFromPool(c_array, size, max, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(c_array), size, max, sizeof((c_array)[0]), pool, add_count)
|
||||
#define DN_LArray_MakeArray(c_array, size, max, count, zero_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, zero_mem)
|
||||
#define DN_LArray_MakeArrayZ(c_array, size, max, count) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, DN_ZeroMem_Yes)
|
||||
#define DN_LArray_Make(c_array, size, max, zero_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, zero_mem)
|
||||
#define DN_LArray_MakeZ(c_array, size, max) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, DN_ZeroMem_Yes)
|
||||
#define DN_LArray_MakeArray(c_array, size, max, count, z_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, z_mem)
|
||||
#define DN_LArray_MakeArrayZ(c_array, size, max, count) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, DN_ZMem_Yes)
|
||||
#define DN_LArray_Make(c_array, size, max, z_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, z_mem)
|
||||
#define DN_LArray_MakeZ(c_array, size, max) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, DN_ZMem_Yes)
|
||||
#define DN_LArray_AddArray(c_array, size, max, items, count, add) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), items, count, add)
|
||||
#define DN_LArray_Add(c_array, size, max, item, add) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), &item, 1, add)
|
||||
#define DN_LArray_AppendArray(c_array, size, max, items, count) (decltype(&(c_array)[0])) DN_CArray2_AddArray (c_array, size, max, sizeof((c_array)[0]), items, count, DN_ArrayAdd_Append)
|
||||
@ -296,10 +296,10 @@ template <typename T> struct DN_List
|
||||
#define DN_IArray_ResizeFromPool(array, pool, new_max) DN_CArray2_ResizeFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max)
|
||||
#define DN_IArray_GrowFromPool(array, pool, new_max) DN_CArray2_GrowFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max)
|
||||
#define DN_IArray_GrowIfNeededFromPool(array, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool, add_count)
|
||||
#define DN_IArray_MakeArray(array, count, zero_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, zero_mem)
|
||||
#define DN_IArray_MakeArrayZ(array, count) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, DN_ZeroMem_Yes)
|
||||
#define DN_IArray_Make(array, zero_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, zero_mem)
|
||||
#define DN_IArray_MakeZ(array) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, DN_ZeroMem_Yes)
|
||||
#define DN_IArray_MakeArray(array, count, z_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, z_mem)
|
||||
#define DN_IArray_MakeArrayZ(array, count) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, DN_ZMem_Yes)
|
||||
#define DN_IArray_Make(array, z_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, z_mem)
|
||||
#define DN_IArray_MakeZ(array) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, DN_ZMem_Yes)
|
||||
#define DN_IArray_AddArray(array, items, count, add) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, add)
|
||||
#define DN_IArray_Add(array, item, add) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, add)
|
||||
#define DN_IArray_AppendArray(array, items, count) (decltype(&((array)->data)[0])) DN_CArray2_AddArray ((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, DN_ArrayAdd_Append)
|
||||
@ -312,7 +312,7 @@ template <typename T> struct DN_List
|
||||
#define DN_IArray_Insert(array, index, item, count) (decltype(&((array)->data)[0])) DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, &item, 1)
|
||||
|
||||
DN_API DN_ArrayEraseResult DN_CArray2_EraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase);
|
||||
DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem);
|
||||
DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZMem z_mem);
|
||||
DN_API void *DN_CArray2_AddArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add);
|
||||
DN_API bool DN_CArray2_Resize (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max);
|
||||
DN_API bool DN_CArray2_Grow (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max);
|
||||
@ -327,7 +327,7 @@ DN_API void DN_Ring_Read (DN_Ring *ring, voi
|
||||
#define DN_Ring_ReadStruct(ring, dest) DN_Ring_Read((ring), (dest), sizeof(*(dest)))
|
||||
|
||||
template <typename T> DN_ArrayEraseResult DN_CArray_EraseRange (T *data, DN_USize *size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase);
|
||||
template <typename T> T * DN_CArray_MakeArray (T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_CArray_MakeArray (T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZMem z_mem);
|
||||
template <typename T> T * DN_CArray_InsertArray (T *data, DN_USize *size, DN_USize max, DN_USize index, T const *items, DN_USize count);
|
||||
template <typename T> T DN_CArray_PopFront (T *data, DN_USize *size, DN_USize count);
|
||||
template <typename T> T DN_CArray_PopBack (T *data, DN_USize *size, DN_USize count);
|
||||
@ -335,9 +335,9 @@ template <typename T> DN_ArrayFindResult<T> DN_CArray_
|
||||
|
||||
// NOTE: DN_SArray /////////////////////////////////////////////////////////////////////////////////
|
||||
#if !defined(DN_NO_SARRAY)
|
||||
template <typename T> DN_SArray<T> DN_SArray_Init (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_InitSlice (DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZeroMem zero_mem);
|
||||
template <typename T, size_t N> DN_SArray<T> DN_SArray_InitCArray (DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZeroMem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_Init (DN_Arena *arena, DN_USize size, DN_ZMem z_mem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_InitSlice (DN_Arena *arena, DN_Slice<T> slice, DN_USize size, DN_ZMem z_mem);
|
||||
template <typename T, size_t N> DN_SArray<T> DN_SArray_InitCArray (DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZMem);
|
||||
template <typename T> DN_SArray<T> DN_SArray_InitBuffer (T* buffer, DN_USize size);
|
||||
template <typename T> bool DN_SArray_IsValid (DN_SArray<T> const *array);
|
||||
template <typename T> DN_Slice<T> DN_SArray_Slice (DN_SArray<T> const *array);
|
||||
@ -347,8 +347,8 @@ template <typename T> T * DN_SArray_
|
||||
#define DN_SArray_AddArrayAssert(...) DN_HardAssert(DN_SArray_AddArray(__VA_ARGS__))
|
||||
#define DN_SArray_AddCArrayAssert(...) DN_HardAssert(DN_SArray_AddCArray(__VA_ARGS__))
|
||||
#define DN_SArray_AddAssert(...) DN_HardAssert(DN_SArray_Add(__VA_ARGS__))
|
||||
template <typename T> T * DN_SArray_MakeArray (DN_SArray<T> *array, DN_USize count, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_SArray_Make (DN_SArray<T> *array, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_SArray_MakeArray (DN_SArray<T> *array, DN_USize count, DN_ZMem z_mem);
|
||||
template <typename T> T * DN_SArray_Make (DN_SArray<T> *array, DN_ZMem z_mem);
|
||||
#define DN_SArray_MakeArrayAssert(...) DN_HardAssert(DN_SArray_MakeArray(__VA_ARGS__))
|
||||
#define DN_SArray_MakeAssert(...) DN_HardAssert(DN_SArray_Make(__VA_ARGS__))
|
||||
template <typename T> T * DN_SArray_InsertArray (DN_SArray<T> *array, DN_USize index, T const *items, DN_USize count);
|
||||
@ -378,8 +378,8 @@ template <typename T, DN_USize N> T * DN_FArray_
|
||||
#define DN_FArray_AddArrayAssert(...) DN_HardAssert(DN_FArray_AddArray(__VA_ARGS__))
|
||||
#define DN_FArray_AddCArrayAssert(...) DN_HardAssert(DN_FArray_AddCArray(__VA_ARGS__))
|
||||
#define DN_FArray_AddAssert(...) DN_HardAssert(DN_FArray_Add(__VA_ARGS__))
|
||||
template <typename T, DN_USize N> T * DN_FArray_MakeArray (DN_FArray<T, N> *array, DN_USize count, DN_ZeroMem zero_mem);
|
||||
template <typename T, DN_USize N> T * DN_FArray_Make (DN_FArray<T, N> *array, DN_ZeroMem zero_mem);
|
||||
template <typename T, DN_USize N> T * DN_FArray_MakeArray (DN_FArray<T, N> *array, DN_USize count, DN_ZMem z_mem);
|
||||
template <typename T, DN_USize N> T * DN_FArray_Make (DN_FArray<T, N> *array, DN_ZMem z_mem);
|
||||
#define DN_FArray_MakeArrayAssert(...) DN_HardAssert(DN_FArray_MakeArray(__VA_ARGS__))
|
||||
#define DN_FArray_MakeAssert(...) DN_HardAssert(DN_FArray_Make(__VA_ARGS__))
|
||||
template <typename T, DN_USize N> T * DN_FArray_InsertArray (DN_FArray<T, N> *array, T const &item, DN_USize index);
|
||||
@ -401,7 +401,7 @@ template <typename T> DN_Slice<T> DN_Slice_I
|
||||
template <typename T, DN_USize N> DN_Slice<T> DN_Slice_InitCArrayCopy (DN_Arena *arena, T const (&array)[N]);
|
||||
template <typename T> DN_Slice<T> DN_Slice_Copy (DN_Arena *arena, DN_Slice<T> slice);
|
||||
template <typename T> DN_Slice<T> DN_Slice_CopyPtr (DN_Arena *arena, T* const data, DN_USize size);
|
||||
template <typename T> DN_Slice<T> DN_Slice_Alloc (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem);
|
||||
template <typename T> DN_Slice<T> DN_Slice_Alloc (DN_Arena *arena, DN_USize size, DN_ZMem z_mem);
|
||||
DN_Str8 DN_Slice_Str8Render (DN_Arena *arena, DN_Slice<DN_Str8> array, DN_Str8 separator);
|
||||
DN_Str8 DN_Slice_Str8RenderSpaceSeparated (DN_Arena *arena, DN_Slice<DN_Str8> array);
|
||||
DN_Str16 DN_Slice_Str16Render (DN_Arena *arena, DN_Slice<DN_Str16> array, DN_Str16 separator);
|
||||
@ -410,7 +410,7 @@ template <typename T> DN_Slice<T> DN_Slice_A
|
||||
|
||||
#if !defined(DN_NO_DSMAP)
|
||||
template <typename T> DN_DSMap<T> DN_DSMap_Init (DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags);
|
||||
template <typename T> void DN_DSMap_Deinit (DN_DSMap<T> *map, DN_ZeroMem zero_mem);
|
||||
template <typename T> void DN_DSMap_Deinit (DN_DSMap<T> *map, DN_ZMem z_mem);
|
||||
template <typename T> bool DN_DSMap_IsValid (DN_DSMap<T> const *map);
|
||||
template <typename T> DN_U32 DN_DSMap_Hash (DN_DSMap<T> const *map, DN_DSMapKey key);
|
||||
template <typename T> DN_U32 DN_DSMap_HashToSlotIndex (DN_DSMap<T> const *map, DN_DSMapKey key);
|
||||
|
||||
@ -1,389 +0,0 @@
|
||||
#define DN_CONVERT_CPP
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
DN_API DN_NibbleFromU8Result DN_CVT_NibbleFromU8(DN_U8 u8)
|
||||
{
|
||||
static char const *table = "0123456789abcdef";
|
||||
DN_U8 lhs = (u8 >> 0) & 0xF;
|
||||
DN_U8 rhs = (u8 >> 4) & 0xF;
|
||||
DN_NibbleFromU8Result result = {};
|
||||
result.nibble0 = table[rhs];
|
||||
result.nibble1 = table[lhs];
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U8 DN_CVT_U8FromHexNibble(char hex)
|
||||
{
|
||||
bool digit = hex >= '0' && hex <= '9';
|
||||
bool upper = hex >= 'A' && hex <= 'F';
|
||||
bool lower = hex >= 'a' && hex <= 'f';
|
||||
DN_U8 result = 0xFF;
|
||||
if (digit)
|
||||
result = hex - '0';
|
||||
if (upper)
|
||||
result = hex - 'A' + 10;
|
||||
if (lower)
|
||||
result = hex - 'a' + 10;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API int DN_CVT_FmtBuffer3DotTruncate(char *buffer, int size, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int size_required = DN_VSNPrintF(buffer, size, fmt, args);
|
||||
int result = DN_Max(DN_Min(size_required, size - 1), 0);
|
||||
if (result == size - 1) {
|
||||
buffer[size - 2] = '.';
|
||||
buffer[size - 3] = '.';
|
||||
}
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64(DN_U64 val, char separator)
|
||||
{
|
||||
DN_CVTU64Str8 result = {};
|
||||
if (val == 0) {
|
||||
result.data[result.size++] = '0';
|
||||
} else {
|
||||
// NOTE: The number is written in reverse because we form the string by
|
||||
// dividing by 10, so we write it in, then reverse it out after all is
|
||||
// done.
|
||||
DN_CVTU64Str8 temp = {};
|
||||
for (DN_USize digit_count = 0; val > 0; digit_count++) {
|
||||
if (separator && (digit_count != 0) && (digit_count % 3 == 0))
|
||||
temp.data[temp.size++] = separator;
|
||||
|
||||
auto digit = DN_CAST(char)(val % 10);
|
||||
temp.data[temp.size++] = '0' + digit;
|
||||
val /= 10;
|
||||
}
|
||||
|
||||
// NOTE: Reverse the string
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6293) // Ill-defined for-loop
|
||||
DN_MSVC_WARNING_DISABLE(6385) // Reading invalid data from 'temp.data' unsigned overflow is valid for loop termination
|
||||
for (DN_USize temp_index = temp.size - 1; temp_index < temp.size; temp_index--) {
|
||||
char ch = temp.data[temp_index];
|
||||
result.data[result.size++] = ch;
|
||||
}
|
||||
DN_MSVC_WARNING_POP
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64(DN_U64 bytes, DN_CVTBytesType type)
|
||||
{
|
||||
DN_Assert(type != DN_CVTBytesType_Count);
|
||||
DN_CVTU64Bytes result = {};
|
||||
result.bytes = DN_CAST(DN_F64) bytes;
|
||||
|
||||
if (type == DN_CVTBytesType_Auto)
|
||||
for (; result.type < DN_CVTBytesType_Count && result.bytes >= 1024.0; result.type = DN_CAST(DN_CVTBytesType)(DN_CAST(DN_USize) result.type + 1))
|
||||
result.bytes /= 1024.0;
|
||||
else
|
||||
for (; result.type < type; result.type = DN_CAST(DN_CVTBytesType)(DN_CAST(DN_USize) result.type + 1))
|
||||
result.bytes /= 1024.0;
|
||||
|
||||
result.suffix = DN_CVT_BytesTypeToStr8(result.type);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesStr8FromU64(DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType desired_type)
|
||||
{
|
||||
DN_CVTU64Bytes byte_size = DN_CVT_BytesFromU64(bytes, desired_type);
|
||||
DN_Str8 result = DN_Str8_FromF(arena, "%.2f%.*s", byte_size.bytes, DN_STR_FMT(byte_size.suffix));
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesTypeToStr8(DN_CVTBytesType type)
|
||||
{
|
||||
DN_Str8 result = DN_STR8("");
|
||||
switch (type) {
|
||||
case DN_CVTBytesType_B: result = DN_STR8("B"); break;
|
||||
case DN_CVTBytesType_KiB: result = DN_STR8("KiB"); break;
|
||||
case DN_CVTBytesType_MiB: result = DN_STR8("MiB"); break;
|
||||
case DN_CVTBytesType_GiB: result = DN_STR8("GiB"); break;
|
||||
case DN_CVTBytesType_TiB: result = DN_STR8("TiB"); break;
|
||||
case DN_CVTBytesType_Count: result = DN_STR8(""); break;
|
||||
case DN_CVTBytesType_Auto: result = DN_STR8(""); break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_AgeFromU64(DN_Arena *arena, DN_U64 age_s, DN_CVTU64AgeUnit unit)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!arena)
|
||||
return result;
|
||||
|
||||
char buffer[512];
|
||||
DN_Arena stack_arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_NoPoison);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(&stack_arena);
|
||||
DN_U64 remainder = age_s;
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Year) {
|
||||
DN_USize value = remainder / DN_YearsToSec(1);
|
||||
remainder -= DN_YearsToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zuyr", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Week) {
|
||||
DN_USize value = remainder / DN_WeeksToSec(1);
|
||||
remainder -= DN_WeeksToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zuw", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Day) {
|
||||
DN_USize value = remainder / DN_DaysToSec(1);
|
||||
remainder -= DN_DaysToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zud", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Hr) {
|
||||
DN_USize value = remainder / DN_HoursToSec(1);
|
||||
remainder -= DN_HoursToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zuh", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Min) {
|
||||
DN_USize value = remainder / DN_MinutesToSec(1);
|
||||
remainder -= DN_MinutesToSec(value);
|
||||
if (value)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zum", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Sec) {
|
||||
DN_USize value = remainder;
|
||||
if (value || builder.string_size == 0)
|
||||
DN_Str8Builder_AppendF(&builder, "%s%zus", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
result = DN_Str8Builder_Build(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_AgeFromF64(DN_Arena *arena, DN_F64 age_s, DN_CVTU64AgeUnit unit)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!arena)
|
||||
return result;
|
||||
|
||||
char buffer[256];
|
||||
DN_Arena stack_arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_NoPoison);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(&stack_arena);
|
||||
DN_F64 remainder = age_s;
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Year) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_YearsToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_YearsToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fyr", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Week) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_WeeksToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_WeeksToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fw", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Day) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_DaysToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_WeeksToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fd", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Hr) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_HoursToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_HoursToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fh", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Min) {
|
||||
DN_F64 value = remainder / DN_CAST(DN_F64) DN_MinutesToSec(1);
|
||||
if (value >= 1.0) {
|
||||
remainder -= DN_MinutesToSec(value);
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fm", builder.string_size ? " " : "", value);
|
||||
}
|
||||
}
|
||||
|
||||
if (unit & DN_CVTU64AgeUnit_Sec) {
|
||||
DN_F64 value = remainder;
|
||||
DN_Str8Builder_AppendF(&builder, "%s%.1fs", builder.string_size ? " " : "", value);
|
||||
}
|
||||
|
||||
result = DN_Str8Builder_Build(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_CVT_U64FromHex(DN_Str8 hex)
|
||||
{
|
||||
DN_Str8 real_hex = DN_Str8_TrimPrefix(DN_Str8_TrimPrefix(hex, DN_STR8("0x")), DN_STR8("0X"));
|
||||
DN_USize max_hex_size = sizeof(DN_U64) * 2 /*hex chars per byte*/;
|
||||
DN_Assert(real_hex.size <= max_hex_size);
|
||||
|
||||
DN_USize size = DN_Min(max_hex_size, real_hex.size);
|
||||
DN_U64 result = 0;
|
||||
for (DN_USize index = 0; index < size; index++) {
|
||||
char ch = real_hex.data[index];
|
||||
DN_U8 val = DN_CVT_U8FromHexNibble(ch);
|
||||
if (val == 0xFF)
|
||||
break;
|
||||
result = (result << 4) | val;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_HexFromU64(DN_Arena *arena, DN_U64 number, uint32_t flags)
|
||||
{
|
||||
DN_Str8 prefix = {};
|
||||
if ((flags & DN_CVTU64HexStrFlags_0xPrefix))
|
||||
prefix = DN_STR8("0x");
|
||||
|
||||
char const *fmt = (flags & DN_CVTU64HexStrFlags_UppercaseHex) ? "%I64X" : "%I64x";
|
||||
DN_USize required_size = DN_CStr8_FSize(fmt, number) + prefix.size;
|
||||
DN_Str8 result = DN_Str8_Alloc(arena, required_size, DN_ZeroMem_No);
|
||||
|
||||
if (DN_Str8_HasData(result)) {
|
||||
DN_Memcpy(result.data, prefix.data, prefix.size);
|
||||
int space = DN_CAST(int) DN_Max((result.size - prefix.size) + 1, 0); /*null-terminator*/
|
||||
DN_SNPrintF(result.data + prefix.size, space, fmt, number);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_CVTU64HexStr DN_CVT_HexFromU64Str8(DN_U64 number, DN_CVTU64HexStrFlags flags)
|
||||
{
|
||||
DN_Str8 prefix = {};
|
||||
if (flags & DN_CVTU64HexStrFlags_0xPrefix)
|
||||
prefix = DN_STR8("0x");
|
||||
|
||||
DN_CVTU64HexStr result = {};
|
||||
DN_Memcpy(result.data, prefix.data, prefix.size);
|
||||
result.size += DN_CAST(int8_t) prefix.size;
|
||||
|
||||
char const *fmt = (flags & DN_CVTU64HexStrFlags_UppercaseHex) ? "%I64X" : "%I64x";
|
||||
int size = DN_SNPrintF(result.data + result.size, DN_ArrayCountU(result.data) - result.size, fmt, number);
|
||||
result.size += DN_CAST(uint8_t) size;
|
||||
DN_Assert(result.size < DN_ArrayCountU(result.data));
|
||||
|
||||
// NOTE: snprintf returns the required size of the format string
|
||||
// irrespective of if there's space or not, but, always null terminates so
|
||||
// the last byte is wasted.
|
||||
result.size = DN_Min(result.size, DN_ArrayCountU(result.data) - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_CVT_HexFromBytesPtr(void const *src, DN_USize src_size, char *dest, DN_USize dest_size)
|
||||
{
|
||||
if (!src || !dest)
|
||||
return false;
|
||||
|
||||
if (!DN_Check(dest_size >= src_size * 2))
|
||||
return false;
|
||||
|
||||
char const *HEX = "0123456789abcdef";
|
||||
unsigned char const *src_u8 = DN_CAST(unsigned char const *) src;
|
||||
for (DN_USize src_index = 0, dest_index = 0; src_index < src_size; src_index++) {
|
||||
char byte = src_u8[src_index];
|
||||
char hex01 = (byte >> 4) & 0b1111;
|
||||
char hex02 = (byte >> 0) & 0b1111;
|
||||
dest[dest_index++] = HEX[(int)hex01];
|
||||
dest[dest_index++] = HEX[(int)hex02];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_HexFromBytes(DN_Arena *arena, void const *src, DN_USize size)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!src || size <= 0)
|
||||
return result;
|
||||
|
||||
result = DN_Str8_Alloc(arena, size * 2, DN_ZeroMem_No);
|
||||
result.data[result.size] = 0;
|
||||
bool converted = DN_CVT_HexFromBytesPtr(src, size, result.data, result.size);
|
||||
DN_Assert(converted);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtrUnchecked(DN_Str8 hex, void *dest, DN_USize dest_size)
|
||||
{
|
||||
DN_USize result = 0;
|
||||
unsigned char *dest_u8 = DN_CAST(unsigned char *) dest;
|
||||
|
||||
for (DN_USize hex_index = 0; hex_index < hex.size; hex_index += 2, result += 1) {
|
||||
char hex01 = hex.data[hex_index];
|
||||
char hex02 = (hex_index + 1 < hex.size) ? hex.data[hex_index + 1] : 0;
|
||||
char bit4_01 = DN_CVT_U8FromHexNibble(hex01);
|
||||
char bit4_02 = DN_CVT_U8FromHexNibble(hex02);
|
||||
char byte = (bit4_01 << 4) | (bit4_02 << 0);
|
||||
dest_u8[result] = byte;
|
||||
}
|
||||
|
||||
DN_Assert(result <= dest_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtr(DN_Str8 hex, void *dest, DN_USize dest_size)
|
||||
{
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0x"));
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0X"));
|
||||
|
||||
DN_USize result = 0;
|
||||
if (!DN_Str8_HasData(hex))
|
||||
return result;
|
||||
|
||||
// NOTE: Trimmed hex can be "0xf" -> "f" or "0xAB" -> "AB"
|
||||
// Either way, the size can be odd or even, hence we round up to the nearest
|
||||
// multiple of two to ensure that we calculate the min buffer size orrectly.
|
||||
DN_USize hex_size_rounded_up = hex.size + (hex.size % 2);
|
||||
DN_USize min_buffer_size = hex_size_rounded_up / 2;
|
||||
if (hex.size <= 0 || !DN_Check(dest_size >= min_buffer_size))
|
||||
return result;
|
||||
|
||||
result = DN_CVT_BytesFromHexPtrUnchecked(hex, dest, dest_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHexUnchecked(DN_Arena *arena, DN_Str8 hex)
|
||||
{
|
||||
DN_USize hex_size_rounded_up = hex.size + (hex.size % 2);
|
||||
DN_Str8 result = DN_Str8_Alloc(arena, (hex_size_rounded_up / 2), DN_ZeroMem_No);
|
||||
if (result.data) {
|
||||
DN_USize bytes_written = DN_CVT_BytesFromHexPtr(hex, result.data, result.size);
|
||||
DN_Assert(bytes_written == result.size);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHex(DN_Arena *arena, DN_Str8 hex)
|
||||
{
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0x"));
|
||||
hex = DN_Str8_TrimPrefix(hex, DN_STR8("0X"));
|
||||
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Str8_HasData(hex))
|
||||
return result;
|
||||
|
||||
if (!DN_Check(DN_Str8_IsAll(hex, DN_Str8IsAll_Hex)))
|
||||
return result;
|
||||
|
||||
result = DN_CVT_BytesFromHexUnchecked(arena, hex);
|
||||
return result;
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
#if !defined(DN_BASE_CONVERT_H)
|
||||
#define DN_BASE_CONVERT_H
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
struct DN_CVTU64Str8
|
||||
{
|
||||
char data[27 + 1]; // NOTE(dn): 27 is the maximum size of DN_U64 including a separator
|
||||
DN_U8 size;
|
||||
};
|
||||
|
||||
enum DN_CVTBytesType
|
||||
{
|
||||
DN_CVTBytesType_B,
|
||||
DN_CVTBytesType_KiB,
|
||||
DN_CVTBytesType_MiB,
|
||||
DN_CVTBytesType_GiB,
|
||||
DN_CVTBytesType_TiB,
|
||||
DN_CVTBytesType_Count,
|
||||
DN_CVTBytesType_Auto,
|
||||
};
|
||||
|
||||
struct DN_CVTU64Bytes
|
||||
{
|
||||
DN_CVTBytesType type;
|
||||
DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c
|
||||
DN_F64 bytes;
|
||||
};
|
||||
|
||||
struct DN_CVTU64HexStr
|
||||
{
|
||||
char data[2 /*0x*/ + 16 /*hex*/ + 1 /*null-terminator*/];
|
||||
DN_U8 size;
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_CVTU64HexStrFlags;
|
||||
enum DN_CVTU64HexStrFlags_
|
||||
{
|
||||
DN_CVTU64HexStrFlags_Nil = 0,
|
||||
DN_CVTU64HexStrFlags_0xPrefix = 1 << 0, /// Add the '0x' prefix from the string
|
||||
DN_CVTU64HexStrFlags_UppercaseHex = 1 << 1, /// Use uppercase ascii characters for hex
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_CVTU64AgeUnit;
|
||||
enum DN_CVTU64AgeUnit_
|
||||
{
|
||||
DN_CVTU64AgeUnit_Sec = 1 << 0,
|
||||
DN_CVTU64AgeUnit_Min = 1 << 1,
|
||||
DN_CVTU64AgeUnit_Hr = 1 << 2,
|
||||
DN_CVTU64AgeUnit_Day = 1 << 3,
|
||||
DN_CVTU64AgeUnit_Week = 1 << 4,
|
||||
DN_CVTU64AgeUnit_Year = 1 << 5,
|
||||
DN_CVTU64AgeUnit_HMS = DN_CVTU64AgeUnit_Sec | DN_CVTU64AgeUnit_Min | DN_CVTU64AgeUnit_Hr,
|
||||
DN_CVTU64AgeUnit_All = DN_CVTU64AgeUnit_HMS | DN_CVTU64AgeUnit_Day | DN_CVTU64AgeUnit_Week | DN_CVTU64AgeUnit_Year,
|
||||
};
|
||||
|
||||
struct DN_NibbleFromU8Result
|
||||
{
|
||||
char nibble0;
|
||||
char nibble1;
|
||||
};
|
||||
|
||||
DN_API DN_NibbleFromU8Result DN_CVT_NibbleFromU8 (DN_U8 u8);
|
||||
DN_API DN_U8 DN_CVT_U8FromHexNibble (char hex);
|
||||
|
||||
DN_API int DN_CVT_FmtBuffer3DotTruncate (char *buffer, int size, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64 (DN_U64 val, char separator);
|
||||
DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64 (DN_U64 bytes, DN_CVTBytesType type);
|
||||
#define DN_CVT_BytesFromU64Auto(bytes) DN_CVT_BytesFromU64(bytes, DN_CVTBytesType_Auto)
|
||||
DN_API DN_Str8 DN_CVT_BytesStr8FromU64 (DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType type);
|
||||
#define DN_CVT_BytesStr8FromTLS(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, type)
|
||||
#define DN_CVT_BytesStr8FromU64Auto(arena, bytes) DN_CVT_BytesStr8FromU64(arena, bytes, DN_CVTBytesType_Auto)
|
||||
#define DN_CVT_BytesStr8FromU64AutoTLS(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, DN_CVTBytesType_Auto)
|
||||
#define DN_CVT_BytesStr8FromU64Frame(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, type)
|
||||
#define DN_CVT_BytesStr8FromU64AutoFrame(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, DN_CVTBytesType_Auto)
|
||||
DN_API DN_Str8 DN_CVT_BytesTypeToStr8 (DN_CVTBytesType type);
|
||||
DN_API DN_Str8 DN_CVT_AgeFromU64 (DN_Arena *arena, DN_U64 age_s, DN_CVTU64AgeUnit unit);
|
||||
DN_API DN_Str8 DN_CVT_AgeFromF64 (DN_Arena *arena, DN_F64 age_s, DN_CVTU64AgeUnit unit);
|
||||
|
||||
DN_API DN_U64 DN_CVT_U64FromHex (DN_Str8 hex);
|
||||
DN_API DN_Str8 DN_CVT_HexFromU64 (DN_Arena *arena, DN_U64 number, DN_CVTU64HexStrFlags flags);
|
||||
#define DN_CVT_HexFromU64Frame(number, flags) DN_CVT_HexFromU64(DN_OS_TLSFrameArena(), number, flags)
|
||||
DN_API DN_CVTU64HexStr DN_CVT_HexFromU64Str (DN_U64 number, DN_CVTU64HexStrFlags flags);
|
||||
|
||||
DN_API bool DN_CVT_HexFromBytesPtr (void const *src, DN_USize src_size, char *dest, DN_USize dest_size);
|
||||
DN_API DN_Str8 DN_CVT_HexFromBytes (DN_Arena *arena, void const *src, DN_USize size);
|
||||
#define DN_CVT_HexFromBytesTLS(...) DN_CVT_HexFromBytes(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
#define DN_CVT_HexFromBytesFrame(...) DN_CVT_HexFromBytes(DN_OS_TLSFrameArena(), __VA_ARGS__)
|
||||
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_USize DN_CVT_BytesFromHexPtr (DN_Str8 hex, void *dest, DN_USize dest_size);
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHexUnchecked (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_BytesFromHexUncheckedFromTLS(...) DN_CVT_BytesFromHexUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
DN_API DN_Str8 DN_CVT_BytesFromHex (DN_Arena *arena, DN_Str8 hex);
|
||||
#define DN_CVT_BytesFromHexFrame(...) DN_CVT_BytesFromHex(DN_OS_TLSFrameArena(), __VA_ARGS__)
|
||||
#define DN_CVT_BytesFromHexTLS(...) DN_CVT_BytesFromHex(DN_OS_TLSTopArena(), __VA_ARGS__)
|
||||
#endif // defined(DN_BASE_CONVERT_H)
|
||||
@ -23,9 +23,9 @@ DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType colour, DN_U8
|
||||
|
||||
DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromU32(DN_LOGColourType colour, DN_U32 value)
|
||||
{
|
||||
DN_U8 r = DN_CAST(DN_U8)(value >> 24);
|
||||
DN_U8 g = DN_CAST(DN_U8)(value >> 16);
|
||||
DN_U8 b = DN_CAST(DN_U8)(value >> 8);
|
||||
DN_U8 r = DN_Cast(DN_U8)(value >> 24);
|
||||
DN_U8 g = DN_Cast(DN_U8)(value >> 16);
|
||||
DN_U8 b = DN_Cast(DN_U8)(value >> 8);
|
||||
DN_Str8 result = DN_LOG_ColourEscapeCodeStr8FromRGB(colour, r, g, b);
|
||||
return result;
|
||||
}
|
||||
@ -35,35 +35,35 @@ DN_API DN_LOGPrefixSize DN_LOG_MakePrefix(DN_LOGStyle style, DN_LOGTypeParam typ
|
||||
DN_Str8 type_str8 = type.str8;
|
||||
if (type.is_u32_enum) {
|
||||
switch (type.u32) {
|
||||
case DN_LOGType_Debug: type_str8 = DN_STR8("DEBUG"); break;
|
||||
case DN_LOGType_Info: type_str8 = DN_STR8("INFO "); break;
|
||||
case DN_LOGType_Warning: type_str8 = DN_STR8("WARN"); break;
|
||||
case DN_LOGType_Error: type_str8 = DN_STR8("ERROR"); break;
|
||||
case DN_LOGType_Count: type_str8 = DN_STR8("BADXX"); break;
|
||||
case DN_LOGType_Debug: type_str8 = DN_Str8Lit("DEBUG"); break;
|
||||
case DN_LOGType_Info: type_str8 = DN_Str8Lit("INFO "); break;
|
||||
case DN_LOGType_Warning: type_str8 = DN_Str8Lit("WARN"); break;
|
||||
case DN_LOGType_Error: type_str8 = DN_Str8Lit("ERROR"); break;
|
||||
case DN_LOGType_Count: type_str8 = DN_Str8Lit("BADXX"); break;
|
||||
}
|
||||
}
|
||||
|
||||
static DN_USize max_type_length = 0;
|
||||
max_type_length = DN_Max(max_type_length, type_str8.size);
|
||||
int type_padding = DN_CAST(int)(max_type_length - type_str8.size);
|
||||
int type_padding = DN_Cast(int)(max_type_length - type_str8.size);
|
||||
|
||||
DN_Str8 colour_esc = {};
|
||||
DN_Str8 bold_esc = {};
|
||||
DN_Str8 reset_esc = {};
|
||||
if (style.colour) {
|
||||
bold_esc = DN_STR8(DN_LOG_BoldEscapeCode);
|
||||
reset_esc = DN_STR8(DN_LOG_ResetEscapeCode);
|
||||
bold_esc = DN_Str8Lit(DN_LOG_BoldEscapeCode);
|
||||
reset_esc = DN_Str8Lit(DN_LOG_ResetEscapeCode);
|
||||
colour_esc = DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType_Fg, style.r, style.g, style.b);
|
||||
}
|
||||
|
||||
DN_Str8 file_name = DN_Str8_FileNameFromPath(call_site.file);
|
||||
DN_Str8 file_name = DN_Str8FileNameFromPath(call_site.file);
|
||||
DN_GCC_WARNING_PUSH
|
||||
DN_GCC_WARNING_DISABLE(-Wformat)
|
||||
DN_GCC_WARNING_DISABLE(-Wformat-extra-args)
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(4477)
|
||||
int size = DN_SNPrintF(dest,
|
||||
DN_CAST(int)dest_size,
|
||||
DN_Cast(int)dest_size,
|
||||
"%04u-%02u-%02uT%02u:%02u:%02u" // date
|
||||
"%S" // colour
|
||||
"%S" // bold
|
||||
@ -82,7 +82,7 @@ DN_API DN_LOGPrefixSize DN_LOG_MakePrefix(DN_LOGStyle style, DN_LOGTypeParam typ
|
||||
colour_esc, // colour
|
||||
bold_esc, // bold
|
||||
type_str8, // type
|
||||
DN_CAST(int) type_padding,
|
||||
DN_Cast(int) type_padding,
|
||||
"", // type padding
|
||||
reset_esc, // reset
|
||||
file_name, // file name
|
||||
|
||||
@ -2,553 +2,3 @@
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
static DN_ArenaBlock *DN_Arena_BlockFromMemFuncs_(DN_U64 reserve, DN_U64 commit, bool track_alloc, bool alloc_can_leak, DN_ArenaMemFuncs mem_funcs)
|
||||
{
|
||||
DN_ArenaBlock *result = nullptr;
|
||||
switch (mem_funcs.type) {
|
||||
case DN_ArenaMemFuncType_Nil:
|
||||
break;
|
||||
|
||||
case DN_ArenaMemFuncType_Basic: {
|
||||
DN_AssertF(reserve > DN_ARENA_HEADER_SIZE, "%I64u > %I64u", reserve, DN_ARENA_HEADER_SIZE);
|
||||
result = DN_CAST(DN_ArenaBlock *) mem_funcs.basic_alloc(reserve);
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
result->used = DN_ARENA_HEADER_SIZE;
|
||||
result->commit = reserve;
|
||||
result->reserve = reserve;
|
||||
} break;
|
||||
|
||||
case DN_ArenaMemFuncType_VMem: {
|
||||
DN_AssertF(mem_funcs.vmem_page_size, "Page size must be set to a non-zero, power of two value");
|
||||
DN_Assert(DN_IsPowerOfTwo(mem_funcs.vmem_page_size));
|
||||
|
||||
DN_USize const page_size = mem_funcs.vmem_page_size;
|
||||
DN_U64 real_reserve = reserve ? reserve : DN_ARENA_RESERVE_SIZE;
|
||||
DN_U64 real_commit = commit ? commit : DN_ARENA_COMMIT_SIZE;
|
||||
real_reserve = DN_AlignUpPowerOfTwo(real_reserve, page_size);
|
||||
real_commit = DN_Min(DN_AlignUpPowerOfTwo(real_commit, page_size), real_reserve);
|
||||
DN_AssertF(DN_ARENA_HEADER_SIZE < real_commit && real_commit <= real_reserve, "%I64u < %I64u <= %I64u", DN_ARENA_HEADER_SIZE, real_commit, real_reserve);
|
||||
|
||||
DN_MemCommit mem_commit = real_reserve == real_commit ? DN_MemCommit_Yes : DN_MemCommit_No;
|
||||
result = DN_CAST(DN_ArenaBlock *) mem_funcs.vmem_reserve(real_reserve, mem_commit, DN_MemPage_ReadWrite);
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
if (mem_commit == DN_MemCommit_No && !mem_funcs.vmem_commit(result, real_commit, DN_MemPage_ReadWrite)) {
|
||||
mem_funcs.vmem_release(result, real_reserve);
|
||||
return result;
|
||||
}
|
||||
|
||||
result->used = DN_ARENA_HEADER_SIZE;
|
||||
result->commit = real_commit;
|
||||
result->reserve = real_reserve;
|
||||
} break;
|
||||
}
|
||||
|
||||
if (track_alloc && result)
|
||||
DN_DBGTrackAlloc(result, result->reserve, alloc_can_leak);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DN_ArenaBlock *DN_Arena_BlockFlagsFromMemFuncs_(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs)
|
||||
{
|
||||
bool track_alloc = (flags & DN_ArenaFlags_NoAllocTrack) == 0;
|
||||
bool alloc_can_leak = flags & DN_ArenaFlags_AllocCanLeak;
|
||||
DN_ArenaBlock *result = DN_Arena_BlockFromMemFuncs_(reserve, commit, track_alloc, alloc_can_leak, mem_funcs);
|
||||
if (result && ((flags & DN_ArenaFlags_NoPoison) == 0))
|
||||
DN_ASanPoisonMemoryRegion(DN_CAST(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_Arena_UpdateStatsOnNewBlock_(DN_Arena *arena, DN_ArenaBlock const *block)
|
||||
{
|
||||
DN_Assert(arena);
|
||||
if (block) {
|
||||
arena->stats.info.used += block->used;
|
||||
arena->stats.info.commit += block->commit;
|
||||
arena->stats.info.reserve += block->reserve;
|
||||
arena->stats.info.blocks += 1;
|
||||
|
||||
arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used);
|
||||
arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit);
|
||||
arena->stats.hwm.reserve = DN_Max(arena->stats.hwm.reserve, arena->stats.info.reserve);
|
||||
arena->stats.hwm.blocks = DN_Max(arena->stats.hwm.blocks, arena->stats.info.blocks);
|
||||
}
|
||||
}
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromBuffer(void *buffer, DN_USize size, DN_ArenaFlags flags)
|
||||
{
|
||||
DN_Assert(buffer);
|
||||
DN_AssertF(DN_ARENA_HEADER_SIZE < size, "Buffer (%zu bytes) too small, need atleast %zu bytes to store arena metadata", size, DN_ARENA_HEADER_SIZE);
|
||||
DN_AssertF(DN_IsPowerOfTwo(size), "Buffer (%zu bytes) must be a power-of-two", size);
|
||||
|
||||
// NOTE: Init block
|
||||
DN_ArenaBlock *block = DN_CAST(DN_ArenaBlock *) buffer;
|
||||
block->commit = size;
|
||||
block->reserve = size;
|
||||
block->used = DN_ARENA_HEADER_SIZE;
|
||||
if (block && ((flags & DN_ArenaFlags_NoPoison) == 0))
|
||||
DN_ASanPoisonMemoryRegion(DN_CAST(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE);
|
||||
|
||||
DN_Arena result = {};
|
||||
result.flags = flags | DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_UserBuffer;
|
||||
result.curr = block;
|
||||
DN_Arena_UpdateStatsOnNewBlock_(&result, result.curr);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromMemFuncs(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs)
|
||||
{
|
||||
DN_Arena result = {};
|
||||
result.flags = flags;
|
||||
result.mem_funcs = mem_funcs;
|
||||
result.flags |= DN_ArenaFlags_MemFuncs;
|
||||
result.curr = DN_Arena_BlockFlagsFromMemFuncs_(reserve, commit, flags, mem_funcs);
|
||||
DN_Arena_UpdateStatsOnNewBlock_(&result, result.curr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_Arena_BlockDeinit_(DN_Arena const *arena, DN_ArenaBlock *block)
|
||||
{
|
||||
DN_USize release_size = block->reserve;
|
||||
if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack))
|
||||
DN_DBGTrackDealloc(block);
|
||||
DN_ASanUnpoisonMemoryRegion(block, block->commit);
|
||||
if (arena->flags & DN_ArenaFlags_MemFuncs) {
|
||||
if (arena->mem_funcs.type == DN_ArenaMemFuncType_Basic)
|
||||
arena->mem_funcs.basic_dealloc(block);
|
||||
else
|
||||
arena->mem_funcs.vmem_release(block, release_size);
|
||||
}
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_Deinit(DN_Arena *arena)
|
||||
{
|
||||
for (DN_ArenaBlock *block = arena ? arena->curr : nullptr; block;) {
|
||||
DN_ArenaBlock *block_to_free = block;
|
||||
block = block->prev;
|
||||
DN_Arena_BlockDeinit_(arena, block_to_free);
|
||||
}
|
||||
if (arena)
|
||||
*arena = {};
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_CommitTo(DN_Arena *arena, DN_U64 pos)
|
||||
{
|
||||
if (!arena || !arena->curr)
|
||||
return false;
|
||||
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
if (pos <= curr->commit)
|
||||
return true;
|
||||
|
||||
DN_U64 real_pos = pos;
|
||||
if (!DN_Check(pos <= curr->reserve))
|
||||
real_pos = curr->reserve;
|
||||
|
||||
DN_Assert(arena->mem_funcs.vmem_page_size);
|
||||
DN_USize end_commit = DN_AlignUpPowerOfTwo(real_pos, arena->mem_funcs.vmem_page_size);
|
||||
DN_USize commit_size = end_commit - curr->commit;
|
||||
char *commit_ptr = DN_CAST(char *) curr + curr->commit;
|
||||
if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite))
|
||||
return false;
|
||||
|
||||
bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0);
|
||||
if (poison)
|
||||
DN_ASanPoisonMemoryRegion(commit_ptr, commit_size);
|
||||
|
||||
curr->commit = end_commit;
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_Commit(DN_Arena *arena, DN_U64 size)
|
||||
{
|
||||
if (!arena || !arena->curr)
|
||||
return false;
|
||||
DN_U64 pos = DN_Min(arena->curr->reserve, arena->curr->commit + size);
|
||||
bool result = DN_Arena_CommitTo(arena, pos);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_Grow(DN_Arena *arena, DN_U64 reserve, DN_U64 commit)
|
||||
{
|
||||
if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer))
|
||||
return false;
|
||||
|
||||
bool result = false;
|
||||
DN_ArenaBlock *new_block = DN_Arena_BlockFlagsFromMemFuncs_(reserve, commit, arena->flags, arena->mem_funcs);
|
||||
if (new_block) {
|
||||
result = true;
|
||||
new_block->prev = arena->curr;
|
||||
arena->curr = new_block;
|
||||
new_block->reserve_sum = new_block->prev->reserve_sum + new_block->prev->reserve;
|
||||
DN_Arena_UpdateStatsOnNewBlock_(arena, arena->curr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_Arena_Alloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem)
|
||||
{
|
||||
if (!arena)
|
||||
return nullptr;
|
||||
|
||||
if (!arena->curr) {
|
||||
arena->curr = DN_Arena_BlockFlagsFromMemFuncs_(DN_ARENA_RESERVE_SIZE, DN_ARENA_COMMIT_SIZE, arena->flags, arena->mem_funcs);
|
||||
DN_Arena_UpdateStatsOnNewBlock_(arena, arena->curr);
|
||||
}
|
||||
|
||||
if (!arena->curr)
|
||||
return nullptr;
|
||||
|
||||
try_alloc_again:
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0);
|
||||
uint8_t real_align = poison ? DN_Max(align, DN_ASAN_POISON_ALIGNMENT) : align;
|
||||
DN_U64 offset_pos = DN_AlignUpPowerOfTwo(curr->used, real_align) + (poison ? DN_ASAN_POISON_GUARD_SIZE : 0);
|
||||
DN_U64 end_pos = offset_pos + size;
|
||||
DN_U64 alloc_size = end_pos - curr->used;
|
||||
|
||||
if (end_pos > curr->reserve) {
|
||||
if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer))
|
||||
return nullptr;
|
||||
DN_USize new_reserve = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_RESERVE_SIZE);
|
||||
DN_USize new_commit = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_COMMIT_SIZE);
|
||||
if (!DN_Arena_Grow(arena, new_reserve, new_commit))
|
||||
return nullptr;
|
||||
goto try_alloc_again;
|
||||
}
|
||||
|
||||
DN_USize prev_arena_commit = curr->commit;
|
||||
if (end_pos > curr->commit) {
|
||||
DN_Assert(arena->mem_funcs.vmem_page_size);
|
||||
DN_Assert(arena->mem_funcs.type == DN_ArenaMemFuncType_VMem);
|
||||
DN_Assert((arena->flags & DN_ArenaFlags_UserBuffer) == 0);
|
||||
DN_USize end_commit = DN_AlignUpPowerOfTwo(end_pos, arena->mem_funcs.vmem_page_size);
|
||||
DN_USize commit_size = end_commit - curr->commit;
|
||||
char *commit_ptr = DN_CAST(char *) curr + curr->commit;
|
||||
if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite))
|
||||
return nullptr;
|
||||
if (poison)
|
||||
DN_ASanPoisonMemoryRegion(commit_ptr, commit_size);
|
||||
curr->commit = end_commit;
|
||||
arena->stats.info.commit += commit_size;
|
||||
arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit);
|
||||
}
|
||||
|
||||
void *result = DN_CAST(char *) curr + offset_pos;
|
||||
curr->used += alloc_size;
|
||||
arena->stats.info.used += alloc_size;
|
||||
arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used);
|
||||
DN_ASanUnpoisonMemoryRegion(result, size);
|
||||
|
||||
if (zero_mem == DN_ZeroMem_Yes) {
|
||||
DN_USize reused_bytes = DN_Min(prev_arena_commit - offset_pos, size);
|
||||
DN_Memset(result, 0, reused_bytes);
|
||||
}
|
||||
|
||||
DN_Assert(arena->stats.hwm.used >= arena->stats.info.used);
|
||||
DN_Assert(arena->stats.hwm.commit >= arena->stats.info.commit);
|
||||
DN_Assert(arena->stats.hwm.reserve >= arena->stats.info.reserve);
|
||||
DN_Assert(arena->stats.hwm.blocks >= arena->stats.info.blocks);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_Arena_AllocContiguous(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem)
|
||||
{
|
||||
DN_ArenaFlags prev_flags = arena->flags;
|
||||
arena->flags |= (DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoPoison);
|
||||
void *memory = DN_Arena_Alloc(arena, size, align, zero_mem);
|
||||
arena->flags = prev_flags;
|
||||
return memory;
|
||||
}
|
||||
|
||||
DN_API void *DN_Arena_Copy(DN_Arena *arena, void const *data, DN_U64 size, uint8_t align)
|
||||
{
|
||||
if (!arena || !data || size == 0)
|
||||
return nullptr;
|
||||
void *result = DN_Arena_Alloc(arena, size, align, DN_ZeroMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, data, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_PopTo(DN_Arena *arena, DN_U64 init_used)
|
||||
{
|
||||
if (!arena || !arena->curr)
|
||||
return;
|
||||
DN_U64 used = DN_Max(DN_ARENA_HEADER_SIZE, init_used);
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
while (curr->reserve_sum >= used) {
|
||||
DN_ArenaBlock *block_to_free = curr;
|
||||
arena->stats.info.used -= block_to_free->used;
|
||||
arena->stats.info.commit -= block_to_free->commit;
|
||||
arena->stats.info.reserve -= block_to_free->reserve;
|
||||
arena->stats.info.blocks -= 1;
|
||||
if (arena->flags & DN_ArenaFlags_UserBuffer)
|
||||
break;
|
||||
curr = curr->prev;
|
||||
DN_Arena_BlockDeinit_(arena, block_to_free);
|
||||
}
|
||||
|
||||
arena->stats.info.used -= curr->used;
|
||||
arena->curr = curr;
|
||||
curr->used = used - curr->reserve_sum;
|
||||
char *poison_ptr = (char *)curr + DN_AlignUpPowerOfTwo(curr->used, DN_ASAN_POISON_ALIGNMENT);
|
||||
DN_USize poison_size = ((char *)curr + curr->commit) - poison_ptr;
|
||||
DN_ASanPoisonMemoryRegion(poison_ptr, poison_size);
|
||||
arena->stats.info.used += curr->used;
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_Pop(DN_Arena *arena, DN_U64 amount)
|
||||
{
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
DN_USize used_sum = curr->reserve_sum + curr->used;
|
||||
if (!DN_Check(amount <= used_sum))
|
||||
amount = used_sum;
|
||||
DN_USize pop_to = used_sum - amount;
|
||||
DN_Arena_PopTo(arena, pop_to);
|
||||
}
|
||||
|
||||
DN_API DN_U64 DN_Arena_Pos(DN_Arena const *arena)
|
||||
{
|
||||
DN_U64 result = (arena && arena->curr) ? arena->curr->reserve_sum + arena->curr->used : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_Arena_Clear(DN_Arena *arena)
|
||||
{
|
||||
DN_Arena_PopTo(arena, 0);
|
||||
}
|
||||
|
||||
DN_API bool DN_Arena_OwnsPtr(DN_Arena const *arena, void *ptr)
|
||||
{
|
||||
bool result = false;
|
||||
uintptr_t uint_ptr = DN_CAST(uintptr_t) ptr;
|
||||
for (DN_ArenaBlock const *block = arena ? arena->curr : nullptr; !result && block; block = block->prev) {
|
||||
uintptr_t begin = DN_CAST(uintptr_t) block + DN_ARENA_HEADER_SIZE;
|
||||
uintptr_t end = begin + block->reserve;
|
||||
result = uint_ptr >= begin && uint_ptr <= end;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaStats DN_Arena_SumStatsArray(DN_ArenaStats const *array, DN_USize size)
|
||||
{
|
||||
DN_ArenaStats result = {};
|
||||
for (DN_ForItSize(it, DN_ArenaStats const, array, size)) {
|
||||
DN_ArenaStats stats = *it.data;
|
||||
result.info.used += stats.info.used;
|
||||
result.info.commit += stats.info.commit;
|
||||
result.info.reserve += stats.info.reserve;
|
||||
result.info.blocks += stats.info.blocks;
|
||||
|
||||
result.hwm.used = DN_Max(result.hwm.used, result.info.used);
|
||||
result.hwm.commit = DN_Max(result.hwm.commit, result.info.commit);
|
||||
result.hwm.reserve = DN_Max(result.hwm.reserve, result.info.reserve);
|
||||
result.hwm.blocks = DN_Max(result.hwm.blocks, result.info.blocks);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaStats DN_Arena_SumStats(DN_ArenaStats lhs, DN_ArenaStats rhs)
|
||||
{
|
||||
DN_ArenaStats array[] = {lhs, rhs};
|
||||
DN_ArenaStats result = DN_Arena_SumStatsArray(array, DN_ArrayCountU(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats(DN_Arena const *array, DN_USize size)
|
||||
{
|
||||
DN_ArenaStats result = {};
|
||||
for (DN_USize index = 0; index < size; index++) {
|
||||
DN_Arena const *arena = array + index;
|
||||
result = DN_Arena_SumStats(result, arena->stats);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_ArenaTempMem DN_Arena_TempMemBegin(DN_Arena *arena)
|
||||
{
|
||||
DN_ArenaTempMem result = {};
|
||||
if (arena) {
|
||||
DN_ArenaBlock *curr = arena->curr;
|
||||
result = {arena, curr ? curr->reserve_sum + curr->used : 0};
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
DN_API void DN_Arena_TempMemEnd(DN_ArenaTempMem mem)
|
||||
{
|
||||
DN_Arena_PopTo(mem.arena, mem.used_sum);
|
||||
};
|
||||
|
||||
DN_ArenaTempMemScope::DN_ArenaTempMemScope(DN_Arena *arena)
|
||||
{
|
||||
mem = DN_Arena_TempMemBegin(arena);
|
||||
}
|
||||
|
||||
DN_ArenaTempMemScope::~DN_ArenaTempMemScope()
|
||||
{
|
||||
DN_Arena_TempMemEnd(mem);
|
||||
}
|
||||
|
||||
// NOTE: DN_Pool ///////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_Pool DN_Pool_FromArena(DN_Arena *arena, uint8_t align)
|
||||
{
|
||||
DN_Pool result = {};
|
||||
if (arena) {
|
||||
result.arena = arena;
|
||||
result.align = align ? align : DN_POOL_DEFAULT_ALIGN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_Pool_IsValid(DN_Pool const *pool)
|
||||
{
|
||||
bool result = pool && pool->arena && pool->align;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_Pool_Alloc(DN_Pool *pool, DN_USize size)
|
||||
{
|
||||
void *result = nullptr;
|
||||
if (!DN_Pool_IsValid(pool))
|
||||
return result;
|
||||
|
||||
DN_USize const required_size = sizeof(DN_PoolSlot) + pool->align + size;
|
||||
DN_USize const size_to_slot_offset = 5; // __lzcnt64(32) e.g. DN_PoolSlotSize_32B
|
||||
DN_USize slot_index = 0;
|
||||
if (required_size > 32) {
|
||||
// NOTE: Round up if not PoT as the low bits are set.
|
||||
DN_USize dist_to_next_msb = DN_CountLeadingZerosUSize(required_size) + 1;
|
||||
dist_to_next_msb -= DN_CAST(DN_USize)(!DN_IsPowerOfTwo(required_size));
|
||||
|
||||
DN_USize const register_size = sizeof(DN_USize) * 8;
|
||||
DN_AssertF(register_size >= (dist_to_next_msb - size_to_slot_offset), "lhs=%zu, rhs=%zu", register_size, (dist_to_next_msb - size_to_slot_offset));
|
||||
slot_index = register_size - dist_to_next_msb - size_to_slot_offset;
|
||||
}
|
||||
|
||||
if (!DN_CheckF(slot_index < DN_PoolSlotSize_Count, "Chunk pool does not support the requested allocation size"))
|
||||
return result;
|
||||
|
||||
DN_USize slot_size_in_bytes = 1ULL << (slot_index + size_to_slot_offset);
|
||||
DN_AssertF(required_size <= (slot_size_in_bytes << 0), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes << 0));
|
||||
DN_AssertF(required_size >= (slot_size_in_bytes >> 1), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes >> 1));
|
||||
|
||||
DN_PoolSlot *slot = nullptr;
|
||||
if (pool->slots[slot_index]) {
|
||||
slot = pool->slots[slot_index];
|
||||
pool->slots[slot_index] = slot->next;
|
||||
DN_Memset(slot->data, 0, size);
|
||||
DN_Assert(DN_IsPowerOfTwoAligned(slot->data, pool->align));
|
||||
} else {
|
||||
void *bytes = DN_Arena_Alloc(pool->arena, slot_size_in_bytes, alignof(DN_PoolSlot), DN_ZeroMem_Yes);
|
||||
slot = DN_CAST(DN_PoolSlot *) bytes;
|
||||
|
||||
// NOTE: The raw pointer is round up to the next 'pool->align'-ed
|
||||
// address ensuring at least 1 byte of padding between the raw pointer
|
||||
// and the pointer given to the user and that the user pointer is
|
||||
// aligned to the pool's alignment.
|
||||
//
|
||||
// This allows us to smuggle 1 byte behind the user pointer that has
|
||||
// the offset to the original pointer.
|
||||
slot->data = DN_CAST(void *) DN_AlignDownPowerOfTwo(DN_CAST(uintptr_t) slot + sizeof(DN_PoolSlot) + pool->align, pool->align);
|
||||
|
||||
uintptr_t offset_to_original_ptr = DN_CAST(uintptr_t) slot->data - DN_CAST(uintptr_t) bytes;
|
||||
DN_Assert(slot->data > bytes);
|
||||
DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align);
|
||||
|
||||
// NOTE: Store the offset to the original pointer behind the user's
|
||||
// pointer.
|
||||
char *offset_to_original_storage = DN_CAST(char *) slot->data - 1;
|
||||
DN_Memcpy(offset_to_original_storage, &offset_to_original_ptr, 1);
|
||||
}
|
||||
|
||||
// NOTE: Smuggle the slot type in the next pointer so that we know, when the
|
||||
// pointer gets returned which free list to return the pointer to.
|
||||
result = slot->data;
|
||||
slot->next = DN_CAST(DN_PoolSlot *) slot_index;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8FV(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Pool_IsValid(pool))
|
||||
return result;
|
||||
|
||||
DN_USize size_required = DN_CStr8_FVSize(fmt, args);
|
||||
result.data = DN_CAST(char *) DN_Pool_Alloc(pool, size_required + 1);
|
||||
if (result.data) {
|
||||
result.size = size_required;
|
||||
DN_VSNPrintF(result.data, DN_CAST(int)(result.size + 1), fmt, args);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8F(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Pool_AllocStr8FV(pool, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8Copy(DN_Pool *pool, DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Pool_IsValid(pool))
|
||||
return result;
|
||||
|
||||
if (!DN_Str8_HasData(string))
|
||||
return result;
|
||||
|
||||
char *data = DN_CAST(char *) DN_Pool_Alloc(pool, string.size + 1);
|
||||
if (!data)
|
||||
return result;
|
||||
|
||||
DN_Memcpy(data, string.data, string.size);
|
||||
data[string.size] = 0;
|
||||
result = DN_Str8_Init(data, string.size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_Pool_Dealloc(DN_Pool *pool, void *ptr)
|
||||
{
|
||||
if (!DN_Pool_IsValid(pool) || !ptr)
|
||||
return;
|
||||
|
||||
DN_Assert(DN_Arena_OwnsPtr(pool->arena, ptr));
|
||||
|
||||
char const *one_byte_behind_ptr = DN_CAST(char *) ptr - 1;
|
||||
DN_USize offset_to_original_ptr = 0;
|
||||
DN_Memcpy(&offset_to_original_ptr, one_byte_behind_ptr, 1);
|
||||
DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align);
|
||||
|
||||
char *original_ptr = DN_CAST(char *) ptr - offset_to_original_ptr;
|
||||
DN_PoolSlot *slot = DN_CAST(DN_PoolSlot *) original_ptr;
|
||||
DN_PoolSlotSize slot_index = DN_CAST(DN_PoolSlotSize)(DN_CAST(uintptr_t) slot->next);
|
||||
DN_Assert(slot_index < DN_PoolSlotSize_Count);
|
||||
|
||||
slot->next = pool->slots[slot_index];
|
||||
pool->slots[slot_index] = slot;
|
||||
}
|
||||
|
||||
DN_API void *DN_Pool_Copy(DN_Pool *pool, void const *data, DN_U64 size, uint8_t align)
|
||||
{
|
||||
if (!pool || !data || size == 0)
|
||||
return nullptr;
|
||||
|
||||
// TODO: Hmm should align be part of the alloc interface in general? I'm not going to worry
|
||||
// about this until we crash because of misalignment.
|
||||
DN_Assert(pool->align >= align);
|
||||
|
||||
void *result = DN_Pool_Alloc(pool, size);
|
||||
if (result)
|
||||
DN_Memcpy(result, data, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -3,244 +3,4 @@
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
enum DN_MemCommit
|
||||
{
|
||||
DN_MemCommit_No,
|
||||
DN_MemCommit_Yes,
|
||||
};
|
||||
|
||||
typedef DN_U32 DN_MemPage;
|
||||
enum DN_MemPage_
|
||||
{
|
||||
// Exception on read/write with a page. This flag overrides the read/write
|
||||
// access.
|
||||
DN_MemPage_NoAccess = 1 << 0,
|
||||
|
||||
DN_MemPage_Read = 1 << 1, // Only read permitted on the page.
|
||||
|
||||
// Only write permitted on the page. On Windows this is not supported and
|
||||
// will be promoted to read+write permissions.
|
||||
DN_MemPage_Write = 1 << 2,
|
||||
|
||||
DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write,
|
||||
|
||||
// Modifier used in conjunction with previous flags. Raises exception on
|
||||
// first access to the page, then, the underlying protection flags are
|
||||
// active. This is supported on Windows, on other OS's using this flag will
|
||||
// set the OS equivalent of DN_MemPage_NoAccess.
|
||||
// This flag must only be used in DN_Mem_Protect
|
||||
DN_MemPage_Guard = 1 << 3,
|
||||
|
||||
// If leak tracing is enabled, this flag will allow the allocation recorded
|
||||
// from the reserve call to be leaked, e.g. not printed when leaks are
|
||||
// dumped to the console.
|
||||
DN_MemPage_AllocRecordLeakPermitted = 1 << 4,
|
||||
|
||||
// If leak tracing is enabled this flag will prevent any allocation record
|
||||
// from being created in the allocation table at all. If this flag is
|
||||
// enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the
|
||||
// record will never be created.
|
||||
DN_MemPage_NoAllocRecordEntry = 1 << 5,
|
||||
|
||||
// [INTERNAL] Do not use. All flags together do not constitute a correct
|
||||
// configuration of pages.
|
||||
DN_MemPage_All = DN_MemPage_NoAccess |
|
||||
DN_MemPage_ReadWrite |
|
||||
DN_MemPage_Guard |
|
||||
DN_MemPage_AllocRecordLeakPermitted |
|
||||
DN_MemPage_NoAllocRecordEntry,
|
||||
};
|
||||
|
||||
#if !defined(DN_ARENA_RESERVE_SIZE)
|
||||
#define DN_ARENA_RESERVE_SIZE DN_Megabytes(64)
|
||||
#endif
|
||||
|
||||
#if !defined(DN_ARENA_COMMIT_SIZE)
|
||||
#define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64)
|
||||
#endif
|
||||
|
||||
enum DN_Allocator
|
||||
{
|
||||
DN_Allocator_Arena,
|
||||
DN_Allocator_Pool,
|
||||
};
|
||||
|
||||
struct DN_ArenaBlock
|
||||
{
|
||||
DN_ArenaBlock *prev;
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 reserve_sum;
|
||||
};
|
||||
|
||||
typedef uint32_t DN_ArenaFlags;
|
||||
|
||||
enum DN_ArenaFlags_
|
||||
{
|
||||
DN_ArenaFlags_Nil = 0,
|
||||
DN_ArenaFlags_NoGrow = 1 << 0,
|
||||
DN_ArenaFlags_NoPoison = 1 << 1,
|
||||
DN_ArenaFlags_NoAllocTrack = 1 << 2,
|
||||
DN_ArenaFlags_AllocCanLeak = 1 << 3,
|
||||
|
||||
// NOTE: Internal flags. Do not use
|
||||
DN_ArenaFlags_UserBuffer = 1 << 4,
|
||||
DN_ArenaFlags_MemFuncs = 1 << 5,
|
||||
};
|
||||
|
||||
struct DN_ArenaInfo
|
||||
{
|
||||
DN_U64 used;
|
||||
DN_U64 commit;
|
||||
DN_U64 reserve;
|
||||
DN_U64 blocks;
|
||||
};
|
||||
|
||||
struct DN_ArenaStats
|
||||
{
|
||||
DN_ArenaInfo info;
|
||||
DN_ArenaInfo hwm;
|
||||
};
|
||||
|
||||
enum DN_ArenaMemFuncType
|
||||
{
|
||||
DN_ArenaMemFuncType_Nil,
|
||||
DN_ArenaMemFuncType_Basic,
|
||||
DN_ArenaMemFuncType_VMem,
|
||||
};
|
||||
|
||||
typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size);
|
||||
typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr);
|
||||
typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags);
|
||||
typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags);
|
||||
typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size);
|
||||
struct DN_ArenaMemFuncs
|
||||
{
|
||||
DN_ArenaMemFuncType type;
|
||||
DN_ArenaMemBasicAllocFunc *basic_alloc;
|
||||
DN_ArenaMemBasicDeallocFunc *basic_dealloc;
|
||||
|
||||
DN_U32 vmem_page_size;
|
||||
DN_ArenaMemVMemReserveFunc *vmem_reserve;
|
||||
DN_ArenaMemVMemCommitFunc *vmem_commit;
|
||||
DN_ArenaMemVMemReleaseFunc *vmem_release;
|
||||
};
|
||||
|
||||
struct DN_Arena
|
||||
{
|
||||
DN_ArenaMemFuncs mem_funcs;
|
||||
DN_ArenaBlock *curr;
|
||||
DN_ArenaStats stats;
|
||||
DN_ArenaFlags flags;
|
||||
DN_Str8 label;
|
||||
DN_Arena *prev, *next;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMem
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_U64 used_sum;
|
||||
};
|
||||
|
||||
struct DN_ArenaTempMemScope
|
||||
{
|
||||
DN_ArenaTempMemScope(DN_Arena *arena);
|
||||
~DN_ArenaTempMemScope();
|
||||
DN_ArenaTempMem mem;
|
||||
};
|
||||
|
||||
DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64);
|
||||
|
||||
#if !defined(DN_POOL_DEFAULT_ALIGN)
|
||||
#define DN_POOL_DEFAULT_ALIGN 16
|
||||
#endif
|
||||
|
||||
struct DN_PoolSlot
|
||||
{
|
||||
void *data;
|
||||
DN_PoolSlot *next;
|
||||
};
|
||||
|
||||
enum DN_PoolSlotSize
|
||||
{
|
||||
DN_PoolSlotSize_32B,
|
||||
DN_PoolSlotSize_64B,
|
||||
DN_PoolSlotSize_128B,
|
||||
DN_PoolSlotSize_256B,
|
||||
DN_PoolSlotSize_512B,
|
||||
DN_PoolSlotSize_1KiB,
|
||||
DN_PoolSlotSize_2KiB,
|
||||
DN_PoolSlotSize_4KiB,
|
||||
DN_PoolSlotSize_8KiB,
|
||||
DN_PoolSlotSize_16KiB,
|
||||
DN_PoolSlotSize_32KiB,
|
||||
DN_PoolSlotSize_64KiB,
|
||||
DN_PoolSlotSize_128KiB,
|
||||
DN_PoolSlotSize_256KiB,
|
||||
DN_PoolSlotSize_512KiB,
|
||||
DN_PoolSlotSize_1MiB,
|
||||
DN_PoolSlotSize_2MiB,
|
||||
DN_PoolSlotSize_4MiB,
|
||||
DN_PoolSlotSize_8MiB,
|
||||
DN_PoolSlotSize_16MiB,
|
||||
DN_PoolSlotSize_32MiB,
|
||||
DN_PoolSlotSize_64MiB,
|
||||
DN_PoolSlotSize_128MiB,
|
||||
DN_PoolSlotSize_256MiB,
|
||||
DN_PoolSlotSize_512MiB,
|
||||
DN_PoolSlotSize_1GiB,
|
||||
DN_PoolSlotSize_2GiB,
|
||||
DN_PoolSlotSize_4GiB,
|
||||
DN_PoolSlotSize_8GiB,
|
||||
DN_PoolSlotSize_16GiB,
|
||||
DN_PoolSlotSize_32GiB,
|
||||
DN_PoolSlotSize_Count,
|
||||
};
|
||||
|
||||
struct DN_Pool
|
||||
{
|
||||
DN_Arena *arena;
|
||||
DN_PoolSlot *slots[DN_PoolSlotSize_Count];
|
||||
DN_U8 align;
|
||||
};
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_Arena_FromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs);
|
||||
DN_API void DN_Arena_Deinit (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_Commit (DN_Arena *arena, DN_U64 size);
|
||||
DN_API bool DN_Arena_CommitTo (DN_Arena *arena, DN_U64 pos);
|
||||
DN_API bool DN_Arena_Grow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit);
|
||||
DN_API void * DN_Arena_Alloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_AllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_Arena_Copy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align);
|
||||
DN_API void DN_Arena_PopTo (DN_Arena *arena, DN_U64 init_used);
|
||||
DN_API void DN_Arena_Pop (DN_Arena *arena, DN_U64 amount);
|
||||
DN_API DN_U64 DN_Arena_Pos (DN_Arena const *arena);
|
||||
DN_API void DN_Arena_Clear (DN_Arena *arena);
|
||||
DN_API bool DN_Arena_OwnsPtr (DN_Arena const *arena, void *ptr);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStatsArray (DN_ArenaStats const *array, DN_USize size);
|
||||
DN_API DN_ArenaStats DN_Arena_SumStats (DN_ArenaStats lhs, DN_ArenaStats rhs);
|
||||
DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats (DN_Arena const *array, DN_USize size);
|
||||
DN_API DN_ArenaTempMem DN_Arena_TempMemBegin (DN_Arena *arena);
|
||||
DN_API void DN_Arena_TempMemEnd (DN_ArenaTempMem mem);
|
||||
#define DN_Arena_New_Frame(T, zero_mem) (T *)DN_Arena_Alloc(DN_OS_TLSGet()->frame_arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_New(arena, T, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewArray(arena, T, count, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T) * (count), alignof(T), zero_mem)
|
||||
#define DN_Arena_NewCopy(arena, T, src) (T *)DN_Arena_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Arena_NewArrayCopy(arena, T, src, count) (T *)DN_Arena_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
|
||||
DN_API DN_Pool DN_Pool_FromArena (DN_Arena *arena, DN_U8 align);
|
||||
DN_API bool DN_Pool_IsValid (DN_Pool const *pool);
|
||||
DN_API void * DN_Pool_Alloc (DN_Pool *pool, DN_USize size);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8FV (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8F (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Pool_AllocStr8Copy (DN_Pool *pool, DN_Str8 string);
|
||||
DN_API void DN_Pool_Dealloc (DN_Pool *pool, void *ptr);
|
||||
DN_API void * DN_Pool_Copy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align);
|
||||
|
||||
#define DN_Pool_New(pool, T) (T *)DN_Pool_Alloc(pool, sizeof(T))
|
||||
#define DN_Pool_NewArray(pool, T, count) (T *)DN_Pool_Alloc(pool, count * sizeof(T))
|
||||
#define DN_Pool_NewCopy(arena, T, src) (T *)DN_Pool_Copy (arena, (src), sizeof(T), alignof(T))
|
||||
#define DN_Pool_NewArrayCopy(arena, T, src, count) (T *)DN_Pool_Copy (arena, (src), sizeof(T) * (count), alignof(T))
|
||||
#endif // !defined(DN_BASE_MEM_H)
|
||||
|
||||
@ -34,12 +34,12 @@ struct DN_StackTraceWalkResultIterator
|
||||
|
||||
|
||||
#if defined(DN_FREESTANDING)
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_Walk(...)
|
||||
#define DN_StackTrace_WalkResultIterate(...)
|
||||
#define DN_StackTrace_WalkResultToStr8(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A")
|
||||
#define DN_StackTrace_WalkResultToStr8(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_WalkStr8(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_WalkStr8FromHeap(...) DN_Str8Lit("N/A")
|
||||
#define DN_StackTrace_GetFrames(...)
|
||||
#define DN_StackTrace_RawFrameToFrame(...)
|
||||
#define DN_StackTrace_Print(...)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,244 +0,0 @@
|
||||
#if !defined(DN_BASE_STRING_H)
|
||||
#define DN_BASE_STRING_H
|
||||
|
||||
#include "../dn_base_inc.h"
|
||||
|
||||
#if !defined(DN_STB_SPRINTF_HEADER_ONLY)
|
||||
#define STB_SPRINTF_IMPLEMENTATION
|
||||
#define STB_SPRINTF_STATIC
|
||||
#endif
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(4505) // Unused function warning
|
||||
DN_GCC_WARNING_PUSH
|
||||
DN_GCC_WARNING_DISABLE(-Wunused-function)
|
||||
#include "../External/stb_sprintf.h"
|
||||
DN_GCC_WARNING_POP
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
#define DN_SPrintF(...) STB_SPRINTF_DECORATE(sprintf)(__VA_ARGS__)
|
||||
#define DN_SNPrintF(...) STB_SPRINTF_DECORATE(snprintf)(__VA_ARGS__)
|
||||
#define DN_VSPrintF(...) STB_SPRINTF_DECORATE(vsprintf)(__VA_ARGS__)
|
||||
#define DN_VSNPrintF(...) STB_SPRINTF_DECORATE(vsnprintf)(__VA_ARGS__)
|
||||
|
||||
struct DN_Str8Link
|
||||
{
|
||||
DN_Str8 string; // The string
|
||||
DN_Str8Link *next; // The next string in the linked list
|
||||
DN_Str8Link *prev; // The prev string in the linked list
|
||||
};
|
||||
|
||||
struct DN_Str8BSplitResult
|
||||
{
|
||||
DN_Str8 lhs;
|
||||
DN_Str8 rhs;
|
||||
};
|
||||
|
||||
struct DN_Str8FindResult
|
||||
{
|
||||
bool found; // True if string was found. If false, the subsequent fields below are not set.
|
||||
DN_USize index; // Index in the buffer where the found string starts
|
||||
DN_Str8 match; // Matching string in the buffer that was searched
|
||||
DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer
|
||||
DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer
|
||||
DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it
|
||||
};
|
||||
|
||||
enum DN_Str8IsAll
|
||||
{
|
||||
DN_Str8IsAll_Digits,
|
||||
DN_Str8IsAll_Hex,
|
||||
};
|
||||
|
||||
enum DN_Str8EqCase
|
||||
{
|
||||
DN_Str8EqCase_Sensitive,
|
||||
DN_Str8EqCase_Insensitive,
|
||||
};
|
||||
|
||||
enum DN_Str8FindFlag
|
||||
{
|
||||
DN_Str8FindFlag_Digit = 1 << 0, // 0-9
|
||||
DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' '
|
||||
DN_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z
|
||||
DN_Str8FindFlag_Plus = 1 << 3, // +
|
||||
DN_Str8FindFlag_Minus = 1 << 4, // -
|
||||
DN_Str8FindFlag_AlphaNum = DN_Str8FindFlag_Alphabet | DN_Str8FindFlag_Digit,
|
||||
};
|
||||
|
||||
enum DN_Str8SplitIncludeEmptyStrings
|
||||
{
|
||||
DN_Str8SplitIncludeEmptyStrings_No,
|
||||
DN_Str8SplitIncludeEmptyStrings_Yes,
|
||||
};
|
||||
|
||||
struct DN_Str8ToU64Result
|
||||
{
|
||||
bool success;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
struct DN_Str8ToI64Result
|
||||
{
|
||||
bool success;
|
||||
int64_t value;
|
||||
};
|
||||
|
||||
struct DN_Str8DotTruncateResult
|
||||
{
|
||||
bool truncated;
|
||||
DN_Str8 str8;
|
||||
};
|
||||
|
||||
struct DN_Str8Builder
|
||||
{
|
||||
DN_Arena *arena; // Allocator to use to back the string list
|
||||
DN_Str8Link *head; // First string in the linked list of strings
|
||||
DN_Str8Link *tail; // Last string in the linked list of strings
|
||||
DN_USize string_size; // The size in bytes necessary to construct the current string
|
||||
DN_USize count; // The number of links in the linked list of strings
|
||||
};
|
||||
|
||||
enum DN_Str8BuilderAdd
|
||||
{
|
||||
DN_Str8BuilderAdd_Append,
|
||||
DN_Str8BuilderAdd_Prepend,
|
||||
};
|
||||
|
||||
struct DN_Str8x64
|
||||
{
|
||||
char data[64];
|
||||
DN_USize size;
|
||||
};
|
||||
|
||||
struct DN_Str8x256
|
||||
{
|
||||
char data[256];
|
||||
DN_USize size;
|
||||
};
|
||||
|
||||
DN_API DN_USize DN_CStr8_FSize (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_USize DN_CStr8_FVSize (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_USize DN_CStr8_Size (char const *a);
|
||||
DN_API DN_USize DN_CStr16_Size (wchar_t const *a);
|
||||
|
||||
#define DN_STR16(string) DN_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1}
|
||||
#define DN_Str16_HasData(string) ((string).data && (string).size)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
DN_API bool operator== (DN_Str16 const &lhs, DN_Str16 const &rhs);
|
||||
DN_API bool operator!= (DN_Str16 const &lhs, DN_Str16 const &rhs);
|
||||
#endif
|
||||
|
||||
#define DN_STR8(string) DN_Str8{(char *)(string), (sizeof(string) - 1)}
|
||||
#define DN_STR_FMT(string) (int)((string).size), (string).data
|
||||
#define DN_Str8_Init(data, size) DN_Str8{(char *)(data), (size_t)(size)}
|
||||
#define DN_Str8_HasData(string) ((string).data && (string).size)
|
||||
DN_API DN_Str8 DN_Str8_Alloc (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem);
|
||||
DN_API DN_Str8 DN_Str8_FromCStr8 (char const *src);
|
||||
DN_API DN_Str8 DN_Str8_FromF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FromFV (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8_FromFPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FromStr8 (DN_Arena *arena, DN_Str8 string);
|
||||
DN_API bool DN_Str8_IsAll (DN_Str8 string, DN_Str8IsAll is_all);
|
||||
DN_API char * DN_Str8_End (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_Slice (DN_Str8 string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8 DN_Str8_Advance (DN_Str8 string, DN_USize amount);
|
||||
DN_API DN_Str8 DN_Str8_NextLine (DN_Str8 string);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplit (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitLast (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_USize DN_Str8_Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8_SplitAlloc (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8FindResult DN_Str8_FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8_FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case);
|
||||
DN_API DN_Str8FindResult DN_Str8_Find (DN_Str8 string, uint32_t flags);
|
||||
DN_API DN_Str8 DN_Str8_Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8_ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API bool DN_Str8_Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8_EqInsensitive (DN_Str8 lhs, DN_Str8 rhs);
|
||||
DN_API bool DN_Str8_StartsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8_StartsWithInsensitive (DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8_EndsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API bool DN_Str8_EndsWithInsensitive (DN_Str8 string, DN_Str8 prefix);
|
||||
DN_API bool DN_Str8_HasChar (DN_Str8 string, char ch);
|
||||
DN_API DN_Str8 DN_Str8_TrimPrefix (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8_TrimHexPrefix (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimSuffix (DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8_TrimAround (DN_Str8 string, DN_Str8 trim_string);
|
||||
DN_API DN_Str8 DN_Str8_TrimHeadWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimTailWhitespace (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimWhitespaceAround (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_TrimByteOrderMark (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_FileNameFromPath (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FileNameNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FilePathNoExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FileExtension (DN_Str8 path);
|
||||
DN_API DN_Str8 DN_Str8_FileDirectoryFromPath (DN_Str8 path);
|
||||
DN_API DN_Str8ToU64Result DN_Str8_ToU64 (DN_Str8 string, char separator);
|
||||
DN_API DN_Str8ToI64Result DN_Str8_ToI64 (DN_Str8 string, char separator);
|
||||
DN_API DN_Str8 DN_Str8_AppendF (DN_Arena *arena, DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_AppendFV (DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8_FillF (DN_Arena *arena, DN_USize count, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FillFV (DN_Arena *arena, DN_USize count, char const *fmt, va_list args);
|
||||
DN_API void DN_Str8_Remove (DN_Str8 *string, DN_USize offset, DN_USize size);
|
||||
DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddle (DN_Arena *arena, DN_Str8 str8, uint32_t side_size, DN_Str8 truncator);
|
||||
DN_API DN_Str8 DN_Str8_Lower (DN_Arena *arena, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_Upper (DN_Arena *arena, DN_Str8 string);
|
||||
#if defined(__cplusplus)
|
||||
DN_API bool operator== (DN_Str8 const &lhs, DN_Str8 const &rhs);
|
||||
DN_API bool operator!= (DN_Str8 const &lhs, DN_Str8 const &rhs);
|
||||
#endif
|
||||
|
||||
DN_API DN_Str8 DN_LStr8_AppendFV (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_LStr8_AppendF (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...);
|
||||
#define DN_IStr8_AppendF(struct_ptr, fmt, ...) DN_LStr8_AppendF((struct_ptr)->data, &(struct_ptr)->size, DN_ArrayCountU((struct_ptr)->data), fmt, ##__VA_ARGS__)
|
||||
#define DN_Str8_FromIStr8(struct_ptr) DN_Str8_Init((struct_ptr)->data, (struct_ptr)->size)
|
||||
|
||||
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromArena (DN_Arena *arena);
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size);
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromBuilder (DN_Arena *arena, DN_Str8Builder const *builder);
|
||||
DN_API bool DN_Str8Builder_AddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8Builder_AddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add);
|
||||
DN_API bool DN_Str8Builder_AddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
#define DN_Str8Builder_AppendArrayRef(builder, strings, size) DN_Str8Builder_AddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8Builder_AppendArrayCopy(builder, strings, size) DN_Str8Builder_AddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8Builder_AppendSliceRef(builder, slice) DN_Str8Builder_AddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
#define DN_Str8Builder_AppendSliceCopy(builder, slice) DN_Str8Builder_AddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append)
|
||||
DN_API bool DN_Str8Builder_AppendRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8Builder_AppendCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8Builder_AppendFV(builder, fmt, args) DN_Str8Builder_AddFV(builder, DN_Str8BuilderAdd_Append, fmt, args)
|
||||
DN_API bool DN_Str8Builder_AppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8Builder_AppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8Builder_AppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize size);
|
||||
DN_API bool DN_Str8Builder_AppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
DN_API bool DN_Str8Builder_AppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src);
|
||||
#define DN_Str8Builder_PrependArrayRef(builder, strings, size) DN_Str8Builder_AddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8Builder_PrependArrayCopy(builder, strings, size) DN_Str8Builder_AddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8Builder_PrependSliceRef(builder, slice) DN_Str8Builder_AddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
#define DN_Str8Builder_PrependSliceCopy(builder, slice) DN_Str8Builder_AddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend)
|
||||
DN_API bool DN_Str8Builder_PrependRef (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API bool DN_Str8Builder_PrependCopy (DN_Str8Builder *builder, DN_Str8 string);
|
||||
#define DN_Str8Builder_PrependFV(builder, fmt, args) DN_Str8Builder_AddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args)
|
||||
DN_API bool DN_Str8Builder_PrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API bool DN_Str8Builder_Erase (DN_Str8Builder *builder, DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8Builder_Build (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8Builder_BuildSlice (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
|
||||
DN_API bool DN_Char_IsAlphabet (char ch);
|
||||
DN_API bool DN_Char_IsDigit (char ch);
|
||||
DN_API bool DN_Char_IsAlphaNum (char ch);
|
||||
DN_API bool DN_Char_IsWhitespace (char ch);
|
||||
DN_API bool DN_Char_IsHex (char ch);
|
||||
DN_API char DN_Char_ToHex (char ch);
|
||||
DN_API char DN_Char_ToHexUnchecked (char ch);
|
||||
DN_API char DN_Char_ToLower (char ch);
|
||||
DN_API char DN_Char_ToUpper (char ch);
|
||||
|
||||
DN_API int DN_UTF8_EncodeCodepoint (uint8_t utf8[4], uint32_t codepoint);
|
||||
DN_API int DN_UTF16_EncodeCodepoint (uint16_t utf16[2], uint32_t codepoint);
|
||||
#endif // !defined(DN_BASE_STRING_H)
|
||||
@ -9,19 +9,19 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init)
|
||||
#if defined(DN_LEAK_TRACKING)
|
||||
// NOTE: Setup the allocation table with allocation tracking turned off on
|
||||
// the arena we're using to initialise the table.
|
||||
core->alloc_table_arena = DN_Arena_FromVMem(DN_Megabytes(1), DN_Kilobytes(512), DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak);
|
||||
core->alloc_table_arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(512), DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak);
|
||||
core->alloc_table = DN_DSMap_Init<DN_DebugAlloc>(&core->alloc_table_arena, 4096, DN_DSMapFlags_Nil);
|
||||
#endif
|
||||
|
||||
// NOTE: Print out init features ///////////////////////////////////////////////////////////////
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena);
|
||||
if (on_init & DN_CoreOnInit_LogLibFeatures) {
|
||||
DN_Str8Builder_AppendRef(&builder, DN_STR8("DN initialised:\n"));
|
||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("DN initialised:\n"));
|
||||
|
||||
DN_F32 page_size_kib = g_dn_os_core_->page_size / 1024.0f;
|
||||
DN_F32 alloc_granularity_kib = g_dn_os_core_->alloc_granularity / 1024.0f;
|
||||
DN_Str8Builder_AppendF(&builder,
|
||||
DN_Str8BuilderAppendF(&builder,
|
||||
" OS Page Size/Alloc Granularity: %.1f/%.1fKiB\n"
|
||||
" Logical Processor Count: %u\n",
|
||||
page_size_kib,
|
||||
@ -30,29 +30,29 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init)
|
||||
|
||||
#if DN_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
|
||||
if (DN_ASAN_POISON) {
|
||||
DN_Str8Builder_AppendF(
|
||||
DN_Str8BuilderAppendF(
|
||||
&builder, " ASAN manual poisoning%s\n", DN_ASAN_VET_POISON ? " (+vet sanity checks)" : "");
|
||||
DN_Str8Builder_AppendF(&builder, " ASAN poison guard size: %u\n", DN_ASAN_POISON_GUARD_SIZE);
|
||||
DN_Str8BuilderAppendF(&builder, " ASAN poison guard size: %u\n", DN_ASAN_POISON_GUARD_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DN_LEAK_TRACKING)
|
||||
DN_Str8Builder_AppendRef(&builder, DN_STR8(" Allocation leak tracing\n"));
|
||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit(" Allocation leak tracing\n"));
|
||||
#endif
|
||||
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN) || defined(DN_PLATFORM_POSIX)
|
||||
DN_POSIXCore *posix = DN_CAST(DN_POSIXCore *)g_dn_os_core_->platform_context;
|
||||
DN_Str8Builder_AppendF(&builder, " Clock GetTime: %S\n", posix->clock_monotonic_raw ? DN_STR8("CLOCK_MONOTONIC_RAW") : DN_STR8("CLOCK_MONOTONIC"));
|
||||
DN_POSIXCore *posix = DN_Cast(DN_POSIXCore *)g_dn_os_core_->platform_context;
|
||||
DN_Str8BuilderAppendF(&builder, " Clock GetTime: %S\n", posix->clock_monotonic_raw ? DN_Str8Lit("CLOCK_MONOTONIC_RAW") : DN_Str8Lit("CLOCK_MONOTONIC"));
|
||||
#endif
|
||||
// TODO(doyle): Add stacktrace feature log
|
||||
}
|
||||
|
||||
if (on_init & DN_CoreOnInit_LogCPUFeatures) {
|
||||
DN_CPUReport const *report = &g_dn_os_core_->cpu_report;
|
||||
DN_Str8 brand = DN_Str8_TrimWhitespaceAround(DN_Str8_Init(report->brand, sizeof(report->brand) - 1));
|
||||
DN_Str8 brand = DN_Str8TrimWhitespaceAround(DN_Str8FromPtr(report->brand, sizeof(report->brand) - 1));
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(3) when a string is required in call to 'DN_Str8Builder_AppendF' Actual type: 'struct DN_Str8'.
|
||||
DN_Str8Builder_AppendF(&builder, " CPU '%S' from '%s' detected:\n", brand, report->vendor);
|
||||
DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(3) when a string is required in call to 'DN_Str8BuilderAppendF' Actual type: 'struct DN_Str8'.
|
||||
DN_Str8BuilderAppendF(&builder, " CPU '%S' from '%s' detected:\n", brand, report->vendor);
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
DN_USize longest_feature_name = 0;
|
||||
@ -64,18 +64,18 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init)
|
||||
for (DN_ForIndexU(feature_index, DN_CPUFeature_Count)) {
|
||||
DN_CPUFeatureDecl feature_decl = g_dn_cpu_feature_decl[feature_index];
|
||||
bool has_feature = DN_CPUHasFeature(report, feature_decl.value);
|
||||
DN_Str8Builder_AppendF(&builder,
|
||||
DN_Str8BuilderAppendF(&builder,
|
||||
" %.*s:%*s%s\n",
|
||||
DN_STR_FMT(feature_decl.label),
|
||||
DN_CAST(int)(longest_feature_name - feature_decl.label.size),
|
||||
DN_Str8PrintFmt(feature_decl.label),
|
||||
DN_Cast(int)(longest_feature_name - feature_decl.label.size),
|
||||
"",
|
||||
has_feature ? "available" : "not available");
|
||||
}
|
||||
}
|
||||
|
||||
DN_Str8 info_log = DN_Str8Builder_Build(&builder, tmem.arena);
|
||||
if (DN_Str8_HasData(info_log))
|
||||
DN_LOG_DebugF("%.*s", DN_STR_FMT(info_log));
|
||||
DN_Str8 info_log = DN_Str8BuilderBuild(&builder, tmem.arena);
|
||||
if (info_log.size)
|
||||
DN_LOG_DebugF("%.*s", DN_Str8PrintFmt(info_log));
|
||||
}
|
||||
|
||||
DN_API void DN_Core_BeginFrame()
|
||||
|
||||
@ -24,7 +24,7 @@ DN_API DN_StackTraceWalkResult DN_StackTrace_Walk(DN_Arena *arena, uint16_t limi
|
||||
if (!SymInitialize(result.process, nullptr /*UserSearchPath*/, true /*fInvadeProcess*/)) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
DN_W32Error error = DN_W32_LastError(tmem.arena);
|
||||
DN_LOG_ErrorF("SymInitialize failed, stack trace can not be generated (%lu): %.*s\n", error.code, DN_STR_FMT(error.msg));
|
||||
DN_LOG_ErrorF("SymInitialize failed, stack trace can not be generated (%lu): %.*s\n", error.code, DN_Str8PrintFmt(error.msg));
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,8 +58,8 @@ DN_API DN_StackTraceWalkResult DN_StackTrace_Walk(DN_Arena *arena, uint16_t limi
|
||||
}
|
||||
DN_TicketMutex_End(&mutex);
|
||||
|
||||
result.base_addr = DN_Arena_NewArray(arena, uint64_t, raw_frames.size, DN_ZeroMem_No);
|
||||
result.size = DN_CAST(uint16_t) raw_frames.size;
|
||||
result.base_addr = DN_ArenaNewArray(arena, uint64_t, raw_frames.size, DN_ZMem_No);
|
||||
result.size = DN_Cast(uint16_t) raw_frames.size;
|
||||
DN_Memcpy(result.base_addr, raw_frames.data, raw_frames.size * sizeof(raw_frames.data[0]));
|
||||
#else
|
||||
(void)limit;
|
||||
@ -68,14 +68,14 @@ DN_API DN_StackTraceWalkResult DN_StackTrace_Walk(DN_Arena *arena, uint16_t limi
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_StackTrace_AddWalkToStr8Builder_(DN_StackTraceWalkResult const *walk, DN_Str8Builder *builder, DN_USize skip)
|
||||
static void DN_StackTrace_AddWalkToStr8Builder(DN_StackTraceWalkResult const *walk, DN_Str8Builder *builder, DN_USize skip)
|
||||
{
|
||||
DN_StackTraceRawFrame raw_frame = {};
|
||||
raw_frame.process = walk->process;
|
||||
for (DN_USize index = skip; index < walk->size; index++) {
|
||||
raw_frame.base_addr = walk->base_addr[index];
|
||||
DN_StackTraceFrame frame = DN_StackTrace_RawFrameToFrame(builder->arena, raw_frame);
|
||||
DN_Str8Builder_AppendF(builder, "%.*s(%zu): %.*s%s", DN_STR_FMT(frame.file_name), frame.line_number, DN_STR_FMT(frame.function_name), (DN_CAST(int) index == walk->size - 1) ? "" : "\n");
|
||||
DN_Str8BuilderAppendF(builder, "%.*s(%zu): %.*s%s", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name), (DN_Cast(int) index == walk->size - 1) ? "" : "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,9 +101,9 @@ DN_API DN_Str8 DN_StackTrace_WalkResultToStr8(DN_Arena *arena, DN_StackTraceWalk
|
||||
return result;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena);
|
||||
DN_StackTrace_AddWalkToStr8Builder_(walk, &builder, skip);
|
||||
result = DN_Str8Builder_Build(&builder, arena);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena);
|
||||
DN_StackTrace_AddWalkToStr8Builder(walk, &builder, skip);
|
||||
result = DN_Str8BuilderBuild(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -119,12 +119,12 @@ DN_API DN_Str8 DN_StackTrace_WalkStr8FromHeap(uint16_t limit, uint16_t skip)
|
||||
{
|
||||
// NOTE: We don't use WalkResultToStr8 because that uses the TLS arenas which
|
||||
// does not use the OS heap.
|
||||
DN_Arena arena = DN_Arena_FromHeap(DN_Kilobytes(64), DN_ArenaFlags_NoAllocTrack);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(&arena);
|
||||
DN_Arena arena = DN_ArenaFromHeap(DN_Kilobytes(64), DN_ArenaFlags_NoAllocTrack);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&arena);
|
||||
DN_StackTraceWalkResult walk = DN_StackTrace_Walk(&arena, limit);
|
||||
DN_StackTrace_AddWalkToStr8Builder_(&walk, &builder, skip);
|
||||
DN_Str8 result = DN_Str8Builder_BuildFromOSHeap(&builder);
|
||||
DN_Arena_Deinit(&arena);
|
||||
DN_StackTrace_AddWalkToStr8Builder(&walk, &builder, skip);
|
||||
DN_Str8 result = DN_Str8BuilderBuildFromOSHeap(&builder);
|
||||
DN_ArenaDeinit(&arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ DN_API DN_Slice<DN_StackTraceFrame> DN_StackTrace_GetFrames(DN_Arena *arena, uin
|
||||
return result;
|
||||
|
||||
DN_USize slice_index = 0;
|
||||
result = DN_Slice_Alloc<DN_StackTraceFrame>(arena, walk.size, DN_ZeroMem_No);
|
||||
result = DN_Slice_Alloc<DN_StackTraceFrame>(arena, walk.size, DN_ZMem_No);
|
||||
for (DN_StackTraceWalkResultIterator it = {}; DN_StackTrace_WalkResultIterate(&it, &walk); ) {
|
||||
result.data[slice_index++] = DN_StackTrace_RawFrameToFrame(arena, it.raw_frame);
|
||||
}
|
||||
@ -167,7 +167,7 @@ DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame(DN_Arena *arena, DN_Stac
|
||||
// NOTE: Get function name /////////////////////////////////////////////////////////////////////
|
||||
|
||||
alignas(SYMBOL_INFOW) char buffer[sizeof(SYMBOL_INFOW) + (MAX_SYM_NAME * sizeof(wchar_t))] = {};
|
||||
SYMBOL_INFOW *symbol = DN_CAST(SYMBOL_INFOW *)buffer;
|
||||
SYMBOL_INFOW *symbol = DN_Cast(SYMBOL_INFOW *)buffer;
|
||||
symbol->SizeOfStruct = sizeof(*symbol);
|
||||
symbol->MaxNameLen = sizeof(buffer) - sizeof(*symbol);
|
||||
|
||||
@ -176,7 +176,7 @@ DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame(DN_Arena *arena, DN_Stac
|
||||
|
||||
// NOTE: Construct result //////////////////////////////////////////////////////////////////////
|
||||
|
||||
DN_Str16 file_name16 = DN_Str16{line.FileName, DN_CStr16_Size(line.FileName)};
|
||||
DN_Str16 file_name16 = DN_Str16{line.FileName, DN_CStr16Size(line.FileName)};
|
||||
DN_Str16 function_name16 = DN_Str16{symbol->Name, symbol->NameLen};
|
||||
|
||||
DN_StackTraceFrame result = {};
|
||||
@ -185,10 +185,10 @@ DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame(DN_Arena *arena, DN_Stac
|
||||
result.file_name = DN_W32_Str16ToStr8(arena, file_name16);
|
||||
result.function_name = DN_W32_Str16ToStr8(arena, function_name16);
|
||||
|
||||
if (!DN_Str8_HasData(result.function_name))
|
||||
result.function_name = DN_STR8("<unknown function>");
|
||||
if (!DN_Str8_HasData(result.file_name))
|
||||
result.file_name = DN_STR8("<unknown file>");
|
||||
if (result.function_name.size == 0)
|
||||
result.function_name = DN_Str8Lit("<unknown function>");
|
||||
if (result.file_name.size == 0)
|
||||
result.file_name = DN_Str8Lit("<unknown file>");
|
||||
#else
|
||||
DN_StackTraceFrame result = {};
|
||||
#endif
|
||||
@ -200,7 +200,7 @@ DN_API void DN_StackTrace_Print(uint16_t limit)
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Slice<DN_StackTraceFrame> stack_trace = DN_StackTrace_GetFrames(tmem.arena, limit);
|
||||
for (DN_StackTraceFrame &frame : stack_trace)
|
||||
DN_OS_PrintErrLnF("%.*s(%I64u): %.*s", DN_STR_FMT(frame.file_name), frame.line_number, DN_STR_FMT(frame.function_name));
|
||||
DN_OS_PrintErrLnF("%.*s(%I64u): %.*s", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name));
|
||||
}
|
||||
|
||||
DN_API void DN_StackTrace_ReloadSymbols()
|
||||
@ -229,12 +229,12 @@ DN_API void DN_DBGTrackAlloc(void *ptr, DN_USize size, bool leak_permitted)
|
||||
// already existed.
|
||||
DN_Str8 stack_trace = DN_StackTrace_WalkStr8FromHeap(128, 3 /*skip*/);
|
||||
DN_DSMap<DN_DebugAlloc> *alloc_table = &g_dn_core->alloc_table;
|
||||
DN_DSMapResult<DN_DebugAlloc> alloc_entry = DN_DSMap_MakeKeyU64(alloc_table, DN_CAST(uint64_t) ptr);
|
||||
DN_DSMapResult<DN_DebugAlloc> alloc_entry = DN_DSMap_MakeKeyU64(alloc_table, DN_Cast(uint64_t) ptr);
|
||||
DN_DebugAlloc *alloc = alloc_entry.value;
|
||||
if (alloc_entry.found) {
|
||||
if ((alloc->flags & DN_DebugAllocFlag_Freed) == 0) {
|
||||
DN_Str8 alloc_size = DN_CVT_BytesStr8FromU64Auto(alloc_table->arena, alloc->size);
|
||||
DN_Str8 new_alloc_size = DN_CVT_BytesStr8FromU64Auto(alloc_table->arena, size);
|
||||
DN_Str8x32 alloc_size = DN_ByteCountStr8x32(alloc->size);
|
||||
DN_Str8x32 new_alloc_size = DN_ByteCountStr8x32(size);
|
||||
DN_HardAssertF(
|
||||
alloc->flags & DN_DebugAllocFlag_Freed,
|
||||
"This pointer is already in the leak tracker, however it has not been freed yet. This "
|
||||
@ -250,10 +250,10 @@ DN_API void DN_DBGTrackAlloc(void *ptr, DN_USize size, bool leak_permitted)
|
||||
"\n"
|
||||
"%.*s\n",
|
||||
ptr,
|
||||
DN_STR_FMT(alloc_size),
|
||||
DN_STR_FMT(alloc->stack_trace),
|
||||
DN_STR_FMT(new_alloc_size),
|
||||
DN_STR_FMT(stack_trace));
|
||||
DN_Str8PrintFmt(alloc_size),
|
||||
DN_Str8PrintFmt(alloc->stack_trace),
|
||||
DN_Str8PrintFmt(new_alloc_size),
|
||||
DN_Str8PrintFmt(stack_trace));
|
||||
}
|
||||
|
||||
// NOTE: Pointer was reused, clean up the prior entry
|
||||
@ -282,7 +282,7 @@ DN_API void DN_DBGTrackDealloc(void *ptr)
|
||||
|
||||
DN_Str8 stack_trace = DN_StackTrace_WalkStr8FromHeap(128, 3 /*skip*/);
|
||||
DN_DSMap<DN_DebugAlloc> *alloc_table = &g_dn_core->alloc_table;
|
||||
DN_DSMapResult<DN_DebugAlloc> alloc_entry = DN_DSMap_FindKeyU64(alloc_table, DN_CAST(uintptr_t) ptr);
|
||||
DN_DSMapResult<DN_DebugAlloc> alloc_entry = DN_DSMap_FindKeyU64(alloc_table, DN_Cast(uintptr_t) ptr);
|
||||
DN_HardAssertF(alloc_entry.found,
|
||||
"Allocated pointer can not be removed as it does not exist in the "
|
||||
"allocation table. When this memory was allocated, the pointer was "
|
||||
@ -291,7 +291,7 @@ DN_API void DN_DBGTrackDealloc(void *ptr)
|
||||
|
||||
DN_DebugAlloc *alloc = alloc_entry.value;
|
||||
if (alloc->flags & DN_DebugAllocFlag_Freed) {
|
||||
DN_Str8 freed_size = DN_CVT_BytesStr8FromU64Auto(alloc_table->arena, alloc->freed_size);
|
||||
DN_Str8x32 freed_size = DN_ByteCountStr8x32(alloc->freed_size);
|
||||
DN_HardAssertF((alloc->flags & DN_DebugAllocFlag_Freed) == 0,
|
||||
"Double free detected, pointer to free was already marked "
|
||||
"as freed. Either the pointer was reallocated but not "
|
||||
@ -309,13 +309,13 @@ DN_API void DN_DBGTrackDealloc(void *ptr)
|
||||
"\n"
|
||||
"%.*s\n"
|
||||
,
|
||||
ptr, DN_STR_FMT(freed_size),
|
||||
DN_STR_FMT(alloc->stack_trace),
|
||||
DN_STR_FMT(alloc->freed_stack_trace),
|
||||
DN_STR_FMT(stack_trace));
|
||||
ptr, DN_Str8PrintFmt(freed_size),
|
||||
DN_Str8PrintFmt(alloc->stack_trace),
|
||||
DN_Str8PrintFmt(alloc->freed_stack_trace),
|
||||
DN_Str8PrintFmt(stack_trace));
|
||||
}
|
||||
|
||||
DN_Assert(!DN_Str8_HasData(alloc->freed_stack_trace));
|
||||
DN_Assert(alloc->freed_stack_trace.size == 0);
|
||||
alloc->flags |= DN_DebugAllocFlag_Freed;
|
||||
alloc->freed_stack_trace = stack_trace;
|
||||
g_dn_core->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.size;
|
||||
@ -333,19 +333,17 @@ DN_API void DN_DBGDumpLeaks()
|
||||
if (alloc_leaked && !leak_permitted) {
|
||||
leaked_bytes += alloc->size;
|
||||
leak_count++;
|
||||
DN_Str8 alloc_size = DN_CVT_BytesStr8FromU64Auto(g_dn_core->alloc_table.arena, alloc->size);
|
||||
DN_Str8x32 alloc_size = DN_ByteCountStr8x32(alloc->size);
|
||||
DN_LOG_WarningF("Pointer (0x%p) leaked %.*s at:\n"
|
||||
"%.*s",
|
||||
alloc->ptr, DN_STR_FMT(alloc_size),
|
||||
DN_STR_FMT(alloc->stack_trace));
|
||||
alloc->ptr, DN_Str8PrintFmt(alloc_size),
|
||||
DN_Str8PrintFmt(alloc->stack_trace));
|
||||
}
|
||||
}
|
||||
|
||||
if (leak_count) {
|
||||
char buffer[512];
|
||||
DN_Arena arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_Nil);
|
||||
DN_Str8 leak_size = DN_CVT_BytesStr8FromU64Auto(&arena, leaked_bytes);
|
||||
DN_LOG_WarningF("There were %I64u leaked allocations totalling %.*s", leak_count, DN_STR_FMT(leak_size));
|
||||
DN_Str8x32 leak_size = DN_ByteCountStr8x32(leaked_bytes);
|
||||
DN_LOG_WarningF("There were %I64u leaked allocations totalling %.*s", leak_count, DN_Str8PrintFmt(leak_size));
|
||||
}
|
||||
}
|
||||
#endif // DN_LEAK_TRACKING
|
||||
@ -396,8 +394,8 @@ DN_API DN_ProfilerZone DN_Profiler_BeginZone(DN_Profiler *profiler, DN_Str8 name
|
||||
// TODO: We need per-thread-local-storage profiler so that we can use these apis
|
||||
// across threads. For now, we let them overwrite each other but this is not tenable.
|
||||
#if 0
|
||||
if (DN_Str8_HasData(anchor->name) && anchor->name != name)
|
||||
DN_AssertF(name == anchor->name, "Potentially overwriting a zone by accident? Anchor is '%.*s', name is '%.*s'", DN_STR_FMT(anchor->name), DN_STR_FMT(name));
|
||||
if (DN_Str8HasData(anchor->name) && anchor->name != name)
|
||||
DN_AssertF(name == anchor->name, "Potentially overwriting a zone by accident? Anchor is '%.*s', name is '%.*s'", DN_Str8PrintFmt(anchor->name), DN_Str8PrintFmt(name));
|
||||
#endif
|
||||
|
||||
if (profiler->tsc == DN_ProfilerTSC_RDTSC)
|
||||
@ -455,7 +453,7 @@ DN_API void DN_Profiler_NewFrame(DN_Profiler *profiler)
|
||||
DN_Memset(next_anchors.data, 0, sizeof(*profiler->anchors) * next_anchors.count);
|
||||
|
||||
// NOTE: Start the frame's zone
|
||||
profiler->frame_zone = DN_Profiler_BeginZone(profiler, DN_STR8("Profiler Frame"), 0);
|
||||
profiler->frame_zone = DN_Profiler_BeginZone(profiler, DN_Str8Lit("Profiler Frame"), 0);
|
||||
}
|
||||
|
||||
DN_API void DN_Profiler_Dump(DN_Profiler *profiler)
|
||||
@ -474,13 +472,13 @@ DN_API void DN_Profiler_Dump(DN_Profiler *profiler)
|
||||
|
||||
DN_U64 tsc_exclusive = anchor->tsc_exclusive;
|
||||
DN_U64 tsc_inclusive = anchor->tsc_inclusive;
|
||||
DN_F64 tsc_exclusive_milliseconds = tsc_exclusive * 1000 / DN_CAST(DN_F64) profiler->tsc_frequency;
|
||||
DN_F64 tsc_exclusive_milliseconds = tsc_exclusive * 1000 / DN_Cast(DN_F64) profiler->tsc_frequency;
|
||||
if (tsc_exclusive == tsc_inclusive) {
|
||||
DN_OS_PrintOutLnF("%.*s[%u]: %.1fms", DN_STR_FMT(anchor->name), anchor->hit_count, tsc_exclusive_milliseconds);
|
||||
DN_OS_PrintOutLnF("%.*s[%u]: %.1fms", DN_Str8PrintFmt(anchor->name), anchor->hit_count, tsc_exclusive_milliseconds);
|
||||
} else {
|
||||
DN_F64 tsc_inclusive_milliseconds = tsc_inclusive * 1000 / DN_CAST(DN_F64) profiler->tsc_frequency;
|
||||
DN_F64 tsc_inclusive_milliseconds = tsc_inclusive * 1000 / DN_Cast(DN_F64) profiler->tsc_frequency;
|
||||
DN_OS_PrintOutLnF("%.*s[%u]: %.1f/%.1fms",
|
||||
DN_STR_FMT(anchor->name),
|
||||
DN_Str8PrintFmt(anchor->name),
|
||||
anchor->hit_count,
|
||||
tsc_exclusive_milliseconds,
|
||||
tsc_inclusive_milliseconds);
|
||||
@ -490,12 +488,12 @@ DN_API void DN_Profiler_Dump(DN_Profiler *profiler)
|
||||
|
||||
DN_API DN_F64 DN_Profiler_SecFromTSC(DN_Profiler *profiler, DN_U64 duration_tsc)
|
||||
{
|
||||
DN_F64 result = DN_CAST(DN_F64)duration_tsc / profiler->tsc_frequency;
|
||||
DN_F64 result = DN_Cast(DN_F64)duration_tsc / profiler->tsc_frequency;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_F64 DN_Profiler_MsFromTSC(DN_Profiler *profiler, DN_U64 duration_tsc)
|
||||
{
|
||||
DN_F64 result = DN_CAST(DN_F64)duration_tsc / profiler->tsc_frequency * 1000.0;
|
||||
DN_F64 result = DN_Cast(DN_F64)duration_tsc / profiler->tsc_frequency * 1000.0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ struct DN_Profiler
|
||||
};
|
||||
|
||||
#define DN_Profiler_ZoneLoop(prof, name, index) \
|
||||
DN_ProfilerZone DN_UniqueName(zone_) = DN_Profiler_BeginZone(prof, DN_STR8(name), index), DN_UniqueName(dummy_) = {}; \
|
||||
DN_ProfilerZone DN_UniqueName(zone_) = DN_Profiler_BeginZone(prof, DN_Str8Lit(name), index), DN_UniqueName(dummy_) = {}; \
|
||||
DN_UniqueName(dummy_).begin_tsc == 0; \
|
||||
DN_Profiler_EndZone(prof, DN_UniqueName(zone_)), DN_UniqueName(dummy_).begin_tsc = 1
|
||||
|
||||
@ -84,7 +84,7 @@ struct DN_Profiler
|
||||
|
||||
DN_API DN_Profiler DN_Profiler_Init (DN_ProfilerAnchor *anchors, DN_USize count, DN_USize anchors_per_frame, DN_ProfilerTSC tsc, DN_U64 tsc_frequency);
|
||||
DN_API DN_ProfilerZone DN_Profiler_BeginZone (DN_Profiler *profiler, DN_Str8 name, DN_U16 anchor_index);
|
||||
#define DN_Profiler_BeginZoneAuto(prof, name) DN_Profiler_BeginZone(prof, DN_STR8(name), __COUNTER__ + 1)
|
||||
#define DN_Profiler_BeginZoneAuto(prof, name) DN_Profiler_BeginZone(prof, DN_Str8Lit(name), __COUNTER__ + 1)
|
||||
DN_API void DN_Profiler_EndZone (DN_Profiler *profiler, DN_ProfilerZone zone);
|
||||
DN_API DN_USize DN_Profiler_FrameCount (DN_Profiler const *profiler);
|
||||
DN_API DN_ProfilerAnchorArray DN_Profiler_FrameAnchorsFromIndex (DN_Profiler *profiler, DN_USize frame_index);
|
||||
|
||||
@ -39,8 +39,8 @@ void DN_Docs_Demo()
|
||||
DN_Core_Init(&core, DN_CoreOnInit_Nil);
|
||||
#endif
|
||||
|
||||
// NOTE: DN_AtomicSetValue64 /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_AtomicSetValue32 /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_AtomicSetValue64
|
||||
// NOTE: DN_AtomicSetValue32
|
||||
// Atomically set the value into the target using an atomic compare and swap
|
||||
// idiom. The return value of the function is the value that was last stored
|
||||
// in the target.
|
||||
@ -54,15 +54,24 @@ void DN_Docs_Demo()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_CVT_HexFromBytes ////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_HexFromBytes
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
unsigned char bytes[2] = {0xFA, 0xCE};
|
||||
DN_Str8 hex = DN_CVT_HexFromBytes(tmem.arena, bytes, sizeof(bytes));
|
||||
DN_Assert(hex == DN_STR8("face")); // NOTE: Guaranteed to be null-terminated
|
||||
DN_Str8 hex = DN_HexFromBytesPtrArena(bytes, sizeof(bytes), tmem.arena);
|
||||
DN_Assert(DN_Str8Eq(hex, DN_Str8Lit("face"))); // NOTE: Guaranteed to be null-terminated
|
||||
}
|
||||
|
||||
// NOTE: DN_Check /////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_BytesFromHex
|
||||
{
|
||||
unsigned char bytes[2];
|
||||
DN_USize bytes_written = DN_BytesFromHexStr8(DN_Str8Lit("0xFACE"), bytes, sizeof(bytes));
|
||||
DN_Assert(bytes_written == 2);
|
||||
DN_Assert(bytes[0] == 0xFA);
|
||||
DN_Assert(bytes[1] == 0xCE);
|
||||
}
|
||||
|
||||
// NOTE: DN_Check
|
||||
//
|
||||
// Check the expression trapping in debug, whilst in release- trapping is
|
||||
// removed and the expression is evaluated as if it were a normal 'if' branch.
|
||||
@ -76,7 +85,7 @@ void DN_Docs_Demo()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_CPUID /////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_CPUID
|
||||
// Execute the 'CPUID' instruction which lets you query the capabilities of
|
||||
// the current CPU.
|
||||
|
||||
@ -94,7 +103,7 @@ void DN_Docs_Demo()
|
||||
// On scope exit, DN_DEFER object executes and assigns x = 3
|
||||
}
|
||||
|
||||
// NOTE: DN_DSMap /////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap
|
||||
//
|
||||
// A hash table configured using the presets recommended by Demitri Spanos
|
||||
// from the Handmade Network (HMN),
|
||||
@ -135,8 +144,8 @@ void DN_Docs_Demo()
|
||||
// buffer, this buffer must be valid throughout the lifetime of the hash
|
||||
// table!
|
||||
{
|
||||
// NOTE: DN_DSMap_Init //////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Deinit //////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Init
|
||||
// NOTE: DN_DSMap_Deinit
|
||||
//
|
||||
// Initialise a hash table where the table size *must* be a
|
||||
// power-of-two, otherwise an assert will be triggered. If
|
||||
@ -154,16 +163,16 @@ void DN_Docs_Demo()
|
||||
//
|
||||
// A 'Deinit' of the map will similarly deallocate the passed in arena (as
|
||||
// the map takes ownership of the arena).
|
||||
DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
DN_DSMap<int> map = DN_DSMap_Init<int>(&arena, /*size*/ 1024, DN_DSMapFlags_Nil); // Size must be PoT!
|
||||
DN_Assert(DN_DSMap_IsValid(&map)); // Valid if no initialisation failure (e.g. mem alloc failure)
|
||||
|
||||
// NOTE: DN_DSMap_KeyCStringLit ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_KeyU64 ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_KeyU64NoHash ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_KeyBuffer ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_KeyStr8 ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_KeyStr8Copy ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_KeyCStringLit
|
||||
// NOTE: DN_DSMap_KeyU64
|
||||
// NOTE: DN_DSMap_KeyU64NoHash
|
||||
// NOTE: DN_DSMap_KeyBuffer
|
||||
// NOTE: DN_DSMap_KeyStr8
|
||||
// NOTE: DN_DSMap_KeyStr8Copy
|
||||
// Create a hash-table key where:
|
||||
//
|
||||
// KeyCStringLit: Uses a Hash(cstring literal)
|
||||
@ -184,11 +193,11 @@ void DN_Docs_Demo()
|
||||
// already sufficiently uniformly distributed already (e.g. using 8
|
||||
// bytes taken from a SHA256 hash as the key) and the first 4 bytes
|
||||
// will be used verbatim.
|
||||
DN_DSMapKey key = DN_DSMap_KeyStr8(&map, DN_STR8("Sample Key"));
|
||||
DN_DSMapKey key = DN_DSMap_KeyStr8(&map, DN_Str8Lit("Sample Key"));
|
||||
|
||||
// NOTE: DN_DSMap_Find ////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Make ////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Set ////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Find
|
||||
// NOTE: DN_DSMap_Make
|
||||
// NOTE: DN_DSMap_Set
|
||||
//
|
||||
// Query or commit key-value pair to the table, where:
|
||||
//
|
||||
@ -219,10 +228,10 @@ void DN_Docs_Demo()
|
||||
int *it_value = &it->value;
|
||||
DN_Assert(*it_value == 0xCAFE);
|
||||
|
||||
DN_Assert(DN_Str8_Init(it_key.buffer_data, it_key.buffer_size) == DN_STR8("Sample Key"));
|
||||
DN_Assert(DN_Str8Eq(DN_Str8FromPtr(it_key.buffer_data, it_key.buffer_size), DN_Str8Lit("Sample Key")));
|
||||
}
|
||||
|
||||
// NOTE: DN_DSMap_Erase ///////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Erase
|
||||
//
|
||||
// Remove the key-value pair from the table. If by erasing the key-value
|
||||
// pair from the table puts the table under 25% load, the table will be
|
||||
@ -234,26 +243,26 @@ void DN_Docs_Demo()
|
||||
DN_Assert(map.occupied == 1); // Sentinel element
|
||||
}
|
||||
|
||||
DN_DSMap_Deinit(&map, DN_ZeroMem_Yes); // Deallocates the 'arena' for us!
|
||||
DN_DSMap_Deinit(&map, DN_ZMem_Yes); // Deallocates the 'arena' for us!
|
||||
}
|
||||
|
||||
// NOTE: DN_DSMap_Hash ////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Hash
|
||||
//
|
||||
// Hash the input key using the custom hash function if it's set on the map,
|
||||
// otherwise uses the default hashing function (32bit Murmur3).
|
||||
|
||||
// NOTE: DN_DSMap_HashToSlotIndex /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_HashToSlotIndex
|
||||
//
|
||||
// Calculate the index into the map's 'slots' array from the given hash.
|
||||
|
||||
// NOTE: DN_DSMap_Resize //////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_DSMap_Resize
|
||||
//
|
||||
// Resize the table and move all elements to the new map, note that the new
|
||||
// size must be a power of two. This function wil fail on memory allocation
|
||||
// failure, or the requested size is smaller than the current number of
|
||||
// elements in the map to resize.
|
||||
|
||||
// NOTE: DN_OSErrSink /////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OSErrSink
|
||||
//
|
||||
// Error sinks are a way of accumulating errors from API calls related or
|
||||
// unrelated into 1 unified error handling pattern. The implemenation of a
|
||||
@ -290,8 +299,8 @@ void DN_Docs_Demo()
|
||||
// produce errors take in the error sink as a parameter.
|
||||
if (0) {
|
||||
DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_STR8("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error);
|
||||
DN_OS_FileWrite(&file, DN_STR8("abc"), error);
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error);
|
||||
DN_OS_FileWrite(&file, DN_Str8Lit("abc"), error);
|
||||
DN_OS_FileClose(&file);
|
||||
if (DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to file")) {
|
||||
// Do error handling!
|
||||
@ -314,15 +323,15 @@ void DN_Docs_Demo()
|
||||
|
||||
if (0) {
|
||||
DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_STR8("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error);
|
||||
DN_OS_FileWrite(&file, DN_STR8("abc"), error);
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error);
|
||||
DN_OS_FileWrite(&file, DN_Str8Lit("abc"), error);
|
||||
DN_OS_FileClose(&file);
|
||||
|
||||
{
|
||||
// NOTE: My error sinks are thread-local, so the returned 'error' is
|
||||
// the same as the 'error' value above.
|
||||
DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_OS_FileWriteAll(DN_STR8("/path/to/another/file"), DN_STR8("123"), error);
|
||||
DN_OS_FileWriteAll(DN_Str8Lit("/path/to/another/file"), DN_Str8Lit("123"), error);
|
||||
DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to another file");
|
||||
}
|
||||
|
||||
@ -331,16 +340,7 @@ void DN_Docs_Demo()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_CVT_BytesFromHex ////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
unsigned char bytes[2];
|
||||
DN_USize bytes_written = DN_CVT_BytesFromHexPtr(DN_STR8("0xFACE"), bytes, sizeof(bytes));
|
||||
DN_Assert(bytes_written == 2);
|
||||
DN_Assert(bytes[0] == 0xFA);
|
||||
DN_Assert(bytes[1] == 0xCE);
|
||||
}
|
||||
|
||||
// NOTE: DN_JSONBuilder_Build /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_Build
|
||||
//
|
||||
// Convert the internal JSON buffer in the builder into a string.
|
||||
|
||||
@ -366,14 +366,14 @@ void DN_Docs_Demo()
|
||||
// the following '"<key>": <value>' (e.g. useful for emitting the 'null'
|
||||
// value)
|
||||
|
||||
// NOTE: DN_JSONBuilder_U64 /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_U64Named /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_I64 /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_I64Named /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_F64 /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_F64Named /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_Bool /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_BoolNamed /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder_U64
|
||||
// NOTE: DN_JSONBuilder_U64Named
|
||||
// NOTE: DN_JSONBuilder_I64
|
||||
// NOTE: DN_JSONBuilder_I64Named
|
||||
// NOTE: DN_JSONBuilder_F64
|
||||
// NOTE: DN_JSONBuilder_F64Named
|
||||
// NOTE: DN_JSONBuilder_Bool
|
||||
// NOTE: DN_JSONBuilder_BoolNamed
|
||||
//
|
||||
// Add the named JSON data type as a key-value object. The named variants
|
||||
// generates internally the key-value pair, e.g.
|
||||
@ -382,7 +382,7 @@ void DN_Docs_Demo()
|
||||
//
|
||||
// And the non-named version emit just the 'value' portion
|
||||
|
||||
// NOTE: DN_List_Iterate //////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_List_Iterate
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_List<int> list = DN_List_Init<int>(/*chunk_size*/ 128);
|
||||
@ -392,13 +392,13 @@ void DN_Docs_Demo()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_LOGProc ///////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_LOGProc
|
||||
//
|
||||
// Function prototype of the logging interface exposed by this library. Logs
|
||||
// emitted using the DN_LOG_* family of functions are routed through this
|
||||
// routine.
|
||||
|
||||
// NOTE: DN_FNV1A /////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_FNV1A
|
||||
#if 0
|
||||
{
|
||||
// Using the default hash as defined by DN_FNV1A32_SEED and
|
||||
@ -422,15 +422,7 @@ void DN_Docs_Demo()
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE: DN_FmtBuffer3DotTruncate //////////////////////////////////////////////////////////////
|
||||
{
|
||||
char buffer[8] = {};
|
||||
int buffer_chars_written = DN_CVT_FmtBuffer3DotTruncate(buffer, sizeof(buffer), "This string is longer than %d characters", DN_CAST(int)(sizeof(buffer) - 1));
|
||||
if (0) // Prints "This ..." which is exactly 8 characters long
|
||||
printf("%.*s", buffer_chars_written, buffer);
|
||||
}
|
||||
|
||||
// NOTE: DN_MurmurHash3 ///////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_MurmurHash3
|
||||
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author (Austin Appleby) hereby disclaims copyright to this source
|
||||
// code.
|
||||
@ -448,11 +440,11 @@ void DN_Docs_Demo()
|
||||
(void)now;
|
||||
}
|
||||
|
||||
// NOTE: DN_OS_DirIterate /////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OS_DirIterate
|
||||
//
|
||||
// Iterate the files within the passed in folder
|
||||
for (DN_OSDirIterator it = {}; DN_OS_PathIterateDir(DN_STR8("."), &it);) {
|
||||
// printf("%.*s\n", DN_STR_FMT(it.file_name));
|
||||
for (DN_OSDirIterator it = {}; DN_OS_PathIterateDir(DN_Str8Lit("."), &it);) {
|
||||
// printf("%.*s\n", DN_Str8PrintFmt(it.file_name));
|
||||
}
|
||||
|
||||
// NOTE: DN_OS_FileDelete
|
||||
@ -473,11 +465,11 @@ void DN_Docs_Demo()
|
||||
if (0) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
|
||||
DN_OS_FileWriteAllSafe(/*path*/ DN_STR8("C:/Home/my.txt"), /*buffer*/ DN_STR8("Hello world"), error);
|
||||
DN_OS_FileWriteAllSafe(/*path*/ DN_Str8Lit("C:/Home/my.txt"), /*buffer*/ DN_Str8Lit("Hello world"), error);
|
||||
DN_OS_ErrSinkEndAndLogErrorF(error, "");
|
||||
}
|
||||
|
||||
// NOTE: DN_OS_EstimateTSCPerSecond ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OS_EstimateTSCPerSecond
|
||||
//
|
||||
// Estimate how many timestamp count's (TSC) there are per second. TSC
|
||||
// is evaluated by calling __rdtsc() or the equivalent on the platform. This
|
||||
@ -491,18 +483,18 @@ void DN_Docs_Demo()
|
||||
// This may return 0 if querying the CPU timestamp counter is not supported
|
||||
// on the platform (e.g. __rdtsc() or __builtin_readcyclecounter() returns 0).
|
||||
|
||||
// NOTE: DN_OS_EXEDir /////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OS_EXEDir
|
||||
//
|
||||
// Retrieve the executable directory without the trailing '/' or ('\' for
|
||||
// windows). If this fails an empty string is returned.
|
||||
|
||||
// NOTE: DN_OS_PerfCounterFrequency ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OS_PerfCounterFrequency
|
||||
//
|
||||
// Get the number of ticks in the performance counter per second for the
|
||||
// operating system you're running on. This value can be used to calculate
|
||||
// duration from OS performance counter ticks.
|
||||
|
||||
// NOTE: DN_OS_Path* //////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OS_Path*
|
||||
// Construct paths ensuring the native OS path separators are used in the
|
||||
// string. In 99% of cases you can use 'PathConvertF' which converts the
|
||||
// given path in one shot ensuring native path separators in the string.
|
||||
@ -531,12 +523,12 @@ void DN_Docs_Demo()
|
||||
// path: path/to/your/desired/folder
|
||||
// popped_path: path/to/your/desired
|
||||
|
||||
// NOTE: DN_OS_SecureRNGBytes /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OS_SecureRNGBytes
|
||||
//
|
||||
// Generate cryptographically secure bytes
|
||||
|
||||
#if 0
|
||||
// NOTE: DN_PCG32 /////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_PCG32
|
||||
//
|
||||
// Random number generator of the PCG family. Implementation taken from
|
||||
// Martins Mmozeiko from Handmade Network.
|
||||
@ -544,20 +536,20 @@ void DN_Docs_Demo()
|
||||
{
|
||||
DN_PCG32 rng = DN_PCG32_Init(0xb917'a66c'1d9b'3bd8);
|
||||
|
||||
// NOTE: DN_PCG32_Range ///////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_PCG32_Range
|
||||
//
|
||||
// Generate a value in the [low, high) interval
|
||||
uint32_t u32_value = DN_PCG32_Range(&rng, 32, 64);
|
||||
DN_Assert(u32_value >= 32 && u32_value < 64);
|
||||
|
||||
// NOTE: DN_PCG32_NextF32 /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_PCG32_NextF64 /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_PCG32_NextF32
|
||||
// NOTE: DN_PCG32_NextF64
|
||||
//
|
||||
// Generate a float/double in the [0, 1) interval
|
||||
DN_F64 f64_value = DN_PCG32_NextF64(&rng);
|
||||
DN_Assert(f64_value >= 0.f && f64_value < 1.f);
|
||||
|
||||
// NOTE: DN_PCG32_Advance /////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_PCG32_Advance
|
||||
//
|
||||
// Step the random number generator by 'delta' steps
|
||||
DN_PCG32_Advance(&rng, /*delta*/ 5);
|
||||
@ -566,7 +558,7 @@ void DN_Docs_Demo()
|
||||
|
||||
#if 0
|
||||
#if !defined(DN_NO_PROFILER)
|
||||
// NOTE: DN_Profiler /////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Profiler
|
||||
//
|
||||
// A profiler based off Casey Muratori's Computer Enhance course, Performance
|
||||
// Aware Programming. This profiler measures function elapsed time using the
|
||||
@ -587,7 +579,7 @@ void DN_Docs_Demo()
|
||||
|
||||
DN_ProfilerZone profiler_zone_main_update = DN_Profiler_BeginZone(Zone_MainLoop);
|
||||
|
||||
// NOTE: DN_Profiler_AnchorBuffer /////////////////////////////////////////////////////
|
||||
// NOTE: DN_Profiler_AnchorBuffer
|
||||
//
|
||||
// Retrieve the requested buffer from the profiler for
|
||||
// writing/reading profiling metrics. Pass in the enum to specify
|
||||
@ -601,7 +593,7 @@ void DN_Docs_Demo()
|
||||
// the front buffer which contain the metrics that you can visualise
|
||||
// regarding the most profiling metrics recorded.
|
||||
|
||||
// NOTE: DN_Profiler_ReadBuffer ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Profiler_ReadBuffer
|
||||
//
|
||||
// Retrieve the buffer of anchors of which there are
|
||||
// `DN_PROFILER_ANCHOR_BUFFER_SIZE` anchors from the most recent run
|
||||
@ -610,19 +602,19 @@ void DN_Docs_Demo()
|
||||
DN_ProfilerAnchor *read_anchors = DN_Profiler_ReadBuffer();
|
||||
for (DN_USize index = 0; index < DN_PROFILER_ANCHOR_BUFFER_SIZE; index++) {
|
||||
DN_ProfilerAnchor *anchor = read_anchors + index;
|
||||
if (DN_Str8_HasData(anchor->name)) {
|
||||
if (DN_Str8HasData(anchor->name)) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_Profiler_WriteBuffer //////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Profiler_WriteBuffer
|
||||
//
|
||||
// Same as `ReadBuffer` however we return the buffer that the profiler
|
||||
// is currently writing anchors into.
|
||||
DN_ProfilerAnchor *write_anchors = DN_Profiler_WriteBuffer();
|
||||
for (DN_USize index = 0; index < DN_PROFILER_ANCHOR_BUFFER_SIZE; index++) {
|
||||
DN_ProfilerAnchor *anchor = write_anchors + index;
|
||||
if (DN_Str8_HasData(anchor->name)) {
|
||||
if (DN_Str8HasData(anchor->name)) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
@ -634,7 +626,7 @@ void DN_Docs_Demo()
|
||||
#endif // !defined(DN_NO_PROFILER)
|
||||
#endif
|
||||
|
||||
// NOTE: DN_Raycast_LineIntersectV2 ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Raycast_LineIntersectV2
|
||||
// Calculate the intersection point of 2 rays returning a `t` value
|
||||
// which is how much along the direction of the 'ray' did the intersection
|
||||
// occur.
|
||||
@ -642,14 +634,14 @@ void DN_Docs_Demo()
|
||||
// The arguments passed in do not need to be normalised for the function to
|
||||
// work.
|
||||
|
||||
// NOTE: DN_Safe_* ////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Safe_*
|
||||
//
|
||||
// Performs the arithmetic operation and uses DN_Check on the operation to
|
||||
// check if it overflows. If it overflows the MAX value of the integer is
|
||||
// returned in add and multiply operations, and, the minimum is returned in
|
||||
// subtraction and division.
|
||||
|
||||
// NOTE: DN_SaturateCast* ////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_SaturateCast*
|
||||
//
|
||||
// Truncate the passed in value to the return type clamping the resulting
|
||||
// value to the max value of the desired data type. It DN_Check's the
|
||||
@ -696,7 +688,7 @@ void DN_Docs_Demo()
|
||||
// Int -> U32: 0 or UINT32_MAX
|
||||
// Int -> U64: 0 or UINT64_MAX
|
||||
|
||||
// NOTE: DN_StackTrace ////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_StackTrace
|
||||
// Emit stack traces at the calling site that these functions are invoked
|
||||
// from.
|
||||
//
|
||||
@ -715,7 +707,7 @@ void DN_Docs_Demo()
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
|
||||
// NOTE: DN_StackTrace_Walk ///////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_StackTrace_Walk
|
||||
//
|
||||
// Generate a stack trace as a series of addresses to the base of the
|
||||
// functions on the call-stack at the current instruction pointer. The
|
||||
@ -725,7 +717,7 @@ void DN_Docs_Demo()
|
||||
|
||||
// Loop over the addresses produced in the stack trace
|
||||
for (DN_StackTraceWalkResultIterator it = {}; DN_StackTrace_WalkResultIterate(&it, &walk);) {
|
||||
// NOTE: DN_StackTrace_RawFrameToFrame ////////////////////////////////////////////////
|
||||
// NOTE: DN_StackTrace_RawFrameToFrame
|
||||
//
|
||||
// Converts the base address into a human readable stack trace
|
||||
// entry (e.g. address, line number, file and function name).
|
||||
@ -733,7 +725,7 @@ void DN_Docs_Demo()
|
||||
|
||||
// You may then print out the frame like so
|
||||
if (0)
|
||||
printf("%.*s(%" PRIu64 "): %.*s\n", DN_STR_FMT(frame.file_name), frame.line_number, DN_STR_FMT(frame.function_name));
|
||||
printf("%.*s(%" PRIu64 "): %.*s\n", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name));
|
||||
}
|
||||
|
||||
// If you load new shared-libraries into the address space it maybe
|
||||
@ -741,7 +733,7 @@ void DN_Docs_Demo()
|
||||
// to resolve the new addresses.
|
||||
DN_StackTrace_ReloadSymbols();
|
||||
|
||||
// NOTE: DN_StackTrace_GetFrames //////////////////////////////////////////////////////////
|
||||
// NOTE: DN_StackTrace_GetFrames
|
||||
//
|
||||
// Helper function to create a stack trace and automatically convert the
|
||||
// raw frames into human readable frames. This function effectively
|
||||
@ -750,7 +742,7 @@ void DN_Docs_Demo()
|
||||
(void)frames;
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_Alloc ////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8FromArena
|
||||
//
|
||||
// Allocates a string with the requested 'size'. An additional byte is
|
||||
// always requested from the allocator to null-terminate the buffer. This
|
||||
@ -760,33 +752,33 @@ void DN_Docs_Demo()
|
||||
// additional null-terminating byte.
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8_Alloc(tmem.arena, /*size*/ 1, DN_ZeroMem_Yes);
|
||||
DN_Str8 string = DN_Str8FromArena(tmem.arena, /*size*/ 1, DN_ZMem_Yes);
|
||||
DN_Assert(string.size == 1);
|
||||
DN_Assert(string.data[string.size] == 0); // It is null-terminated!
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_BSplit //////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8BSplit
|
||||
//
|
||||
// Splits a string into 2 substrings occuring prior and after the first
|
||||
// occurence of the delimiter. Neither strings include the matched
|
||||
// delimiter. If no delimiter is found, the 'rhs' of the split will be
|
||||
// empty.
|
||||
{
|
||||
DN_Str8BSplitResult dot_split = DN_Str8_BSplit(/*string*/ DN_STR8("abc.def.ghi"), /*delimiter*/ DN_STR8("."));
|
||||
DN_Str8BSplitResult slash_split = DN_Str8_BSplit(/*string*/ DN_STR8("abc.def.ghi"), /*delimiter*/ DN_STR8("/"));
|
||||
DN_Assert(dot_split.lhs == DN_STR8("abc") && dot_split.rhs == DN_STR8("def.ghi"));
|
||||
DN_Assert(slash_split.lhs == DN_STR8("abc.def.ghi") && slash_split.rhs == DN_STR8(""));
|
||||
DN_Str8BSplitResult dot_split = DN_Str8BSplit(/*string*/ DN_Str8Lit("abc.def.ghi"), /*delimiter*/ DN_Str8Lit("."));
|
||||
DN_Str8BSplitResult slash_split = DN_Str8BSplit(/*string*/ DN_Str8Lit("abc.def.ghi"), /*delimiter*/ DN_Str8Lit("/"));
|
||||
DN_Assert(DN_Str8Eq(dot_split.lhs, DN_Str8Lit("abc")) && DN_Str8Eq(dot_split.rhs, DN_Str8Lit("def.ghi")));
|
||||
DN_Assert(DN_Str8Eq(slash_split.lhs, DN_Str8Lit("abc.def.ghi")) && DN_Str8Eq(slash_split.rhs, DN_Str8Lit("")));
|
||||
|
||||
// Loop that walks the string and produces ("abc", "def", "ghi")
|
||||
for (DN_Str8 it = DN_STR8("abc.def.ghi"); it.size;) {
|
||||
DN_Str8BSplitResult split = DN_Str8_BSplit(it, DN_STR8("."));
|
||||
for (DN_Str8 it = DN_Str8Lit("abc.def.ghi"); it.size;) {
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(it, DN_Str8Lit("."));
|
||||
DN_Str8 chunk = split.lhs; // "abc", "def", ...
|
||||
it = split.rhs;
|
||||
(void)chunk;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_FileNameFromPath /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8FileNameFromPath
|
||||
//
|
||||
// Takes a slice to the file name from a file path. The file name is
|
||||
// evaluated by searching from the end of the string backwards to the first
|
||||
@ -795,41 +787,41 @@ void DN_Docs_Demo()
|
||||
// if there were any.
|
||||
{
|
||||
{
|
||||
DN_Str8 string = DN_Str8_FileNameFromPath(DN_STR8("C:/Folder/item.txt"));
|
||||
DN_Assert(string == DN_STR8("item.txt"));
|
||||
DN_Str8 string = DN_Str8FileNameFromPath(DN_Str8Lit("C:/Folder/item.txt"));
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("item.txt")));
|
||||
}
|
||||
{
|
||||
// TODO(doyle): Intuitively this seems incorrect. Empty string instead?
|
||||
DN_Str8 string = DN_Str8_FileNameFromPath(DN_STR8("C:/Folder/"));
|
||||
DN_Assert(string == DN_STR8("C:/Folder"));
|
||||
DN_Str8 string = DN_Str8FileNameFromPath(DN_Str8Lit("C:/Folder/"));
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("C:/Folder")));
|
||||
}
|
||||
{
|
||||
DN_Str8 string = DN_Str8_FileNameFromPath(DN_STR8("C:/Folder"));
|
||||
DN_Assert(string == DN_STR8("Folder"));
|
||||
DN_Str8 string = DN_Str8FileNameFromPath(DN_Str8Lit("C:/Folder"));
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("Folder")));
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_FilePathNoExtension //////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8FilePathNoExtension
|
||||
//
|
||||
// This function preserves the original string if no extension was found.
|
||||
// An extension is defined as the substring after the last '.' encountered
|
||||
// in the string.
|
||||
{
|
||||
DN_Str8 string = DN_Str8_FilePathNoExtension(DN_STR8("C:/Folder/item.txt.bak"));
|
||||
DN_Assert(string == DN_STR8("C:/Folder/item.txt"));
|
||||
DN_Str8 string = DN_Str8FilePathNoExtension(DN_Str8Lit("C:/Folder/item.txt.bak"));
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("C:/Folder/item.txt")));
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_FileNameNoExtension //////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8FileNameNoExtension
|
||||
//
|
||||
// This function is the same as calling 'FileNameFromPath' followed by
|
||||
// 'FilePathNoExtension'
|
||||
{
|
||||
DN_Str8 string = DN_Str8_FileNameNoExtension(DN_STR8("C:/Folder/item.txt.bak"));
|
||||
DN_Assert(string == DN_STR8("item.txt"));
|
||||
DN_Str8 string = DN_Str8FileNameNoExtension(DN_Str8Lit("C:/Folder/item.txt.bak"));
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("item.txt")));
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_Replace ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8_ReplaceInsensitive ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Replace
|
||||
// NOTE: DN_Str8ReplaceInsensitive
|
||||
//
|
||||
// Replace any matching substring 'find' with 'replace' in the passed in
|
||||
// 'string'. The 'start_index' may be specified to offset which index the
|
||||
@ -840,16 +832,16 @@ void DN_Docs_Demo()
|
||||
// were done or not.
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8_Replace(/*string*/ DN_STR8("Foo Foo Bar"),
|
||||
/*find*/ DN_STR8("Foo"),
|
||||
/*replace*/ DN_STR8("Moo"),
|
||||
DN_Str8 string = DN_Str8Replace(/*string*/ DN_Str8Lit("Foo Foo Bar"),
|
||||
/*find*/ DN_Str8Lit("Foo"),
|
||||
/*replace*/ DN_Str8Lit("Moo"),
|
||||
/*start_index*/ 1,
|
||||
/*arena*/ tmem.arena,
|
||||
/*eq_case*/ DN_Str8EqCase_Sensitive);
|
||||
DN_Assert(string == DN_STR8("Foo Moo Bar"));
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("Foo Moo Bar")));
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_Segment //////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Segment
|
||||
//
|
||||
// Add a delimiting 'segment_char' every 'segment_size' number of characters
|
||||
// in the string.
|
||||
@ -858,38 +850,42 @@ void DN_Docs_Demo()
|
||||
// of the string.
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8_Segment(tmem.arena, /*string*/ DN_STR8("123456789"), /*segment_size*/ 3, /*segment_char*/ ',');
|
||||
DN_Assert(string == DN_STR8("123,456,789"));
|
||||
DN_Str8 string = DN_Str8Segment(tmem.arena, /*string*/ DN_Str8Lit("123456789"), /*segment_size*/ 3, /*segment_char*/ ',');
|
||||
DN_Assert(DN_Str8Eq(string, DN_Str8Lit("123,456,789")));
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_Split ////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Split
|
||||
{
|
||||
// Splits the string at each delimiter into substrings occuring prior and
|
||||
// after until the next delimiter.
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
{
|
||||
DN_Slice<DN_Str8> splits = DN_Str8_SplitAlloc(/*arena*/ tmem.arena,
|
||||
/*string*/ DN_STR8("192.168.8.1"),
|
||||
/*delimiter*/ DN_STR8("."),
|
||||
DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ tmem.arena,
|
||||
/*string*/ DN_Str8Lit("192.168.8.1"),
|
||||
/*delimiter*/ DN_Str8Lit("."),
|
||||
/*mode*/ DN_Str8SplitIncludeEmptyStrings_No);
|
||||
DN_Assert(splits.size == 4);
|
||||
DN_Assert(splits.data[0] == DN_STR8("192") && splits.data[1] == DN_STR8("168") && splits.data[2] == DN_STR8("8") && splits.data[3] == DN_STR8("1"));
|
||||
DN_Assert(splits.count == 4);
|
||||
DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("192")) &&
|
||||
DN_Str8Eq(splits.data[1], DN_Str8Lit("168")) &&
|
||||
DN_Str8Eq(splits.data[2], DN_Str8Lit("8")) &&
|
||||
DN_Str8Eq(splits.data[3], DN_Str8Lit("1")));
|
||||
}
|
||||
|
||||
// You can include empty strings that occur when splitting by setting
|
||||
// the split mode to include empty strings.
|
||||
{
|
||||
DN_Slice<DN_Str8> splits = DN_Str8_SplitAlloc(/*arena*/ tmem.arena,
|
||||
/*string*/ DN_STR8("a--b"),
|
||||
/*delimiter*/ DN_STR8("-"),
|
||||
DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ tmem.arena,
|
||||
/*string*/ DN_Str8Lit("a--b"),
|
||||
/*delimiter*/ DN_Str8Lit("-"),
|
||||
/*mode*/ DN_Str8SplitIncludeEmptyStrings_Yes);
|
||||
DN_Assert(splits.size == 3);
|
||||
DN_Assert(splits.data[0] == DN_STR8("a") && splits.data[1] == DN_STR8("") && splits.data[2] == DN_STR8("b"));
|
||||
DN_Assert(splits.count == 3);
|
||||
DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("a")) &&
|
||||
DN_Str8Eq(splits.data[1], DN_Str8Lit("")) &&
|
||||
DN_Str8Eq(splits.data[2], DN_Str8Lit("b")));
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_ToI64 ////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8_ToU64 ////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_I64FromStr8, DN_U64FromStr8
|
||||
//
|
||||
// Convert a number represented as a string to a signed 64 bit number.
|
||||
//
|
||||
@ -909,31 +905,31 @@ void DN_Docs_Demo()
|
||||
// 'ToI64' either '+' or '-' prefix is permitted
|
||||
{
|
||||
{
|
||||
DN_Str8ToI64Result result = DN_Str8_ToI64(DN_STR8("-1,234"), /*separator*/ ',');
|
||||
DN_I64FromResult result = DN_I64FromStr8(DN_Str8Lit("-1,234"), /*separator*/ ',');
|
||||
DN_Assert(result.success && result.value == -1234);
|
||||
}
|
||||
{
|
||||
DN_Str8ToI64Result result = DN_Str8_ToI64(DN_STR8("-1,234"), /*separator*/ 0);
|
||||
DN_I64FromResult result = DN_I64FromStr8(DN_Str8Lit("-1,234"), /*separator*/ 0);
|
||||
DN_Assert(!result.success && result.value == 1); // 1 because it's a greedy conversion
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_TrimByteOrderMark ////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8TrimByteOrderMark
|
||||
//
|
||||
// Removes a leading UTF8, UTF16 BE/LE, UTF32 BE/LE byte order mark from the
|
||||
// string if it's present.
|
||||
|
||||
// NOTE: DN_STR_FMT ///////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8PrintFmt
|
||||
//
|
||||
// Unpacks a string struct that has the fields {.data, .size} for printing a
|
||||
// pointer and length style string using the printf format specifier "%.*s"
|
||||
//
|
||||
// printf("%.*s\n", DN_STR_FMT(DN_STR8("Hello world")));
|
||||
// printf("%.*s\n", DN_Str8PrintFmt(DN_Str8Lit("Hello world")));
|
||||
|
||||
// NOTE: DN_Str8Builder_AppendF ////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Builder_AppendFV ////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Builder_AppendRef ////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Builder_AppendCopy ////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8BuilderAppendF
|
||||
// NOTE: DN_Str8BuilderAppendFV
|
||||
// NOTE: DN_Str8BuilderAppendRef
|
||||
// NOTE: DN_Str8BuilderAppendCopy
|
||||
//
|
||||
// - Appends a string to the string builder as follows
|
||||
//
|
||||
@ -941,8 +937,8 @@ void DN_Docs_Demo()
|
||||
// AppendCopy: Stores the string slice by copy (with builder's arena)
|
||||
// AppendF/V: Constructs a format string and calls 'AppendRef'
|
||||
|
||||
// NOTE: DN_Str8Builder_Build ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Builder_BuildCRT ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8BuilderBuild
|
||||
// NOTE: DN_Str8BuilderBuildCRT
|
||||
//
|
||||
// Constructs the final string by merging all the appended strings into
|
||||
// one merged string.
|
||||
@ -950,11 +946,11 @@ void DN_Docs_Demo()
|
||||
// The CRT variant calls into 'malloc' and the string *must* be released
|
||||
// using 'free'.
|
||||
|
||||
// NOTE: DN_Str8Builder_BuildSlice ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8BuilderBuildSlice
|
||||
//
|
||||
// Constructs the final string into an array of strings (e.g. a slice)
|
||||
|
||||
// NOTE: DN_TicketMutex ///////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_TicketMutex
|
||||
//
|
||||
// A mutex implemented using an atomic compare and swap on tickets handed
|
||||
// out for each critical section.
|
||||
@ -974,13 +970,13 @@ void DN_Docs_Demo()
|
||||
DN_TicketMutex_Begin(&mutex); // Simple procedural mutual exclusion lock
|
||||
DN_TicketMutex_End(&mutex);
|
||||
|
||||
// NOTE: DN_TicketMutex_MakeTicket ////////////////////////////////////////////////////////
|
||||
// NOTE: DN_TicketMutex_MakeTicket
|
||||
//
|
||||
// Request the next available ticket for locking from the mutex.
|
||||
DN_UInt ticket = DN_TicketMutex_MakeTicket(&mutex);
|
||||
|
||||
if (DN_TicketMutex_CanLock(&mutex, ticket)) {
|
||||
// NOTE: DN_TicketMutex_BeginTicket ///////////////////////////////////////////////////
|
||||
// NOTE: DN_TicketMutex_BeginTicket
|
||||
//
|
||||
// Locks the mutex using the given ticket if possible. If it's not
|
||||
// the next ticket to be locked the executing thread will block
|
||||
@ -991,7 +987,7 @@ void DN_Docs_Demo()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_ThreadContext /////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_ThreadContext
|
||||
//
|
||||
// Each thread is assigned in their thread-local storage (TLS) tmem and
|
||||
// permanent arena allocators. These can be used for allocations with a
|
||||
@ -1041,21 +1037,21 @@ void DN_Docs_Demo()
|
||||
// @param[in] conflict_arena A pointer to the arena currently being used in the
|
||||
// function
|
||||
|
||||
// NOTE: DN_CVT_Str8FromU64 /////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8x32FromFmt
|
||||
{
|
||||
DN_CVTU64Str8 string = DN_CVT_Str8FromU64(123123, ',');
|
||||
if (0) // Prints "123,123"
|
||||
printf("%.*s", DN_STR_FMT(string));
|
||||
DN_Str8x32 string = DN_Str8x32FromFmt("%" PRIu64, 123123);
|
||||
if (0) // Prints "123123"
|
||||
printf("%.*s", DN_Str8PrintFmt(string));
|
||||
}
|
||||
|
||||
// NOTE: DN_CVT_AgeFromU64 //////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_CVT_AgeFromU64
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_CVT_AgeFromU64(tmem.arena, DN_HoursToSec(2) + DN_MinutesToSec(30), DN_CVTU64AgeUnit_All);
|
||||
DN_Assert(DN_Str8_Eq(string, DN_STR8("2h 30m")));
|
||||
DN_Str8x128 string = DN_AgeStr8FromSecF64(DN_SecFromHours(2) + DN_SecFromMins(30), DN_AgeUnit_All);
|
||||
DN_Assert(DN_Str8Eq(DN_Str8FromStruct(&string), DN_Str8Lit("2h 30m")));
|
||||
}
|
||||
|
||||
// NOTE: DN_VArray ////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray
|
||||
//
|
||||
// An array that is backed by virtual memory by reserving addressing space
|
||||
// and comitting pages as items are allocated in the array. This array never
|
||||
@ -1079,8 +1075,8 @@ void DN_Docs_Demo()
|
||||
// In addition to no realloc on expansion or shrinking.
|
||||
//
|
||||
{
|
||||
// NOTE: DN_VArray_Init ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_InitByteSize ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_Init
|
||||
// NOTE: DN_VArray_InitByteSize
|
||||
//
|
||||
// Initialise an array with the requested byte size or item capacity
|
||||
// respectively. The returned array may have a higher capacity than the
|
||||
@ -1090,10 +1086,10 @@ void DN_Docs_Demo()
|
||||
DN_VArray<int> array = DN_VArray_Init<int>(1024);
|
||||
DN_Assert(array.size == 0 && array.max >= 1024);
|
||||
|
||||
// NOTE: DN_VArray_Make //////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_Add //////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_MakeArray //////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_AddArray //////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_Make
|
||||
// NOTE: DN_VArray_Add
|
||||
// NOTE: DN_VArray_MakeArray
|
||||
// NOTE: DN_VArray_AddArray
|
||||
//
|
||||
// Allocate items from the array where:
|
||||
//
|
||||
@ -1105,7 +1101,7 @@ void DN_Docs_Demo()
|
||||
int *item = DN_VArray_Add(&array, 0xCAFE);
|
||||
DN_Assert(*item == 0xCAFE && array.size == 1);
|
||||
|
||||
// NOTE: DN_VArray_AddCArray /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_AddCArray
|
||||
DN_VArray_AddCArray(&array, {1, 2, 3});
|
||||
DN_Assert(array.size == 4);
|
||||
|
||||
@ -1116,7 +1112,7 @@ void DN_Docs_Demo()
|
||||
if (index != 1)
|
||||
continue;
|
||||
|
||||
// NOTE: DN_VArray_EraseRange /////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_EraseRange
|
||||
//
|
||||
// Erase the next 'count' items at 'begin_index' in the array.
|
||||
// 'count' can be positive or negative which dictates the if we
|
||||
@ -1151,7 +1147,7 @@ void DN_Docs_Demo()
|
||||
array.data[2] == 3);
|
||||
#endif
|
||||
|
||||
// NOTE: DN_VArray_Reserve ////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_VArray_Reserve
|
||||
//
|
||||
// Ensure that the requested number of items are backed by physical pages
|
||||
// from the OS. Calling this pre-emptively will minimise syscalls into the
|
||||
@ -1164,31 +1160,31 @@ void DN_Docs_Demo()
|
||||
DN_VArray_Deinit(&array);
|
||||
}
|
||||
|
||||
// NOTE: DN_W32_LastError /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_W32_ErrorCodeToMsg /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_W32_LastError
|
||||
// NOTE: DN_W32_ErrorCodeToMsg
|
||||
#if defined(DN_PLATFORM_WIN32)
|
||||
if (0) {
|
||||
// Generate the error string for the last Win32 API called that return
|
||||
// an error value.
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_W32Error get_last_error = DN_W32_LastError(tmem.arena);
|
||||
printf("Error (%lu): %.*s", get_last_error.code, DN_STR_FMT(get_last_error.msg));
|
||||
printf("Error (%lu): %.*s", get_last_error.code, DN_Str8PrintFmt(get_last_error.msg));
|
||||
|
||||
// Alternatively, pass in the error code directly
|
||||
DN_W32Error error_msg_for_code = DN_W32_ErrorCodeToMsg(tmem.arena, /*error_code*/ 0);
|
||||
printf("Error (%lu): %.*s", error_msg_for_code.code, DN_STR_FMT(error_msg_for_code.msg));
|
||||
printf("Error (%lu): %.*s", error_msg_for_code.code, DN_Str8PrintFmt(error_msg_for_code.msg));
|
||||
}
|
||||
|
||||
// NOTE: DN_W32_MakeProcessDPIAware ///////////////////////////////////////////////////////////
|
||||
// NOTE: DN_W32_MakeProcessDPIAware
|
||||
//
|
||||
// Call once at application start-up to ensure that the application is DPI
|
||||
// aware on Windows and ensure that application UI is scaled up
|
||||
// appropriately for the monitor.
|
||||
|
||||
// NOTE: DN_W32_Str8ToStr16 /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_W32_Str8ToStr16Buffer /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_W32_Str16ToStr8 /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_W32_Str16ToStr8Buffer /////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_W32_Str8ToStr16
|
||||
// NOTE: DN_W32_Str8ToStr16Buffer
|
||||
// NOTE: DN_W32_Str16ToStr8
|
||||
// NOTE: DN_W32_Str16ToStr8Buffer
|
||||
//
|
||||
// Convert a UTF8 <-> UTF16 string.
|
||||
//
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
static DN_I32 DN_ASYNC_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
{
|
||||
DN_OS_ThreadSetName(DN_Str8_FromIStr8(&thread->name));
|
||||
DN_ASYNCCore *async = DN_CAST(DN_ASYNCCore *) thread->user_context;
|
||||
DN_OS_ThreadSetName(DN_Str8FromPtr(thread->name.data, thread->name.size));
|
||||
DN_ASYNCCore *async = DN_Cast(DN_ASYNCCore *) thread->user_context;
|
||||
DN_Ring *ring = &async->ring;
|
||||
for (;;) {
|
||||
DN_OS_SemaphoreWait(&async->worker_sem, UINT32_MAX);
|
||||
@ -51,7 +51,7 @@ DN_API void DN_ASYNC_Init(DN_ASYNCCore *async, char *base, DN_USize base_size, D
|
||||
async->threads = threads;
|
||||
for (DN_ForIndexU(index, async->thread_count)) {
|
||||
DN_OSThread *thread = async->threads + index;
|
||||
DN_IStr8_AppendF(&thread->name, "ASYNC W%zu", index);
|
||||
DN_FmtAppend(thread->name.data, &thread->name.size, DN_ArrayCountU(thread->name.data), "ASYNC W%zu", index);
|
||||
DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, async);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,11 +6,11 @@ DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item)
|
||||
if (mode == DN_BinPackMode_Serialise) {
|
||||
DN_U64 it = *item;
|
||||
do {
|
||||
DN_U8 write_value = DN_CAST(DN_U8)(it & VALUE_MASK);
|
||||
DN_U8 write_value = DN_Cast(DN_U8)(it & VALUE_MASK);
|
||||
it >>= 7;
|
||||
if (it)
|
||||
write_value |= CONTINUE_BIT;
|
||||
DN_Str8Builder_AppendBytesCopy(&pack->writer, &write_value, sizeof(write_value));
|
||||
DN_Str8BuilderAppendBytesCopy(&pack->writer, &write_value, sizeof(write_value));
|
||||
} while (it);
|
||||
} else {
|
||||
*item = 0;
|
||||
@ -18,7 +18,7 @@ DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item)
|
||||
for (DN_U8 src = CONTINUE_BIT; (src & CONTINUE_BIT) && bits_read < 64; bits_read += 7) {
|
||||
src = pack->read.data[pack->read_index++];
|
||||
DN_U8 masked_src = src & VALUE_MASK;
|
||||
*item |= (DN_CAST(DN_U64) masked_src << bits_read);
|
||||
*item |= (DN_Cast(DN_U64) masked_src << bits_read);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,10 +109,10 @@ DN_API void DN_BinPack_Str8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPa
|
||||
{
|
||||
DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size));
|
||||
if (mode == DN_BinPackMode_Serialise) {
|
||||
DN_Str8Builder_AppendBytesCopy(&pack->writer, string->data, string->size);
|
||||
DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size);
|
||||
} else {
|
||||
DN_Str8 src = DN_Str8_Slice(pack->read, pack->read_index, string->size);
|
||||
*string = DN_Str8_FromStr8(arena, src);
|
||||
DN_Str8 src = DN_Str8Slice(pack->read, pack->read_index, string->size);
|
||||
*string = DN_Str8FromStr8Arena(arena, src);
|
||||
pack->read_index += src.size;
|
||||
}
|
||||
}
|
||||
@ -121,17 +121,17 @@ DN_API void DN_BinPack_Str8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackM
|
||||
{
|
||||
DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size));
|
||||
if (mode == DN_BinPackMode_Serialise) {
|
||||
DN_Str8Builder_AppendBytesCopy(&pack->writer, string->data, string->size);
|
||||
DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size);
|
||||
} else {
|
||||
DN_Str8 src = DN_Str8_Slice(pack->read, pack->read_index, string->size);
|
||||
*string = DN_Pool_AllocStr8Copy(pool, src);
|
||||
DN_Str8 src = DN_Str8Slice(pack->read, pack->read_index, string->size);
|
||||
*string = DN_Str8FromStr8Pool(pool, src);
|
||||
pack->read_index += src.size;
|
||||
}
|
||||
}
|
||||
|
||||
DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size)
|
||||
{
|
||||
DN_Str8 string = DN_Str8_Init(*ptr, *size);
|
||||
DN_Str8 string = DN_Str8FromPtr(*ptr, *size);
|
||||
DN_BinPack_Str8FromArena(pack, arena, mode, &string);
|
||||
*ptr = string.data;
|
||||
*size = string.size;
|
||||
@ -139,7 +139,7 @@ DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinP
|
||||
|
||||
DN_API void DN_BinPack_BytesFromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size)
|
||||
{
|
||||
DN_Str8 string = DN_Str8_Init(*ptr, *size);
|
||||
DN_Str8 string = DN_Str8FromPtr(*ptr, *size);
|
||||
DN_BinPack_Str8FromPool(pack, pool, mode, &string);
|
||||
*ptr = string.data;
|
||||
*size = string.size;
|
||||
@ -149,9 +149,9 @@ DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr,
|
||||
{
|
||||
DN_BinPack_VarInt_(pack, mode, &size, sizeof(size));
|
||||
if (mode == DN_BinPackMode_Serialise) {
|
||||
DN_Str8Builder_AppendBytesCopy(&pack->writer, ptr, size);
|
||||
DN_Str8BuilderAppendBytesCopy(&pack->writer, ptr, size);
|
||||
} else {
|
||||
DN_Str8 src = DN_Str8_Slice(pack->read, pack->read_index, size);
|
||||
DN_Str8 src = DN_Str8Slice(pack->read, pack->read_index, size);
|
||||
DN_Assert(src.size == size);
|
||||
DN_Memcpy(ptr, src.data, DN_Min(src.size, size));
|
||||
pack->read_index += src.size;
|
||||
@ -160,6 +160,6 @@ DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr,
|
||||
|
||||
DN_API DN_Str8 DN_BinPack_Build(DN_BinPack const *pack, DN_Arena *arena)
|
||||
{
|
||||
DN_Str8 result = DN_Str8Builder_Build(&pack->writer, arena);
|
||||
DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -180,10 +180,10 @@ enum DN_CGenEmit
|
||||
DN_CGenEmit_Implementation = 1 << 1,
|
||||
};
|
||||
|
||||
#define DN_CGen_MDToDNStr8(str8) DN_Str8_Init((str8).str, (str8).size)
|
||||
#define DN_CGen_MDToDNStr8(str8) DN_Str8FromPtr((str8).str, (str8).size)
|
||||
#define DN_CGen_DNToMDStr8(str8) \
|
||||
{ \
|
||||
DN_CAST(MD_u8 *) \
|
||||
DN_Cast(MD_u8 *) \
|
||||
(str8).data, \
|
||||
(str8).size \
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ static bool DN_CSV_TokeniserValid(DN_CSVTokeniser *tokeniser)
|
||||
static bool DN_CSV_TokeniserNextRow(DN_CSVTokeniser *tokeniser)
|
||||
{
|
||||
bool result = false;
|
||||
if (DN_CSV_TokeniserValid(tokeniser) && DN_Str8_HasData(tokeniser->string)) {
|
||||
if (DN_CSV_TokeniserValid(tokeniser) && DN_Str8HasData(tokeniser->string)) {
|
||||
// NOTE: First time querying row iterator is nil, let tokeniser advance
|
||||
if (tokeniser->it) {
|
||||
// NOTE: Only advance the tokeniser if we're at the end of the line and
|
||||
@ -39,7 +39,7 @@ static DN_Str8 DN_CSV_TokeniserNextField(DN_CSVTokeniser *tokeniser)
|
||||
if (!DN_CSV_TokeniserValid(tokeniser))
|
||||
return result;
|
||||
|
||||
if (!DN_Str8_HasData(tokeniser->string)) {
|
||||
if (!DN_Str8HasData(tokeniser->string)) {
|
||||
tokeniser->bad = true;
|
||||
return result;
|
||||
}
|
||||
@ -111,8 +111,8 @@ static DN_Str8 DN_CSV_TokeniserNextField(DN_CSVTokeniser *tokeniser)
|
||||
tokeniser->it++;
|
||||
|
||||
// NOTE: Generate the record
|
||||
result.data = DN_CAST(char *) begin;
|
||||
result.size = DN_CAST(int)(end - begin);
|
||||
result.data = DN_Cast(char *) begin;
|
||||
result.size = DN_Cast(int)(end - begin);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ static int DN_CSV_TokeniserNextN(DN_CSVTokeniser *tokeniser, DN_Str8 *fields, in
|
||||
int result = 0;
|
||||
for (; result < fields_size; result++) {
|
||||
fields[result] = column_iterator ? DN_CSV_TokeniserNextColumn(tokeniser) : DN_CSV_TokeniserNextField(tokeniser);
|
||||
if (!DN_CSV_TokeniserValid(tokeniser) || !DN_Str8_HasData(fields[result]))
|
||||
if (!DN_CSV_TokeniserValid(tokeniser) || !DN_Str8HasData(fields[result]))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -177,11 +177,11 @@ static void DN_CSV_PackU64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_U64 *
|
||||
{
|
||||
if (serialise == DN_CSVSerialise_Read) {
|
||||
DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser);
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(csv_value, 0);
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8ToU64(csv_value, 0);
|
||||
DN_Assert(to_u64.success);
|
||||
*value = to_u64.value;
|
||||
} else {
|
||||
DN_Str8Builder_AppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value);
|
||||
DN_Str8BuilderAppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,11 +189,11 @@ static void DN_CSV_PackI64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_I64 *
|
||||
{
|
||||
if (serialise == DN_CSVSerialise_Read) {
|
||||
DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser);
|
||||
DN_Str8ToI64Result to_i64 = DN_Str8_ToI64(csv_value, 0);
|
||||
DN_Str8ToI64Result to_i64 = DN_Str8ToI64(csv_value, 0);
|
||||
DN_Assert(to_i64.success);
|
||||
*value = to_i64.value;
|
||||
} else {
|
||||
DN_Str8Builder_AppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value);
|
||||
DN_Str8BuilderAppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,9 +250,9 @@ static void DN_CSV_PackStr8(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_Str8
|
||||
{
|
||||
if (serialise == DN_CSVSerialise_Read) {
|
||||
DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser);
|
||||
*str8 = DN_Str8_FromStr8(arena, csv_value);
|
||||
*str8 = DN_Str8FromStr8(arena, csv_value);
|
||||
} else {
|
||||
DN_Str8Builder_AppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_STR_FMT(*str8));
|
||||
DN_Str8BuilderAppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_Str8PrintFmt(*str8));
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ static void DN_CSV_PackBuffer(DN_CSVPack *pack, DN_CSVSerialise serialise, void
|
||||
*size = DN_Min(*size, csv_value.size);
|
||||
DN_Memcpy(dest, csv_value.data, *size);
|
||||
} else {
|
||||
DN_Str8Builder_AppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_CAST(int)(*size), dest);
|
||||
DN_Str8BuilderAppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_Cast(int)(*size), dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ static bool DN_CSV_PackNewLine(DN_CSVPack *pack, DN_CSVSerialise serialise)
|
||||
result = DN_CSV_TokeniserNextRow(&pack->read_tokeniser);
|
||||
} else {
|
||||
pack->write_column = 0;
|
||||
result = DN_Str8Builder_AppendRef(&pack->write_builder, DN_STR8("\n"));
|
||||
result = DN_Str8BuilderAppendRef(&pack->write_builder, DN_Str8Lit("\n"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
// Default values recommended by: http://isthe.com/chongo/tech/comp/fnv/
|
||||
DN_API uint32_t DN_FNV1A32_Iterate(void const *bytes, DN_USize size, uint32_t hash)
|
||||
{
|
||||
auto buffer = DN_CAST(uint8_t const *)bytes;
|
||||
auto buffer = DN_Cast(uint8_t const *)bytes;
|
||||
for (DN_USize i = 0; i < size; i++)
|
||||
hash = (buffer[i] ^ hash) * 16777619 /*FNV Prime*/;
|
||||
return hash;
|
||||
@ -35,7 +35,7 @@ DN_API uint32_t DN_FNV1A32_Hash(void const *bytes, DN_USize size)
|
||||
|
||||
DN_API uint64_t DN_FNV1A64_Iterate(void const *bytes, DN_USize size, uint64_t hash)
|
||||
{
|
||||
auto buffer = DN_CAST(uint8_t const *)bytes;
|
||||
auto buffer = DN_Cast(uint8_t const *)bytes;
|
||||
for (DN_USize i = 0; i < size; i++)
|
||||
hash = (buffer[i] ^ hash) * 1099511628211 /*FNV Prime*/;
|
||||
return hash;
|
||||
|
||||
@ -40,6 +40,6 @@ DN_API uint64_t DN_FNV1A64_Iterate (void const *bytes, DN_USize si
|
||||
DN_API uint32_t DN_MurmurHash3_x86U32 (void const *key, int len, uint32_t seed);
|
||||
DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128 (void const *key, int len, uint32_t seed);
|
||||
#define DN_MurmurHash3_x64U128AsU64(key, len, seed) (DN_MurmurHash3_x64U128(key, len, seed).e[0])
|
||||
#define DN_MurmurHash3_x64U128AsU32(key, len, seed) (DN_CAST(uint32_t)DN_MurmurHash3_x64U128(key, len, seed).e[0])
|
||||
#define DN_MurmurHash3_x64U128AsU32(key, len, seed) (DN_Cast(uint32_t)DN_MurmurHash3_x64U128(key, len, seed).e[0])
|
||||
|
||||
#endif // !defined(DN_HASH_H)
|
||||
|
||||
@ -106,7 +106,7 @@ DN_API DN_JSONBuilder DN_JSONBuilder_Init(DN_Arena *arena, int spaces_per_indent
|
||||
|
||||
DN_API DN_Str8 DN_JSONBuilder_Build(DN_JSONBuilder const *builder, DN_Arena *arena)
|
||||
{
|
||||
DN_Str8 result = DN_Str8Builder_Build(&builder->string_builder, arena);
|
||||
DN_Str8 result = DN_Str8BuilderBuild(&builder->string_builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -142,18 +142,18 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str
|
||||
int spaces = builder->indent_level * spaces_per_indent;
|
||||
|
||||
if (key.size)
|
||||
DN_Str8Builder_AppendF(&builder->string_builder,
|
||||
DN_Str8BuilderAppendF(&builder->string_builder,
|
||||
"%.*s%*c\"%.*s\": %.*s",
|
||||
prefix_size,
|
||||
prefix,
|
||||
spaces,
|
||||
' ',
|
||||
DN_STR_FMT(key),
|
||||
DN_STR_FMT(value));
|
||||
DN_Str8PrintFmt(key),
|
||||
DN_Str8PrintFmt(value));
|
||||
else if (spaces == 0)
|
||||
DN_Str8Builder_AppendF(&builder->string_builder, "%.*s%.*s", prefix_size, prefix, DN_STR_FMT(value));
|
||||
DN_Str8BuilderAppendF(&builder->string_builder, "%.*s%.*s", prefix_size, prefix, DN_Str8PrintFmt(value));
|
||||
else
|
||||
DN_Str8Builder_AppendF(&builder->string_builder, "%.*s%*c%.*s", prefix_size, prefix, spaces, ' ', DN_STR_FMT(value));
|
||||
DN_Str8BuilderAppendF(&builder->string_builder, "%.*s%*c%.*s", prefix_size, prefix, spaces, ' ', DN_Str8PrintFmt(value));
|
||||
|
||||
if (item == DN_JSONBuilderItem_OpenContainer)
|
||||
builder->indent_level++;
|
||||
@ -164,7 +164,7 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str
|
||||
DN_API void DN_JSONBuilder_KeyValueFV(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, va_list args)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(builder->string_builder.arena);
|
||||
DN_Str8 value = DN_Str8_FromFV(tmem.arena, value_fmt, args);
|
||||
DN_Str8 value = DN_Str8FromFmtVArena(tmem.arena, value_fmt, args);
|
||||
DN_JSONBuilder_KeyValue(builder, key, value);
|
||||
}
|
||||
|
||||
@ -178,22 +178,22 @@ DN_API void DN_JSONBuilder_KeyValueF(DN_JSONBuilder *builder, DN_Str8 key, char
|
||||
|
||||
DN_API void DN_JSONBuilder_ObjectBeginNamed(DN_JSONBuilder *builder, DN_Str8 name)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_STR8("{"));
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_Str8Lit("{"));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_ObjectEnd(DN_JSONBuilder *builder)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, DN_STR8(""), DN_STR8("}"));
|
||||
DN_JSONBuilder_KeyValue(builder, DN_Str8Lit(""), DN_Str8Lit("}"));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_ArrayBeginNamed(DN_JSONBuilder *builder, DN_Str8 name)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_STR8("["));
|
||||
DN_JSONBuilder_KeyValue(builder, name, DN_Str8Lit("["));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_ArrayEnd(DN_JSONBuilder *builder)
|
||||
{
|
||||
DN_JSONBuilder_KeyValue(builder, DN_STR8(""), DN_STR8("]"));
|
||||
DN_JSONBuilder_KeyValue(builder, DN_Str8Lit(""), DN_Str8Lit("]"));
|
||||
}
|
||||
|
||||
DN_API void DN_JSONBuilder_Str8Named(DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value)
|
||||
@ -239,136 +239,7 @@ DN_API void DN_JSONBuilder_F64Named(DN_JSONBuilder *builder, DN_Str8 key, double
|
||||
|
||||
DN_API void DN_JSONBuilder_BoolNamed(DN_JSONBuilder *builder, DN_Str8 key, bool value)
|
||||
{
|
||||
DN_Str8 value_string = value ? DN_STR8("true") : DN_STR8("false");
|
||||
DN_Str8 value_string = value ? DN_Str8Lit("true") : DN_Str8Lit("false");
|
||||
DN_JSONBuilder_KeyValueF(builder, key, "%.*s", value_string.size, value_string.data);
|
||||
}
|
||||
#endif // !defined(DN_NO_JSON_BUILDER)
|
||||
|
||||
// NOTE: DN_JobQueue ///////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_JobQueueSPMC DN_OS_JobQueueSPMCInit()
|
||||
{
|
||||
DN_JobQueueSPMC result = {};
|
||||
result.thread_wait_for_job_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.wait_for_completion_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/);
|
||||
result.complete_queue_write_semaphore = DN_OS_SemaphoreInit(DN_ArrayCountU(result.complete_queue));
|
||||
result.mutex = DN_OS_MutexInit();
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_JobQueueSPMCCanAdd(DN_JobQueueSPMC const *queue, uint32_t count)
|
||||
{
|
||||
uint32_t read_index = queue->read_index;
|
||||
uint32_t write_index = queue->write_index;
|
||||
uint32_t size = write_index - read_index;
|
||||
bool result = (size + count) <= DN_ArrayCountU(queue->jobs);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_JobQueueSPMCAddArray(DN_JobQueueSPMC *queue, DN_Job *jobs, uint32_t count)
|
||||
{
|
||||
if (!queue)
|
||||
return false;
|
||||
|
||||
uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1;
|
||||
uint32_t read_index = queue->read_index;
|
||||
uint32_t write_index = queue->write_index;
|
||||
uint32_t size = write_index - read_index;
|
||||
|
||||
if ((size + count) > DN_ArrayCountU(queue->jobs))
|
||||
return false;
|
||||
|
||||
for (size_t offset = 0; offset < count; offset++) {
|
||||
uint32_t wrapped_write_index = (write_index + offset) & pot_mask;
|
||||
queue->jobs[wrapped_write_index] = jobs[offset];
|
||||
}
|
||||
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
queue->write_index += count;
|
||||
DN_OS_SemaphoreIncrement(&queue->thread_wait_for_job_semaphore, count);
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API bool DN_OS_JobQueueSPMCAdd(DN_JobQueueSPMC *queue, DN_Job job)
|
||||
{
|
||||
bool result = DN_OS_JobQueueSPMCAddArray(queue, &job, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API int32_t DN_OS_JobQueueSPMCThread(DN_OSThread *thread)
|
||||
{
|
||||
DN_JobQueueSPMC *queue = DN_CAST(DN_JobQueueSPMC *) thread->user_context;
|
||||
uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1;
|
||||
static_assert(DN_ArrayCountU(queue->jobs) == DN_ArrayCountU(queue->complete_queue), "PoT mask is used to mask access to both arrays");
|
||||
|
||||
for (;;) {
|
||||
DN_OS_SemaphoreWait(&queue->thread_wait_for_job_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
if (queue->quit)
|
||||
break;
|
||||
|
||||
DN_Assert(queue->read_index != queue->write_index);
|
||||
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
uint32_t wrapped_read_index = queue->read_index & pot_mask;
|
||||
DN_Job job = queue->jobs[wrapped_read_index];
|
||||
queue->read_index += 1;
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
job.elapsed_tsc -= DN_CPUGetTSC();
|
||||
job.func(thread, job.user_context);
|
||||
job.elapsed_tsc += DN_CPUGetTSC();
|
||||
|
||||
if (job.add_to_completion_queue) {
|
||||
DN_OS_SemaphoreWait(&queue->complete_queue_write_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
queue->complete_queue[(queue->complete_write_index++ & pot_mask)] = job;
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
DN_OS_SemaphoreIncrement(&queue->complete_queue_write_semaphore, 1);
|
||||
}
|
||||
|
||||
// NOTE: Update finish counter
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
queue->finish_index += 1;
|
||||
|
||||
// NOTE: If all jobs are finished and we have another thread who is
|
||||
// blocked via `WaitForCompletion` for this job queue, we will go
|
||||
// release the semaphore to wake them all up.
|
||||
bool all_jobs_finished = queue->finish_index == queue->write_index;
|
||||
if (all_jobs_finished && queue->threads_waiting_for_completion) {
|
||||
DN_OS_SemaphoreIncrement(&queue->wait_for_completion_semaphore,
|
||||
queue->threads_waiting_for_completion);
|
||||
queue->threads_waiting_for_completion = 0;
|
||||
}
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
}
|
||||
|
||||
return queue->quit_exit_code;
|
||||
}
|
||||
|
||||
DN_API void DN_OS_JobQueueSPMCWaitForCompletion(DN_JobQueueSPMC *queue)
|
||||
{
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
if (queue->finish_index == queue->write_index) {
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
return;
|
||||
}
|
||||
queue->threads_waiting_for_completion++;
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
DN_OS_SemaphoreWait(&queue->wait_for_completion_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
}
|
||||
|
||||
DN_API DN_USize DN_OS_JobQueueSPMCGetFinishedJobs(DN_JobQueueSPMC *queue, DN_Job *jobs, DN_USize jobs_size)
|
||||
{
|
||||
DN_USize result = 0;
|
||||
if (!queue || !jobs || jobs_size <= 0)
|
||||
return result;
|
||||
|
||||
uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1;
|
||||
DN_OS_MutexLock(&queue->mutex);
|
||||
while (queue->complete_read_index < queue->complete_write_index && result < jobs_size)
|
||||
jobs[result++] = queue->complete_queue[(queue->complete_read_index++ & pot_mask)];
|
||||
DN_OS_MutexUnlock(&queue->mutex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -95,42 +95,6 @@ struct DN_BinarySearchResult
|
||||
template <typename T>
|
||||
using DN_QSortLessThanProc = bool(T const &a, T const &b, void *user_context);
|
||||
|
||||
// NOTE: Misc //////////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JobQueue ///////////////////////////////////////////////////////////////////////////////
|
||||
typedef void(DN_JobQueueFunc)(DN_OSThread *thread, void *user_context);
|
||||
struct DN_Job
|
||||
{
|
||||
DN_JobQueueFunc *func; // The function to invoke for the job
|
||||
void *user_context; // Pointer user can set to use in their `job_func`
|
||||
uint64_t elapsed_tsc;
|
||||
uint16_t user_tag; // Arbitrary value the user can set to identiy the type of `user_context` this job has
|
||||
bool add_to_completion_queue; // When true, on job completion, job must be dequeued from the completion queue via `GetFinishedJobs`
|
||||
};
|
||||
|
||||
#if !defined(DN_JOB_QUEUE_SPMC_SIZE)
|
||||
#define DN_JOB_QUEUE_SPMC_SIZE 128
|
||||
#endif
|
||||
|
||||
struct DN_JobQueueSPMC
|
||||
{
|
||||
DN_OSMutex mutex;
|
||||
DN_OSSemaphore thread_wait_for_job_semaphore;
|
||||
DN_OSSemaphore wait_for_completion_semaphore;
|
||||
DN_U32 threads_waiting_for_completion;
|
||||
|
||||
DN_Job jobs[DN_JOB_QUEUE_SPMC_SIZE];
|
||||
DN_B32 quit;
|
||||
DN_U32 quit_exit_code;
|
||||
DN_U32 volatile read_index;
|
||||
DN_U32 volatile finish_index;
|
||||
DN_U32 volatile write_index;
|
||||
|
||||
DN_OSSemaphore complete_queue_write_semaphore;
|
||||
DN_Job complete_queue[DN_JOB_QUEUE_SPMC_SIZE];
|
||||
DN_U32 volatile complete_read_index;
|
||||
DN_U32 volatile complete_write_index;
|
||||
};
|
||||
|
||||
// NOTE: DN_PCG32 //////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_PCG32 DN_PCG32_Init (uint64_t seed);
|
||||
DN_API uint32_t DN_PCG32_Next (DN_PCG32 *rng);
|
||||
@ -173,41 +137,25 @@ DN_API void DN_JSONBuilder_I64Named (DN_JSONBuilde
|
||||
DN_API void DN_JSONBuilder_F64Named (DN_JSONBuilder *builder, DN_Str8 key, double value, int decimal_places);
|
||||
DN_API void DN_JSONBuilder_BoolNamed (DN_JSONBuilder *builder, DN_Str8 key, bool value);
|
||||
|
||||
#define DN_JSONBuilder_ObjectBegin(builder) DN_JSONBuilder_ObjectBeginNamed(builder, DN_STR8(""))
|
||||
#define DN_JSONBuilder_ArrayBegin(builder) DN_JSONBuilder_ArrayBeginNamed(builder, DN_STR8(""))
|
||||
#define DN_JSONBuilder_Str8(builder, value) DN_JSONBuilder_Str8Named(builder, DN_STR8(""), value)
|
||||
#define DN_JSONBuilder_Literal(builder, value) DN_JSONBuilder_LiteralNamed(builder, DN_STR8(""), value)
|
||||
#define DN_JSONBuilder_U64(builder, value) DN_JSONBuilder_U64Named(builder, DN_STR8(""), value)
|
||||
#define DN_JSONBuilder_I64(builder, value) DN_JSONBuilder_I64Named(builder, DN_STR8(""), value)
|
||||
#define DN_JSONBuilder_F64(builder, value) DN_JSONBuilder_F64Named(builder, DN_STR8(""), value)
|
||||
#define DN_JSONBuilder_Bool(builder, value) DN_JSONBuilder_BoolNamed(builder, DN_STR8(""), value)
|
||||
#define DN_JSONBuilder_ObjectBegin(builder) DN_JSONBuilder_ObjectBeginNamed(builder, DN_Str8Lit(""))
|
||||
#define DN_JSONBuilder_ArrayBegin(builder) DN_JSONBuilder_ArrayBeginNamed(builder, DN_Str8Lit(""))
|
||||
#define DN_JSONBuilder_Str8(builder, value) DN_JSONBuilder_Str8Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_Literal(builder, value) DN_JSONBuilder_LiteralNamed(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_U64(builder, value) DN_JSONBuilder_U64Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_I64(builder, value) DN_JSONBuilder_I64Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_F64(builder, value) DN_JSONBuilder_F64Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_Bool(builder, value) DN_JSONBuilder_BoolNamed(builder, DN_Str8Lit(""), value)
|
||||
#endif // !defined(DN_NO_JSON_BUILDER)
|
||||
|
||||
// NOTE: DN_BinarySearch ///////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_BinarySearch
|
||||
template <typename T> bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs);
|
||||
template <typename T> DN_BinarySearchResult DN_BinarySearch (T const *array,
|
||||
DN_USize array_size,
|
||||
T const &find,
|
||||
DN_BinarySearchType type = DN_BinarySearchType_Match,
|
||||
DN_BinarySearchLessThanProc<T> less_than = DN_BinarySearch_DefaultLessThan);
|
||||
template <typename T> DN_BinarySearchResult DN_BinarySearch (T const *array, DN_USize array_size, T const &find, DN_BinarySearchType type = DN_BinarySearchType_Match, DN_BinarySearchLessThanProc<T> less_than = DN_BinarySearch_DefaultLessThan);
|
||||
|
||||
// NOTE: DN_QSort //////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_QSort
|
||||
template <typename T> bool DN_QSort_DefaultLessThan(T const &lhs, T const &rhs, void *user_context);
|
||||
template <typename T> void DN_QSort (T *array,
|
||||
DN_USize array_size,
|
||||
void *user_context,
|
||||
DN_QSortLessThanProc<T> less_than = DN_QSort_DefaultLessThan);
|
||||
template <typename T> void DN_QSort (T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc<T> less_than = DN_QSort_DefaultLessThan);
|
||||
|
||||
// NOTE: DN_JobQueue ///////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_JobQueueSPMC DN_OS_JobQueueSPMCInit ();
|
||||
DN_API bool DN_OS_JobQueueSPMCCanAdd (DN_JobQueueSPMC const *queue, uint32_t count);
|
||||
DN_API bool DN_OS_JobQueueSPMCAddArray (DN_JobQueueSPMC *queue, DN_Job *jobs, uint32_t count);
|
||||
DN_API bool DN_OS_JobQueueSPMCAdd (DN_JobQueueSPMC *queue, DN_Job job);
|
||||
DN_API void DN_OS_JobQueueSPMCWaitForCompletion (DN_JobQueueSPMC *queue);
|
||||
DN_API int32_t DN_OS_JobQueueSPMCThread (DN_OSThread *thread);
|
||||
DN_API DN_USize DN_OS_JobQueueSPMCGetFinishedJobs (DN_JobQueueSPMC *queue, DN_Job *jobs, DN_USize jobs_size);
|
||||
|
||||
// NOTE: DN_BinarySearch ///////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_BinarySearch
|
||||
template <typename T>
|
||||
bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs)
|
||||
{
|
||||
|
||||
@ -7,8 +7,8 @@ void *DN_JSON_ArenaAllocFunc(void *user_data, size_t count)
|
||||
if (!user_data)
|
||||
return result;
|
||||
|
||||
DN_Arena *arena = DN_CAST(DN_Arena*)user_data;
|
||||
result = DN_Arena_Alloc(arena, count, alignof(json_value_s), DN_ZeroMem_No);
|
||||
DN_Arena *arena = DN_Cast(DN_Arena*)user_data;
|
||||
result = DN_ArenaAlloc(arena, count, alignof(json_value_s), DN_ZMem_No);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -30,9 +30,9 @@ char const *DN_JSON_TypeEnumCString(json_type_e type, size_t *size)
|
||||
bool DN_JSON_String8Cmp(json_string_s const *lhs, DN_Str8 key)
|
||||
{
|
||||
bool result = false;
|
||||
if (lhs && DN_Str8_HasData(key)) {
|
||||
DN_Str8 lhs_string = DN_Str8_Init(lhs->string, lhs->string_size);
|
||||
result = DN_Str8_Eq(lhs_string, key);
|
||||
if (lhs && key.size) {
|
||||
DN_Str8 lhs_string = DN_Str8FromPtr(lhs->string, lhs->string_size);
|
||||
result = DN_Str8Eq(lhs_string, key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -42,7 +42,7 @@ DN_JSONIt DN_JSON_LoadFileToIt(DN_Arena *arena, DN_Str8 json)
|
||||
{
|
||||
json_parse_result_s parse_result = {};
|
||||
json_value_ex_s *ex_value =
|
||||
DN_CAST(json_value_ex_s *) json_parse_ex(json.data,
|
||||
DN_Cast(json_value_ex_s *) json_parse_ex(json.data,
|
||||
json.size,
|
||||
json_parse_flags_allow_location_information,
|
||||
DN_JSON_ArenaAllocFunc,
|
||||
@ -124,13 +124,13 @@ json_value_s *DN_JSON_ItPushCurrValue(DN_JSONIt *it)
|
||||
return result;
|
||||
|
||||
if (curr->type == DN_JSON_ItEntryTypeObjElement) {
|
||||
json_object_element_s *element = DN_CAST(json_object_element_s *) curr->value;
|
||||
json_object_element_s *element = DN_Cast(json_object_element_s *) curr->value;
|
||||
result = element->value;
|
||||
} else if (curr->type == DN_JSON_ItEntryTypeArrayElement) {
|
||||
json_array_element_s *element = DN_CAST(json_array_element_s *) curr->value;
|
||||
json_array_element_s *element = DN_Cast(json_array_element_s *) curr->value;
|
||||
result = element->value;
|
||||
} else {
|
||||
result = DN_CAST(json_value_s *) curr->value;
|
||||
result = DN_Cast(json_value_s *) curr->value;
|
||||
}
|
||||
|
||||
if (result->type == json_type_array) {
|
||||
@ -155,18 +155,18 @@ bool DN_JSON_ItNext(DN_JSONIt *it)
|
||||
json_object_element_s *obj_element = nullptr;
|
||||
json_array_element_s *array_element = nullptr;
|
||||
if (curr->type == DN_JSON_ItEntryTypeObj) {
|
||||
auto *obj = DN_CAST(json_object_s *) curr->value;
|
||||
auto *obj = DN_Cast(json_object_s *) curr->value;
|
||||
obj_element = obj->start;
|
||||
} else if (curr->type == DN_JSON_ItEntryTypeObjElement) {
|
||||
auto *element = DN_CAST(json_object_element_s *) curr->value;
|
||||
auto *element = DN_Cast(json_object_element_s *) curr->value;
|
||||
obj_element = element->next;
|
||||
DN_JSON_ItPop(it);
|
||||
} else if (curr->type == DN_JSON_ItEntryTypeArray) {
|
||||
auto *value = DN_CAST(json_value_s *) curr->value;
|
||||
auto *value = DN_Cast(json_value_s *) curr->value;
|
||||
auto *array = json_value_as_array(value);
|
||||
array_element = array->start;
|
||||
} else if (curr->type == DN_JSON_ItEntryTypeArrayElement) {
|
||||
auto *element = DN_CAST(json_array_element_s *) curr->value;
|
||||
auto *element = DN_Cast(json_array_element_s *) curr->value;
|
||||
array_element = element->next;
|
||||
DN_JSON_ItPop(it);
|
||||
} else {
|
||||
@ -201,17 +201,17 @@ json_value_s *DN_JSON_ItCurrValue(DN_JSONIt *it)
|
||||
return result;
|
||||
|
||||
if (curr->type == DN_JSON_ItEntryTypeObjElement) {
|
||||
auto *element = DN_CAST(json_object_element_s *)curr->value;
|
||||
auto *element = DN_Cast(json_object_element_s *)curr->value;
|
||||
result = element->value;
|
||||
} else if (curr->type == DN_JSON_ItEntryTypeArrayElement) {
|
||||
auto *element = DN_CAST(json_array_element_s *)curr->value;
|
||||
auto *element = DN_Cast(json_array_element_s *)curr->value;
|
||||
result = element->value;
|
||||
} else if (curr->type == DN_JSON_ItEntryTypeString ||
|
||||
curr->type == DN_JSON_ItEntryTypeNumber ||
|
||||
curr->type == DN_JSON_ItEntryTypeObj ||
|
||||
curr->type == DN_JSON_ItEntryTypeArray)
|
||||
{
|
||||
result = DN_CAST(json_value_s *)curr->value;
|
||||
result = DN_Cast(json_value_s *)curr->value;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -221,7 +221,7 @@ json_object_element_s *DN_JSON_ItCurrObjElement(DN_JSONIt *it)
|
||||
{
|
||||
DN_JSONItEntry *curr = DN_JSON_ItCurr(it);
|
||||
auto *result = (curr && curr->type == DN_JSON_ItEntryTypeObjElement)
|
||||
? DN_CAST(json_object_element_s *) curr->value
|
||||
? DN_Cast(json_object_element_s *) curr->value
|
||||
: nullptr;
|
||||
return result;
|
||||
}
|
||||
@ -291,7 +291,7 @@ DN_Str8 DN_JSON_ItKey(DN_JSONIt *it)
|
||||
json_object_element_s *curr = DN_JSON_ItCurrObjElement(it);
|
||||
DN_Str8 result = {};
|
||||
if (curr) {
|
||||
result.data = DN_CAST(char *)curr->name->string;
|
||||
result.data = DN_Cast(char *)curr->name->string;
|
||||
result.size = curr->name->string_size;
|
||||
}
|
||||
return result;
|
||||
@ -364,7 +364,7 @@ DN_Str8 DN_JSON_ItValueToString(DN_JSONIt *it)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (json_string_s *curr = DN_JSON_ItValueIsString(it))
|
||||
result = DN_Str8_Init(curr->string, curr->string_size);
|
||||
result = DN_Str8FromPtr(curr->string, curr->string_size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ int64_t DN_JSON_ItValueToI64(DN_JSONIt *it)
|
||||
{
|
||||
int64_t result = {};
|
||||
if (json_number_s *curr = DN_JSON_ItValueIsNumber(it))
|
||||
result = DN_Str8_ToI64(DN_Str8_Init(curr->number, curr->number_size), 0 /*separator*/).value;
|
||||
result = DN_I64FromStr8(DN_Str8FromPtr(curr->number, curr->number_size), 0 /*separator*/).value;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -380,7 +380,7 @@ uint64_t DN_JSON_ItValueToU64(DN_JSONIt *it)
|
||||
{
|
||||
uint64_t result = {};
|
||||
if (json_number_s *curr = DN_JSON_ItValueIsNumber(it))
|
||||
result = DN_Str8_ToU64(DN_Str8_Init(curr->number, curr->number_size), 0 /*separator*/).value;
|
||||
result = DN_U64FromStr8(DN_Str8FromPtr(curr->number, curr->number_size), 0 /*separator*/).value;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -402,27 +402,27 @@ void DN_JSON_ItErrorUnknownKeyValue_(DN_JSONIt *it, DN_CallSite call_site)
|
||||
return;
|
||||
|
||||
size_t value_type_size = 0;
|
||||
char const *value_type = DN_JSON_TypeEnumCString(DN_CAST(json_type_e)curr->value->type, &value_type_size);
|
||||
char const *value_type = DN_JSON_TypeEnumCString(DN_Cast(json_type_e)curr->value->type, &value_type_size);
|
||||
|
||||
json_string_s const *key = curr->name;
|
||||
if (it->flags & json_parse_flags_allow_location_information) {
|
||||
json_string_ex_s const *info = DN_CAST(json_string_ex_s const *)key;
|
||||
json_string_ex_s const *info = DN_Cast(json_string_ex_s const *)key;
|
||||
DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning),
|
||||
call_site,
|
||||
"Unknown key-value pair in object [loc=%zu:%zu, key=%.*s, value=%.*s]",
|
||||
info->line_no,
|
||||
info->row_no,
|
||||
DN_CAST(int) key->string_size,
|
||||
DN_Cast(int) key->string_size,
|
||||
key->string,
|
||||
DN_CAST(int) value_type_size,
|
||||
DN_Cast(int) value_type_size,
|
||||
value_type);
|
||||
} else {
|
||||
DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning),
|
||||
call_site,
|
||||
"Unknown key-value pair in object [key=%.*s, value=%.*s]",
|
||||
DN_CAST(int) key->string_size,
|
||||
DN_Cast(int) key->string_size,
|
||||
key->string,
|
||||
DN_CAST(int) value_type_size,
|
||||
DN_Cast(int) value_type_size,
|
||||
value_type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1200,15 +1200,14 @@ DN_API DN_Str8x256 DN_M4_ColumnMajorString(DN_M4 mat)
|
||||
for (int row = 0; row < 4; row++) {
|
||||
for (int it = 0; it < 4; it++) {
|
||||
if (it == 0)
|
||||
DN_IStr8_AppendF(&result, "|");
|
||||
DN_IStr8_AppendF(&result, "%.5f", mat.columns[it][row]);
|
||||
DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|");
|
||||
DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%.5f", mat.columns[it][row]);
|
||||
if (it != 3)
|
||||
DN_IStr8_AppendF(&result, ", ");
|
||||
DN_FmtAppend(result.data, &result.size, sizeof(result.data), ", ");
|
||||
else
|
||||
DN_IStr8_AppendF(&result, "|\n");
|
||||
DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|\n");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -24,24 +24,24 @@ static DN_NET2Response DN_NET2_WaitForAnyResponse(DN_NET2Core *net, DN_Arena *ar
|
||||
|
||||
// NOTE: Fill in the result
|
||||
DN_NET2ResponseInternal const *response = &request->response;
|
||||
result.request = {DN_CAST(DN_U64) request};
|
||||
result.request = {DN_Cast(DN_U64) request};
|
||||
result.success = response->status != DN_NET2RequestStatus_Error;
|
||||
result.ws_type = response->ws_type;
|
||||
result.http_status = response->http_status;
|
||||
result.body = DN_Str8Builder_Build(&response->body, arena);
|
||||
result.body = DN_Str8BuilderBuild(&response->body, arena);
|
||||
if (response->error.size)
|
||||
result.error = DN_Str8_FromStr8(arena, response->error);
|
||||
result.error = DN_Str8FromStr8Arena(arena, response->error);
|
||||
|
||||
// NOTE: Deallocate the memory used in the request
|
||||
DN_Arena_PopTo(&request->arena, request->start_response_arena_pos);
|
||||
request->response.body = DN_Str8Builder_FromArena(&request->arena);
|
||||
DN_ArenaPopTo(&request->arena, request->start_response_arena_pos);
|
||||
request->response.body = DN_Str8BuilderFromArena(&request->arena);
|
||||
|
||||
// NOTE: For websocket requests, notify the NET thread we've read data from it and it can go
|
||||
// back to polling the socket for more data
|
||||
if (request->type == DN_NET2RequestType_WS && request->response.status != DN_NET2RequestStatus_Error) {
|
||||
DN_NET2RingEvent event = {};
|
||||
event.type = DN_NET2RingEventType_ReceivedWSReceipt;
|
||||
event.request = {DN_CAST(DN_U64)request};
|
||||
event.request = {DN_Cast(DN_U64)request};
|
||||
for (DN_OS_MutexScope(&net->ring_mutex))
|
||||
DN_Ring_WriteStruct(&net->ring, &event);
|
||||
curl_multi_wakeup(net->curlm);
|
||||
@ -55,7 +55,7 @@ static DN_NET2Response DN_NET2_WaitForResponse(DN_NET2Core *net, DN_NET2Request
|
||||
{
|
||||
DN_NET2Response result = {};
|
||||
if (request.handle != 0) {
|
||||
DN_NET2RequestInternal *request_ptr = DN_CAST(DN_NET2RequestInternal *) request.handle;
|
||||
DN_NET2RequestInternal *request_ptr = DN_Cast(DN_NET2RequestInternal *) request.handle;
|
||||
DN_OSSemaphoreWaitResult wait = DN_OS_SemaphoreWait(&request_ptr->completion_sem, timeout_ms);
|
||||
if (wait == DN_OSSemaphoreWaitResult_Success) {
|
||||
// NOTE: Fill in the result
|
||||
@ -64,19 +64,19 @@ static DN_NET2Response DN_NET2_WaitForResponse(DN_NET2Core *net, DN_NET2Request
|
||||
result.success = response->status != DN_NET2RequestStatus_Error;
|
||||
result.ws_type = response->ws_type;
|
||||
result.http_status = response->http_status;
|
||||
result.body = DN_Str8Builder_Build(&response->body, arena);
|
||||
result.body = DN_Str8BuilderBuild(&response->body, arena);
|
||||
if (response->error.size)
|
||||
result.error = DN_Str8_FromStr8(arena, response->error);
|
||||
result.error = DN_Str8FromStr8Arena(arena, response->error);
|
||||
|
||||
// NOTE: Deallocate the memory used in the request
|
||||
DN_Arena_PopTo(&request_ptr->arena, request_ptr->start_response_arena_pos);
|
||||
request_ptr->response.body = DN_Str8Builder_FromArena(&request_ptr->arena);
|
||||
DN_ArenaPopTo(&request_ptr->arena, request_ptr->start_response_arena_pos);
|
||||
request_ptr->response.body = DN_Str8BuilderFromArena(&request_ptr->arena);
|
||||
|
||||
// NOTE: Decrement the global completion tracking semaphore (this is so that if you waited on
|
||||
// the net object's semaphore, you don't get a phantom wakeup because this function already
|
||||
// consumed it).
|
||||
DN_OSSemaphoreWaitResult net_wait_result = DN_OS_SemaphoreWait(&net->completion_sem, 0 /*timeout_ms*/);
|
||||
DN_AssertF(net_wait_result == DN_OSSemaphoreWaitResult_Success, "Wait result was: %zu", DN_CAST(DN_USize)net_wait_result);
|
||||
DN_AssertF(net_wait_result == DN_OSSemaphoreWaitResult_Success, "Wait result was: %zu", DN_Cast(DN_USize)net_wait_result);
|
||||
|
||||
// NOTE: Remove the request from the done list
|
||||
for (DN_OS_MutexScope(&net->free_or_done_mutex)) {
|
||||
@ -119,18 +119,18 @@ static void DN_NET2_DeinitRequest(DN_NET2Core *net, DN_NET2Request *request)
|
||||
|
||||
static DN_USize DN_NET2_HTTPCallback_(char *payload, DN_USize size, DN_USize count, void *user_data)
|
||||
{
|
||||
auto *request = DN_CAST(DN_NET2RequestInternal *) user_data;
|
||||
auto *request = DN_Cast(DN_NET2RequestInternal *) user_data;
|
||||
DN_USize result = 0;
|
||||
DN_USize payload_size = size * count;
|
||||
if (DN_Str8Builder_AppendBytesCopy(&request->response.body, payload, payload_size))
|
||||
if (DN_Str8BuilderAppendBytesCopy(&request->response.body, payload, payload_size))
|
||||
result = payload_size;
|
||||
return result;
|
||||
}
|
||||
|
||||
static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
{
|
||||
DN_NET2Core *net = DN_CAST(DN_NET2Core *) thread->user_context;
|
||||
DN_OS_ThreadSetName(DN_Str8_Init(net->curl_thread.name.data, net->curl_thread.name.size));
|
||||
DN_NET2Core *net = DN_Cast(DN_NET2Core *) thread->user_context;
|
||||
DN_OS_ThreadSetName(DN_Str8FromPtr(net->curl_thread.name.data, net->curl_thread.name.size));
|
||||
|
||||
for (;;) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
@ -146,7 +146,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
case DN_NET2RingEventType_Nil: dequeue_ring = false; break;
|
||||
|
||||
case DN_NET2RingEventType_DoHTTP: {
|
||||
DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *)event.request.handle;
|
||||
DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *)event.request.handle;
|
||||
DN_Assert(request->response.status != DN_NET2RequestStatus_Error);
|
||||
switch (request->type) {
|
||||
case DN_NET2RequestType_Nil: {
|
||||
@ -156,7 +156,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
|
||||
case DN_NET2RequestType_HTTP: {
|
||||
DN_Assert(request->response.status == DN_NET2RequestStatus_Nil);
|
||||
DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context;
|
||||
DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context;
|
||||
CURLMcode multi_add = curl_multi_add_handle(net->curlm, conn->curl);
|
||||
DN_Assert(multi_add == CURLM_OK);
|
||||
DN_Assert(request->next == nullptr);
|
||||
@ -172,7 +172,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
DN_Assert(request->next == nullptr);
|
||||
DN_Assert(request->prev == nullptr);
|
||||
if (request->response.status == DN_NET2RequestStatus_Nil) {
|
||||
DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context;
|
||||
DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context;
|
||||
CURLMcode multi_add = curl_multi_add_handle(net->curlm, conn->curl);
|
||||
DN_Assert(multi_add == CURLM_OK);
|
||||
DN_DLList_Append(net->http_list, request); // Open the WS connection
|
||||
@ -187,7 +187,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
DN_Str8 payload = {};
|
||||
for (DN_OS_MutexScope(&net->ring_mutex)) {
|
||||
DN_Assert(DN_Ring_HasData(&net->ring, event.send_ws_payload_size));
|
||||
payload = DN_Str8_Alloc(tmem.arena, event.send_ws_payload_size, DN_ZeroMem_No);
|
||||
payload = DN_Str8FromArena(tmem.arena, event.send_ws_payload_size, DN_ZMem_No);
|
||||
DN_Ring_Read(&net->ring, payload.data, payload.size);
|
||||
}
|
||||
|
||||
@ -201,11 +201,11 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
case DN_NET2WSType_Pong: curlws_flag = CURLWS_PONG; break;
|
||||
}
|
||||
|
||||
DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *) event.request.handle;
|
||||
DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *) event.request.handle;
|
||||
DN_Assert(request->type == DN_NET2RequestType_WS);
|
||||
DN_Assert(request->response.status == DN_NET2RequestStatus_HTTPReceived || request->response.status == DN_NET2RequestStatus_WSReceived);
|
||||
|
||||
DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context;
|
||||
DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context;
|
||||
DN_USize sent = 0;
|
||||
CURLcode send_result = curl_ws_send(conn->curl, payload.data, payload.size, &sent, 0, curlws_flag);
|
||||
DN_AssertF(send_result == CURLE_OK, "Failed to send: %s", curl_easy_strerror(send_result));
|
||||
@ -213,7 +213,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
} break;
|
||||
|
||||
case DN_NET2RingEventType_ReceivedWSReceipt: {
|
||||
DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *) event.request.handle;
|
||||
DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *) event.request.handle;
|
||||
DN_Assert(request->type == DN_NET2RequestType_WS);
|
||||
DN_Assert(request->response.status == DN_NET2RequestStatus_WSReceived ||
|
||||
request->response.status == DN_NET2RequestStatus_HTTPReceived);
|
||||
@ -224,13 +224,13 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
|
||||
case DN_NET2RingEventType_DeinitRequest: {
|
||||
if (event.request.handle != 0) {
|
||||
DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *) event.request.handle;
|
||||
DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *) event.request.handle;
|
||||
request->response = {};
|
||||
|
||||
DN_Arena_Clear(&request->arena);
|
||||
DN_ArenaClear(&request->arena);
|
||||
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
||||
|
||||
DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context;
|
||||
DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context;
|
||||
curl_multi_remove_handle(net->curlm, conn->curl);
|
||||
curl_easy_reset(conn->curl);
|
||||
curl_slist_free_all(conn->curl_slist);
|
||||
@ -255,10 +255,10 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
if (msg) {
|
||||
// NOTE: Get request handle
|
||||
DN_NET2RequestInternal *request = nullptr;
|
||||
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, DN_CAST(void **) & request);
|
||||
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, DN_Cast(void **) & request);
|
||||
DN_Assert(request);
|
||||
|
||||
DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *)request->context;
|
||||
DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *)request->context;
|
||||
DN_Assert(conn->curl == msg->easy_handle);
|
||||
|
||||
if (msg->data.result == CURLE_OK) {
|
||||
@ -267,14 +267,14 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
if (get_result == CURLE_OK) {
|
||||
request->response.status = DN_NET2RequestStatus_HTTPReceived;
|
||||
} else {
|
||||
request->response.error = DN_Str8_FromF(&request->arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result));
|
||||
request->response.error = DN_Str8FromFmtArena(&request->arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result));
|
||||
request->response.status = DN_NET2RequestStatus_Error;
|
||||
}
|
||||
} else {
|
||||
request->response.status = DN_NET2RequestStatus_Error;
|
||||
request->response.error = DN_Str8_FromF(&request->arena,
|
||||
request->response.error = DN_Str8FromFmtArena(&request->arena,
|
||||
"Net request to '%.*s' failed (CURL %d): %s",
|
||||
DN_STR_FMT(request->url),
|
||||
DN_Str8PrintFmt(request->url),
|
||||
msg->data.result,
|
||||
curl_easy_strerror(msg->data.result));
|
||||
}
|
||||
@ -309,7 +309,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
const curl_ws_frame *meta = nullptr;
|
||||
size_t bytes_read_this_frame = {};
|
||||
|
||||
DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context;
|
||||
DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context;
|
||||
for (;;) {
|
||||
// NOTE: Determine WS payload size received
|
||||
DN_USize bytes_read = 0;
|
||||
@ -318,10 +318,10 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
break;
|
||||
|
||||
// NOTE: Allocate and read
|
||||
DN_Str8 buffer = DN_Str8_Alloc(&request->arena, meta->bytesleft, DN_ZeroMem_No);
|
||||
DN_Str8 buffer = DN_Str8FromArena(&request->arena, meta->bytesleft, DN_ZMem_No);
|
||||
receive_result = curl_ws_recv(conn->curl, buffer.data, buffer.size, &buffer.size, &meta);
|
||||
bytes_read_this_frame += buffer.size;
|
||||
DN_Str8Builder_AppendRef(&request->response.body, buffer);
|
||||
DN_Str8BuilderAppendRef(&request->response.body, buffer);
|
||||
|
||||
if (meta->flags & CURLWS_TEXT)
|
||||
request->response.ws_type = DN_NET2WSType_Text;
|
||||
@ -364,9 +364,9 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread)
|
||||
request->response.status = DN_NET2RequestStatus_WSReceived;
|
||||
if (receive_result != CURLE_OK) {
|
||||
request->response.status = DN_NET2RequestStatus_Error;
|
||||
request->response.error = DN_Str8_FromF(&request->arena,
|
||||
request->response.error = DN_Str8FromFmtArena(&request->arena,
|
||||
"Websocket failed to receive data for '%.*s' (CURL %d): %s",
|
||||
DN_STR_FMT(request->url),
|
||||
DN_Str8PrintFmt(request->url),
|
||||
receive_result,
|
||||
curl_easy_strerror(receive_result));
|
||||
}
|
||||
@ -385,25 +385,25 @@ static void DN_NET2_Init(DN_NET2Core *net, char *ring_base, DN_USize ring_size,
|
||||
{
|
||||
net->base = base;
|
||||
net->base_size = base_size;
|
||||
net->arena = DN_Arena_FromBuffer(net->base, net->base_size, DN_ArenaFlags_Nil);
|
||||
net->arena = DN_ArenaFromBuffer(net->base, net->base_size, DN_ArenaFlags_Nil);
|
||||
net->ring.base = ring_base;
|
||||
net->ring.size = ring_size;
|
||||
net->ring_mutex = DN_OS_MutexInit();
|
||||
net->completion_sem = DN_OS_SemaphoreInit(0);
|
||||
net->free_or_done_mutex = DN_OS_MutexInit();
|
||||
net->curlm = DN_CAST(CURLM *)curl_multi_init();
|
||||
net->curlm = DN_Cast(CURLM *)curl_multi_init();
|
||||
DN_DLList_InitArena(net->free_list, DN_NET2RequestInternal, &net->arena);
|
||||
DN_DLList_InitArena(net->http_list, DN_NET2RequestInternal, &net->arena);
|
||||
DN_DLList_InitArena(net->ws_list, DN_NET2RequestInternal, &net->arena);
|
||||
DN_DLList_InitArena(net->done_list, DN_NET2RequestInternal, &net->arena);
|
||||
|
||||
DN_IStr8_AppendF(&net->curl_thread.name, "NET (CURL)");
|
||||
DN_FmtAppend(net->curl_thread.name.data, &net->curl_thread.name.size, sizeof(net->curl_thread.name.data), "NET (CURL)");
|
||||
DN_OS_ThreadInit(&net->curl_thread, DN_NET2_ThreadEntryPoint_, net);
|
||||
}
|
||||
|
||||
static void DN_NET2_SetupCurlRequest_(DN_NET2RequestInternal *request)
|
||||
{
|
||||
DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context;
|
||||
DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context;
|
||||
CURL *curl = conn->curl;
|
||||
curl_easy_setopt(curl, CURLOPT_PRIVATE, request);
|
||||
|
||||
@ -430,13 +430,13 @@ static void DN_NET2_SetupCurlRequest_(DN_NET2RequestInternal *request)
|
||||
} break;
|
||||
|
||||
case DN_NET2RequestType_HTTP: {
|
||||
request->method = DN_Str8_TrimWhitespaceAround(request->method);
|
||||
DN_Str8 const GET = DN_STR8("GET");
|
||||
DN_Str8 const POST = DN_STR8("POST");
|
||||
request->method = DN_Str8TrimWhitespaceAround(request->method);
|
||||
DN_Str8 const GET = DN_Str8Lit("GET");
|
||||
DN_Str8 const POST = DN_Str8Lit("POST");
|
||||
|
||||
if (DN_Str8_EqInsensitive(request->method, GET)) {
|
||||
if (DN_Str8EqInsensitive(request->method, GET)) {
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1);
|
||||
} else if (DN_Str8_EqInsensitive(request->method, POST)) {
|
||||
} else if (DN_Str8EqInsensitive(request->method, POST)) {
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
||||
if (request->args.payload.size > DN_Gigabytes(2))
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, request->args.payload.size);
|
||||
@ -451,7 +451,7 @@ static void DN_NET2_SetupCurlRequest_(DN_NET2RequestInternal *request)
|
||||
|
||||
// NOTE: Handle basic auth
|
||||
if (request->args.flags & DN_NET2DoHTTPFlags_BasicAuth) {
|
||||
if (DN_Str8_HasData(request->args.username) && DN_Str8_HasData(request->args.password)) {
|
||||
if (request->args.username.size && request->args.password.size) {
|
||||
DN_Assert(request->args.username.data[request->args.username.size] == 0);
|
||||
DN_Assert(request->args.password.data[request->args.password.size] == 0);
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, request->args.username.data);
|
||||
@ -470,42 +470,42 @@ static DN_NET2Request DN_NET2_DoRequest_(DN_NET2Core *net, DN_Str8 url, DN_Str8
|
||||
DN_DLList_Dequeue(net->free_list, request);
|
||||
|
||||
if (!request) {
|
||||
request = DN_Arena_New(&net->arena, DN_NET2RequestInternal, DN_ZeroMem_Yes);
|
||||
request = DN_ArenaNew(&net->arena, DN_NET2RequestInternal, DN_ZMem_Yes);
|
||||
DN_NET2CurlConn *conn = new (request->context) DN_NET2CurlConn;
|
||||
conn->curl = DN_CAST(CURL *)curl_easy_init();
|
||||
conn->curl = DN_Cast(CURL *)curl_easy_init();
|
||||
}
|
||||
|
||||
// NOTE: Setup request
|
||||
DN_NET2Request result = {};
|
||||
if (request) {
|
||||
result.handle = DN_CAST(DN_U64) request;
|
||||
result.handle = DN_Cast(DN_U64) request;
|
||||
if (!request->arena.curr)
|
||||
request->arena = DN_Arena_FromVMem(DN_Megabytes(1), DN_Kilobytes(1), DN_ArenaFlags_Nil);
|
||||
request->arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(1), DN_ArenaFlags_Nil);
|
||||
|
||||
request->type = type;
|
||||
request->gen = DN_Max(request->gen + 1, 1);
|
||||
request->url = DN_Str8_FromStr8(&request->arena, url);
|
||||
request->method = DN_Str8_FromStr8(&request->arena, method);
|
||||
request->url = DN_Str8FromStr8Arena(&request->arena, url);
|
||||
request->method = DN_Str8FromStr8Arena(&request->arena, method);
|
||||
|
||||
if (args) {
|
||||
request->args.flags = args->flags;
|
||||
request->args.username = DN_Str8_FromStr8(&request->arena, args->username);
|
||||
request->args.password = DN_Str8_FromStr8(&request->arena, args->password);
|
||||
request->args.username = DN_Str8FromStr8Arena(&request->arena, args->username);
|
||||
request->args.password = DN_Str8FromStr8Arena(&request->arena, args->password);
|
||||
if (type == DN_NET2RequestType_HTTP)
|
||||
request->args.payload = DN_Str8_FromStr8(&request->arena, args->payload);
|
||||
request->args.payload = DN_Str8FromStr8Arena(&request->arena, args->payload);
|
||||
|
||||
request->args.headers = DN_Arena_NewArray(&request->arena, DN_Str8, args->headers_size, DN_ZeroMem_No);
|
||||
request->args.headers = DN_ArenaNewArray(&request->arena, DN_Str8, args->headers_size, DN_ZMem_No);
|
||||
DN_Assert(request->args.headers);
|
||||
if (request->args.headers) {
|
||||
for (DN_ForItSize(it, DN_Str8, args->headers, args->headers_size))
|
||||
request->args.headers[it.index] = DN_Str8_FromStr8(&request->arena, *it.data);
|
||||
request->args.headers[it.index] = DN_Str8FromStr8Arena(&request->arena, *it.data);
|
||||
request->args.headers_size = args->headers_size;
|
||||
}
|
||||
}
|
||||
|
||||
request->response.body = DN_Str8Builder_FromArena(&request->arena);
|
||||
request->response.body = DN_Str8BuilderFromArena(&request->arena);
|
||||
request->completion_sem = DN_OS_SemaphoreInit(0);
|
||||
request->start_response_arena_pos = DN_Arena_Pos(&request->arena);
|
||||
request->start_response_arena_pos = DN_ArenaPos(&request->arena);
|
||||
|
||||
DN_NET2_SetupCurlRequest_(request);
|
||||
|
||||
@ -530,7 +530,7 @@ static DN_NET2Request DN_NET2_DoHTTP(DN_NET2Core *net, DN_Str8 url, DN_Str8 meth
|
||||
|
||||
static DN_NET2Request DN_NET2_OpenWS(DN_NET2Core *net, DN_Str8 url, DN_NET2DoHTTPArgs const *args)
|
||||
{
|
||||
DN_NET2Request result = DN_NET2_DoRequest_(net, url, DN_STR8(""), args, DN_NET2RequestType_WS);
|
||||
DN_NET2Request result = DN_NET2_DoRequest_(net, url, DN_Str8Lit(""), args, DN_NET2RequestType_WS);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -303,6 +303,41 @@ static DN_UTCore DN_Tests_Base()
|
||||
DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_XSAVE) == DN_RefImplCPUReport::XSAVE());
|
||||
#endif
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Age")) {
|
||||
// NOTE: Seconds and milliseconds
|
||||
{
|
||||
DN_Str8x128 str8 = DN_AgeStr8FromMsU64(1001, DN_AgeUnit_Sec | DN_AgeUnit_Ms);
|
||||
DN_Str8 expect = DN_Str8Lit("1s 1ms");
|
||||
DN_UT_AssertF(&result, DN_MemEq(str8.data, str8.size, expect.data, expect.size), "str8=%.*s, expect=%.*s", DN_Str8PrintFmt(str8), DN_Str8PrintFmt(expect));
|
||||
}
|
||||
|
||||
// NOTE: Fractional seconds
|
||||
{
|
||||
DN_Str8x128 str8 = DN_AgeStr8FromMsU64(1001, DN_AgeUnit_FractionalSec);
|
||||
DN_Str8 expect = DN_Str8Lit("1.001s");
|
||||
DN_UT_AssertF(&result, DN_MemEq(str8.data, str8.size, expect.data, expect.size), "str8=%.*s, expect=%.*s", DN_Str8PrintFmt(str8), DN_Str8PrintFmt(expect));
|
||||
}
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "String")) {
|
||||
{
|
||||
DN_Str8x32 str8 = DN_Str8x32FromU64(123456, ' ');
|
||||
DN_Str8 expect = DN_Str8Lit("123 456");
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(DN_Str8FromStruct(&str8), expect), "buf_str8=%.*s, expect=%.*s", DN_Str8PrintFmt(str8), DN_Str8PrintFmt(expect));
|
||||
}
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Misc")) {
|
||||
{
|
||||
char buf[8] = {};
|
||||
DN_USize buf_size = 0;
|
||||
DN_FmtAppendResult buf_str8 = DN_FmtAppendTruncate(buf, &buf_size, sizeof(buf), DN_Str8Lit("..."), "This string is longer than %d characters", DN_Cast(int)(sizeof(buf) - 1));
|
||||
DN_Str8 expect = DN_Str8Lit("This..."); // 7 characters long, 1 byte reserved for null-terminator
|
||||
DN_UT_Assert(&result, buf_str8.truncated);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(buf_str8.str8, expect), "buf_str8=%.*s, expect=%.*s", DN_Str8PrintFmt(buf_str8.str8), DN_Str8PrintFmt(expect));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC)
|
||||
return result;
|
||||
@ -316,27 +351,27 @@ static DN_UTCore DN_Tests_Arena()
|
||||
for (DN_UT_Test(&result, "Reused memory is zeroed out")) {
|
||||
uint8_t alignment = 1;
|
||||
DN_USize alloc_size = DN_Kilobytes(128);
|
||||
DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
DN_DEFER
|
||||
{
|
||||
DN_Arena_Deinit(&arena);
|
||||
DN_ArenaDeinit(&arena);
|
||||
};
|
||||
|
||||
// NOTE: Allocate 128 kilobytes, fill it with garbage, then reset the arena
|
||||
uintptr_t first_ptr_address = 0;
|
||||
{
|
||||
DN_ArenaTempMem temp_mem = DN_Arena_TempMemBegin(&arena);
|
||||
void *ptr = DN_Arena_Alloc(&arena, alloc_size, alignment, DN_ZeroMem_Yes);
|
||||
first_ptr_address = DN_CAST(uintptr_t) ptr;
|
||||
DN_ArenaTempMem temp_mem = DN_ArenaTempMemBegin(&arena);
|
||||
void *ptr = DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes);
|
||||
first_ptr_address = DN_Cast(uintptr_t) ptr;
|
||||
DN_Memset(ptr, 'z', alloc_size);
|
||||
DN_Arena_TempMemEnd(temp_mem);
|
||||
DN_ArenaTempMemEnd(temp_mem);
|
||||
}
|
||||
|
||||
// NOTE: Reallocate 128 kilobytes
|
||||
char *ptr = DN_CAST(char *) DN_Arena_Alloc(&arena, alloc_size, alignment, DN_ZeroMem_Yes);
|
||||
char *ptr = DN_Cast(char *) DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes);
|
||||
|
||||
// NOTE: Double check we got the same pointer
|
||||
DN_UT_Assert(&result, first_ptr_address == DN_CAST(uintptr_t) ptr);
|
||||
DN_UT_Assert(&result, first_ptr_address == DN_Cast(uintptr_t) ptr);
|
||||
|
||||
// NOTE: Check that the bytes are set to 0
|
||||
for (DN_USize i = 0; i < alloc_size; i++)
|
||||
@ -345,56 +380,56 @@ static DN_UTCore DN_Tests_Arena()
|
||||
|
||||
for (DN_UT_Test(&result, "Test arena grows naturally, 1mb + 4mb")) {
|
||||
// NOTE: Allocate 1mb, then 4mb, this should force the arena to grow
|
||||
DN_Arena arena = DN_Arena_FromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil);
|
||||
DN_Arena arena = DN_ArenaFromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil);
|
||||
DN_DEFER
|
||||
{
|
||||
DN_Arena_Deinit(&arena);
|
||||
DN_ArenaDeinit(&arena);
|
||||
};
|
||||
|
||||
char *ptr_1mb = DN_Arena_NewArray(&arena, char, DN_Megabytes(1), DN_ZeroMem_Yes);
|
||||
char *ptr_4mb = DN_Arena_NewArray(&arena, char, DN_Megabytes(4), DN_ZeroMem_Yes);
|
||||
char *ptr_1mb = DN_ArenaNewArray(&arena, char, DN_Megabytes(1), DN_ZMem_Yes);
|
||||
char *ptr_4mb = DN_ArenaNewArray(&arena, char, DN_Megabytes(4), DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, ptr_1mb);
|
||||
DN_UT_Assert(&result, ptr_4mb);
|
||||
|
||||
DN_ArenaBlock const *block_4mb_begin = arena.curr;
|
||||
char const *block_4mb_end = DN_CAST(char *) block_4mb_begin + block_4mb_begin->reserve;
|
||||
char const *block_4mb_end = DN_Cast(char *) block_4mb_begin + block_4mb_begin->reserve;
|
||||
|
||||
DN_ArenaBlock const *block_1mb_begin = block_4mb_begin->prev;
|
||||
DN_UT_AssertF(&result, block_1mb_begin, "New block should have been allocated");
|
||||
char const *block_1mb_end = DN_CAST(char *) block_1mb_begin + block_1mb_begin->reserve;
|
||||
char const *block_1mb_end = DN_Cast(char *) block_1mb_begin + block_1mb_begin->reserve;
|
||||
|
||||
DN_UT_AssertF(&result, block_1mb_begin != block_4mb_begin, "New block should have been allocated and linked");
|
||||
DN_UT_AssertF(&result, ptr_1mb >= DN_CAST(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block");
|
||||
DN_UT_AssertF(&result, ptr_4mb >= DN_CAST(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block");
|
||||
DN_UT_AssertF(&result, ptr_1mb >= DN_Cast(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block");
|
||||
DN_UT_AssertF(&result, ptr_4mb >= DN_Cast(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block");
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Test arena grows naturally, 1mb, temp memory 4mb")) {
|
||||
DN_Arena arena = DN_Arena_FromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil);
|
||||
DN_Arena arena = DN_ArenaFromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil);
|
||||
DN_DEFER
|
||||
{
|
||||
DN_Arena_Deinit(&arena);
|
||||
DN_ArenaDeinit(&arena);
|
||||
};
|
||||
|
||||
// NOTE: Allocate 1mb, then 4mb, this should force the arena to grow
|
||||
char *ptr_1mb = DN_CAST(char *) DN_Arena_Alloc(&arena, DN_Megabytes(1), 1 /*align*/, DN_ZeroMem_Yes);
|
||||
char *ptr_1mb = DN_Cast(char *) DN_ArenaAlloc(&arena, DN_Megabytes(1), 1 /*align*/, DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, ptr_1mb);
|
||||
|
||||
DN_ArenaTempMem temp_memory = DN_Arena_TempMemBegin(&arena);
|
||||
DN_ArenaTempMem temp_memory = DN_ArenaTempMemBegin(&arena);
|
||||
{
|
||||
char *ptr_4mb = DN_Arena_NewArray(&arena, char, DN_Megabytes(4), DN_ZeroMem_Yes);
|
||||
char *ptr_4mb = DN_ArenaNewArray(&arena, char, DN_Megabytes(4), DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, ptr_4mb);
|
||||
|
||||
DN_ArenaBlock const *block_4mb_begin = arena.curr;
|
||||
char const *block_4mb_end = DN_CAST(char *) block_4mb_begin + block_4mb_begin->reserve;
|
||||
char const *block_4mb_end = DN_Cast(char *) block_4mb_begin + block_4mb_begin->reserve;
|
||||
|
||||
DN_ArenaBlock const *block_1mb_begin = block_4mb_begin->prev;
|
||||
char const *block_1mb_end = DN_CAST(char *) block_1mb_begin + block_1mb_begin->reserve;
|
||||
char const *block_1mb_end = DN_Cast(char *) block_1mb_begin + block_1mb_begin->reserve;
|
||||
|
||||
DN_UT_AssertF(&result, block_1mb_begin != block_4mb_begin, "New block should have been allocated and linked");
|
||||
DN_UT_AssertF(&result, ptr_1mb >= DN_CAST(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block");
|
||||
DN_UT_AssertF(&result, ptr_4mb >= DN_CAST(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block");
|
||||
DN_UT_AssertF(&result, ptr_1mb >= DN_Cast(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block");
|
||||
DN_UT_AssertF(&result, ptr_4mb >= DN_Cast(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block");
|
||||
}
|
||||
DN_Arena_TempMemEnd(temp_memory);
|
||||
DN_ArenaTempMemEnd(temp_memory);
|
||||
DN_UT_Assert(&result, arena.curr->prev == nullptr);
|
||||
DN_UT_AssertF(&result,
|
||||
arena.curr->reserve >= DN_Megabytes(1),
|
||||
@ -414,79 +449,80 @@ static DN_UTCore DN_Tests_Bin()
|
||||
DN_UT_LogF(&test, "DN_Bin\n");
|
||||
{
|
||||
for (DN_UT_Test(&test, "Convert 0x123")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("0x123"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0x123"));
|
||||
DN_UT_AssertF(&test, result == 0x123, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert 0xFFFF")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("0xFFFF"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0xFFFF"));
|
||||
DN_UT_AssertF(&test, result == 0xFFFF, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert FFFF")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("FFFF"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("FFFF"));
|
||||
DN_UT_AssertF(&test, result == 0xFFFF, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert abCD")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("abCD"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("abCD"));
|
||||
DN_UT_AssertF(&test, result == 0xabCD, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert 0xabCD")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("0xabCD"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0xabCD"));
|
||||
DN_UT_AssertF(&test, result == 0xabCD, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert 0x")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("0x"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0x"));
|
||||
DN_UT_AssertF(&test, result == 0x0, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert 0X")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("0X"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0X"));
|
||||
DN_UT_AssertF(&test, result == 0x0, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert 3")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("3"));
|
||||
uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("3"));
|
||||
DN_UT_AssertF(&test, result == 3, "result: %" PRIu64, result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert f")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("f"));
|
||||
DN_UT_AssertF(&test, result == 0xf, "result: %" PRIu64, result);
|
||||
DN_U64FromResult result = DN_U64FromHexStr8(DN_Str8Lit("f"));
|
||||
DN_UT_Assert(&test, result.success);
|
||||
DN_UT_Assert(&test, result.value == 0xf);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert g")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("g"));
|
||||
DN_UT_AssertF(&test, result == 0, "result: %" PRIu64, result);
|
||||
DN_U64FromResult result = DN_U64FromHexStr8(DN_Str8Lit("g"));
|
||||
DN_UT_Assert(&test, !result.success);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&test, "Convert -0x3")) {
|
||||
uint64_t result = DN_CVT_U64FromHex(DN_STR8("-0x3"));
|
||||
DN_UT_AssertF(&test, result == 0, "result: %" PRIu64, result);
|
||||
DN_U64FromResult result = DN_U64FromHexStr8(DN_Str8Lit("-0x3"));
|
||||
DN_UT_Assert(&test, !result.success);
|
||||
}
|
||||
|
||||
uint32_t number = 0xd095f6;
|
||||
for (DN_UT_Test(&test, "Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_CVT_HexFromBytes(tmem.arena, &number, sizeof(number));
|
||||
DN_UT_AssertF(&test, DN_Str8_Eq(number_hex, DN_STR8("f695d000")), "number_hex=%.*s", DN_STR_FMT(number_hex));
|
||||
DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), tmem.arena);
|
||||
DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("f695d000")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex));
|
||||
}
|
||||
|
||||
number = 0xf6ed00;
|
||||
for (DN_UT_Test(&test, "Convert %x to string", number)) {
|
||||
DN_Str8 number_hex = DN_CVT_HexFromBytes(tmem.arena, &number, sizeof(number));
|
||||
DN_UT_AssertF(&test, DN_Str8_Eq(number_hex, DN_STR8("00edf600")), "number_hex=%.*s", DN_STR_FMT(number_hex));
|
||||
DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), tmem.arena);
|
||||
DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("00edf600")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex));
|
||||
}
|
||||
|
||||
DN_Str8 hex = DN_STR8("0xf6ed00");
|
||||
for (DN_UT_Test(&test, "Convert %.*s to bytes", DN_STR_FMT(hex))) {
|
||||
DN_Str8 bytes = DN_CVT_BytesFromHex(tmem.arena, hex);
|
||||
DN_Str8 hex = DN_Str8Lit("0xf6ed00");
|
||||
for (DN_UT_Test(&test, "Convert %.*s to bytes", DN_Str8PrintFmt(hex))) {
|
||||
DN_Str8 bytes = DN_BytesFromHexStr8Arena(hex, tmem.arena);
|
||||
DN_UT_AssertF(&test,
|
||||
DN_Str8_Eq(bytes, DN_STR8("\xf6\xed\x00")),
|
||||
DN_Str8Eq(bytes, DN_Str8Lit("\xf6\xed\x00")),
|
||||
"number_hex=%.*s",
|
||||
DN_STR_FMT(DN_CVT_HexFromBytes(tmem.arena, bytes.data, bytes.size)));
|
||||
DN_Str8PrintFmt(DN_HexFromBytesPtrArena(bytes.data, bytes.size, tmem.arena)));
|
||||
}
|
||||
}
|
||||
return test;
|
||||
@ -808,16 +844,16 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
{
|
||||
DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
uint32_t const MAP_SIZE = 64;
|
||||
DN_DSMap<uint64_t> map = DN_DSMap_Init<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
|
||||
DN_DEFER
|
||||
{
|
||||
DN_DSMap_Deinit(&map, DN_ZeroMem_Yes);
|
||||
DN_DSMap_Deinit(&map, DN_ZMem_Yes);
|
||||
};
|
||||
|
||||
for (DN_UT_Test(&result, "Find non-existent value")) {
|
||||
DN_DSMapResult<uint64_t> find = DN_DSMap_FindKeyStr8(&map, DN_STR8("Foo"));
|
||||
DN_DSMapResult<uint64_t> find = DN_DSMap_FindKeyStr8(&map, DN_Str8Lit("Foo"));
|
||||
DN_UT_Assert(&result, !find.found);
|
||||
DN_UT_Assert(&result, map.size == MAP_SIZE);
|
||||
DN_UT_Assert(&result, map.initial_size == MAP_SIZE);
|
||||
@ -856,20 +892,20 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
for (int result_type = 0; result_type < DSMapTestType_Count; result_type++) {
|
||||
DN_Str8 prefix = {};
|
||||
switch (result_type) {
|
||||
case DSMapTestType_Set: prefix = DN_STR8("Set"); break;
|
||||
case DSMapTestType_MakeSlot: prefix = DN_STR8("Make slot"); break;
|
||||
case DSMapTestType_Set: prefix = DN_Str8Lit("Set"); break;
|
||||
case DSMapTestType_MakeSlot: prefix = DN_Str8Lit("Make slot"); break;
|
||||
}
|
||||
|
||||
DN_ArenaTempMemScope temp_mem_scope = DN_ArenaTempMemScope(tmem.arena);
|
||||
DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
|
||||
uint32_t const MAP_SIZE = 64;
|
||||
DN_DSMap<uint64_t> map = DN_DSMap_Init<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
|
||||
DN_DEFER
|
||||
{
|
||||
DN_DSMap_Deinit(&map, DN_ZeroMem_Yes);
|
||||
DN_DSMap_Deinit(&map, DN_ZMem_Yes);
|
||||
};
|
||||
|
||||
for (DN_UT_Test(&result, "%.*s: Test growing", DN_STR_FMT(prefix))) {
|
||||
for (DN_UT_Test(&result, "%.*s: Test growing", DN_Str8PrintFmt(prefix))) {
|
||||
uint64_t map_start_size = map.size;
|
||||
uint64_t value = 0;
|
||||
uint64_t grow_threshold = map_start_size * 3 / 4;
|
||||
@ -904,13 +940,13 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
}
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "%.*s: Check the sentinel is present", DN_STR_FMT(prefix))) {
|
||||
for (DN_UT_Test(&result, "%.*s: Check the sentinel is present", DN_Str8PrintFmt(prefix))) {
|
||||
DN_DSMapSlot<uint64_t> NIL_SLOT = {};
|
||||
DN_DSMapSlot<uint64_t> sentinel = map.slots[DN_DS_MAP_SENTINEL_SLOT];
|
||||
DN_UT_Assert(&result, DN_Memcmp(&sentinel, &NIL_SLOT, sizeof(NIL_SLOT)) == 0);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "%.*s: Recheck all the hash tables values after growing", DN_STR_FMT(prefix))) {
|
||||
for (DN_UT_Test(&result, "%.*s: Recheck all the hash tables values after growing", DN_Str8PrintFmt(prefix))) {
|
||||
for (uint64_t index = 1 /*Sentinel*/; index < map.occupied; index++) {
|
||||
DN_DSMapSlot<uint64_t> const *slot = map.slots + index;
|
||||
|
||||
@ -930,7 +966,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
}
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "%.*s: Test shrinking", DN_STR_FMT(prefix))) {
|
||||
for (DN_UT_Test(&result, "%.*s: Test shrinking", DN_Str8PrintFmt(prefix))) {
|
||||
uint64_t start_map_size = map.size;
|
||||
uint64_t start_map_occupied = map.occupied;
|
||||
uint64_t value = 0;
|
||||
@ -1008,7 +1044,7 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
array.max = DN_ArrayCountU(array_buffer);
|
||||
|
||||
for (DN_UT_Test(&result, "Make item")) {
|
||||
int *item = DN_IArray_Make(&array, DN_ZeroMem_Yes);
|
||||
int *item = DN_IArray_Make(&array, DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, item && array.size == 1);
|
||||
}
|
||||
}
|
||||
@ -1307,8 +1343,8 @@ static DN_UTCore DN_Tests_BaseContainers()
|
||||
|
||||
// NOTE: Verify that the items returned from the data array are
|
||||
// contiguous in memory.
|
||||
UnalignedObject *make_item_a = DN_VArray_MakeArray(&array, 1, DN_ZeroMem_Yes);
|
||||
UnalignedObject *make_item_b = DN_VArray_MakeArray(&array, 1, DN_ZeroMem_Yes);
|
||||
UnalignedObject *make_item_a = DN_VArray_MakeArray(&array, 1, DN_ZMem_Yes);
|
||||
UnalignedObject *make_item_b = DN_VArray_MakeArray(&array, 1, DN_ZMem_Yes);
|
||||
DN_Memset(make_item_a->data, 'a', sizeof(make_item_a->data));
|
||||
DN_Memset(make_item_b->data, 'b', sizeof(make_item_b->data));
|
||||
DN_UT_Assert(&result, (uintptr_t)make_item_b == (uintptr_t)(make_item_a + 1));
|
||||
@ -1387,7 +1423,7 @@ static DN_UTCore DN_Tests_Intrinsics()
|
||||
for (DN_UT_Test(&result, "DN_AtomicSetValue64")) {
|
||||
int64_t a = 0;
|
||||
int64_t b = 111;
|
||||
DN_AtomicSetValue64(DN_CAST(uint64_t *) & a, b);
|
||||
DN_AtomicSetValue64(DN_Cast(uint64_t *) & a, b);
|
||||
DN_UT_AssertF(&result, a == b, "a: %" PRId64 ", b: %" PRId64, a, b);
|
||||
}
|
||||
|
||||
@ -1603,7 +1639,7 @@ enum DN_Tests__HashType
|
||||
|
||||
DN_Str8 const DN_UT_HASH_STRING_[] =
|
||||
{
|
||||
#define DN_UT_HASH_X_ENTRY(enum_val, string) DN_STR8(string),
|
||||
#define DN_UT_HASH_X_ENTRY(enum_val, string) DN_Str8Lit(string),
|
||||
DN_UT_HASH_X_MACRO
|
||||
#undef DN_UT_HASH_X_ENTRY
|
||||
};
|
||||
@ -1617,13 +1653,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_SHA3_224: {
|
||||
DN_KCBytes28 hash = DN_KC_SHA3_224Str8(input);
|
||||
DN_KCBytes28 expect;
|
||||
DN_RefImpl_FIPS202_SHA3_224_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_RefImpl_FIPS202_SHA3_224_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes28Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&hash).data),
|
||||
DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1631,13 +1667,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_SHA3_256: {
|
||||
DN_KCBytes32 hash = DN_KC_SHA3_256Str8(input);
|
||||
DN_KCBytes32 expect;
|
||||
DN_RefImpl_FIPS202_SHA3_256_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_RefImpl_FIPS202_SHA3_256_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes32Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&hash).data),
|
||||
DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1645,13 +1681,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_SHA3_384: {
|
||||
DN_KCBytes48 hash = DN_KC_SHA3_384Str8(input);
|
||||
DN_KCBytes48 expect;
|
||||
DN_RefImpl_FIPS202_SHA3_384_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_RefImpl_FIPS202_SHA3_384_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes48Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&hash).data),
|
||||
DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1659,13 +1695,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_SHA3_512: {
|
||||
DN_KCBytes64 hash = DN_KC_SHA3_512Str8(input);
|
||||
DN_KCBytes64 expect;
|
||||
DN_RefImpl_FIPS202_SHA3_512_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_RefImpl_FIPS202_SHA3_512_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data);
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes64Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&hash).data),
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1673,13 +1709,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_Keccak_224: {
|
||||
DN_KCBytes28 hash = DN_KC_Keccak224Str8(input);
|
||||
DN_KCBytes28 expect;
|
||||
DN_RefImpl_Keccak_(1152, 448, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_RefImpl_Keccak_(1152, 448, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes28Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&hash).data),
|
||||
DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1687,13 +1723,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_Keccak_256: {
|
||||
DN_KCBytes32 hash = DN_KC_Keccak256Str8(input);
|
||||
DN_KCBytes32 expect;
|
||||
DN_RefImpl_Keccak_(1088, 512, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_RefImpl_Keccak_(1088, 512, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes32Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&hash).data),
|
||||
DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1701,13 +1737,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_Keccak_384: {
|
||||
DN_KCBytes48 hash = DN_KC_Keccak384Str8(input);
|
||||
DN_KCBytes48 expect;
|
||||
DN_RefImpl_Keccak_(832, 768, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_RefImpl_Keccak_(832, 768, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes48Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&hash).data),
|
||||
DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1715,13 +1751,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
case Hash_Keccak_512: {
|
||||
DN_KCBytes64 hash = DN_KC_Keccak512Str8(input);
|
||||
DN_KCBytes64 expect;
|
||||
DN_RefImpl_Keccak_(576, 1024, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_RefImpl_Keccak_(576, 1024, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect));
|
||||
DN_UT_AssertF(test,
|
||||
DN_KC_Bytes64Equals(&hash, &expect),
|
||||
"\ninput: %.*s"
|
||||
"\nhash: %.*s"
|
||||
"\nexpect: %.*s",
|
||||
DN_STR_FMT(input_hex),
|
||||
DN_Str8PrintFmt(input_hex),
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&hash).data),
|
||||
DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&expect).data));
|
||||
} break;
|
||||
@ -1732,10 +1768,10 @@ DN_UTCore DN_Tests_Keccak()
|
||||
{
|
||||
DN_UTCore test = DN_UT_Init();
|
||||
DN_Str8 const INPUTS[] = {
|
||||
DN_STR8("abc"),
|
||||
DN_STR8(""),
|
||||
DN_STR8("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
|
||||
DN_STR8("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmno"
|
||||
DN_Str8Lit("abc"),
|
||||
DN_Str8Lit(""),
|
||||
DN_Str8Lit("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
|
||||
DN_Str8Lit("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmno"
|
||||
"pqrstnopqrstu"),
|
||||
};
|
||||
|
||||
@ -1744,20 +1780,20 @@ DN_UTCore DN_Tests_Keccak()
|
||||
for (int hash_type = 0; hash_type < Hash_Count; hash_type++) {
|
||||
DN_PCG32 rng = DN_PCG32_Init(0xd48e'be21'2af8'733d);
|
||||
for (DN_Str8 input : INPUTS) {
|
||||
DN_UT_BeginF(&test, "%.*s - Input: %.*s", DN_STR_FMT(DN_UT_HASH_STRING_[hash_type]), DN_CAST(int) DN_Min(input.size, 54), input.data);
|
||||
DN_UT_BeginF(&test, "%.*s - Input: %.*s", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type]), DN_Cast(int) DN_Min(input.size, 54), input.data);
|
||||
DN_Tests_KeccakDispatch_(&test, hash_type, input);
|
||||
DN_UT_End(&test);
|
||||
}
|
||||
|
||||
DN_UT_BeginF(&test, "%.*s - Deterministic random inputs", DN_STR_FMT(DN_UT_HASH_STRING_[hash_type]));
|
||||
DN_UT_BeginF(&test, "%.*s - Deterministic random inputs", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type]));
|
||||
for (DN_USize index = 0; index < 128; index++) {
|
||||
char src[4096] = {};
|
||||
uint32_t src_size = DN_PCG32_Range(&rng, 0, sizeof(src));
|
||||
|
||||
for (DN_USize src_index = 0; src_index < src_size; src_index++)
|
||||
src[src_index] = DN_CAST(char) DN_PCG32_Range(&rng, 0, 255);
|
||||
src[src_index] = DN_Cast(char) DN_PCG32_Range(&rng, 0, 255);
|
||||
|
||||
DN_Str8 input = DN_Str8_Init(src, src_size);
|
||||
DN_Str8 input = DN_Str8FromPtr(src, src_size);
|
||||
DN_Tests_KeccakDispatch_(&test, hash_type, input);
|
||||
}
|
||||
DN_UT_End(&test);
|
||||
@ -1813,8 +1849,8 @@ static DN_UTCore DN_Tests_OS()
|
||||
for (DN_UT_Test(&result, "Query executable directory")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 os_result = DN_OS_EXEDir(tmem.arena);
|
||||
DN_UT_Assert(&result, DN_Str8_HasData(os_result));
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_STR_FMT(os_result));
|
||||
DN_UT_Assert(&result, os_result.size);
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_Str8PrintFmt(os_result));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "DN_OS_PerfCounterNow")) {
|
||||
@ -1844,37 +1880,37 @@ static DN_UTCore DN_Tests_OS()
|
||||
DN_UT_LogF(&result, "\nDN_OS Filesystem\n");
|
||||
{
|
||||
for (DN_UT_Test(&result, "Make directory recursive \"abcd/efgh\"")) {
|
||||
DN_UT_AssertF(&result, DN_OS_PathMakeDir(DN_STR8("abcd/efgh")), "Failed to make directory");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_STR8("abcd")), "Directory was not made");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_STR8("abcd/efgh")), "Subdirectory was not made");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_STR8("abcd")) == false, "This function should only return true for files");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_STR8("abcd/efgh")) == false, "This function should only return true for files");
|
||||
DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd/efgh")), "Failed to delete directory");
|
||||
DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd")), "Failed to cleanup directory");
|
||||
DN_UT_AssertF(&result, DN_OS_PathMakeDir(DN_Str8Lit("abcd/efgh")), "Failed to make directory");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_Str8Lit("abcd")), "Directory was not made");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_Str8Lit("abcd/efgh")), "Subdirectory was not made");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_Str8Lit("abcd")) == false, "This function should only return true for files");
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_Str8Lit("abcd/efgh")) == false, "This function should only return true for files");
|
||||
DN_UT_AssertF(&result, DN_OS_PathDelete(DN_Str8Lit("abcd/efgh")), "Failed to delete directory");
|
||||
DN_UT_AssertF(&result, DN_OS_PathDelete(DN_Str8Lit("abcd")), "Failed to cleanup directory");
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "File write, read, copy, move and delete")) {
|
||||
// NOTE: Write step
|
||||
DN_Str8 const SRC_FILE = DN_STR8("dn_result_file");
|
||||
DN_B32 write_result = DN_OS_FileWriteAll(SRC_FILE, DN_STR8("1234"), nullptr);
|
||||
DN_Str8 const SRC_FILE = DN_Str8Lit("dn_result_file");
|
||||
DN_B32 write_result = DN_OS_FileWriteAll(SRC_FILE, DN_Str8Lit("1234"), nullptr);
|
||||
DN_UT_Assert(&result, write_result);
|
||||
DN_UT_Assert(&result, DN_OS_PathIsFile(SRC_FILE));
|
||||
|
||||
// NOTE: Read step
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 read_file = DN_OS_FileReadAllArena(tmem.arena, SRC_FILE, nullptr);
|
||||
DN_UT_AssertF(&result, DN_Str8_HasData(read_file), "Failed to load file");
|
||||
DN_UT_AssertF(&result, read_file.size, "Failed to load file");
|
||||
DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size);
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(read_file, DN_STR8("1234")), "Read %zu bytes instead of the expected 4: '%.*s'", read_file.size, DN_STR_FMT(read_file));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(read_file, DN_Str8Lit("1234")), "Read %zu bytes instead of the expected 4: '%.*s'", read_file.size, DN_Str8PrintFmt(read_file));
|
||||
|
||||
// NOTE: Copy step
|
||||
DN_Str8 const COPY_FILE = DN_STR8("dn_result_file_copy");
|
||||
DN_Str8 const COPY_FILE = DN_Str8Lit("dn_result_file_copy");
|
||||
DN_B32 copy_result = DN_OS_FileCopy(SRC_FILE, COPY_FILE, true /*overwrite*/, nullptr);
|
||||
DN_UT_Assert(&result, copy_result);
|
||||
DN_UT_Assert(&result, DN_OS_PathIsFile(COPY_FILE));
|
||||
|
||||
// NOTE: Move step
|
||||
DN_Str8 const MOVE_FILE = DN_STR8("dn_result_file_move");
|
||||
DN_Str8 const MOVE_FILE = DN_Str8Lit("dn_result_file_move");
|
||||
DN_B32 move_result = DN_OS_FileMove(COPY_FILE, MOVE_FILE, true /*overwrite*/, nullptr);
|
||||
DN_UT_Assert(&result, move_result);
|
||||
DN_UT_Assert(&result, DN_OS_PathIsFile(MOVE_FILE));
|
||||
@ -2079,7 +2115,7 @@ static DN_UTCore DN_Tests_Str8()
|
||||
DN_UT_LogF(&result, "DN_Str8\n");
|
||||
{
|
||||
for (DN_UT_Test(&result, "Initialise with string literal w/ macro")) {
|
||||
DN_Str8 string = DN_STR8("AB");
|
||||
DN_Str8 string = DN_Str8Lit("AB");
|
||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||
DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]);
|
||||
DN_UT_AssertF(&result, string.data[1] == 'B', "string[1]: %c", string.data[1]);
|
||||
@ -2087,7 +2123,7 @@ static DN_UTCore DN_Tests_Str8()
|
||||
|
||||
for (DN_UT_Test(&result, "Initialise with format string")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8_FromF(tmem.arena, "%s", "AB");
|
||||
DN_Str8 string = DN_Str8FromFmtArena(tmem.arena, "%s", "AB");
|
||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||
DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]);
|
||||
DN_UT_AssertF(&result, string.data[1] == 'B', "string[1]: %c", string.data[1]);
|
||||
@ -2096,8 +2132,8 @@ static DN_UTCore DN_Tests_Str8()
|
||||
|
||||
for (DN_UT_Test(&result, "Copy string")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_STR8("AB");
|
||||
DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, string);
|
||||
DN_Str8 string = DN_Str8Lit("AB");
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, string);
|
||||
DN_UT_AssertF(&result, copy.size == 2, "size: %zu", copy.size);
|
||||
DN_UT_AssertF(&result, copy.data[0] == 'A', "copy[0]: %c", copy.data[0]);
|
||||
DN_UT_AssertF(&result, copy.data[1] == 'B', "copy[1]: %c", copy.data[1]);
|
||||
@ -2105,226 +2141,209 @@ static DN_UTCore DN_Tests_Str8()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Trim whitespace around string")) {
|
||||
DN_Str8 string = DN_Str8_TrimWhitespaceAround(DN_STR8(" AB "));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(string, DN_STR8("AB")), "[string=%.*s]", DN_STR_FMT(string));
|
||||
DN_Str8 string = DN_Str8TrimWhitespaceAround(DN_Str8Lit(" AB "));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(string, DN_Str8Lit("AB")), "[string=%.*s]", DN_Str8PrintFmt(string));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Allocate string from arena")) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 string = DN_Str8_Alloc(tmem.arena, 2, DN_ZeroMem_No);
|
||||
DN_Str8 string = DN_Str8FromArena(tmem.arena, 2, DN_ZMem_No);
|
||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||
}
|
||||
|
||||
// NOTE: TrimPrefix/Suffix /////////////////////////////////////////////////////////////////////
|
||||
for (DN_UT_Test(&result, "Trim prefix with matching prefix")) {
|
||||
DN_Str8 input = DN_STR8("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8_TrimPrefix(input, DN_STR8("nft/"));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(str_result, DN_STR8("abc")), "%.*s", DN_STR_FMT(str_result));
|
||||
DN_Str8 input = DN_Str8Lit("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8TrimPrefix(input, DN_Str8Lit("nft/"));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("abc")), "%.*s", DN_Str8PrintFmt(str_result));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Trim prefix with non matching prefix")) {
|
||||
DN_Str8 input = DN_STR8("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8_TrimPrefix(input, DN_STR8(" ft/"));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(str_result, input), "%.*s", DN_STR_FMT(str_result));
|
||||
DN_Str8 input = DN_Str8Lit("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8TrimPrefix(input, DN_Str8Lit(" ft/"));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(str_result, input), "%.*s", DN_Str8PrintFmt(str_result));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Trim suffix with matching suffix")) {
|
||||
DN_Str8 input = DN_STR8("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8_TrimSuffix(input, DN_STR8("abc"));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(str_result, DN_STR8("nft/")), "%.*s", DN_STR_FMT(str_result));
|
||||
DN_Str8 input = DN_Str8Lit("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8TrimSuffix(input, DN_Str8Lit("abc"));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("nft/")), "%.*s", DN_Str8PrintFmt(str_result));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Trim suffix with non matching suffix")) {
|
||||
DN_Str8 input = DN_STR8("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8_TrimSuffix(input, DN_STR8("ab"));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(str_result, input), "%.*s", DN_STR_FMT(str_result));
|
||||
DN_Str8 input = DN_Str8Lit("nft/abc");
|
||||
DN_Str8 str_result = DN_Str8TrimSuffix(input, DN_Str8Lit("ab"));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(str_result, input), "%.*s", DN_Str8PrintFmt(str_result));
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_IsAllDigits //////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8IsAllDigits //////////////////////////////////////////////////////////////
|
||||
for (DN_UT_Test(&result, "Is all digits fails on non-digit string")) {
|
||||
DN_B32 str_result = DN_Str8_IsAll(DN_STR8("@123string"), DN_Str8IsAll_Digits);
|
||||
DN_B32 str_result = DN_Str8IsAll(DN_Str8Lit("@123string"), DN_Str8IsAllType_Digits);
|
||||
DN_UT_Assert(&result, str_result == false);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Is all digits fails on nullptr")) {
|
||||
DN_B32 str_result = DN_Str8_IsAll(DN_Str8_Init(nullptr, 0), DN_Str8IsAll_Digits);
|
||||
DN_UT_Assert(&result, str_result == false);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Is all digits fails on nullptr w/ size")) {
|
||||
DN_B32 str_result = DN_Str8_IsAll(DN_Str8_Init(nullptr, 1), DN_Str8IsAll_Digits);
|
||||
DN_B32 str_result = DN_Str8IsAll(DN_Str8FromPtr(nullptr, 0), DN_Str8IsAllType_Digits);
|
||||
DN_UT_Assert(&result, str_result == false);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Is all digits fails on string w/ 0 size")) {
|
||||
char const buf[] = "@123string";
|
||||
DN_B32 str_result = DN_Str8_IsAll(DN_Str8_Init(buf, 0), DN_Str8IsAll_Digits);
|
||||
DN_B32 str_result = DN_Str8IsAll(DN_Str8FromPtr(buf, 0), DN_Str8IsAllType_Digits);
|
||||
DN_UT_Assert(&result, !str_result);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Is all digits success")) {
|
||||
DN_B32 str_result = DN_Str8_IsAll(DN_STR8("23"), DN_Str8IsAll_Digits);
|
||||
DN_UT_Assert(&result, DN_CAST(bool) str_result == true);
|
||||
DN_B32 str_result = DN_Str8IsAll(DN_Str8Lit("23"), DN_Str8IsAllType_Digits);
|
||||
DN_UT_Assert(&result, DN_Cast(bool) str_result == true);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Is all digits fails on whitespace")) {
|
||||
DN_B32 str_result = DN_Str8_IsAll(DN_STR8("23 "), DN_Str8IsAll_Digits);
|
||||
DN_UT_Assert(&result, DN_CAST(bool) str_result == false);
|
||||
DN_B32 str_result = DN_Str8IsAll(DN_Str8Lit("23 "), DN_Str8IsAllType_Digits);
|
||||
DN_UT_Assert(&result, DN_Cast(bool) str_result == false);
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_BSplit ///////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8BSplit ///////////////////////////////////////////////////////////////////
|
||||
{
|
||||
{
|
||||
char const *TEST_FMT = "Binary split \"%.*s\" with \"%.*s\"";
|
||||
DN_Str8 delimiter = DN_STR8("/");
|
||||
DN_Str8 input = DN_STR8("abcdef");
|
||||
for (DN_UT_Test(&result, TEST_FMT, DN_STR_FMT(input), DN_STR_FMT(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("abcdef")), "[lhs=%.*s]", DN_STR_FMT(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("")), "[rhs=%.*s]", DN_STR_FMT(split.rhs));
|
||||
DN_Str8 delimiter = DN_Str8Lit("/");
|
||||
DN_Str8 input = DN_Str8Lit("abcdef");
|
||||
for (DN_UT_Test(&result, TEST_FMT, DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("abcdef")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs));
|
||||
}
|
||||
|
||||
input = DN_STR8("abc/def");
|
||||
for (DN_UT_Test(&result, TEST_FMT, DN_STR_FMT(input), DN_STR_FMT(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("abc")), "[lhs=%.*s]", DN_STR_FMT(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("def")), "[rhs=%.*s]", DN_STR_FMT(split.rhs));
|
||||
input = DN_Str8Lit("abc/def");
|
||||
for (DN_UT_Test(&result, TEST_FMT, DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("abc")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("def")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs));
|
||||
}
|
||||
|
||||
input = DN_STR8("/abcdef");
|
||||
for (DN_UT_Test(&result, TEST_FMT, DN_STR_FMT(input), DN_STR_FMT(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("")), "[lhs=%.*s]", DN_STR_FMT(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("abcdef")), "[rhs=%.*s]", DN_STR_FMT(split.rhs));
|
||||
input = DN_Str8Lit("/abcdef");
|
||||
for (DN_UT_Test(&result, TEST_FMT, DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("abcdef")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
DN_Str8 delimiter = DN_STR8("-=-");
|
||||
DN_Str8 input = DN_STR8("123-=-456");
|
||||
for (DN_UT_Test(&result, "Binary split \"%.*s\" with \"%.*s\"", DN_STR_FMT(input), DN_STR_FMT(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("123")), "[lhs=%.*s]", DN_STR_FMT(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("456")), "[rhs=%.*s]", DN_STR_FMT(split.rhs));
|
||||
DN_Str8 delimiter = DN_Str8Lit("-=-");
|
||||
DN_Str8 input = DN_Str8Lit("123-=-456");
|
||||
for (DN_UT_Test(&result, "Binary split \"%.*s\" with \"%.*s\"", DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) {
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("123")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs));
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("456")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_ToI64 /////////////////////////////////////////////////////////////////////////
|
||||
for (DN_UT_Test(&result, "To I64: Convert null string")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_Str8_Init(nullptr, 5), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 0);
|
||||
}
|
||||
|
||||
// NOTE: DN_I64FromStr8
|
||||
for (DN_UT_Test(&result, "To I64: Convert empty string")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8(""), 0);
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit(""), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 0);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To I64: Convert \"1\"")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1"), 0);
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1"), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 1);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To I64: Convert \"-0\"")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("-0"), 0);
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-0"), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 0);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To I64: Convert \"-1\"")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("-1"), 0);
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-1"), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == -1);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To I64: Convert \"1.2\"")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1.2"), 0);
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1.2"), 0);
|
||||
DN_UT_Assert(&result, !str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 1);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To I64: Convert \"1,234\"")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1,234"), ',');
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,234"), ',');
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 1234);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To I64: Convert \"1,2\"")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1,2"), ',');
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,2"), ',');
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 12);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To I64: Convert \"12a3\"")) {
|
||||
DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("12a3"), 0);
|
||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("12a3"), 0);
|
||||
DN_UT_Assert(&result, !str_result.success);
|
||||
DN_UT_Assert(&result, str_result.value == 12);
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_ToU64 /////////////////////////////////////////////////////////////////////////
|
||||
for (DN_UT_Test(&result, "To U64: Convert nullptr")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_Str8_Init(nullptr, 5), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
// NOTE: DN_U64FromStr8
|
||||
for (DN_UT_Test(&result, "To U64: Convert empty string")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8(""), 0);
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit(""), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To U64: Convert \"1\"")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1"), 0);
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1"), 0);
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 1, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To U64: Convert \"-0\"")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("-0"), 0);
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("-0"), 0);
|
||||
DN_UT_Assert(&result, !str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To U64: Convert \"-1\"")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("-1"), 0);
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("-1"), 0);
|
||||
DN_UT_Assert(&result, !str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To U64: Convert \"1.2\"")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1.2"), 0);
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1.2"), 0);
|
||||
DN_UT_Assert(&result, !str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 1, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To U64: Convert \"1,234\"")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1,234"), ',');
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1,234"), ',');
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 1234, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To U64: Convert \"1,2\"")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1,2"), ',');
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1,2"), ',');
|
||||
DN_UT_Assert(&result, str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 12, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "To U64: Convert \"12a3\"")) {
|
||||
DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("12a3"), 0);
|
||||
DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("12a3"), 0);
|
||||
DN_UT_Assert(&result, !str_result.success);
|
||||
DN_UT_AssertF(&result, str_result.value == 12, "result: %" PRIu64, str_result.value);
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_Find /////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8Find
|
||||
for (DN_UT_Test(&result, "Find: String (char) is not in buffer")) {
|
||||
DN_Str8 buf = DN_STR8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
||||
DN_Str8 find = DN_STR8("2");
|
||||
DN_Str8FindResult str_result = DN_Str8_FindStr8(buf, find, DN_Str8EqCase_Sensitive);
|
||||
DN_Str8 buf = DN_Str8Lit("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
||||
DN_Str8 find = DN_Str8Lit("2");
|
||||
DN_Str8FindResult str_result = DN_Str8FindStr8(buf, find, DN_Str8EqCase_Sensitive);
|
||||
DN_UT_Assert(&result, !str_result.found);
|
||||
DN_UT_Assert(&result, str_result.index == 0);
|
||||
DN_UT_Assert(&result, str_result.match.data == nullptr);
|
||||
@ -2332,33 +2351,33 @@ static DN_UTCore DN_Tests_Str8()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Find: String (char) is in buffer")) {
|
||||
DN_Str8 buf = DN_STR8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
||||
DN_Str8 find = DN_STR8("6");
|
||||
DN_Str8FindResult str_result = DN_Str8_FindStr8(buf, find, DN_Str8EqCase_Sensitive);
|
||||
DN_Str8 buf = DN_Str8Lit("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55");
|
||||
DN_Str8 find = DN_Str8Lit("6");
|
||||
DN_Str8FindResult str_result = DN_Str8FindStr8(buf, find, DN_Str8EqCase_Sensitive);
|
||||
DN_UT_Assert(&result, str_result.found);
|
||||
DN_UT_Assert(&result, str_result.index == 2);
|
||||
DN_UT_Assert(&result, str_result.match.data[0] == '6');
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_FileNameFromPath //////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8FileNameFromPath
|
||||
for (DN_UT_Test(&result, "File name from Windows path")) {
|
||||
DN_Str8 buf = DN_STR8("C:\\ABC\\str_result.exe");
|
||||
DN_Str8 str_result = DN_Str8_FileNameFromPath(buf);
|
||||
DN_UT_AssertF(&result, str_result == DN_STR8("str_result.exe"), "%.*s", DN_STR_FMT(str_result));
|
||||
DN_Str8 buf = DN_Str8Lit("C:\\ABC\\str_result.exe");
|
||||
DN_Str8 str_result = DN_Str8FileNameFromPath(buf);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("str_result.exe")), "%.*s", DN_Str8PrintFmt(str_result));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "File name from Linux path")) {
|
||||
DN_Str8 buf = DN_STR8("/ABC/str_result.exe");
|
||||
DN_Str8 str_result = DN_Str8_FileNameFromPath(buf);
|
||||
DN_UT_AssertF(&result, str_result == DN_STR8("str_result.exe"), "%.*s", DN_STR_FMT(str_result));
|
||||
DN_Str8 buf = DN_Str8Lit("/ABC/str_result.exe");
|
||||
DN_Str8 str_result = DN_Str8FileNameFromPath(buf);
|
||||
DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("str_result.exe")), "%.*s", DN_Str8PrintFmt(str_result));
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8_TrimPrefix ////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_Str8TrimPrefix
|
||||
for (DN_UT_Test(&result, "Trim prefix")) {
|
||||
DN_Str8 prefix = DN_STR8("@123");
|
||||
DN_Str8 buf = DN_STR8("@123string");
|
||||
DN_Str8 str_result = DN_Str8_TrimPrefix(buf, prefix, DN_Str8EqCase_Sensitive);
|
||||
DN_UT_Assert(&result, str_result == DN_STR8("string"));
|
||||
DN_Str8 prefix = DN_Str8Lit("@123");
|
||||
DN_Str8 buf = DN_Str8Lit("@123string");
|
||||
DN_Str8 str_result = DN_Str8TrimPrefix(buf, prefix, DN_Str8EqCase_Sensitive);
|
||||
DN_UT_Assert(&result, DN_Str8Eq(str_result, DN_Str8Lit("string")));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -2383,8 +2402,8 @@ static DN_UTCore DN_Tests_TicketMutex()
|
||||
DN_TicketMutex mutex = {};
|
||||
unsigned int ticket_a = DN_TicketMutex_MakeTicket(&mutex);
|
||||
unsigned int ticket_b = DN_TicketMutex_MakeTicket(&mutex);
|
||||
DN_UT_Assert(&result, DN_CAST(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false);
|
||||
DN_UT_Assert(&result, DN_CAST(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true);
|
||||
DN_UT_Assert(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false);
|
||||
DN_UT_Assert(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true);
|
||||
|
||||
DN_TicketMutex_BeginTicket(&mutex, ticket_a);
|
||||
DN_TicketMutex_End(&mutex);
|
||||
@ -2405,22 +2424,22 @@ static DN_UTCore DN_Tests_Win()
|
||||
DN_UT_LogF(&result, "OS Win32\n");
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 input8 = DN_STR8("String");
|
||||
DN_Str8 input8 = DN_Str8Lit("String");
|
||||
DN_Str16 input16 = DN_Str16{(wchar_t *)(L"String"), sizeof(L"String") / sizeof(L"String"[0]) - 1};
|
||||
|
||||
for (DN_UT_Test(&result, "Str8 to Str16")) {
|
||||
DN_Str16 str_result = DN_W32_Str8ToStr16(tmem.arena, input8);
|
||||
DN_UT_Assert(&result, str_result == input16);
|
||||
DN_UT_Assert(&result, DN_Str16Eq(str_result, input16));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Str16 to Str8")) {
|
||||
DN_Str8 str_result = DN_W32_Str16ToStr8(tmem.arena, input16);
|
||||
DN_UT_Assert(&result, str_result == input8);
|
||||
DN_UT_Assert(&result, DN_Str8Eq(str_result, input8));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Str16 to Str8: Null terminates string")) {
|
||||
int size_required = DN_W32_Str16ToStr8Buffer(input16, nullptr, 0);
|
||||
char *string = DN_Arena_NewArray(tmem.arena, char, size_required + 1, DN_ZeroMem_No);
|
||||
char *string = DN_ArenaNewArray(tmem.arena, char, size_required + 1, DN_ZMem_No);
|
||||
|
||||
// Fill the string with error sentinels
|
||||
DN_Memset(string, 'Z', size_required + 1);
|
||||
@ -2438,8 +2457,8 @@ static DN_UTCore DN_Tests_Win()
|
||||
int size_returned = DN_W32_Str16ToStr8Buffer(input16, nullptr, 0);
|
||||
char const EXPECTED[] = {'S', 't', 'r', 'i', 'n', 'g', 0};
|
||||
|
||||
DN_UT_AssertF(&result, DN_CAST(int) string8.size == size_returned, "string_size: %d, result: %d", DN_CAST(int) string8.size, size_returned);
|
||||
DN_UT_AssertF(&result, DN_CAST(int) string8.size == DN_ArrayCountU(EXPECTED) - 1, "string_size: %d, expected: %zu", DN_CAST(int) string8.size, DN_ArrayCountU(EXPECTED) - 1);
|
||||
DN_UT_AssertF(&result, DN_Cast(int) string8.size == size_returned, "string_size: %d, result: %d", DN_Cast(int) string8.size, size_returned);
|
||||
DN_UT_AssertF(&result, DN_Cast(int) string8.size == DN_ArrayCountU(EXPECTED) - 1, "string_size: %d, expected: %zu", DN_Cast(int) string8.size, DN_ArrayCountU(EXPECTED) - 1);
|
||||
DN_UT_Assert(&result, DN_Memcmp(EXPECTED, string8.data, sizeof(EXPECTED)) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ DN_TypeGetField DN_Type_GetField(DN_TypeInfo const *type_info, DN_Str8 name)
|
||||
if (type_field->name == name) {
|
||||
result.success = true;
|
||||
result.index = index;
|
||||
result.field = DN_CAST(DN_TypeField *)type_field;
|
||||
result.field = DN_Cast(DN_TypeField *)type_field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ static DN_OSCore *g_dn_os_core_;
|
||||
static void DN_OS_LOGEmitFromTypeTypeFV_(DN_LOGTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_Assert(user_data);
|
||||
DN_OSCore *core = DN_CAST(DN_OSCore *)user_data;
|
||||
DN_OSCore *core = DN_Cast(DN_OSCore *)user_data;
|
||||
|
||||
// NOTE: Open log file for appending if requested ////////////////////////////////////////////////
|
||||
DN_TicketMutex_Begin(&core->log_file_mutex);
|
||||
@ -71,17 +71,17 @@ static void DN_OS_LOGEmitFromTypeTypeFV_(DN_LOGTypeParam type, void *user_data,
|
||||
va_copy(args_copy, args);
|
||||
DN_TicketMutex_Begin(&core->log_file_mutex);
|
||||
{
|
||||
DN_OS_FileWrite(&core->log_file, DN_Str8_Init(prefix_buffer, prefix_size.size), nullptr);
|
||||
DN_OS_FileWriteF(&core->log_file, nullptr, "%*s ", DN_CAST(int)prefix_size.padding, "");
|
||||
DN_OS_FileWrite(&core->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.size), nullptr);
|
||||
DN_OS_FileWriteF(&core->log_file, nullptr, "%*s ", DN_Cast(int)prefix_size.padding, "");
|
||||
DN_OS_FileWriteFV(&core->log_file, nullptr, fmt, args_copy);
|
||||
DN_OS_FileWrite(&core->log_file, DN_STR8("\n"), nullptr);
|
||||
DN_OS_FileWrite(&core->log_file, DN_Str8Lit("\n"), nullptr);
|
||||
}
|
||||
DN_TicketMutex_End(&core->log_file_mutex);
|
||||
va_end(args_copy);
|
||||
|
||||
DN_OSPrintDest dest = (type.is_u32_enum && type.u32 == DN_LOGType_Error) ? DN_OSPrintDest_Err : DN_OSPrintDest_Out;
|
||||
DN_OS_Print(dest, DN_Str8_Init(prefix_buffer, prefix_size.size));
|
||||
DN_OS_PrintF(dest, "%*s ", DN_CAST(int)prefix_size.padding, "");
|
||||
DN_OS_Print(dest, DN_Str8FromPtr(prefix_buffer, prefix_size.size));
|
||||
DN_OS_PrintF(dest, "%*s ", DN_Cast(int)prefix_size.padding, "");
|
||||
DN_OS_PrintLnFV(dest, fmt, args);
|
||||
}
|
||||
|
||||
@ -114,24 +114,24 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args)
|
||||
|
||||
{
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
os->arena = DN_Arena_FromHeap(DN_Megabytes(1), DN_ArenaFlags_NoAllocTrack);
|
||||
os->arena = DN_ArenaFromHeap(DN_Megabytes(1), DN_ArenaFlags_NoAllocTrack);
|
||||
#else
|
||||
os->arena = DN_Arena_FromVMem(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack);
|
||||
os->arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack);
|
||||
#endif
|
||||
|
||||
#if defined(DN_PLATFORM_WIN32)
|
||||
os->platform_context = DN_Arena_New(&os->arena, DN_W32Core, DN_ZeroMem_Yes);
|
||||
os->platform_context = DN_ArenaNew(&os->arena, DN_W32Core, DN_ZMem_Yes);
|
||||
#elif defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
os->platform_context = DN_Arena_New(&os->arena, DN_POSIXCore, DN_ZeroMem_Yes);
|
||||
os->platform_context = DN_ArenaNew(&os->arena, DN_POSIXCore, DN_ZMem_Yes);
|
||||
#endif
|
||||
|
||||
#if defined(DN_PLATFORM_WIN32)
|
||||
DN_W32Core *w32 = DN_CAST(DN_W32Core *) os->platform_context;
|
||||
DN_W32Core *w32 = DN_Cast(DN_W32Core *) os->platform_context;
|
||||
InitializeCriticalSection(&w32->sync_primitive_free_list_mutex);
|
||||
|
||||
QueryPerformanceFrequency(&w32->qpc_frequency);
|
||||
HMODULE module = LoadLibraryA("kernel32.dll");
|
||||
w32->set_thread_description = DN_CAST(DN_W32SetThreadDescriptionFunc *) GetProcAddress(module, "SetThreadDescription");
|
||||
w32->set_thread_description = DN_Cast(DN_W32SetThreadDescriptionFunc *) GetProcAddress(module, "SetThreadDescription");
|
||||
FreeLibrary(module);
|
||||
|
||||
// NOTE: win32 bcrypt
|
||||
@ -142,7 +142,7 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args)
|
||||
else
|
||||
DN_LOG_ErrorF("Failed to initialise Windows secure random number generator, error: %d", init_status);
|
||||
#else
|
||||
DN_Posix_Init(DN_CAST(DN_POSIXCore *)os->platform_context);
|
||||
DN_Posix_Init(DN_Cast(DN_POSIXCore *)os->platform_context);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args)
|
||||
DN_OS_TLSSetCurrentThreadTLS(&os->tls);
|
||||
os->cpu_report = DN_CPUGetReport();
|
||||
|
||||
#define DN_CPU_FEAT_XENTRY(label) g_dn_cpu_feature_decl[DN_CPUFeature_##label] = {DN_CPUFeature_##label, DN_STR8(#label)};
|
||||
#define DN_CPU_FEAT_XENTRY(label) g_dn_cpu_feature_decl[DN_CPUFeature_##label] = {DN_CPUFeature_##label, DN_Str8Lit(#label)};
|
||||
DN_CPU_FEAT_XMACRO
|
||||
#undef DN_CPU_FEAT_XENTRY
|
||||
DN_Assert(g_dn_os_core_);
|
||||
@ -182,7 +182,7 @@ DN_API void DN_OS_DumpThreadContextArenaStat(DN_Str8 file_path)
|
||||
FILE *file = nullptr;
|
||||
fopen_s(&file, file_path.data, "a+b");
|
||||
if (file) {
|
||||
DN_LOG_ErrorF("Failed to dump thread context arenas [file=%.*s]", DN_STR_FMT(file_path));
|
||||
DN_LOG_ErrorF("Failed to dump thread context arenas [file=%.*s]", DN_Str8PrintFmt(file_path));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -223,29 +223,56 @@ DN_API void DN_OS_DumpThreadContextArenaStat(DN_Str8 file_path)
|
||||
stat.blocks_hwm = DN_Max(stat.blocks_hwm, current->blocks_hwm);
|
||||
}
|
||||
|
||||
DN_ArenaStatStr stats_string = DN_Arena_StatStr(&stat);
|
||||
DN_ArenaStatStr stats_string = DN_ArenaStatStr(&stat);
|
||||
fprintf(file, " [ALL] CURR %.*s\n", stats_string.size, stats_string.data);
|
||||
}
|
||||
|
||||
// NOTE: Print individual thread arena data
|
||||
for (DN_USize index = 0; index < stats_size; index++) {
|
||||
DN_ArenaStat const *current = stats + index;
|
||||
DN_ArenaStatStr current_string = DN_Arena_StatStr(current);
|
||||
fprintf(file, " [%03d] CURR %.*s\n", DN_CAST(int) index, current_string.size, current_string.data);
|
||||
DN_ArenaStatStr current_string = DN_ArenaStatStr(current);
|
||||
fprintf(file, " [%03d] CURR %.*s\n", DN_Cast(int) index, current_string.size, current_string.data);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
DN_LOG_InfoF("Dumped thread context arenas [file=%.*s]", DN_STR_FMT(file_path));
|
||||
DN_LOG_InfoF("Dumped thread context arenas [file=%.*s]", DN_Str8PrintFmt(file_path));
|
||||
#else
|
||||
(void)file_path;
|
||||
#endif // #if defined(DN_DEBUG_THREAD_CONTEXT)
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_BytesFromHexPtrArenaFrame(void const *hex, DN_USize hex_count)
|
||||
{
|
||||
DN_Arena *frame_arena = DN_OS_TLSFrameArena();
|
||||
DN_Str8 result = DN_BytesFromHexPtrArena(hex, hex_count, frame_arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_BytesFromHexStr8ArenaFrame(DN_Str8 hex)
|
||||
{
|
||||
DN_Str8 result = DN_OS_BytesFromHexPtrArenaFrame(hex.data, hex.size);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaFrame(void const *bytes, DN_USize bytes_count)
|
||||
{
|
||||
DN_Arena *frame_arena = DN_OS_TLSFrameArena();
|
||||
DN_Str8 result = DN_HexFromBytesPtrArena(bytes, bytes_count, frame_arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaTLS(void const *bytes, DN_USize bytes_count)
|
||||
{
|
||||
DN_Arena *tls_arena = DN_OS_TLSArena();
|
||||
DN_Str8 result = DN_HexFromBytesPtrArena(bytes, bytes_count, tls_arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Date //////////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8(DN_OSDateTime time, char date_separator, char hms_separator)
|
||||
{
|
||||
DN_OSDateTimeStr8 result = {};
|
||||
result.hms_size = DN_CAST(uint8_t) DN_SNPrintF(result.hms,
|
||||
result.hms_size = DN_Cast(uint8_t) DN_SNPrintF(result.hms,
|
||||
DN_ArrayCountI(result.hms),
|
||||
"%02hhu%c%02hhu%c%02hhu",
|
||||
time.hour,
|
||||
@ -254,7 +281,7 @@ DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8(DN_OSDateTime time, char date_s
|
||||
hms_separator,
|
||||
time.seconds);
|
||||
|
||||
result.date_size = DN_CAST(uint8_t) DN_SNPrintF(result.date,
|
||||
result.date_size = DN_Cast(uint8_t) DN_SNPrintF(result.date,
|
||||
DN_ArrayCountI(result.date),
|
||||
"%hu%c%02hhu%c%02hhu",
|
||||
time.year,
|
||||
@ -300,9 +327,9 @@ DN_API DN_Str8 DN_OS_EXEDir(DN_Arena *arena)
|
||||
return result;
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
DN_Str8 exe_path = DN_OS_EXEPath(tmem.arena);
|
||||
DN_Str8 separators[] = {DN_STR8("/"), DN_STR8("\\")};
|
||||
DN_Str8BSplitResult split = DN_Str8_BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators));
|
||||
result = DN_Str8_FromStr8(arena, split.lhs);
|
||||
DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")};
|
||||
DN_Str8BSplitResult split = DN_Str8BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators));
|
||||
result = DN_Str8FromStr8Arena(arena, split.lhs);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -311,7 +338,7 @@ DN_API DN_F64 DN_OS_PerfCounterS(uint64_t begin, uint64_t end)
|
||||
{
|
||||
uint64_t frequency = DN_OS_PerfCounterFrequency();
|
||||
uint64_t ticks = end - begin;
|
||||
DN_F64 result = ticks / DN_CAST(DN_F64) frequency;
|
||||
DN_F64 result = ticks / DN_Cast(DN_F64) frequency;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -319,7 +346,7 @@ DN_API DN_F64 DN_OS_PerfCounterMs(uint64_t begin, uint64_t end)
|
||||
{
|
||||
uint64_t frequency = DN_OS_PerfCounterFrequency();
|
||||
uint64_t ticks = end - begin;
|
||||
DN_F64 result = (ticks * 1'000) / DN_CAST(DN_F64) frequency;
|
||||
DN_F64 result = (ticks * 1'000) / DN_Cast(DN_F64) frequency;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -327,7 +354,7 @@ DN_API DN_F64 DN_OS_PerfCounterUs(uint64_t begin, uint64_t end)
|
||||
{
|
||||
uint64_t frequency = DN_OS_PerfCounterFrequency();
|
||||
uint64_t ticks = end - begin;
|
||||
DN_F64 result = (ticks * 1'000'000) / DN_CAST(DN_F64) frequency;
|
||||
DN_F64 result = (ticks * 1'000'000) / DN_Cast(DN_F64) frequency;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -335,7 +362,7 @@ DN_API DN_F64 DN_OS_PerfCounterNs(uint64_t begin, uint64_t end)
|
||||
{
|
||||
uint64_t frequency = DN_OS_PerfCounterFrequency();
|
||||
uint64_t ticks = end - begin;
|
||||
DN_F64 result = (ticks * 1'000'000'000) / DN_CAST(DN_F64) frequency;
|
||||
DN_F64 result = (ticks * 1'000'000'000) / DN_Cast(DN_F64) frequency;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -415,9 +442,9 @@ struct DN_OSFileWriteChunker_
|
||||
|
||||
static char *DN_OS_FileWriteChunker_(const char *buf, void *user, int len)
|
||||
{
|
||||
DN_OSFileWriteChunker_ *chunker = DN_CAST(DN_OSFileWriteChunker_ *)user;
|
||||
DN_OSFileWriteChunker_ *chunker = DN_Cast(DN_OSFileWriteChunker_ *)user;
|
||||
chunker->success = DN_OS_FileWritePtr(chunker->file, buf, len, chunker->err);
|
||||
char *result = chunker->success ? DN_CAST(char *) buf : nullptr;
|
||||
char *result = chunker->success ? DN_Cast(char *) buf : nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -452,24 +479,24 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_St
|
||||
DN_Str8 result = {};
|
||||
DN_OSPathInfo path_info = DN_OS_PathInfo(path);
|
||||
if (!path_info.exists) {
|
||||
DN_OS_ErrSinkAppendF(err, 1, "File does not exist/could not be queried for reading '%.*s'", DN_STR_FMT(path));
|
||||
DN_OS_ErrSinkAppendF(err, 1, "File does not exist/could not be queried for reading '%.*s'", DN_Str8PrintFmt(path));
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Allocate
|
||||
DN_ArenaTempMem arena_tmp = {};
|
||||
if (alloc_type == DN_Allocator_Arena) {
|
||||
DN_Arena *arena = DN_CAST(DN_Arena *) allocator;
|
||||
arena_tmp = DN_Arena_TempMemBegin(arena);
|
||||
result = DN_Str8_Alloc(arena, path_info.size, DN_ZeroMem_No);
|
||||
DN_Arena *arena = DN_Cast(DN_Arena *) allocator;
|
||||
arena_tmp = DN_ArenaTempMemBegin(arena);
|
||||
result = DN_Str8FromArena(arena, path_info.size, DN_ZMem_No);
|
||||
} else {
|
||||
DN_Pool *pool = DN_CAST(DN_Pool *) allocator;
|
||||
result = DN_Str8_AllocPool(pool, path_info.size);
|
||||
DN_Pool *pool = DN_Cast(DN_Pool *) allocator;
|
||||
result = DN_Str8FromPool(pool, path_info.size);
|
||||
}
|
||||
|
||||
if (!result.data) {
|
||||
DN_CVTU64Bytes bytes_str = DN_CVT_BytesFromU64Auto(path_info.size);
|
||||
DN_OS_ErrSinkAppendF(err, 1 /*err_code*/, "Failed to allocate %.1f %.*s for reading file '%.*s'", bytes_str.bytes, DN_STR_FMT(bytes_str.suffix), DN_STR_FMT(path));
|
||||
DN_Str8x32 bytes_str = DN_ByteCountStr8x32(path_info.size);
|
||||
DN_OS_ErrSinkAppendF(err, 1 /*err_code*/, "Failed to allocate %.*s for reading file '%.*s'", DN_Str8PrintFmt(bytes_str), DN_Str8PrintFmt(path));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -478,10 +505,10 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_St
|
||||
DN_OSFileRead read = DN_OS_FileRead(&file, result.data, result.size, err);
|
||||
if (file.error || !read.success) {
|
||||
if (alloc_type == DN_Allocator_Arena) {
|
||||
DN_Arena_TempMemEnd(arena_tmp);
|
||||
DN_ArenaTempMemEnd(arena_tmp);
|
||||
} else {
|
||||
DN_Pool *pool = DN_CAST(DN_Pool *) allocator;
|
||||
DN_Pool_Dealloc(pool, result.data);
|
||||
DN_Pool *pool = DN_Cast(DN_Pool *) allocator;
|
||||
DN_PoolDealloc(pool, result.data);
|
||||
}
|
||||
result = {};
|
||||
}
|
||||
@ -519,7 +546,7 @@ DN_API bool DN_OS_FileWriteAll(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error
|
||||
DN_API bool DN_OS_FileWriteAllFV(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args);
|
||||
DN_Str8 buffer = DN_Str8FromFmtVArena(tmem.arena, fmt, args);
|
||||
bool result = DN_OS_FileWriteAll(file_path, buffer, error);
|
||||
return result;
|
||||
}
|
||||
@ -536,7 +563,7 @@ DN_API bool DN_OS_FileWriteAllF(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_A
|
||||
DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 tmp_path = DN_Str8_FromF(tmem.arena, "%.*s.tmp", DN_STR_FMT(path));
|
||||
DN_Str8 tmp_path = DN_Str8FromFmtArena(tmem.arena, "%.*s.tmp", DN_Str8PrintFmt(path));
|
||||
if (!DN_OS_FileWriteAll(tmp_path, buffer, error))
|
||||
return false;
|
||||
if (!DN_OS_FileCopy(tmp_path, path, true /*overwrite*/, error))
|
||||
@ -549,7 +576,7 @@ DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *e
|
||||
DN_API bool DN_OS_FileWriteAllSafeFV(DN_Str8 path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args);
|
||||
DN_Str8 buffer = DN_Str8FromFmtVArena(tmem.arena, fmt, args);
|
||||
bool result = DN_OS_FileWriteAllSafe(path, buffer, error);
|
||||
return result;
|
||||
}
|
||||
@ -564,26 +591,26 @@ DN_API bool DN_OS_FileWriteAllSafeF(DN_Str8 path, DN_OSErrSink *error, DN_FMT_AT
|
||||
|
||||
DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
|
||||
{
|
||||
if (!arena || !fs_path || !DN_Str8_HasData(path))
|
||||
if (!arena || !fs_path || path.size == 0)
|
||||
return false;
|
||||
|
||||
if (path.size <= 0)
|
||||
return true;
|
||||
|
||||
DN_Str8 const delimiter_array[] = {
|
||||
DN_STR8("\\"),
|
||||
DN_STR8("/")};
|
||||
DN_Str8Lit("\\"),
|
||||
DN_Str8Lit("/")};
|
||||
|
||||
if (fs_path->links_size == 0)
|
||||
fs_path->has_prefix_path_separator = (path.data[0] == '/');
|
||||
|
||||
for (;;) {
|
||||
DN_Str8BSplitResult delimiter = DN_Str8_BSplitArray(path, delimiter_array, DN_ArrayCountU(delimiter_array));
|
||||
for (; delimiter.lhs.data; delimiter = DN_Str8_BSplitArray(delimiter.rhs, delimiter_array, DN_ArrayCountU(delimiter_array))) {
|
||||
DN_Str8BSplitResult delimiter = DN_Str8BSplitArray(path, delimiter_array, DN_ArrayCountU(delimiter_array));
|
||||
for (; delimiter.lhs.data; delimiter = DN_Str8BSplitArray(delimiter.rhs, delimiter_array, DN_ArrayCountU(delimiter_array))) {
|
||||
if (delimiter.lhs.size <= 0)
|
||||
continue;
|
||||
|
||||
DN_OSPathLink *link = DN_Arena_New(arena, DN_OSPathLink, DN_ZeroMem_Yes);
|
||||
DN_OSPathLink *link = DN_ArenaNew(arena, DN_OSPathLink, DN_ZMem_Yes);
|
||||
if (!link)
|
||||
return false;
|
||||
|
||||
@ -619,8 +646,8 @@ DN_API bool DN_OS_PathAddRefFrame(DN_OSPath *fs_path, DN_Str8 path)
|
||||
|
||||
DN_API bool DN_OS_PathAdd(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
|
||||
{
|
||||
DN_Str8 copy = DN_Str8_FromStr8(arena, path);
|
||||
bool result = DN_Str8_HasData(copy) ? true : DN_OS_PathAddRef(arena, fs_path, copy);
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(arena, path);
|
||||
bool result = copy.size ? true : DN_OS_PathAddRef(arena, fs_path, copy);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -628,7 +655,7 @@ DN_API bool DN_OS_PathAddF(DN_Arena *arena, DN_OSPath *fs_path, DN_FMT_ATTRIB ch
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8_FromFV(arena, fmt, args);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(arena, fmt, args);
|
||||
va_end(args);
|
||||
bool result = DN_OS_PathAddRef(arena, fs_path, path);
|
||||
return result;
|
||||
@ -668,7 +695,7 @@ DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATT
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8_FromFV(tmem.arena, fmt, args);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(tmem.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathTo(arena, path, path_separator);
|
||||
return result;
|
||||
@ -685,7 +712,7 @@ DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8_FromFV(tmem.arena, fmt, args);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(tmem.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_Path(arena, path);
|
||||
return result;
|
||||
@ -699,7 +726,7 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
|
||||
|
||||
// NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\'
|
||||
DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.size : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.size);
|
||||
result = DN_Str8_Alloc(arena, string_size, DN_ZeroMem_No);
|
||||
result = DN_Str8FromArena(arena, string_size, DN_ZMem_No);
|
||||
if (result.data) {
|
||||
char *dest = result.data;
|
||||
if (fs_path->has_prefix_path_separator) {
|
||||
@ -750,7 +777,7 @@ DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Slice<DN_Str8> cmd_line, DN_OSExecAr
|
||||
// NOTE: DN_OSThread ///////////////////////////////////////////////////////////////////////////////
|
||||
static void DN_OS_ThreadExecute_(void *user_context)
|
||||
{
|
||||
DN_OSThread *thread = DN_CAST(DN_OSThread *) user_context;
|
||||
DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context;
|
||||
DN_OS_TLSInit(&thread->tls, thread->tls_init_args);
|
||||
DN_OS_TLSSetCurrentThreadTLS(&thread->tls);
|
||||
DN_OS_SemaphoreWait(&thread->init_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT);
|
||||
@ -760,7 +787,7 @@ static void DN_OS_ThreadExecute_(void *user_context)
|
||||
DN_API void DN_OS_ThreadSetName(DN_Str8 name)
|
||||
{
|
||||
DN_OSTLS *tls = DN_OS_TLSGet();
|
||||
tls->name_size = DN_CAST(uint8_t) DN_Min(name.size, sizeof(tls->name) - 1);
|
||||
tls->name_size = DN_Cast(uint8_t) DN_Min(name.size, sizeof(tls->name) - 1);
|
||||
DN_Memcpy(tls->name, name.data, tls->name_size);
|
||||
tls->name[tls->name_size] = 0;
|
||||
|
||||
|
||||
@ -124,7 +124,7 @@ enum DN_OSFileAccess_
|
||||
#else
|
||||
#define DN_OSPathSeperator "/"
|
||||
#endif
|
||||
#define DN_OSPathSeperatorString DN_STR8(DN_OSPathSeperator)
|
||||
#define DN_OSPathSeperatorString DN_Str8Lit(DN_OSPathSeperator)
|
||||
#endif
|
||||
|
||||
struct DN_OSPathLink
|
||||
@ -208,7 +208,7 @@ struct DN_OSConditionVariable
|
||||
DN_U64 handle;
|
||||
};
|
||||
|
||||
// NOTE: DN_OSThread ///////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OSThread
|
||||
typedef DN_I32(DN_OSThreadFunc)(struct DN_OSThread *);
|
||||
|
||||
struct DN_OSThread
|
||||
@ -223,7 +223,7 @@ struct DN_OSThread
|
||||
DN_OSSemaphore init_semaphore;
|
||||
};
|
||||
|
||||
// NOTE: DN_OSHttp /////////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_OSHttp
|
||||
enum DN_OSHttpRequestSecure
|
||||
{
|
||||
DN_OSHttpRequestSecure_No,
|
||||
@ -309,13 +309,18 @@ DN_API void DN_OS_Init (D
|
||||
DN_API void DN_OS_EmitLogsWithOSPrintFunctions (DN_OSCore *os);
|
||||
DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path);
|
||||
|
||||
DN_API DN_Str8 DN_OS_BytesFromHexPtrArenaFrame (void const *hex, DN_USize hex_count);
|
||||
DN_API DN_Str8 DN_OS_BytesFromHexStr8ArenaFrame (DN_Str8 hex);
|
||||
DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaFrame (void const *bytes, DN_USize bytes_count);
|
||||
DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaTLS (void const *bytes, DN_USize bytes_count);
|
||||
|
||||
DN_API void * DN_OS_MemReserve (DN_USize size, DN_MemCommit commit, DN_MemPage page_flags);
|
||||
DN_API bool DN_OS_MemCommit (void *ptr, DN_USize size, DN_U32 page_flags);
|
||||
DN_API void DN_OS_MemDecommit (void *ptr, DN_USize size);
|
||||
DN_API void DN_OS_MemRelease (void *ptr, DN_USize size);
|
||||
DN_API int DN_OS_MemProtect (void *ptr, DN_USize size, DN_U32 page_flags);
|
||||
|
||||
DN_API void * DN_OS_MemAlloc (DN_USize size, DN_ZeroMem zero_mem);
|
||||
DN_API void * DN_OS_MemAlloc (DN_USize size, DN_ZMem z_mem);
|
||||
DN_API void DN_OS_MemDealloc (void *ptr);
|
||||
|
||||
DN_API DN_OSDateTime DN_OS_DateLocalTimeNow ();
|
||||
@ -409,8 +414,8 @@ DN_API DN_Str8 DN_OS_PathF (D
|
||||
#define DN_OS_PathFFromTLS(...) DN_OS_PathF(DN_OS_TLSTopArena(), ##__VA_ARGS__)
|
||||
#define DN_OS_PathFFromFrame(...) DN_OS_PathF(DN_OS_TLSFrameArena(), ##__VA_ARGS__)
|
||||
|
||||
#define DN_OS_PathBuildFwdSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_STR8("/"))
|
||||
#define DN_OS_PathBuildBackSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_STR8("\\"))
|
||||
#define DN_OS_PathBuildFwdSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_Str8Lit("/"))
|
||||
#define DN_OS_PathBuildBackSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_Str8Lit("\\"))
|
||||
#define DN_OS_PathBuild(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_OSPathSeparatorString)
|
||||
|
||||
DN_API void DN_OS_Exit (int32_t exit_code);
|
||||
|
||||
@ -3,23 +3,23 @@
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn_os_inc.h"
|
||||
|
||||
static void *DN_Arena_BasicAllocFromOSHeap(DN_USize size)
|
||||
static void *DN_ArenaBasicAllocFromOSHeap(DN_USize size)
|
||||
{
|
||||
void *result = DN_OS_MemAlloc(size, DN_ZeroMem_Yes);
|
||||
void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromHeap(DN_U64 size, DN_ArenaFlags flags)
|
||||
DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags)
|
||||
{
|
||||
DN_ArenaMemFuncs mem_funcs = {};
|
||||
mem_funcs.type = DN_ArenaMemFuncType_Basic;
|
||||
mem_funcs.basic_alloc = DN_Arena_BasicAllocFromOSHeap;
|
||||
mem_funcs.basic_alloc = DN_ArenaBasicAllocFromOSHeap;
|
||||
mem_funcs.basic_dealloc = DN_OS_MemDealloc;
|
||||
DN_Arena result = DN_Arena_FromMemFuncs(size, size, flags, mem_funcs);
|
||||
DN_Arena result = DN_ArenaFromMemFuncs(size, size, flags, mem_funcs);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags)
|
||||
DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags)
|
||||
{
|
||||
DN_ArenaMemFuncs mem_funcs = {};
|
||||
mem_funcs.type = DN_ArenaMemFuncType_VMem;
|
||||
@ -27,7 +27,7 @@ DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags f
|
||||
mem_funcs.vmem_reserve = DN_OS_MemReserve;
|
||||
mem_funcs.vmem_commit = DN_OS_MemCommit;
|
||||
mem_funcs.vmem_release = DN_OS_MemRelease;
|
||||
DN_Arena result = DN_Arena_FromMemFuncs(reserve, commit, flags, mem_funcs);
|
||||
DN_Arena result = DN_ArenaFromMemFuncs(reserve, commit, flags, mem_funcs);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#if !defined(DN_OS_ALLOCATOR_H)
|
||||
#define DN_OS_ALLOCATOR_H
|
||||
|
||||
DN_API DN_Arena DN_Arena_FromHeap(DN_U64 size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags);
|
||||
DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags);
|
||||
|
||||
#endif // !defined(DN_OS_ALLOCATOR_H)
|
||||
|
||||
@ -22,7 +22,7 @@ template <typename T>
|
||||
DN_VArray<T> DN_VArray_InitByteSize(DN_USize byte_size)
|
||||
{
|
||||
DN_VArray<T> result = {};
|
||||
result.data = DN_CAST(T *) DN_OS_MemReserve(byte_size, DN_MemCommit_No, DN_MemPage_ReadWrite);
|
||||
result.data = DN_Cast(T *) DN_OS_MemReserve(byte_size, DN_MemCommit_No, DN_MemPage_ReadWrite);
|
||||
if (result.data)
|
||||
result.max = byte_size / sizeof(T);
|
||||
return result;
|
||||
@ -80,7 +80,7 @@ DN_Slice<T> DN_VArray_Slice(DN_VArray<T> const *array)
|
||||
template <typename T>
|
||||
T *DN_VArray_AddArray(DN_VArray<T> *array, T const *items, DN_USize count)
|
||||
{
|
||||
T *result = DN_VArray_MakeArray(array, count, DN_ZeroMem_No);
|
||||
T *result = DN_VArray_MakeArray(array, count, DN_ZMem_No);
|
||||
if (result)
|
||||
DN_Memcpy(result, items, count * sizeof(T));
|
||||
return result;
|
||||
@ -101,7 +101,7 @@ T *DN_VArray_Add(DN_VArray<T> *array, T const &item)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_VArray_MakeArray(DN_VArray<T> *array, DN_USize count, DN_ZeroMem zero_mem)
|
||||
T *DN_VArray_MakeArray(DN_VArray<T> *array, DN_USize count, DN_ZMem z_mem)
|
||||
{
|
||||
if (!DN_VArray_IsValid(array))
|
||||
return nullptr;
|
||||
@ -115,15 +115,15 @@ T *DN_VArray_MakeArray(DN_VArray<T> *array, DN_USize count, DN_ZeroMem zero_mem)
|
||||
// TODO: Use placement new
|
||||
T *result = array->data + array->size;
|
||||
array->size += count;
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(result, 0, count * sizeof(T));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *DN_VArray_Make(DN_VArray<T> *array, DN_ZeroMem zero_mem)
|
||||
T *DN_VArray_Make(DN_VArray<T> *array, DN_ZMem z_mem)
|
||||
{
|
||||
T *result = DN_VArray_MakeArray(array, 1, zero_mem);
|
||||
T *result = DN_VArray_MakeArray(array, 1, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -177,10 +177,10 @@ DN_ArrayEraseResult DN_VArray_EraseRange(DN_VArray<T> *array, DN_USize begin_ind
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DN_VArray_Clear(DN_VArray<T> *array, DN_ZeroMem zero_mem)
|
||||
void DN_VArray_Clear(DN_VArray<T> *array, DN_ZMem z_mem)
|
||||
{
|
||||
if (array) {
|
||||
if (zero_mem == DN_ZeroMem_Yes)
|
||||
if (z_mem == DN_ZMem_Yes)
|
||||
DN_Memset(array->data, 0, array->size * sizeof(T));
|
||||
array->size = 0;
|
||||
}
|
||||
|
||||
@ -30,8 +30,8 @@ template <typename T> T * DN_VArray_
|
||||
#define DN_VArray_AddArrayAssert(...) DN_HardAssert(DN_VArray_AddArray(__VA_ARGS__))
|
||||
#define DN_VArray_AddCArrayAssert(...) DN_HardAssert(DN_VArray_AddCArray(__VA_ARGS__))
|
||||
#define DN_VArray_AddAssert(...) DN_HardAssert(DN_VArray_Add(__VA_ARGS__))
|
||||
template <typename T> T * DN_VArray_MakeArray (DN_VArray<T> *array, DN_USize count, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_VArray_Make (DN_VArray<T> *array, DN_ZeroMem zero_mem);
|
||||
template <typename T> T * DN_VArray_MakeArray (DN_VArray<T> *array, DN_USize count, DN_ZMem z_mem);
|
||||
template <typename T> T * DN_VArray_Make (DN_VArray<T> *array, DN_ZMem z_mem);
|
||||
#define DN_VArray_MakeArrayAssert(...) DN_HardAssert(DN_VArray_MakeArray(__VA_ARGS__))
|
||||
#define DN_VArray_MakeAssert(...) DN_HardAssert(DN_VArray_Make(__VA_ARGS__))
|
||||
template <typename T> T * DN_VArray_InsertArray (DN_VArray<T> *array, DN_USize index, T const *items, DN_USize count);
|
||||
@ -43,5 +43,5 @@ template <typename T> T * DN_VArray_
|
||||
template <typename T> T DN_VArray_PopFront (DN_VArray<T> *array, DN_USize count);
|
||||
template <typename T> T DN_VArray_PopBack (DN_VArray<T> *array, DN_USize count);
|
||||
template <typename T> DN_ArrayEraseResult DN_VArray_EraseRange (DN_VArray<T> *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase);
|
||||
template <typename T> void DN_VArray_Clear (DN_VArray<T> *array, DN_ZeroMem zero_mem);
|
||||
template <typename T> void DN_VArray_Clear (DN_VArray<T> *array, DN_ZMem z_mem);
|
||||
#endif // !defined(DN_OS_CONTAINERS_H)
|
||||
|
||||
@ -65,10 +65,10 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags)
|
||||
if (!ptr || size == 0)
|
||||
return 0;
|
||||
|
||||
static DN_Str8 const ALIGNMENT_ERROR_MSG = DN_STR8(
|
||||
static DN_Str8 const ALIGNMENT_ERROR_MSG = DN_Str8Lit(
|
||||
"Page protection requires pointers to be page aligned because we "
|
||||
"can only guard memory at a multiple of the page boundary.");
|
||||
DN_AssertF(DN_IsPowerOfTwoAligned(DN_CAST(uintptr_t) ptr, g_dn_os_core_->page_size),
|
||||
DN_AssertF(DN_IsPowerOfTwoAligned(DN_Cast(uintptr_t) ptr, g_dn_os_core_->page_size),
|
||||
"%s",
|
||||
ALIGNMENT_ERROR_MSG.data);
|
||||
DN_AssertF(
|
||||
@ -80,9 +80,9 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
void *result = zero_mem == DN_ZeroMem_Yes ? calloc(1, size) : malloc(size);
|
||||
void *result = z_mem == DN_ZMem_Yes ? calloc(1, size) : malloc(size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -113,9 +113,9 @@ DN_API DN_OSDateTime DN_OS_DateLocalTimeNow()
|
||||
result.minutes = time.tm_min;
|
||||
result.seconds = time.tm_sec;
|
||||
|
||||
result.day = DN_CAST(uint8_t) time.tm_mday;
|
||||
result.month = DN_CAST(uint8_t) time.tm_mon + 1;
|
||||
result.year = 1900 + DN_CAST(int16_t) time.tm_year;
|
||||
result.day = DN_Cast(uint8_t) time.tm_mday;
|
||||
result.month = DN_Cast(uint8_t) time.tm_mon + 1;
|
||||
result.year = 1900 + DN_Cast(int16_t) time.tm_year;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ DN_API uint64_t DN_OS_DateToUnixTimeS(DN_OSDateTime date)
|
||||
|
||||
DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(uint64_t time)
|
||||
{
|
||||
time_t posix_time = DN_CAST(time_t) time;
|
||||
time_t posix_time = DN_Cast(time_t) time;
|
||||
struct tm posix_date = *gmtime(&posix_time);
|
||||
DN_OSDateTime result = {};
|
||||
result.year = posix_date.tm_year + 1900;
|
||||
@ -196,7 +196,7 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_OSDiskSpace result = {};
|
||||
DN_Str8 path_z_terminated = DN_Str8_FromStr8(tmem.arena, path);
|
||||
DN_Str8 path_z_terminated = DN_Str8FromStr8(tmem.arena, path);
|
||||
|
||||
struct statvfs info = {};
|
||||
if (statvfs(path_z_terminated.data, &info) != 0)
|
||||
@ -217,7 +217,7 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
|
||||
int required_size_wo_null_terminator = 0;
|
||||
for (int try_size = 128;; try_size *= 2) {
|
||||
auto scoped_arena = DN_ArenaTempMemScope(arena);
|
||||
char *try_buf = DN_Arena_NewArray(arena, char, try_size, DN_ZeroMem_No);
|
||||
char *try_buf = DN_ArenaNewArray(arena, char, try_size, DN_ZMem_No);
|
||||
int bytes_written = readlink("/proc/self/exe", try_buf, try_size);
|
||||
if (bytes_written == -1) {
|
||||
// Failed, we're unable to determine the executable directory
|
||||
@ -245,9 +245,9 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
|
||||
}
|
||||
|
||||
if (required_size_wo_null_terminator) {
|
||||
DN_ArenaTempMem temp_mem = DN_Arena_TempMemBegin(arena);
|
||||
DN_ArenaTempMem temp_mem = DN_ArenaTempMemBegin(arena);
|
||||
char *exe_path =
|
||||
DN_Arena_NewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZeroMem_No);
|
||||
DN_ArenaNewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZMem_No);
|
||||
exe_path[required_size_wo_null_terminator] = 0;
|
||||
|
||||
int bytes_written = readlink("/proc/self/exe", exe_path, required_size_wo_null_terminator);
|
||||
@ -255,9 +255,9 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
|
||||
// Note that if read-link fails again can be because there's
|
||||
// a potential race condition here, our exe or directory could have
|
||||
// been deleted since the last call, so we need to be careful.
|
||||
DN_Arena_TempMemEnd(temp_mem);
|
||||
DN_ArenaTempMemEnd(temp_mem);
|
||||
} else {
|
||||
result = DN_Str8_Init(exe_path, required_size_wo_null_terminator);
|
||||
result = DN_Str8FromPtr(exe_path, required_size_wo_null_terminator);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -284,7 +284,7 @@ DN_API DN_U64 DN_OS_PerfCounterFrequency()
|
||||
static DN_POSIXCore *DN_OS_GetPOSIXCore_()
|
||||
{
|
||||
DN_Assert(g_dn_os_core_ && g_dn_os_core_->platform_context);
|
||||
DN_POSIXCore *result = DN_CAST(DN_POSIXCore *)g_dn_os_core_->platform_context;
|
||||
DN_POSIXCore *result = DN_Cast(DN_POSIXCore *)g_dn_os_core_->platform_context;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ DN_API DN_U64 DN_OS_PerfCounterNow()
|
||||
DN_POSIXCore *posix = DN_OS_GetPOSIXCore_();
|
||||
struct timespec ts;
|
||||
clock_gettime(posix->clock_monotonic_raw ? CLOCK_MONOTONIC_RAW : CLOCK_MONOTONIC, &ts);
|
||||
DN_U64 result = DN_CAST(DN_U64) ts.tv_sec * 1'000'000'000 + DN_CAST(DN_U64) ts.tv_nsec;
|
||||
DN_U64 result = DN_Cast(DN_U64) ts.tv_sec * 1'000'000'000 + DN_Cast(DN_U64) ts.tv_nsec;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -309,7 +309,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
DN_OS_ErrSinkAppendF(error,
|
||||
error_code,
|
||||
"Failed to open file '%.*s' for copying: (%d) %s",
|
||||
DN_STR_FMT(src),
|
||||
DN_Str8PrintFmt(src),
|
||||
error_code,
|
||||
strerror(error_code));
|
||||
return result;
|
||||
@ -326,7 +326,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
DN_OS_ErrSinkAppendF(error,
|
||||
error_code,
|
||||
"Failed to open file destination '%.*s' for copying to: (%d) %s",
|
||||
DN_STR_FMT(src),
|
||||
DN_Str8PrintFmt(src),
|
||||
error_code,
|
||||
strerror(error_code));
|
||||
return result;
|
||||
@ -343,7 +343,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
DN_OS_ErrSinkAppendF(error,
|
||||
error_code,
|
||||
"Failed to query file size of '%.*s' for copying: (%d) %s",
|
||||
DN_STR_FMT(src),
|
||||
DN_Str8PrintFmt(src),
|
||||
error_code,
|
||||
strerror(error_code));
|
||||
return result;
|
||||
@ -354,16 +354,16 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
if (!result) {
|
||||
int error_code = errno;
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 file_size_str8 = DN_CVT_BytesStr8FromU64(tmem.arena, stat_existing.st_size, DN_CVTBytesType_Auto);
|
||||
DN_Str8 bytes_written_str8 = DN_CVT_BytesStr8FromU64(tmem.arena, bytes_written, DN_CVTBytesType_Auto);
|
||||
DN_Str8 file_size_str8 = DN_Str8FromByteCount(tmem.arena, stat_existing.st_size, DN_ByteCountType_Auto);
|
||||
DN_Str8 bytes_written_str8 = DN_Str8FromByteCount(tmem.arena, bytes_written, DN_ByteCountType_Auto);
|
||||
DN_OS_ErrSinkAppendF(error,
|
||||
error_code,
|
||||
"Failed to copy file '%.*s' to '%.*s', we copied %.*s but the file "
|
||||
"size is %.*s: (%d) %s",
|
||||
DN_STR_FMT(src),
|
||||
DN_STR_FMT(dest),
|
||||
DN_STR_FMT(bytes_written_str8),
|
||||
DN_STR_FMT(file_size_str8),
|
||||
DN_Str8PrintFmt(src),
|
||||
DN_Str8PrintFmt(dest),
|
||||
DN_Str8PrintFmt(bytes_written_str8),
|
||||
DN_Str8PrintFmt(file_size_str8),
|
||||
error_code,
|
||||
strerror(error_code));
|
||||
}
|
||||
@ -392,7 +392,7 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
error,
|
||||
error_code,
|
||||
"File '%.*s' was moved but failed to be unlinked from old location: (%d) %s",
|
||||
DN_STR_FMT(src),
|
||||
DN_Str8PrintFmt(src),
|
||||
error_code,
|
||||
strerror(error_code));
|
||||
}
|
||||
@ -406,7 +406,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path,
|
||||
DN_OSErrSink *error)
|
||||
{
|
||||
DN_OSFile result = {};
|
||||
if (!DN_Str8_HasData(path) || path.size <= 0)
|
||||
if (path.size == 0 || path.size <= 0)
|
||||
return result;
|
||||
|
||||
if ((access & ~(DN_OSFileAccess_All) || ((access & DN_OSFileAccess_All) == 0))) {
|
||||
@ -420,7 +420,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path,
|
||||
error,
|
||||
1,
|
||||
"Failed to open file '%.*s': File access flag 'execute' is not supported",
|
||||
DN_STR_FMT(path));
|
||||
DN_Str8PrintFmt(path));
|
||||
DN_InvalidCodePath; // TODO: Not supported via fopen
|
||||
return result;
|
||||
}
|
||||
@ -444,7 +444,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path,
|
||||
1,
|
||||
"Failed to open file '%.*s': File could not be opened in requested "
|
||||
"mode 'DN_OSFileOpen' flag %d",
|
||||
DN_STR_FMT(path),
|
||||
DN_Str8PrintFmt(path),
|
||||
open_mode);
|
||||
return result;
|
||||
}
|
||||
@ -480,10 +480,10 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size
|
||||
if (!file || !file->handle || file->error || !buffer || size <= 0)
|
||||
return result;
|
||||
|
||||
result.bytes_read = fread(buffer, 1, size, DN_CAST(FILE *) file->handle);
|
||||
if (feof(DN_CAST(FILE*)file->handle)) {
|
||||
result.bytes_read = fread(buffer, 1, size, DN_Cast(FILE *) file->handle);
|
||||
if (feof(DN_Cast(FILE*)file->handle)) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size);
|
||||
DN_Str8 buffer_size_str8 = DN_ByteCountStr8x32TLS(size);
|
||||
DN_OS_ErrSinkAppendF(err, 1, "Failed to read %S from file", buffer_size_str8);
|
||||
return result;
|
||||
}
|
||||
@ -497,12 +497,12 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz
|
||||
if (!file || !file->handle || file->error || !buffer || size <= 0)
|
||||
return false;
|
||||
bool result =
|
||||
fwrite(buffer, DN_CAST(DN_USize) size, 1 /*count*/, DN_CAST(FILE *) file->handle) ==
|
||||
fwrite(buffer, DN_Cast(DN_USize) size, 1 /*count*/, DN_Cast(FILE *) file->handle) ==
|
||||
1 /*count*/;
|
||||
if (!result) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size);
|
||||
DN_OS_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_STR_FMT(buffer_size_str8));
|
||||
DN_Str8 buffer_size_str8 = DN_ByteCountStr8x32TLS(size);
|
||||
DN_OS_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_Str8PrintFmt(buffer_size_str8));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -510,7 +510,7 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz
|
||||
DN_API bool DN_OS_FileFlush(DN_OSFile *file, DN_OSErrSink *err)
|
||||
{
|
||||
// TODO: errno is not thread safe
|
||||
int fd = fileno(DN_CAST(FILE *) file->handle);
|
||||
int fd = fileno(DN_Cast(FILE *) file->handle);
|
||||
if (fd == -1) {
|
||||
DN_OS_ErrSinkAppendF(err, errno, "Failed to flush file buffer to disk, file handle could not be converted to descriptor (%d): %s", fd, strerror(errno));
|
||||
return false;
|
||||
@ -528,14 +528,14 @@ DN_API void DN_OS_FileClose(DN_OSFile *file)
|
||||
{
|
||||
if (!file || !file->handle || file->error)
|
||||
return;
|
||||
fclose(DN_CAST(FILE *) file->handle);
|
||||
fclose(DN_Cast(FILE *) file->handle);
|
||||
*file = {};
|
||||
}
|
||||
|
||||
DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
|
||||
{
|
||||
DN_OSPathInfo result = {};
|
||||
if (!DN_Str8_HasData(path))
|
||||
if (path.size == 0)
|
||||
return result;
|
||||
|
||||
struct stat file_stat;
|
||||
@ -559,7 +559,7 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
|
||||
DN_API bool DN_OS_PathDelete(DN_Str8 path)
|
||||
{
|
||||
bool result = false;
|
||||
if (DN_Str8_HasData(path))
|
||||
if (path.size)
|
||||
result = remove(path.data) == 0;
|
||||
return result;
|
||||
}
|
||||
@ -567,7 +567,7 @@ DN_API bool DN_OS_PathDelete(DN_Str8 path)
|
||||
DN_API bool DN_OS_PathIsFile(DN_Str8 path)
|
||||
{
|
||||
bool result = false;
|
||||
if (!DN_Str8_HasData(path))
|
||||
if (path.size == 0)
|
||||
return result;
|
||||
|
||||
struct stat stat_result;
|
||||
@ -579,7 +579,7 @@ DN_API bool DN_OS_PathIsFile(DN_Str8 path)
|
||||
DN_API bool DN_OS_PathIsDir(DN_Str8 path)
|
||||
{
|
||||
bool result = false;
|
||||
if (!DN_Str8_HasData(path))
|
||||
if (path.size == 0)
|
||||
return result;
|
||||
|
||||
struct stat stat_result;
|
||||
@ -598,7 +598,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
|
||||
DN_USize path_indexes_size = 0;
|
||||
uint16_t path_indexes[64] = {};
|
||||
|
||||
DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, path);
|
||||
DN_Str8 copy = DN_Str8FromStr8(tmem.arena, path);
|
||||
for (DN_USize index = copy.size - 1; index < copy.size; index--) {
|
||||
bool first_char = index == (copy.size - 1);
|
||||
char ch = copy.data[index];
|
||||
@ -626,7 +626,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
|
||||
} else {
|
||||
// NOTE: There's nothing that exists at this path, we can
|
||||
// create a directory here
|
||||
path_indexes[path_indexes_size++] = DN_CAST(uint16_t) index;
|
||||
path_indexes[path_indexes_size++] = DN_Cast(uint16_t) index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -654,23 +654,23 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
|
||||
struct dirent *entry;
|
||||
for (;;) {
|
||||
entry = readdir(DN_CAST(DIR *) it->handle);
|
||||
entry = readdir(DN_Cast(DIR *) it->handle);
|
||||
if (entry == NULL)
|
||||
break;
|
||||
|
||||
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
DN_USize name_size = DN_CStr8_Size(entry->d_name);
|
||||
DN_USize name_size = DN_CStrSize(entry->d_name);
|
||||
DN_USize clamped_size = DN_Min(sizeof(it->buffer) - 1, name_size);
|
||||
DN_AssertF(name_size == clamped_size, "name: %s, name_size: %zu, clamped_size: %zu", entry->d_name, name_size, clamped_size);
|
||||
DN_Memcpy(it->buffer, entry->d_name, clamped_size);
|
||||
it->buffer[clamped_size] = 0;
|
||||
it->file_name = DN_Str8_Init(it->buffer, clamped_size);
|
||||
it->file_name = DN_Str8FromPtr(it->buffer, clamped_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
closedir(DN_CAST(DIR *) it->handle);
|
||||
closedir(DN_Cast(DIR *) it->handle);
|
||||
it->handle = NULL;
|
||||
it->file_name = {};
|
||||
it->buffer[0] = 0;
|
||||
@ -679,7 +679,7 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
|
||||
DN_API void DN_OS_Exit(int32_t exit_code)
|
||||
{
|
||||
exit(DN_CAST(int) exit_code);
|
||||
exit(DN_Cast(int) exit_code);
|
||||
}
|
||||
|
||||
enum DN_OSPipeType_
|
||||
@ -757,30 +757,30 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle,
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
if (arena && handle.stdout_read) {
|
||||
char buffer[4096];
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena);
|
||||
for (;;) {
|
||||
ssize_t bytes_read =
|
||||
read(stdout_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer));
|
||||
if (bytes_read <= 0)
|
||||
break;
|
||||
DN_Str8Builder_AppendF(&builder, "%.*s", bytes_read, buffer);
|
||||
DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer);
|
||||
}
|
||||
|
||||
result.stdout_text = DN_Str8Builder_Build(&builder, arena);
|
||||
result.stdout_text = DN_Str8BuilderBuild(&builder, arena);
|
||||
}
|
||||
|
||||
if (arena && handle.stderr_read) {
|
||||
char buffer[4096];
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena);
|
||||
for (;;) {
|
||||
ssize_t bytes_read =
|
||||
read(stderr_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer));
|
||||
if (bytes_read <= 0)
|
||||
break;
|
||||
DN_Str8Builder_AppendF(&builder, "%.*s", bytes_read, buffer);
|
||||
DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer);
|
||||
}
|
||||
|
||||
result.stderr_text = DN_Str8Builder_Build(&builder, arena);
|
||||
result.stderr_text = DN_Str8BuilderBuild(&builder, arena);
|
||||
}
|
||||
}
|
||||
|
||||
@ -803,7 +803,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
return result;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_STR8(" "));
|
||||
DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_Str8Lit(" "));
|
||||
int stdout_pipe[DN_OSPipeType__Count] = {};
|
||||
int stderr_pipe[DN_OSPipeType__Count] = {};
|
||||
|
||||
@ -815,7 +815,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to create stdout pipe to redirect the output of the command '%.*s': %s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
strerror(result.os_error_code));
|
||||
return result;
|
||||
}
|
||||
@ -842,7 +842,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to create stderr pipe to redirect the output of the command '%.*s': %s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
strerror(result.os_error_code));
|
||||
return result;
|
||||
}
|
||||
@ -865,7 +865,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to fork process to execute the command '%.*s': %s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
strerror(result.os_error_code));
|
||||
return result;
|
||||
}
|
||||
@ -878,7 +878,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to redirect stdout 'write' pipe for output of command '%.*s': %s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
strerror(result.os_error_code));
|
||||
return result;
|
||||
}
|
||||
@ -890,27 +890,27 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to redirect stderr 'read' pipe for output of command '%.*s': %s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
strerror(result.os_error_code));
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: Convert the command into something suitable for execvp
|
||||
char **argv =
|
||||
DN_Arena_NewArray(tmem.arena, char *, cmd_line.size + 1 /*null*/, DN_ZeroMem_Yes);
|
||||
DN_ArenaNewArray(tmem.arena, char *, cmd_line.size + 1 /*null*/, DN_ZMem_Yes);
|
||||
if (!argv) {
|
||||
result.exit_code = -1;
|
||||
DN_OS_ErrSinkAppendF(
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to create argument values from command line '%.*s': Out of memory",
|
||||
DN_STR_FMT(cmd_rendered));
|
||||
DN_Str8PrintFmt(cmd_rendered));
|
||||
return result;
|
||||
}
|
||||
|
||||
for (DN_ForIndexU(arg_index, cmd_line.size)) {
|
||||
DN_Str8 arg = cmd_line.data[arg_index];
|
||||
argv[arg_index] = DN_Str8_FromStr8(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated
|
||||
argv[arg_index] = DN_Str8FromStr8(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated
|
||||
}
|
||||
|
||||
// NOTE: Change the working directory if there is one
|
||||
@ -928,14 +928,14 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
|
||||
if (args->working_dir.size) {
|
||||
prev_working_dir = get_current_dir_name();
|
||||
DN_Str8 working_dir = DN_Str8_FromStr8(tmem.arena, args->working_dir);
|
||||
DN_Str8 working_dir = DN_Str8FromStr8(tmem.arena, args->working_dir);
|
||||
if (chdir(working_dir.data) == -1) {
|
||||
result.os_error_code = errno;
|
||||
DN_OS_ErrSinkAppendF(
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to create argument values from command line '%.*s': %s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
strerror(result.os_error_code));
|
||||
return result;
|
||||
}
|
||||
@ -949,7 +949,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
|
||||
error,
|
||||
result.os_error_code,
|
||||
"Failed to execute command'%.*s': %s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
strerror(result.os_error_code));
|
||||
return result;
|
||||
}
|
||||
@ -1016,7 +1016,7 @@ static DN_POSIXSyncPrimitive *DN_POSIX_AllocSyncPrimitive_()
|
||||
result->next = nullptr;
|
||||
} else {
|
||||
DN_OSCore *os = g_dn_os_core_;
|
||||
result = DN_Arena_New(&os->arena, DN_POSIXSyncPrimitive, DN_ZeroMem_Yes);
|
||||
result = DN_ArenaNew(&os->arena, DN_POSIXSyncPrimitive, DN_ZMem_Yes);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&posix->sync_primitive_free_list_mutex);
|
||||
@ -1272,7 +1272,7 @@ DN_API DN_U32 DN_OS_ThreadID()
|
||||
{
|
||||
pid_t result = gettid();
|
||||
DN_Assert(gettid() >= 0);
|
||||
return DN_CAST(DN_U32) result;
|
||||
return DN_Cast(DN_U32) result;
|
||||
}
|
||||
|
||||
DN_API void DN_Posix_Init(DN_POSIXCore *posix)
|
||||
@ -1294,7 +1294,7 @@ DN_API void DN_Posix_ThreadSetName(DN_Str8 name)
|
||||
(void)name;
|
||||
#else
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, name);
|
||||
DN_Str8 copy = DN_Str8FromStr8(tmem.arena, name);
|
||||
pthread_t thread = pthread_self();
|
||||
pthread_setname_np(thread, (char *)copy.data);
|
||||
#endif
|
||||
@ -1313,49 +1313,49 @@ DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus()
|
||||
// ...
|
||||
//
|
||||
// VmSize is the total virtual memory used
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_STR8("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr);
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr);
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
|
||||
|
||||
if (!file.error) {
|
||||
char buf[256];
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromTLS();
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
for (;;) {
|
||||
DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr);
|
||||
if (!read.success || read.bytes_read == 0)
|
||||
break;
|
||||
DN_Str8Builder_AppendF(&builder, "%.*s", DN_CAST(int)read.bytes_read, buf);
|
||||
DN_Str8BuilderAppendF(&builder, "%.*s", DN_Cast(int)read.bytes_read, buf);
|
||||
}
|
||||
|
||||
DN_Str8 const NAME = DN_STR8("Name:");
|
||||
DN_Str8 const PID = DN_STR8("Pid:");
|
||||
DN_Str8 const VM_PEAK = DN_STR8("VmPeak:");
|
||||
DN_Str8 const VM_SIZE = DN_STR8("VmSize:");
|
||||
DN_Str8 status_buf = DN_Str8Builder_BuildFromTLS(&builder);
|
||||
DN_Slice<DN_Str8> lines = DN_Str8_SplitFromTLS(status_buf, DN_STR8("\n"), DN_Str8SplitIncludeEmptyStrings_No);
|
||||
DN_Str8 const NAME = DN_Str8Lit("Name:");
|
||||
DN_Str8 const PID = DN_Str8Lit("Pid:");
|
||||
DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:");
|
||||
DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:");
|
||||
DN_Str8 status_buf = DN_Str8BuilderBuildFromTLS(&builder);
|
||||
DN_Slice<DN_Str8> lines = DN_Str8SplitFromTLS(status_buf, DN_Str8Lit("\n"), DN_Str8SplitIncludeEmptyStrings_No);
|
||||
|
||||
for (DN_ForIt(line_it, DN_Str8, &lines)) {
|
||||
DN_Str8 line = DN_Str8_TrimWhitespaceAround(*line_it.data);
|
||||
if (DN_Str8_StartsWith(line, NAME, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 str8 = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, NAME.size, line.size));
|
||||
DN_Str8 line = DN_Str8TrimWhitespaceAround(*line_it.data);
|
||||
if (DN_Str8StartsWith(line, NAME, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, NAME.size, line.size));
|
||||
result.name_size = DN_Min(str8.size, sizeof(result.name));
|
||||
DN_Memcpy(result.name, str8.data, result.name_size);
|
||||
} else if (DN_Str8_StartsWith(line, PID, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 str8 = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, PID.size, line.size));
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(str8, 0);
|
||||
} else if (DN_Str8StartsWith(line, PID, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, PID.size, line.size));
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8ToU64(str8, 0);
|
||||
result.pid = to_u64.value;
|
||||
DN_Assert(to_u64.success);
|
||||
} else if (DN_Str8_StartsWith(line, VM_SIZE, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 size_with_kb = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, VM_SIZE.size, line.size));
|
||||
DN_Assert(DN_Str8_EndsWith(size_with_kb, DN_STR8("kB")));
|
||||
DN_Str8 vm_size = DN_Str8_BSplit(size_with_kb, DN_STR8(" ")).lhs;
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(vm_size, 0);
|
||||
} else if (DN_Str8StartsWith(line, VM_SIZE, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_SIZE.size, line.size));
|
||||
DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB")));
|
||||
DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs;
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8ToU64(vm_size, 0);
|
||||
result.vm_size = DN_Kilobytes(to_u64.value);
|
||||
DN_Assert(to_u64.success);
|
||||
} else if (DN_Str8_StartsWith(line, VM_PEAK, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 size_with_kb = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, VM_PEAK.size, line.size));
|
||||
DN_Assert(DN_Str8_EndsWith(size_with_kb, DN_STR8("kB")));
|
||||
DN_Str8 vm_size = DN_Str8_BSplit(size_with_kb, DN_STR8(" ")).lhs;
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(vm_size, 0);
|
||||
} else if (DN_Str8StartsWith(line, VM_PEAK, DN_Str8EqCase_Insensitive)) {
|
||||
DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_PEAK.size, line.size));
|
||||
DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB")));
|
||||
DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs;
|
||||
DN_Str8ToU64Result to_u64 = DN_Str8ToU64(vm_size, 0);
|
||||
result.vm_peak = DN_Kilobytes(to_u64.value);
|
||||
DN_Assert(to_u64.success);
|
||||
}
|
||||
@ -1411,12 +1411,12 @@ static EM_BOOL EMWebSocketOnCloseCallback(int type, const EmscriptenWebSocketClo
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
static void DN_OS_HttpRequestEMFetchOnSuccessCallback(emscripten_fetch_t *fetch)
|
||||
{
|
||||
DN_OSHttpResponse *response = DN_CAST(DN_OSHttpResponse *) fetch->userData;
|
||||
DN_OSHttpResponse *response = DN_Cast(DN_OSHttpResponse *) fetch->userData;
|
||||
if (!DN_Check(response))
|
||||
return;
|
||||
|
||||
response->http_status = DN_CAST(DN_U32) fetch->status;
|
||||
response->body = DN_Str8_Alloc(response->arena, fetch->numBytes, DN_ZeroMem_No);
|
||||
response->http_status = DN_Cast(DN_U32) fetch->status;
|
||||
response->body = DN_Str8FromArena(response->arena, fetch->numBytes, DN_ZMem_No);
|
||||
if (response->body.data)
|
||||
DN_Memcpy(response->body.data, fetch->data, fetch->numBytes);
|
||||
|
||||
@ -1426,12 +1426,12 @@ static void DN_OS_HttpRequestEMFetchOnSuccessCallback(emscripten_fetch_t *fetch)
|
||||
|
||||
static void DN_OS_HttpRequestEMFetchOnErrorCallback(emscripten_fetch_t *fetch)
|
||||
{
|
||||
DN_OSHttpResponse *response = DN_CAST(DN_OSHttpResponse *) fetch->userData;
|
||||
DN_OSHttpResponse *response = DN_Cast(DN_OSHttpResponse *) fetch->userData;
|
||||
if (!DN_Check(response))
|
||||
return;
|
||||
|
||||
response->http_status = DN_CAST(DN_U32) fetch->status;
|
||||
response->body = DN_Str8_Alloc(response->arena, fetch->numBytes, DN_ZeroMem_No);
|
||||
response->http_status = DN_Cast(DN_U32) fetch->status;
|
||||
response->body = DN_Str8FromArena(response->arena, fetch->numBytes, DN_ZMem_No);
|
||||
if (response->body.size)
|
||||
DN_Memcpy(response->body.data, fetch->data, fetch->numBytes);
|
||||
|
||||
@ -1467,15 +1467,15 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
|
||||
|
||||
if (method.size >= sizeof(fetch_attribs.requestMethod)) {
|
||||
response->error_msg =
|
||||
DN_Str8_FromF(arena,
|
||||
DN_Str8FromFmtArena(arena,
|
||||
"Request method in EM has a size limit of 31 characters, method was "
|
||||
"'%.*s' which is %zu characters long",
|
||||
DN_STR_FMT(method),
|
||||
DN_Str8PrintFmt(method),
|
||||
method.size);
|
||||
DN_CheckF(method.size < sizeof(fetch_attribs.requestMethod),
|
||||
"%.*s",
|
||||
DN_STR_FMT(response->error_msg));
|
||||
response->error_code = DN_CAST(DN_U32) - 1;
|
||||
DN_Str8PrintFmt(response->error_msg));
|
||||
response->error_code = DN_Cast(DN_U32) - 1;
|
||||
DN_AtomicAddU32(&response->done, 1);
|
||||
return;
|
||||
}
|
||||
@ -1489,11 +1489,11 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
|
||||
fetch_attribs.onerror = DN_OS_HttpRequestEMFetchOnErrorCallback;
|
||||
fetch_attribs.userData = response;
|
||||
|
||||
DN_Str8 url = DN_Str8_FromF(tmem, "%.*s%.*s", DN_STR_FMT(host), DN_STR_FMT(path));
|
||||
DN_Str8 url = DN_Str8FromFmtArena(tmem, "%.*s%.*s", DN_Str8PrintFmt(host), DN_Str8PrintFmt(path));
|
||||
DN_LOG_InfoF("Initiating HTTP '%s' request to '%.*s' with payload '%.*s'",
|
||||
fetch_attribs.requestMethod,
|
||||
DN_STR_FMT(url),
|
||||
DN_STR_FMT(body));
|
||||
DN_Str8PrintFmt(url),
|
||||
DN_Str8PrintFmt(body));
|
||||
response->on_complete_semaphore = DN_OS_SemaphoreInit(0);
|
||||
response->em_handle = emscripten_fetch(&fetch_attribs, url.data);
|
||||
#else // #elif defined(DN_OS_WIN32)
|
||||
@ -1511,7 +1511,7 @@ DN_API void DN_OS_HttpRequestFree(DN_OSHttpResponse *response)
|
||||
}
|
||||
#endif // #elif defined(DN_OS_WIN32)
|
||||
|
||||
DN_Arena_Deinit(&response->tmp_arena);
|
||||
DN_ArenaDeinit(&response->tmp_arena);
|
||||
DN_OS_SemaphoreDeinit(&response->on_complete_semaphore);
|
||||
*response = {};
|
||||
}
|
||||
|
||||
@ -57,15 +57,15 @@ DN_API void DN_OS_Print(DN_OSPrintDest dest, DN_Str8 string)
|
||||
}
|
||||
|
||||
// NOTE: Write the string //////////////////////////////////////////////////////////////////////
|
||||
DN_Assert(string.size < DN_CAST(unsigned long) - 1);
|
||||
DN_Assert(string.size < DN_Cast(unsigned long) - 1);
|
||||
unsigned long bytes_written = 0;
|
||||
(void)bytes_written;
|
||||
if (print_to_console)
|
||||
WriteConsoleA(print_handle, string.data, DN_CAST(unsigned long) string.size, &bytes_written, nullptr);
|
||||
WriteConsoleA(print_handle, string.data, DN_Cast(unsigned long) string.size, &bytes_written, nullptr);
|
||||
else
|
||||
WriteFile(print_handle, string.data, DN_CAST(unsigned long) string.size, &bytes_written, nullptr);
|
||||
WriteFile(print_handle, string.data, DN_Cast(unsigned long) string.size, &bytes_written, nullptr);
|
||||
#else
|
||||
fprintf(dest == DN_OSPrintDest_Out ? stdout : stderr, "%.*s", DN_STR_FMT(string));
|
||||
fprintf(dest == DN_OSPrintDest_Out ? stdout : stderr, "%.*s", DN_Str8PrintFmt(string));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -91,20 +91,20 @@ DN_API void DN_OS_PrintStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 str
|
||||
if (style.colour)
|
||||
DN_OS_Print(dest, DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType_Fg, style.r, style.g, style.b));
|
||||
if (style.bold == DN_LOGBold_Yes)
|
||||
DN_OS_Print(dest, DN_STR8(DN_LOG_BoldEscapeCode));
|
||||
DN_OS_Print(dest, DN_Str8Lit(DN_LOG_BoldEscapeCode));
|
||||
DN_OS_Print(dest, string);
|
||||
if (style.colour || style.bold == DN_LOGBold_Yes)
|
||||
DN_OS_Print(dest, DN_STR8(DN_LOG_ResetEscapeCode));
|
||||
DN_OS_Print(dest, DN_Str8Lit(DN_LOG_ResetEscapeCode));
|
||||
}
|
||||
}
|
||||
|
||||
static char *DN_OS_PrintVSPrintfChunker_(const char *buf, void *user, int len)
|
||||
{
|
||||
DN_Str8 string = {};
|
||||
string.data = DN_CAST(char *) buf;
|
||||
string.data = DN_Cast(char *) buf;
|
||||
string.size = len;
|
||||
|
||||
DN_OSPrintDest dest = DN_CAST(DN_OSPrintDest) DN_CAST(uintptr_t) user;
|
||||
DN_OSPrintDest dest = DN_Cast(DN_OSPrintDest) DN_Cast(uintptr_t) user;
|
||||
DN_OS_Print(dest, string);
|
||||
return (char *)buf;
|
||||
}
|
||||
@ -113,7 +113,7 @@ DN_API void DN_OS_PrintFV(DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va
|
||||
{
|
||||
char buffer[STB_SPRINTF_MIN];
|
||||
STB_SPRINTF_DECORATE(vsprintfcb)
|
||||
(DN_OS_PrintVSPrintfChunker_, DN_CAST(void *) DN_CAST(uintptr_t) dest, buffer, fmt, args);
|
||||
(DN_OS_PrintVSPrintfChunker_, DN_Cast(void *) DN_Cast(uintptr_t) dest, buffer, fmt, args);
|
||||
}
|
||||
|
||||
DN_API void DN_OS_PrintFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
@ -122,17 +122,17 @@ DN_API void DN_OS_PrintFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_AT
|
||||
if (style.colour)
|
||||
DN_OS_Print(dest, DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType_Fg, style.r, style.g, style.b));
|
||||
if (style.bold == DN_LOGBold_Yes)
|
||||
DN_OS_Print(dest, DN_STR8(DN_LOG_BoldEscapeCode));
|
||||
DN_OS_Print(dest, DN_Str8Lit(DN_LOG_BoldEscapeCode));
|
||||
DN_OS_PrintFV(dest, fmt, args);
|
||||
if (style.colour || style.bold == DN_LOGBold_Yes)
|
||||
DN_OS_Print(dest, DN_STR8(DN_LOG_ResetEscapeCode));
|
||||
DN_OS_Print(dest, DN_Str8Lit(DN_LOG_ResetEscapeCode));
|
||||
}
|
||||
}
|
||||
|
||||
DN_API void DN_OS_PrintLn(DN_OSPrintDest dest, DN_Str8 string)
|
||||
{
|
||||
DN_OS_Print(dest, string);
|
||||
DN_OS_Print(dest, DN_STR8("\n"));
|
||||
DN_OS_Print(dest, DN_Str8Lit("\n"));
|
||||
}
|
||||
|
||||
DN_API void DN_OS_PrintLnF(DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
@ -146,13 +146,13 @@ DN_API void DN_OS_PrintLnF(DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, .
|
||||
DN_API void DN_OS_PrintLnFV(DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_OS_PrintFV(dest, fmt, args);
|
||||
DN_OS_Print(dest, DN_STR8("\n"));
|
||||
DN_OS_Print(dest, DN_Str8Lit("\n"));
|
||||
}
|
||||
|
||||
DN_API void DN_OS_PrintLnStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 string)
|
||||
{
|
||||
DN_OS_PrintStyle(dest, style, string);
|
||||
DN_OS_Print(dest, DN_STR8("\n"));
|
||||
DN_OS_Print(dest, DN_Str8Lit("\n"));
|
||||
}
|
||||
|
||||
DN_API void DN_OS_PrintLnFStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
@ -166,5 +166,5 @@ DN_API void DN_OS_PrintLnFStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_A
|
||||
DN_API void DN_OS_PrintLnFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_OS_PrintFVStyle(dest, style, fmt, args);
|
||||
DN_OS_Print(dest, DN_STR8("\n"));
|
||||
DN_OS_Print(dest, DN_Str8Lit("\n"));
|
||||
}
|
||||
|
||||
@ -3,230 +3,227 @@
|
||||
#include "../dn_base_inc.h"
|
||||
#include "../dn_os_inc.h"
|
||||
|
||||
// NOTE: DN_Str8 ///////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_Str8 DN_Str8_FromFrameF(DN_FMT_ATTRIB char const *fmt, ...)
|
||||
// NOTE: DN_Str8
|
||||
DN_API DN_Str8 DN_Str8FromFmtArenaFrame(DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSGet()->frame_arena, fmt, args);
|
||||
DN_Arena *frame_arena = DN_OS_TLSGet()->frame_arena;
|
||||
DN_Str8 result = DN_Str8FromFmtVArena(frame_arena, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromFrameFV(DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
DN_API DN_Str8 DN_Str8FromFmtVArenaFrame(DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSGet()->frame_arena, fmt, args);
|
||||
DN_Arena *frame_arena = DN_OS_TLSGet()->frame_arena;
|
||||
DN_Str8 result = DN_Str8FromFmtVArena(frame_arena, fmt, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromFrame(DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_API DN_Str8 DN_Str8FromArenaFrame(DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Alloc(DN_OS_TLSGet()->frame_arena, size, zero_mem);
|
||||
DN_Arena *frame_arena = DN_OS_TLSGet()->frame_arena;
|
||||
DN_Str8 result = DN_Str8FromArena(frame_arena, size, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromHeapF(DN_FMT_ATTRIB char const *fmt, ...)
|
||||
DN_API DN_Str8 DN_Str8FromHeapF(DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
DN_Str8 result = {};
|
||||
DN_USize size = DN_CStr8_FVSize(fmt, args);
|
||||
if (size) {
|
||||
result = DN_Str8_FromHeap(size, DN_ZeroMem_No);
|
||||
if (DN_Str8_HasData(result))
|
||||
DN_VSNPrintF(result.data, DN_SaturateCastISizeToInt(size + 1 /*null-terminator*/), fmt, args);
|
||||
}
|
||||
|
||||
DN_USize size = DN_FmtVSize(fmt, args);
|
||||
DN_Str8 result = DN_Str8FromHeap(size, DN_ZMem_No);
|
||||
DN_VSNPrintF(result.data, DN_Cast(int)(result.size + 1), fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromHeap(DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_API DN_Str8 DN_Str8FromHeap(DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
result.data = DN_CAST(char *)DN_OS_MemAlloc(size + 1, zero_mem);
|
||||
if (result.data)
|
||||
result.size = size;
|
||||
result.data[result.size] = 0;
|
||||
result.data = DN_Cast(char *)DN_OS_MemAlloc(size + 1, z_mem);
|
||||
if (result.data) {
|
||||
result.size = size;
|
||||
result.data[result.size] = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromTLSFV(DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
DN_API DN_Str8 DN_Str8FromTLSFV(DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSTopArena(), fmt, args);
|
||||
DN_Str8 result = DN_Str8FromFmtVArena(DN_OS_TLSTopArena(), fmt, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromTLSF(DN_FMT_ATTRIB char const *fmt, ...)
|
||||
DN_API DN_Str8 DN_Str8FromTLSF(DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSTopArena(), fmt, args);
|
||||
DN_Str8 result = DN_Str8FromFmtVArena(DN_OS_TLSTopArena(), fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromTLS(DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_API DN_Str8 DN_Str8FromTLS(DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Alloc(DN_OS_TLSTopArena(), size, zero_mem);
|
||||
DN_Str8 result = DN_Str8FromArena(DN_OS_TLSTopArena(), size, z_mem);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromStr8Frame(DN_Str8 string)
|
||||
DN_API DN_Str8 DN_Str8FromStr8Frame(DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_FromStr8(DN_OS_TLSGet()->frame_arena, string);
|
||||
DN_Str8 result = DN_Str8FromStr8Arena(DN_OS_TLSGet()->frame_arena, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromStr8TLS(DN_Str8 string)
|
||||
DN_API DN_Str8 DN_Str8FromStr8TLS(DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_FromStr8(DN_OS_TLSTopArena(), string);
|
||||
DN_Str8 result = DN_Str8FromStr8Arena(DN_OS_TLSTopArena(), string);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8_SplitFromFrame(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode)
|
||||
DN_API DN_Str8SplitResult DN_Str8SplitFromFrame(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode)
|
||||
{
|
||||
DN_Slice<DN_Str8> result = DN_Str8_SplitAlloc(DN_OS_TLSGet()->frame_arena, string, delimiter, mode);
|
||||
DN_Str8SplitResult result = DN_Str8SplitArena(DN_OS_TLSGet()->frame_arena, string, delimiter, mode);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8_SplitFromTLS(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode)
|
||||
DN_API DN_Str8SplitResult DN_Str8SplitFromTLS(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode)
|
||||
{
|
||||
DN_Slice<DN_Str8> result = DN_Str8_SplitAlloc(DN_OS_TLSTopArena(), string, delimiter, mode);
|
||||
DN_Str8SplitResult result = DN_Str8SplitArena(DN_OS_TLSTopArena(), string, delimiter, mode);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_SegmentFromFrame(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
DN_API DN_Str8 DN_Str8SegmentFromFrame(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Segment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char);
|
||||
DN_Str8 result = DN_Str8Segment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_SegmentFromTLS(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
DN_API DN_Str8 DN_Str8SegmentFromTLS(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Segment(DN_OS_TLSTopArena(), src, segment_size, segment_char);
|
||||
DN_Str8 result = DN_Str8Segment(DN_OS_TLSTopArena(), src, segment_size, segment_char);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_ReverseSegmentFromFrame(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
DN_API DN_Str8 DN_Str8ReverseSegmentFromFrame(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_ReverseSegment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char);
|
||||
DN_Str8 result = DN_Str8ReverseSegment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_ReverseSegmentFromTLS(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
DN_API DN_Str8 DN_Str8ReverseSegmentFromTLS(DN_Str8 src, DN_USize segment_size, char segment_char)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_ReverseSegment(DN_OS_TLSTopArena(), src, segment_size, segment_char);
|
||||
DN_Str8 result = DN_Str8ReverseSegment(DN_OS_TLSTopArena(), src, segment_size, segment_char);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_AppendFFromFrame(DN_Str8 string, char const *fmt, ...)
|
||||
DN_API DN_Str8 DN_Str8AppendFFromFrame(DN_Str8 string, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Str8_AppendFV(DN_OS_TLSGet()->frame_arena, string, fmt, args);
|
||||
DN_Str8 result = DN_Str8AppendFV(DN_OS_TLSGet()->frame_arena, string, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_AppendFFromTLS(DN_Str8 string, char const *fmt, ...)
|
||||
DN_API DN_Str8 DN_Str8AppendFFromTLS(DN_Str8 string, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Str8_AppendFV(DN_OS_TLSTopArena(), string, fmt, args);
|
||||
DN_Str8 result = DN_Str8AppendFV(DN_OS_TLSTopArena(), string, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FillFFromFrame(DN_USize count, char const *fmt, ...)
|
||||
DN_API DN_Str8 DN_Str8FillFFromFrame(DN_USize count, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Str8_FillFV(DN_OS_TLSGet()->frame_arena, count, fmt, args);
|
||||
DN_Str8 result = DN_Str8FillFV(DN_OS_TLSGet()->frame_arena, count, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FillFFromTLS(DN_USize count, char const *fmt, ...)
|
||||
DN_API DN_Str8 DN_Str8FillFFromTLS(DN_USize count, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 result = DN_Str8_FillFV(DN_OS_TLSTopArena(), count, fmt, args);
|
||||
DN_Str8 result = DN_Str8FillFV(DN_OS_TLSTopArena(), count, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromFrame(DN_Str8 str8, uint32_t side_size, DN_Str8 truncator)
|
||||
DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaFrame(DN_Str8 str8, uint32_t side_size, DN_Str8 truncator)
|
||||
{
|
||||
DN_Str8DotTruncateResult result = DN_Str8_DotTruncateMiddle(DN_OS_TLSGet()->frame_arena, str8, side_size, truncator);
|
||||
DN_Str8TruncateResult result = DN_Str8TruncateMiddle(DN_OS_TLSGet()->frame_arena, str8, side_size, truncator);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromTLS(DN_Str8 str8, uint32_t side_size, DN_Str8 truncator)
|
||||
DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaTLS(DN_Str8 str8, uint32_t side_size, DN_Str8 truncator)
|
||||
{
|
||||
DN_Str8DotTruncateResult result = DN_Str8_DotTruncateMiddle(DN_OS_TLSTopArena(), str8, side_size, truncator);
|
||||
DN_Str8TruncateResult result = DN_Str8TruncateMiddle(DN_OS_TLSTopArena(), str8, side_size, truncator);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
DN_API DN_Str8 DN_Str8_PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad)
|
||||
DN_API DN_Str8 DN_Str8PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad)
|
||||
{
|
||||
// TODO: Implement this without requiring TLS so it can go into base strings
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(arena);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromTLS();
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
|
||||
DN_Str8BSplitResult split = DN_Str8_BSplit(src, DN_STR8("\n"));
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(src, DN_Str8Lit("\n"));
|
||||
while (split.lhs.size) {
|
||||
DN_Str8Builder_AppendRef(&builder, pad);
|
||||
DN_Str8Builder_AppendRef(&builder, split.lhs);
|
||||
split = DN_Str8_BSplit(split.rhs, DN_STR8("\n"));
|
||||
DN_Str8BuilderAppendRef(&builder, pad);
|
||||
DN_Str8BuilderAppendRef(&builder, split.lhs);
|
||||
split = DN_Str8BSplit(split.rhs, DN_Str8Lit("\n"));
|
||||
if (split.lhs.size)
|
||||
DN_Str8Builder_AppendRef(&builder, DN_STR8("\n"));
|
||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("\n"));
|
||||
}
|
||||
|
||||
DN_Str8 result = DN_Str8Builder_Build(&builder, arena);
|
||||
DN_Str8 result = DN_Str8BuilderBuild(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_PadNewLinesFromFrame(DN_Str8 src, DN_Str8 pad)
|
||||
DN_API DN_Str8 DN_Str8PadNewLinesFromFrame(DN_Str8 src, DN_Str8 pad)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_PadNewLines(DN_OS_TLSGet()->frame_arena, src, pad);
|
||||
DN_Str8 result = DN_Str8PadNewLines(DN_OS_TLSGet()->frame_arena, src, pad);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_PadNewLinesFromTLS(DN_Str8 src, DN_Str8 pad)
|
||||
DN_API DN_Str8 DN_Str8PadNewLinesFromTLS(DN_Str8 src, DN_Str8 pad)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_PadNewLines(DN_OS_TLSTopArena(), src, pad);
|
||||
DN_Str8 result = DN_Str8PadNewLines(DN_OS_TLSTopArena(), src, pad);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_UpperFromFrame(DN_Str8 string)
|
||||
DN_API DN_Str8 DN_Str8UpperFromFrame(DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Upper(DN_OS_TLSGet()->frame_arena, string);
|
||||
DN_Str8 result = DN_Str8Upper(DN_OS_TLSGet()->frame_arena, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_UpperFromTLS(DN_Str8 string)
|
||||
DN_API DN_Str8 DN_Str8UpperFromTLS(DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Upper(DN_OS_TLSTopArena(), string);
|
||||
DN_Str8 result = DN_Str8Upper(DN_OS_TLSTopArena(), string);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_LowerFromFrame(DN_Str8 string)
|
||||
DN_API DN_Str8 DN_Str8LowerFromFrame(DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Lower(DN_OS_TLSGet()->frame_arena, string);
|
||||
DN_Str8 result = DN_Str8Lower(DN_OS_TLSGet()->frame_arena, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_LowerFromTLS(DN_Str8 string)
|
||||
DN_API DN_Str8 DN_Str8LowerFromTLS(DN_Str8 string)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Lower(DN_OS_TLSTopArena(), string);
|
||||
DN_Str8 result = DN_Str8Lower(DN_OS_TLSTopArena(), string);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_Replace(DN_Str8 string,
|
||||
DN_API DN_Str8 DN_Str8Replace(DN_Str8 string,
|
||||
DN_Str8 find,
|
||||
DN_Str8 replace,
|
||||
DN_USize start_index,
|
||||
@ -235,19 +232,19 @@ DN_API DN_Str8 DN_Str8_Replace(DN_Str8 string,
|
||||
{
|
||||
// TODO: Implement this without requiring TLS so it can go into base strings
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Str8_HasData(string) || !DN_Str8_HasData(find) || find.size > string.size || find.size == 0 || string.size == 0) {
|
||||
result = DN_Str8_FromStr8(arena, string);
|
||||
if (string.size == 0 || find.size == 0 || find.size > string.size || find.size == 0 || string.size == 0) {
|
||||
result = DN_Str8FromStr8Arena(arena, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
DN_Str8Builder string_builder = DN_Str8Builder_FromArena(tmem.arena);
|
||||
DN_Str8Builder string_builder = DN_Str8BuilderFromArena(tmem.arena);
|
||||
DN_USize max = string.size - find.size;
|
||||
DN_USize head = start_index;
|
||||
|
||||
for (DN_USize tail = head; tail <= max; tail++) {
|
||||
DN_Str8 check = DN_Str8_Slice(string, tail, find.size);
|
||||
if (!DN_Str8_Eq(check, find, eq_case))
|
||||
DN_Str8 check = DN_Str8Slice(string, tail, find.size);
|
||||
if (!DN_Str8Eq(check, find, eq_case))
|
||||
continue;
|
||||
|
||||
if (start_index > 0 && string_builder.string_size == 0) {
|
||||
@ -255,43 +252,43 @@ DN_API DN_Str8 DN_Str8_Replace(DN_Str8 string,
|
||||
// need to add the string up to the hint. We only do this if there's
|
||||
// a replacement action, otherwise we have a special case for no
|
||||
// replacements, where the entire string gets copied.
|
||||
DN_Str8 slice = DN_Str8_Init(string.data, head);
|
||||
DN_Str8Builder_AppendRef(&string_builder, slice);
|
||||
DN_Str8 slice = DN_Str8FromPtr(string.data, head);
|
||||
DN_Str8BuilderAppendRef(&string_builder, slice);
|
||||
}
|
||||
|
||||
DN_Str8 range = DN_Str8_Slice(string, head, (tail - head));
|
||||
DN_Str8Builder_AppendRef(&string_builder, range);
|
||||
DN_Str8Builder_AppendRef(&string_builder, replace);
|
||||
DN_Str8 range = DN_Str8Slice(string, head, (tail - head));
|
||||
DN_Str8BuilderAppendRef(&string_builder, range);
|
||||
DN_Str8BuilderAppendRef(&string_builder, replace);
|
||||
head = tail + find.size;
|
||||
tail += find.size - 1; // NOTE: -1 since the for loop will post increment us past the end of the find string
|
||||
}
|
||||
|
||||
if (string_builder.string_size == 0) {
|
||||
// NOTE: No replacement possible, so we just do a full-copy
|
||||
result = DN_Str8_FromStr8(arena, string);
|
||||
result = DN_Str8FromStr8Arena(arena, string);
|
||||
} else {
|
||||
DN_Str8 remainder = DN_Str8_Init(string.data + head, string.size - head);
|
||||
DN_Str8Builder_AppendRef(&string_builder, remainder);
|
||||
result = DN_Str8Builder_Build(&string_builder, arena);
|
||||
DN_Str8 remainder = DN_Str8FromPtr(string.data + head, string.size - head);
|
||||
DN_Str8BuilderAppendRef(&string_builder, remainder);
|
||||
result = DN_Str8BuilderBuild(&string_builder, arena);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_Str8_ReplaceInsensitive(DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena)
|
||||
DN_API DN_Str8 DN_Str8ReplaceInsensitive(DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena)
|
||||
{
|
||||
DN_Str8 result = DN_Str8_Replace(string, find, replace, start_index, arena, DN_Str8EqCase_Insensitive);
|
||||
DN_Str8 result = DN_Str8Replace(string, find, replace, start_index, arena, DN_Str8EqCase_Insensitive);
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: DN_Str8Builder ////////////////////////////////////////////////////////////////////////////
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildFromOSHeap(DN_Str8Builder const *builder)
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildFromOSHeap(DN_Str8Builder const *builder)
|
||||
{
|
||||
DN_Str8 result = DN_ZeroInit;
|
||||
if (!builder || builder->string_size <= 0 || builder->count <= 0)
|
||||
return result;
|
||||
|
||||
result.data = DN_CAST(char *) DN_OS_MemAlloc(builder->string_size + 1, DN_ZeroMem_No);
|
||||
result.data = DN_Cast(char *) DN_OS_MemAlloc(builder->string_size + 1, DN_ZMem_No);
|
||||
if (!result.data)
|
||||
return result;
|
||||
|
||||
|
||||
@ -6,69 +6,69 @@
|
||||
|
||||
// NOTE: DN_Str8 ///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FromFrameFV (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8_FromFrameF (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FromFrame (DN_USize size, DN_ZeroMem zero_mem);
|
||||
DN_API DN_Str8 DN_Str8_FromHeapF (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FromHeap (DN_USize size, DN_ZeroMem zero_mem);
|
||||
DN_API DN_Str8 DN_Str8_FromTLSFV (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8_FromTLSF (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FromTLS (DN_USize size, DN_ZeroMem zero_mem);
|
||||
DN_API DN_Str8 DN_Str8_FromStr8Frame (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_FromStr8TLS (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FromFmtVArenaFrame (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8FromFmtArenaFrame (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FromArenaFrame (DN_USize size, DN_ZMem z_mem);
|
||||
DN_API DN_Str8 DN_Str8FromHeapF (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FromHeap (DN_USize size, DN_ZMem z_mem);
|
||||
DN_API DN_Str8 DN_Str8FromTLSFV (DN_FMT_ATTRIB char const *fmt, va_list args);
|
||||
DN_API DN_Str8 DN_Str8FromTLSF (DN_FMT_ATTRIB char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FromTLS (DN_USize size, DN_ZMem z_mem);
|
||||
DN_API DN_Str8 DN_Str8FromStr8Frame (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8FromStr8TLS (DN_Str8 string);
|
||||
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8_SplitFromFrame (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8_SplitFromTLS (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8SplitResult DN_Str8SplitFromFrame (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8SplitResult DN_Str8SplitFromTLS (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_SegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8_SegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8SegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8SegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_ReverseSegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8_ReverseSegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8ReverseSegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
DN_API DN_Str8 DN_Str8ReverseSegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_AppendFFromFrame (DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_AppendFFromTLS (DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8AppendFFromFrame (DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8AppendFFromTLS (DN_Str8 string, char const *fmt, ...);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_FillFFromFrame (DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8_FillFFromTLS (DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FillFFromFrame (DN_Str8 string, char const *fmt, ...);
|
||||
DN_API DN_Str8 DN_Str8FillFFromTLS (DN_Str8 string, char const *fmt, ...);
|
||||
|
||||
DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromFrame (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator);
|
||||
DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromTLS (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator);
|
||||
DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaFrame (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator);
|
||||
DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaTLS (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_PadNewLines (DN_Arena *arena, DN_Str8 src, DN_Str8 pad);
|
||||
DN_API DN_Str8 DN_Str8_PadNewLinesFromFrame (DN_Str8 src, DN_Str8 pad);
|
||||
DN_API DN_Str8 DN_Str8_PadNewLinesFromTLS (DN_Str8 src, DN_Str8 pad);
|
||||
DN_API DN_Str8 DN_Str8PadNewLines (DN_Arena *arena, DN_Str8 src, DN_Str8 pad);
|
||||
DN_API DN_Str8 DN_Str8PadNewLinesFromFrame (DN_Str8 src, DN_Str8 pad);
|
||||
DN_API DN_Str8 DN_Str8PadNewLinesFromTLS (DN_Str8 src, DN_Str8 pad);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_UpperFromFrame (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_UpperFromTLS (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8UpperFromFrame (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8UpperFromTLS (DN_Str8 string);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_LowerFromFrame (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8_LowerFromTLS (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8LowerFromFrame (DN_Str8 string);
|
||||
DN_API DN_Str8 DN_Str8LowerFromTLS (DN_Str8 string);
|
||||
|
||||
DN_API DN_Str8 DN_Str8_Replace (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8_ReplaceInsensitive (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena);
|
||||
DN_API DN_Str8 DN_Str8Replace (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive);
|
||||
DN_API DN_Str8 DN_Str8ReplaceInsensitive (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena);
|
||||
|
||||
// NOTE: DN_Str8Builder ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromArena () { return DN_Str8Builder_FromArena(DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromTLS () { return DN_Str8Builder_FromArena(DN_OS_TLSTopArena()); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromArena () { return DN_Str8BuilderFromArena(DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromTLS () { return DN_Str8BuilderFromArena(DN_OS_TLSTopArena()); }
|
||||
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrRefFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrRef(DN_OS_TLSGet()->frame_arena, strings, size); }
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrRefTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrRef(DN_OS_TLSTopArena(), strings, size); }
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopyFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrCopy(DN_OS_TLSGet()->frame_arena, strings, size); }
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopyTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrCopy(DN_OS_TLSTopArena(), strings, size); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRefFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrRef(DN_OS_TLSGet()->frame_arena, strings, size); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRefTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrRef(DN_OS_TLSTopArena(), strings, size); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopyFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrCopy(DN_OS_TLSGet()->frame_arena, strings, size); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopyTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrCopy(DN_OS_TLSTopArena(), strings, size); }
|
||||
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromBuilderFrame (DN_Str8Builder const *builder) { return DN_Str8Builder_FromBuilder(DN_OS_TLSGet()->frame_arena, builder); }
|
||||
DN_API DN_Str8Builder DN_Str8Builder_FromBuilderTLS (DN_Str8Builder const *builder) { return DN_Str8Builder_FromBuilder(DN_OS_TLSTopArena(), builder); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromBuilderFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderFromBuilder(DN_OS_TLSGet()->frame_arena, builder); }
|
||||
DN_API DN_Str8Builder DN_Str8BuilderFromBuilderTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderFromBuilder(DN_OS_TLSTopArena(), builder); }
|
||||
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildFromFrame (DN_Str8Builder const *builder) { return DN_Str8Builder_Build(builder, DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildFromHeap (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildFromTLS (DN_Str8Builder const *builder) { return DN_Str8Builder_Build(builder, DN_OS_TLSTopArena()); }
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildFromFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderBuild(builder, DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildFromHeap (DN_Str8Builder const *builder, DN_Arena *arena);
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildFromTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderBuild(builder, DN_OS_TLSTopArena()); }
|
||||
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildDelimitedFromFrame(DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8Builder_BuildDelimited(builder, delimiter, DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Str8 DN_Str8Builder_BuildDelimitedFromTLS (DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8Builder_BuildDelimited(builder, delimiter, DN_OS_TLSTopArena()); }
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildDelimitedFromFrame(DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8BuilderBuildDelimited(builder, delimiter, DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Str8 DN_Str8BuilderBuildDelimitedFromTLS (DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8BuilderBuildDelimited(builder, delimiter, DN_OS_TLSTopArena()); }
|
||||
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8Builder_BuildSliceFromFrame (DN_Str8Builder const *builder) { return DN_Str8Builder_BuildSlice(builder, DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8Builder_BuildSliceFromTLS (DN_Str8Builder const *builder) { return DN_Str8Builder_BuildSlice(builder, DN_OS_TLSTopArena()); }
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8BuilderBuildSliceFromFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderBuildSlice(builder, DN_OS_TLSGet()->frame_arena); }
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8BuilderBuildSliceFromTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderBuildSlice(builder, DN_OS_TLSTopArena()); }
|
||||
|
||||
#endif // !defined(DN_OS_STRING_H)
|
||||
|
||||
@ -5,7 +5,7 @@ DN_OSTLSTMem::DN_OSTLSTMem(DN_OSTLS *tls, DN_U8 arena_index, DN_OSTLSPushTMem pu
|
||||
{
|
||||
DN_Assert(arena_index == DN_OSTLSArena_TMem0 || arena_index == DN_OSTLSArena_TMem1);
|
||||
arena = tls->arenas + arena_index;
|
||||
temp_mem = DN_Arena_TempMemBegin(arena);
|
||||
temp_mem = DN_ArenaTempMemBegin(arena);
|
||||
destructed = false;
|
||||
push_arena = push_tmem;
|
||||
if (push_arena)
|
||||
@ -15,7 +15,7 @@ DN_OSTLSTMem::DN_OSTLSTMem(DN_OSTLS *tls, DN_U8 arena_index, DN_OSTLSPushTMem pu
|
||||
DN_OSTLSTMem::~DN_OSTLSTMem()
|
||||
{
|
||||
DN_Assert(destructed == false);
|
||||
DN_Arena_TempMemEnd(temp_mem);
|
||||
DN_ArenaTempMemEnd(temp_mem);
|
||||
destructed = true;
|
||||
if (push_arena)
|
||||
DN_OS_TLSPopArena();
|
||||
@ -37,9 +37,9 @@ DN_API void DN_OS_TLSInit(DN_OSTLS *tls, DN_OSTLSInitArgs args)
|
||||
// for setting up the alloc tracking data structures.
|
||||
for (DN_ForItCArray(it, DN_Arena, tls->arenas)) {
|
||||
DN_Arena *arena = it.data;
|
||||
switch (DN_CAST(DN_OSTLSArena) it.index) {
|
||||
default: *arena = DN_Arena_FromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break;
|
||||
case DN_OSTLSArena_ErrorSink: *arena = DN_Arena_FromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break;
|
||||
switch (DN_Cast(DN_OSTLSArena) it.index) {
|
||||
default: *arena = DN_ArenaFromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break;
|
||||
case DN_OSTLSArena_ErrorSink: *arena = DN_ArenaFromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break;
|
||||
case DN_OSTLSArena_Count: DN_InvalidCodePath; break;
|
||||
}
|
||||
}
|
||||
@ -55,7 +55,7 @@ DN_API void DN_OS_TLSDeinit(DN_OSTLS *tls)
|
||||
tls->err_sink = {};
|
||||
tls->arena_stack_index = {};
|
||||
for (DN_ForItCArray(it, DN_Arena, tls->arenas))
|
||||
DN_Arena_Deinit(it.data);
|
||||
DN_ArenaDeinit(it.data);
|
||||
}
|
||||
|
||||
DN_THREAD_LOCAL DN_OSTLS *g_dn_curr_thread_tls;
|
||||
@ -163,22 +163,22 @@ DN_API DN_OSErrSink *DN_OS_ErrSinkBegin_(DN_OSErrSinkMode mode, DN_CallSite call
|
||||
DN_OSTLS *tls = DN_OS_TLSGet();
|
||||
DN_OSErrSink *err = &tls->err_sink;
|
||||
DN_OSErrSink *result = err;
|
||||
DN_USize arena_pos = DN_Arena_Pos(result->arena);
|
||||
DN_USize arena_pos = DN_ArenaPos(result->arena);
|
||||
|
||||
if (tls->err_sink.stack_size == DN_ArrayCountU(err->stack)) {
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromTLS();
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
DN_USize counter = 0;
|
||||
for (DN_ForItSize(it, DN_OSErrSinkNode, err->stack, err->stack_size)) {
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(4) when a string is required in call to 'DN_Str8Builder_AppendF' Actual type: 'struct DN_Str8'.
|
||||
DN_Str8Builder_AppendF(&builder, " [%04zu] %S:%u %S\n", counter++, it.data->call_site.file, it.data->call_site.line, it.data->call_site.function);
|
||||
DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(4) when a string is required in call to 'DN_Str8BuilderAppendF' Actual type: 'struct DN_Str8'.
|
||||
DN_Str8BuilderAppendF(&builder, " [%04zu] %S:%u %S\n", counter++, it.data->call_site.file, it.data->call_site.line, it.data->call_site.function);
|
||||
DN_MSVC_WARNING_POP
|
||||
}
|
||||
|
||||
DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(6) when a string is required in call to 'DN_LOG_EmitFromType' Actual type: 'struct DN_Str8'.
|
||||
DN_AssertF(tls->err_sink.stack_size < DN_ArrayCountU(err->stack),
|
||||
"Error sink has run out of error scopes, potential leak. Scopes were\n%S", DN_Str8Builder_BuildFromTLS(&builder));
|
||||
"Error sink has run out of error scopes, potential leak. Scopes were\n%S", DN_Str8BuilderBuildFromTLS(&builder));
|
||||
DN_MSVC_WARNING_POP
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ DN_API DN_OSErrSink *DN_OS_ErrSinkBegin_(DN_OSErrSinkMode mode, DN_CallSite call
|
||||
|
||||
// NOTE: Handle allocation error
|
||||
if (!DN_Check(node && node->msg_sentinel)) {
|
||||
DN_Arena_PopTo(result->arena, arena_pos);
|
||||
DN_ArenaPopTo(result->arena, arena_pos);
|
||||
node->msg_sentinel = nullptr;
|
||||
tls->err_sink.stack_size--;
|
||||
}
|
||||
@ -221,8 +221,8 @@ DN_API DN_OSErrSinkMsg *DN_OS_ErrSinkEnd(DN_Arena *arena, DN_OSErrSink *err)
|
||||
DN_OSErrSinkNode *node = err->stack + (err->stack_size - 1);
|
||||
DN_OSErrSinkMsg *prev = nullptr;
|
||||
for (DN_OSErrSinkMsg *it = node->msg_sentinel->next; it != node->msg_sentinel; it = it->next) {
|
||||
DN_OSErrSinkMsg *entry = DN_Arena_New(arena, DN_OSErrSinkMsg, DN_ZeroMem_Yes);
|
||||
entry->msg = DN_Str8_FromStr8(arena, it->msg);
|
||||
DN_OSErrSinkMsg *entry = DN_ArenaNew(arena, DN_OSErrSinkMsg, DN_ZMem_Yes);
|
||||
entry->msg = DN_Str8FromStr8Arena(arena, it->msg);
|
||||
entry->call_site = it->call_site;
|
||||
entry->error_code = it->error_code;
|
||||
if (!result)
|
||||
@ -234,36 +234,36 @@ DN_API DN_OSErrSinkMsg *DN_OS_ErrSinkEnd(DN_Arena *arena, DN_OSErrSink *err)
|
||||
|
||||
// NOTE: Deallocate all the memory for this scope
|
||||
err->stack_size--;
|
||||
DN_Arena_PopTo(err->arena, node->arena_pos);
|
||||
DN_ArenaPopTo(err->arena, node->arena_pos);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_OS_ErrSinkAddMsgToStr8Builder_(DN_Str8Builder *builder, DN_OSErrSinkMsg *msg, DN_OSErrSinkMsg *end)
|
||||
static void DN_OS_ErrSinkAddMsgToStr8Builder(DN_Str8Builder *builder, DN_OSErrSinkMsg *msg, DN_OSErrSinkMsg *end)
|
||||
{
|
||||
if (msg == end) // NOTE: No error messages to add
|
||||
return;
|
||||
|
||||
if (msg->next == end) {
|
||||
DN_OSErrSinkMsg *it = msg;
|
||||
DN_Str8 file_name = DN_Str8_FileNameFromPath(it->call_site.file);
|
||||
DN_Str8Builder_AppendF(builder,
|
||||
DN_Str8 file_name = DN_Str8FileNameFromPath(it->call_site.file);
|
||||
DN_Str8BuilderAppendF(builder,
|
||||
"%.*s:%05I32u:%.*s %.*s",
|
||||
DN_STR_FMT(file_name),
|
||||
DN_Str8PrintFmt(file_name),
|
||||
it->call_site.line,
|
||||
DN_STR_FMT(it->call_site.function),
|
||||
DN_STR_FMT(it->msg));
|
||||
DN_Str8PrintFmt(it->call_site.function),
|
||||
DN_Str8PrintFmt(it->msg));
|
||||
} else {
|
||||
// NOTE: More than one message
|
||||
for (DN_OSErrSinkMsg *it = msg; it != end; it = it->next) {
|
||||
DN_Str8 file_name = DN_Str8_FileNameFromPath(it->call_site.file);
|
||||
DN_Str8Builder_AppendF(builder,
|
||||
DN_Str8 file_name = DN_Str8FileNameFromPath(it->call_site.file);
|
||||
DN_Str8BuilderAppendF(builder,
|
||||
"%s - %.*s:%05I32u:%.*s%s%.*s",
|
||||
it == msg ? "" : "\n",
|
||||
DN_STR_FMT(file_name),
|
||||
DN_Str8PrintFmt(file_name),
|
||||
it->call_site.line,
|
||||
DN_STR_FMT(it->call_site.function),
|
||||
DN_Str8_HasData(it->msg) ? " " : "",
|
||||
DN_STR_FMT(it->msg));
|
||||
DN_Str8PrintFmt(it->call_site.function),
|
||||
it->msg.size ? " " : "",
|
||||
DN_Str8PrintFmt(it->msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -280,16 +280,16 @@ DN_API DN_Str8 DN_OS_ErrSinkEndStr8(DN_Arena *arena, DN_OSErrSink *err)
|
||||
|
||||
// NOTE: Walk the list and allocate it onto the user's arena
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(arena);
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromTLS();
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
DN_OSErrSinkNode *node = err->stack + (err->stack_size - 1);
|
||||
DN_OS_ErrSinkAddMsgToStr8Builder_(&builder, node->msg_sentinel->next, node->msg_sentinel);
|
||||
DN_OS_ErrSinkAddMsgToStr8Builder(&builder, node->msg_sentinel->next, node->msg_sentinel);
|
||||
|
||||
// NOTE: Deallocate all the memory for this scope
|
||||
err->stack_size--;
|
||||
DN_U64 arena_pos = node->arena_pos;
|
||||
DN_Arena_PopTo(err->arena, arena_pos);
|
||||
DN_ArenaPopTo(err->arena, arena_pos);
|
||||
|
||||
result = DN_Str8Builder_Build(&builder, arena);
|
||||
result = DN_Str8BuilderBuild(&builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -310,20 +310,20 @@ DN_API bool DN_OS_ErrSinkEndAndLogError_(DN_OSErrSink *err, DN_CallSite call_sit
|
||||
if (!msg)
|
||||
return false;
|
||||
|
||||
DN_Str8Builder builder = DN_Str8Builder_FromTLS();
|
||||
if (DN_Str8_HasData(err_msg)) {
|
||||
DN_Str8Builder_AppendRef(&builder, err_msg);
|
||||
DN_Str8Builder_AppendRef(&builder, DN_STR8(":"));
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromTLS();
|
||||
if (err_msg.size) {
|
||||
DN_Str8BuilderAppendRef(&builder, err_msg);
|
||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit(":"));
|
||||
} else {
|
||||
DN_Str8Builder_AppendRef(&builder, DN_STR8("Error(s) encountered:"));
|
||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("Error(s) encountered:"));
|
||||
}
|
||||
|
||||
if (msg->next) // NOTE: More than 1 message
|
||||
DN_Str8Builder_AppendRef(&builder, DN_STR8("\n"));
|
||||
DN_OS_ErrSinkAddMsgToStr8Builder_(&builder, msg, nullptr);
|
||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("\n"));
|
||||
DN_OS_ErrSinkAddMsgToStr8Builder(&builder, msg, nullptr);
|
||||
|
||||
DN_Str8 log = DN_Str8Builder_BuildFromTLS(&builder);
|
||||
DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Error), call_site, "%.*s", DN_STR_FMT(log));
|
||||
DN_Str8 log = DN_Str8BuilderBuildFromTLS(&builder);
|
||||
DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Error), call_site, "%.*s", DN_Str8PrintFmt(log));
|
||||
|
||||
if (mode == DN_OSErrSinkMode_DebugBreakOnEndAndLog)
|
||||
DN_DebugBreak;
|
||||
@ -333,7 +333,7 @@ DN_API bool DN_OS_ErrSinkEndAndLogError_(DN_OSErrSink *err, DN_CallSite call_sit
|
||||
DN_API bool DN_OS_ErrSinkEndAndLogErrorFV_(DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 log = DN_Str8_FromFV(tmem.arena, fmt, args);
|
||||
DN_Str8 log = DN_Str8FromFmtVArena(tmem.arena, fmt, args);
|
||||
bool result = DN_OS_ErrSinkEndAndLogError_(err, call_site, log);
|
||||
return result;
|
||||
}
|
||||
@ -343,7 +343,7 @@ DN_API bool DN_OS_ErrSinkEndAndLogErrorF_(DN_OSErrSink *err, DN_CallSite call_si
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 log = DN_Str8_FromFV(tmem.arena, fmt, args);
|
||||
DN_Str8 log = DN_Str8FromFmtVArena(tmem.arena, fmt, args);
|
||||
bool result = DN_OS_ErrSinkEndAndLogError_(err, call_site, log);
|
||||
va_end(args);
|
||||
return result;
|
||||
@ -373,9 +373,9 @@ DN_API void DN_OS_ErrSinkAppendFV_(DN_OSErrSink *err, DN_U32 error_code, DN_FMT_
|
||||
DN_OSErrSinkNode *node = err->stack + (err->stack_size - 1);
|
||||
DN_AssertF(node, "Error sink must be begun by calling 'Begin' before using this function.");
|
||||
|
||||
DN_OSErrSinkMsg *msg = DN_Arena_New(err->arena, DN_OSErrSinkMsg, DN_ZeroMem_Yes);
|
||||
DN_OSErrSinkMsg *msg = DN_ArenaNew(err->arena, DN_OSErrSinkMsg, DN_ZMem_Yes);
|
||||
if (DN_Check(msg)) {
|
||||
msg->msg = DN_Str8_FromFV(err->arena, fmt, args);
|
||||
msg->msg = DN_Str8FromFmtVArena(err->arena, fmt, args);
|
||||
msg->error_code = error_code;
|
||||
msg->call_site = DN_OS_TLSGet()->call_site;
|
||||
DN_DLList_Prepend(node->msg_sentinel, msg);
|
||||
|
||||
@ -94,8 +94,8 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags)
|
||||
return 0;
|
||||
|
||||
static DN_Str8 const ALIGNMENT_ERROR_MSG =
|
||||
DN_STR8("Page protection requires pointers to be page aligned because we can only guard memory at a multiple of the page boundary.");
|
||||
DN_AssertF(DN_IsPowerOfTwoAligned(DN_CAST(uintptr_t) ptr, g_dn_os_core_->page_size), "%s", ALIGNMENT_ERROR_MSG.data);
|
||||
DN_Str8Lit("Page protection requires pointers to be page aligned because we can only guard memory at a multiple of the page boundary.");
|
||||
DN_AssertF(DN_IsPowerOfTwoAligned(DN_Cast(uintptr_t) ptr, g_dn_os_core_->page_size), "%s", ALIGNMENT_ERROR_MSG.data);
|
||||
DN_AssertF(DN_IsPowerOfTwoAligned(size, g_dn_os_core_->page_size), "%s", ALIGNMENT_ERROR_MSG.data);
|
||||
|
||||
unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags);
|
||||
@ -108,11 +108,11 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags)
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZeroMem zero_mem)
|
||||
DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem)
|
||||
{
|
||||
DN_U32 flags = zero_mem == DN_ZeroMem_Yes ? HEAP_ZERO_MEMORY : 0;
|
||||
DN_Assert(size <= DN_CAST(DWORD)(-1));
|
||||
void *result = HeapAlloc(GetProcessHeap(), flags, DN_CAST(DWORD) size);
|
||||
DN_U32 flags = z_mem == DN_ZMem_Yes ? HEAP_ZERO_MEMORY : 0;
|
||||
DN_Assert(size <= DN_Cast(DWORD)(-1));
|
||||
void *result = HeapAlloc(GetProcessHeap(), flags, DN_Cast(DWORD) size);
|
||||
DN_Assert(g_dn_os_core_);
|
||||
DN_AtomicAddU64(&g_dn_os_core_->mem_allocs_total, 1);
|
||||
DN_AtomicAddU64(&g_dn_os_core_->mem_allocs_frame, 1);
|
||||
@ -131,12 +131,12 @@ DN_API DN_OSDateTime DN_OS_DateLocalTimeNow()
|
||||
GetLocalTime(&sys_time);
|
||||
|
||||
DN_OSDateTime result = {};
|
||||
result.hour = DN_CAST(uint8_t) sys_time.wHour;
|
||||
result.minutes = DN_CAST(uint8_t) sys_time.wMinute;
|
||||
result.seconds = DN_CAST(uint8_t) sys_time.wSecond;
|
||||
result.day = DN_CAST(uint8_t) sys_time.wDay;
|
||||
result.month = DN_CAST(uint8_t) sys_time.wMonth;
|
||||
result.year = DN_CAST(int16_t) sys_time.wYear;
|
||||
result.hour = DN_Cast(uint8_t) sys_time.wHour;
|
||||
result.minutes = DN_Cast(uint8_t) sys_time.wMinute;
|
||||
result.seconds = DN_Cast(uint8_t) sys_time.wSecond;
|
||||
result.day = DN_Cast(uint8_t) sys_time.wDay;
|
||||
result.month = DN_Cast(uint8_t) sys_time.wMonth;
|
||||
result.year = DN_Cast(int16_t) sys_time.wYear;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -214,22 +214,22 @@ DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(DN_U64 time)
|
||||
FileTimeToSystemTime(&file_time, &sys_time);
|
||||
|
||||
DN_OSDateTime result = {};
|
||||
result.year = DN_CAST(uint16_t) sys_time.wYear;
|
||||
result.month = DN_CAST(uint8_t) sys_time.wMonth;
|
||||
result.day = DN_CAST(uint8_t) sys_time.wDay;
|
||||
result.hour = DN_CAST(uint8_t) sys_time.wHour;
|
||||
result.minutes = DN_CAST(uint8_t) sys_time.wMinute;
|
||||
result.seconds = DN_CAST(uint8_t) sys_time.wSecond;
|
||||
result.year = DN_Cast(uint16_t) sys_time.wYear;
|
||||
result.month = DN_Cast(uint8_t) sys_time.wMonth;
|
||||
result.day = DN_Cast(uint8_t) sys_time.wDay;
|
||||
result.hour = DN_Cast(uint8_t) sys_time.wHour;
|
||||
result.minutes = DN_Cast(uint8_t) sys_time.wMinute;
|
||||
result.seconds = DN_Cast(uint8_t) sys_time.wSecond;
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
|
||||
{
|
||||
DN_Assert(g_dn_os_core_);
|
||||
DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context;
|
||||
DN_W32Core *w32 = DN_Cast(DN_W32Core *) g_dn_os_core_->platform_context;
|
||||
DN_Assert(w32->bcrypt_init_success);
|
||||
|
||||
long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_CAST(unsigned char *) buffer, size, 0 /*flags*/);
|
||||
long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_Cast(unsigned char *) buffer, size, 0 /*flags*/);
|
||||
// NOTE: This can only fail if the handle is invalid or one or more parameters are invalid. We
|
||||
// validate our parameters so this shouldn't be the case.
|
||||
DN_Assert(gen_status == 0);
|
||||
@ -284,7 +284,7 @@ DN_API void DN_OS_SleepMs(DN_UInt milliseconds)
|
||||
DN_API DN_U64 DN_OS_PerfCounterFrequency()
|
||||
{
|
||||
DN_Assert(g_dn_os_core_);
|
||||
DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context;
|
||||
DN_W32Core *w32 = DN_Cast(DN_W32Core *) g_dn_os_core_->platform_context;
|
||||
DN_Assert(w32->qpc_frequency.QuadPart);
|
||||
DN_U64 result = w32->qpc_frequency.QuadPart;
|
||||
return result;
|
||||
@ -322,10 +322,10 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
DN_OS_ErrSinkAppendF(err,
|
||||
win_error.code,
|
||||
"Failed to copy file '%.*s' to '%.*s': (%u) %.*s",
|
||||
DN_STR_FMT(src),
|
||||
DN_STR_FMT(dest),
|
||||
DN_Str8PrintFmt(src),
|
||||
DN_Str8PrintFmt(dest),
|
||||
win_error.code,
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -347,10 +347,10 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
DN_OS_ErrSinkAppendF(err,
|
||||
win_error.code,
|
||||
"Failed to move file '%.*s' to '%.*s': (%u) %.*s",
|
||||
DN_STR_FMT(src),
|
||||
DN_STR_FMT(dest),
|
||||
DN_Str8PrintFmt(src),
|
||||
DN_Str8PrintFmt(dest),
|
||||
win_error.code,
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -358,7 +358,7 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
|
||||
DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 access, DN_OSErrSink *err)
|
||||
{
|
||||
DN_OSFile result = {};
|
||||
if (!DN_Str8_HasData(path) || path.size <= 0)
|
||||
if (path.size == 0 || path.size <= 0)
|
||||
return result;
|
||||
|
||||
if ((access & ~DN_OSFileAccess_All) || ((access & DN_OSFileAccess_All) == 0)) {
|
||||
@ -401,7 +401,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 ac
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
DN_W32Error win_error = DN_W32_LastError(tmem.arena);
|
||||
result.error = true;
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to open file at '%.*s': '%.*s'", DN_STR_FMT(path), DN_STR_FMT(win_error.msg));
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to open file at '%.*s': '%.*s'", DN_Str8PrintFmt(path), DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -417,24 +417,24 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
if (!DN_Check(size <= (unsigned long)-1)) {
|
||||
DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size);
|
||||
DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size);
|
||||
DN_OS_ErrSinkAppendF(
|
||||
err,
|
||||
1 /*error_code*/,
|
||||
"Current implementation doesn't support reading >4GiB file (requested %.*s), implement Win32 overlapped IO",
|
||||
DN_STR_FMT(buffer_size_str8));
|
||||
DN_Str8PrintFmt(buffer_size_str8));
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long bytes_read = 0;
|
||||
unsigned long read_result = ReadFile(/*HANDLE hFile*/ file->handle,
|
||||
/*LPVOID lpBuffer*/ buffer,
|
||||
/*DWORD nNumberOfBytesToRead*/ DN_CAST(unsigned long) size,
|
||||
/*DWORD nNumberOfBytesToRead*/ DN_Cast(unsigned long) size,
|
||||
/*LPDWORD lpNumberOfByesRead*/ &bytes_read,
|
||||
/*LPOVERLAPPED lpOverlapped*/ nullptr);
|
||||
if (read_result == 0) {
|
||||
DN_W32Error win_error = DN_W32_LastError(tmem.arena);
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to read data from file: (%u) %.*s", win_error.code, DN_STR_FMT(win_error.msg));
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to read data from file: (%u) %.*s", win_error.code, DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -445,9 +445,9 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size
|
||||
win_error.code,
|
||||
"Failed to read the desired number of bytes from file, we read %uB but we expected %uB: (%u) %.*s",
|
||||
bytes_read,
|
||||
DN_CAST(unsigned long) size,
|
||||
DN_Cast(unsigned long) size,
|
||||
win_error.code,
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -462,9 +462,9 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz
|
||||
return false;
|
||||
|
||||
bool result = true;
|
||||
char const *end = DN_CAST(char *) buffer + size;
|
||||
for (char const *ptr = DN_CAST(char const *) buffer; result && ptr != end;) {
|
||||
unsigned long write_size = DN_CAST(unsigned long) DN_Min((unsigned long)-1, end - ptr);
|
||||
char const *end = DN_Cast(char *) buffer + size;
|
||||
for (char const *ptr = DN_Cast(char const *) buffer; result && ptr != end;) {
|
||||
unsigned long write_size = DN_Cast(unsigned long) DN_Min((unsigned long)-1, end - ptr);
|
||||
unsigned long bytes_written = 0;
|
||||
result = WriteFile(file->handle, ptr, write_size, &bytes_written, nullptr /*lpOverlapped*/) != 0;
|
||||
ptr += bytes_written;
|
||||
@ -473,8 +473,8 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz
|
||||
if (!result) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_W32Error win_error = DN_W32_LastError(tmem.arena);
|
||||
DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size);
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to write buffer (%.*s) to file handle: %.*s", DN_STR_FMT(buffer_size_str8), DN_STR_FMT(win_error.msg));
|
||||
DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size);
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to write buffer (%.*s) to file handle: %.*s", DN_Str8PrintFmt(buffer_size_str8), DN_Str8PrintFmt(win_error.msg));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -484,14 +484,14 @@ DN_API bool DN_OS_FileFlush(DN_OSFile *file, DN_OSErrSink *err)
|
||||
if (!file || !file->handle || file->error)
|
||||
return false;
|
||||
|
||||
BOOL result = FlushFileBuffers(DN_CAST(HANDLE) file->handle);
|
||||
BOOL result = FlushFileBuffers(DN_Cast(HANDLE) file->handle);
|
||||
if (!result) {
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_W32Error win_error = DN_W32_LastError(tmem.arena);
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to flush file buffer to disk: %.*s", DN_STR_FMT(win_error.msg));
|
||||
DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to flush file buffer to disk: %.*s", DN_Str8PrintFmt(win_error.msg));
|
||||
}
|
||||
|
||||
return DN_CAST(bool) result;
|
||||
return DN_Cast(bool) result;
|
||||
}
|
||||
|
||||
DN_API void DN_OS_FileClose(DN_OSFile *file)
|
||||
@ -505,7 +505,7 @@ DN_API void DN_OS_FileClose(DN_OSFile *file)
|
||||
DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
|
||||
{
|
||||
DN_OSPathInfo result = {};
|
||||
if (!DN_Str8_HasData(path))
|
||||
if (path.size == 0)
|
||||
return result;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
@ -521,7 +521,7 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
|
||||
result.last_write_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftLastWriteTime);
|
||||
|
||||
LARGE_INTEGER large_int = {};
|
||||
large_int.u.HighPart = DN_CAST(int32_t) attrib_data.nFileSizeHigh;
|
||||
large_int.u.HighPart = DN_Cast(int32_t) attrib_data.nFileSizeHigh;
|
||||
large_int.u.LowPart = attrib_data.nFileSizeLow;
|
||||
result.size = (DN_U64)large_int.QuadPart;
|
||||
|
||||
@ -538,7 +538,7 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
|
||||
DN_API bool DN_OS_PathDelete(DN_Str8 path)
|
||||
{
|
||||
bool result = false;
|
||||
if (!DN_Str8_HasData(path))
|
||||
if (path.size == 0)
|
||||
return result;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
@ -554,7 +554,7 @@ DN_API bool DN_OS_PathDelete(DN_Str8 path)
|
||||
DN_API bool DN_OS_PathIsFile(DN_Str8 path)
|
||||
{
|
||||
bool result = false;
|
||||
if (!DN_Str8_HasData(path))
|
||||
if (path.size == 0)
|
||||
return result;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
@ -571,7 +571,7 @@ DN_API bool DN_OS_PathIsFile(DN_Str8 path)
|
||||
DN_API bool DN_OS_PathIsDir(DN_Str8 path)
|
||||
{
|
||||
bool result = false;
|
||||
if (!DN_Str8_HasData(path))
|
||||
if (path.size == 0)
|
||||
return result;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
@ -639,7 +639,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
|
||||
|
||||
DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
{
|
||||
if (!DN_Str8_HasData(path) || !it || path.size <= 0)
|
||||
if (path.size == 0 || !it || path.size <= 0)
|
||||
return false;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
@ -648,10 +648,10 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
if (it->handle) {
|
||||
wide_it.handle = it->handle;
|
||||
} else {
|
||||
bool needs_asterisks = DN_Str8_EndsWith(path, DN_STR8("\\")) ||
|
||||
DN_Str8_EndsWith(path, DN_STR8("/"));
|
||||
bool has_glob = DN_Str8_EndsWith(path, DN_STR8("\\*")) ||
|
||||
DN_Str8_EndsWith(path, DN_STR8("/*"));
|
||||
bool needs_asterisks = DN_Str8EndsWith(path, DN_Str8Lit("\\")) ||
|
||||
DN_Str8EndsWith(path, DN_Str8Lit("/"));
|
||||
bool has_glob = DN_Str8EndsWith(path, DN_Str8Lit("\\*")) ||
|
||||
DN_Str8EndsWith(path, DN_Str8Lit("/*"));
|
||||
|
||||
DN_Str8 adjusted_path = path;
|
||||
if (!has_glob) {
|
||||
@ -659,9 +659,9 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
// add those characters in this branch, so overwrite the null
|
||||
// character, add the glob and re-null terminate the buffer.
|
||||
if (needs_asterisks)
|
||||
adjusted_path = DN_OS_PathF(tmem.arena, "%.*s*", DN_STR_FMT(path));
|
||||
adjusted_path = DN_OS_PathF(tmem.arena, "%.*s*", DN_Str8PrintFmt(path));
|
||||
else
|
||||
adjusted_path = DN_OS_PathF(tmem.arena, "%.*s/*", DN_STR_FMT(path));
|
||||
adjusted_path = DN_OS_PathF(tmem.arena, "%.*s/*", DN_Str8PrintFmt(path));
|
||||
}
|
||||
|
||||
path16 = DN_W32_Str8ToStr16(tmem.arena, adjusted_path);
|
||||
@ -673,7 +673,7 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
it->handle = wide_it.handle;
|
||||
if (result) {
|
||||
int size = DN_W32_Str16ToStr8Buffer(wide_it.file_name, it->buffer, DN_ArrayCountU(it->buffer));
|
||||
it->file_name = DN_Str8_Init(it->buffer, size);
|
||||
it->file_name = DN_Str8FromPtr(it->buffer, size);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -683,7 +683,7 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
// NOTE: DN_OSExec /////////////////////////////////////////////////////////////////////////////////
|
||||
DN_API void DN_OS_Exit(int32_t exit_code)
|
||||
{
|
||||
ExitProcess(DN_CAST(UINT) exit_code);
|
||||
ExitProcess(DN_Cast(UINT) exit_code);
|
||||
}
|
||||
|
||||
DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
|
||||
@ -734,7 +734,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
|
||||
if (exec_result == WAIT_FAILED) {
|
||||
DN_W32Error win_error = DN_W32_LastError(tmem.arena);
|
||||
result.os_error_code = win_error.code;
|
||||
DN_OS_ErrSinkAppendF(err, result.os_error_code, "Executed command failed to terminate: %.*s", DN_STR_FMT(win_error.msg));
|
||||
DN_OS_ErrSinkAppendF(err, result.os_error_code, "Executed command failed to terminate: %.*s", DN_Str8PrintFmt(win_error.msg));
|
||||
} else if (DN_Check(exec_result == WAIT_TIMEOUT || exec_result == WAIT_OBJECT_0)) {
|
||||
// NOTE: Read stdout from process //////////////////////////////////////////////////////
|
||||
// If the pipes are full, the process will block. We periodically
|
||||
@ -746,7 +746,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
|
||||
DWORD bytes_read = 0;
|
||||
char *dest_buffer = handle.stdout_write && stdout_buffer ? stdout_buffer : sink;
|
||||
size_t dest_size = handle.stdout_write && stdout_buffer ? stdout_buffer_size : DN_ArrayCountU(sink);
|
||||
BOOL success = ReadFile(handle.stdout_read, dest_buffer, DN_CAST(DWORD) dest_size, &bytes_read, NULL);
|
||||
BOOL success = ReadFile(handle.stdout_read, dest_buffer, DN_Cast(DWORD) dest_size, &bytes_read, NULL);
|
||||
(void)success; // TODO:
|
||||
if (stdout_size)
|
||||
*stdout_size = bytes_read;
|
||||
@ -760,7 +760,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
|
||||
char *dest_buffer = handle.stderr_write && stderr_buffer ? stderr_buffer : sink;
|
||||
size_t dest_size = handle.stderr_write && stderr_buffer ? stderr_buffer_size : DN_ArrayCountU(sink);
|
||||
DWORD bytes_read = 0;
|
||||
BOOL success = ReadFile(handle.stderr_read, dest_buffer, DN_CAST(DWORD) dest_size, &bytes_read, NULL);
|
||||
BOOL success = ReadFile(handle.stderr_read, dest_buffer, DN_Cast(DWORD) dest_size, &bytes_read, NULL);
|
||||
(void)success; // TODO:
|
||||
if (stderr_size)
|
||||
*stderr_size = bytes_read;
|
||||
@ -779,7 +779,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
|
||||
DN_OS_ErrSinkAppendF(err,
|
||||
result.os_error_code,
|
||||
"Failed to retrieve command exit code: %.*s",
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
}
|
||||
|
||||
// NOTE: Cleanup ///////////////////////////////////////////////////////////////////////////////
|
||||
@ -790,8 +790,8 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
|
||||
CloseHandle(handle.process);
|
||||
}
|
||||
|
||||
result.stdout_text = DN_Str8_Init(stdout_buffer, stdout_size ? *stdout_size : 0);
|
||||
result.stderr_text = DN_Str8_Init(stderr_buffer, stderr_size ? *stderr_size : 0);
|
||||
result.stdout_text = DN_Str8FromPtr(stdout_buffer, stdout_size ? *stdout_size : 0);
|
||||
result.stderr_text = DN_Str8FromPtr(stderr_buffer, stderr_size ? *stderr_size : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -827,17 +827,17 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Arena *are
|
||||
while (!result.finished) {
|
||||
size_t stdout_size = DN_Kilobytes(8);
|
||||
size_t stderr_size = DN_Kilobytes(8);
|
||||
char *stdout_buffer = DN_Arena_NewArray(tmem.arena, char, stdout_size, DN_ZeroMem_No);
|
||||
char *stderr_buffer = DN_Arena_NewArray(tmem.arena, char, stderr_size, DN_ZeroMem_No);
|
||||
char *stdout_buffer = DN_ArenaNewArray(tmem.arena, char, stdout_size, DN_ZMem_No);
|
||||
char *stderr_buffer = DN_ArenaNewArray(tmem.arena, char, stderr_size, DN_ZMem_No);
|
||||
result = DN_OS_ExecPump(handle, stdout_buffer, &stdout_size, stderr_buffer, &stderr_size, wait_ms, err);
|
||||
DN_Str8Builder_AppendCopy(&stdout_builder, result.stdout_text);
|
||||
DN_Str8Builder_AppendCopy(&stderr_builder, result.stderr_text);
|
||||
wait_ms = (DN_Str8_HasData(result.stdout_text) || DN_Str8_HasData(result.stderr_text)) ? FAST_WAIT_TIME_MS : SLOW_WAIT_TIME_MS;
|
||||
DN_Str8BuilderAppendCopy(&stdout_builder, result.stdout_text);
|
||||
DN_Str8BuilderAppendCopy(&stderr_builder, result.stderr_text);
|
||||
wait_ms = (result.stdout_text.size || result.stderr_text.size) ? FAST_WAIT_TIME_MS : SLOW_WAIT_TIME_MS;
|
||||
}
|
||||
|
||||
// NOTE: Get stdout/stderr. If no arena is passed this is a no-op //////////////////////////////
|
||||
result.stdout_text = DN_Str8Builder_Build(&stdout_builder, arena);
|
||||
result.stderr_text = DN_Str8Builder_Build(&stderr_builder, arena);
|
||||
result.stdout_text = DN_Str8BuilderBuild(&stdout_builder, arena);
|
||||
result.stderr_text = DN_Str8BuilderBuild(&stderr_builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -849,16 +849,16 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line, DN_OSExe
|
||||
return result;
|
||||
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
|
||||
DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_STR8(" "));
|
||||
DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_Str8Lit(" "));
|
||||
DN_Str16 cmd16 = DN_W32_Str8ToStr16(tmem.arena, cmd_rendered);
|
||||
DN_Str16 working_dir16 = DN_W32_Str8ToStr16(tmem.arena, args->working_dir);
|
||||
|
||||
DN_Str8Builder env_builder = DN_Str8Builder_FromTLS();
|
||||
DN_Str8Builder_AppendArrayRef(&env_builder, args->environment.data, args->environment.size);
|
||||
DN_Str8Builder env_builder = DN_Str8BuilderFromTLS();
|
||||
DN_Str8BuilderAppendArrayRef(&env_builder, args->environment.data, args->environment.size);
|
||||
if (env_builder.string_size)
|
||||
DN_Str8Builder_AppendRef(&env_builder, DN_STR8("\0"));
|
||||
DN_Str8BuilderAppendRef(&env_builder, DN_Str8Lit("\0"));
|
||||
|
||||
DN_Str8 env_block8 = DN_Str8Builder_BuildDelimitedFromTLS(&env_builder, DN_STR8("\0"));
|
||||
DN_Str8 env_block8 = DN_Str8BuilderBuildDelimitedFromTLS(&env_builder, DN_Str8Lit("\0"));
|
||||
DN_Str16 env_block16 = {};
|
||||
if (env_block8.size)
|
||||
env_block16 = DN_W32_Str8ToStr16(tmem.arena, env_block8);
|
||||
@ -887,8 +887,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line, DN_OSExe
|
||||
err,
|
||||
result.os_error_code,
|
||||
"Failed to create stdout pipe to redirect the output of the command '%.*s': %.*s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -899,8 +899,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line, DN_OSExe
|
||||
result.os_error_code,
|
||||
"Failed to make stdout 'read' pipe non-inheritable when trying to "
|
||||
"execute command '%.*s': %.*s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -928,8 +928,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line, DN_OSExe
|
||||
err,
|
||||
result.os_error_code,
|
||||
"Failed to create stderr pipe to redirect the output of the command '%.*s': %.*s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -940,8 +940,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line, DN_OSExe
|
||||
result.os_error_code,
|
||||
"Failed to make stderr 'read' pipe non-inheritable when trying to "
|
||||
"execute command '%.*s': %.*s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -971,8 +971,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line, DN_OSExe
|
||||
DN_OS_ErrSinkAppendF(err,
|
||||
result.os_error_code,
|
||||
"Failed to execute command '%.*s': %.*s",
|
||||
DN_STR_FMT(cmd_rendered),
|
||||
DN_STR_FMT(win_error.msg));
|
||||
DN_Str8PrintFmt(cmd_rendered),
|
||||
DN_Str8PrintFmt(win_error.msg));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -992,7 +992,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line, DN_OSExe
|
||||
static DN_W32Core *DN_OS_GetW32Core_()
|
||||
{
|
||||
DN_Assert(g_dn_os_core_ && g_dn_os_core_->platform_context);
|
||||
DN_W32Core *result = DN_CAST(DN_W32Core *)g_dn_os_core_->platform_context;
|
||||
DN_W32Core *result = DN_Cast(DN_W32Core *)g_dn_os_core_->platform_context;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1023,7 +1023,7 @@ static DN_W32SyncPrimitive *DN_W32_AllocSyncPrimitive_()
|
||||
result->next = nullptr;
|
||||
} else {
|
||||
DN_OSCore *os = g_dn_os_core_;
|
||||
result = DN_Arena_New(&os->arena, DN_W32SyncPrimitive, DN_ZeroMem_Yes);
|
||||
result = DN_ArenaNew(&os->arena, DN_W32SyncPrimitive, DN_ZMem_Yes);
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&w32->sync_primitive_free_list_mutex);
|
||||
@ -1164,7 +1164,7 @@ DN_API bool DN_OS_ConditionVariableWait(DN_OSConditionVariable *cv, DN_OSMutex *
|
||||
if (mutex && cv && mutex->handle != 0 && cv->handle != 0 && sleep_ms > 0) {
|
||||
DN_W32SyncPrimitive *mutex_primitive = DN_OS_U64ToW32SyncPrimitive_(mutex->handle);
|
||||
DN_W32SyncPrimitive *cv_primitive = DN_OS_U64ToW32SyncPrimitive_(cv->handle);
|
||||
result = SleepConditionVariableCS(&cv_primitive->cv, &mutex_primitive->mutex, DN_CAST(DWORD) sleep_ms);
|
||||
result = SleepConditionVariableCS(&cv_primitive->cv, &mutex_primitive->mutex, DN_Cast(DWORD) sleep_ms);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1248,7 +1248,7 @@ DN_API DN_U32 DN_OS_ThreadID()
|
||||
DN_API void DN_W32_ThreadSetName(DN_Str8 name)
|
||||
{
|
||||
DN_OSTLS *tls = DN_OS_TLSGet();
|
||||
DN_ArenaTempMem tmem = DN_Arena_TempMemBegin(tls->arenas + DN_OSTLSArena_TMem0);
|
||||
DN_ArenaTempMem tmem = DN_ArenaTempMemBegin(tls->arenas + DN_OSTLSArena_TMem0);
|
||||
|
||||
// NOTE: SetThreadDescription is only available in
|
||||
// Windows Server 2016, Windows 10 LTSB 2016 and Windows 10 version 1607
|
||||
@ -1258,7 +1258,7 @@ DN_API void DN_W32_ThreadSetName(DN_Str8 name)
|
||||
if (w32->set_thread_description) {
|
||||
DN_Str16 name16 = DN_W32_Str8ToStr16(tmem.arena, name);
|
||||
w32->set_thread_description(GetCurrentThread(), (WCHAR *)name16.data);
|
||||
DN_Arena_TempMemEnd(tmem);
|
||||
DN_ArenaTempMemEnd(tmem);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1275,7 +1275,7 @@ DN_API void DN_W32_ThreadSetName(DN_Str8 name)
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, name);
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, name);
|
||||
DN_W32ThreadNameInfo info = {};
|
||||
info.dwType = 0x1000;
|
||||
info.szName = (char *)copy.data;
|
||||
@ -1291,7 +1291,7 @@ DN_API void DN_W32_ThreadSetName(DN_Str8 name)
|
||||
}
|
||||
DN_MSVC_WARNING_POP
|
||||
|
||||
DN_Arena_TempMemEnd(tmem);
|
||||
DN_ArenaTempMemEnd(tmem);
|
||||
}
|
||||
|
||||
// NOTE: DN_OSHttp /////////////////////////////////////////////////////////////////////////////////
|
||||
@ -1300,8 +1300,8 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d
|
||||
(void)session;
|
||||
(void)dwStatusInformationLength;
|
||||
|
||||
DN_OSHttpResponse *response = DN_CAST(DN_OSHttpResponse *) dwContext;
|
||||
HINTERNET request = DN_CAST(HINTERNET) response->w32_request_handle;
|
||||
DN_OSHttpResponse *response = DN_Cast(DN_OSHttpResponse *) dwContext;
|
||||
HINTERNET request = DN_Cast(HINTERNET) response->w32_request_handle;
|
||||
DN_W32Error error = {};
|
||||
DWORD const READ_BUFFER_SIZE = DN_Megabytes(1);
|
||||
|
||||
@ -1331,7 +1331,7 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d
|
||||
&status,
|
||||
&status_size,
|
||||
WINHTTP_NO_HEADER_INDEX)) {
|
||||
response->http_status = DN_CAST(uint16_t) status;
|
||||
response->http_status = DN_Cast(uint16_t) status;
|
||||
|
||||
// NOTE: You can normally call into WinHttpQueryDataAvailable which means the kernel
|
||||
// will buffer the response into a single buffer and return us the full size of the
|
||||
@ -1343,7 +1343,7 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d
|
||||
// This is advantageous to avoid a copy from the kernel buffer into our buffer. If the
|
||||
// end user application knows the typical payload size then they can optimise for this
|
||||
// to prevent unnecessary allocation on the user side.
|
||||
void *buffer = DN_Arena_Alloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZeroMem_No);
|
||||
void *buffer = DN_ArenaAlloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZMem_No);
|
||||
if (!WinHttpReadData(request, buffer, READ_BUFFER_SIZE, nullptr))
|
||||
error = DN_W32_LastError(&response->tmp_arena);
|
||||
} else {
|
||||
@ -1353,17 +1353,17 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d
|
||||
} else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_READ_COMPLETE) {
|
||||
DWORD bytes_read = dwStatusInformationLength;
|
||||
if (bytes_read) {
|
||||
DN_Str8 prev_buffer = DN_Str8_Init(DN_CAST(char *) lpvStatusInformation, bytes_read);
|
||||
DN_Str8Builder_AppendRef(&response->builder, prev_buffer);
|
||||
DN_Str8 prev_buffer = DN_Str8FromPtr(DN_Cast(char *) lpvStatusInformation, bytes_read);
|
||||
DN_Str8BuilderAppendRef(&response->builder, prev_buffer);
|
||||
|
||||
void *buffer = DN_Arena_Alloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZeroMem_No);
|
||||
void *buffer = DN_ArenaAlloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZMem_No);
|
||||
if (!WinHttpReadData(request, buffer, READ_BUFFER_SIZE, nullptr))
|
||||
error = DN_W32_LastError(&response->tmp_arena);
|
||||
}
|
||||
} else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE) {
|
||||
} else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR) {
|
||||
WINHTTP_ASYNC_RESULT *async_result = DN_CAST(WINHTTP_ASYNC_RESULT *) lpvStatusInformation;
|
||||
error = DN_W32_ErrorCodeToMsg(&response->tmp_arena, DN_CAST(DN_U32) async_result->dwError);
|
||||
WINHTTP_ASYNC_RESULT *async_result = DN_Cast(WINHTTP_ASYNC_RESULT *) lpvStatusInformation;
|
||||
error = DN_W32_ErrorCodeToMsg(&response->tmp_arena, DN_Cast(DN_U32) async_result->dwError);
|
||||
} else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE) {
|
||||
if (!WinHttpReceiveResponse(request, 0))
|
||||
error = DN_W32_LastError(&response->tmp_arena);
|
||||
@ -1375,7 +1375,7 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d
|
||||
if (request) {
|
||||
bool read_complete = dwInternetStatus == WINHTTP_CALLBACK_STATUS_READ_COMPLETE && dwStatusInformationLength == 0;
|
||||
if (read_complete)
|
||||
response->body = DN_Str8Builder_Build(&response->builder, response->arena);
|
||||
response->body = DN_Str8BuilderBuild(&response->builder, response->arena);
|
||||
|
||||
if (read_complete || dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR || error.code) {
|
||||
DN_OS_SemaphoreIncrement(&response->on_complete_semaphore, 1);
|
||||
@ -1433,9 +1433,9 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
|
||||
WINHTTP_CALLBACK_STATUS_REQUEST_ERROR |
|
||||
WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE;
|
||||
if (WinHttpSetStatusCallback(response->w32_request_session,
|
||||
DN_CAST(WINHTTP_STATUS_CALLBACK) DN_OS_HttpRequestWin32Callback,
|
||||
DN_Cast(WINHTTP_STATUS_CALLBACK) DN_OS_HttpRequestWin32Callback,
|
||||
callback_flags,
|
||||
DN_CAST(DWORD_PTR) nullptr /*dwReserved*/) == WINHTTP_INVALID_STATUS_CALLBACK) {
|
||||
DN_Cast(DWORD_PTR) nullptr /*dwReserved*/) == WINHTTP_INVALID_STATUS_CALLBACK) {
|
||||
error = DN_W32_LastError(&response->tmp_arena);
|
||||
return;
|
||||
}
|
||||
@ -1465,11 +1465,11 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
|
||||
response->on_complete_semaphore = DN_OS_SemaphoreInit(0);
|
||||
if (!WinHttpSendRequest(response->w32_request_handle,
|
||||
headers16.data,
|
||||
DN_CAST(DWORD) headers16.size,
|
||||
DN_Cast(DWORD) headers16.size,
|
||||
body.data /*optional data*/,
|
||||
DN_CAST(DWORD) body.size /*optional length*/,
|
||||
DN_CAST(DWORD) body.size /*total content length*/,
|
||||
DN_CAST(DWORD_PTR) response)) {
|
||||
DN_Cast(DWORD) body.size /*optional length*/,
|
||||
DN_Cast(DWORD) body.size /*total content length*/,
|
||||
DN_Cast(DWORD_PTR) response)) {
|
||||
error = DN_W32_LastError(&response->tmp_arena);
|
||||
return;
|
||||
}
|
||||
@ -1486,7 +1486,7 @@ DN_API void DN_OS_HttpRequestFree(DN_OSHttpResponse *response)
|
||||
response->w32_request_session = nullptr;
|
||||
response->w32_request_connection = nullptr;
|
||||
response->w32_request_handle = nullptr;
|
||||
DN_Arena_Deinit(&response->tmp_arena);
|
||||
DN_ArenaDeinit(&response->tmp_arena);
|
||||
DN_OS_SemaphoreDeinit(&response->on_complete_semaphore);
|
||||
|
||||
*response = {};
|
||||
@ -1569,11 +1569,11 @@ DN_API void DN_W32_MakeProcessDPIAware()
|
||||
if (!lib_handle)
|
||||
return;
|
||||
|
||||
if (auto *set_process_dpi_awareness_context = DN_CAST(SetProcessDpiAwarenessContextProc *) GetProcAddress(DN_CAST(HMODULE) lib_handle, "SetProcessDpiAwarenessContext"))
|
||||
if (auto *set_process_dpi_awareness_context = DN_Cast(SetProcessDpiAwarenessContextProc *) GetProcAddress(DN_Cast(HMODULE) lib_handle, "SetProcessDpiAwarenessContext"))
|
||||
set_process_dpi_awareness_context(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
else if (auto *set_process_dpi_awareness = DN_CAST(SetProcessDpiAwarenessProc *) GetProcAddress(DN_CAST(HMODULE) lib_handle, "SetProcessDpiAwareness"))
|
||||
else if (auto *set_process_dpi_awareness = DN_Cast(SetProcessDpiAwarenessProc *) GetProcAddress(DN_Cast(HMODULE) lib_handle, "SetProcessDpiAwareness"))
|
||||
set_process_dpi_awareness(DPI_AWARENESS_PER_MONITOR_AWARE);
|
||||
else if (auto *set_process_dpi_aware = DN_CAST(SetProcessDpiAwareProc *) GetProcAddress(DN_CAST(HMODULE) lib_handle, "SetProcessDpiAware"))
|
||||
else if (auto *set_process_dpi_aware = DN_Cast(SetProcessDpiAwareProc *) GetProcAddress(DN_Cast(HMODULE) lib_handle, "SetProcessDpiAware"))
|
||||
set_process_dpi_aware();
|
||||
}
|
||||
|
||||
@ -1581,18 +1581,18 @@ DN_API void DN_W32_MakeProcessDPIAware()
|
||||
DN_API DN_Str16 DN_W32_Str8ToStr16(DN_Arena *arena, DN_Str8 src)
|
||||
{
|
||||
DN_Str16 result = {};
|
||||
if (!arena || !DN_Str8_HasData(src))
|
||||
if (!arena || src.size == 0)
|
||||
return result;
|
||||
|
||||
int required_size = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, nullptr /*dest*/, 0 /*dest size*/);
|
||||
int required_size = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, nullptr /*dest*/, 0 /*dest size*/);
|
||||
if (required_size <= 0)
|
||||
return result;
|
||||
|
||||
wchar_t *buffer = DN_Arena_NewArray(arena, wchar_t, required_size + 1, DN_ZeroMem_No);
|
||||
wchar_t *buffer = DN_ArenaNewArray(arena, wchar_t, required_size + 1, DN_ZMem_No);
|
||||
if (!buffer)
|
||||
return result;
|
||||
|
||||
int chars_written = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, buffer, required_size);
|
||||
int chars_written = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, buffer, required_size);
|
||||
if (DN_Check(chars_written == required_size)) {
|
||||
result.data = buffer;
|
||||
result.size = chars_written;
|
||||
@ -1604,14 +1604,14 @@ DN_API DN_Str16 DN_W32_Str8ToStr16(DN_Arena *arena, DN_Str8 src)
|
||||
DN_API int DN_W32_Str8ToStr16Buffer(DN_Str8 src, wchar_t *dest, int dest_size)
|
||||
{
|
||||
int result = 0;
|
||||
if (!DN_Str8_HasData(src))
|
||||
if (src.size == 0)
|
||||
return result;
|
||||
|
||||
result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, nullptr /*dest*/, 0 /*dest size*/);
|
||||
result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, nullptr /*dest*/, 0 /*dest size*/);
|
||||
if (result <= 0 || result > dest_size || !dest)
|
||||
return result;
|
||||
|
||||
result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, dest, DN_CAST(int) dest_size);
|
||||
result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, dest, DN_Cast(int) dest_size);
|
||||
dest[DN_Min(result, dest_size - 1)] = 0;
|
||||
return result;
|
||||
}
|
||||
@ -1620,7 +1620,7 @@ DN_API int DN_W32_Str8ToStr16Buffer(DN_Str8 src, wchar_t *dest, int dest_size)
|
||||
DN_API int DN_W32_Str16ToStr8Buffer(DN_Str16 src, char *dest, int dest_size)
|
||||
{
|
||||
int result = 0;
|
||||
if (!DN_Str16_HasData(src))
|
||||
if (src.size == 0)
|
||||
return result;
|
||||
|
||||
int src_size = DN_SaturateCastISizeToInt(src.size);
|
||||
@ -1631,7 +1631,7 @@ DN_API int DN_W32_Str16ToStr8Buffer(DN_Str16 src, char *dest, int dest_size)
|
||||
if (result <= 0 || result > dest_size || !dest)
|
||||
return result;
|
||||
|
||||
result = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, dest, DN_CAST(int) dest_size, nullptr, nullptr);
|
||||
result = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, dest, DN_Cast(int) dest_size, nullptr, nullptr);
|
||||
dest[DN_Min(result, dest_size - 1)] = 0;
|
||||
return result;
|
||||
}
|
||||
@ -1639,7 +1639,7 @@ DN_API int DN_W32_Str16ToStr8Buffer(DN_Str16 src, char *dest, int dest_size)
|
||||
DN_API DN_Str8 DN_W32_Str16ToStr8(DN_Arena *arena, DN_Str16 src)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!arena || !DN_Str16_HasData(src))
|
||||
if (!arena || src.size == 0)
|
||||
return result;
|
||||
|
||||
int src_size = DN_SaturateCastISizeToInt(src.size);
|
||||
@ -1653,11 +1653,11 @@ DN_API DN_Str8 DN_W32_Str16ToStr8(DN_Arena *arena, DN_Str16 src)
|
||||
// NOTE: Str8 allocate ensures there's one extra byte for
|
||||
// null-termination already so no-need to +1 the required size
|
||||
DN_ArenaTempMemScope temp_mem = DN_ArenaTempMemScope(arena);
|
||||
DN_Str8 buffer = DN_Str8_Alloc(arena, required_size, DN_ZeroMem_No);
|
||||
if (!DN_Str8_HasData(buffer))
|
||||
DN_Str8 buffer = DN_Str8FromArena(arena, required_size, DN_ZMem_No);
|
||||
if (buffer.size == 0)
|
||||
return result;
|
||||
|
||||
int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_CAST(int) buffer.size, nullptr, nullptr);
|
||||
int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_Cast(int) buffer.size, nullptr, nullptr);
|
||||
if (DN_Check(chars_written == required_size)) {
|
||||
result = buffer;
|
||||
result.data[result.size] = 0;
|
||||
@ -1670,7 +1670,7 @@ DN_API DN_Str8 DN_W32_Str16ToStr8(DN_Arena *arena, DN_Str16 src)
|
||||
DN_API DN_Str8 DN_W32_Str16ToStr8FromHeap(DN_Str16 src)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!DN_Str16_HasData(src))
|
||||
if (src.size == 0)
|
||||
return result;
|
||||
|
||||
int src_size = DN_SaturateCastISizeToInt(src.size);
|
||||
@ -1683,11 +1683,11 @@ DN_API DN_Str8 DN_W32_Str16ToStr8FromHeap(DN_Str16 src)
|
||||
|
||||
// NOTE: Str8 allocate ensures there's one extra byte for
|
||||
// null-termination already so no-need to +1 the required size
|
||||
DN_Str8 buffer = DN_Str8_FromHeap(required_size, DN_ZeroMem_No);
|
||||
if (!DN_Str8_HasData(buffer))
|
||||
DN_Str8 buffer = DN_Str8FromHeap(required_size, DN_ZMem_No);
|
||||
if (buffer.size == 0)
|
||||
return result;
|
||||
|
||||
int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_CAST(int) buffer.size, nullptr, nullptr);
|
||||
int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_Cast(int) buffer.size, nullptr, nullptr);
|
||||
if (DN_Check(chars_written == required_size)) {
|
||||
result = buffer;
|
||||
result.data[result.size] = 0;
|
||||
@ -1708,17 +1708,17 @@ DN_API DN_Str16 DN_W32_EXEPathW(DN_Arena *arena)
|
||||
wchar_t *module_path = nullptr;
|
||||
do {
|
||||
module_size += 256;
|
||||
module_path = DN_Arena_NewArray(tmem.arena, wchar_t, module_size, DN_ZeroMem_No);
|
||||
module_path = DN_ArenaNewArray(tmem.arena, wchar_t, module_size, DN_ZMem_No);
|
||||
if (!module_path)
|
||||
return result;
|
||||
module_size = DN_CAST(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_CAST(int) module_size);
|
||||
module_size = DN_Cast(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_Cast(int) module_size);
|
||||
} while (GetLastError() == ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
DN_USize index_of_last_slash = 0;
|
||||
for (DN_USize index = module_size - 1; !index_of_last_slash && index < module_size; index--)
|
||||
index_of_last_slash = module_path[index] == '\\' ? index : 0;
|
||||
|
||||
result.data = DN_Arena_NewArray(arena, wchar_t, module_size + 1, DN_ZeroMem_No);
|
||||
result.data = DN_ArenaNewArray(arena, wchar_t, module_size + 1, DN_ZMem_No);
|
||||
result.size = module_size;
|
||||
DN_Memcpy(result.data, module_path, sizeof(wchar_t) * result.size);
|
||||
result.data[result.size] = 0;
|
||||
@ -1734,17 +1734,17 @@ DN_API DN_Str16 DN_W32_EXEDirW(DN_Arena *arena)
|
||||
wchar_t *module_path = nullptr;
|
||||
do {
|
||||
module_size += 256;
|
||||
module_path = DN_Arena_NewArray(tmem.arena, wchar_t, module_size, DN_ZeroMem_No);
|
||||
module_path = DN_ArenaNewArray(tmem.arena, wchar_t, module_size, DN_ZMem_No);
|
||||
if (!module_path)
|
||||
return result;
|
||||
module_size = DN_CAST(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_CAST(int) module_size);
|
||||
module_size = DN_Cast(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_Cast(int) module_size);
|
||||
} while (GetLastError() == ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
DN_USize index_of_last_slash = 0;
|
||||
for (DN_USize index = module_size - 1; !index_of_last_slash && index < module_size; index--)
|
||||
index_of_last_slash = module_path[index] == '\\' ? index : 0;
|
||||
|
||||
result.data = DN_Arena_NewArray(arena, wchar_t, index_of_last_slash + 1, DN_ZeroMem_No);
|
||||
result.data = DN_ArenaNewArray(arena, wchar_t, index_of_last_slash + 1, DN_ZMem_No);
|
||||
result.size = index_of_last_slash;
|
||||
DN_Memcpy(result.data, module_path, sizeof(wchar_t) * result.size);
|
||||
result.data[result.size] = 0;
|
||||
@ -1768,9 +1768,9 @@ DN_API DN_Str16 DN_W32_WorkingDirW(DN_Arena *arena, DN_Str16 suffix)
|
||||
// NOTE: required_size is the size required *including* the null-terminator
|
||||
DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena);
|
||||
unsigned long required_size = GetCurrentDirectoryW(0, nullptr);
|
||||
unsigned long desired_size = required_size + DN_CAST(unsigned long) suffix.size;
|
||||
unsigned long desired_size = required_size + DN_Cast(unsigned long) suffix.size;
|
||||
|
||||
wchar_t *tmem_w_path = DN_Arena_NewArray(tmem.arena, wchar_t, desired_size, DN_ZeroMem_No);
|
||||
wchar_t *tmem_w_path = DN_ArenaNewArray(tmem.arena, wchar_t, desired_size, DN_ZMem_No);
|
||||
if (!tmem_w_path)
|
||||
return result;
|
||||
|
||||
@ -1780,7 +1780,7 @@ DN_API DN_Str16 DN_W32_WorkingDirW(DN_Arena *arena, DN_Str16 suffix)
|
||||
return result;
|
||||
}
|
||||
|
||||
wchar_t *w_path = DN_Arena_NewArray(arena, wchar_t, desired_size, DN_ZeroMem_No);
|
||||
wchar_t *w_path = DN_ArenaNewArray(arena, wchar_t, desired_size, DN_ZMem_No);
|
||||
if (!w_path)
|
||||
return result;
|
||||
|
||||
@ -1790,7 +1790,7 @@ DN_API DN_Str16 DN_W32_WorkingDirW(DN_Arena *arena, DN_Str16 suffix)
|
||||
w_path[desired_size] = 0;
|
||||
}
|
||||
|
||||
result = DN_Str16{w_path, DN_CAST(DN_USize)(desired_size - 1)};
|
||||
result = DN_Str16{w_path, DN_Cast(DN_USize)(desired_size - 1)};
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1821,7 +1821,7 @@ DN_API bool DN_W32_DirWIterate(DN_Str16 path, DN_W32FolderIteratorW *it)
|
||||
if (find_data.cFileName[0] == '.' || (find_data.cFileName[0] == '.' && find_data.cFileName[1] == '.'))
|
||||
continue;
|
||||
|
||||
it->file_name.size = DN_CStr16_Size(find_data.cFileName);
|
||||
it->file_name.size = DN_CStr16Size(find_data.cFileName);
|
||||
DN_Assert(it->file_name.size < (DN_ArrayCountU(it->file_name_buf) - 1));
|
||||
DN_Memcpy(it->file_name.data, find_data.cFileName, it->file_name.size * sizeof(wchar_t));
|
||||
it->file_name_buf[it->file_name.size] = 0;
|
||||
|
||||
@ -6,7 +6,7 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindAVX512F(DN_Str8 string, DN_Str8 find)
|
||||
{
|
||||
// NOTE: Algorithm as described in http://0x80.pl/articles/simd-strfind.html
|
||||
DN_Str8FindResult result = {};
|
||||
if (!DN_Str8_HasData(string) || !DN_Str8_HasData(find) || find.size > string.size)
|
||||
if (string.size == 0 || find.size == 0 || find.size > string.size)
|
||||
return result;
|
||||
|
||||
__m512i const find_first_ch = _mm512_set1_epi8(find.data[0]);
|
||||
@ -77,10 +77,10 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindAVX512F(DN_Str8 string, DN_Str8 find)
|
||||
}
|
||||
|
||||
if (result.found) {
|
||||
result.start_to_before_match = DN_Str8_Init(string.data, result.index);
|
||||
result.match = DN_Str8_Init(string.data + result.index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - result.index);
|
||||
result.after_match_to_end_of_buffer = DN_Str8_Advance(result.match_to_end_of_buffer, find.size);
|
||||
result.start_to_before_match = DN_Str8FromPtr(string.data, result.index);
|
||||
result.match = DN_Str8FromPtr(string.data + result.index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - result.index);
|
||||
result.after_match_to_end_of_buffer = DN_Str8Advance(result.match_to_end_of_buffer, find.size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -91,14 +91,14 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindAVX512F(DN_Str8 string, DN_Str8 find)
|
||||
}
|
||||
|
||||
for (DN_USize index = ptr - string.data; index < string.size; index++) {
|
||||
DN_Str8 string_slice = DN_Str8_Slice(string, index, find.size);
|
||||
if (DN_Str8_Eq(string_slice, find)) {
|
||||
DN_Str8 string_slice = DN_Str8Slice(string, index, find.size);
|
||||
if (DN_Str8Eq(string_slice, find)) {
|
||||
result.found = true;
|
||||
result.index = index;
|
||||
result.start_to_before_match = DN_Str8_Init(string.data, index);
|
||||
result.match = DN_Str8_Init(string.data + index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - index);
|
||||
result.after_match_to_end_of_buffer = DN_Str8_Advance(result.match_to_end_of_buffer, find.size);
|
||||
result.start_to_before_match = DN_Str8FromPtr(string.data, index);
|
||||
result.match = DN_Str8FromPtr(string.data + index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - index);
|
||||
result.after_match_to_end_of_buffer = DN_Str8Advance(result.match_to_end_of_buffer, find.size);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -110,7 +110,7 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindLastAVX512F(DN_Str8 string, DN_Str8 fin
|
||||
{
|
||||
// NOTE: Algorithm as described in http://0x80.pl/articles/simd-strfind.html
|
||||
DN_Str8FindResult result = {};
|
||||
if (!DN_Str8_HasData(string) || !DN_Str8_HasData(find) || find.size > string.size)
|
||||
if (string.size == 0 || find.size == 0 || find.size > string.size)
|
||||
return result;
|
||||
|
||||
__m512i const find_first_ch = _mm512_set1_epi8(find.data[0]);
|
||||
@ -182,9 +182,9 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindLastAVX512F(DN_Str8 string, DN_Str8 fin
|
||||
}
|
||||
|
||||
if (result.found) {
|
||||
result.start_to_before_match = DN_Str8_Init(string.data, result.index);
|
||||
result.match = DN_Str8_Init(string.data + result.index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - result.index);
|
||||
result.start_to_before_match = DN_Str8FromPtr(string.data, result.index);
|
||||
result.match = DN_Str8FromPtr(string.data + result.index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - result.index);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -193,13 +193,13 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindLastAVX512F(DN_Str8 string, DN_Str8 fin
|
||||
}
|
||||
|
||||
for (DN_USize index = ptr - string.data - 1; index < string.size; index--) {
|
||||
DN_Str8 string_slice = DN_Str8_Slice(string, index, find.size);
|
||||
if (DN_Str8_Eq(string_slice, find)) {
|
||||
DN_Str8 string_slice = DN_Str8Slice(string, index, find.size);
|
||||
if (DN_Str8Eq(string_slice, find)) {
|
||||
result.found = true;
|
||||
result.index = index;
|
||||
result.start_to_before_match = DN_Str8_Init(string.data, index);
|
||||
result.match = DN_Str8_Init(string.data + index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - index);
|
||||
result.start_to_before_match = DN_Str8FromPtr(string.data, index);
|
||||
result.match = DN_Str8FromPtr(string.data + index, find.size);
|
||||
result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - index);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -214,7 +214,7 @@ DN_API DN_Str8BSplitResult DN_SIMD_Str8BSplitAVX512F(DN_Str8 string, DN_Str8 fin
|
||||
if (find_result.found) {
|
||||
result.lhs.data = string.data;
|
||||
result.lhs.size = find_result.index;
|
||||
result.rhs = DN_Str8_Advance(find_result.match_to_end_of_buffer, find.size);
|
||||
result.rhs = DN_Str8Advance(find_result.match_to_end_of_buffer, find.size);
|
||||
} else {
|
||||
result.lhs = string;
|
||||
}
|
||||
@ -229,7 +229,7 @@ DN_API DN_Str8BSplitResult DN_SIMD_Str8BSplitLastAVX512F(DN_Str8 string, DN_Str8
|
||||
if (find_result.found) {
|
||||
result.lhs.data = string.data;
|
||||
result.lhs.size = find_result.index;
|
||||
result.rhs = DN_Str8_Advance(find_result.match_to_end_of_buffer, find.size);
|
||||
result.rhs = DN_Str8Advance(find_result.match_to_end_of_buffer, find.size);
|
||||
} else {
|
||||
result.lhs = string;
|
||||
}
|
||||
@ -240,7 +240,7 @@ DN_API DN_Str8BSplitResult DN_SIMD_Str8BSplitLastAVX512F(DN_Str8 string, DN_Str8
|
||||
DN_API DN_USize DN_SIMD_Str8SplitAVX512F(DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode)
|
||||
{
|
||||
DN_USize result = 0; // The number of splits in the actual string.
|
||||
if (!DN_Str8_HasData(string) || !DN_Str8_HasData(delimiter) || delimiter.size <= 0)
|
||||
if (string.size == 0 || delimiter.size == 0 || delimiter.size <= 0)
|
||||
return result;
|
||||
|
||||
DN_Str8BSplitResult split = {};
|
||||
@ -262,7 +262,7 @@ DN_API DN_Slice<DN_Str8> DN_SIMD_Str8SplitAllocAVX512F(DN_Arena *arena, DN_Str8
|
||||
{
|
||||
DN_Slice<DN_Str8> result = {};
|
||||
DN_USize splits_required = DN_SIMD_Str8SplitAVX512F(string, delimiter, /*splits*/ nullptr, /*count*/ 0, mode);
|
||||
result.data = DN_Arena_NewArray(arena, DN_Str8, splits_required, DN_ZeroMem_No);
|
||||
result.data = DN_ArenaNewArray(arena, DN_Str8, splits_required, DN_ZMem_No);
|
||||
if (result.data) {
|
||||
result.size = DN_SIMD_Str8SplitAVX512F(string, delimiter, result.data, splits_required, mode);
|
||||
DN_Assert(splits_required == result.size);
|
||||
|
||||
@ -18,11 +18,11 @@
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
DN_API DN_Str8FindResult DN_Str8_FindStr8AVX512F (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8FindResult DN_Str8_FindLastStr8AVX512F (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitAVX512F (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8_BSplitLastAVX512F(DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_USize DN_Str8_SplitAVX512F (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8_SplitAllocAVX512F (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Str8FindResult DN_Str8FindStr8AVX512F (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8FindResult DN_Str8FindLastStr8AVX512F (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitAVX512F (DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_Str8BSplitResult DN_Str8BSplitLastAVX512F(DN_Str8 string, DN_Str8 find);
|
||||
DN_API DN_USize DN_Str8SplitAVX512F (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
DN_API DN_Slice<DN_Str8> DN_Str8SplitAllocAVX512F (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
|
||||
|
||||
#endif // DN_SIMD_AVX512F_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,20 @@
|
||||
#if !defined(DN_INI_H)
|
||||
#define DN_INI_H
|
||||
|
||||
#include <stdint.h> // uint32_t
|
||||
#include <stdint.h> // size_t
|
||||
|
||||
#if !defined(DN_INI_Assert)
|
||||
#include <assert.h>
|
||||
#define DN_INI_Assert(expr) assert(expr)
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(DN_INI_VSNPrintF)
|
||||
#include <stdio.h>
|
||||
#define DN_INI_VSNPrintF(buffer, size, fmt, args) vsnprintf(buffer, size, fmt, args)
|
||||
#endif
|
||||
|
||||
#if !defined(DN_INI_Memset) || !defined(DN_INI_Memcmp) || !defined(DN_INI_Memcpy)
|
||||
#include <string.h>
|
||||
#if !defined(DN_INI_Memset)
|
||||
@ -27,7 +34,7 @@ typedef enum DN_INITokenType {
|
||||
DN_INITokenType_Nil,
|
||||
DN_INITokenType_Section,
|
||||
DN_INITokenType_Key,
|
||||
DN_INITokenType_KeyValueSeparator,
|
||||
DN_INITokenType_FieldSeparator,
|
||||
DN_INITokenType_MultilineValue,
|
||||
DN_INITokenType_Value,
|
||||
DN_INITokenType_Comment,
|
||||
@ -37,7 +44,7 @@ typedef enum DN_INITokenType {
|
||||
|
||||
typedef struct DN_INIStr8 {
|
||||
char *data;
|
||||
uint32_t size;
|
||||
size_t size;
|
||||
} DN_INIStr8;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@ -49,63 +56,133 @@ typedef struct DN_INIStr8 {
|
||||
typedef struct DN_INIToken {
|
||||
char *data;
|
||||
DN_INITokenType type;
|
||||
uint32_t count;
|
||||
uint32_t next_p;
|
||||
bool new_line;
|
||||
size_t count;
|
||||
size_t next_p;
|
||||
bool line_start_new_line;
|
||||
|
||||
// NOTE: Line metadata
|
||||
DN_INIStr8 error;
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
char *line_start;
|
||||
size_t line;
|
||||
size_t column;
|
||||
char * line_start;
|
||||
} DN_INIToken;
|
||||
|
||||
typedef struct DN_INITokeniser {
|
||||
char *data;
|
||||
char *line_start;
|
||||
uint32_t count;
|
||||
uint32_t pos;
|
||||
DN_INIToken prev_token;
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
char *data;
|
||||
char *line_start;
|
||||
size_t count;
|
||||
size_t pos;
|
||||
DN_INIToken prev_token;
|
||||
size_t line;
|
||||
size_t column;
|
||||
} DN_INITokeniser;
|
||||
|
||||
typedef struct DN_INIKeyValue DN_INIKeyValue;
|
||||
struct DN_INIKeyValue {
|
||||
typedef enum DN_INIFieldType {
|
||||
DN_INIFieldType_String,
|
||||
DN_INIFieldType_Bool,
|
||||
DN_INIFieldType_USize,
|
||||
} DN_INIFieldType;
|
||||
|
||||
typedef struct DN_INIField DN_INIField;
|
||||
struct DN_INIField {
|
||||
DN_INIStr8 key;
|
||||
DN_INIFieldType value_type;
|
||||
DN_INIStr8 value;
|
||||
DN_INIKeyValue *next;
|
||||
bool value_bool;
|
||||
size_t value_usize;
|
||||
DN_INIField *next;
|
||||
};
|
||||
|
||||
typedef struct DN_INISection DN_INISection;
|
||||
struct DN_INISection {
|
||||
DN_INIStr8 name;
|
||||
DN_INIKeyValue *first_key_value;
|
||||
DN_INIKeyValue *last_key_value;
|
||||
uint32_t key_values_count;
|
||||
DN_INIToken token;
|
||||
DN_INISection *next, *parent;
|
||||
DN_INISection *child_first, *child_last;
|
||||
DN_INIStr8 name;
|
||||
DN_INIField *first_field;
|
||||
DN_INIField *last_field;
|
||||
size_t fields_count;
|
||||
DN_INIToken token;
|
||||
DN_INISection *next, *parent;
|
||||
DN_INISection *child_first, *child_last;
|
||||
size_t child_count;
|
||||
};
|
||||
|
||||
typedef struct DN_INIParse {
|
||||
typedef struct DN_INICore DN_INICore;
|
||||
struct DN_INICore {
|
||||
DN_INISection first_section;
|
||||
uint32_t total_sections_count;
|
||||
uint32_t total_key_values_count;
|
||||
size_t total_sections_count;
|
||||
size_t total_fields_count;
|
||||
DN_INIToken error_token;
|
||||
uint32_t memory_required;
|
||||
} DN_INIParse;
|
||||
size_t memory_required;
|
||||
};
|
||||
|
||||
DN_INITokeniser DN_INI_TokeniserFromPtr (char const *buf, uint32_t count);
|
||||
DN_INIToken DN_INI_NextToken (DN_INITokeniser const *tokeniser);
|
||||
void DN_INI_EatToken (DN_INITokeniser *tokeniser, DN_INIToken token);
|
||||
DN_INISection * DN_INI_FindSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
|
||||
DN_INISection * DN_INI_FindSection (DN_INISection *section, char const *name, uint32_t name_size);
|
||||
DN_INIKeyValue *DN_INI_KeyFromSectionStr8(DN_INISection *section, DN_INIStr8 str8);
|
||||
DN_INIKeyValue *DN_INI_KeyFromSection (DN_INISection *section, char const *key, uint32_t key_size);
|
||||
DN_INIParse DN_INI_ParseFromPtr (char const *buf, uint32_t count, char *base, uint32_t base_count);
|
||||
typedef struct DN_INIArena DN_INIArena;
|
||||
struct DN_INIArena {
|
||||
char *base;
|
||||
size_t used, max;
|
||||
};
|
||||
|
||||
typedef struct DN_INIStr8FromResult DN_INIStr8FromResult;
|
||||
struct DN_INIStr8FromResult {
|
||||
bool success;
|
||||
DN_INIStr8 str8;
|
||||
size_t size_req;
|
||||
};
|
||||
|
||||
typedef struct DN_INIFieldUSize DN_INIFieldUSize;
|
||||
struct DN_INIFieldUSize
|
||||
{
|
||||
bool success;
|
||||
DN_INIField *field;
|
||||
size_t value;
|
||||
};
|
||||
|
||||
typedef struct DN_INIFieldStr8 DN_INIFieldStr8;
|
||||
struct DN_INIFieldStr8
|
||||
{
|
||||
bool success;
|
||||
DN_INIField *field;
|
||||
DN_INIStr8 value;
|
||||
};
|
||||
|
||||
typedef struct DN_INIFieldBool DN_INIFieldBool;
|
||||
struct DN_INIFieldBool
|
||||
{
|
||||
bool success;
|
||||
DN_INIField *field;
|
||||
bool value;
|
||||
};
|
||||
|
||||
|
||||
// NOTE: Utilities
|
||||
int DN_INI_SNPrintF_ (char const *buffer, size_t size, char const *fmt, ...);
|
||||
void * DN_INI_ArenaAlloc (DN_INIArena *arena, size_t size);
|
||||
DN_INIStr8 DN_INI_Str8FromPtr (char const *data, size_t count);
|
||||
|
||||
// NOTE: Tokeniser/Parsing
|
||||
DN_INITokeniser DN_INI_TokeniserFromPtr (char const *buf, size_t count);
|
||||
DN_INIToken DN_INI_NextToken (DN_INITokeniser const *tokeniser);
|
||||
void DN_INI_EatToken (DN_INITokeniser *tokeniser, DN_INIToken token);
|
||||
|
||||
// NOTE: Lookup
|
||||
DN_INISection * DN_INI_ChildSectionFromStr8 (DN_INISection *section, DN_INIStr8 str8);
|
||||
DN_INISection * DN_INI_ChildSectionFromCStr (DN_INISection *section, char const *name, size_t name_size);
|
||||
DN_INIField * DN_INI_FieldFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
|
||||
DN_INIField * DN_INI_FieldFromSection (DN_INISection *section, char const *key, size_t key_size);
|
||||
DN_INIFieldUSize DN_INI_FieldUSizeFromSectionStr8(DN_INISection *section, DN_INIStr8 str8);
|
||||
DN_INIFieldStr8 DN_INI_FieldStr8FromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
|
||||
DN_INIFieldBool DN_INI_FieldBoolFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
|
||||
DN_INICore DN_INI_ParseFromPtr (char const *buf, size_t count, char *base, size_t base_count);
|
||||
|
||||
// NOTE: Building
|
||||
DN_INISection * DN_INI_AppendSectionF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *fmt, ...);
|
||||
DN_INIField * DN_INI_AppendKeyBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, bool value);
|
||||
DN_INIField * DN_INI_AppendKeyPtrBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, bool value);
|
||||
DN_INIField * DN_INI_AppendKeyUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, size_t value);
|
||||
DN_INIField * DN_INI_AppendKeyPtrUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, size_t value);
|
||||
DN_INIField * DN_INI_AppendKeyCStr8 (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *value, size_t value_size);
|
||||
DN_INIField * DN_INI_AppendKeyF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *fmt, ...);
|
||||
void DN_INI_AppendField (DN_INISection *section, DN_INIField *field);
|
||||
|
||||
#if defined(DN_INI_WITH_UNIT_TESTS)
|
||||
void DN_INI_UnitTests ();
|
||||
void DN_INI_UnitTests ();
|
||||
#endif
|
||||
#endif // !defined(DN_INI_H)
|
||||
|
||||
@ -2,7 +2,4 @@
|
||||
|
||||
#include "Base/dn_base.cpp"
|
||||
#include "Base/dn_base_containers.cpp"
|
||||
#include "Base/dn_base_convert.cpp"
|
||||
#include "Base/dn_base_mem.cpp"
|
||||
#include "Base/dn_base_string.cpp"
|
||||
#include "Base/dn_base_log.cpp"
|
||||
|
||||
@ -56,10 +56,7 @@
|
||||
#include "Base/dn_base.h"
|
||||
#include "Base/dn_base_os.h"
|
||||
#include "Base/dn_base_assert.h"
|
||||
#include "Base/dn_base_mem.h"
|
||||
#include "Base/dn_base_log.h"
|
||||
#include "Base/dn_base_string.h"
|
||||
#include "Base/dn_base_containers.h"
|
||||
#include "Base/dn_base_convert.h"
|
||||
|
||||
#endif // !defined(DN_BASE_INC_H)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user