Fix single header build with updated DN lib

This commit is contained in:
2026-05-18 11:19:15 +10:00
parent 0ff24117dd
commit 0905a10f61
31 changed files with 9674 additions and 38601 deletions
+299
View File
@@ -0,0 +1,299 @@
#include "dn_json_builder.h"
static void DN_JSB_Indent_(DN_JSBBuilder *builder, char *buf, size_t buf_size, size_t depth)
{
for (size_t i = 0; i < depth; i++) {
DN_JSB_AppendF_(builder, buf, buf_size, " ");
}
}
DN_JSBDepth *DN_JSB_PeekDepth_(DN_JSBBuilder *builder, size_t offset)
{
DN_JSBDepth *result = 0;
if (builder->depth_count > offset)
result = &builder->depth[builder->depth_count - (1 + offset)];
return result;
}
bool DN_JSB_PushDepth_(DN_JSBBuilder *builder, DN_JSBDepthType type)
{
bool result = false;
if (builder->depth_count < builder->depth_max) {
DN_JSBDepth *depth = &builder->depth[builder->depth_count++];
depth->last_action = DN_JSBAction_Nil;
depth->type = type;
result = true;
}
return result;
}
DN_JSBResult DN_JSB_PushObject(DN_JSBBuilder *builder, char *buf, size_t buf_size)
{
DN_JSBDepth *top_depth = DN_JSB_PeekDepth_(builder, 0);
if (top_depth && top_depth->type != DN_JSBDepthType_Array) {
if ((top_depth->last_action == DN_JSBAction_Value || top_depth->last_action == DN_JSBAction_PopArray || top_depth->last_action == DN_JSBAction_PushObject))
return DN_JSBResult_BadAPIUsage;
}
if (!DN_JSB_PushDepth_(builder, DN_JSBDepthType_Object))
return DN_JSBResult_DepthArrayOutOfMem;
bool leading_comma = top_depth && (top_depth->last_action != DN_JSBAction_Nil && top_depth->last_action != DN_JSBAction_Key);
if (builder->pretty && top_depth && top_depth->type == DN_JSBDepthType_Array) {
if (leading_comma) {
DN_JSB_AppendF_(builder, buf, buf_size, ",\n");
} else {
DN_JSB_AppendF_(builder, buf, buf_size, "\n");
}
DN_JSB_Indent_(builder, buf, buf_size, builder->depth_count - 1);
leading_comma = false;
}
DN_JSBResult result = DN_JSB_AppendF_(builder, buf, buf_size, "%s{", leading_comma ? "," : "");
if (top_depth)
top_depth->last_action = DN_JSBAction_PushObject; // Record the push on the now, previous depth
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_PopObject(DN_JSBBuilder *builder, char *buf, size_t buf_size)
{
DN_JSBDepth *top_depth = DN_JSB_PeekDepth_(builder, 0);
if (!top_depth || top_depth->type != DN_JSBDepthType_Object)
return DN_JSBResult_BadAPIUsage;
bool had_children = top_depth->last_action != DN_JSBAction_Nil;
builder->depth_count--; // Remove the depth entry from the stack
DN_JSBDepth *new_top = DN_JSB_PeekDepth_(builder, 0);
if (new_top)
new_top->last_action = DN_JSBAction_PopObject;
if (builder->pretty && had_children) {
DN_JSB_AppendF_(builder, buf, buf_size, "\n");
DN_JSB_Indent_(builder, buf, buf_size, builder->depth_count);
}
DN_JSBResult result = DN_JSB_AppendF_(builder, buf, buf_size, "}");
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_PushArray(DN_JSBBuilder *builder, char *buf, size_t buf_size)
{
DN_JSBDepth *top_depth = DN_JSB_PeekDepth_(builder, 0);
if (top_depth && top_depth->type != DN_JSBDepthType_Array) {
if (top_depth->last_action == DN_JSBAction_Value || top_depth->last_action == DN_JSBAction_PopArray || top_depth->last_action == DN_JSBAction_PushObject || top_depth->last_action == DN_JSBAction_PopObject)
return DN_JSBResult_BadAPIUsage;
}
if (!DN_JSB_PushDepth_(builder, DN_JSBDepthType_Array))
return DN_JSBResult_DepthArrayOutOfMem;
bool leading_comma = top_depth && (top_depth->last_action != DN_JSBAction_Nil && top_depth->last_action != DN_JSBAction_Key);
if (builder->pretty && top_depth && top_depth->type == DN_JSBDepthType_Array) {
if (leading_comma) {
DN_JSB_AppendF_(builder, buf, buf_size, ",\n");
} else {
DN_JSB_AppendF_(builder, buf, buf_size, "\n");
}
DN_JSB_Indent_(builder, buf, buf_size, builder->depth_count - 1);
leading_comma = false;
}
DN_JSBResult result = DN_JSB_AppendF_(builder, buf, buf_size, "%s[", leading_comma ? "," : "");
if (top_depth)
top_depth->last_action = DN_JSBAction_PushArray; // Record the push on the now, previous depth
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_PopArray(DN_JSBBuilder *builder, char *buf, size_t buf_size)
{
DN_JSBDepth *top_depth = DN_JSB_PeekDepth_(builder, 0);
if (!top_depth || top_depth->type != DN_JSBDepthType_Array)
return DN_JSBResult_BadAPIUsage;
bool had_children = top_depth->last_action != DN_JSBAction_Nil;
builder->depth_count--; // Remove the depth entry from the stack
DN_JSBDepth *new_top = DN_JSB_PeekDepth_(builder, 0);
if (new_top)
new_top->last_action = DN_JSBAction_PopArray;
if (builder->pretty && had_children) {
DN_JSB_AppendF_(builder, buf, buf_size, "\n");
DN_JSB_Indent_(builder, buf, buf_size, builder->depth_count);
}
DN_JSBResult result = DN_JSB_AppendF_(builder, buf, buf_size, "]");
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_KeyF(DN_JSBBuilder *builder, char *buf, size_t buf_size, char const *fmt, ...)
{
DN_JSBDepth *top_depth = DN_JSB_PeekDepth_(builder, 0);
if (!top_depth || top_depth->last_action == DN_JSBAction_Key || top_depth->last_action == DN_JSBAction_PushArray)
return DN_JSBResult_BadAPIUsage;
va_list args;
va_start(args, fmt);
if (builder->pretty) {
if (top_depth->last_action != DN_JSBAction_Nil) {
DN_JSB_AppendF_(builder, buf, buf_size, ",\n");
} else {
DN_JSB_AppendF_(builder, buf, buf_size, "\n");
}
DN_JSB_Indent_(builder, buf, buf_size, builder->depth_count);
DN_JSB_AppendF_(builder, buf, buf_size, "\"");
DN_JSB_AppendFV_(builder, buf, buf_size, fmt, args);
DN_JSBResult result = DN_JSB_AppendF_(builder, buf, buf_size, "\": ");
va_end(args);
if (result == DN_JSBResult_Success)
top_depth->last_action = DN_JSBAction_Key;
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSB_AppendF_(builder, buf, buf_size, "%s\"", top_depth->last_action != DN_JSBAction_Nil ? "," : "");
DN_JSB_AppendFV_(builder, buf, buf_size, fmt, args);
DN_JSBResult result = DN_JSB_AppendF_(builder, buf, buf_size, "\":");
va_end(args);
if (result == DN_JSBResult_Success)
top_depth->last_action = DN_JSBAction_Key;
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_ValueStringF(DN_JSBBuilder *builder, char *buf, size_t buf_size, char const *fmt, ...)
{
DN_JSBResult result = DN_JSB_BeginWriteValue_(builder, buf, buf_size);
if (result == DN_JSBResult_Success) {
DN_JSB_AppendF_(builder, buf, buf_size, "\"");
va_list args;
va_start(args, fmt);
DN_JSB_AppendFV_(builder, buf, buf_size, fmt, args);
va_end(args);
result = DN_JSB_AppendF_(builder, buf, buf_size, "\"");
DN_JSB_FinishWriteValue_(builder, result);
}
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_ValueNull(DN_JSBBuilder *builder, char *buf, size_t buf_size)
{
DN_JSBResult result = DN_JSB_BeginWriteValue_(builder, buf, buf_size);
if (result == DN_JSBResult_Success) {
result = DN_JSB_AppendF_(builder, buf, buf_size, "null");
DN_JSB_FinishWriteValue_(builder, result);
}
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_ValueBool(DN_JSBBuilder *builder, char *buf, size_t buf_size, bool flag)
{
DN_JSBResult result = DN_JSB_BeginWriteValue_(builder, buf, buf_size);
if (result == DN_JSBResult_Success) {
result = DN_JSB_AppendF_(builder, buf, buf_size, flag ? "true" : "false");
DN_JSB_FinishWriteValue_(builder, result);
}
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_ValueNumber(DN_JSBBuilder *builder, char *buf, size_t buf_size, double number)
{
DN_JSBResult result = DN_JSB_BeginWriteValue_(builder, buf, buf_size);
if (result == DN_JSBResult_Success) {
result = DN_JSB_AppendF_(builder, buf, buf_size, "%.17G", number);
DN_JSB_FinishWriteValue_(builder, result);
}
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_BeginWriteValue_(DN_JSBBuilder *builder, char *buf, size_t buf_size)
{
DN_JSBDepth *top = DN_JSB_PeekDepth_(builder, 0);
if (!top)
return DN_JSBResult_BadAPIUsage;
bool is_key = top->last_action == DN_JSBAction_Key;
bool is_array = top->type == DN_JSBDepthType_Array;
if (!is_key && !is_array)
return DN_JSBResult_BadAPIUsage;
DN_JSBResult result = DN_JSBResult_Success;
if (top->type == DN_JSBDepthType_Array) {
if (builder->pretty) {
if (top->last_action != DN_JSBAction_Nil) {
DN_JSB_AppendF_(builder, buf, buf_size, ",\n");
} else {
DN_JSB_AppendF_(builder, buf, buf_size, "\n");
}
DN_JSB_Indent_(builder, buf, buf_size, builder->depth_count);
} else if (top->last_action != DN_JSBAction_Nil) {
result = DN_JSB_AppendF_(builder, buf, buf_size, ",");
}
}
return result;
}
void DN_JSB_FinishWriteValue_(DN_JSBBuilder *builder, DN_JSBResult last_value_raw_str_result)
{
if (last_value_raw_str_result == DN_JSBResult_Success) {
DN_JSBDepth *top_depth = DN_JSB_PeekDepth_(builder, 0);
top_depth->last_action = DN_JSBAction_Value;
}
}
DN_JSBResult DN_JSB_AppendFV_(DN_JSBBuilder *builder, char *buf, size_t buf_size, char const *fmt, va_list args)
{
// NOTE: Calc size required
size_t size = 0;
{
va_list args_copy;
va_copy(args_copy, args);
size = DN_JSB_VSNPrintF(0, 0, fmt, args_copy);
va_end(args_copy);
}
// NOTE: Do the write
DN_JSBResult result = DN_JSBResult_Success;
if (buf) {
if (builder->p > buf_size)
return DN_JSBResult_BadAPIUsage;
char *dest = buf + builder->p;
size_t dest_size = (buf + buf_size) - dest;
if ((size + 1) <= dest_size) { // NOTE: +1 because vsnprintf always null-terminates the stream
DN_JSB_VSNPrintF(dest, dest_size, fmt, args);
} else {
result = DN_JSBResult_BufOutOfMem;
}
}
if (result == DN_JSBResult_Success)
builder->p += size;
if (builder->error == DN_JSBResult_Success)
builder->error = result;
return result;
}
DN_JSBResult DN_JSB_AppendF_(DN_JSBBuilder *builder, char *buf, size_t buf_size, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
DN_JSBResult result = DN_JSB_AppendFV_(builder, buf, buf_size, fmt, args);
va_end(args);
return result;
}