Latest primitive changes
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
// Generated by the DN single header generator 2026-07-08 14:23:35
|
// Generated by the DN single header generator 2026-07-12 16:23:32
|
||||||
|
|
||||||
// DN: Single header generator commented out => #if defined(_CLANGD)
|
// DN: Single header generator commented out => #if defined(_CLANGD)
|
||||||
// #define DN_WITH_TESTS 1
|
// #define DN_WITH_TESTS 1
|
||||||
@@ -350,6 +350,18 @@ DN_API DN_U32 DN_AlignUpPowerOfTwoU32(DN_U32 val)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN_API void DN_ByteSwapU64Ptr(DN_U8 *dest, DN_U64 src)
|
||||||
|
{
|
||||||
|
dest[0] = DN_Cast(DN_U8)((src >> 56) & 0xFF);
|
||||||
|
dest[1] = DN_Cast(DN_U8)((src >> 48) & 0xFF);
|
||||||
|
dest[2] = DN_Cast(DN_U8)((src >> 40) & 0xFF);
|
||||||
|
dest[3] = DN_Cast(DN_U8)((src >> 32) & 0xFF);
|
||||||
|
dest[4] = DN_Cast(DN_U8)((src >> 24) & 0xFF);
|
||||||
|
dest[5] = DN_Cast(DN_U8)((src >> 16) & 0xFF);
|
||||||
|
dest[6] = DN_Cast(DN_U8)((src >> 8) & 0xFF);
|
||||||
|
dest[7] = DN_Cast(DN_U8)(src & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
DN_API DN_CPUIDResult DN_CPUID(DN_CPUIDArgs args)
|
DN_API DN_CPUIDResult DN_CPUID(DN_CPUIDArgs args)
|
||||||
{
|
{
|
||||||
DN_CPUIDResult result = {};
|
DN_CPUIDResult result = {};
|
||||||
@@ -2591,19 +2603,48 @@ DN_API DN_USizeFromResult DN_USizeFromU8x32HiBE(DN_U8x32 const *val)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void DN_ByteSwapU64Ptr(DN_U8 *dest, DN_U64 src)
|
static DN_U32FromResult DN_U32FromU64FromResult_(DN_U64FromResult u64)
|
||||||
{
|
{
|
||||||
dest[0] = DN_Cast(DN_U8)((src >> 56) & 0xFF);
|
DN_U32FromResult result = {};
|
||||||
dest[1] = DN_Cast(DN_U8)((src >> 48) & 0xFF);
|
result.value = DN_Cast(DN_U32)DN_Min(u64.value, UINT32_MAX);
|
||||||
dest[2] = DN_Cast(DN_U8)((src >> 40) & 0xFF);
|
result.success = u64.value <= UINT32_MAX;
|
||||||
dest[3] = DN_Cast(DN_U8)((src >> 32) & 0xFF);
|
return result;
|
||||||
dest[4] = DN_Cast(DN_U8)((src >> 24) & 0xFF);
|
|
||||||
dest[5] = DN_Cast(DN_U8)((src >> 16) & 0xFF);
|
|
||||||
dest[6] = DN_Cast(DN_U8)((src >> 8) & 0xFF);
|
|
||||||
dest[7] = DN_Cast(DN_U8)(src & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
DN_API DN_U32FromResult DN_U32FromHexStr8(DN_Str8 hex)
|
||||||
|
{
|
||||||
|
DN_U64FromResult u64 = DN_U64FromHexPtr(hex.data, hex.count);
|
||||||
|
DN_U32FromResult result = DN_U32FromU64FromResult_(u64);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiters(DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count)
|
||||||
|
{
|
||||||
|
DN_U64FromResult u64 = DN_U64FromStr8Delimiters(string, delimiters, delimiters_count);
|
||||||
|
DN_U32FromResult result = DN_U32FromU64FromResult_(u64);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiter(DN_Str8 string, DN_Str8 delimiter)
|
||||||
|
{
|
||||||
|
DN_U32FromResult result = DN_U32FromStr8Delimiters(string, &delimiter, 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromStr8(DN_Str8 string)
|
||||||
|
{
|
||||||
|
DN_U64FromResult u64 = DN_U64FromStr8(string);
|
||||||
|
DN_U32FromResult result = DN_U32FromU64FromResult_(u64);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromPtr(void const *data, DN_USize size)
|
||||||
|
{
|
||||||
|
DN_U32FromResult result = DN_U32FromStr8(DN_Str8FromPtr(data, size));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiters(DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count)
|
||||||
{
|
{
|
||||||
// NOTE: Argument check
|
// NOTE: Argument check
|
||||||
DN_I64FromResult result = {};
|
DN_I64FromResult result = {};
|
||||||
@@ -2619,6 +2660,7 @@ DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Handle negation
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
DN_USize start_index = 0;
|
DN_USize start_index = 0;
|
||||||
if (!DN_CharIsDigit(trim_string.data[0])) {
|
if (!DN_CharIsDigit(trim_string.data[0])) {
|
||||||
@@ -2630,12 +2672,25 @@ DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
|||||||
|
|
||||||
// NOTE: Convert the string number to the binary number
|
// NOTE: Convert the string number to the binary number
|
||||||
for (DN_USize index = start_index; index < trim_string.count; index++) {
|
for (DN_USize index = start_index; index < trim_string.count; index++) {
|
||||||
char ch = trim_string.data[index];
|
|
||||||
|
// NOTE: Check for presence of the delimiter, we skip the first character as a U64 string
|
||||||
|
// prefixed with a delimiter is not considered valid.
|
||||||
if (index) {
|
if (index) {
|
||||||
if (separator != 0 && ch == separator)
|
DN_USize max_delimiter_match = 0;
|
||||||
|
for (DN_ForItSize(it, DN_Str8 const, delimiters, delimiters_count)) {
|
||||||
|
DN_Str8 delimiter = *it.data;
|
||||||
|
DN_Str8 check_slice = DN_Str8Subset(trim_string, index, delimiter.count);
|
||||||
|
if (DN_Str8EqSensitive(check_slice, delimiter))
|
||||||
|
max_delimiter_match = DN_Max(max_delimiter_match, delimiter.count); // Take length, there might be multiple so we keep going
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_delimiter_match) {
|
||||||
|
index += max_delimiter_match - 1;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char ch = trim_string.data[index];
|
||||||
if (!DN_CharIsDigit(ch))
|
if (!DN_CharIsDigit(ch))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -2651,16 +2706,28 @@ DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_I64FromResult DN_I64FromPtr(void const *data, DN_USize size, char separator)
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiter(DN_Str8 string, DN_Str8 delimiter)
|
||||||
{
|
{
|
||||||
DN_Str8 str8 = DN_Str8FromPtr((char *)data, size);
|
DN_I64FromResult result = DN_I64FromStr8Delimiters(string, &delimiter, 1);
|
||||||
DN_I64FromResult result = DN_I64FromStr8(str8, separator);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_I64 DN_I64FromPtrUnsafe(void const *data, DN_USize size, char separator)
|
DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string)
|
||||||
{
|
{
|
||||||
DN_I64FromResult from = DN_I64FromPtr(data, size, separator);
|
DN_I64FromResult result = DN_I64FromStr8Delimiters(string, nullptr, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_I64FromResult DN_I64FromPtr(void const *data, DN_USize size)
|
||||||
|
{
|
||||||
|
DN_Str8 str8 = DN_Str8FromPtr((char *)data, size);
|
||||||
|
DN_I64FromResult result = DN_I64FromStr8Delimiters(str8, nullptr, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_I64 DN_I64FromPtrUnsafe(void const *data, DN_USize size)
|
||||||
|
{
|
||||||
|
DN_I64FromResult from = DN_I64FromPtr(data, size);
|
||||||
DN_I64 result = from.value;
|
DN_I64 result = from.value;
|
||||||
DN_Assert(from.success);
|
DN_Assert(from.success);
|
||||||
return result;
|
return result;
|
||||||
@@ -5168,6 +5235,12 @@ DN_API DN_Hex64 DN_Hex64FromPtrBytes32(void const *bytes, DN_USize bytes_count,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN_API DN_Hex64 DN_Hex64FromU8x32(DN_U8x32 const *value, DN_TrimLeadingZero trim_leading_z)
|
||||||
|
{
|
||||||
|
DN_Hex64 result = DN_Hex64FromPtrBytes32(value->data, DN_ArrayCountU(value->data), trim_leading_z);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DN_API DN_Hex128 DN_Hex128FromPtrBytes64(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
DN_API DN_Hex128 DN_Hex128FromPtrBytes64(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||||
{
|
{
|
||||||
DN_Hex128 result = {};
|
DN_Hex128 result = {};
|
||||||
@@ -9219,7 +9292,7 @@ DN_API void DN_CSVPackI64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_I64 *v
|
|||||||
{
|
{
|
||||||
if (serialise == DN_CSVSerialise_Read) {
|
if (serialise == DN_CSVSerialise_Read) {
|
||||||
DN_Str8 csv_value = DN_CSVTokeniserNextColumn(&pack->read_tokeniser);
|
DN_Str8 csv_value = DN_CSVTokeniserNextColumn(&pack->read_tokeniser);
|
||||||
DN_I64FromResult to_i64 = DN_I64FromStr8(csv_value, 0);
|
DN_I64FromResult to_i64 = DN_I64FromStr8(csv_value);
|
||||||
DN_Assert(to_i64.success);
|
DN_Assert(to_i64.success);
|
||||||
*value = to_i64.value;
|
*value = to_i64.value;
|
||||||
} else {
|
} else {
|
||||||
@@ -10907,49 +10980,49 @@ DN_API DN_TestCore DN_TestSuite(DN_Arena *arena_)
|
|||||||
|
|
||||||
// NOTE: DN_I64FromStr8
|
// NOTE: DN_I64FromStr8
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert empty string")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert empty string")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit(""), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit(""));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 0);
|
DN_TestVerifyExpr(&result, str_result.value == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1"));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 1);
|
DN_TestVerifyExpr(&result, str_result.value == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-0\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-0\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-0"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-0"));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 0);
|
DN_TestVerifyExpr(&result, str_result.value == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-1\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-1\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-1"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-1"));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == -1);
|
DN_TestVerifyExpr(&result, str_result.value == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1.2\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1.2\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1.2"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1.2"));
|
||||||
DN_TestVerifyExpr(&result, !str_result.success);
|
DN_TestVerifyExpr(&result, !str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 1);
|
DN_TestVerifyExpr(&result, str_result.value == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,234\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,234\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,234"), ',');
|
DN_I64FromResult str_result = DN_I64FromStr8Delimiter(DN_Str8Lit("1,234"), DN_Str8Lit(","));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 1234);
|
DN_TestVerifyExpr(&result, str_result.value == 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,2\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,2\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,2"), ',');
|
DN_I64FromResult str_result = DN_I64FromStr8Delimiter(DN_Str8Lit("1,2"), DN_Str8Lit(","));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 12);
|
DN_TestVerifyExpr(&result, str_result.value == 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"12a3\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"12a3\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("12a3"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("12a3"));
|
||||||
DN_TestVerifyExpr(&result, !str_result.success);
|
DN_TestVerifyExpr(&result, !str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 12);
|
DN_TestVerifyExpr(&result, str_result.value == 12);
|
||||||
}
|
}
|
||||||
@@ -16171,8 +16244,14 @@ DN_NETRequestHandle DN_NET_SetupRequest(DN_NETRequest *request, DN_Str8 url, DN_
|
|||||||
// NOTE: Setup request
|
// NOTE: Setup request
|
||||||
DN_Assert(request);
|
DN_Assert(request);
|
||||||
if (request) {
|
if (request) {
|
||||||
if (!request->mem.curr)
|
if (request->mem.curr)
|
||||||
|
DN_AssertF(request->arena.mem == nullptr,
|
||||||
|
"DN_NET_RequestRecycle should be called on the request before putting it into the "
|
||||||
|
"free-list and reusing it. This is so that we centralise the one place that we "
|
||||||
|
"reinitialise the temp arena for the request into this codepath.");
|
||||||
|
else
|
||||||
request->mem = DN_MemListFromHeap(DN_Megabytes(1), DN_Kilobytes(1), DN_MemFlags_Nil, DN_OS_HeapInitVirtual());
|
request->mem = DN_MemListFromHeap(DN_Megabytes(1), DN_Kilobytes(1), DN_MemFlags_Nil, DN_OS_HeapInitVirtual());
|
||||||
|
|
||||||
request->arena = DN_ArenaTempBeginFromMemList(&request->mem);
|
request->arena = DN_ArenaTempBeginFromMemList(&request->mem);
|
||||||
request->type = type;
|
request->type = type;
|
||||||
request->gen = DN_Max(request->gen + 1, 1);
|
request->gen = DN_Max(request->gen + 1, 1);
|
||||||
@@ -16205,10 +16284,25 @@ DN_NETRequestHandle DN_NET_SetupRequest(DN_NETRequest *request, DN_Str8 url, DN_
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DN_NET_EndFinishedRequest(DN_NETRequest *request)
|
void DN_NET_RequestRecycle(DN_NETRequest *request)
|
||||||
{
|
{
|
||||||
// NOTE: Deallocate the memory used in the request and reset the string builder
|
DN_NETRequest resetter = {};
|
||||||
|
resetter.mem = request->mem;
|
||||||
|
resetter.arena = request->arena;
|
||||||
|
resetter.start_response_arena = request->start_response_arena;
|
||||||
|
resetter.gen = request->gen + 1;
|
||||||
|
DN_Memcpy(resetter.context, request->context, sizeof(resetter.context));
|
||||||
|
*request = resetter;
|
||||||
|
|
||||||
|
// NOTE: Deallocate the memory used in the request. Note we have to end the start response arena
|
||||||
|
// first to satisfy the UAF checker which requires that the temporary memory arenas are ended in
|
||||||
|
// the reverse order that they were created in.
|
||||||
|
//
|
||||||
|
// The arenas are created when `DN_NET_SetupRequest` is called to reuse the request.
|
||||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||||
|
DN_ArenaTempEnd(&request->arena, DN_ArenaReset_Yes);
|
||||||
|
request->arena = {};
|
||||||
|
request->start_response_arena = {};
|
||||||
}
|
}
|
||||||
#endif // #if DN_WITH_NET
|
#endif // #if DN_WITH_NET
|
||||||
|
|
||||||
@@ -16276,8 +16370,13 @@ static void DN_NET_CurlMarkRequestDone_(DN_NETCore *net, DN_NETRequest *request)
|
|||||||
DN_NETCurlCore *curl = DN_Cast(DN_NETCurlCore *)net->context;
|
DN_NETCurlCore *curl = DN_Cast(DN_NETCurlCore *)net->context;
|
||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->thread_request_list, request));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->thread_request_list, request));
|
||||||
|
|
||||||
DN_DoublyLLDetach(curl->thread_request_list, request);
|
DN_DoublyLLDetach(curl->thread_request_list, request);
|
||||||
|
DN_Assert(curl->thread_request_count);
|
||||||
|
curl->thread_request_count--;
|
||||||
|
|
||||||
DN_DoublyLLAppend(curl->response_list, request);
|
DN_DoublyLLAppend(curl->response_list, request);
|
||||||
|
curl->response_count++;
|
||||||
}
|
}
|
||||||
DN_OS_SemaphoreIncrement(&net->completion_sem, 1);
|
DN_OS_SemaphoreIncrement(&net->completion_sem, 1);
|
||||||
DN_OS_SemaphoreIncrement(&request->completion_sem, 1);
|
DN_OS_SemaphoreIncrement(&request->completion_sem, 1);
|
||||||
@@ -16324,8 +16423,11 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
||||||
DN_DoublyLLDetach(curl->request_list, req);
|
DN_DoublyLLDetach(curl->request_list, req);
|
||||||
|
DN_Assert(curl->request_count);
|
||||||
|
curl->request_count--;
|
||||||
}
|
}
|
||||||
DN_DoublyLLAppend(curl->thread_request_list, req);
|
DN_DoublyLLAppend(curl->thread_request_list, req);
|
||||||
|
curl->thread_request_count++;
|
||||||
|
|
||||||
// NOTE: Add the connection to CURLM and start ticking it once we finish handling all the
|
// NOTE: Add the connection to CURLM and start ticking it once we finish handling all the
|
||||||
// ring events
|
// ring events
|
||||||
@@ -16371,15 +16473,18 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
// NOTE: End the temp memory storing the WS data we just read and the user returned to us
|
// NOTE: End the temp memory storing the WS data we just read and the user returned to us
|
||||||
// (we got their receipt back). Then restart the temp memory scope for the next websocket
|
// (we got their receipt back). Then restart the temp memory scope for the next websocket
|
||||||
// payload
|
// payload
|
||||||
DN_NET_EndFinishedRequest(req);
|
DN_ArenaTempEnd(&req->start_response_arena, DN_ArenaReset_Yes);
|
||||||
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
||||||
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
||||||
|
|
||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
||||||
DN_DoublyLLDetach(curl->request_list, req);
|
DN_DoublyLLDetach(curl->request_list, req);
|
||||||
|
DN_Assert(curl->request_count);
|
||||||
|
curl->request_count--;
|
||||||
}
|
}
|
||||||
DN_DoublyLLAppend(curl->thread_request_list, req);
|
DN_DoublyLLAppend(curl->thread_request_list, req);
|
||||||
|
curl->thread_request_count++;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DN_NETCurlRingEventType_DeinitRequest: {
|
case DN_NETCurlRingEventType_DeinitRequest: {
|
||||||
@@ -16394,10 +16499,11 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->deinit_list, request));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->deinit_list, request));
|
||||||
DN_DoublyLLDetach(curl->deinit_list, request);
|
DN_DoublyLLDetach(curl->deinit_list, request);
|
||||||
|
DN_Assert(curl->deinit_count);
|
||||||
|
curl->deinit_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Now we can modify the request, release resources
|
// NOTE: Now we can modify the request, release resources
|
||||||
DN_NET_EndFinishedRequest(request);
|
|
||||||
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
||||||
|
|
||||||
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
||||||
@@ -16409,15 +16515,13 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
curl_req->handle = copy;
|
curl_req->handle = copy;
|
||||||
|
|
||||||
// NOTE: Zero the struct preserving just the data we need to retain
|
// NOTE: Zero the struct preserving just the data we need to retain
|
||||||
DN_NETRequest resetter = {};
|
DN_NET_RequestRecycle(request);
|
||||||
resetter.arena = request->arena;
|
|
||||||
resetter.gen = request->gen + 1;
|
|
||||||
DN_Memcpy(resetter.context, request->context, sizeof(resetter.context));
|
|
||||||
*request = resetter;
|
|
||||||
|
|
||||||
// NOTE: Add it to the free list
|
// NOTE: Add it to the free list
|
||||||
for (DN_OS_MutexScope(&curl->list_mutex))
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_DoublyLLAppend(curl->free_list, request);
|
DN_DoublyLLAppend(curl->free_list, request);
|
||||||
|
curl->free_count++;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16661,10 +16765,20 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
|||||||
for (DN_OS_MutexScope(&curl_core->list_mutex)) {
|
for (DN_OS_MutexScope(&curl_core->list_mutex)) {
|
||||||
req = curl_core->free_list;
|
req = curl_core->free_list;
|
||||||
DN_DoublyLLDetach(curl_core->free_list, req);
|
DN_DoublyLLDetach(curl_core->free_list, req);
|
||||||
|
if (req) {
|
||||||
|
DN_Assert(curl_core->free_count);
|
||||||
|
curl_core->free_count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE None in the free list so allocate one
|
if (req) {
|
||||||
if (!req) {
|
DN_AssertF(req->mem.curr->used == DN_ARENA_HEADER_SIZE,
|
||||||
|
"A reused request from the free-list should have its memory reset essentially to "
|
||||||
|
"zero. If this isn't the case then we're leaking memory and have forgotten to "
|
||||||
|
"reset the arena before putting the request back into the free list. Request has "
|
||||||
|
"used %s.", DN_Str8x32FromByteCountU64Auto(req->mem.curr->used).data);
|
||||||
|
} else{
|
||||||
|
// NOTE: None in the free list so allocate one
|
||||||
DN_OS_MutexLock(&curl_core->list_mutex);
|
DN_OS_MutexLock(&curl_core->list_mutex);
|
||||||
DN_U64 arena_pos = DN_MemListPos(net->arena.mem);
|
DN_U64 arena_pos = DN_MemListPos(net->arena.mem);
|
||||||
req = DN_ArenaNewZ(&net->arena, DN_NETRequest);
|
req = DN_ArenaNewZ(&net->arena, DN_NETRequest);
|
||||||
@@ -16761,8 +16875,10 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
|||||||
// NOTE: Immediately add the request to the request list so it happens "atomically" in the
|
// NOTE: Immediately add the request to the request list so it happens "atomically" in the
|
||||||
// calling thread. If the calling thread deinitialises this layer before the CURL thread can be
|
// calling thread. If the calling thread deinitialises this layer before the CURL thread can be
|
||||||
// pre-empted, we can lose track of this request.
|
// pre-empted, we can lose track of this request.
|
||||||
for (DN_OS_MutexScope(&curl_core->list_mutex))
|
for (DN_OS_MutexScope(&curl_core->list_mutex)) {
|
||||||
DN_DoublyLLAppend(curl_core->request_list, req);
|
DN_DoublyLLAppend(curl_core->request_list, req);
|
||||||
|
curl_core->request_count++;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Enqueue request to go into CURL's ring queue. The CURL thread will sleep and wait for
|
// NOTE: Enqueue request to go into CURL's ring queue. The CURL thread will sleep and wait for
|
||||||
// bytes to come in for the request and then dump the response into the done list to be consumed
|
// bytes to come in for the request and then dump the response into the done list to be consumed
|
||||||
@@ -16846,15 +16962,20 @@ static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN
|
|||||||
DN_AssertF(DN_NET_CurlRequestIsInList(curl->response_list, req),
|
DN_AssertF(DN_NET_CurlRequestIsInList(curl->response_list, req),
|
||||||
"A completed response should only signal the completion semaphore when it's in the response list");
|
"A completed response should only signal the completion semaphore when it's in the response list");
|
||||||
DN_DoublyLLDetach(curl->response_list, req);
|
DN_DoublyLLDetach(curl->response_list, req);
|
||||||
|
DN_Assert(curl->response_count);
|
||||||
|
curl->response_count--;
|
||||||
|
|
||||||
// NOTE: A websocket that is continuing to get data should go back into the request list because
|
// NOTE: A websocket that is continuing to get data should go back into the request list because
|
||||||
// there's more data to be received. All other requests need to go into the deinit list (so that
|
// there's more data to be received. All other requests need to go into the deinit list (so that
|
||||||
// we keep track of it in the time inbetween it takes for the CURL thread to be scheduled and
|
// we keep track of it in the time inbetween it takes for the CURL thread to be scheduled and
|
||||||
// release the CURL handle from CURLM and release resources e.t.c.)
|
// release the CURL handle from CURLM and release resources e.t.c.)
|
||||||
if (continue_ws_request)
|
if (continue_ws_request) {
|
||||||
DN_DoublyLLAppend(curl->request_list, req);
|
DN_DoublyLLAppend(curl->request_list, req);
|
||||||
else
|
curl->request_count++;
|
||||||
|
} else {
|
||||||
DN_DoublyLLAppend(curl->deinit_list, req);
|
DN_DoublyLLAppend(curl->deinit_list, req);
|
||||||
|
curl->deinit_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Submit the post-request event to the CURL thread
|
// NOTE: Submit the post-request event to the CURL thread
|
||||||
@@ -16975,7 +17096,7 @@ static DN_NETEmcWSEvent *DN_NET_EmcAllocWSEvent_(DN_NETRequest *request)
|
|||||||
{
|
{
|
||||||
// NOTE: Allocate the event and attach to the request
|
// NOTE: Allocate the event and attach to the request
|
||||||
DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1];
|
DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1];
|
||||||
DN_NETEmcWSEvent *result = DN_ArenaNew(&request->arena, DN_NETEmcWSEvent, DN_ZMem_Yes);
|
DN_NETEmcWSEvent *result = DN_ArenaNew(&request->start_response_arena, DN_NETEmcWSEvent, DN_ZMem_Yes);
|
||||||
DN_Assert(result);
|
DN_Assert(result);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (!emc_request->first_event)
|
if (!emc_request->first_event)
|
||||||
@@ -17023,7 +17144,7 @@ static bool DN_NET_EmcWSOnMessage(int eventType, const EmscriptenWebSocketMessag
|
|||||||
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
||||||
net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary;
|
net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary;
|
||||||
if (event->numBytes > 0)
|
if (event->numBytes > 0)
|
||||||
net_event->payload = DN_Str8FromPtrArena(event->data, event->numBytes, &req->arena);
|
net_event->payload = DN_Str8FromPtrArena(event->data, event->numBytes, &req->start_response_arena);
|
||||||
DN_NET_EmcOnRequestDone_(net, req);
|
DN_NET_EmcOnRequestDone_(net, req);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -17044,7 +17165,12 @@ static bool DN_NET_EmcWSOnClose(int eventType, EmscriptenWebSocketCloseEvent con
|
|||||||
DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0];
|
DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0];
|
||||||
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
||||||
net_event->state = DN_NETResponseState_WSClose;
|
net_event->state = DN_NETResponseState_WSClose;
|
||||||
net_event->payload = DN_Str8FromFmtArena(&req->arena, "Websocket closed '%.*s': (%u) %s (was %s close)", DN_Str8PrintFmt(req->url), event->code, event->reason, event->wasClean ? "clean" : "unclean");
|
net_event->payload = DN_Str8FromFmtArena(&req->start_response_arena,
|
||||||
|
"Websocket closed '%.*s': (%u) %s (was %s close)",
|
||||||
|
DN_Str8PrintFmt(req->url),
|
||||||
|
event->code,
|
||||||
|
event->reason,
|
||||||
|
event->wasClean ? "clean" : "unclean");
|
||||||
DN_NET_EmcOnRequestDone_(net, req);
|
DN_NET_EmcOnRequestDone_(net, req);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -17093,25 +17219,19 @@ static DN_NETRequest *DN_NET_EmcAllocRequest_(DN_NETCore *net)
|
|||||||
DN_NETRequest *result = emc->free_list;
|
DN_NETRequest *result = emc->free_list;
|
||||||
if (result) {
|
if (result) {
|
||||||
emc->free_list = emc->free_list->next;
|
emc->free_list = emc->free_list->next;
|
||||||
result->next = nullptr;
|
result->next = nullptr;
|
||||||
DN_Assert(result->prev == nullptr);
|
DN_Assert(result->prev == nullptr);
|
||||||
if (emc->free_list) {
|
if (emc->free_list) {
|
||||||
DN_Assert(emc->free_list->prev == nullptr);
|
DN_Assert(emc->free_list->prev == nullptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// NOTE: Setup the request's arena here. WASM doesn't have the concept of virtual memory
|
result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes);
|
||||||
// so we use malloc to initialise it.
|
result->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&net->arena, DN_NETEmcRequest, DN_ZMem_Yes);
|
||||||
result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes);
|
|
||||||
if (result) {
|
|
||||||
result->arena = DN_ArenaFromMemList(&result->mem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Setup some emscripten specific data into our request context
|
// NOTE: Setup some emscripten specific data into our request context
|
||||||
if (result) {
|
if (result)
|
||||||
result->context[0] = DN_Cast(DN_UPtr) net;
|
result->context[0] = DN_Cast(DN_UPtr) net;
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17184,9 +17304,6 @@ DN_NETRequestHandle DN_NET_EmcDoWS(DN_NETCore *net, DN_Str8 url)
|
|||||||
if (!req)
|
if (!req)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// NOTE: Setup some emscripten specific data into our request context
|
|
||||||
req->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&req->start_response_arena, DN_NETEmcRequest, DN_ZMem_Yes);
|
|
||||||
|
|
||||||
// NOTE: Create the websocket request and dispatch it via emscripten
|
// NOTE: Create the websocket request and dispatch it via emscripten
|
||||||
EmscriptenWebSocketCreateAttributes attr;
|
EmscriptenWebSocketCreateAttributes attr;
|
||||||
emscripten_websocket_init_create_attributes(&attr);
|
emscripten_websocket_init_create_attributes(&attr);
|
||||||
@@ -17218,7 +17335,7 @@ void DN_NET_EmcDoWSSend(DN_NETRequestHandle handle, DN_Str8 data, DN_NETWSSend s
|
|||||||
DN_U64 pos = DN_MemListPos(request_ptr->start_response_arena.mem);
|
DN_U64 pos = DN_MemListPos(request_ptr->start_response_arena.mem);
|
||||||
DN_Str8 data_null_terminated = DN_Str8FromStr8Arena(data, &request_ptr->start_response_arena);
|
DN_Str8 data_null_terminated = DN_Str8FromStr8Arena(data, &request_ptr->start_response_arena);
|
||||||
result = emscripten_websocket_send_utf8_text(emc_request->socket, data_null_terminated.data);
|
result = emscripten_websocket_send_utf8_text(emc_request->socket, data_null_terminated.data);
|
||||||
DN_MemListPopTo(request_ptr->arena.mem, pos);
|
DN_MemListPopTo(request_ptr->start_response_arena.mem, pos);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DN_NETWSSend_Binary: {
|
case DN_NETWSSend_Binary: {
|
||||||
@@ -17297,19 +17414,21 @@ static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEm
|
|||||||
// NOTE: Deallocate the memory used in the request and reset the string builder (as all
|
// NOTE: Deallocate the memory used in the request and reset the string builder (as all
|
||||||
// payload(s) have been read from the request).
|
// payload(s) have been read from the request).
|
||||||
if (!end_request)
|
if (!end_request)
|
||||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end_request) {
|
if (end_request) {
|
||||||
DN_NET_EndFinishedRequest(request);
|
|
||||||
emscripten_websocket_delete(emc_request->socket);
|
emscripten_websocket_delete(emc_request->socket);
|
||||||
emc_request->socket = 0;
|
emc_request->socket = 0;
|
||||||
|
|
||||||
DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context;
|
DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context;
|
||||||
request->next = emc->free_list;
|
request->next = emc->free_list;
|
||||||
request->prev = nullptr;
|
request->prev = nullptr;
|
||||||
request->gen++;
|
|
||||||
emc->free_list = request;
|
emc->free_list = request;
|
||||||
|
|
||||||
|
DN_Assert(emc_request->first_event == nullptr);
|
||||||
|
DN_Assert(emc_request->last_event == nullptr);
|
||||||
|
DN_NET_RequestRecycle(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Generated by the DN single header generator 2026-07-08 14:23:34
|
// Generated by the DN single header generator 2026-07-12 16:23:32
|
||||||
|
|
||||||
#if !defined(DN_H)
|
#if !defined(DN_H)
|
||||||
#define DN_H
|
#define DN_H
|
||||||
@@ -1029,6 +1029,13 @@ struct DN_U64FromResult
|
|||||||
DN_U64 value;
|
DN_U64 value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct DN_U32FromResult DN_U32FromResult;
|
||||||
|
struct DN_U32FromResult
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
DN_U32 value;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct DN_USizeFromResult DN_USizeFromResult;
|
typedef struct DN_USizeFromResult DN_USizeFromResult;
|
||||||
struct DN_USizeFromResult
|
struct DN_USizeFromResult
|
||||||
{
|
{
|
||||||
@@ -4916,9 +4923,15 @@ DN_API DN_U64 DN_U64FromU8x32HiBEUnsafe
|
|||||||
DN_API DN_U64FromResult DN_U64FromU8x32HiBE (DN_U8x32 const *val); // Checks [0:24) bytes aren't set before getting the U64
|
DN_API DN_U64FromResult DN_U64FromU8x32HiBE (DN_U8x32 const *val); // Checks [0:24) bytes aren't set before getting the U64
|
||||||
DN_API DN_USize DN_USizeFromU8x32HiBEUnsafe (DN_U8x32 const *val); // Get USize stored in big-endian at the high bytes [32 - sizeof USize:32)
|
DN_API DN_USize DN_USizeFromU8x32HiBEUnsafe (DN_U8x32 const *val); // Get USize stored in big-endian at the high bytes [32 - sizeof USize:32)
|
||||||
DN_API DN_USizeFromResult DN_USizeFromU8x32HiBE (DN_U8x32 const *val); // Checks [0:sizeof USize) bytes aren't set before getting the U64
|
DN_API DN_USizeFromResult DN_USizeFromU8x32HiBE (DN_U8x32 const *val); // Checks [0:sizeof USize) bytes aren't set before getting the U64
|
||||||
DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string, char separator);
|
DN_API DN_U32FromResult DN_U32FromHexStr8 (DN_Str8 hex);
|
||||||
DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size, char separator);
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiters (DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count);
|
||||||
DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size, char separator);
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiter (DN_Str8 string, DN_Str8 delimiter);
|
||||||
|
DN_API DN_U32FromResult DN_U32FromPtr (void const *data, DN_USize size);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiters (DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiter (DN_Str8 string, DN_Str8 delimiter);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size);
|
||||||
|
DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size);
|
||||||
|
|
||||||
DN_API bool DN_U8x32Eq (DN_U8x32 const *lhs, DN_U8x32 const *rhs);
|
DN_API bool DN_U8x32Eq (DN_U8x32 const *lhs, DN_U8x32 const *rhs);
|
||||||
DN_API DN_U8x32 DN_U8x32FromBytesLeftPadZ (DN_U8 const *ptr, DN_USize size);
|
DN_API DN_U8x32 DN_U8x32FromBytesLeftPadZ (DN_U8 const *ptr, DN_USize size);
|
||||||
@@ -5136,6 +5149,7 @@ DN_API DN_Str8 DN_Str8HexFromPtrBytesArena
|
|||||||
DN_API DN_Str8 DN_Str8HexFromStr8BytesArena (DN_Str8 bytes, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Str8 DN_Str8HexFromStr8BytesArena (DN_Str8 bytes, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z);
|
||||||
DN_API DN_Hex32 DN_Hex32FromPtrBytes16 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Hex32 DN_Hex32FromPtrBytes16 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
||||||
DN_API DN_Hex64 DN_Hex64FromPtrBytes32 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Hex64 DN_Hex64FromPtrBytes32 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
||||||
|
DN_API DN_Hex64 DN_Hex64FromU8x32 (DN_U8x32 const *value, DN_TrimLeadingZero trim_leading_z);
|
||||||
DN_API DN_Hex128 DN_Hex128FromPtrBytes64 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Hex128 DN_Hex128FromPtrBytes64 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
||||||
|
|
||||||
DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
||||||
@@ -5978,26 +5992,14 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2
|
|||||||
#define DN_LArrayMakeAssert(c_array, ptr_size, z_mem) DN_PArrayMakeAssert(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem)
|
#define DN_LArrayMakeAssert(c_array, ptr_size, z_mem) DN_PArrayMakeAssert(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem)
|
||||||
#define DN_LArrayMakeAssertZ(c_array, ptr_size) DN_PArrayMakeAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
#define DN_LArrayMakeAssertZ(c_array, ptr_size) DN_PArrayMakeAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
||||||
#define DN_LArrayMakeAssertNoZ(c_array, ptr_size) DN_PArrayMakeAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
#define DN_LArrayMakeAssertNoZ(c_array, ptr_size) DN_PArrayMakeAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
||||||
#define DN_LArrayMakeArena(c_array, ptr_size, arena, z_mem) DN_PArrayMakeArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, z_mem)
|
|
||||||
#define DN_LArrayMakeArenaZ(c_array, ptr_size, arena) DN_PArrayMakeArenaZ(c_array, ptr_size, DN_ArrayCountU(c_array), arena)
|
|
||||||
#define DN_LArrayMakeArenaNoZ(c_array, ptr_size, arena) DN_PArrayMakeArenaNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), arena)
|
|
||||||
#define DN_LArrayMakePool(c_array, ptr_size, pool, z_mem) DN_PArrayMakePool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, z_mem)
|
|
||||||
#define DN_LArrayMakePoolZ(c_array, ptr_size, pool) DN_PArrayMakePoolZ(c_array, ptr_size, DN_ArrayCountU(c_array), pool)
|
|
||||||
#define DN_LArrayMakePoolNoZ(c_array, ptr_size, pool) DN_PArrayMakePoolNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), pool)
|
|
||||||
|
|
||||||
#define DN_LArrayAddArray(c_array, ptr_size, items, count, add) DN_PArrayAddArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count, add)
|
#define DN_LArrayAddArray(c_array, ptr_size, items, count, add) DN_PArrayAddArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count, add)
|
||||||
#define DN_LArrayAdd(c_array, ptr_size, item, add) DN_PArrayAdd(c_array, ptr_size, DN_ArrayCountU(c_array), item, add)
|
#define DN_LArrayAdd(c_array, ptr_size, item, add) DN_PArrayAdd(c_array, ptr_size, DN_ArrayCountU(c_array), item, add)
|
||||||
#define DN_LArrayAddArena(c_array, ptr_size, arena, item, add) DN_PArrayAddArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, item, add)
|
|
||||||
#define DN_LArrayAddPool(c_array, ptr_size, pool, item, add) DN_PArrayAddPool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, item, add)
|
|
||||||
#define DN_LArrayAppendArray(c_array, ptr_size, items, count) DN_PArrayAppendArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
#define DN_LArrayAppendArray(c_array, ptr_size, items, count) DN_PArrayAppendArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
||||||
#define DN_LArrayAppend(c_array, ptr_size, item) DN_PArrayAppend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
#define DN_LArrayAppend(c_array, ptr_size, item) DN_PArrayAppend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
||||||
#define DN_LArrayAppendArena(c_array, ptr_size, arena, item) DN_PArrayAppendArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, item)
|
|
||||||
#define DN_LArrayAppendPool(c_array, ptr_size, pool, item) DN_PArrayAppendPool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, item)
|
|
||||||
#define DN_LArrayAppendAssert(c_array, ptr_size, item) DN_PArrayAppendAssert(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
#define DN_LArrayAppendAssert(c_array, ptr_size, item) DN_PArrayAppendAssert(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
||||||
#define DN_LArrayPrependArray(c_array, ptr_size, items, count) DN_PArrayPrependArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
#define DN_LArrayPrependArray(c_array, ptr_size, items, count) DN_PArrayPrependArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
||||||
#define DN_LArrayPrepend(c_array, ptr_size, item) DN_PArrayPrepend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
#define DN_LArrayPrepend(c_array, ptr_size, item) DN_PArrayPrepend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
||||||
#define DN_LArrayPrependArena(c_array, ptr_size, arena, item) DN_PArrayPrependArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, item)
|
|
||||||
#define DN_LArrayPrependPool(c_array, ptr_size, pool, item) DN_PArrayPrependPool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, item)
|
|
||||||
#define DN_LArrayEraseRange(c_array, ptr_size, begin_index, count, erase) DN_PArrayEraseRange(c_array, ptr_size, begin_index, count, erase)
|
#define DN_LArrayEraseRange(c_array, ptr_size, begin_index, count, erase) DN_PArrayEraseRange(c_array, ptr_size, begin_index, count, erase)
|
||||||
#define DN_LArrayErase(c_array, ptr_size, index, erase) DN_PArrayErase(c_array, ptr_size, index, erase)
|
#define DN_LArrayErase(c_array, ptr_size, index, erase) DN_PArrayErase(c_array, ptr_size, index, erase)
|
||||||
#define DN_LArrayInsertArray(c_array, ptr_size, index, items, count) DN_PArrayInsertArray(c_array, ptr_size, DN_ArrayCountU(c_array), index, items, count)
|
#define DN_LArrayInsertArray(c_array, ptr_size, index, items, count) DN_PArrayInsertArray(c_array, ptr_size, DN_ArrayCountU(c_array), index, items, count)
|
||||||
@@ -7211,7 +7213,6 @@ DN_Str8 DN_NET_Str8DiagnosticFromResponse(DN_NETResponse const* resp
|
|||||||
// NOTE: Internal functions for different networking implementations to use
|
// NOTE: Internal functions for different networking implementations to use
|
||||||
void DN_NET_BaseInit (DN_NETCore *net, char *base, DN_U64 base_size);
|
void DN_NET_BaseInit (DN_NETCore *net, char *base, DN_U64 base_size);
|
||||||
DN_NETRequestHandle DN_NET_SetupRequest (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type);
|
DN_NETRequestHandle DN_NET_SetupRequest (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type);
|
||||||
void DN_NET_EndFinishedRequest (DN_NETRequest *request);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DN_WITH_NET_CURL
|
#if DN_WITH_NET_CURL
|
||||||
@@ -7240,6 +7241,11 @@ struct DN_NETCurlCore
|
|||||||
DN_NETRequest *response_list; // Finished requests that are to be deqeued by the user via wait for response
|
DN_NETRequest *response_list; // Finished requests that are to be deqeued by the user via wait for response
|
||||||
DN_NETRequest *deinit_list; // Requests that are finished and are awaiting to be de-initialised by the CURL thread
|
DN_NETRequest *deinit_list; // Requests that are finished and are awaiting to be de-initialised by the CURL thread
|
||||||
DN_NETRequest *free_list; // Request pool that new requests will use before allocating
|
DN_NETRequest *free_list; // Request pool that new requests will use before allocating
|
||||||
|
DN_USize request_count;
|
||||||
|
DN_USize response_count;
|
||||||
|
DN_USize deinit_count;
|
||||||
|
DN_USize free_count;
|
||||||
|
DN_USize thread_request_count;
|
||||||
|
|
||||||
// NOTE: Networking thread only
|
// NOTE: Networking thread only
|
||||||
DN_NETRequest *thread_request_list; // Current requests being executed by the CURL thread.
|
DN_NETRequest *thread_request_list; // Current requests being executed by the CURL thread.
|
||||||
|
|||||||
+181
-62
@@ -348,6 +348,18 @@ DN_API DN_U32 DN_AlignUpPowerOfTwoU32(DN_U32 val)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN_API void DN_ByteSwapU64Ptr(DN_U8 *dest, DN_U64 src)
|
||||||
|
{
|
||||||
|
dest[0] = DN_Cast(DN_U8)((src >> 56) & 0xFF);
|
||||||
|
dest[1] = DN_Cast(DN_U8)((src >> 48) & 0xFF);
|
||||||
|
dest[2] = DN_Cast(DN_U8)((src >> 40) & 0xFF);
|
||||||
|
dest[3] = DN_Cast(DN_U8)((src >> 32) & 0xFF);
|
||||||
|
dest[4] = DN_Cast(DN_U8)((src >> 24) & 0xFF);
|
||||||
|
dest[5] = DN_Cast(DN_U8)((src >> 16) & 0xFF);
|
||||||
|
dest[6] = DN_Cast(DN_U8)((src >> 8) & 0xFF);
|
||||||
|
dest[7] = DN_Cast(DN_U8)(src & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
DN_API DN_CPUIDResult DN_CPUID(DN_CPUIDArgs args)
|
DN_API DN_CPUIDResult DN_CPUID(DN_CPUIDArgs args)
|
||||||
{
|
{
|
||||||
DN_CPUIDResult result = {};
|
DN_CPUIDResult result = {};
|
||||||
@@ -2589,19 +2601,48 @@ DN_API DN_USizeFromResult DN_USizeFromU8x32HiBE(DN_U8x32 const *val)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void DN_ByteSwapU64Ptr(DN_U8 *dest, DN_U64 src)
|
static DN_U32FromResult DN_U32FromU64FromResult_(DN_U64FromResult u64)
|
||||||
{
|
{
|
||||||
dest[0] = DN_Cast(DN_U8)((src >> 56) & 0xFF);
|
DN_U32FromResult result = {};
|
||||||
dest[1] = DN_Cast(DN_U8)((src >> 48) & 0xFF);
|
result.value = DN_Cast(DN_U32)DN_Min(u64.value, UINT32_MAX);
|
||||||
dest[2] = DN_Cast(DN_U8)((src >> 40) & 0xFF);
|
result.success = u64.value <= UINT32_MAX;
|
||||||
dest[3] = DN_Cast(DN_U8)((src >> 32) & 0xFF);
|
return result;
|
||||||
dest[4] = DN_Cast(DN_U8)((src >> 24) & 0xFF);
|
|
||||||
dest[5] = DN_Cast(DN_U8)((src >> 16) & 0xFF);
|
|
||||||
dest[6] = DN_Cast(DN_U8)((src >> 8) & 0xFF);
|
|
||||||
dest[7] = DN_Cast(DN_U8)(src & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
DN_API DN_U32FromResult DN_U32FromHexStr8(DN_Str8 hex)
|
||||||
|
{
|
||||||
|
DN_U64FromResult u64 = DN_U64FromHexPtr(hex.data, hex.count);
|
||||||
|
DN_U32FromResult result = DN_U32FromU64FromResult_(u64);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiters(DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count)
|
||||||
|
{
|
||||||
|
DN_U64FromResult u64 = DN_U64FromStr8Delimiters(string, delimiters, delimiters_count);
|
||||||
|
DN_U32FromResult result = DN_U32FromU64FromResult_(u64);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiter(DN_Str8 string, DN_Str8 delimiter)
|
||||||
|
{
|
||||||
|
DN_U32FromResult result = DN_U32FromStr8Delimiters(string, &delimiter, 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromStr8(DN_Str8 string)
|
||||||
|
{
|
||||||
|
DN_U64FromResult u64 = DN_U64FromStr8(string);
|
||||||
|
DN_U32FromResult result = DN_U32FromU64FromResult_(u64);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_U32FromResult DN_U32FromPtr(void const *data, DN_USize size)
|
||||||
|
{
|
||||||
|
DN_U32FromResult result = DN_U32FromStr8(DN_Str8FromPtr(data, size));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiters(DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count)
|
||||||
{
|
{
|
||||||
// NOTE: Argument check
|
// NOTE: Argument check
|
||||||
DN_I64FromResult result = {};
|
DN_I64FromResult result = {};
|
||||||
@@ -2617,6 +2658,7 @@ DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Handle negation
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
DN_USize start_index = 0;
|
DN_USize start_index = 0;
|
||||||
if (!DN_CharIsDigit(trim_string.data[0])) {
|
if (!DN_CharIsDigit(trim_string.data[0])) {
|
||||||
@@ -2628,12 +2670,25 @@ DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
|||||||
|
|
||||||
// NOTE: Convert the string number to the binary number
|
// NOTE: Convert the string number to the binary number
|
||||||
for (DN_USize index = start_index; index < trim_string.count; index++) {
|
for (DN_USize index = start_index; index < trim_string.count; index++) {
|
||||||
char ch = trim_string.data[index];
|
|
||||||
|
// NOTE: Check for presence of the delimiter, we skip the first character as a U64 string
|
||||||
|
// prefixed with a delimiter is not considered valid.
|
||||||
if (index) {
|
if (index) {
|
||||||
if (separator != 0 && ch == separator)
|
DN_USize max_delimiter_match = 0;
|
||||||
|
for (DN_ForItSize(it, DN_Str8 const, delimiters, delimiters_count)) {
|
||||||
|
DN_Str8 delimiter = *it.data;
|
||||||
|
DN_Str8 check_slice = DN_Str8Subset(trim_string, index, delimiter.count);
|
||||||
|
if (DN_Str8EqSensitive(check_slice, delimiter))
|
||||||
|
max_delimiter_match = DN_Max(max_delimiter_match, delimiter.count); // Take length, there might be multiple so we keep going
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_delimiter_match) {
|
||||||
|
index += max_delimiter_match - 1;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char ch = trim_string.data[index];
|
||||||
if (!DN_CharIsDigit(ch))
|
if (!DN_CharIsDigit(ch))
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -2649,16 +2704,28 @@ DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_I64FromResult DN_I64FromPtr(void const *data, DN_USize size, char separator)
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiter(DN_Str8 string, DN_Str8 delimiter)
|
||||||
{
|
{
|
||||||
DN_Str8 str8 = DN_Str8FromPtr((char *)data, size);
|
DN_I64FromResult result = DN_I64FromStr8Delimiters(string, &delimiter, 1);
|
||||||
DN_I64FromResult result = DN_I64FromStr8(str8, separator);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_I64 DN_I64FromPtrUnsafe(void const *data, DN_USize size, char separator)
|
DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string)
|
||||||
{
|
{
|
||||||
DN_I64FromResult from = DN_I64FromPtr(data, size, separator);
|
DN_I64FromResult result = DN_I64FromStr8Delimiters(string, nullptr, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_I64FromResult DN_I64FromPtr(void const *data, DN_USize size)
|
||||||
|
{
|
||||||
|
DN_Str8 str8 = DN_Str8FromPtr((char *)data, size);
|
||||||
|
DN_I64FromResult result = DN_I64FromStr8Delimiters(str8, nullptr, 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_I64 DN_I64FromPtrUnsafe(void const *data, DN_USize size)
|
||||||
|
{
|
||||||
|
DN_I64FromResult from = DN_I64FromPtr(data, size);
|
||||||
DN_I64 result = from.value;
|
DN_I64 result = from.value;
|
||||||
DN_Assert(from.success);
|
DN_Assert(from.success);
|
||||||
return result;
|
return result;
|
||||||
@@ -5166,6 +5233,12 @@ DN_API DN_Hex64 DN_Hex64FromPtrBytes32(void const *bytes, DN_USize bytes_count,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN_API DN_Hex64 DN_Hex64FromU8x32(DN_U8x32 const *value, DN_TrimLeadingZero trim_leading_z)
|
||||||
|
{
|
||||||
|
DN_Hex64 result = DN_Hex64FromPtrBytes32(value->data, DN_ArrayCountU(value->data), trim_leading_z);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
DN_API DN_Hex128 DN_Hex128FromPtrBytes64(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
DN_API DN_Hex128 DN_Hex128FromPtrBytes64(void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z)
|
||||||
{
|
{
|
||||||
DN_Hex128 result = {};
|
DN_Hex128 result = {};
|
||||||
@@ -9217,7 +9290,7 @@ DN_API void DN_CSVPackI64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_I64 *v
|
|||||||
{
|
{
|
||||||
if (serialise == DN_CSVSerialise_Read) {
|
if (serialise == DN_CSVSerialise_Read) {
|
||||||
DN_Str8 csv_value = DN_CSVTokeniserNextColumn(&pack->read_tokeniser);
|
DN_Str8 csv_value = DN_CSVTokeniserNextColumn(&pack->read_tokeniser);
|
||||||
DN_I64FromResult to_i64 = DN_I64FromStr8(csv_value, 0);
|
DN_I64FromResult to_i64 = DN_I64FromStr8(csv_value);
|
||||||
DN_Assert(to_i64.success);
|
DN_Assert(to_i64.success);
|
||||||
*value = to_i64.value;
|
*value = to_i64.value;
|
||||||
} else {
|
} else {
|
||||||
@@ -10905,49 +10978,49 @@ DN_API DN_TestCore DN_TestSuite(DN_Arena *arena_)
|
|||||||
|
|
||||||
// NOTE: DN_I64FromStr8
|
// NOTE: DN_I64FromStr8
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert empty string")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert empty string")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit(""), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit(""));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 0);
|
DN_TestVerifyExpr(&result, str_result.value == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1"));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 1);
|
DN_TestVerifyExpr(&result, str_result.value == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-0\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-0\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-0"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-0"));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 0);
|
DN_TestVerifyExpr(&result, str_result.value == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-1\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"-1\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-1"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-1"));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == -1);
|
DN_TestVerifyExpr(&result, str_result.value == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1.2\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1.2\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1.2"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1.2"));
|
||||||
DN_TestVerifyExpr(&result, !str_result.success);
|
DN_TestVerifyExpr(&result, !str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 1);
|
DN_TestVerifyExpr(&result, str_result.value == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,234\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,234\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,234"), ',');
|
DN_I64FromResult str_result = DN_I64FromStr8Delimiter(DN_Str8Lit("1,234"), DN_Str8Lit(","));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 1234);
|
DN_TestVerifyExpr(&result, str_result.value == 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,2\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"1,2\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,2"), ',');
|
DN_I64FromResult str_result = DN_I64FromStr8Delimiter(DN_Str8Lit("1,2"), DN_Str8Lit(","));
|
||||||
DN_TestVerifyExpr(&result, str_result.success);
|
DN_TestVerifyExpr(&result, str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 12);
|
DN_TestVerifyExpr(&result, str_result.value == 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"12a3\"")) {
|
for (DN_TestScopeF(&result, "[Strings] To I64: Convert \"12a3\"")) {
|
||||||
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("12a3"), 0);
|
DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("12a3"));
|
||||||
DN_TestVerifyExpr(&result, !str_result.success);
|
DN_TestVerifyExpr(&result, !str_result.success);
|
||||||
DN_TestVerifyExpr(&result, str_result.value == 12);
|
DN_TestVerifyExpr(&result, str_result.value == 12);
|
||||||
}
|
}
|
||||||
@@ -13035,8 +13108,14 @@ DN_NETRequestHandle DN_NET_SetupRequest(DN_NETRequest *request, DN_Str8 url, DN_
|
|||||||
// NOTE: Setup request
|
// NOTE: Setup request
|
||||||
DN_Assert(request);
|
DN_Assert(request);
|
||||||
if (request) {
|
if (request) {
|
||||||
if (!request->mem.curr)
|
if (request->mem.curr)
|
||||||
|
DN_AssertF(request->arena.mem == nullptr,
|
||||||
|
"DN_NET_RequestRecycle should be called on the request before putting it into the "
|
||||||
|
"free-list and reusing it. This is so that we centralise the one place that we "
|
||||||
|
"reinitialise the temp arena for the request into this codepath.");
|
||||||
|
else
|
||||||
request->mem = DN_MemListFromHeap(DN_Megabytes(1), DN_Kilobytes(1), DN_MemFlags_Nil, DN_OS_HeapInitVirtual());
|
request->mem = DN_MemListFromHeap(DN_Megabytes(1), DN_Kilobytes(1), DN_MemFlags_Nil, DN_OS_HeapInitVirtual());
|
||||||
|
|
||||||
request->arena = DN_ArenaTempBeginFromMemList(&request->mem);
|
request->arena = DN_ArenaTempBeginFromMemList(&request->mem);
|
||||||
request->type = type;
|
request->type = type;
|
||||||
request->gen = DN_Max(request->gen + 1, 1);
|
request->gen = DN_Max(request->gen + 1, 1);
|
||||||
@@ -13069,10 +13148,25 @@ DN_NETRequestHandle DN_NET_SetupRequest(DN_NETRequest *request, DN_Str8 url, DN_
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DN_NET_EndFinishedRequest(DN_NETRequest *request)
|
void DN_NET_RequestRecycle(DN_NETRequest *request)
|
||||||
{
|
{
|
||||||
// NOTE: Deallocate the memory used in the request and reset the string builder
|
DN_NETRequest resetter = {};
|
||||||
|
resetter.mem = request->mem;
|
||||||
|
resetter.arena = request->arena;
|
||||||
|
resetter.start_response_arena = request->start_response_arena;
|
||||||
|
resetter.gen = request->gen + 1;
|
||||||
|
DN_Memcpy(resetter.context, request->context, sizeof(resetter.context));
|
||||||
|
*request = resetter;
|
||||||
|
|
||||||
|
// NOTE: Deallocate the memory used in the request. Note we have to end the start response arena
|
||||||
|
// first to satisfy the UAF checker which requires that the temporary memory arenas are ended in
|
||||||
|
// the reverse order that they were created in.
|
||||||
|
//
|
||||||
|
// The arenas are created when `DN_NET_SetupRequest` is called to reuse the request.
|
||||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||||
|
DN_ArenaTempEnd(&request->arena, DN_ArenaReset_Yes);
|
||||||
|
request->arena = {};
|
||||||
|
request->start_response_arena = {};
|
||||||
}
|
}
|
||||||
#endif // #if DN_WITH_NET
|
#endif // #if DN_WITH_NET
|
||||||
|
|
||||||
@@ -13140,8 +13234,13 @@ static void DN_NET_CurlMarkRequestDone_(DN_NETCore *net, DN_NETRequest *request)
|
|||||||
DN_NETCurlCore *curl = DN_Cast(DN_NETCurlCore *)net->context;
|
DN_NETCurlCore *curl = DN_Cast(DN_NETCurlCore *)net->context;
|
||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->thread_request_list, request));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->thread_request_list, request));
|
||||||
|
|
||||||
DN_DoublyLLDetach(curl->thread_request_list, request);
|
DN_DoublyLLDetach(curl->thread_request_list, request);
|
||||||
|
DN_Assert(curl->thread_request_count);
|
||||||
|
curl->thread_request_count--;
|
||||||
|
|
||||||
DN_DoublyLLAppend(curl->response_list, request);
|
DN_DoublyLLAppend(curl->response_list, request);
|
||||||
|
curl->response_count++;
|
||||||
}
|
}
|
||||||
DN_OS_SemaphoreIncrement(&net->completion_sem, 1);
|
DN_OS_SemaphoreIncrement(&net->completion_sem, 1);
|
||||||
DN_OS_SemaphoreIncrement(&request->completion_sem, 1);
|
DN_OS_SemaphoreIncrement(&request->completion_sem, 1);
|
||||||
@@ -13188,8 +13287,11 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
||||||
DN_DoublyLLDetach(curl->request_list, req);
|
DN_DoublyLLDetach(curl->request_list, req);
|
||||||
|
DN_Assert(curl->request_count);
|
||||||
|
curl->request_count--;
|
||||||
}
|
}
|
||||||
DN_DoublyLLAppend(curl->thread_request_list, req);
|
DN_DoublyLLAppend(curl->thread_request_list, req);
|
||||||
|
curl->thread_request_count++;
|
||||||
|
|
||||||
// NOTE: Add the connection to CURLM and start ticking it once we finish handling all the
|
// NOTE: Add the connection to CURLM and start ticking it once we finish handling all the
|
||||||
// ring events
|
// ring events
|
||||||
@@ -13235,15 +13337,18 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
// NOTE: End the temp memory storing the WS data we just read and the user returned to us
|
// NOTE: End the temp memory storing the WS data we just read and the user returned to us
|
||||||
// (we got their receipt back). Then restart the temp memory scope for the next websocket
|
// (we got their receipt back). Then restart the temp memory scope for the next websocket
|
||||||
// payload
|
// payload
|
||||||
DN_NET_EndFinishedRequest(req);
|
DN_ArenaTempEnd(&req->start_response_arena, DN_ArenaReset_Yes);
|
||||||
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
||||||
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
||||||
|
|
||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
||||||
DN_DoublyLLDetach(curl->request_list, req);
|
DN_DoublyLLDetach(curl->request_list, req);
|
||||||
|
DN_Assert(curl->request_count);
|
||||||
|
curl->request_count--;
|
||||||
}
|
}
|
||||||
DN_DoublyLLAppend(curl->thread_request_list, req);
|
DN_DoublyLLAppend(curl->thread_request_list, req);
|
||||||
|
curl->thread_request_count++;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DN_NETCurlRingEventType_DeinitRequest: {
|
case DN_NETCurlRingEventType_DeinitRequest: {
|
||||||
@@ -13258,10 +13363,11 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->deinit_list, request));
|
DN_Assert(DN_NET_CurlRequestIsInList(curl->deinit_list, request));
|
||||||
DN_DoublyLLDetach(curl->deinit_list, request);
|
DN_DoublyLLDetach(curl->deinit_list, request);
|
||||||
|
DN_Assert(curl->deinit_count);
|
||||||
|
curl->deinit_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Now we can modify the request, release resources
|
// NOTE: Now we can modify the request, release resources
|
||||||
DN_NET_EndFinishedRequest(request);
|
|
||||||
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
||||||
|
|
||||||
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
||||||
@@ -13273,15 +13379,13 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
curl_req->handle = copy;
|
curl_req->handle = copy;
|
||||||
|
|
||||||
// NOTE: Zero the struct preserving just the data we need to retain
|
// NOTE: Zero the struct preserving just the data we need to retain
|
||||||
DN_NETRequest resetter = {};
|
DN_NET_RequestRecycle(request);
|
||||||
resetter.arena = request->arena;
|
|
||||||
resetter.gen = request->gen + 1;
|
|
||||||
DN_Memcpy(resetter.context, request->context, sizeof(resetter.context));
|
|
||||||
*request = resetter;
|
|
||||||
|
|
||||||
// NOTE: Add it to the free list
|
// NOTE: Add it to the free list
|
||||||
for (DN_OS_MutexScope(&curl->list_mutex))
|
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||||
DN_DoublyLLAppend(curl->free_list, request);
|
DN_DoublyLLAppend(curl->free_list, request);
|
||||||
|
curl->free_count++;
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13525,10 +13629,20 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
|||||||
for (DN_OS_MutexScope(&curl_core->list_mutex)) {
|
for (DN_OS_MutexScope(&curl_core->list_mutex)) {
|
||||||
req = curl_core->free_list;
|
req = curl_core->free_list;
|
||||||
DN_DoublyLLDetach(curl_core->free_list, req);
|
DN_DoublyLLDetach(curl_core->free_list, req);
|
||||||
|
if (req) {
|
||||||
|
DN_Assert(curl_core->free_count);
|
||||||
|
curl_core->free_count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE None in the free list so allocate one
|
if (req) {
|
||||||
if (!req) {
|
DN_AssertF(req->mem.curr->used == DN_ARENA_HEADER_SIZE,
|
||||||
|
"A reused request from the free-list should have its memory reset essentially to "
|
||||||
|
"zero. If this isn't the case then we're leaking memory and have forgotten to "
|
||||||
|
"reset the arena before putting the request back into the free list. Request has "
|
||||||
|
"used %s.", DN_Str8x32FromByteCountU64Auto(req->mem.curr->used).data);
|
||||||
|
} else{
|
||||||
|
// NOTE: None in the free list so allocate one
|
||||||
DN_OS_MutexLock(&curl_core->list_mutex);
|
DN_OS_MutexLock(&curl_core->list_mutex);
|
||||||
DN_U64 arena_pos = DN_MemListPos(net->arena.mem);
|
DN_U64 arena_pos = DN_MemListPos(net->arena.mem);
|
||||||
req = DN_ArenaNewZ(&net->arena, DN_NETRequest);
|
req = DN_ArenaNewZ(&net->arena, DN_NETRequest);
|
||||||
@@ -13625,8 +13739,10 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
|||||||
// NOTE: Immediately add the request to the request list so it happens "atomically" in the
|
// NOTE: Immediately add the request to the request list so it happens "atomically" in the
|
||||||
// calling thread. If the calling thread deinitialises this layer before the CURL thread can be
|
// calling thread. If the calling thread deinitialises this layer before the CURL thread can be
|
||||||
// pre-empted, we can lose track of this request.
|
// pre-empted, we can lose track of this request.
|
||||||
for (DN_OS_MutexScope(&curl_core->list_mutex))
|
for (DN_OS_MutexScope(&curl_core->list_mutex)) {
|
||||||
DN_DoublyLLAppend(curl_core->request_list, req);
|
DN_DoublyLLAppend(curl_core->request_list, req);
|
||||||
|
curl_core->request_count++;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Enqueue request to go into CURL's ring queue. The CURL thread will sleep and wait for
|
// NOTE: Enqueue request to go into CURL's ring queue. The CURL thread will sleep and wait for
|
||||||
// bytes to come in for the request and then dump the response into the done list to be consumed
|
// bytes to come in for the request and then dump the response into the done list to be consumed
|
||||||
@@ -13710,15 +13826,20 @@ static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN
|
|||||||
DN_AssertF(DN_NET_CurlRequestIsInList(curl->response_list, req),
|
DN_AssertF(DN_NET_CurlRequestIsInList(curl->response_list, req),
|
||||||
"A completed response should only signal the completion semaphore when it's in the response list");
|
"A completed response should only signal the completion semaphore when it's in the response list");
|
||||||
DN_DoublyLLDetach(curl->response_list, req);
|
DN_DoublyLLDetach(curl->response_list, req);
|
||||||
|
DN_Assert(curl->response_count);
|
||||||
|
curl->response_count--;
|
||||||
|
|
||||||
// NOTE: A websocket that is continuing to get data should go back into the request list because
|
// NOTE: A websocket that is continuing to get data should go back into the request list because
|
||||||
// there's more data to be received. All other requests need to go into the deinit list (so that
|
// there's more data to be received. All other requests need to go into the deinit list (so that
|
||||||
// we keep track of it in the time inbetween it takes for the CURL thread to be scheduled and
|
// we keep track of it in the time inbetween it takes for the CURL thread to be scheduled and
|
||||||
// release the CURL handle from CURLM and release resources e.t.c.)
|
// release the CURL handle from CURLM and release resources e.t.c.)
|
||||||
if (continue_ws_request)
|
if (continue_ws_request) {
|
||||||
DN_DoublyLLAppend(curl->request_list, req);
|
DN_DoublyLLAppend(curl->request_list, req);
|
||||||
else
|
curl->request_count++;
|
||||||
|
} else {
|
||||||
DN_DoublyLLAppend(curl->deinit_list, req);
|
DN_DoublyLLAppend(curl->deinit_list, req);
|
||||||
|
curl->deinit_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Submit the post-request event to the CURL thread
|
// NOTE: Submit the post-request event to the CURL thread
|
||||||
@@ -13839,7 +13960,7 @@ static DN_NETEmcWSEvent *DN_NET_EmcAllocWSEvent_(DN_NETRequest *request)
|
|||||||
{
|
{
|
||||||
// NOTE: Allocate the event and attach to the request
|
// NOTE: Allocate the event and attach to the request
|
||||||
DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1];
|
DN_NETEmcRequest *emc_request = DN_Cast(DN_NETEmcRequest *) request->context[1];
|
||||||
DN_NETEmcWSEvent *result = DN_ArenaNew(&request->arena, DN_NETEmcWSEvent, DN_ZMem_Yes);
|
DN_NETEmcWSEvent *result = DN_ArenaNew(&request->start_response_arena, DN_NETEmcWSEvent, DN_ZMem_Yes);
|
||||||
DN_Assert(result);
|
DN_Assert(result);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (!emc_request->first_event)
|
if (!emc_request->first_event)
|
||||||
@@ -13887,7 +14008,7 @@ static bool DN_NET_EmcWSOnMessage(int eventType, const EmscriptenWebSocketMessag
|
|||||||
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
||||||
net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary;
|
net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary;
|
||||||
if (event->numBytes > 0)
|
if (event->numBytes > 0)
|
||||||
net_event->payload = DN_Str8FromPtrArena(event->data, event->numBytes, &req->arena);
|
net_event->payload = DN_Str8FromPtrArena(event->data, event->numBytes, &req->start_response_arena);
|
||||||
DN_NET_EmcOnRequestDone_(net, req);
|
DN_NET_EmcOnRequestDone_(net, req);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -13908,7 +14029,12 @@ static bool DN_NET_EmcWSOnClose(int eventType, EmscriptenWebSocketCloseEvent con
|
|||||||
DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0];
|
DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0];
|
||||||
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
||||||
net_event->state = DN_NETResponseState_WSClose;
|
net_event->state = DN_NETResponseState_WSClose;
|
||||||
net_event->payload = DN_Str8FromFmtArena(&req->arena, "Websocket closed '%.*s': (%u) %s (was %s close)", DN_Str8PrintFmt(req->url), event->code, event->reason, event->wasClean ? "clean" : "unclean");
|
net_event->payload = DN_Str8FromFmtArena(&req->start_response_arena,
|
||||||
|
"Websocket closed '%.*s': (%u) %s (was %s close)",
|
||||||
|
DN_Str8PrintFmt(req->url),
|
||||||
|
event->code,
|
||||||
|
event->reason,
|
||||||
|
event->wasClean ? "clean" : "unclean");
|
||||||
DN_NET_EmcOnRequestDone_(net, req);
|
DN_NET_EmcOnRequestDone_(net, req);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -13957,25 +14083,19 @@ static DN_NETRequest *DN_NET_EmcAllocRequest_(DN_NETCore *net)
|
|||||||
DN_NETRequest *result = emc->free_list;
|
DN_NETRequest *result = emc->free_list;
|
||||||
if (result) {
|
if (result) {
|
||||||
emc->free_list = emc->free_list->next;
|
emc->free_list = emc->free_list->next;
|
||||||
result->next = nullptr;
|
result->next = nullptr;
|
||||||
DN_Assert(result->prev == nullptr);
|
DN_Assert(result->prev == nullptr);
|
||||||
if (emc->free_list) {
|
if (emc->free_list) {
|
||||||
DN_Assert(emc->free_list->prev == nullptr);
|
DN_Assert(emc->free_list->prev == nullptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// NOTE: Setup the request's arena here. WASM doesn't have the concept of virtual memory
|
result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes);
|
||||||
// so we use malloc to initialise it.
|
result->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&net->arena, DN_NETEmcRequest, DN_ZMem_Yes);
|
||||||
result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes);
|
|
||||||
if (result) {
|
|
||||||
result->arena = DN_ArenaFromMemList(&result->mem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Setup some emscripten specific data into our request context
|
// NOTE: Setup some emscripten specific data into our request context
|
||||||
if (result) {
|
if (result)
|
||||||
result->context[0] = DN_Cast(DN_UPtr) net;
|
result->context[0] = DN_Cast(DN_UPtr) net;
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14048,9 +14168,6 @@ DN_NETRequestHandle DN_NET_EmcDoWS(DN_NETCore *net, DN_Str8 url)
|
|||||||
if (!req)
|
if (!req)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// NOTE: Setup some emscripten specific data into our request context
|
|
||||||
req->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&req->start_response_arena, DN_NETEmcRequest, DN_ZMem_Yes);
|
|
||||||
|
|
||||||
// NOTE: Create the websocket request and dispatch it via emscripten
|
// NOTE: Create the websocket request and dispatch it via emscripten
|
||||||
EmscriptenWebSocketCreateAttributes attr;
|
EmscriptenWebSocketCreateAttributes attr;
|
||||||
emscripten_websocket_init_create_attributes(&attr);
|
emscripten_websocket_init_create_attributes(&attr);
|
||||||
@@ -14082,7 +14199,7 @@ void DN_NET_EmcDoWSSend(DN_NETRequestHandle handle, DN_Str8 data, DN_NETWSSend s
|
|||||||
DN_U64 pos = DN_MemListPos(request_ptr->start_response_arena.mem);
|
DN_U64 pos = DN_MemListPos(request_ptr->start_response_arena.mem);
|
||||||
DN_Str8 data_null_terminated = DN_Str8FromStr8Arena(data, &request_ptr->start_response_arena);
|
DN_Str8 data_null_terminated = DN_Str8FromStr8Arena(data, &request_ptr->start_response_arena);
|
||||||
result = emscripten_websocket_send_utf8_text(emc_request->socket, data_null_terminated.data);
|
result = emscripten_websocket_send_utf8_text(emc_request->socket, data_null_terminated.data);
|
||||||
DN_MemListPopTo(request_ptr->arena.mem, pos);
|
DN_MemListPopTo(request_ptr->start_response_arena.mem, pos);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DN_NETWSSend_Binary: {
|
case DN_NETWSSend_Binary: {
|
||||||
@@ -14161,19 +14278,21 @@ static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEm
|
|||||||
// NOTE: Deallocate the memory used in the request and reset the string builder (as all
|
// NOTE: Deallocate the memory used in the request and reset the string builder (as all
|
||||||
// payload(s) have been read from the request).
|
// payload(s) have been read from the request).
|
||||||
if (!end_request)
|
if (!end_request)
|
||||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end_request) {
|
if (end_request) {
|
||||||
DN_NET_EndFinishedRequest(request);
|
|
||||||
emscripten_websocket_delete(emc_request->socket);
|
emscripten_websocket_delete(emc_request->socket);
|
||||||
emc_request->socket = 0;
|
emc_request->socket = 0;
|
||||||
|
|
||||||
DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context;
|
DN_NETEmcCore *emc = DN_Cast(DN_NETEmcCore *) net->context;
|
||||||
request->next = emc->free_list;
|
request->next = emc->free_list;
|
||||||
request->prev = nullptr;
|
request->prev = nullptr;
|
||||||
request->gen++;
|
|
||||||
emc->free_list = request;
|
emc->free_list = request;
|
||||||
|
|
||||||
|
DN_Assert(emc_request->first_event == nullptr);
|
||||||
|
DN_Assert(emc_request->last_event == nullptr);
|
||||||
|
DN_NET_RequestRecycle(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
+22
-16
@@ -1027,6 +1027,13 @@ struct DN_U64FromResult
|
|||||||
DN_U64 value;
|
DN_U64 value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct DN_U32FromResult DN_U32FromResult;
|
||||||
|
struct DN_U32FromResult
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
DN_U32 value;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct DN_USizeFromResult DN_USizeFromResult;
|
typedef struct DN_USizeFromResult DN_USizeFromResult;
|
||||||
struct DN_USizeFromResult
|
struct DN_USizeFromResult
|
||||||
{
|
{
|
||||||
@@ -2986,9 +2993,15 @@ DN_API DN_U64 DN_U64FromU8x32HiBEUnsafe
|
|||||||
DN_API DN_U64FromResult DN_U64FromU8x32HiBE (DN_U8x32 const *val); // Checks [0:24) bytes aren't set before getting the U64
|
DN_API DN_U64FromResult DN_U64FromU8x32HiBE (DN_U8x32 const *val); // Checks [0:24) bytes aren't set before getting the U64
|
||||||
DN_API DN_USize DN_USizeFromU8x32HiBEUnsafe (DN_U8x32 const *val); // Get USize stored in big-endian at the high bytes [32 - sizeof USize:32)
|
DN_API DN_USize DN_USizeFromU8x32HiBEUnsafe (DN_U8x32 const *val); // Get USize stored in big-endian at the high bytes [32 - sizeof USize:32)
|
||||||
DN_API DN_USizeFromResult DN_USizeFromU8x32HiBE (DN_U8x32 const *val); // Checks [0:sizeof USize) bytes aren't set before getting the U64
|
DN_API DN_USizeFromResult DN_USizeFromU8x32HiBE (DN_U8x32 const *val); // Checks [0:sizeof USize) bytes aren't set before getting the U64
|
||||||
DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string, char separator);
|
DN_API DN_U32FromResult DN_U32FromHexStr8 (DN_Str8 hex);
|
||||||
DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size, char separator);
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiters (DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count);
|
||||||
DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size, char separator);
|
DN_API DN_U32FromResult DN_U32FromStr8Delimiter (DN_Str8 string, DN_Str8 delimiter);
|
||||||
|
DN_API DN_U32FromResult DN_U32FromPtr (void const *data, DN_USize size);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiters (DN_Str8 string, DN_Str8 const *delimiters, DN_USize delimiters_count);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8Delimiter (DN_Str8 string, DN_Str8 delimiter);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string);
|
||||||
|
DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size);
|
||||||
|
DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size);
|
||||||
|
|
||||||
DN_API bool DN_U8x32Eq (DN_U8x32 const *lhs, DN_U8x32 const *rhs);
|
DN_API bool DN_U8x32Eq (DN_U8x32 const *lhs, DN_U8x32 const *rhs);
|
||||||
DN_API DN_U8x32 DN_U8x32FromBytesLeftPadZ (DN_U8 const *ptr, DN_USize size);
|
DN_API DN_U8x32 DN_U8x32FromBytesLeftPadZ (DN_U8 const *ptr, DN_USize size);
|
||||||
@@ -3206,6 +3219,7 @@ DN_API DN_Str8 DN_Str8HexFromPtrBytesArena
|
|||||||
DN_API DN_Str8 DN_Str8HexFromStr8BytesArena (DN_Str8 bytes, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Str8 DN_Str8HexFromStr8BytesArena (DN_Str8 bytes, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z);
|
||||||
DN_API DN_Hex32 DN_Hex32FromPtrBytes16 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Hex32 DN_Hex32FromPtrBytes16 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
||||||
DN_API DN_Hex64 DN_Hex64FromPtrBytes32 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Hex64 DN_Hex64FromPtrBytes32 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
||||||
|
DN_API DN_Hex64 DN_Hex64FromU8x32 (DN_U8x32 const *value, DN_TrimLeadingZero trim_leading_z);
|
||||||
DN_API DN_Hex128 DN_Hex128FromPtrBytes64 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
DN_API DN_Hex128 DN_Hex128FromPtrBytes64 (void const *bytes, DN_USize bytes_count, DN_TrimLeadingZero trim_leading_z);
|
||||||
|
|
||||||
DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units);
|
||||||
@@ -4048,26 +4062,14 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2
|
|||||||
#define DN_LArrayMakeAssert(c_array, ptr_size, z_mem) DN_PArrayMakeAssert(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem)
|
#define DN_LArrayMakeAssert(c_array, ptr_size, z_mem) DN_PArrayMakeAssert(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem)
|
||||||
#define DN_LArrayMakeAssertZ(c_array, ptr_size) DN_PArrayMakeAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
#define DN_LArrayMakeAssertZ(c_array, ptr_size) DN_PArrayMakeAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
||||||
#define DN_LArrayMakeAssertNoZ(c_array, ptr_size) DN_PArrayMakeAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
#define DN_LArrayMakeAssertNoZ(c_array, ptr_size) DN_PArrayMakeAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
||||||
#define DN_LArrayMakeArena(c_array, ptr_size, arena, z_mem) DN_PArrayMakeArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, z_mem)
|
|
||||||
#define DN_LArrayMakeArenaZ(c_array, ptr_size, arena) DN_PArrayMakeArenaZ(c_array, ptr_size, DN_ArrayCountU(c_array), arena)
|
|
||||||
#define DN_LArrayMakeArenaNoZ(c_array, ptr_size, arena) DN_PArrayMakeArenaNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), arena)
|
|
||||||
#define DN_LArrayMakePool(c_array, ptr_size, pool, z_mem) DN_PArrayMakePool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, z_mem)
|
|
||||||
#define DN_LArrayMakePoolZ(c_array, ptr_size, pool) DN_PArrayMakePoolZ(c_array, ptr_size, DN_ArrayCountU(c_array), pool)
|
|
||||||
#define DN_LArrayMakePoolNoZ(c_array, ptr_size, pool) DN_PArrayMakePoolNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), pool)
|
|
||||||
|
|
||||||
#define DN_LArrayAddArray(c_array, ptr_size, items, count, add) DN_PArrayAddArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count, add)
|
#define DN_LArrayAddArray(c_array, ptr_size, items, count, add) DN_PArrayAddArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count, add)
|
||||||
#define DN_LArrayAdd(c_array, ptr_size, item, add) DN_PArrayAdd(c_array, ptr_size, DN_ArrayCountU(c_array), item, add)
|
#define DN_LArrayAdd(c_array, ptr_size, item, add) DN_PArrayAdd(c_array, ptr_size, DN_ArrayCountU(c_array), item, add)
|
||||||
#define DN_LArrayAddArena(c_array, ptr_size, arena, item, add) DN_PArrayAddArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, item, add)
|
|
||||||
#define DN_LArrayAddPool(c_array, ptr_size, pool, item, add) DN_PArrayAddPool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, item, add)
|
|
||||||
#define DN_LArrayAppendArray(c_array, ptr_size, items, count) DN_PArrayAppendArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
#define DN_LArrayAppendArray(c_array, ptr_size, items, count) DN_PArrayAppendArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
||||||
#define DN_LArrayAppend(c_array, ptr_size, item) DN_PArrayAppend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
#define DN_LArrayAppend(c_array, ptr_size, item) DN_PArrayAppend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
||||||
#define DN_LArrayAppendArena(c_array, ptr_size, arena, item) DN_PArrayAppendArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, item)
|
|
||||||
#define DN_LArrayAppendPool(c_array, ptr_size, pool, item) DN_PArrayAppendPool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, item)
|
|
||||||
#define DN_LArrayAppendAssert(c_array, ptr_size, item) DN_PArrayAppendAssert(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
#define DN_LArrayAppendAssert(c_array, ptr_size, item) DN_PArrayAppendAssert(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
||||||
#define DN_LArrayPrependArray(c_array, ptr_size, items, count) DN_PArrayPrependArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
#define DN_LArrayPrependArray(c_array, ptr_size, items, count) DN_PArrayPrependArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
||||||
#define DN_LArrayPrepend(c_array, ptr_size, item) DN_PArrayPrepend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
#define DN_LArrayPrepend(c_array, ptr_size, item) DN_PArrayPrepend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
||||||
#define DN_LArrayPrependArena(c_array, ptr_size, arena, item) DN_PArrayPrependArena(c_array, ptr_size, DN_ArrayCountU(c_array), arena, item)
|
|
||||||
#define DN_LArrayPrependPool(c_array, ptr_size, pool, item) DN_PArrayPrependPool(c_array, ptr_size, DN_ArrayCountU(c_array), pool, item)
|
|
||||||
#define DN_LArrayEraseRange(c_array, ptr_size, begin_index, count, erase) DN_PArrayEraseRange(c_array, ptr_size, begin_index, count, erase)
|
#define DN_LArrayEraseRange(c_array, ptr_size, begin_index, count, erase) DN_PArrayEraseRange(c_array, ptr_size, begin_index, count, erase)
|
||||||
#define DN_LArrayErase(c_array, ptr_size, index, erase) DN_PArrayErase(c_array, ptr_size, index, erase)
|
#define DN_LArrayErase(c_array, ptr_size, index, erase) DN_PArrayErase(c_array, ptr_size, index, erase)
|
||||||
#define DN_LArrayInsertArray(c_array, ptr_size, index, items, count) DN_PArrayInsertArray(c_array, ptr_size, DN_ArrayCountU(c_array), index, items, count)
|
#define DN_LArrayInsertArray(c_array, ptr_size, index, items, count) DN_PArrayInsertArray(c_array, ptr_size, DN_ArrayCountU(c_array), index, items, count)
|
||||||
@@ -5281,7 +5283,6 @@ DN_Str8 DN_NET_Str8DiagnosticFromResponse(DN_NETResponse const* resp
|
|||||||
// NOTE: Internal functions for different networking implementations to use
|
// NOTE: Internal functions for different networking implementations to use
|
||||||
void DN_NET_BaseInit (DN_NETCore *net, char *base, DN_U64 base_size);
|
void DN_NET_BaseInit (DN_NETCore *net, char *base, DN_U64 base_size);
|
||||||
DN_NETRequestHandle DN_NET_SetupRequest (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type);
|
DN_NETRequestHandle DN_NET_SetupRequest (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type);
|
||||||
void DN_NET_EndFinishedRequest (DN_NETRequest *request);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DN_WITH_NET_CURL
|
#if DN_WITH_NET_CURL
|
||||||
@@ -5310,6 +5311,11 @@ struct DN_NETCurlCore
|
|||||||
DN_NETRequest *response_list; // Finished requests that are to be deqeued by the user via wait for response
|
DN_NETRequest *response_list; // Finished requests that are to be deqeued by the user via wait for response
|
||||||
DN_NETRequest *deinit_list; // Requests that are finished and are awaiting to be de-initialised by the CURL thread
|
DN_NETRequest *deinit_list; // Requests that are finished and are awaiting to be de-initialised by the CURL thread
|
||||||
DN_NETRequest *free_list; // Request pool that new requests will use before allocating
|
DN_NETRequest *free_list; // Request pool that new requests will use before allocating
|
||||||
|
DN_USize request_count;
|
||||||
|
DN_USize response_count;
|
||||||
|
DN_USize deinit_count;
|
||||||
|
DN_USize free_count;
|
||||||
|
DN_USize thread_request_count;
|
||||||
|
|
||||||
// NOTE: Networking thread only
|
// NOTE: Networking thread only
|
||||||
DN_NETRequest *thread_request_list; // Current requests being executed by the CURL thread.
|
DN_NETRequest *thread_request_list; // Current requests being executed by the CURL thread.
|
||||||
|
|||||||
Reference in New Issue
Block a user