Add default allocation type for memstacks, operator bool for slices
This commit is contained in:
parent
a0b64be71b
commit
4f665562f1
@ -10,10 +10,10 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
i32 const ALIGN64 = 64;
|
i32 const ALIGN64 = 64;
|
||||||
i32 const ALIGN16 = 16;
|
i32 const ALIGN16 = 16;
|
||||||
i32 const ALIGN4 = 4;
|
i32 const ALIGN4 = 4;
|
||||||
DqnMemStack::AllocTo allocTo = DqnMemStack::AllocTo::Head;
|
DqnMemStack::PushType push_type = DqnMemStack::PushType::Head;
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
u8 *result1 = (u8 *)stack.Push(2, allocTo, ALIGN4);
|
u8 *result1 = (u8 *)stack.Push(2, push_type, ALIGN4);
|
||||||
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN4);
|
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN4);
|
||||||
DQN_ASSERT(result1 == result2);
|
DQN_ASSERT(result1 == result2);
|
||||||
stack.Pop(result1);
|
stack.Pop(result1);
|
||||||
@ -22,7 +22,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
u8 *result1 = (u8 *)stack.Push(120, allocTo, ALIGN16);
|
u8 *result1 = (u8 *)stack.Push(120, push_type, ALIGN16);
|
||||||
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN16);
|
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN16);
|
||||||
DQN_ASSERT(result1 == result2);
|
DQN_ASSERT(result1 == result2);
|
||||||
stack.Pop(result1);
|
stack.Pop(result1);
|
||||||
@ -31,7 +31,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
|
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
u8 *result1 = (u8 *)stack.Push(12, allocTo, ALIGN64);
|
u8 *result1 = (u8 *)stack.Push(12, push_type, ALIGN64);
|
||||||
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN64);
|
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN64);
|
||||||
DQN_ASSERT(result1 == result2);
|
DQN_ASSERT(result1 == result2);
|
||||||
stack.Pop(result1);
|
stack.Pop(result1);
|
||||||
@ -151,7 +151,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroClear::Yes, DqnMemStack::Flag::BoundsGuard);
|
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroClear::Yes, DqnMemStack::Flag::BoundsGuard);
|
||||||
|
|
||||||
auto *pop1 = stack.Push(222);
|
auto *pop1 = stack.Push(222);
|
||||||
auto *pop2 = stack.Push(333, DqnMemStack::AllocTo::Tail);
|
auto *pop2 = stack.Push(333, DqnMemStack::PushType::Tail);
|
||||||
|
|
||||||
DqnMemStack::Block *blockToReturnTo = stack.block;
|
DqnMemStack::Block *blockToReturnTo = stack.block;
|
||||||
auto headBefore = blockToReturnTo->head;
|
auto headBefore = blockToReturnTo->head;
|
||||||
@ -160,9 +160,9 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
{
|
{
|
||||||
auto memGuard1 = stack.TempRegionGuard();
|
auto memGuard1 = stack.TempRegionGuard();
|
||||||
auto *result2 = stack.Push(100);
|
auto *result2 = stack.Push(100);
|
||||||
auto *result3 = stack.Push(100, DqnMemStack::AllocTo::Tail);
|
auto *result3 = stack.Push(100, DqnMemStack::PushType::Tail);
|
||||||
auto *result4 = stack.Push(100);
|
auto *result4 = stack.Push(100);
|
||||||
auto *result5 = stack.Push(100, DqnMemStack::AllocTo::Tail);
|
auto *result5 = stack.Push(100, DqnMemStack::PushType::Tail);
|
||||||
DQN_ASSERT(result2 && result3 && result4 && result5);
|
DQN_ASSERT(result2 && result3 && result4 && result5);
|
||||||
DQN_ASSERT(result3 > result5);
|
DQN_ASSERT(result3 > result5);
|
||||||
DQN_ASSERT(result2 < result4);
|
DQN_ASSERT(result2 < result4);
|
||||||
@ -298,7 +298,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
DqnMemStack stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroClear::Yes, DqnMemStack::Flag::BoundsGuard);
|
DqnMemStack stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroClear::Yes, DqnMemStack::Flag::BoundsGuard);
|
||||||
|
|
||||||
auto *result1 = stack.Push(100);
|
auto *result1 = stack.Push(100);
|
||||||
auto *result2 = stack.Push(100, DqnMemStack::AllocTo::Tail);
|
auto *result2 = stack.Push(100, DqnMemStack::PushType::Tail);
|
||||||
auto *headBefore = stack.block->head;
|
auto *headBefore = stack.block->head;
|
||||||
auto *tail_before = stack.block->tail;
|
auto *tail_before = stack.block->tail;
|
||||||
DQN_ASSERT(result2 && result1);
|
DQN_ASSERT(result2 && result1);
|
||||||
@ -330,7 +330,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
|
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
|
||||||
auto *block_before = stack.block;
|
auto *block_before = stack.block;
|
||||||
|
|
||||||
auto *result2 = stack.Push(DQN_MEGABYTE(1), DqnMemStack::AllocTo::Tail);
|
auto *result2 = stack.Push(DQN_MEGABYTE(1), DqnMemStack::PushType::Tail);
|
||||||
DQN_ASSERT(result2 && result1);
|
DQN_ASSERT(result2 && result1);
|
||||||
DQN_ASSERT(result2 != result1);
|
DQN_ASSERT(result2 != result1);
|
||||||
DQN_ASSERT(stack.block->prev_block == block_before);
|
DQN_ASSERT(stack.block->prev_block == block_before);
|
||||||
@ -360,7 +360,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
|
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
|
||||||
auto *block_before = stack.block;
|
auto *block_before = stack.block;
|
||||||
|
|
||||||
auto *result2 = stack.Push(DQN_MEGABYTE(1), DqnMemStack::AllocTo::Tail);
|
auto *result2 = stack.Push(DQN_MEGABYTE(1), DqnMemStack::PushType::Tail);
|
||||||
DQN_ASSERT(result2 == nullptr);
|
DQN_ASSERT(result2 == nullptr);
|
||||||
DQN_ASSERT(stack.block->prev_block == nullptr);
|
DQN_ASSERT(stack.block->prev_block == nullptr);
|
||||||
DQN_ASSERT(stack.block == block_before);
|
DQN_ASSERT(stack.block == block_before);
|
||||||
@ -427,7 +427,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
auto *tail_before = stack.block->tail;
|
auto *tail_before = stack.block->tail;
|
||||||
|
|
||||||
isize buf_size = 16;
|
isize buf_size = 16;
|
||||||
char *buf = (char *)stack.Push(buf_size, DqnMemStack::AllocTo::Tail);
|
char *buf = (char *)stack.Push(buf_size, DqnMemStack::PushType::Tail);
|
||||||
DqnMem_Set(buf, 'X', buf_size);
|
DqnMem_Set(buf, 'X', buf_size);
|
||||||
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
|
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
|
||||||
|
|
||||||
@ -491,7 +491,7 @@ FILE_SCOPE void DqnMemStack_Test()
|
|||||||
auto *tail_before = stack.block->tail;
|
auto *tail_before = stack.block->tail;
|
||||||
|
|
||||||
isize buf_size = 16;
|
isize buf_size = 16;
|
||||||
char *buf = (char *)stack.Push(buf_size, DqnMemStack::AllocTo::Tail);
|
char *buf = (char *)stack.Push(buf_size, DqnMemStack::PushType::Tail);
|
||||||
DqnMem_Set(buf, 'X', buf_size);
|
DqnMem_Set(buf, 'X', buf_size);
|
||||||
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
|
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
|
||||||
|
|
||||||
|
82
dqn.h
82
dqn.h
@ -770,19 +770,20 @@ struct DqnSlice
|
|||||||
union { T *data; T *str; };
|
union { T *data; T *str; };
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
operator bool() const { bool result = (str != nullptr); return result; }
|
||||||
DqnSlice() = default;
|
DqnSlice() = default;
|
||||||
DqnSlice(T *data_, int len_) : data(data_), len(len_) {}
|
DqnSlice(T *data_, int len_) : data(data_), len(len_) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
using DqnBuffer = DqnSlice<T>;
|
using DqnBuffer = DqnSlice<T>;
|
||||||
|
|
||||||
#define DQN_BUFFER_STR_LIT(literal) DqnBuffer<char const>(literal, DQN_CHAR_COUNT(literal))
|
#define DQN_BUFFER_STR_LIT(literal) DqnBuffer<char const>(literal, DQN_CHAR_COUNT(literal))
|
||||||
#define DQN_BUFFER_STRCMP(a, b, ignore_case) ((a).len == (b).len && (DqnStr_Cmp((char *)((a).str), (char *)((b).str), (a).len, ignore_case) == 0))
|
#define DQN_BUFFER_STRCMP(a, b, ignore_case) ((a).len == (b).len && (DqnStr_Cmp((char *)((a).str), (char *)((b).str), (a).len, ignore_case) == 0))
|
||||||
#define DQN_BUFFER_MEMCMP(a, b) ((a).len == (b).len && (DqnMem_Cmp((void *)((a).str), (void *)((b).str), (a).len) == 0))
|
#define DQN_BUFFER_MEMCMP(a, b) ((a).len == (b).len && (DqnMem_Cmp((void *)((a).str), (void *)((b).str), (a).len) == 0))
|
||||||
|
|
||||||
#define DQN_BUFFER_STR_LIT_STRCMP(a, b, ignore_case) ((a).len == (b).len && (DqnStr_Cmp((char *)((a).str), (char *)((b).str), (a).len, ignore_case) == 0))
|
#define DQN_SLICE_STRCMP(a, b, ignore_case) ((a).len == (b).len && (DqnStr_Cmp((char *)((a).str), (char *)((b).str), (a).len, ignore_case) == 0))
|
||||||
#define DQN_BUFFER_STR_LIT_MEMCMP(a, b) ((a).len == (b).len && (DqnMem_Cmp((void *)((a).str), (void *)((b).str), (a).len) == 0))
|
#define DQN_SLICE_MEMCMP(a, b) ((a).len == (b).len && (DqnMem_Cmp((void *)((a).str), (void *)((b).str), (a).len) == 0))
|
||||||
// #DqnChar API
|
// #DqnChar API
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
DQN_FILE_SCOPE char DqnChar_ToLower (char c);
|
DQN_FILE_SCOPE char DqnChar_ToLower (char c);
|
||||||
@ -902,7 +903,8 @@ i32 Dqn_SplitString(char const *src, i32 src_len, char split_char, DqnSlice<char
|
|||||||
i32 Dqn_GetNumSplits(char const *src, i32 src_len, char split_char);
|
i32 Dqn_GetNumSplits(char const *src, i32 src_len, char split_char);
|
||||||
|
|
||||||
// Skips whitespace then reads UTF8 rune upto first \r or \n and null terminates at that point. Advances input to the start of the next line.
|
// Skips whitespace then reads UTF8 rune upto first \r or \n and null terminates at that point. Advances input to the start of the next line.
|
||||||
// return: The immediate null terminated line
|
// line_len: (Optional) Returns the length of the null terminated line returned
|
||||||
|
// return : The immediate null terminated line, nullptr if no more lines are to be read.
|
||||||
DQN_FILE_SCOPE char *Dqn_EatLine(char **input, int *line_len);
|
DQN_FILE_SCOPE char *Dqn_EatLine(char **input, int *line_len);
|
||||||
DQN_FILE_SCOPE wchar_t *Dqn_EatLine(wchar_t **input, int *line_len);
|
DQN_FILE_SCOPE wchar_t *Dqn_EatLine(wchar_t **input, int *line_len);
|
||||||
|
|
||||||
@ -1358,16 +1360,16 @@ template <typename T> void DqnArray<T>::Reserve(isize new_max)
|
|||||||
// #DqnMemTracker
|
// #DqnMemTracker
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
// Allocation Layout
|
// Allocation Layout
|
||||||
// +--------------------+-------------------------------------------------------------------------+-----------------------------+-----------------+
|
// +--------------------+-------------------------------------------------------------------------+------------------------+-----------------+
|
||||||
// | Ptr From Allocator | Offset To Src | Alignment | Alloc Type | Alloc Amount | B. Guard (Opt.) | Aligned Ptr For Client | B. Guard (Opt.) |
|
// | Ptr From Allocator | Offset To Src | Alignment | Alloc Type | Alloc Amount | B. Guard (Opt.) | Aligned Ptr For Client | B. Guard (Opt.) |
|
||||||
// +--------------------+-------------------------------------------------------------------------+-----------------------------+-----------------+
|
// +--------------------+-------------------------------------------------------------------------+------------------------+-----------------+
|
||||||
// Ptr From Allocator: The pointer returned by the allocator, not aligned
|
// Ptr From Allocator: The pointer returned by the allocator, not aligned
|
||||||
|
// Offset To Src: Number of bytes to subtract from the "Aligned Ptr For Client" to return to the "Ptr From Allocator"
|
||||||
// Alignment: The pointer given to the client is aligned to this power of two boundary
|
// Alignment: The pointer given to the client is aligned to this power of two boundary
|
||||||
// Alloc Type: If the allocation was allocated from the head or tail of the memory block (mainly for memstacks).
|
// Alloc Type: If the allocation was allocated from the head or tail of the memory block (mainly for memstacks).
|
||||||
// Alloc Amount: The requested allocation amount by the client (so does not include metadata)
|
// Alloc Amount: The requested allocation amount by the client (so does not include metadata)
|
||||||
// B. Guard: Bounds Guard value.
|
// B. Guard: Bounds Guard value.
|
||||||
// Aligned Ptr For Client: The allocated memory for the client.
|
// Aligned Ptr For Client: The allocated memory for the client.
|
||||||
// Offset To Src: Number of bytes to subtract from the "Aligned Ptr For Client" to return to the "Ptr From Allocator"
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct DqnPtrHeader
|
struct DqnPtrHeader
|
||||||
@ -1428,7 +1430,8 @@ struct DqnMemStack
|
|||||||
NonExpandableAssert = (1 << 1), // Assert when non-expandable is set and we run out of space
|
NonExpandableAssert = (1 << 1), // Assert when non-expandable is set and we run out of space
|
||||||
BoundsGuard = (1 << 2), // Track, check and add 4 byte guards on the boundaries of all allocations
|
BoundsGuard = (1 << 2), // Track, check and add 4 byte guards on the boundaries of all allocations
|
||||||
PushAssertsOnFail = (1 << 3), // Assert when push() fails.
|
PushAssertsOnFail = (1 << 3), // Assert when push() fails.
|
||||||
All = (NonExpandable | NonExpandableAssert | BoundsGuard | PushAssertsOnFail),
|
DefaultAllocateTail = (1 << 4), // If set, allocate to tail when push_type is unspecified, otherwise allocate to head
|
||||||
|
DefaultFlags = (NonExpandable | NonExpandableAssert | BoundsGuard | PushAssertsOnFail),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Info // Statistics of the memory stack.
|
struct Info // Statistics of the memory stack.
|
||||||
@ -1441,16 +1444,15 @@ struct DqnMemStack
|
|||||||
|
|
||||||
struct Block
|
struct Block
|
||||||
{
|
{
|
||||||
char *memory; // Read
|
char *memory;
|
||||||
isize size; // Read
|
isize size;
|
||||||
isize used_; // Read
|
char *head;
|
||||||
Block *prev_block; // Read Uses a linked list approach for additional blocks
|
char *tail;
|
||||||
|
Block *prev_block;
|
||||||
char *head; // Read
|
|
||||||
char *tail; // Read
|
|
||||||
|
|
||||||
Block() = default;
|
Block() = default;
|
||||||
Block(void *memory_, isize size_) { *this = {}; memory = (char *)memory_; size = size_; head = memory; tail = memory + size; }
|
Block(void *memory_, isize size_) { *this = {}; memory = (char *)memory_; size = size_; head = memory; tail = memory + size; }
|
||||||
|
isize Usage() const { return size - (tail - head); }
|
||||||
};
|
};
|
||||||
|
|
||||||
DqnMemTracker tracker; // Read: Metadata for managing ptr allocation
|
DqnMemTracker tracker; // Read: Metadata for managing ptr allocation
|
||||||
@ -1470,12 +1472,13 @@ struct DqnMemStack
|
|||||||
|
|
||||||
// Allocation API
|
// Allocation API
|
||||||
// =============================================================================================
|
// =============================================================================================
|
||||||
enum struct AllocTo { Head, Tail };
|
enum struct PushType { Default, Head, Tail };
|
||||||
|
|
||||||
// Allocate memory from the MemStack.
|
// Allocate memory from the MemStack.
|
||||||
// alignment: Ptr returned from allocator is aligned to this value and MUST be power of 2.
|
// alignment: Ptr returned from allocator is aligned to this value and MUST be power of 2.
|
||||||
// return: nullptr if out of space OR stack is using fixed memory/size OR stack full and platform malloc fails.
|
// return: nullptr if out of space OR stack is using fixed memory/size OR stack full and platform malloc fails.
|
||||||
void *Push (isize size, AllocTo allocTo = AllocTo::Head, u8 alignment = 4);
|
void *Push (isize size, PushType push_type = PushType::Default, u8 alignment = 4);
|
||||||
|
void SetDefaultAllocate(PushType type) { if (type == PushType::Default) return; if (type == PushType::Head) flags |= Flag::DefaultAllocateTail; else flags &= ~Flag::DefaultAllocateTail; }
|
||||||
|
|
||||||
// Frees the given ptr. It MUST be the last allocated item in the stack, asserts otherwise.
|
// Frees the given ptr. It MUST be the last allocated item in the stack, asserts otherwise.
|
||||||
void Pop (void *ptr, Dqn::ZeroClear clear = Dqn::ZeroClear::No);
|
void Pop (void *ptr, Dqn::ZeroClear clear = Dqn::ZeroClear::No);
|
||||||
@ -1532,10 +1535,10 @@ struct DqnMemStack
|
|||||||
void FreeHead (void *ptr) { (void)ptr; return; }
|
void FreeHead (void *ptr) { (void)ptr; return; }
|
||||||
void *ReallocHead(void *ptr, size_t size) { DqnPtrHeader *header = tracker.PtrToHeader((char *)ptr); void *result = Push(size); DqnMem_Copy(result, ptr, header->alloc_amount); return result; }
|
void *ReallocHead(void *ptr, size_t size) { DqnPtrHeader *header = tracker.PtrToHeader((char *)ptr); void *result = Push(size); DqnMem_Copy(result, ptr, header->alloc_amount); return result; }
|
||||||
|
|
||||||
void *MallocTail (size_t size) { return Push(size, AllocTo::Tail); }
|
void *MallocTail (size_t size) { return Push(size, PushType::Tail); }
|
||||||
void *CallocTail (size_t size) { void *result = Push(size, AllocTo::Tail); DqnMem_Clear(result, 0, size); }
|
void *CallocTail (size_t size) { void *result = Push(size, PushType::Tail); DqnMem_Clear(result, 0, size); }
|
||||||
void FreeTail (void *ptr) { (void)ptr; return; }
|
void FreeTail (void *ptr) { (void)ptr; return; }
|
||||||
void *ReallocTail(void *ptr, size_t size) { DqnPtrHeader *header = tracker.PtrToHeader((char *)ptr); void *result = Push(size, AllocTo::Tail); DqnMem_Copy(result, ptr, header->alloc_amount); return result; }
|
void *ReallocTail(void *ptr, size_t size) { DqnPtrHeader *header = tracker.PtrToHeader((char *)ptr); void *result = Push(size, PushType::Tail); DqnMem_Copy(result, ptr, header->alloc_amount); return result; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// #DqnHash API
|
// #DqnHash API
|
||||||
@ -2407,8 +2410,8 @@ DQN_FILE_SCOPE bool DqnFile_ReadAll(wchar_t const *path, u8 *buf, usize buf_si
|
|||||||
// return: False if file access failure OR nullptr arguments.
|
// return: False if file access failure OR nullptr arguments.
|
||||||
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnAllocator *allocator = DQN_DEFAULT_ALLOCATOR);
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnAllocator *allocator = DQN_DEFAULT_ALLOCATOR);
|
||||||
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnAllocator *allocator = DQN_DEFAULT_ALLOCATOR);
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnAllocator *allocator = DQN_DEFAULT_ALLOCATOR);
|
||||||
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::AllocTo allocTo = DqnMemStack::AllocTo::Head);
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::PushType push_type = DqnMemStack::PushType::Head);
|
||||||
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::AllocTo allocTo = DqnMemStack::AllocTo::Head);
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::PushType push_type = DqnMemStack::PushType::Head);
|
||||||
|
|
||||||
DQN_FILE_SCOPE bool DqnFile_WriteAll(char const *path, u8 const *buf, usize const buf_size);
|
DQN_FILE_SCOPE bool DqnFile_WriteAll(char const *path, u8 const *buf, usize const buf_size);
|
||||||
DQN_FILE_SCOPE bool DqnFile_WriteAll(wchar_t const *path, u8 const *buf, usize const buf_size);
|
DQN_FILE_SCOPE bool DqnFile_WriteAll(wchar_t const *path, u8 const *buf, usize const buf_size);
|
||||||
@ -2989,19 +2992,29 @@ void DqnMemStack::LazyInit(isize size, Dqn::ZeroClear clear, u32 flags_, DqnAllo
|
|||||||
this->tracker.Init(bounds_guard);
|
this->tracker.Init(bounds_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *DqnMemStack::Push(isize size, AllocTo allocTo, u8 alignment)
|
void *DqnMemStack::Push(isize size, PushType push_type, u8 alignment)
|
||||||
{
|
{
|
||||||
DQN_ASSERT(size >= 0 && (alignment % 2 == 0));
|
DQN_ASSERT(size >= 0 && (alignment % 2 == 0));
|
||||||
DQN_ALWAYS_ASSERTM(alignment <= 128, "Alignment supported. Update metadata to use u16 for storing the offset!");
|
DQN_ALWAYS_ASSERTM(alignment <= 128, "Alignment _not_ supported. Update metadata to use u16 for storing the offset!");
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!this->block)
|
if (!this->block)
|
||||||
LazyInit(MINIMUM_BLOCK_SIZE, Dqn::ZeroClear::Yes, Flag::All, DQN_DEFAULT_ALLOCATOR);
|
LazyInit(MINIMUM_BLOCK_SIZE, Dqn::ZeroClear::Yes, Flag::DefaultFlags, DQN_DEFAULT_ALLOCATOR);
|
||||||
|
|
||||||
bool const push_to_head = (allocTo == AllocTo::Head);
|
|
||||||
isize size_to_alloc = this->tracker.GetAllocationSize(size, alignment);
|
isize size_to_alloc = this->tracker.GetAllocationSize(size, alignment);
|
||||||
|
bool push_to_head = true;
|
||||||
|
if (push_type == PushType::Default)
|
||||||
|
{
|
||||||
|
if (this->flags & Flag::DefaultAllocateTail) push_to_head = false;
|
||||||
|
else push_to_head = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
push_to_head = (push_type == PushType::Head);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Allocate New Block If Full
|
// Allocate New Block If Full
|
||||||
// =============================================================================================
|
// =============================================================================================
|
||||||
@ -3045,7 +3058,6 @@ void *DqnMemStack::Push(isize size, AllocTo allocTo, u8 alignment)
|
|||||||
DQN_ASSERT(this->block->tail >= this->block->head);
|
DQN_ASSERT(this->block->tail >= this->block->head);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->block->used_ = this->block->size - (this->block->tail - this->block->head);
|
|
||||||
// Instrument allocation with guards and tracker
|
// Instrument allocation with guards and tracker
|
||||||
// =============================================================================================
|
// =============================================================================================
|
||||||
{
|
{
|
||||||
@ -4240,13 +4252,13 @@ DQN_FILE_SCOPE char *Dqn_EatLine(char **input, int *line_len)
|
|||||||
{
|
{
|
||||||
char *ptr_to_rune = (*input - rune_len);
|
char *ptr_to_rune = (*input - rune_len);
|
||||||
*ptr_to_rune = 0;
|
*ptr_to_rune = 0;
|
||||||
*line_len = static_cast<int>(ptr_to_rune - result);
|
if (line_len) *line_len = static_cast<int>(ptr_to_rune - result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rune_len == 0)
|
else if (rune_len == 0)
|
||||||
{
|
{
|
||||||
*line_len = static_cast<int>(*input - result);
|
if (line_len) *line_len = static_cast<int>(*input - result);
|
||||||
*input = nullptr;
|
*input = nullptr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -4262,7 +4274,7 @@ DQN_FILE_SCOPE wchar_t *Dqn_EatLine(wchar_t **input, int *line_len)
|
|||||||
{
|
{
|
||||||
if (!(*input))
|
if (!(*input))
|
||||||
{
|
{
|
||||||
*line_len = static_cast<int>(*input - result);
|
if (line_len) *line_len = static_cast<int>(*input - result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4270,7 +4282,7 @@ DQN_FILE_SCOPE wchar_t *Dqn_EatLine(wchar_t **input, int *line_len)
|
|||||||
if (ch == '\r' || ch == '\n')
|
if (ch == '\r' || ch == '\n')
|
||||||
{
|
{
|
||||||
(*input)[0] = 0;
|
(*input)[0] = 0;
|
||||||
*line_len = static_cast<int>(*input - result);
|
if (line_len) *line_len = static_cast<int>(*input - result);
|
||||||
(*input)++;
|
(*input)++;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -7760,7 +7772,7 @@ DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnAllocat
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::AllocTo allocTo)
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::PushType push_type)
|
||||||
{
|
{
|
||||||
u8 *result = nullptr;
|
u8 *result = nullptr;
|
||||||
DqnFile file = {};
|
DqnFile file = {};
|
||||||
@ -7771,7 +7783,7 @@ DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnMemS
|
|||||||
}
|
}
|
||||||
DQN_DEFER(file.Close());
|
DQN_DEFER(file.Close());
|
||||||
|
|
||||||
result = static_cast<u8 *>(stack->Push(file.size, allocTo));
|
result = static_cast<u8 *>(stack->Push(file.size, push_type));
|
||||||
usize bytes_read = file.Read(result, file.size);
|
usize bytes_read = file.Read(result, file.size);
|
||||||
if (bytes_read == file.size)
|
if (bytes_read == file.size)
|
||||||
{
|
{
|
||||||
@ -7785,7 +7797,7 @@ DQN_FILE_SCOPE u8 *DqnFile_ReadAll(wchar_t const *path, usize *buf_size, DqnMemS
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::AllocTo allocTo)
|
DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnMemStack *stack, DqnMemStack::PushType push_type)
|
||||||
{
|
{
|
||||||
u8 *result = nullptr;
|
u8 *result = nullptr;
|
||||||
DqnFile file = {};
|
DqnFile file = {};
|
||||||
@ -7796,7 +7808,7 @@ DQN_FILE_SCOPE u8 *DqnFile_ReadAll(char const *path, usize *buf_size, DqnMemStac
|
|||||||
}
|
}
|
||||||
DQN_DEFER(file.Close());
|
DQN_DEFER(file.Close());
|
||||||
|
|
||||||
result = static_cast<u8 *>(stack->Push(file.size, allocTo));
|
result = static_cast<u8 *>(stack->Push(file.size, push_type));
|
||||||
usize bytes_read = file.Read(result, file.size);
|
usize bytes_read = file.Read(result, file.size);
|
||||||
if (bytes_read == file.size)
|
if (bytes_read == file.size)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user