Cleanup base layer

This commit is contained in:
doylet 2025-10-19 22:31:56 +11:00
parent fd7a543e34
commit fff3fe1988
50 changed files with 5056 additions and 4848 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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,6 +420,363 @@ struct DN_TicketMutex
unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned
};
struct DN_U64FromResult
{
bool success;
DN_U64 value;
};
struct DN_I64FromResult
{
bool success;
DN_I64 value;
};
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 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,
// 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);
@ -492,4 +865,193 @@ DN_API void DN_ASanUnpoisonMemoryRegion(void const volatile *ptr, DN_
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)

View File

@ -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; \
} \

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
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.
//

View File

@ -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);
}
}

View File

@ -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

View File

@ -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 \
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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)

View File

@ -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 = {};
}

View File

@ -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"));
}

View File

@ -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.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;

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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,61 +56,131 @@ 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;
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;
size_t count;
size_t pos;
DN_INIToken prev_token;
uint32_t line;
uint32_t column;
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_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);
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);
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);
// 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 ();

View File

@ -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"

View File

@ -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)