Update naming convention of library
This commit is contained in:
parent
37ae9b0e40
commit
f6ae4ad2a0
@ -1,19 +1,5 @@
|
|||||||
#if !defined(DQN_CPP_FILE_H)
|
#if !defined(DQN_CPP_FILE_H)
|
||||||
#define 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 <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -21,32 +7,22 @@
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// NOTE: Dqn_CppFile: Helper functions to generate formatted CPP files
|
// NOTE: Dqn_CppFile: Helper functions to generate formatted CPP files
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
#if !defined(DQN_CPPF_ASSERT)
|
#define DQN_CPPF_ASSERT(expr) do { if (!(expr)) { *((int *)0) = 0; } } while (0)
|
||||||
#define DQN_CPPF_ASSERT(expr) do { if (!(expr)) { *((volatile int *)0) = 0; } } while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct Dqn_CppFile
|
struct Dqn_CppFile
|
||||||
{
|
{
|
||||||
FILE *file; // The file to output to.
|
FILE *file;
|
||||||
int indent; // The current indent level
|
int indent;
|
||||||
int space_per_indent; // The number of spaces applied per indent. If zero- the functions give a default value.
|
int space_per_indent;
|
||||||
bool append_extra_new_line; // If true, when code blocks are terminated, an additional new line will be appended for whitespacing.
|
bool append_extra_new_line;
|
||||||
};
|
};
|
||||||
|
|
||||||
// return: The number of spaces per indent at this point of invocation. If
|
int Dqn_CppFile_SpacePerIndent(Dqn_CppFile *cpp);
|
||||||
// spaces-per-indent in the CppFile is set to 0 the indent defaults to 4 spaces.
|
|
||||||
int Dqn_CppFile_SpacePerIndent(Dqn_CppFile const *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_LineBeginV (Dqn_CppFile *cpp, char const *fmt, va_list args);
|
||||||
void Dqn_CppFile_LineBegin (Dqn_CppFile *cpp, char const *fmt, ...);
|
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, ...);
|
void Dqn_CppFile_LineEnd (Dqn_CppFile *cpp, char const *fmt, ...);
|
||||||
|
void Dqn_CppFile_LineAdd (Dqn_CppFile *cpp, char const *fmt, ...);
|
||||||
// Create a line in the C++ file and terminate it with a new-line.
|
|
||||||
void Dqn_CppFile_LineV (Dqn_CppFile *cpp, char const *fmt, va_list args);
|
void Dqn_CppFile_LineV (Dqn_CppFile *cpp, char const *fmt, va_list args);
|
||||||
void Dqn_CppFile_Line (Dqn_CppFile *cpp, char const *fmt, ...);
|
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_Indent (Dqn_CppFile *cpp);
|
||||||
void Dqn_CppFile_Unindent (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.
|
// 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
|
// 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.
|
// 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_BeginBlock (Dqn_CppFile *cpp, char const *fmt, ...);
|
||||||
void Dqn_CppFile_EndBlock (Dqn_CppFile *cpp, bool trailing_semicolon, bool new_line_on_next_block);
|
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
|
// 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;
|
int result = cpp->space_per_indent == 0 ? 4 : cpp->space_per_indent;
|
||||||
return result;
|
return result;
|
||||||
@ -110,14 +68,6 @@ void Dqn_CppFile_LineBegin(Dqn_CppFile *cpp, char const *fmt, ...)
|
|||||||
va_end(args);
|
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, ...)
|
void Dqn_CppFile_LineEnd(Dqn_CppFile *cpp, char const *fmt, ...)
|
||||||
{
|
{
|
||||||
if (fmt)
|
if (fmt)
|
||||||
@ -131,6 +81,14 @@ void Dqn_CppFile_LineEnd(Dqn_CppFile *cpp, char const *fmt, ...)
|
|||||||
fputc('\n', cpp->file);
|
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)
|
void Dqn_CppFile_LineV(Dqn_CppFile *cpp, char const *fmt, va_list args)
|
||||||
{
|
{
|
||||||
Dqn_CppFile_LineBeginV(cpp, fmt, args);
|
Dqn_CppFile_LineBeginV(cpp, fmt, args);
|
||||||
|
319
dqn_jsmn.h
319
dqn_jsmn.h
@ -14,10 +14,7 @@
|
|||||||
// code of the header file. This will also automatically enable the JSMN
|
// code of the header file. This will also automatically enable the JSMN
|
||||||
// implementation.
|
// implementation.
|
||||||
//
|
//
|
||||||
|
#include <assert.h>
|
||||||
#if !defined(DQN_H)
|
|
||||||
#error You must include "dqn.h" before including "dqn_jsmn.h"
|
|
||||||
#endif // DQN_H
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// NOTE: JSMN Configuration
|
// NOTE: JSMN Configuration
|
||||||
@ -245,6 +242,22 @@ int jsmn_iterator_next( jsmn_iterator_t *iterator, jsmntok_t **jsmn_identifier,
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Header File
|
// 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 \
|
#define DQN_JSMN_X_MACRO \
|
||||||
DQN_JSMN_X_ENTRY(Object) \
|
DQN_JSMN_X_ENTRY(Object) \
|
||||||
DQN_JSMN_X_ENTRY(Array) \
|
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(Number) \
|
||||||
DQN_JSMN_X_ENTRY(Bool)
|
DQN_JSMN_X_ENTRY(Bool)
|
||||||
|
|
||||||
enum struct Dqn_JsmnTokenIs
|
enum Dqn_JsmnTokenIs
|
||||||
{
|
{
|
||||||
#define DQN_JSMN_X_ENTRY(enum_val) enum_val,
|
#define DQN_JSMN_X_ENTRY(enum_val) Dqn_JsmnTokenIs_##enum_val,
|
||||||
DQN_JSMN_X_MACRO
|
DQN_JSMN_X_MACRO
|
||||||
#undef DQN_JSMN_X_ENTRY
|
#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) DQN_JSMN_STRING(#enum_val),
|
||||||
{
|
DQN_JSMN_X_MACRO
|
||||||
#define DQN_JSMN_X_ENTRY(enum_val) case Dqn_JsmnTokenIs::enum_val: return DQN_STRING(#enum_val);
|
#undef DQN_JSMN_X_ENTRY
|
||||||
DQN_JSMN_X_MACRO
|
|
||||||
#undef DQN_JSMN_X_ENTRY
|
|
||||||
}
|
|
||||||
|
|
||||||
return DQN_STRING("DQN_JSMN_UNHANDLED_ENUM");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_JsmnError
|
struct Dqn_JsmnError
|
||||||
{
|
{
|
||||||
jsmntok_t token;
|
jsmntok_t token;
|
||||||
Dqn_String json;
|
Dqn_JsmnString json;
|
||||||
Dqn_JsmnTokenIs expected;
|
Dqn_JsmnTokenIs expected;
|
||||||
char const *cpp_file; // The file of the .cpp/h source code that triggered the error
|
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
|
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
|
struct Dqn_JsmnErrorHandle
|
||||||
{
|
{
|
||||||
Dqn_ArenaAllocator *arena;
|
Dqn_JsmnError errors[DQN_JSMN_ERROR_HANDLE_SIZE];
|
||||||
Dqn_List<Dqn_JsmnError> list;
|
int errors_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_Jsmn
|
struct Dqn_Jsmn
|
||||||
{
|
{
|
||||||
jsmn_parser parser;
|
bool valid;
|
||||||
Dqn_String json;
|
jsmn_parser parser;
|
||||||
int tokens_size;
|
Dqn_JsmnString json;
|
||||||
jsmntok_t *tokens;
|
int tokens_size;
|
||||||
|
jsmntok_t *tokens;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_JsmnIterator
|
struct Dqn_JsmnIterator
|
||||||
{
|
{
|
||||||
Dqn_b32 init;
|
bool init;
|
||||||
jsmn_iterator_t jsmn_it;
|
jsmn_iterator_t jsmn_it;
|
||||||
Dqn_String json;
|
Dqn_JsmnString json;
|
||||||
jsmntok_t *key;
|
jsmntok_t *key;
|
||||||
jsmntok_t *value;
|
jsmntok_t *value;
|
||||||
|
|
||||||
@ -308,61 +318,81 @@ struct Dqn_JsmnIterator
|
|||||||
int token_index_hint;
|
int token_index_hint;
|
||||||
};
|
};
|
||||||
|
|
||||||
Dqn_Jsmn Dqn_Jsmn_InitWithJSON (Dqn_String json, Dqn_ArenaAllocator *arena);
|
// Calculate the number of tokens required to parse the 'json' input.
|
||||||
Dqn_Jsmn Dqn_Jsmn_InitWithJSONFile (Dqn_String file, Dqn_ArenaAllocator *arena);
|
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.
|
// return: If the token is an array, return the size of the array otherwise -1.
|
||||||
int Dqn_Jsmn_TokenArraySize(jsmntok_t token);
|
int Dqn_Jsmn_TokenArraySize(jsmntok_t token);
|
||||||
Dqn_String Dqn_Jsmn_TokenString(jsmntok_t token, Dqn_String json);
|
Dqn_JsmnString Dqn_Jsmn_TokenString(jsmntok_t token, Dqn_JsmnString json);
|
||||||
Dqn_b32 Dqn_Jsmn_TokenBool(jsmntok_t token, Dqn_String json);
|
bool Dqn_Jsmn_TokenBool(jsmntok_t token, Dqn_JsmnString json);
|
||||||
Dqn_u64 Dqn_Jsmn_TokenU64(jsmntok_t token, Dqn_String 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
|
// 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
|
// shown below. The goal here is to minimise the amount of state the user has to
|
||||||
// manage.
|
// manage.
|
||||||
#if 0
|
#if 0
|
||||||
Dqn_ArenaAllocator arena = {};
|
Dqn_ArenaAllocator arena = {};
|
||||||
Dqn_String json = DQN_STRING(R"({
|
Dqn_JsmnString json = DQN_STRING(R"({
|
||||||
"test": {
|
"test": {
|
||||||
"test2": 0
|
"test2": 0
|
||||||
}
|
}
|
||||||
})");
|
})");
|
||||||
|
|
||||||
Dqn_Jsmn jsmn_state = Dqn_Jsmn_InitWithJSON(json, &arena);
|
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);
|
Dqn_JsmnString key = Dqn_JsmnITerator_Key(&it);
|
||||||
if (Dqn_JsmnIterator_Key(&it) == DQN_STRING("test"))
|
if (key == DQN_STRING("test"))
|
||||||
{
|
{
|
||||||
if (!Dqn_JsmnIterator_ExpectValue(&it, Dqn_JsmnTokenIs::Object, nullptr))
|
if (!Dqn_Jsmn_IteratorExpectValue(&it, Dqn_JsmnTokenIs_Object, nullptr))
|
||||||
continue;
|
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;
|
continue;
|
||||||
|
|
||||||
Dqn_u64 test_2_value = Dqn_JsmnIterator_U64(&obj_it);
|
uint64_t test_2_value = Dqn_Jsmn_IteratorU64(&obj_it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
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);
|
||||||
Dqn_String Dqn_JsmnIterator_Key (Dqn_JsmnIterator *it);
|
Dqn_JsmnString Dqn_Jsmn_IteratorKey(Dqn_JsmnIterator *it);
|
||||||
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);
|
||||||
|
|
||||||
#define Dqn_JsmnIterator_ExpectValue(it, expected, err_handle) Dqn_JsmnIterator__ExpectValue(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_JsmnIterator_ExpectKey(it, expected, err_handle) Dqn_JsmnIterator__ExpectKey(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
|
// 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
|
// 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.
|
// the type requested, a zero initialised value is returned.
|
||||||
Dqn_String Dqn_JsmnIterator_String(Dqn_JsmnIterator const *it);
|
Dqn_JsmnString Dqn_Jsmn_IteratorString(Dqn_JsmnIterator const *it);
|
||||||
Dqn_b32 Dqn_JsmnIterator_Bool (Dqn_JsmnIterator const *it);
|
bool Dqn_Jsmn_IteratorBool(Dqn_JsmnIterator const *it);
|
||||||
Dqn_u64 Dqn_JsmnIterator_U64 (Dqn_JsmnIterator const *it);
|
uint64_t Dqn_Jsmn_IteratorU64(Dqn_JsmnIterator const *it);
|
||||||
|
|
||||||
#define DQN_JSMN_ERROR_HANDLE_DUMP(handle) \
|
#define DQN_JSMN_ERROR_HANDLE_DUMP(handle) \
|
||||||
for (Dqn_ListChunk<Dqn_JsmnError> *chunk = handle.list.head; chunk; chunk = chunk->next) \
|
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_LOG_E("Json parsing error in %s:%d, expected token type: %.*s, token was: %.*s", \
|
||||||
Dqn_Str_FileNameFromPath(error->cpp_file), \
|
Dqn_Str_FileNameFromPath(error->cpp_file), \
|
||||||
error->cpp_line, \
|
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))); \
|
DQN_STRING_FMT(Dqn_Jsmn_TokenString(error->token, error->json))); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
@ -383,27 +413,89 @@ Dqn_u64 Dqn_JsmnIterator_U64 (Dqn_JsmnIterator const *it);
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Implementation
|
// 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 = {};
|
bool result = lhs.size == rhs.size;
|
||||||
result.json = json;
|
for (int i = 0; i < lhs.size && result; i++) result &= lhs.str[i] == rhs.str[i];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
jsmn_init(&result.parser);
|
bool Dqn_Jsmn_StringIsValid(Dqn_JsmnString string)
|
||||||
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 result = string.str && string.size >= 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
jsmn_init(&result.parser);
|
bool Dqn_Jsmn_IsDigit(char ch)
|
||||||
result.tokens_size = jsmn_parse(&result.parser, result.json.str, result.json.size, result.tokens, result.tokens_size);
|
{
|
||||||
|
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;
|
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);
|
Dqn_Jsmn result = Dqn_Jsmn_InitWithJSON(json, arena);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif // DQN_H
|
||||||
|
|
||||||
int Dqn_Jsmn_TokenArraySize(jsmntok_t token)
|
int Dqn_Jsmn_TokenArraySize(jsmntok_t token)
|
||||||
{
|
{
|
||||||
@ -411,58 +503,58 @@ int Dqn_Jsmn_TokenArraySize(jsmntok_t token)
|
|||||||
return result;
|
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;
|
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];
|
char ch = json.str[token.start];
|
||||||
Dqn_b32 result = ch == 't';
|
bool result = ch == 't';
|
||||||
if (!result) { DQN_ASSERT(ch == 'f'); }
|
if (!result) { assert(ch == 'f'); }
|
||||||
return result;
|
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);
|
assert(token.start < json.size);
|
||||||
Dqn_String string = Dqn_String_Init(json.str + token.start, token.end - token.start);
|
Dqn_JsmnString string = {json.str + token.start, token.end - token.start};
|
||||||
Dqn_u64 result = Dqn_String_ToU64(string);
|
uint64_t result = Dqn_Jsmn_StringToU64(string);
|
||||||
return result;
|
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;
|
return;
|
||||||
|
|
||||||
if (!err_handle->list.head)
|
if (handle->errors_size >= DQN_JSMN_ERROR_HANDLE_SIZE)
|
||||||
err_handle->list = Dqn_List_InitWithArena<Dqn_JsmnError>(err_handle->arena, 16);
|
return;
|
||||||
|
|
||||||
Dqn_JsmnError *error = Dqn_List_Make(&err_handle->list, 1);
|
Dqn_JsmnError *error = handle->errors + handle->errors_size++;
|
||||||
if (error)
|
error->expected = expected;
|
||||||
{
|
error->json = json;
|
||||||
error->expected = expected;
|
error->cpp_file = file;
|
||||||
error->json = json;
|
error->cpp_line = line;
|
||||||
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)
|
if (!it->init)
|
||||||
{
|
{
|
||||||
it->init = true;
|
it->init = true;
|
||||||
it->json = jsmn_state->json;
|
if (jsmn_state->valid)
|
||||||
jsmn_iterator_init(&it->jsmn_it, jsmn_state->tokens, jsmn_state->tokens_size, prev_it ? jsmn_iterator_position(&prev_it->jsmn_it) : 0);
|
{
|
||||||
|
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;
|
bool result = false;
|
||||||
if (!Dqn_String_IsValid(it->json) || it->json.size <= 0) {
|
if (!Dqn_Jsmn_StringIsValid(it->json) || it->json.size <= 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,20 +570,20 @@ Dqn_b32 Dqn_JsmnIterator_Next(Dqn_JsmnIterator *it, Dqn_Jsmn *jsmn_state, Dqn_Js
|
|||||||
return result;
|
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)
|
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;
|
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 = {};
|
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)
|
if (it_key == key)
|
||||||
{
|
{
|
||||||
result = it;
|
result = it;
|
||||||
@ -502,26 +594,26 @@ Dqn_JsmnIterator Dqn_JsmnIterator_FindKey(Dqn_Jsmn *jsmn_state, Dqn_String key,
|
|||||||
return result;
|
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)
|
switch (expected)
|
||||||
{
|
{
|
||||||
case Dqn_JsmnTokenIs::Object: result = token.type == JSMN_OBJECT; break;
|
case Dqn_JsmnTokenIs_Object: result = token.type == JSMN_OBJECT; break;
|
||||||
case Dqn_JsmnTokenIs::Array: result = token.type == JSMN_ARRAY; break;
|
case Dqn_JsmnTokenIs_Array: result = token.type == JSMN_ARRAY; break;
|
||||||
case Dqn_JsmnTokenIs::String: result = token.type == JSMN_STRING; 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];
|
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;
|
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];
|
char ch = it->json.str[token.start];
|
||||||
result = token.type == JSMN_PRIMITIVE && (ch == 't' || ch == 'f');
|
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;
|
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;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dqn_String Dqn_JsmnIterator_String(Dqn_JsmnIterator const *it)
|
Dqn_JsmnString Dqn_Jsmn_IteratorString(Dqn_JsmnIterator const *it)
|
||||||
{
|
{
|
||||||
Dqn_String result = {};
|
Dqn_JsmnString result = {};
|
||||||
if (it->value && it->json.str) result = Dqn_String_Init(it->json.str + it->value->start, it->value->end - it->value->start);
|
if (it->value && it->json.str)
|
||||||
|
result = {it->json.str + it->value->start, it->value->end - it->value->start};
|
||||||
return result;
|
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;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
78
dqn_keccak.h
78
dqn_keccak.h
@ -38,26 +38,6 @@
|
|||||||
// #define DQN_KECCAK_IMPLEMENTATION
|
// #define DQN_KECCAK_IMPLEMENTATION
|
||||||
// Define this in one and only one C++ file to enable the implementation
|
// Define this in one and only one C++ file to enable the implementation
|
||||||
// code of the header file.
|
// 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)
|
#if !defined(DQN_KECCAK_MEMCOPY)
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -69,18 +49,11 @@
|
|||||||
#define DQN_KECCAK_MEMCMP(dest, src, count) memcmp(dest, src, count)
|
#define DQN_KECCAK_MEMCMP(dest, src, count) memcmp(dest, src, count)
|
||||||
#endif
|
#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(DQN_KECCAK_ASSERT)
|
||||||
#if defined(NDEBUG)
|
#if defined(NDEBUG)
|
||||||
#define DQN_KECCAK_ASSERT(expr)
|
#define DQN_KECCAK_ASSERT(expr)
|
||||||
#else
|
#else
|
||||||
#define DQN_KECCAK_ASSERT(expr) \
|
#define DQN_KECCAK_ASSERT(expr) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
if (!(expr)) \
|
if (!(expr)) \
|
||||||
@ -132,26 +105,18 @@ typedef unsigned int Dqn_Keccak_uint;
|
|||||||
// NOTE: SHA3
|
// NOTE: SHA3
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Applies the FIPS 202 SHA3 algorithm on the supplied buffer. The size of
|
// 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.
|
// 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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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
|
// 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
|
// 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.
|
// 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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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);
|
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
|
// Convert a binary buffer into its hex representation into dest. The dest
|
||||||
// buffer must be large enough to contain the hex representation, i.e.
|
// 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.
|
// atleast src_size * 2). This function does *not* null-terminate the buffer.
|
||||||
// The returned result does *not* include a leading 0x prefix.
|
|
||||||
void Dqn_Keccak_BytesToHex(void const *src, Dqn_Keccak_u64 src_size, char *dest, Dqn_Keccak_u64 dest_size);
|
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
|
// Converts a fixed amount of bytes into a hexadecimal string. Helper functions
|
||||||
// that call into Dqn_Keccak_BytesToHex.
|
// that call into Dqn_Keccak_BytesToHex.
|
||||||
// return: The hexadecimal string of the bytes, null-terminated.
|
// 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 Dqn_Keccak_Bytes28ToHex(Dqn_KeccakBytes28 const *bytes)
|
||||||
{
|
{
|
||||||
Dqn_KeccakString56 result;
|
Dqn_KeccakString56 result;
|
||||||
@ -957,7 +887,7 @@ Dqn_KeccakBytes32 Dqn_Keccak_Hex64StringToBytes(Dqn_String hex)
|
|||||||
{
|
{
|
||||||
DQN_KECCAK_ASSERT(hex.size == 64);
|
DQN_KECCAK_ASSERT(hex.size == 64);
|
||||||
Dqn_KeccakBytes32 result;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // DQN_H
|
#endif // DQN_H
|
||||||
|
552
dqn_tests.cpp
552
dqn_tests.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user