Update naming convention of library

This commit is contained in:
doyle 2021-09-24 22:29:34 +10:00
parent 37ae9b0e40
commit f6ae4ad2a0
5 changed files with 1574 additions and 1595 deletions

2146
dqn.h

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,5 @@
#if !defined(DQN_CPP_FILE_H)
#define DQN_CPP_FILE_H
// -----------------------------------------------------------------------------
// NOTE: Overview
// -----------------------------------------------------------------------------
// Utility functions for creating C++ files at run-time.
//
// -----------------------------------------------------------------------------
// NOTE: Macros
// -----------------------------------------------------------------------------
// #define DQN_CPP_FILE_IMPLEMENTATION
// Define this in one and only one C++ file to enable the implementation
// code of the header file.
//
// #define DQN_CPPF_ASSERT(expr)
// Define this macro to override the default assert used.
#include <stdio.h>
#include <stdarg.h>
@ -21,32 +7,22 @@
// -----------------------------------------------------------------------------
// NOTE: Dqn_CppFile: Helper functions to generate formatted CPP files
// -----------------------------------------------------------------------------
#if !defined(DQN_CPPF_ASSERT)
#define DQN_CPPF_ASSERT(expr) do { if (!(expr)) { *((volatile int *)0) = 0; } } while (0)
#endif
#define DQN_CPPF_ASSERT(expr) do { if (!(expr)) { *((int *)0) = 0; } } while (0)
struct Dqn_CppFile
{
FILE *file; // The file to output to.
int indent; // The current indent level
int space_per_indent; // The number of spaces applied per indent. If zero- the functions give a default value.
bool append_extra_new_line; // If true, when code blocks are terminated, an additional new line will be appended for whitespacing.
FILE *file;
int indent;
int space_per_indent;
bool append_extra_new_line;
};
// return: The number of spaces per indent at this point of invocation. If
// spaces-per-indent in the CppFile is set to 0 the indent defaults to 4 spaces.
int Dqn_CppFile_SpacePerIndent(Dqn_CppFile const *cpp);
int Dqn_CppFile_SpacePerIndent(Dqn_CppFile *cpp);
// Create a line in the C++ file. This is a piece-meal API where you can
// flexibly construct a line by calling {LineBegin, LineAdd, LineEnd}. Calling
// LineEnd terminates the line with a trailing new-line. Calling LineAdd is
// optional if the line can be constructed with just a LineAdd and LineEnd.
void Dqn_CppFile_LineBeginV (Dqn_CppFile *cpp, char const *fmt, va_list args);
void Dqn_CppFile_LineBegin (Dqn_CppFile *cpp, char const *fmt, ...);
void Dqn_CppFile_LineAdd (Dqn_CppFile *cpp, char const *fmt, ...);
void Dqn_CppFile_LineEnd (Dqn_CppFile *cpp, char const *fmt, ...);
// Create a line in the C++ file and terminate it with a new-line.
void Dqn_CppFile_LineAdd (Dqn_CppFile *cpp, char const *fmt, ...);
void Dqn_CppFile_LineV (Dqn_CppFile *cpp, char const *fmt, va_list args);
void Dqn_CppFile_Line (Dqn_CppFile *cpp, char const *fmt, ...);
@ -54,27 +30,9 @@ void Dqn_CppFile_NewLine (Dqn_CppFile *cpp);
void Dqn_CppFile_Indent (Dqn_CppFile *cpp);
void Dqn_CppFile_Unindent (Dqn_CppFile *cpp);
// Begin a C++ code block which is any block that utilises a opening and
// closing brace.
// fmt: (Optional) The format string to print at the beginning of the block.
// When the fmt string is given, it will place a new-line at the end of the fmt
// string. When fmt is nullptr, no new line will be appended.
/*
Dqn_CppFile_Line(&cpp, "void MyFunction(int x, int y)");
Dqn_CppFile_BeginBlock(&cpp, nullptr);
Dqn_CppFile_Line(&cpp, "int result = x + y;");
Dqn_CppFile_Line(&cpp, "return result;");
Dqn_CppFile_EndFuncBlock(&cpp);
// Generates
//
// void MyFunction(int x, int y)
// {
// int result = x + y;
// return result;
// }
//
*/
void Dqn_CppFile_BeginBlock (Dqn_CppFile *cpp, char const *fmt, ...);
void Dqn_CppFile_EndBlock (Dqn_CppFile *cpp, bool trailing_semicolon, bool new_line_on_next_block);
@ -89,7 +47,7 @@ void Dqn_CppFile_EndBlock (Dqn_CppFile *cpp, bool trailing_semicolon, bo
// -----------------------------------------------------------------------------
// NOTE: Dqn_CppFile Implementation
// -----------------------------------------------------------------------------
int Dqn_CppFile_SpacePerIndent(Dqn_CppFile const *cpp)
int Dqn_CppFile_SpacePerIndent(Dqn_CppFile *cpp)
{
int result = cpp->space_per_indent == 0 ? 4 : cpp->space_per_indent;
return result;
@ -110,14 +68,6 @@ void Dqn_CppFile_LineBegin(Dqn_CppFile *cpp, char const *fmt, ...)
va_end(args);
}
void Dqn_CppFile_LineAdd(Dqn_CppFile *cpp, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(cpp->file, fmt, args);
va_end(args);
}
void Dqn_CppFile_LineEnd(Dqn_CppFile *cpp, char const *fmt, ...)
{
if (fmt)
@ -131,6 +81,14 @@ void Dqn_CppFile_LineEnd(Dqn_CppFile *cpp, char const *fmt, ...)
fputc('\n', cpp->file);
}
void Dqn_CppFile_LineAdd(Dqn_CppFile *cpp, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(cpp->file, fmt, args);
va_end(args);
}
void Dqn_CppFile_LineV(Dqn_CppFile *cpp, char const *fmt, va_list args)
{
Dqn_CppFile_LineBeginV(cpp, fmt, args);

View File

@ -14,10 +14,7 @@
// code of the header file. This will also automatically enable the JSMN
// implementation.
//
#if !defined(DQN_H)
#error You must include "dqn.h" before including "dqn_jsmn.h"
#endif // DQN_H
#include <assert.h>
// -----------------------------------------------------------------------------
// NOTE: JSMN Configuration
@ -245,6 +242,22 @@ int jsmn_iterator_next( jsmn_iterator_t *iterator, jsmntok_t **jsmn_identifier,
// -----------------------------------------------------------------------------
// Header File
// -----------------------------------------------------------------------------
#define DQN_JSMN_STRING(string) Dqn_JsmnString{(string), sizeof(string) - 1}
struct Dqn_JsmnString
{
union {
char * str;
char const *const_str;
};
int size;
};
bool Dqn_Jsmn_StringEq(Dqn_JsmnString lhs, Dqn_JsmnString rhs);
bool Dqn_Jsmn_StringIsValid(Dqn_JsmnString string);
bool Dqn_Jsmn_IsDigit(char ch);
uint64_t Dqn_Jsmn_StringToU64(Dqn_JsmnString string);
bool operator==(Dqn_JsmnString lhs, Dqn_JsmnString rhs);
#define DQN_JSMN_X_MACRO \
DQN_JSMN_X_ENTRY(Object) \
DQN_JSMN_X_ENTRY(Array) \
@ -252,53 +265,50 @@ int jsmn_iterator_next( jsmn_iterator_t *iterator, jsmntok_t **jsmn_identifier,
DQN_JSMN_X_ENTRY(Number) \
DQN_JSMN_X_ENTRY(Bool)
enum struct Dqn_JsmnTokenIs
enum Dqn_JsmnTokenIs
{
#define DQN_JSMN_X_ENTRY(enum_val) enum_val,
DQN_JSMN_X_MACRO
#define DQN_JSMN_X_ENTRY(enum_val) Dqn_JsmnTokenIs_##enum_val,
DQN_JSMN_X_MACRO
#undef DQN_JSMN_X_ENTRY
};
inline Dqn_String const Dqn_JsmnTokenIsEnumString(Dqn_JsmnTokenIs token)
Dqn_JsmnString const Dqn_Jsmn_TokenIsToString[]
{
switch (token)
{
#define DQN_JSMN_X_ENTRY(enum_val) case Dqn_JsmnTokenIs::enum_val: return DQN_STRING(#enum_val);
DQN_JSMN_X_MACRO
#undef DQN_JSMN_X_ENTRY
}
return DQN_STRING("DQN_JSMN_UNHANDLED_ENUM");
#define DQN_JSMN_X_ENTRY(enum_val) DQN_JSMN_STRING(#enum_val),
DQN_JSMN_X_MACRO
#undef DQN_JSMN_X_ENTRY
};
struct Dqn_JsmnError
{
jsmntok_t token;
Dqn_String json;
Dqn_JsmnString json;
Dqn_JsmnTokenIs expected;
char const *cpp_file; // The file of the .cpp/h source code that triggered the error
int cpp_line; // The line of the .cpp/h source code that triggered the error
};
#define DQN_JSMN_ERROR_HANDLE_SIZE 128
struct Dqn_JsmnErrorHandle
{
Dqn_ArenaAllocator *arena;
Dqn_List<Dqn_JsmnError> list;
Dqn_JsmnError errors[DQN_JSMN_ERROR_HANDLE_SIZE];
int errors_size;
};
struct Dqn_Jsmn
{
jsmn_parser parser;
Dqn_String json;
int tokens_size;
jsmntok_t *tokens;
bool valid;
jsmn_parser parser;
Dqn_JsmnString json;
int tokens_size;
jsmntok_t *tokens;
};
struct Dqn_JsmnIterator
{
Dqn_b32 init;
bool init;
jsmn_iterator_t jsmn_it;
Dqn_String json;
Dqn_JsmnString json;
jsmntok_t *key;
jsmntok_t *value;
@ -308,61 +318,81 @@ struct Dqn_JsmnIterator
int token_index_hint;
};
Dqn_Jsmn Dqn_Jsmn_InitWithJSON (Dqn_String json, Dqn_ArenaAllocator *arena);
Dqn_Jsmn Dqn_Jsmn_InitWithJSONFile (Dqn_String file, Dqn_ArenaAllocator *arena);
// Calculate the number of tokens required to parse the 'json' input.
int Dqn_Jsmn_TokensRequired(char const *json, int size);
// To initialise successfully, call this function with the 'jsmn' parameter
// set with the 'jsmn->tokens' and 'jsmn->tokens_size' fields set to a valid
// destination buffer with a sufficient size that will be written on completion
// of the function. The required amount of tokens can be calculated using
// Dqn_Jsmn_TokensRequired.
//
// The function *does* not validate that the 'jsmn->tokens_size' is sufficient
// to hold the tokens in release mode.
//
// return: False if any of the parameters are invalid or the 'jsmn' tokens or
// size are not set, otherwise true. Additionally, 'jsmn->valid' is set
// accordingly to match the result of initialisation.
bool Dqn_Jsmn_InitWithJSONCString(char const *json, int size, Dqn_Jsmn *jsmn);
#if defined(DQN_H)
Dqn_Jsmn Dqn_Jsmn_InitWithJSON(Dqn_JsmnString json, Dqn_ArenaAllocator *arena);
Dqn_Jsmn Dqn_Jsmn_InitWithJSONFile(Dqn_JsmnString file, Dqn_ArenaAllocator *arena);
#endif // DQN_H
// return: If the token is an array, return the size of the array otherwise -1.
int Dqn_Jsmn_TokenArraySize(jsmntok_t token);
Dqn_String Dqn_Jsmn_TokenString(jsmntok_t token, Dqn_String json);
Dqn_b32 Dqn_Jsmn_TokenBool(jsmntok_t token, Dqn_String json);
Dqn_u64 Dqn_Jsmn_TokenU64(jsmntok_t token, Dqn_String json);
int Dqn_Jsmn_TokenArraySize(jsmntok_t token);
Dqn_JsmnString Dqn_Jsmn_TokenString(jsmntok_t token, Dqn_JsmnString json);
bool Dqn_Jsmn_TokenBool(jsmntok_t token, Dqn_JsmnString json);
uint64_t Dqn_Jsmn_TokenU64(jsmntok_t token, Dqn_JsmnString json);
// Iterator abstraction over jsmn_iterator_t, example on how to use this is
// shown below. The goal here is to minimise the amount of state the user has to
// manage.
#if 0
Dqn_ArenaAllocator arena = {};
Dqn_String json = DQN_STRING(R"({
Dqn_JsmnString json = DQN_STRING(R"({
"test": {
"test2": 0
}
})");
Dqn_Jsmn jsmn_state = Dqn_Jsmn_InitWithJSON(json, &arena);
for (Dqn_JsmnIterator it = {}; Dqn_JsmnIterator_Next(&it, &jsmn_state, nullptr /*prev_it*/); )
for (Dqn_JsmnIterator it = {}; Dqn_Jsmn_IteratorNext(&it, &jsmn_state, nullptr /*prev_it*/); )
{
Dqn_String key_str = Dqn_Jsmn_TokenString(*it.key, jsmn_state.json);
if (Dqn_JsmnIterator_Key(&it) == DQN_STRING("test"))
Dqn_JsmnString key = Dqn_JsmnITerator_Key(&it);
if (key == DQN_STRING("test"))
{
if (!Dqn_JsmnIterator_ExpectValue(&it, Dqn_JsmnTokenIs::Object, nullptr))
if (!Dqn_Jsmn_IteratorExpectValue(&it, Dqn_JsmnTokenIs_Object, nullptr))
continue;
for (Dqn_JsmnIterator obj_it = {}; Dqn_JsmnIterator_Next(&obj_it, &jsmn_state, &it); )
for (Dqn_JsmnIterator obj_it = {}; Dqn_Jsmn_IteratorNext(&obj_it, &jsmn_state, &it); )
{
if (Dqn_JsmnIterator_Key(&it) == DQN_STRING("test2"))
Dqn_JsmnString obj_key = Dqn_JsmnITerator_Key(&obj_it);
if (obj_key == DQN_STRING("test2"))
{
if (!Dqn_JsmnIterator_ExpectValue(&it, Dqn_JsmnTokenIs::Number, nullptr))
if (!Dqn_Jsmn_IteratorExpectValue(&obj_it, Dqn_JsmnTokenIs_Number, nullptr))
continue;
Dqn_u64 test_2_value = Dqn_JsmnIterator_U64(&obj_it);
uint64_t test_2_value = Dqn_Jsmn_IteratorU64(&obj_it);
}
}
}
}
#endif
Dqn_b32 Dqn_JsmnIterator_Next(Dqn_JsmnIterator *it, Dqn_Jsmn *jsmn_state, Dqn_JsmnIterator *prev_it);
Dqn_String Dqn_JsmnIterator_Key (Dqn_JsmnIterator *it);
Dqn_JsmnIterator Dqn_JsmnIterator_FindKey(Dqn_Jsmn *jsmn_state, Dqn_String key, Dqn_JsmnIterator *parent_it);
bool Dqn_Jsmn_IteratorNext(Dqn_JsmnIterator *it, Dqn_Jsmn *jsmn_state, Dqn_JsmnIterator *prev_it);
Dqn_JsmnString Dqn_Jsmn_IteratorKey(Dqn_JsmnIterator *it);
Dqn_JsmnIterator Dqn_Jsmn_IteratorFindKey(Dqn_Jsmn *jsmn_state, Dqn_JsmnString key, Dqn_JsmnIterator *parent_it);
#define Dqn_JsmnIterator_ExpectValue(it, expected, err_handle) Dqn_JsmnIterator__ExpectValue(it, expected, err_handle, __FILE__, __LINE__)
#define Dqn_JsmnIterator_ExpectKey(it, expected, err_handle) Dqn_JsmnIterator__ExpectKey(it, expected, err_handle, __FILE__, __LINE__)
#define Dqn_Jsmn_IteratorExpectValue(it, expected, err_handle) Dqn_Jsmn_Iterator_ExpectValue(it, expected, err_handle, __FILE__, __LINE__)
#define Dqn_Jsmn_IteratorExpectKey(it, expected, err_handle) Dqn_Jsmn_Iterator_ExpectKey(it, expected, err_handle, __FILE__, __LINE__)
// Convert the value part of the key-value JSON pair the iterator is currently
// pointing to, to a string/bool/u64. If the iterator's value does not point to
// the type requested, a zero initialised value is returned.
Dqn_String Dqn_JsmnIterator_String(Dqn_JsmnIterator const *it);
Dqn_b32 Dqn_JsmnIterator_Bool (Dqn_JsmnIterator const *it);
Dqn_u64 Dqn_JsmnIterator_U64 (Dqn_JsmnIterator const *it);
Dqn_JsmnString Dqn_Jsmn_IteratorString(Dqn_JsmnIterator const *it);
bool Dqn_Jsmn_IteratorBool(Dqn_JsmnIterator const *it);
uint64_t Dqn_Jsmn_IteratorU64(Dqn_JsmnIterator const *it);
#define DQN_JSMN_ERROR_HANDLE_DUMP(handle) \
for (Dqn_ListChunk<Dqn_JsmnError> *chunk = handle.list.head; chunk; chunk = chunk->next) \
@ -372,7 +402,7 @@ Dqn_u64 Dqn_JsmnIterator_U64 (Dqn_JsmnIterator const *it);
DQN_LOG_E("Json parsing error in %s:%d, expected token type: %.*s, token was: %.*s", \
Dqn_Str_FileNameFromPath(error->cpp_file), \
error->cpp_line, \
DQN_STRING_FMT(Dqn_JsmnTokenIsEnumString(error->expected)), \
DQN_STRING_FMT(Dqn_Jsmn_TokenIsToString(error->expected)), \
DQN_STRING_FMT(Dqn_Jsmn_TokenString(error->token, error->json))); \
} \
}
@ -383,27 +413,89 @@ Dqn_u64 Dqn_JsmnIterator_U64 (Dqn_JsmnIterator const *it);
// -----------------------------------------------------------------------------
// Implementation
// -----------------------------------------------------------------------------
Dqn_Jsmn Dqn_Jsmn_InitWithJSON(Dqn_String json, Dqn_ArenaAllocator *arena)
bool Dqn_Jsmn_StringEq(Dqn_JsmnString lhs, Dqn_JsmnString rhs)
{
Dqn_Jsmn result = {};
result.json = json;
bool result = lhs.size == rhs.size;
for (int i = 0; i < lhs.size && result; i++) result &= lhs.str[i] == rhs.str[i];
return result;
}
jsmn_init(&result.parser);
result.tokens_size = jsmn_parse(&result.parser, result.json.str, result.json.size, nullptr, 0);
result.tokens = Dqn_ArenaAllocator_NewArray(arena, jsmntok_t, result.tokens_size, Dqn_ZeroMem::No);
bool Dqn_Jsmn_StringIsValid(Dqn_JsmnString string)
{
bool result = string.str && string.size >= 0;
return result;
}
jsmn_init(&result.parser);
result.tokens_size = jsmn_parse(&result.parser, result.json.str, result.json.size, result.tokens, result.tokens_size);
bool Dqn_Jsmn_IsDigit(char ch)
{
bool result = (ch >= '0' && ch <= '9');
return result;
}
uint64_t Dqn_Jsmn_StringToU64(Dqn_JsmnString string)
{
uint64_t result = 0;
if (!Dqn_Jsmn_StringIsValid(string))
return result;
for (int i = 0; i < string.size; i++)
{
char ch = string.str[i];
if (!Dqn_Jsmn_IsDigit(ch))
return result;
uint64_t digit = ch - '0';
result = (result * 10) + digit;
}
return result;
}
Dqn_Jsmn Dqn_Jsmn_InitWithJSONFile(Dqn_String file, Dqn_ArenaAllocator *arena)
bool operator==(Dqn_JsmnString lhs, Dqn_JsmnString rhs)
{
Dqn_String json = Dqn_File_ArenaReadFileToString(file.str, arena);
bool result = Dqn_Jsmn_StringEq(lhs, rhs);
return result;
}
int Dqn_Jsmn_TokensRequired(char const *json, int size)
{
jsmn_parser parser;
jsmn_init(&parser);
int result = jsmn_parse(&parser, json, size, nullptr, 0);
return result;
}
bool Dqn_Jsmn_InitWithJSONCString(char const *json, int size, Dqn_Jsmn *jsmn)
{
if (!jsmn || !jsmn->tokens || jsmn->tokens_size == 0 || !json)
return false;
assert(jsmn->tokens_size == Dqn_Jsmn_TokensRequired(json, size));
*jsmn = {};
jsmn_init(&jsmn->parser);
jsmn->valid = jsmn_parse(&jsmn->parser, jsmn->json.str, jsmn->json.size, jsmn->tokens, jsmn->tokens_size) > 0;
return jsmn->valid;
}
#if defined(DQN_H)
Dqn_Jsmn Dqn_Jsmn_InitWithJSON(Dqn_JsmnString json, Dqn_ArenaAllocator *arena)
{
Dqn_Jsmn result = {};
result.tokens_size = Dqn_Jsmn_InitWithJSONCString(json.str, json.size, nullptr);
result.tokens = Dqn_ArenaAllocator_NewArray(arena, jsmntok_t, result.tokens_size, Dqn_ZeroMem::No);
Dqn_Jsmn_InitWithJSONCString(json.str, json.size, &result)
return result;
}
Dqn_Jsmn Dqn_Jsmn_InitWithJSONFile(Dqn_JsmnString file, Dqn_ArenaAllocator *arena)
{
Dqn_JsmnString json = Dqn_File_ArenaReadFileToString(file.str, arena);
Dqn_Jsmn result = Dqn_Jsmn_InitWithJSON(json, arena);
return result;
}
#endif // DQN_H
int Dqn_Jsmn_TokenArraySize(jsmntok_t token)
{
@ -411,58 +503,58 @@ int Dqn_Jsmn_TokenArraySize(jsmntok_t token)
return result;
}
Dqn_String Dqn_Jsmn_TokenString(jsmntok_t token, Dqn_String json)
Dqn_JsmnString Dqn_Jsmn_TokenString(jsmntok_t token, Dqn_JsmnString json)
{
Dqn_String result = Dqn_String_Init(json.str + token.start, token.end - token.start);
Dqn_JsmnString result = {json.str + token.start, token.end - token.start};
return result;
}
Dqn_b32 Dqn_Jsmn_TokenBool(jsmntok_t token, Dqn_String json)
bool Dqn_Jsmn_TokenBool(jsmntok_t token, Dqn_JsmnString json)
{
DQN_ASSERT_MSG(token.start < json.size, "%I64d < %I64u", token.start, json.size);
assert(token.start < json.size);
char ch = json.str[token.start];
Dqn_b32 result = ch == 't';
if (!result) { DQN_ASSERT(ch == 'f'); }
bool result = ch == 't';
if (!result) { assert(ch == 'f'); }
return result;
}
Dqn_u64 Dqn_Jsmn_TokenU64(jsmntok_t token, Dqn_String json)
uint64_t Dqn_Jsmn_TokenU64(jsmntok_t token, Dqn_JsmnString json)
{
DQN_ASSERT_MSG(token.start < json.size, "%I64d < %I64u", token.start, json.size);
Dqn_String string = Dqn_String_Init(json.str + token.start, token.end - token.start);
Dqn_u64 result = Dqn_String_ToU64(string);
assert(token.start < json.size);
Dqn_JsmnString string = {json.str + token.start, token.end - token.start};
uint64_t result = Dqn_Jsmn_StringToU64(string);
return result;
}
void Dqn_JsmnErrorHandle__AddError(Dqn_JsmnErrorHandle *err_handle, jsmntok_t token, Dqn_String json, Dqn_JsmnTokenIs expected, char const *file, int line)
void Dqn_JsmnErrorHandle__AddError(Dqn_JsmnErrorHandle *handle, jsmntok_t token, Dqn_JsmnString json, Dqn_JsmnTokenIs expected, char const *file, int line)
{
if (!err_handle)
if (!handle)
return;
if (!err_handle->list.head)
err_handle->list = Dqn_List_InitWithArena<Dqn_JsmnError>(err_handle->arena, 16);
if (handle->errors_size >= DQN_JSMN_ERROR_HANDLE_SIZE)
return;
Dqn_JsmnError *error = Dqn_List_Make(&err_handle->list, 1);
if (error)
{
error->expected = expected;
error->json = json;
error->cpp_file = file;
error->cpp_line = line;
}
Dqn_JsmnError *error = handle->errors + handle->errors_size++;
error->expected = expected;
error->json = json;
error->cpp_file = file;
error->cpp_line = line;
}
Dqn_b32 Dqn_JsmnIterator_Next(Dqn_JsmnIterator *it, Dqn_Jsmn *jsmn_state, Dqn_JsmnIterator *prev_it)
bool Dqn_Jsmn_IteratorNext(Dqn_JsmnIterator *it, Dqn_Jsmn *jsmn_state, Dqn_JsmnIterator *prev_it)
{
if (!it->init)
{
it->init = true;
it->json = jsmn_state->json;
jsmn_iterator_init(&it->jsmn_it, jsmn_state->tokens, jsmn_state->tokens_size, prev_it ? jsmn_iterator_position(&prev_it->jsmn_it) : 0);
if (jsmn_state->valid)
{
it->json = jsmn_state->json;
jsmn_iterator_init(&it->jsmn_it, jsmn_state->tokens, jsmn_state->tokens_size, prev_it ? jsmn_iterator_position(&prev_it->jsmn_it) : 0);
}
}
Dqn_b32 result = false;
if (!Dqn_String_IsValid(it->json) || it->json.size <= 0) {
bool result = false;
if (!Dqn_Jsmn_StringIsValid(it->json) || it->json.size <= 0) {
return result;
}
@ -478,20 +570,20 @@ Dqn_b32 Dqn_JsmnIterator_Next(Dqn_JsmnIterator *it, Dqn_Jsmn *jsmn_state, Dqn_Js
return result;
}
Dqn_String Dqn_JsmnIterator_Key(Dqn_JsmnIterator *it)
Dqn_JsmnString Dqn_Jsmn_IteratorKey(Dqn_JsmnIterator *it)
{
Dqn_String result = {};
Dqn_JsmnString result = {};
if (it && it->key)
result = Dqn_String_Init(it->json.str + it->key->start, it->key->end - it->key->start);
result = {it->json.str + it->key->start, it->key->end - it->key->start};
return result;
}
Dqn_JsmnIterator Dqn_JsmnIterator_FindKey(Dqn_Jsmn *jsmn_state, Dqn_String key, Dqn_JsmnIterator *parent_it)
Dqn_JsmnIterator Dqn_Jsmn_IteratorFindKey(Dqn_Jsmn *jsmn_state, Dqn_JsmnString key, Dqn_JsmnIterator *parent_it)
{
Dqn_JsmnIterator result = {};
for (Dqn_JsmnIterator it = {}; Dqn_JsmnIterator_Next(&it, jsmn_state, parent_it); )
for (Dqn_JsmnIterator it = {}; Dqn_Jsmn_IteratorNext(&it, jsmn_state, parent_it); )
{
Dqn_String it_key = Dqn_Jsmn_TokenString(*it.key, jsmn_state->json);
Dqn_JsmnString it_key = Dqn_Jsmn_TokenString(*it.key, jsmn_state->json);
if (it_key == key)
{
result = it;
@ -502,26 +594,26 @@ Dqn_JsmnIterator Dqn_JsmnIterator_FindKey(Dqn_Jsmn *jsmn_state, Dqn_String key,
return result;
}
static Dqn_b32 Dqn_JsmnIterator__Expect(Dqn_JsmnIterator *it, Dqn_JsmnTokenIs expected, jsmntok_t token, Dqn_JsmnErrorHandle *err_handle, char const *file, unsigned int line)
static bool Dqn_Jsmn_Iterator_Expect(Dqn_JsmnIterator *it, Dqn_JsmnTokenIs expected, jsmntok_t token, Dqn_JsmnErrorHandle *err_handle, char const *file, unsigned int line)
{
Dqn_b32 result = false;
bool result = false;
switch (expected)
{
case Dqn_JsmnTokenIs::Object: result = token.type == JSMN_OBJECT; break;
case Dqn_JsmnTokenIs::Array: result = token.type == JSMN_ARRAY; break;
case Dqn_JsmnTokenIs::String: result = token.type == JSMN_STRING; break;
case Dqn_JsmnTokenIs_Object: result = token.type == JSMN_OBJECT; break;
case Dqn_JsmnTokenIs_Array: result = token.type == JSMN_ARRAY; break;
case Dqn_JsmnTokenIs_String: result = token.type == JSMN_STRING; break;
case Dqn_JsmnTokenIs::Number:
case Dqn_JsmnTokenIs_Number:
{
DQN_ASSERT_MSG(token.start < it->json.size, "%I64d < %I64u", token.start, it->json.size);
assert(token.start < it->json.size);
char ch = it->json.str[token.start];
result = token.type == JSMN_PRIMITIVE && (ch == '-' || Dqn_Char_IsDigit(ch));
result = token.type == JSMN_PRIMITIVE && (ch == '-' || Dqn_Jsmn_IsDigit(ch));
}
break;
case Dqn_JsmnTokenIs::Bool:
case Dqn_JsmnTokenIs_Bool:
{
DQN_ASSERT_MSG(token.start < it->json.size, "%I64d < %I64u", token.start, it->json.size);
assert(token.start < it->json.size);
char ch = it->json.str[token.start];
result = token.type == JSMN_PRIMITIVE && (ch == 't' || ch == 'f');
}
@ -534,34 +626,35 @@ static Dqn_b32 Dqn_JsmnIterator__Expect(Dqn_JsmnIterator *it, Dqn_JsmnTokenIs ex
return result;
}
Dqn_b32 Dqn_JsmnIterator__ExpectValue(Dqn_JsmnIterator *it, Dqn_JsmnTokenIs expected, Dqn_JsmnErrorHandle *err_handle, char const *file, unsigned int line)
bool Dqn_Jsmn_Iterator_ExpectValue(Dqn_JsmnIterator *it, Dqn_JsmnTokenIs expected, Dqn_JsmnErrorHandle *err_handle, char const *file, unsigned int line)
{
Dqn_b32 result = it->value && Dqn_JsmnIterator__Expect(it, expected, *it->value, err_handle, file, line);
bool result = it->value && Dqn_Jsmn_Iterator_Expect(it, expected, *it->value, err_handle, file, line);
return result;
}
Dqn_b32 Dqn_JsmnIterator__ExpectKey(Dqn_JsmnIterator *it, Dqn_JsmnTokenIs expected, Dqn_JsmnErrorHandle *err_handle, char const *file, unsigned int line)
bool Dqn_Jsmn_Iterator_ExpectKey(Dqn_JsmnIterator *it, Dqn_JsmnTokenIs expected, Dqn_JsmnErrorHandle *err_handle, char const *file, unsigned int line)
{
Dqn_b32 result = it->key && Dqn_JsmnIterator__Expect(it, expected, *it->key, err_handle, file, line);
bool result = it->key && Dqn_Jsmn_Iterator_Expect(it, expected, *it->key, err_handle, file, line);
return result;
}
Dqn_String Dqn_JsmnIterator_String(Dqn_JsmnIterator const *it)
Dqn_JsmnString Dqn_Jsmn_IteratorString(Dqn_JsmnIterator const *it)
{
Dqn_String result = {};
if (it->value && it->json.str) result = Dqn_String_Init(it->json.str + it->value->start, it->value->end - it->value->start);
Dqn_JsmnString result = {};
if (it->value && it->json.str)
result = {it->json.str + it->value->start, it->value->end - it->value->start};
return result;
}
Dqn_b32 Dqn_JsmnIterator_Bool(Dqn_JsmnIterator const *it)
bool Dqn_Jsmn_IteratorBool(Dqn_JsmnIterator const *it)
{
Dqn_b32 result = it->value && Dqn_Jsmn_TokenBool(*it->value, it->json);
bool result = it->value && Dqn_Jsmn_TokenBool(*it->value, it->json);
return result;
}
Dqn_u64 Dqn_JsmnIterator_U64(Dqn_JsmnIterator const *it)
uint64_t Dqn_Jsmn_IteratorU64(Dqn_JsmnIterator const *it)
{
Dqn_u64 result = it->value && Dqn_Jsmn_TokenU64(*it->value, it->json);
uint64_t result = it->value && Dqn_Jsmn_TokenU64(*it->value, it->json);
return result;
}

View File

@ -38,26 +38,6 @@
// #define DQN_KECCAK_IMPLEMENTATION
// Define this in one and only one C++ file to enable the implementation
// code of the header file.
//
// #define DQN_KECCAK_MEMCOPY
// Define this macro to override the memcpy implementation and avoid pulling
// in string.h.
//
// #define DQN_KECCAK_MEMCMP
// Define this macro to override the memcmp implementation and avoid pulling
// in string.h.
//
// #define DQN_NO_MALLOC_FUNCTIONS
// Define this macro to disable the non-essential helper functions that use
// malloc.
//
// #define DQN_KECCAK_MALLOC
// Define this macro to override the malloc implementation. This library
// provides helper functions that use malloc if DQN_NO_MALLOC_FUNCTIONS is
// not defined.
//
// #define DQN_KECCAK_ASSERT
// Define this macro to override the assert implementation.
#if !defined(DQN_KECCAK_MEMCOPY)
#include <string.h>
@ -69,18 +49,11 @@
#define DQN_KECCAK_MEMCMP(dest, src, count) memcmp(dest, src, count)
#endif
#if !defined(DQN_NO_MALLOC_FUNCTIONS)
#if !defined(DQN_KECCAK_MALLOC)
#include <stdlib.h>
#define DQN_KECCAK_MALLOC(size) malloc(size)
#endif
#endif
#if !defined(DQN_KECCAK_ASSERT)
#if defined(NDEBUG)
#define DQN_KECCAK_ASSERT(expr)
#else
#define DQN_KECCAK_ASSERT(expr) \
#define DQN_KECCAK_ASSERT(expr) \
do \
{ \
if (!(expr)) \
@ -132,26 +105,18 @@ typedef unsigned int Dqn_Keccak_uint;
// NOTE: SHA3
// -----------------------------------------------------------------------------
// Applies the FIPS 202 SHA3 algorithm on the supplied buffer. The size of
// the returned hash is (bit-rate/8) bytes, i.e. the dest_size must be at least
// the returned hash is (bit-rate/8) bytes, i.e. the dest_size must be atleast
// 32 bytes for SHA-256 and so forth.
// dest_size: The passed in destination buffer must be >= 28 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_SHA3_224(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes28 Dqn_Keccak_SHA3_224_ToBytes28(void *bytes, Dqn_Keccak_u64 bytes_size);
// dest_size: The passed in destination buffer must be >= 32 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_SHA3_256(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes32 Dqn_Keccak_SHA3_256_ToBytes32(void *bytes, Dqn_Keccak_u64 bytes_size);
// dest_size: The passed in destination buffer must be >= 48 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_SHA3_384(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes48 Dqn_Keccak_SHA3_384_ToBytes48(void *bytes, Dqn_Keccak_u64 bytes_size);
// dest_size: The passed in destination buffer must be >= 64 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_SHA3_512(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes64 Dqn_Keccak_SHA3_512_ToBytes64(void *bytes, Dqn_Keccak_u64 bytes_size);
@ -176,24 +141,15 @@ Dqn_KeccakBytes64 Dqn_Keccak_SHA3_512_U8ArrayToBytes64(Dqn_Array<Dqn_Keccak_u8>
// Applies the non-finalized SHA3 algorithm (i.e. a delimited suffix of 0x1
// instead of 0x6 in SHA3). This is the version of the algorithm used by
// Ethereum and Monero as they adopted SHA3 before it was finalized.
// dest_size: The passed in destination buffer must be >= 28 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_224(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes28 Dqn_Keccak_224_ToBytes28(void *bytes, Dqn_Keccak_u64 bytes_size);
// dest_size: The passed in destination buffer must be >= 32 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_256(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes32 Dqn_Keccak_256_ToBytes32(void *bytes, Dqn_Keccak_u64 bytes_size);
// dest_size: The passed in destination buffer must be >= 48 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_384(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes48 Dqn_Keccak_384_ToBytes48(void *bytes, Dqn_Keccak_u64 bytes_size);
// dest_size: The passed in destination buffer must be >= 64 (bytes), otherwise
// the function asserts or does no-op in release.
void Dqn_Keccak_512(void const *src, Dqn_Keccak_u64 src_size, void *dest, int dest_size);
Dqn_KeccakBytes64 Dqn_Keccak_512_ToBytes64(void *bytes, Dqn_Keccak_u64 bytes_size);
@ -217,20 +173,9 @@ Dqn_KeccakBytes64 Dqn_Keccak_512_U8ArrayToBytes64(Dqn_Array<Dqn_Keccak_u8> array
// -----------------------------------------------------------------------------
// Convert a binary buffer into its hex representation into dest. The dest
// buffer must be large enough to contain the hex representation, i.e.
// at least src_size * 2). This function does *not* null-terminate the buffer.
// The returned result does *not* include a leading 0x prefix.
// atleast src_size * 2). This function does *not* null-terminate the buffer.
void Dqn_Keccak_BytesToHex(void const *src, Dqn_Keccak_u64 src_size, char *dest, Dqn_Keccak_u64 dest_size);
#if defined(DQN_NO_MALLOC_FUNCTIONS)
// Convert the src bytes into a null-terminated c-string using malloc. Calls
// into Dqn_Keccak_BytesToHex under the hood.
// src: If src is nullptr, the function returns an empty null-terminated
// string, otherwise, the bytes will be converted and returned as hex.
// return: A null-terminated c-string. This string must be freed by the user
// using the CRT free(..). If malloc fails the returned string is nullptr.
char *Dqn_Keccak_BytesToHexCString(void const *src, Dqn_Keccak_u64 src_size);
#endif // DQN_NO_MALLOC_FUNCTIONS
// Converts a fixed amount of bytes into a hexadecimal string. Helper functions
// that call into Dqn_Keccak_BytesToHex.
// return: The hexadecimal string of the bytes, null-terminated.
@ -878,21 +823,6 @@ void Dqn_Keccak_BytesToHex(void const *src, Dqn_Keccak_u64 src_size, char *dest,
}
}
#if defined(DQN_NO_MALLOC_FUNCTIONS)
char *Dqn_Keccak_BytesToHexCString(void const *src, Dqn_Keccak_u64 src_size)
{
int result_size = (src_size * 2);
char *result = DQN_KECCAK_MALLOC(result_size + 1 /*null-terminator*/);
if (result)
{
Dqn_Keccak_BytesToHex(src, src_size, result, result_size);
result[result_size] = 0;
}
return result;
}
#endif // DQN_NO_MALLOC_FUNCTIONS
Dqn_KeccakString56 Dqn_Keccak_Bytes28ToHex(Dqn_KeccakBytes28 const *bytes)
{
Dqn_KeccakString56 result;
@ -957,7 +887,7 @@ Dqn_KeccakBytes32 Dqn_Keccak_Hex64StringToBytes(Dqn_String hex)
{
DQN_KECCAK_ASSERT(hex.size == 64);
Dqn_KeccakBytes32 result;
Dqn_Hex_HexToBytes(hex.str, hex.size, result.data, sizeof(result));
Dqn_HexToBytes(hex.str, hex.size, result.data, sizeof(result));
return result;
}
#endif // DQN_H

File diff suppressed because it is too large Load Diff