Get latest changes from upstream
This commit is contained in:
@@ -201,6 +201,6 @@ DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr,
|
||||
|
||||
DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena)
|
||||
{
|
||||
DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena);
|
||||
DN_Str8 result = DN_Str8FromStr8BuilderArena(&pack->writer, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ DN_API DN_JSONBuilder DN_JSONBuilder_Init(DN_Arena *arena, int spaces_per_indent
|
||||
|
||||
DN_API DN_Str8 DN_JSONBuilder_Build(DN_JSONBuilder const *builder, DN_Arena *arena)
|
||||
{
|
||||
DN_Str8 result = DN_Str8BuilderBuild(&builder->string_builder, arena);
|
||||
DN_Str8 result = DN_Str8FromStr8BuilderArena(&builder->string_builder, arena);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str
|
||||
|
||||
DN_API void DN_JSONBuilder_KeyValueFV(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, va_list args)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(&builder->string_builder.arena, 1);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&builder->string_builder.arena, 1);
|
||||
DN_Str8 value = DN_Str8FromFmtVArena(&scratch.arena, value_fmt, args);
|
||||
DN_JSONBuilder_KeyValue(builder, key, value);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
|
||||
@@ -79,15 +79,12 @@ enum DN_BinarySearchType
|
||||
|
||||
struct DN_BinarySearchResult
|
||||
{
|
||||
bool found;
|
||||
DN_USize index;
|
||||
bool found;
|
||||
DN_USize index;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using DN_QSortLessThanProc = bool(T const &a, T const &b, void *user_context);
|
||||
|
||||
#if !defined(DN_NO_JSON_BUILDER)
|
||||
// NOTE: DN_JSONBuilder ////////////////////////////////////////////////////////////////////////////
|
||||
// NOTE: DN_JSONBuilder
|
||||
#define DN_JSONBuilder_Object(builder) \
|
||||
DN_DeferLoop(DN_JSONBuilder_ObjectBegin(builder), \
|
||||
DN_JSONBuilder_ObjectEnd(builder))
|
||||
@@ -133,10 +130,6 @@ DN_API void DN_JSONBuilder_BoolNamed (DN_JSONBuilde
|
||||
template <typename T> bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs);
|
||||
template <typename T> DN_BinarySearchResult DN_BinarySearch (T const *array, DN_USize array_size, T const &find, DN_BinarySearchType type = DN_BinarySearchType_Match, DN_BinarySearchLessThanProc<T> less_than = DN_BinarySearch_DefaultLessThan);
|
||||
|
||||
// NOTE: DN_QSort
|
||||
template <typename T> bool DN_QSort_DefaultLessThan(T const &lhs, T const &rhs, void *user_context);
|
||||
template <typename T> void DN_QSort (T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc<T> less_than = DN_QSort_DefaultLessThan);
|
||||
|
||||
// NOTE: DN_BinarySearch
|
||||
template <typename T>
|
||||
bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs)
|
||||
@@ -189,76 +182,4 @@ DN_BinarySearchResult DN_BinarySearch(T const *array,
|
||||
result.index = first - array;
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: DN_QSort //////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
bool DN_QSort_DefaultLessThan(T const &lhs, T const &rhs, void *user_context)
|
||||
{
|
||||
(void)user_context;
|
||||
bool result = lhs < rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DN_QSort(T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc<T> less_than)
|
||||
{
|
||||
if (!array || array_size <= 1 || !less_than)
|
||||
return;
|
||||
|
||||
// NOTE: Insertion Sort, under 24->32 is an optimal amount /////////////////////////////////////
|
||||
const DN_USize QSORT_THRESHOLD = 24;
|
||||
if (array_size < QSORT_THRESHOLD) {
|
||||
for (DN_USize item_to_insert_index = 1; item_to_insert_index < array_size; item_to_insert_index++) {
|
||||
for (DN_USize index = 0; index < item_to_insert_index; index++) {
|
||||
if (!less_than(array[index], array[item_to_insert_index], user_context)) {
|
||||
T item_to_insert = array[item_to_insert_index];
|
||||
for (DN_USize i = item_to_insert_index; i > index; i--)
|
||||
array[i] = array[i - 1];
|
||||
|
||||
array[index] = item_to_insert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Quick sort, under 24->32 is an optimal amount /////////////////////////////////////////
|
||||
DN_USize last_index = array_size - 1;
|
||||
DN_USize pivot_index = array_size / 2;
|
||||
DN_USize partition_index = 0;
|
||||
DN_USize start_index = 0;
|
||||
|
||||
// Swap pivot with last index, so pivot is always at the end of the array.
|
||||
// This makes logic much simpler.
|
||||
DN_Swap(array[last_index], array[pivot_index]);
|
||||
pivot_index = last_index;
|
||||
|
||||
// 4^, 8, 7, 5, 2, 3, 6
|
||||
if (less_than(array[start_index], array[pivot_index], user_context))
|
||||
partition_index++;
|
||||
start_index++;
|
||||
|
||||
// 4, |8, 7, 5^, 2, 3, 6*
|
||||
// 4, 5, |7, 8, 2^, 3, 6*
|
||||
// 4, 5, 2, |8, 7, ^3, 6*
|
||||
// 4, 5, 2, 3, |7, 8, ^6*
|
||||
for (DN_USize index = start_index; index < last_index; index++) {
|
||||
if (less_than(array[index], array[pivot_index], user_context)) {
|
||||
DN_Swap(array[partition_index], array[index]);
|
||||
partition_index++;
|
||||
}
|
||||
}
|
||||
|
||||
// Move pivot to right of partition
|
||||
// 4, 5, 2, 3, |6, 8, ^7*
|
||||
DN_Swap(array[partition_index], array[pivot_index]);
|
||||
DN_QSort(array, partition_index, user_context, less_than);
|
||||
|
||||
// Skip the value at partion index since that is guaranteed to be sorted.
|
||||
// 4, 5, 2, 3, (x), 8, 7
|
||||
DN_USize one_after_partition_index = partition_index + 1;
|
||||
DN_QSort(array + one_after_partition_index, (array_size - one_after_partition_index), user_context, less_than);
|
||||
}
|
||||
|
||||
#endif // !defined(DN_HELPERS_H)
|
||||
|
||||
+41
-7
@@ -42,15 +42,40 @@ DN_NETRequestHandle DN_NET_HandleFromRequest(DN_NETRequest *request)
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_NET_EndFinishedRequest_(DN_NETRequest *request)
|
||||
bool DN_NET_ResponseHasFailed(DN_NETResponse const* resp)
|
||||
{
|
||||
// NOTE: Deallocate the memory used in the request and reset the string builder
|
||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||
// NOTE: Check that the request is completely detached
|
||||
DN_Assert(request->next == nullptr);
|
||||
bool result = false;
|
||||
if (resp->type == DN_NETRequestType_HTTP)
|
||||
result = resp->state == DN_NETResponseState_Error || resp->http_status >= 400;
|
||||
else
|
||||
result = resp->state == DN_NETResponseState_Error;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_NET_BaseInit_(DN_NETCore *net, char *base, DN_U64 base_size)
|
||||
DN_Str8 DN_NET_Str8DiagnosticFromResponse(DN_NETResponse const* resp, DN_Arena *arena)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||
bool resp_failed = DN_NET_ResponseHasFailed(resp);
|
||||
DN_Str8BuilderAppendF(&builder, "Request %s (%s", resp_failed ? "failed" : "succeeded", resp->type == DN_NETRequestType_HTTP ? "HTTP" : "WS");
|
||||
if (resp->type == DN_NETRequestType_HTTP) {
|
||||
if (resp->http_status)
|
||||
DN_Str8BuilderAppendF(&builder, " %u", resp->http_status);
|
||||
}
|
||||
DN_Str8BuilderAppendF(&builder, ")");
|
||||
if (resp->body.size || resp->error_str8.size) {
|
||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit(" with "));
|
||||
if (resp->body.size)
|
||||
DN_Str8BuilderAppendF(&builder, "%.*s", DN_Str8PrintFmt(resp->body));
|
||||
if (resp->error_str8.size)
|
||||
DN_Str8BuilderAppendF(&builder, "%s%.*s", resp->body.size ? ". " : "", DN_Str8PrintFmt(resp->error_str8));
|
||||
}
|
||||
DN_Str8 result = DN_Str8FromStr8BuilderArena(&builder, arena);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_NET_BaseInit(DN_NETCore *net, char *base, DN_U64 base_size)
|
||||
{
|
||||
net->base = base;
|
||||
net->base_size = base_size;
|
||||
@@ -59,7 +84,7 @@ void DN_NET_BaseInit_(DN_NETCore *net, char *base, DN_U64 base_size)
|
||||
net->completion_sem = DN_OS_SemaphoreInit(0);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// NOTE: Setup request
|
||||
DN_Assert(request);
|
||||
@@ -94,5 +119,14 @@ DN_NETRequestHandle DN_NET_SetupRequest_(DN_NETRequest *request, DN_Str8 url, DN
|
||||
|
||||
DN_NETRequestHandle result = DN_NET_HandleFromRequest(request);
|
||||
request->response.request = result;
|
||||
request->response.type = request->type;
|
||||
return result;
|
||||
}
|
||||
|
||||
void DN_NET_EndFinishedRequest(DN_NETRequest *request)
|
||||
{
|
||||
// NOTE: Deallocate the memory used in the request and reset the string builder
|
||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||
// NOTE: Check that the request is completely detached
|
||||
DN_Assert(request->next == nullptr);
|
||||
}
|
||||
|
||||
+10
-7
@@ -51,7 +51,7 @@ struct DN_NETDoHTTPArgs
|
||||
DN_U16 headers_size;
|
||||
|
||||
// NOTE: HTTP args only
|
||||
DN_Str8 payload;
|
||||
DN_Str8 payload;
|
||||
};
|
||||
|
||||
struct DN_NETRequestHandle
|
||||
@@ -63,6 +63,7 @@ struct DN_NETRequestHandle
|
||||
struct DN_NETResponse
|
||||
{
|
||||
// NOTE: Common to WS and HTTP responses
|
||||
DN_NETRequestType type;
|
||||
DN_NETResponseState state;
|
||||
DN_NETRequestHandle request;
|
||||
DN_Str8 error_str8;
|
||||
@@ -119,13 +120,15 @@ struct DN_NETCore
|
||||
DN_NETInterface api;
|
||||
};
|
||||
|
||||
DN_Str8 DN_NET_Str8FromResponseState(DN_NETResponseState state);
|
||||
DN_NETRequest * DN_NET_RequestFromHandle (DN_NETRequestHandle handle);
|
||||
DN_NETRequestHandle DN_NET_HandleFromRequest (DN_NETRequest *request);
|
||||
DN_Str8 DN_NET_Str8FromResponseState (DN_NETResponseState state);
|
||||
DN_NETRequest * DN_NET_RequestFromHandle (DN_NETRequestHandle handle);
|
||||
DN_NETRequestHandle DN_NET_HandleFromRequest (DN_NETRequest *request);
|
||||
bool DN_NET_ResponseHasFailed (DN_NETResponse const* resp);
|
||||
DN_Str8 DN_NET_Str8DiagnosticFromResponse(DN_NETResponse const* resp, DN_Arena *arena);
|
||||
|
||||
// NOTE: Internal functions for different networking implementations to use
|
||||
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);
|
||||
void DN_NET_EndFinishedRequest_ (DN_NETRequest *request);
|
||||
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);
|
||||
void DN_NET_EndFinishedRequest (DN_NETRequest *request);
|
||||
|
||||
#endif // DN_NET_H
|
||||
|
||||
@@ -93,7 +93,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
DN_OS_ThreadSetNameFmt("%.*s", DN_Str8PrintFmt(curl->thread.name));
|
||||
|
||||
while (!curl->kill_thread) {
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch tmem = DN_TCScratchBeginArena(nullptr, 0);
|
||||
|
||||
// NOTE: Handle events sitting in the ring queue
|
||||
for (bool dequeue_ring = true; dequeue_ring;) {
|
||||
@@ -159,7 +159,7 @@ 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
|
||||
// (we got their receipt back). Then restart the temp memory scope for the next websocket
|
||||
// payload
|
||||
DN_NET_EndFinishedRequest_(req);
|
||||
DN_NET_EndFinishedRequest(req);
|
||||
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
||||
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
||||
|
||||
@@ -175,12 +175,15 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
DN_NETRequest *request = DN_Cast(DN_NETRequest *) event.request.handle;
|
||||
|
||||
// NOTE: Release resources
|
||||
DN_NET_EndFinishedRequest_(request);
|
||||
DN_NET_EndFinishedRequest(request);
|
||||
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
||||
|
||||
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
||||
curl_easy_reset(curl_req->handle);
|
||||
curl_slist_free_all(curl_req->slist);
|
||||
curl_easy_reset(curl_req->handle);
|
||||
CURL *copy = curl_req->handle;
|
||||
*curl_req = {};
|
||||
curl_req->handle = copy;
|
||||
|
||||
// NOTE: Zero the struct preserving just the data we need to retain
|
||||
DN_NETRequest resetter = {};
|
||||
@@ -230,13 +233,13 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
req->response.state = DN_NETResponseState_WSOpen;
|
||||
}
|
||||
} else {
|
||||
req->response.error_str8 = DN_Str8FromFmtArena(&req->arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result));
|
||||
req->response.error_str8 = DN_Str8FromFmtArena(&req->start_response_arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result));
|
||||
req->response.state = DN_NETResponseState_Error;
|
||||
}
|
||||
} else {
|
||||
DN_USize curl_extended_error_size = DN_CStr8Size(curl_req->error);
|
||||
req->response.state = DN_NETResponseState_Error;
|
||||
req->response.error_str8 = DN_Str8FromFmtArena(&req->arena,
|
||||
req->response.error_str8 = DN_Str8FromFmtArena(&req->start_response_arena,
|
||||
"HTTP request '%.*s' failed (CURL %d): %s%s%s%s",
|
||||
DN_Str8PrintFmt(req->url),
|
||||
msg->data.result,
|
||||
@@ -400,7 +403,7 @@ DN_NETInterface DN_NET_CurlInterface()
|
||||
|
||||
void DN_NET_CurlInit(DN_NETCore *net, char *base, DN_U64 base_size)
|
||||
{
|
||||
DN_NET_BaseInit_(net, base, base_size);
|
||||
DN_NET_BaseInit(net, base, base_size);
|
||||
DN_NETCurlCore *curl = DN_ArenaNew(&net->arena, DN_NETCurlCore, DN_ZMem_Yes);
|
||||
net->context = curl;
|
||||
net->api = DN_NET_CurlInterface();
|
||||
@@ -458,8 +461,7 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
||||
// NOTE: Setup the request
|
||||
DN_NETCurlRequest *curl_req = DN_NET_CurlRequestFromRequest_(req);
|
||||
{
|
||||
result = DN_NET_SetupRequest_(req, url, method, args, type);
|
||||
req->response.request = result;
|
||||
result = DN_NET_SetupRequest(req, url, method, args, type);
|
||||
req->context[1] = DN_Cast(DN_UPtr) net;
|
||||
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
||||
}
|
||||
@@ -480,8 +482,10 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, req);
|
||||
|
||||
// NOTE: Assign HTTP headers
|
||||
for (DN_ForItSize(it, DN_Str8, req->args.headers, req->args.headers_size))
|
||||
for (DN_ForItSize(it, DN_Str8, req->args.headers, req->args.headers_size)) {
|
||||
DN_Assert(it.data->data[it.data->size] == 0);
|
||||
curl_req->slist = curl_slist_append(curl_req->slist, it.data->data);
|
||||
}
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_req->slist);
|
||||
|
||||
// NOTE: Setup handle for protocol
|
||||
@@ -593,7 +597,7 @@ static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN
|
||||
DN_NETResponse result = req->response;
|
||||
DN_NETCurlRequest *curl_req = DN_NET_CurlRequestFromRequest_(req);
|
||||
{
|
||||
result.body = DN_Str8BuilderBuild(&curl_req->str8_builder, arena);
|
||||
result.body = DN_Str8FromStr8BuilderArena(&curl_req->str8_builder, arena);
|
||||
if (result.error_str8.size)
|
||||
result.error_str8 = DN_Str8FromStr8Arena(result.error_str8, arena);
|
||||
}
|
||||
|
||||
+94
-34
@@ -365,6 +365,66 @@ static DN_UTCore DN_TST_Base()
|
||||
DN_UT_Assert(&result, mutex.ticket == ticket_b + 1);
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "QSort String (Natural)")) {
|
||||
DN_Str8 list[] = {
|
||||
DN_Str8Lit("item10"),
|
||||
DN_Str8Lit("item2"),
|
||||
DN_Str8Lit("item1"),
|
||||
DN_Str8Lit("item20"),
|
||||
DN_Str8Lit("item12"),
|
||||
DN_Str8Lit("Afile"),
|
||||
DN_Str8Lit("file2"),
|
||||
DN_Str8Lit("file10"),
|
||||
DN_Str8Lit("file1"),
|
||||
DN_Str8Lit("z_last"),
|
||||
DN_Str8Lit("m_middle"),
|
||||
DN_Str8Lit("a_first"),
|
||||
DN_Str8Lit("version-1.2.10"),
|
||||
DN_Str8Lit("version-1.2.2"),
|
||||
DN_Str8Lit("version-1.10.0"),
|
||||
};
|
||||
|
||||
DN_QSortStr8NaturalAsc(list, DN_ArrayCountU(list), DN_Str8EqCase_Sensitive);
|
||||
|
||||
DN_USize list_index = 0;
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("Afile")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("a_first")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("file1")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("file2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("file10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item1")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item12")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item20")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("m_middle")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.10.0")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("z_last")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "QSort String (Lexicographic)")) {
|
||||
DN_Str8 list[] = {
|
||||
DN_Str8Lit("z_last"),
|
||||
DN_Str8Lit("m_middle"),
|
||||
DN_Str8Lit("a_first"),
|
||||
DN_Str8Lit("version-1.2.10"),
|
||||
DN_Str8Lit("version-1.2.2"),
|
||||
DN_Str8Lit("version-1.10.0"),
|
||||
};
|
||||
|
||||
DN_QSortStr8LexicographicAsc(list, DN_ArrayCountU(list), DN_Str8EqCase_Insensitive);
|
||||
|
||||
DN_USize list_index = 0;
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("a_first")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("m_middle")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.10.0")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("z_last")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||
}
|
||||
|
||||
// NOTE: MSVC SAL complains that we are using Interlocked functionality on
|
||||
// variables it has detected as *not* being shared across threads. This is
|
||||
// fine, we're just running some basic results, so permit it.
|
||||
@@ -529,7 +589,7 @@ static DN_UTCore DN_TST_BaseArena()
|
||||
|
||||
static DN_UTCore DN_TST_BaseBytesHex()
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_UTCore test = DN_UT_Init();
|
||||
DN_UT_LogF(&test, "Bytes <-> Hex\n");
|
||||
{
|
||||
@@ -935,7 +995,7 @@ static DN_UTCore DN_TST_BaseDSMap()
|
||||
DN_UTCore result = DN_UT_Init();
|
||||
DN_UT_LogF(&result, "DN_DSMap\n");
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
{
|
||||
DN_MemList mem = DN_MemListFromVMem(0, 0, DN_MemFlags_Nil);
|
||||
DN_Arena arena = DN_ArenaFromMemList(&mem);
|
||||
@@ -1134,7 +1194,7 @@ static DN_UTCore DN_TST_BaseIArray()
|
||||
struct CustomArray
|
||||
{
|
||||
int *data;
|
||||
DN_USize size;
|
||||
DN_USize count;
|
||||
DN_USize max;
|
||||
};
|
||||
|
||||
@@ -1145,24 +1205,24 @@ static DN_UTCore DN_TST_BaseIArray()
|
||||
|
||||
for (DN_UT_Test(&result, "Make item")) {
|
||||
int *item = DN_IArrayMake(&array, DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, item && array.size == 1);
|
||||
DN_UT_Assert(&result, item && array.count == 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static DN_UTCore DN_TST_BaseCArray2()
|
||||
static DN_UTCore DN_TST_BaseArray()
|
||||
{
|
||||
DN_UTCore result = DN_UT_Init();
|
||||
DN_UT_LogF(&result, "DN_CArray2\n");
|
||||
DN_UT_LogF(&result, "DN_Array\n");
|
||||
{
|
||||
for (DN_UT_Test(&result, "Positive count, middle of array, stable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 5, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 2);
|
||||
DN_UT_Assert(&result, erase.it_index == 3);
|
||||
DN_UT_AssertF(&result, erase.it_index == 2, "erase.it_index=%zu", erase.it_index);
|
||||
DN_UT_Assert(&result, size == 8);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
@@ -1170,10 +1230,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Negative count, middle of array, stable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 3);
|
||||
DN_UT_Assert(&result, erase.it_index == 3);
|
||||
DN_UT_Assert(&result, erase.it_index == 2);
|
||||
DN_UT_Assert(&result, size == 7);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
@@ -1181,10 +1241,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "count = -1, stable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||
DN_UT_Assert(&result, erase.it_index == 5);
|
||||
DN_UT_Assert(&result, erase.it_index == 4);
|
||||
DN_UT_Assert(&result, size == 9);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
@@ -1192,10 +1252,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Positive count, unstable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable);
|
||||
int expected[] = {0, 1, 2, 8, 9, 5, 6, 7};
|
||||
DN_UT_Assert(&result, erase.items_erased == 2);
|
||||
DN_UT_Assert(&result, erase.it_index == 3);
|
||||
DN_UT_Assert(&result, erase.it_index == 2);
|
||||
DN_UT_Assert(&result, size == 8);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
@@ -1203,10 +1263,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Negative count, unstable erase")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable);
|
||||
int expected[] = {0, 1, 2, 7, 8, 9, 6};
|
||||
DN_UT_Assert(&result, erase.items_erased == 3);
|
||||
DN_UT_Assert(&result, erase.it_index == 3);
|
||||
DN_UT_Assert(&result, erase.it_index == 2);
|
||||
DN_UT_Assert(&result, size == 7);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
@@ -1214,7 +1274,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Edge case - begin_index at start, negative count")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 0, -2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 0, -2, DN_ArrayErase_Stable);
|
||||
int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||
DN_UT_Assert(&result, erase.it_index == 0);
|
||||
@@ -1225,10 +1285,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Edge case - begin_index at end, positive count")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||
DN_UT_Assert(&result, erase.it_index == 9);
|
||||
DN_UT_Assert(&result, erase.it_index == 8);
|
||||
DN_UT_Assert(&result, size == 9);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
@@ -1236,7 +1296,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Invalid input - count = 0")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 0, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 0, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||
DN_UT_Assert(&result, erase.it_index == 0);
|
||||
@@ -1246,7 +1306,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
|
||||
for (DN_UT_Test(&result, "Invalid input - null data")) {
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(nullptr, &size, sizeof(int), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(nullptr, &size, sizeof(int), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||
DN_UT_Assert(&result, erase.it_index == 0);
|
||||
DN_UT_Assert(&result, size == 10);
|
||||
@@ -1254,7 +1314,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
|
||||
for (DN_UT_Test(&result, "Invalid input - null size")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, NULL, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, NULL, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||
DN_UT_Assert(&result, erase.it_index == 0);
|
||||
}
|
||||
@@ -1262,7 +1322,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Invalid input - empty array")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 0;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||
DN_UT_Assert(&result, erase.it_index == 0);
|
||||
DN_UT_Assert(&result, size == 0);
|
||||
@@ -1271,10 +1331,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
||||
for (DN_UT_Test(&result, "Out-of-bounds begin_index")) {
|
||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_USize size = 10;
|
||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable);
|
||||
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable);
|
||||
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||
DN_UT_Assert(&result, erase.it_index == 10);
|
||||
DN_UT_Assert(&result, erase.it_index == 9);
|
||||
DN_UT_Assert(&result, size == 10);
|
||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||
}
|
||||
@@ -1632,7 +1692,7 @@ DN_Str8 const DN_UT_HASH_STRING_[] =
|
||||
|
||||
void DN_TST_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 input_hex = DN_HexFromPtrBytesArena(input.data, input.size, &scratch.arena, DN_TrimLeadingZero_No);
|
||||
|
||||
switch (hash_type) {
|
||||
@@ -1860,7 +1920,7 @@ static DN_UTCore DN_TST_OS()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Query executable directory")) {
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 os_result = DN_OS_EXEDir(&scratch.arena);
|
||||
DN_UT_Assert(&result, os_result.size);
|
||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_Str8PrintFmt(os_result));
|
||||
@@ -1911,7 +1971,7 @@ static DN_UTCore DN_TST_OS()
|
||||
DN_UT_Assert(&result, DN_OS_PathIsFile(SRC_FILE));
|
||||
|
||||
// NOTE: Read step
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 read_file = DN_OS_FileReadAllArena(&scratch.arena, SRC_FILE, nullptr);
|
||||
DN_UT_AssertF(&result, read_file.size, "Failed to load file");
|
||||
DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size);
|
||||
@@ -2166,7 +2226,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Initialise with format string")) {
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 string = DN_Str8FromFmtArena(&scratch.arena, "%s", "AB");
|
||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||
DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]);
|
||||
@@ -2176,7 +2236,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Copy string")) {
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 string = DN_Str8Lit("AB");
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(string, &scratch.arena);
|
||||
DN_UT_AssertF(&result, copy.size == 2, "size: %zu", copy.size);
|
||||
@@ -2192,7 +2252,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
||||
}
|
||||
|
||||
for (DN_UT_Test(&result, "Allocate string from arena")) {
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 string = DN_Str8AllocArena(2, DN_ZMem_No, &scratch.arena);
|
||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
@@ -2530,7 +2590,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
||||
|
||||
// NOTE: DN_Str8TruncMiddle (arena wrapper)
|
||||
for (DN_UT_Test(&result, "TruncMiddle: Arena wrapper allocates and truncates correctly")) {
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 str = DN_Str8Lit("HelloBeautifulWorld");
|
||||
DN_Str8 trunc = DN_Str8Lit("...");
|
||||
DN_Str8TruncResult res = DN_Str8TruncMiddle(str, 5, trunc, &scratch.arena);
|
||||
@@ -2551,7 +2611,7 @@ static DN_UTCore DN_TST_Win()
|
||||
#if defined(DN_PLATFORM_WIN32)
|
||||
DN_UT_LogF(&result, "OS Win32\n");
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 input8 = DN_Str8Lit("String");
|
||||
DN_Str16 input16 = DN_Str16{(wchar_t *)(L"String"), sizeof(L"String") / sizeof(L"String"[0]) - 1};
|
||||
|
||||
@@ -2700,7 +2760,7 @@ DN_TSTResult DN_TST_RunSuite(DN_TSTPrint print)
|
||||
#endif
|
||||
DN_TST_BaseDSMap(),
|
||||
DN_TST_BaseIArray(),
|
||||
DN_TST_BaseCArray2(),
|
||||
DN_TST_BaseArray(),
|
||||
DN_TST_BaseVArray(),
|
||||
DN_TST_Keccak(),
|
||||
DN_TST_M4(),
|
||||
|
||||
@@ -35,8 +35,8 @@ DN_MSVC_WARNING_PUSH
|
||||
DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap.
|
||||
int main(int, char**)
|
||||
{
|
||||
DN_Core dn = {};
|
||||
DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS | DN_InitFlags_ThreadContext, nullptr);
|
||||
DN_Core dn = {};
|
||||
DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS | DN_InitFlags_ThreadContext, DN_TCInitArgsDefault());
|
||||
DN_TST_RunSuite(DN_TSTPrint_Yes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user