dqn: Introduce arena catalog
This commit is contained in:
		
							parent
							
								
									7fa4af549f
								
							
						
					
					
						commit
						cb8323dfc8
					
				
							
								
								
									
										212
									
								
								dqn_cpp_file.h
									
									
									
									
									
								
							
							
						
						
									
										212
									
								
								dqn_cpp_file.h
									
									
									
									
									
								
							| @ -7,63 +7,149 @@ | |||||||
| #include <stdarg.h> /// va_list... | #include <stdarg.h> /// va_list... | ||||||
| #include <assert.h> /// assert | #include <assert.h> /// assert | ||||||
| 
 | 
 | ||||||
| struct Dqn_CppFile /// Maintains state for printing C++ style formatted files
 | typedef struct Dqn_CppFile { ///< Maintains state for printing C++ style formatted files
 | ||||||
| { |     FILE          *file;                ///< (Write) File to print to
 | ||||||
|     FILE *file;             ///< File to print to
 |  | ||||||
|     int            indent;              ///< Current indent level of the printer
 |     int            indent;              ///< Current indent level of the printer
 | ||||||
|     int   space_per_indent; ///< Number of spaces per indent
 |     int            space_per_indent;    ///< (Write) Number of spaces per indent
 | ||||||
|     bool  k_and_r_indent;   ///< K&R style indenting when opening a block scope, e.g. "{\n" vs "\n{"
 |     unsigned char  if_chain[256]; ///
 | ||||||
| }; |     unsigned char  if_chain_size; ///
 | ||||||
|  | } Dqn_CppFile; | ||||||
| 
 | 
 | ||||||
| /// Print the format string indented and terminate the string with a new-line.
 | /// Print the format string indented and terminate the string with a new-line.
 | ||||||
| void Dqn_CppFLineV(Dqn_CppFile *cpp, char const *fmt, va_list args); | void Dqn_CppLineV(Dqn_CppFile *cpp, char const *fmt, va_list args); | ||||||
| void Dqn_CppFLine(Dqn_CppFile *cpp, char const *fmt, ...); | void Dqn_CppLine(Dqn_CppFile *cpp, char const *fmt, ...); | ||||||
| 
 | 
 | ||||||
| /// Print the format string indented
 | /// Print the format string indented
 | ||||||
| void Dqn_CppFPrintV(Dqn_CppFile *cpp, char const *fmt, va_list args); | void Dqn_CppPrintV(Dqn_CppFile *cpp, char const *fmt, va_list args); | ||||||
| void Dqn_CppFPrint(Dqn_CppFile *cpp, char const *fmt, ...); | void Dqn_CppPrint(Dqn_CppFile *cpp, char const *fmt, ...); | ||||||
| 
 | 
 | ||||||
| /// Print the format string
 | /// Print the format string
 | ||||||
| #define Dqn_CppFAppend(cpp, fmt, ...) vfprintf(cpp->file, fmt, ##__VAR_ARGS__) | #define Dqn_CppAppend(cpp, fmt, ...) fprintf((cpp)->file, fmt, ##__VA_ARGS__) | ||||||
|  | #define Dqn_CppAppendV(cpp, fmt, args) vfprintf((cpp)->file, fmt, args) | ||||||
| 
 | 
 | ||||||
| /// End the current line, useful after CppFPrint and CppFAppend
 | /// End the current line, useful after CppPrint and CppAppend
 | ||||||
| #define Dqn_CppFEndLine(cpp) fputc('\n', (cpp)->file) | #define Dqn_CppNewLine(cpp) fputc('\n', (cpp)->file) | ||||||
| 
 | 
 | ||||||
| /// Manually modify the indent level
 | /// Manually modify the indent level
 | ||||||
| #define Dqn_CppFIndent(cpp) (cpp)->indent++; | #define Dqn_CppIndent(cpp) (cpp)->indent++ | ||||||
| #define Dqn_CppFUnindent(cpp) (cpp)->indent--; assert(cpp->indent >= 0) | #define Dqn_CppUnindent(cpp) (cpp)->indent--; assert((cpp)->indent >= 0) | ||||||
|  | 
 | ||||||
|  | /// Block scope functions that execute a function on entry and exit of the 
 | ||||||
|  | /// scope by exploiting the comma operator and a for loop.
 | ||||||
|  | ///
 | ||||||
|  | /// @code
 | ||||||
|  | /// Dqn_CppEnumBlock(cpp, "abc") {
 | ||||||
|  | ///     printf("Hello world!");
 | ||||||
|  | /// }
 | ||||||
|  | ///
 | ||||||
|  | /// // Is equivalent to
 | ||||||
|  | ///
 | ||||||
|  | /// Dqn_CppBeginBlock(cpp, "abc");
 | ||||||
|  | /// printf("Hello world!");
 | ||||||
|  | /// Dqn_CppEndEnumBlock(cpp);
 | ||||||
|  | /// @endcode
 | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppEnumBlock(cpp, fmt, ...)                          \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndEnumBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppForBlock(cpp, fmt, ...)                           \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginBlock(cpp, false /*append*/, "for (" fmt ")", ##__VA_ARGS__), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndForBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppWhileBlock(cpp, fmt, ...)                           \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginBlock(cpp, false /*append*/, "while (" fmt ")", ##__VA_ARGS__), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndForBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppIfOrElseIfBlock(cpp, fmt, ...)             \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginIfOrElseIfBlock(cpp, fmt, ##__VA_ARGS__), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndIfOrElseIfBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppElseBlock(cpp)                             \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginElseBlock(cpp), true);          \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndElseBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppFuncBlock(cpp, fmt, ...)                          \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndFuncBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppStructBlock(cpp, fmt, ...)                        \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginBlock(cpp, false /*append*/, "struct " fmt, ##__VA_ARGS__), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndStructBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppSwitchBlock(cpp, fmt, ...)                        \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) =            \ | ||||||
|  |              (Dqn_CppBeginBlock(cpp, false /*append*/, "switch (" fmt ")", ##__VA_ARGS__), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                  \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppEndSwitchBlock(cpp), false)) | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppIfChain(cpp)                                                             \ | ||||||
|  |     for (bool DQN_CPP_TOKEN_PASTE_(once_, __LINE__) = (Dqn_CppBeginIfChain(cpp), true); \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__);                                         \ | ||||||
|  |          DQN_CPP_TOKEN_PASTE_(once_, __LINE__)      = (Dqn_CppEndIfChain(cpp), false)) | ||||||
| 
 | 
 | ||||||
| /// Print the format string followed by a "{" and enter a new line whilst
 | /// Print the format string followed by a "{" and enter a new line whilst
 | ||||||
| /// increasing the indent level after the brace.
 | /// increasing the indent level after the brace.
 | ||||||
| void Dqn_CppFBeginBlock(Dqn_CppFile *cpp, char const *fmt, ...); | void Dqn_CppBeginBlock (Dqn_CppFile *cpp, bool append, char const *fmt, ...); | ||||||
| void Dqn_CppFEndBlock  (Dqn_CppFile *cpp, bool trailing_semicolon, bool new_line_on_next_block); | void Dqn_CppBeginBlockV(Dqn_CppFile *cpp, bool append, char const *fmt, va_list args); | ||||||
|  | void Dqn_CppEndBlock   (Dqn_CppFile *cpp); | ||||||
| 
 | 
 | ||||||
| /// End a block, specifically for the following language constructs.
 | /// Begin/End a block, specifically for the following language constructs.
 | ||||||
| #define Dqn_CppFEndEnumBlock(cpp)   Dqn_CppFEndBlock(cpp, true  /*trailing_semicolon*/, true  /*new_line_on_next_block*/) | #define Dqn_CppBeginEnumBlock(cpp, fmt, ...)   Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__) | ||||||
| #define Dqn_CppFEndForBlock(cpp)    Dqn_CppFEndBlock(cpp, false /*trailing_semicolon*/, false /*new_line_on_next_block*/) | #define Dqn_CppEndEnumBlock(cpp)               Dqn_CppEndBlock(cpp), Dqn_CppAppend(cpp, ";\n") | ||||||
| #define Dqn_CppFEndIfBlock(cpp)     Dqn_CppFEndBlock(cpp, false /*trailing_semicolon*/, false /*new_line_on_next_block*/) | 
 | ||||||
| #define Dqn_CppFEndFuncBlock(cpp)   Dqn_CppFEndBlock(cpp, false /*trailing_semicolon*/, true  /*new_line_on_next_block*/) | #define Dqn_CppBeginForBlock(cpp, fmt, ...)    Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__) | ||||||
| #define Dqn_CppFEndStructBlock(cpp) Dqn_CppFEndBlock(cpp, true  /*trailing_semicolon*/, true  /*new_line_on_next_block*/) | #define Dqn_CppEndForBlock(cpp)                Dqn_CppEndBlock(cpp), Dqn_CppAppend(cpp, "\n") | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppBeginFuncBlock(cpp, fmt, ...)   Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__) | ||||||
|  | #define Dqn_CppEndFuncBlock(cpp)               Dqn_CppEndBlock(cpp), Dqn_CppAppend(cpp, "\n") | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppBeginStructBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__) | ||||||
|  | #define Dqn_CppEndStructBlock(cpp)             Dqn_CppEndBlock(cpp), Dqn_CppAppend(cpp, ";\n") | ||||||
|  | 
 | ||||||
|  | #define Dqn_CppBeginSwitchBlock(cpp, fmt, ...) Dqn_CppBeginBlock(cpp, false /*append*/, fmt, ##__VA_ARGS__) | ||||||
|  | #define Dqn_CppEndSwitchBlock(cpp)             Dqn_CppEndBlock(cpp), Dqn_CppAppend(cpp, "\n") | ||||||
|  | 
 | ||||||
|  | void    Dqn_CppBeginIfOrElseIfBlock            (Dqn_CppFile *cpp, char const *fmt, ...); | ||||||
|  | #define Dqn_CppEndIfOrElseIfBlock(cpp)         Dqn_CppEndBlock(cpp) | ||||||
|  | 
 | ||||||
|  | void    Dqn_CppBeginElseBlock                  (Dqn_CppFile *cpp); | ||||||
|  | #define Dqn_CppEndElseBlock(cpp)               Dqn_CppEndBlock(cpp) | ||||||
|  | 
 | ||||||
|  | #define DQN_CPP_TOKEN_PASTE2_(x, y) x ## y | ||||||
|  | #define DQN_CPP_TOKEN_PASTE_(x, y) DQN_CPP_TOKEN_PASTE2_(x, y) | ||||||
| #endif // DQN_CPP_FILE_H
 | #endif // DQN_CPP_FILE_H
 | ||||||
| 
 | 
 | ||||||
| #if defined(DQN_CPP_FILE_IMPLEMENTATION) | #if defined(DQN_CPP_FILE_IMPLEMENTATION) | ||||||
| // NOTE: Dqn_CppFile Implementation
 | void Dqn_CppLineV(Dqn_CppFile *cpp, char const *fmt, va_list args) | ||||||
| // =============================================================================
 |  | ||||||
| void Dqn_CppFLineV(Dqn_CppFile *cpp, char const *fmt, va_list args) |  | ||||||
| { | { | ||||||
|     Dqn_CppFPrintV(cpp, fmt, args); |     Dqn_CppPrintV(cpp, fmt, args); | ||||||
|     Dqn_CppFLineEnd(cpp, nullptr); |     Dqn_CppNewLine(cpp); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_CppFLine(Dqn_CppFile *cpp, char const *fmt, ...) | void Dqn_CppLine(Dqn_CppFile *cpp, char const *fmt, ...) | ||||||
| { | { | ||||||
|     va_list args; |     va_list args; | ||||||
|     va_start(args, fmt); |     va_start(args, fmt); | ||||||
|     Dqn_CppFLineV(cpp, fmt, args); |     Dqn_CppLineV(cpp, fmt, args); | ||||||
|     va_end(args); |     va_end(args); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_CppFPrintV(Dqn_CppFile *cpp, char const *fmt, va_list args) | void Dqn_CppPrintV(Dqn_CppFile *cpp, char const *fmt, va_list args) | ||||||
| { | { | ||||||
|     int space_per_indent = cpp->space_per_indent == 0 ? 4 : cpp->space_per_indent; |     int space_per_indent = cpp->space_per_indent == 0 ? 4 : cpp->space_per_indent; | ||||||
|     int spaces           = fmt ? (cpp->indent * space_per_indent) : 0; |     int spaces           = fmt ? (cpp->indent * space_per_indent) : 0; | ||||||
| @ -71,29 +157,71 @@ void Dqn_CppFPrintV(Dqn_CppFile *cpp, char const *fmt, va_list args) | |||||||
|     vfprintf(cpp->file, fmt, args); |     vfprintf(cpp->file, fmt, args); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_CppFPrint(Dqn_CppFile *cpp, char const *fmt, ...) | void Dqn_CppPrint(Dqn_CppFile *cpp, char const *fmt, ...) | ||||||
| { | { | ||||||
|     va_list args; |     va_list args; | ||||||
|     va_start(args, fmt); |     va_start(args, fmt); | ||||||
|     Dqn_CppFPrintV(cpp, fmt, args); |     Dqn_CppPrintV(cpp, fmt, args); | ||||||
|     va_end(args); |     va_end(args); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_CppFBeginBlock(Dqn_CppFile *cpp, char const *fmt, ...) | void Dqn_CppBeginBlock(Dqn_CppFile *cpp, bool append, char const *fmt, ...) | ||||||
| { | { | ||||||
|     va_list args; |     va_list args; | ||||||
|     va_start(args, fmt); |     va_start(args, fmt); | ||||||
|     Dqn_CppFLineV(cpp, fmt, args); |     Dqn_CppBeginBlockV(cpp, append, fmt, args); | ||||||
|     va_end(args); |     va_end(args); | ||||||
|     Dqn_CppFPrint(cpp, "%s", cpp->k_and_r_indent ? "{\n" : "\n{"); |  | ||||||
|     Dqn_CppFIndent(cpp); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_CppFEndBlock(Dqn_CppFile *cpp, bool trailing_semicolon, bool new_line_on_next_block) | void Dqn_CppBeginBlockV(Dqn_CppFile *cpp, bool append, char const *fmt, va_list args) | ||||||
| { | { | ||||||
|     Dqn_CppFUnindent(cpp); |     if (append) | ||||||
|     Dqn_CppFLine(cpp, trailing_semicolon ? "};" : "}"); |         Dqn_CppAppendV(cpp, fmt, args); | ||||||
|     if (new_line_on_next_block) |     else | ||||||
|         fputc('\n', cpp->file); |         Dqn_CppPrintV(cpp, fmt, args); | ||||||
|  |     Dqn_CppAppend(cpp, " {\n"); | ||||||
|  |     Dqn_CppIndent(cpp); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void Dqn_CppEndBlock(Dqn_CppFile *cpp) | ||||||
|  | { | ||||||
|  |     Dqn_CppUnindent(cpp); | ||||||
|  |     Dqn_CppPrint(cpp, "}"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Dqn_CppBeginIfOrElseIfBlock(Dqn_CppFile *cpp, char const *fmt, ...) | ||||||
|  | { | ||||||
|  |     va_list args; | ||||||
|  |     va_start(args, fmt); | ||||||
|  |     if (cpp->if_chain[cpp->if_chain_size - 1] == 0) | ||||||
|  |         Dqn_CppPrint(cpp, "if"); | ||||||
|  |     else | ||||||
|  |         Dqn_CppAppend(cpp, " else if"); | ||||||
|  | 
 | ||||||
|  |     Dqn_CppAppend(cpp, " ("); | ||||||
|  |     Dqn_CppAppendV(cpp, fmt, args); | ||||||
|  |     Dqn_CppAppend(cpp, ") {\n"); | ||||||
|  |     Dqn_CppIndent(cpp); | ||||||
|  |     va_end(args); | ||||||
|  |     cpp->if_chain[cpp->if_chain_size - 1]++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Dqn_CppBeginElseBlock(Dqn_CppFile *cpp) | ||||||
|  | { | ||||||
|  |     if (cpp->if_chain[cpp->if_chain_size - 1] >= 1) | ||||||
|  |         Dqn_CppBeginBlock(cpp, true /*append*/, " else"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Dqn_CppBeginIfChain(Dqn_CppFile *cpp) | ||||||
|  | { | ||||||
|  |     assert(cpp->if_chain_size < sizeof(cpp->if_chain)/sizeof(cpp->if_chain[0])); | ||||||
|  |     cpp->if_chain_size++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Dqn_CppEndIfChain(Dqn_CppFile *cpp) | ||||||
|  | { | ||||||
|  |     if (cpp->if_chain[cpp->if_chain_size - 1] >= 1) | ||||||
|  |         Dqn_CppNewLine(cpp); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #endif // DQN_CPP_FILE_IMPLEMENTATION
 | #endif // DQN_CPP_FILE_IMPLEMENTATION
 | ||||||
|  | |||||||
							
								
								
									
										727
									
								
								dqn_json.h
									
									
									
									
									
								
							
							
						
						
									
										727
									
								
								dqn_json.h
									
									
									
									
									
								
							| @ -11,83 +11,6 @@ void *Dqn_JSON_ArenaAllocFunc(void *user_data, size_t count); | |||||||
| char const *Dqn_JSON_TypeEnumCString(json_type_e type, size_t *size); | char const *Dqn_JSON_TypeEnumCString(json_type_e type, size_t *size); | ||||||
| bool Dqn_JSON_String8Cmp(json_string_s const *lhs, Dqn_String8 rhs); | bool Dqn_JSON_String8Cmp(json_string_s const *lhs, Dqn_String8 rhs); | ||||||
| 
 | 
 | ||||||
| #define Dqn_JSON_RecordIgnoredObjElement(element, flags) Dqn_JSON_RecordIgnoredObjElement_(element, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| void    Dqn_JSON_RecordIgnoredObjElement_(json_object_element_s const *element, size_t flags, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define Dqn_JSON_RecordIgnoredArrayElement(element, flags) Dqn_JSON_RecordIgnoredArrayElement_(element, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| void    Dqn_JSON_RecordIgnoredArrayElement_(json_array_element_s const *element, size_t flags, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define Dqn_JSON_RecordIgnoredValue(value, flags) Dqn_JSON_RecordIgnoredValue_(value, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| void    Dqn_JSON_RecordIgnoredValue_(json_value_s const *value, size_t flags, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_ValueCheck
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| #define        Dqn_JSON_ValueCheck(val, type, flags, require) Dqn_JSON_ValueCheck(val, type, flags, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_value_s  *Dqn_JSON_ValueCheck_(json_value_s *val, json_type_e type, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ValueCheckObj(val, flags, require) Dqn_JSON_ValueCheckObj_(val, flags, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_object_s *Dqn_JSON_ValueCheckObj_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ValueCheckArray(val, flags, require) Dqn_JSON_ValueCheckArray_(val, flags, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_array_s  *Dqn_JSON_ValueCheckArray_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ValueCheckString(val, flags, require) Dqn_JSON_ValueCheckString_(val, flags, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_string_s *Dqn_JSON_ValueCheckString_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ValueCheckNumber(val, flags, require) Dqn_JSON_ValueCheckNumber_(val, flags, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_number_s *Dqn_JSON_ValueCheckNumber_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define       Dqn_JSON_ValueCheckBool(val, flags, require) Dqn_JSON_ValueCheckBool_(val, flags, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_value_s *Dqn_JSON_ValueCheckBool_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_ValueRequire
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| #define Dqn_JSON_ValueRequire(val, type, flags) Dqn_JSON_ValueCheck(val, type,    flags, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ValueRequireObj(val, flags) Dqn_JSON_ValueCheckObj_(val,       flags, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ValueRequireArray(val, flags) Dqn_JSON_ValueCheckArray_(val,   flags, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ValueRequireString(val, flags) Dqn_JSON_ValueCheckString_(val, flags, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ValueRequireNumber(val, flags) Dqn_JSON_ValueCheckNumber_(val, flags, true /*require*/ DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ValueRequireBool(val, flags) Dqn_JSON_ValueCheckBool_(val,     flags, true /*require*/ DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_ObjElementCheck
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| #define        Dqn_JSON_ObjElementCheckNamed(element, type, key, flags) Dqn_JSON_ObjElementCheckNamed_(element, type, key, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_value_s  *Dqn_JSON_ObjElementCheckNamed_(json_object_element_s *element, json_type_e type, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ObjElementCheckNamedObj(element, key, flags) Dqn_JSON_ObjElementCheckNamedObj_(element, key, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_object_s *Dqn_JSON_ObjElementCheckNamedObj_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ObjElementCheckNamedArray(element, key, flags) Dqn_JSON_ObjElementCheckNamedArray_(element, key, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_array_s  *Dqn_JSON_ObjElementCheckNamedArray_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ObjElementCheckNamedString(element, key, flags) Dqn_JSON_ObjElementCheckNamedString_(element, key, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_string_s *Dqn_JSON_ObjElementCheckNamedString_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ObjElementCheckNamedNumber(element, key, flags) Dqn_JSON_ObjElementCheckNamedNumber_(element, key, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_number_s *Dqn_JSON_ObjElementCheckNamedNumber_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_ObjElementCheckNamedBool(element, key, flags) Dqn_JSON_ObjElementCheckNamedBool_(element, key, flags, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_value_s  *Dqn_JSON_ObjElementCheckNamedBool_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_ObjElementIs
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| #define Dqn_JSON_ObjElementIsNamed(element, type, key) Dqn_JSON_ObjElementCheckNamed_(element, type,  key, 0 /*flags*/, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementIsNamedObj(element, key)    Dqn_JSON_ObjElementCheckNamedObj_(element,    key, 0 /*flags*/, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementIsNamedArray(element, key)  Dqn_JSON_ObjElementCheckNamedArray_(element,  key, 0 /*flags*/, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementIsNamedString(element, key) Dqn_JSON_ObjElementCheckNamedString_(element, key, 0 /*flags*/, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementIsNamedNumber(element, key) Dqn_JSON_ObjElementCheckNamedNumber_(element, key, 0 /*flags*/, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementIsNamedBool(element, key)   Dqn_JSON_ObjElementCheckNamedBool_(element,   key, 0 /*flags*/, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_ObjElementRequire
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| #define Dqn_JSON_ObjElementRequireNamed(element, type, key)  Dqn_JSON_ObjElementCheckNamed_(element, type,  key, 0 /*flags*/, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementRequireNamedObj(element, key)    Dqn_JSON_ObjElementCheckNamedObj_(element,    key, 0 /*flags*/, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementRequireNamedArray(element, key)  Dqn_JSON_ObjElementCheckNamedArray_(element,  key, 0 /*flags*/, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementRequireNamedString(element, key) Dqn_JSON_ObjElementCheckNamedString_(element, key, 0 /*flags*/, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementRequireNamedNumber(element, key) Dqn_JSON_ObjElementCheckNamedNumber_(element, key, 0 /*flags*/, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_ObjElementRequireNamedBool(element, key)   Dqn_JSON_ObjElementCheckNamedBool_(element,   key, 0 /*flags*/, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_Iterator
 | // NOTE: Dqn_JSON_Iterator
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| enum Dqn_JSONIteratorEntryType | enum Dqn_JSONIteratorEntryType | ||||||
| @ -115,91 +38,63 @@ struct Dqn_JSONIterator | |||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_IteratorPush/Pop
 | // NOTE: Dqn_JSON_IteratorPush/Pop
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| bool Dqn_JSON_IteratorPushObjElement(Dqn_JSONIterator *state, json_object_element_s *element); | bool Dqn_JSON_IteratorPushObjElement(Dqn_JSONIterator *it, json_object_element_s *element); | ||||||
| bool Dqn_JSON_IteratorPushObj(Dqn_JSONIterator *state, json_object_s *obj); | bool Dqn_JSON_IteratorPushObj(Dqn_JSONIterator *it, json_object_s *obj); | ||||||
| bool Dqn_JSON_IteratorPushArrayElement(Dqn_JSONIterator *state, json_array_element_s *element); | bool Dqn_JSON_IteratorPushArrayElement(Dqn_JSONIterator *it, json_array_element_s *element); | ||||||
| bool Dqn_JSON_IteratorPushArray(Dqn_JSONIterator *state, json_array_s *array); | bool Dqn_JSON_IteratorPushArray(Dqn_JSONIterator *it, json_array_s *array); | ||||||
| void Dqn_JSON_IteratorPop(Dqn_JSONIterator *state); | bool Dqn_JSON_IteratorPushValue(Dqn_JSONIterator *it, json_value_s *value); | ||||||
|  | void Dqn_JSON_IteratorPop(Dqn_JSONIterator *it); | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_Iterator tree navigation
 | // NOTE: Dqn_JSON_Iterator tree navigation
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| json_value_s *Dqn_JSON_IteratorPushKey(Dqn_JSONIterator *state); | json_value_s *Dqn_JSON_IteratorPushCurrValue(Dqn_JSONIterator *it); | ||||||
| bool Dqn_JSON_IteratorNextField(Dqn_JSONIterator *state); | bool Dqn_JSON_IteratorNext(Dqn_JSONIterator *it); | ||||||
| 
 | 
 | ||||||
| #define Dqn_JSON_IteratorErrorUnrecognisedKey(state) Dqn_JSON_IteratorErrorUnrecognisedKey_(state, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | #define Dqn_JSON_IteratorErrorUnrecognisedKey(it) Dqn_JSON_IteratorErrorUnrecognisedKey_(it, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | ||||||
| void Dqn_JSON_IteratorErrorUnrecognisedKey_(Dqn_JSONIterator *state, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); | void Dqn_JSON_IteratorErrorUnrecognisedKey_(Dqn_JSONIterator *it, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); | ||||||
| 
 | 
 | ||||||
| #define Dqn_JSON_IteratorPushKeyIterateThenPop(state) \ | #define Dqn_JSON_IteratorPushCurrValueIterateThenPop(it) \ | ||||||
|     for(void *DQN_UNIQUE_NAME(ptr) = Dqn_JSON_IteratorPushKey(state); DQN_UNIQUE_NAME(ptr); Dqn_JSON_IteratorPop(state), DQN_UNIQUE_NAME(ptr) = nullptr) \ |     for(void *DQN_UNIQUE_NAME(ptr) = Dqn_JSON_IteratorPushCurrValue(it); DQN_UNIQUE_NAME(ptr); Dqn_JSON_IteratorPop(it), DQN_UNIQUE_NAME(ptr) = nullptr) \ | ||||||
|         while (Dqn_JSON_IteratorNextField(state)) |         while (Dqn_JSON_IteratorNext(it)) | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_IteratorCurr
 | // NOTE: Dqn_JSON_IteratorCurr
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| Dqn_JSONIteratorEntry *Dqn_JSON_IteratorCurr(Dqn_JSONIterator *state); | Dqn_JSONIteratorEntry *Dqn_JSON_IteratorCurr(Dqn_JSONIterator *it); | ||||||
| json_value_s          *Dqn_JSON_IteratorCurrValue(Dqn_JSONIterator *state); | json_value_s          *Dqn_JSON_IteratorCurrValue(Dqn_JSONIterator *it); | ||||||
| json_object_element_s *Dqn_JSON_IteratorCurrObjElement(Dqn_JSONIterator *state); | json_object_element_s *Dqn_JSON_IteratorCurrObjElement(Dqn_JSONIterator *it); | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_IteratorKeyCheck
 | // NOTE: Dqn_JSON_IteratorValueIs
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
|  | json_value_s  *Dqn_JSON_IteratorValueIs(Dqn_JSONIterator *it, json_type_e type); | ||||||
|  | json_object_s *Dqn_JSON_IteratorValueIsObj(Dqn_JSONIterator *it); | ||||||
|  | json_array_s  *Dqn_JSON_IteratorValueIsArray(Dqn_JSONIterator *it); | ||||||
|  | json_string_s *Dqn_JSON_IteratorValueIsString(Dqn_JSONIterator *it); | ||||||
|  | json_number_s *Dqn_JSON_IteratorValueIsNumber(Dqn_JSONIterator *it); | ||||||
|  | json_value_s  *Dqn_JSON_IteratorValueIsBool(Dqn_JSONIterator *it); | ||||||
| 
 | 
 | ||||||
| #define        Dqn_JSON_IteratorKeyCheck(state, type, require) Dqn_JSON_IteratorKeyCheck(state, type, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | size_t Dqn_JSON_IteratorValueArraySize(Dqn_JSONIterator *it); | ||||||
| json_value_s  *Dqn_JSON_IteratorKeyCheck_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 | 
 | ||||||
| #define        Dqn_JSON_IteratorKeyCheckObj(state, require) Dqn_JSON_IteratorKeyCheckObj_(state, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | // NOTE: Dqn_JSON_IteratorKeyValueIs
 | ||||||
| json_object_s *Dqn_JSON_IteratorKeyCheckObj_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_IteratorKeyCheckArray(state, require) Dqn_JSON_IteratorKeyCheckArray_(state, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_array_s  *Dqn_JSON_IteratorKeyCheckArray_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_IteratorKeyCheckString(state, require) Dqn_JSON_IteratorKeyCheckString_(state, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_string_s *Dqn_JSON_IteratorKeyCheckString_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_IteratorKeyCheckNumber(state, require) Dqn_JSON_IteratorKeyCheckNumber_(state, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_number_s *Dqn_JSON_IteratorKeyCheckNumber_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_IteratorKeyCheckBool(state, require) Dqn_JSON_IteratorKeyCheckBool_(state, require, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_value_s  *Dqn_JSON_IteratorKeyCheckBool_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_Iterator_KeyIs
 |  | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| #define Dqn_JSON_IteratorKeyIs(state, type) Dqn_JSON_IteratorKeyCheck(state, type,    false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | Dqn_String8    Dqn_JSON_IteratorKey(Dqn_JSONIterator *it); | ||||||
| #define Dqn_JSON_IteratorKeyIsObj(state) Dqn_JSON_IteratorKeyCheckObj_(state,       false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | bool           Dqn_JSON_IteratorKeyIs(Dqn_JSONIterator *it, Dqn_String8 key); | ||||||
| #define Dqn_JSON_IteratorKeyIsArray(state) Dqn_JSON_IteratorKeyCheckArray_(state,   false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | json_object_s *Dqn_JSON_IteratorKeyValueIsObj(Dqn_JSONIterator *it, Dqn_String8 key); | ||||||
| #define Dqn_JSON_IteratorKeyIsString(state) Dqn_JSON_IteratorKeyCheckString_(state, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | json_array_s  *Dqn_JSON_IteratorKeyValueIsArray(Dqn_JSONIterator *it, Dqn_String8 key); | ||||||
| #define Dqn_JSON_IteratorKeyIsNumber(state) Dqn_JSON_IteratorKeyCheckNumber_(state, false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | json_string_s *Dqn_JSON_IteratorKeyValueIsString(Dqn_JSONIterator *it, Dqn_String8 key); | ||||||
| #define Dqn_JSON_IteratorKeyIsBool(state) Dqn_JSON_IteratorKeyCheckBool_(state,     false /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | json_number_s *Dqn_JSON_IteratorKeyValueIsNumber(Dqn_JSONIterator *it, Dqn_String8 key); | ||||||
|  | json_value_s  *Dqn_JSON_IteratorKeyValueIsBool(Dqn_JSONIterator *it, Dqn_String8 key); | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_Iterator_KeyRequire
 | // NOTE: Dqn_JSON_IteratorValueTo
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| #define Dqn_JSON_IteratorKeyRequire(state, type, require) Dqn_JSON_IteratorKeyCheck(state, type,  true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | Dqn_String8 Dqn_JSON_IteratorValueToString(Dqn_JSONIterator *it); | ||||||
| #define Dqn_JSON_IteratorKeyRequireObj(state, require) Dqn_JSON_IteratorKeyCheckObj_(state,       true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | int64_t     Dqn_JSON_IteratorValueToI64(Dqn_JSONIterator *it); | ||||||
| #define Dqn_JSON_IteratorKeyRequireArray(state, require) Dqn_JSON_IteratorKeyCheckArray_(state,   true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | uint64_t    Dqn_JSON_IteratorValueToU64(Dqn_JSONIterator *it); | ||||||
| #define Dqn_JSON_IteratorKeyRequireString(state, require) Dqn_JSON_IteratorKeyCheckString_(state, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | bool        Dqn_JSON_IteratorValueToBool(Dqn_JSONIterator *it); | ||||||
| #define Dqn_JSON_IteratorKeyRequireNumber(state, require) Dqn_JSON_IteratorKeyCheckNumber_(state, true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| #define Dqn_JSON_IteratorKeyRequireBool(state, require) Dqn_JSON_IteratorKeyCheckBool_(state,     true /*require*/, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_IteratorKeyIsNamed
 | #define Dqn_JSON_IteratorErrorUnknownKeyValue(it) \ | ||||||
| // -----------------------------------------------------------------------------
 |     Dqn_JSON_IteratorErrorUnknownKeyValue_(it, DQN_CALL_SITE) | ||||||
| #define        Dqn_JSON_IteratorKeyIsNamedObj(state, key) Dqn_JSON_IteratorKeyIsNamedObj_(state, key, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_object_s *Dqn_JSON_IteratorKeyIsNamedObj_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 | 
 | ||||||
| #define        Dqn_JSON_IteratorKeyIsNamedArray(state, key) Dqn_JSON_IteratorKeyIsNamedArray_(state, key, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) | void Dqn_JSON_IteratorErrorUnknownKeyValue_(Dqn_JSONIterator *it, Dqn_String8 file, Dqn_String8 func, int line); | ||||||
| json_array_s  *Dqn_JSON_IteratorKeyIsNamedArray_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_IteratorKeyIsNamedString(state, key) Dqn_JSON_IteratorKeyIsNamedString_(state, key, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_string_s *Dqn_JSON_IteratorKeyIsNamedString_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_IteratorKeyIsNamedNumber(state, key) Dqn_JSON_IteratorKeyIsNamedNumber_(state, key, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_number_s *Dqn_JSON_IteratorKeyIsNamedNumber_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| #define        Dqn_JSON_IteratorKeyIsNamedBool(state, key) Dqn_JSON_IteratorKeyIsNamedBool_(state, key, DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__) |  | ||||||
| json_value_s  *Dqn_JSON_IteratorKeyIsNamedBool_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line); |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_IteratorKeyTo
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| Dqn_String8 Dqn_JSON_IteratorKeyToString(Dqn_JSONIterator *state); |  | ||||||
| int64_t     Dqn_JSON_IteratorKeyToI64(Dqn_JSONIterator *state); |  | ||||||
| bool        Dqn_JSON_IteratorKeyToBool(Dqn_JSONIterator *state); |  | ||||||
| 
 | 
 | ||||||
| #endif // DQN_JSON_H
 | #endif // DQN_JSON_H
 | ||||||
| 
 | 
 | ||||||
| @ -242,323 +137,74 @@ bool Dqn_JSON_String8Cmp(json_string_s const *lhs, Dqn_String8 key) | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_JSON_RecordIgnoredObjElement_(json_object_element_s const *element, size_t flags, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_string_s const *key = element->name; |  | ||||||
|     size_t value_type_size = 0; |  | ||||||
|     char const *value_type = Dqn_JSON_TypeEnumCString(DQN_CAST(json_type_e)element->value->type, &value_type_size); |  | ||||||
|     if (flags == json_parse_flags_allow_location_information) { |  | ||||||
|         auto const *info = DQN_CAST(json_string_ex_s const *)key; |  | ||||||
|         Dqn_Log(Dqn_LogType::Warning, |  | ||||||
|                 nullptr, |  | ||||||
|                 file, |  | ||||||
|                 func, |  | ||||||
|                 line, |  | ||||||
|                 "Ignored key-value pair in object [line=%zu, col=%zu, key=%.*s, type=%.*s]", |  | ||||||
|                 info->line_no, |  | ||||||
|                 info->row_no, |  | ||||||
|                 key->string_size, |  | ||||||
|                 key->string, |  | ||||||
|                 value_type_size, |  | ||||||
|                 value_type); |  | ||||||
|     } else { |  | ||||||
|         Dqn_Log(Dqn_LogType::Warning, |  | ||||||
|                 nullptr, |  | ||||||
|                 file, |  | ||||||
|                 func, |  | ||||||
|                 line, |  | ||||||
|                 "Ignored key-value pair in object [key=%.*s, type=%.*s]", |  | ||||||
|                 key->string_size, |  | ||||||
|                 key->string, |  | ||||||
|                 value_type_size, |  | ||||||
|                 value_type); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void Dqn_JSON_RecordIgnoredArrayElement_(json_array_element_s const *element, size_t flags, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_value_s const *value = element->value; |  | ||||||
|     size_t              size  = 0; |  | ||||||
|     char const         *type  = Dqn_JSON_TypeEnumCString((json_type_e)value->type, &size); |  | ||||||
|     if (flags == json_parse_flags_allow_location_information) { |  | ||||||
|         size_t line_no = 0; |  | ||||||
|         size_t row_no = 0; |  | ||||||
|         if (value->type == json_type_string) { |  | ||||||
|             auto *info = DQN_CAST(json_string_ex_s const *) value; |  | ||||||
|             line_no    = info->line_no; |  | ||||||
|             row_no     = info->row_no; |  | ||||||
|         } else { |  | ||||||
|             auto *info = DQN_CAST(json_value_ex_s const *) value; |  | ||||||
|             line_no    = info->line_no; |  | ||||||
|             row_no     = info->row_no; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Dqn_Log(Dqn_LogType::Warning, |  | ||||||
|                 nullptr, |  | ||||||
|                 file, |  | ||||||
|                 func, |  | ||||||
|                 line, |  | ||||||
|                 "Ignored value in array [line=%zu, col=%zu, value_type=%.*s]", |  | ||||||
|                 line_no, |  | ||||||
|                 row_no, |  | ||||||
|                 size, |  | ||||||
|                 type); |  | ||||||
|     } else { |  | ||||||
|         Dqn_Log(Dqn_LogType::Warning, |  | ||||||
|                 nullptr, |  | ||||||
|                 file, |  | ||||||
|                 func, |  | ||||||
|                 line, |  | ||||||
|                 "Ignored value in array [value_type=%.*s]", |  | ||||||
|                 size, |  | ||||||
|                 type); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void Dqn_JSON_RecordIgnoredValue_(json_value_s const *value, size_t flags, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     size_t              size  = 0; |  | ||||||
|     char const         *type  = Dqn_JSON_TypeEnumCString((json_type_e)value->type, &size); |  | ||||||
|     if (flags == json_parse_flags_allow_location_information) { |  | ||||||
|         size_t line_no = 0; |  | ||||||
|         size_t row_no = 0; |  | ||||||
|         if (value->type == json_type_string) { |  | ||||||
|             auto *info = DQN_CAST(json_string_ex_s const *) value; |  | ||||||
|             line_no    = info->line_no; |  | ||||||
|             row_no     = info->row_no; |  | ||||||
|         } else { |  | ||||||
|             auto *info = DQN_CAST(json_value_ex_s const *) value; |  | ||||||
|             line_no    = info->line_no; |  | ||||||
|             row_no     = info->row_no; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Dqn_Log(Dqn_LogType::Warning, |  | ||||||
|                 nullptr, |  | ||||||
|                 file, |  | ||||||
|                 func, |  | ||||||
|                 line, |  | ||||||
|                 "Ignored value in json [line=%zu, col=%zu, value_type=%.*s]", |  | ||||||
|                 line_no, |  | ||||||
|                 row_no, |  | ||||||
|                 size, |  | ||||||
|                 type); |  | ||||||
|     } else { |  | ||||||
|         Dqn_Log(Dqn_LogType::Warning, |  | ||||||
|                 nullptr, |  | ||||||
|                 file, |  | ||||||
|                 func, |  | ||||||
|                 line, |  | ||||||
|                 "Ignored value in json [value_type=%.*s]", |  | ||||||
|                 size, |  | ||||||
|                 type); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_ValueCheck
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| json_value_s *Dqn_JSON_ValueCheck_(json_value_s *val, json_type_e type, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_value_s *result = (val && val->type == type) ? val : nullptr; |  | ||||||
|     if (!result && require) { |  | ||||||
|         size_t      expect_size = 0; |  | ||||||
|         char const *expect_type = Dqn_JSON_TypeEnumCString(type, &expect_size); |  | ||||||
|         size_t      val_size    = 0; |  | ||||||
|         char const *val_type    = Dqn_JSON_TypeEnumCString((json_type_e)val->type, &val_size); |  | ||||||
|         if (flags == json_parse_flags_allow_location_information) { |  | ||||||
|             auto const *info = DQN_CAST(json_value_ex_s const *) val; |  | ||||||
|             Dqn_Log(Dqn_LogType::Error, |  | ||||||
|                     nullptr /*user_data*/, |  | ||||||
|                     file, |  | ||||||
|                     func, |  | ||||||
|                     line, |  | ||||||
|                     "Expected json '%.*s' [line=%zu, col=%zu, value_type=%.*s]", |  | ||||||
|                     expect_size, |  | ||||||
|                     expect_type, |  | ||||||
|                     info->line_no, |  | ||||||
|                     info->row_no, |  | ||||||
|                     val_size, |  | ||||||
|                     val_type); |  | ||||||
|         } else { |  | ||||||
|             Dqn_Log(Dqn_LogType::Error, |  | ||||||
|                     nullptr /*userdata*/, |  | ||||||
|                     file, |  | ||||||
|                     func, |  | ||||||
|                     line, |  | ||||||
|                     "Expected json '%.*s' [value_type=%.*s]", |  | ||||||
|                     expect_size, |  | ||||||
|                     expect_type, |  | ||||||
|                     val_size, |  | ||||||
|                     val_type); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_object_s *Dqn_JSON_ValueCheckObj_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_object_s *result = nullptr; |  | ||||||
|     if (Dqn_JSON_ValueCheck_(val, json_type_object, flags, require, file, func, line)) |  | ||||||
|         result = json_value_as_object(val); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_array_s *Dqn_JSON_ValueCheckArray_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_array_s *result = nullptr; |  | ||||||
|     if (Dqn_JSON_ValueCheck_(val, json_type_array, flags, require, file, func, line)) |  | ||||||
|         result = json_value_as_array(val); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_string_s *Dqn_JSON_ValueCheckString_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_string_s *result = nullptr; |  | ||||||
|     if (Dqn_JSON_ValueCheck_(val, json_type_string, flags, require, file, func, line)) |  | ||||||
|         result = json_value_as_string(val); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_number_s *Dqn_JSON_ValueCheckNumber_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_number_s *result = nullptr; |  | ||||||
|     if (Dqn_JSON_ValueCheck_(val, json_type_number, flags, require, file, func, line)) |  | ||||||
|         result = json_value_as_number(val); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_value_s *Dqn_JSON_ValueCheckBool_(json_value_s *val, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_value_s *result = nullptr; |  | ||||||
|     if (val->type == json_type_true || val->type == json_type_false) { |  | ||||||
|         result = val; |  | ||||||
|     } else { |  | ||||||
|         if (require) { |  | ||||||
|             size_t      val_size = 0; |  | ||||||
|             char const *val_type = Dqn_JSON_TypeEnumCString((json_type_e)val->type, &val_size); |  | ||||||
|             if (flags == json_parse_flags_allow_location_information) { |  | ||||||
|                 auto const *info = DQN_CAST(json_value_ex_s const *) val; |  | ||||||
|                 Dqn_Log(Dqn_LogType::Error, |  | ||||||
|                         nullptr /*userdata*/, |  | ||||||
|                         file, |  | ||||||
|                         func, |  | ||||||
|                         line, |  | ||||||
|                         "Expected json bool [line=%zu, col=%zu, value_type=%.*s]", |  | ||||||
|                         info->line_no, |  | ||||||
|                         info->row_no, |  | ||||||
|                         val_size, |  | ||||||
|                         val_type); |  | ||||||
|             } else { |  | ||||||
|                 Dqn_Log(Dqn_LogType::Error, |  | ||||||
|                         nullptr /*userdata*/, |  | ||||||
|                         file, |  | ||||||
|                         func, |  | ||||||
|                         line, |  | ||||||
|                         "Expected json bool [value_type=%.*s]", |  | ||||||
|                         val_size, |  | ||||||
|                         val_type); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_ObjElementCheck
 |  | ||||||
| // -----------------------------------------------------------------------------
 |  | ||||||
| json_value_s *Dqn_JSON_ObjElementCheckNamed_(json_object_element_s *element, json_type_e type, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_value_s *result = nullptr; |  | ||||||
|     if (element && Dqn_JSON_String8Cmp(element->name, key)) |  | ||||||
|         result = Dqn_JSON_ValueCheck_(element->value, type, flags, require, file, func, line); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_object_s *Dqn_JSON_ObjElementCheckNamedObj_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_object_s *result = DQN_CAST(json_object_s *)Dqn_JSON_ObjElementCheckNamed_(element, json_type_object, key, flags, require, file, func, line); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_array_s *Dqn_JSON_ObjElementCheckNamedArray_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_array_s *result = DQN_CAST(json_array_s *)Dqn_JSON_ObjElementCheckNamed_(element, json_type_array, key, flags, require, file, func, line); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_string_s *Dqn_JSON_ObjElementCheckNamedString_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_string_s *result = DQN_CAST(json_string_s *)Dqn_JSON_ObjElementCheckNamed_(element, json_type_string, key, flags, require, file, func, line); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_number_s *Dqn_JSON_ObjElementCheckNamedNumber_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_number_s *result = DQN_CAST(json_number_s *)Dqn_JSON_ObjElementCheckNamed_(element, json_type_number, key, flags, require, file, func, line); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| json_value_s *Dqn_JSON_ObjElementCheckNamedBool_(json_object_element_s *element, Dqn_String8 key, size_t flags, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     json_value_s *result = nullptr; |  | ||||||
|     if (element && Dqn_JSON_String8Cmp(element->name, key)) |  | ||||||
|         result = Dqn_JSON_ValueCheckBool_(element->value, flags, require, file, func, line); |  | ||||||
|     return result; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_Iterator_push/pop
 | // NOTE: Dqn_JSON_Iterator_push/pop
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| bool Dqn_JSON_IteratorPushObjElement(Dqn_JSONIterator *state, json_object_element_s *element) | bool Dqn_JSON_IteratorPushObjElement(Dqn_JSONIterator *it, json_object_element_s *element) | ||||||
| { | { | ||||||
|     if (!state || !element) |     if (!it || !element) | ||||||
|         return false; |         return false; | ||||||
|     DQN_ASSERT(state->stack_count < DQN_ARRAY_ICOUNT(state->stack)); |     DQN_ASSERT(it->stack_count < DQN_ARRAY_ICOUNT(it->stack)); | ||||||
|     state->stack[state->stack_count++] = {Dqn_JSON_IteratorEntryTypeObjElement, element}; |     it->stack[it->stack_count++] = {Dqn_JSON_IteratorEntryTypeObjElement, element}; | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Dqn_JSON_IteratorPushObj(Dqn_JSONIterator *state, json_object_s *obj) | bool Dqn_JSON_IteratorPushObj(Dqn_JSONIterator *it, json_object_s *obj) | ||||||
| { | { | ||||||
|     if (!state || !obj) |     if (!it || !obj) | ||||||
|         return false; |         return false; | ||||||
|     DQN_ASSERT(state->stack_count < DQN_ARRAY_ICOUNT(state->stack)); |     DQN_ASSERT(it->stack_count < DQN_ARRAY_ICOUNT(it->stack)); | ||||||
|     state->stack[state->stack_count++] = {Dqn_JSON_IteratorEntryTypeObj, obj}; |     it->stack[it->stack_count++] = {Dqn_JSON_IteratorEntryTypeObj, obj}; | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Dqn_JSON_IteratorPushArrayElement(Dqn_JSONIterator *state, json_array_element_s *element) | bool Dqn_JSON_IteratorPushArrayElement(Dqn_JSONIterator *it, json_array_element_s *element) | ||||||
| { | { | ||||||
|     if (!state || !element) |     if (!it || !element) | ||||||
|         return false; |         return false; | ||||||
|     DQN_ASSERT(state->stack_count < DQN_ARRAY_ICOUNT(state->stack)); |     DQN_ASSERT(it->stack_count < DQN_ARRAY_ICOUNT(it->stack)); | ||||||
|     state->stack[state->stack_count++] = {Dqn_JSON_IteratorEntryTypeArrayElement, element}; |     it->stack[it->stack_count++] = {Dqn_JSON_IteratorEntryTypeArrayElement, element}; | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Dqn_JSON_IteratorPushArray(Dqn_JSONIterator *state, json_array_s *array) | bool Dqn_JSON_IteratorPushArray(Dqn_JSONIterator *it, json_array_s *array) | ||||||
| { | { | ||||||
|     if (!state || !array) |     if (!it || !array) | ||||||
|         return false; |         return false; | ||||||
|     DQN_ASSERT(state->stack_count < DQN_ARRAY_ICOUNT(state->stack)); |     DQN_ASSERT(it->stack_count < DQN_ARRAY_ICOUNT(it->stack)); | ||||||
|     state->stack[state->stack_count++] = {Dqn_JSON_IteratorEntryTypeArray, array}; |     it->stack[it->stack_count++] = {Dqn_JSON_IteratorEntryTypeArray, array}; | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_JSON_IteratorPop(Dqn_JSONIterator *state) | bool Dqn_JSON_IteratorPushValue(Dqn_JSONIterator *it, json_value_s *value) | ||||||
| { | { | ||||||
|     if (!state) |     bool result = false; | ||||||
|  |     if (!it || !value) | ||||||
|  |         return result; | ||||||
|  | 
 | ||||||
|  |     if (value->type == json_type_object) { | ||||||
|  |         result = Dqn_JSON_IteratorPushObj(it, json_value_as_object(value)); | ||||||
|  |     } else if (value->type == json_type_array) { | ||||||
|  |         result = Dqn_JSON_IteratorPushArray(it, json_value_as_array(value)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Dqn_JSON_IteratorPop(Dqn_JSONIterator *it) | ||||||
|  | { | ||||||
|  |     if (!it) | ||||||
|         return; |         return; | ||||||
|     DQN_ASSERT(state->stack_count > 0); |     DQN_ASSERT(it->stack_count > 0); | ||||||
|     if (state->stack_count > 0) |     if (it->stack_count > 0) | ||||||
|         state->stack_count--; |         it->stack_count--; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_Iterator json tree navigation
 | // NOTE: Dqn_JSON_Iterator json tree navigation
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| json_value_s *Dqn_JSON_IteratorPushKey(Dqn_JSONIterator *state) | json_value_s *Dqn_JSON_IteratorPushCurrValue(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_value_s          *result = nullptr; |     json_value_s          *result = nullptr; | ||||||
|     Dqn_JSONIteratorEntry *curr   = Dqn_JSON_IteratorCurr(state); |     Dqn_JSONIteratorEntry *curr   = Dqn_JSON_IteratorCurr(it); | ||||||
|     if (!curr) |     if (!curr) | ||||||
|         return result; |         return result; | ||||||
| 
 | 
 | ||||||
| @ -575,19 +221,22 @@ json_value_s *Dqn_JSON_IteratorPushKey(Dqn_JSONIterator *state) | |||||||
|     if (result->type == json_type_array) { |     if (result->type == json_type_array) { | ||||||
|         json_array_s *array = json_value_as_array(result); |         json_array_s *array = json_value_as_array(result); | ||||||
|         DQN_ASSERT(array); |         DQN_ASSERT(array); | ||||||
|         Dqn_JSON_IteratorPushArray(state, array); |         Dqn_JSON_IteratorPushArray(it, array); | ||||||
|     } else if (result->type == json_type_object) { |     } else if (result->type == json_type_object) { | ||||||
|         json_object_s *obj = json_value_as_object(result); |         json_object_s *obj = json_value_as_object(result); | ||||||
|         DQN_ASSERT(obj); |         DQN_ASSERT(obj); | ||||||
|         Dqn_JSON_IteratorPushObj(state, obj); |         Dqn_JSON_IteratorPushObj(it, obj); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Dqn_JSON_IteratorNextField(Dqn_JSONIterator *state) | bool Dqn_JSON_IteratorNext(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     Dqn_JSONIteratorEntry *curr          = Dqn_JSON_IteratorCurr(state); |     Dqn_JSONIteratorEntry *curr = Dqn_JSON_IteratorCurr(it); | ||||||
|  |     if (!curr) | ||||||
|  |         return false; | ||||||
|  | 
 | ||||||
|     json_object_element_s *obj_element   = nullptr; |     json_object_element_s *obj_element   = nullptr; | ||||||
|     json_array_element_s  *array_element = nullptr; |     json_array_element_s  *array_element = nullptr; | ||||||
|     if (curr->type == Dqn_JSON_IteratorEntryTypeObj) { |     if (curr->type == Dqn_JSON_IteratorEntryTypeObj) { | ||||||
| @ -596,61 +245,43 @@ bool Dqn_JSON_IteratorNextField(Dqn_JSONIterator *state) | |||||||
|     } else if (curr->type == Dqn_JSON_IteratorEntryTypeObjElement) { |     } else if (curr->type == Dqn_JSON_IteratorEntryTypeObjElement) { | ||||||
|         auto *element = DQN_CAST(json_object_element_s *) curr->value; |         auto *element = DQN_CAST(json_object_element_s *) curr->value; | ||||||
|         obj_element   = element->next; |         obj_element   = element->next; | ||||||
|         Dqn_JSON_IteratorPop(state); |         Dqn_JSON_IteratorPop(it); | ||||||
|     } else if (curr->type == Dqn_JSON_IteratorEntryTypeArray) { |     } else if (curr->type == Dqn_JSON_IteratorEntryTypeArray) { | ||||||
|         auto *array   = DQN_CAST(json_array_s *) curr->value; |         auto *array   = DQN_CAST(json_array_s *) curr->value; | ||||||
|         array_element = array->start; |         array_element = array->start; | ||||||
|     } else if (curr->type == Dqn_JSON_IteratorEntryTypeArrayElement) { |     } else if (curr->type == Dqn_JSON_IteratorEntryTypeArrayElement) { | ||||||
|         auto *element = DQN_CAST(json_array_element_s *) curr->value; |         auto *element = DQN_CAST(json_array_element_s *) curr->value; | ||||||
|         array_element = element->next; |         array_element = element->next; | ||||||
|         Dqn_JSON_IteratorPop(state); |         Dqn_JSON_IteratorPop(it); | ||||||
|     } else { |     } else { | ||||||
|         Dqn_JSON_IteratorPop(state); |         Dqn_JSON_IteratorPop(it); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (obj_element) |     if (obj_element) | ||||||
|         Dqn_JSON_IteratorPushObjElement(state, obj_element); |         Dqn_JSON_IteratorPushObjElement(it, obj_element); | ||||||
|     else if (array_element) |     else if (array_element) | ||||||
|         Dqn_JSON_IteratorPushArrayElement(state, array_element); |         Dqn_JSON_IteratorPushArrayElement(it, array_element); | ||||||
| 
 | 
 | ||||||
|     bool result = obj_element || array_element; |     bool result = obj_element || array_element; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Dqn_JSON_IteratorErrorUnrecognisedKey_(Dqn_JSONIterator *state, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) |  | ||||||
| { |  | ||||||
|     Dqn_JSONIteratorEntry *curr = Dqn_JSON_IteratorCurr(state); |  | ||||||
|     if (!curr) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     if (curr->type == Dqn_JSON_IteratorEntryTypeObjElement) { |  | ||||||
|         json_object_element_s *element = DQN_CAST(json_object_element_s *) curr->value; |  | ||||||
|         Dqn_JSON_RecordIgnoredObjElement_(element, state->flags, file, func, line); |  | ||||||
|     } else if (curr->type == Dqn_JSON_IteratorEntryTypeArrayElement) { |  | ||||||
|         json_array_element_s *element = DQN_CAST(json_array_element_s *) curr->value; |  | ||||||
|         Dqn_JSON_RecordIgnoredArrayElement_(element, state->flags, file, func, line); |  | ||||||
|     } else { |  | ||||||
|         json_value_s *value = DQN_CAST(json_value_s *) curr->value; |  | ||||||
|         Dqn_JSON_RecordIgnoredValue_(value, state->flags, file, func, line); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NOTE: Dqn_JSON_IteratorCurr
 | // NOTE: Dqn_JSON_IteratorCurr
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| Dqn_JSONIteratorEntry *Dqn_JSON_IteratorCurr(Dqn_JSONIterator *state) | Dqn_JSONIteratorEntry *Dqn_JSON_IteratorCurr(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     Dqn_JSONIteratorEntry *result = nullptr; |     Dqn_JSONIteratorEntry *result = nullptr; | ||||||
|     if (!state || state->stack_count <= 0) |     if (!it || it->stack_count <= 0) | ||||||
|         return result; |         return result; | ||||||
| 
 | 
 | ||||||
|     result = &state->stack[state->stack_count - 1]; |     result = &it->stack[it->stack_count - 1]; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_value_s *Dqn_JSON_IteratorCurrValue(Dqn_JSONIterator *state) | json_value_s *Dqn_JSON_IteratorCurrValue(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_value_s *result = nullptr; |     json_value_s *result = nullptr; | ||||||
|     Dqn_JSONIteratorEntry *curr = Dqn_JSON_IteratorCurr(state); |     Dqn_JSONIteratorEntry *curr = Dqn_JSON_IteratorCurr(it); | ||||||
|     if (!curr) |     if (!curr) | ||||||
|         return result; |         return result; | ||||||
| 
 | 
 | ||||||
| @ -671,120 +302,200 @@ json_value_s *Dqn_JSON_IteratorCurrValue(Dqn_JSONIterator *state) | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_object_element_s *Dqn_JSON_IteratorCurrObjElement(Dqn_JSONIterator *state) | json_object_element_s *Dqn_JSON_IteratorCurrObjElement(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     Dqn_JSONIteratorEntry *curr   = Dqn_JSON_IteratorCurr(state); |     Dqn_JSONIteratorEntry *curr   = Dqn_JSON_IteratorCurr(it); | ||||||
|     auto                  *result = (curr && curr->type == Dqn_JSON_IteratorEntryTypeObjElement) |     auto                  *result = (curr && curr->type == Dqn_JSON_IteratorEntryTypeObjElement) | ||||||
|                                         ? DQN_CAST(json_object_element_s *) curr->value |                                         ? DQN_CAST(json_object_element_s *) curr->value | ||||||
|                                         : nullptr; |                                         : nullptr; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_IteratorKeyCheck
 | // NOTE: Dqn_JSON_IteratorValueIs
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| json_value_s *Dqn_JSON_IteratorKeyCheck_(Dqn_JSONIterator *state, json_type_e type, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_value_s *Dqn_JSON_IteratorValueIs(Dqn_JSONIterator *it, json_type_e type) | ||||||
| { | { | ||||||
|     json_value_s  *curr  = Dqn_JSON_IteratorCurrValue(state); |     json_value_s  *curr  = Dqn_JSON_IteratorCurrValue(it); | ||||||
|     json_value_s *result = Dqn_JSON_ValueCheck_(curr, type, state->flags, require, file, func, line); |     json_value_s *result = (curr && type == curr->type) ? curr : nullptr; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_object_s *Dqn_JSON_IteratorKeyCheckObj_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_object_s *Dqn_JSON_IteratorValueIsObj(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_value_s  *curr   = Dqn_JSON_IteratorCurrValue(state); |     json_value_s *curr    = Dqn_JSON_IteratorCurrValue(it); | ||||||
|     json_object_s *result = Dqn_JSON_ValueCheckObj_(curr, state->flags, require, file, func, line); |     json_object_s *result = curr ? json_value_as_object(curr) : nullptr; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_array_s *Dqn_JSON_IteratorKeyCheckArray_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_array_s *Dqn_JSON_IteratorValueIsArray(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_value_s *curr   = Dqn_JSON_IteratorCurrValue(state); |     json_value_s *curr   = Dqn_JSON_IteratorCurrValue(it); | ||||||
|     json_array_s *result = Dqn_JSON_ValueCheckArray_(curr, state->flags, require, file, func, line); |     json_array_s *result = curr ? json_value_as_array(curr) : nullptr; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_string_s *Dqn_JSON_IteratorKeyCheckString_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_string_s *Dqn_JSON_IteratorValueIsString(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_value_s  *curr   = Dqn_JSON_IteratorCurrValue(state); |     json_value_s *curr    = Dqn_JSON_IteratorCurrValue(it); | ||||||
|     json_string_s *result = Dqn_JSON_ValueCheckString_(curr, state->flags, require, file, func, line); |     json_string_s *result = curr ? json_value_as_string(curr) : nullptr; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_number_s *Dqn_JSON_IteratorKeyCheckNumber_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_number_s *Dqn_JSON_IteratorValueIsNumber(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_value_s  *curr   = Dqn_JSON_IteratorCurrValue(state); |     json_value_s *curr    = Dqn_JSON_IteratorCurrValue(it); | ||||||
|     json_number_s *result = Dqn_JSON_ValueCheckNumber_(curr, state->flags, require, file, func, line); |     json_number_s *result = curr ? json_value_as_number(curr) : nullptr; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_value_s *Dqn_JSON_IteratorKeyCheckBool_(Dqn_JSONIterator *state, bool require, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_value_s *Dqn_JSON_IteratorValueIsBool(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_value_s *curr   = Dqn_JSON_IteratorCurrValue(state); |     json_value_s *curr   = Dqn_JSON_IteratorCurrValue(it); | ||||||
|     json_value_s *result = Dqn_JSON_ValueCheckBool_(curr, state->flags, require, file, func, line); |     json_value_s *result = (curr && (curr->type == json_type_true || curr->type == json_type_false)) ? curr : nullptr; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_IteratorKeyIsNamed
 | size_t Dqn_JSON_IteratorValueArraySize(Dqn_JSONIterator *it) | ||||||
|  | { | ||||||
|  |     size_t result = 0; | ||||||
|  |     if (json_array_s *curr = Dqn_JSON_IteratorValueIsArray(it)) | ||||||
|  |         result = curr->length; | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // NOTE: Dqn_JSON_IteratorKeyValueIs
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| json_object_s *Dqn_JSON_IteratorKeyIsNamedObj_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | Dqn_String8 Dqn_JSON_IteratorKey(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(state); |     json_object_element_s *curr = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|     json_object_s         *result = state ? Dqn_JSON_ObjElementCheckNamedObj_(curr, key, state->flags, false /*require*/, file, func, line) : nullptr; |     Dqn_String8 result = {}; | ||||||
|  |     if (curr) { | ||||||
|  |         result.data = DQN_CAST(char *)curr->name->string; | ||||||
|  |         result.size = curr->name->string_size; | ||||||
|  |     } | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_array_s *Dqn_JSON_IteratorKeyIsNamedArray_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | bool Dqn_JSON_IteratorKeyIs(Dqn_JSONIterator *it, Dqn_String8 key) | ||||||
| { | { | ||||||
|     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(state); |     json_object_element_s *curr = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|     json_array_s          *result = state ? Dqn_JSON_ObjElementCheckNamedArray_(curr, key, state->flags, false /*require*/, file, func, line) : nullptr; |     bool result                 = Dqn_JSON_String8Cmp(curr->name, key); | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_string_s *Dqn_JSON_IteratorKeyIsNamedString_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_object_s *Dqn_JSON_IteratorKeyValueIsObj(Dqn_JSONIterator *it, Dqn_String8 key) | ||||||
| { | { | ||||||
|     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(state); |     json_object_s         *result = nullptr; | ||||||
|     json_string_s         *result = state ? Dqn_JSON_ObjElementCheckNamedString_(curr, key, state->flags, false /*require*/, file, func, line) : nullptr; |     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|  |     if (curr && Dqn_JSON_String8Cmp(curr->name, key)) | ||||||
|  |         result = json_value_as_object(curr->value); | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_number_s *Dqn_JSON_IteratorKeyIsNamedNumber_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_array_s *Dqn_JSON_IteratorKeyValueIsArray(Dqn_JSONIterator *it, Dqn_String8 key) | ||||||
| { | { | ||||||
|     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(state); |     json_array_s          *result = nullptr; | ||||||
|     json_number_s         *result = state ? Dqn_JSON_ObjElementCheckNamedNumber_(curr, key, state->flags, false /*require*/, file, func, line) : nullptr; |     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|  |     if (curr && Dqn_JSON_String8Cmp(curr->name, key)) | ||||||
|  |         result = json_value_as_array(curr->value); | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| json_value_s *Dqn_JSON_IteratorKeyIsNamedBool_(Dqn_JSONIterator *state, Dqn_String8 key, Dqn_String8 file, Dqn_String8 func, Dqn_uint line) | json_string_s *Dqn_JSON_IteratorKeyValueIsString(Dqn_JSONIterator *it, Dqn_String8 key) | ||||||
| { | { | ||||||
|     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(state); |     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|     json_value_s          *result = state ? Dqn_JSON_ObjElementCheckNamedBool_(curr, key, state->flags, false /*require*/, file, func, line) : nullptr; |     json_string_s         *result = nullptr; | ||||||
|  |     if (curr && Dqn_JSON_String8Cmp(curr->name, key)) | ||||||
|  |         result = json_value_as_string(curr->value); | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | json_number_s *Dqn_JSON_IteratorKeyValueIsNumber(Dqn_JSONIterator *it, Dqn_String8 key) | ||||||
|  | { | ||||||
|  |     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|  |     json_number_s         *result = nullptr; | ||||||
|  |     if (curr && Dqn_JSON_String8Cmp(curr->name, key)) | ||||||
|  |         result = json_value_as_number(curr->value); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // NOTE: Dqn_JSON_IteratorKeyTo
 | json_value_s *Dqn_JSON_IteratorKeyValueIsBool(Dqn_JSONIterator *it, Dqn_String8 key) | ||||||
|  | { | ||||||
|  |     json_object_element_s *curr   = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|  |     json_value_s          *result = nullptr; | ||||||
|  |     if (curr && Dqn_JSON_String8Cmp(curr->name, key)) | ||||||
|  |         result = curr->value->type == json_type_true || curr->value->type == json_type_false ? curr->value : nullptr; | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // NOTE: Dqn_JSON_IteratorValueTo
 | ||||||
| // -----------------------------------------------------------------------------
 | // -----------------------------------------------------------------------------
 | ||||||
| Dqn_String8 Dqn_JSON_IteratorKeyToString(Dqn_JSONIterator *state) | Dqn_String8 Dqn_JSON_IteratorValueToString(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     Dqn_String8 result = {}; |     Dqn_String8 result = {}; | ||||||
|     if (json_string_s *curr = Dqn_JSON_IteratorKeyIsString(state)) |     if (json_string_s *curr = Dqn_JSON_IteratorValueIsString(it)) | ||||||
|         result = Dqn_String8_Init(curr->string, curr->string_size); |         result = Dqn_String8_Init(curr->string, curr->string_size); | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int64_t Dqn_JSON_IteratorKeyToI64(Dqn_JSONIterator *state) | int64_t Dqn_JSON_IteratorValueToI64(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     int64_t result = {}; |     int64_t result = {}; | ||||||
|     if (json_number_s *curr = Dqn_JSON_IteratorKeyIsNumber(state)) |     if (json_number_s *curr = Dqn_JSON_IteratorValueIsNumber(it)) | ||||||
|         result = Dqn_String8_ToI64(Dqn_String8_Init(curr->number, curr->number_size), 0 /*separator*/); |         result = Dqn_String8_ToI64(Dqn_String8_Init(curr->number, curr->number_size), 0 /*separator*/); | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Dqn_JSON_IteratorKeyToBool(Dqn_JSONIterator *state) | uint64_t Dqn_JSON_IteratorValueToU64(Dqn_JSONIterator *it) | ||||||
|  | { | ||||||
|  |     uint64_t result = {}; | ||||||
|  |     if (json_number_s *curr = Dqn_JSON_IteratorValueIsNumber(it)) | ||||||
|  |         result = Dqn_String8_ToU64(Dqn_String8_Init(curr->number, curr->number_size), 0 /*separator*/); | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool Dqn_JSON_IteratorValueToBool(Dqn_JSONIterator *it) | ||||||
| { | { | ||||||
|     bool result = {}; |     bool result = {}; | ||||||
|     if (json_value_s *curr = Dqn_JSON_IteratorKeyIsBool(state)) |     if (json_value_s *curr = Dqn_JSON_IteratorValueIsBool(it)) | ||||||
|         result = curr->type == json_type_true; |         result = curr->type == json_type_true; | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void Dqn_JSON_IteratorErrorUnknownKeyValue_(Dqn_JSONIterator *it, Dqn_CallSite call_site) | ||||||
|  | { | ||||||
|  |     if (!it) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     json_object_element_s const *curr = Dqn_JSON_IteratorCurrObjElement(it); | ||||||
|  |     if (!curr) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     size_t value_type_size = 0; | ||||||
|  |     char const *value_type = Dqn_JSON_TypeEnumCString(DQN_CAST(json_type_e)curr->value->type, &value_type_size); | ||||||
|  | 
 | ||||||
|  |     json_string_s const *key = curr->name; | ||||||
|  |     if (it->flags & json_parse_flags_allow_location_information) { | ||||||
|  |         json_string_ex_s const *info = DQN_CAST(json_string_ex_s const *)key; | ||||||
|  |         Dqn_Log_TypeFCallSite(Dqn_LogType_Warning, | ||||||
|  |                               call_site, | ||||||
|  |                               "Unknown key-value pair in object [loc=%zu:%zu, key=%.*s, value=%.*s]", | ||||||
|  |                               info->line_no, | ||||||
|  |                               info->row_no, | ||||||
|  |                               key->string_size, | ||||||
|  |                               key->string, | ||||||
|  |                               value_type_size, | ||||||
|  |                               value_type); | ||||||
|  |     } else { | ||||||
|  |         Dqn_Log_TypeFCallSite(Dqn_LogType_Warning, | ||||||
|  |                               call_site, | ||||||
|  |                               "Unknown key-value pair in object [key=%.*s, value=%.*s]", | ||||||
|  |                               key->string_size, | ||||||
|  |                               key->string, | ||||||
|  |                               value_type_size, | ||||||
|  |                               value_type); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #endif // defined(DQN_JSON_IMPLEMENTATION)
 | #endif // defined(DQN_JSON_IMPLEMENTATION)
 | ||||||
|  | |||||||
| @ -4,17 +4,20 @@ | |||||||
| /*
 | /*
 | ||||||
| #define DQN_TEST_WITH_MAIN   Define this to enable the main function and allow standalone compiling | #define DQN_TEST_WITH_MAIN   Define this to enable the main function and allow standalone compiling | ||||||
|                              and running of the file. |                              and running of the file. | ||||||
|  | #define DQN_TEST_WITH_KECCAK Define this to enable the main function and allow standalone compiling | ||||||
|  |                              and running of the file. | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| #if defined(DQN_TEST_WITH_MAIN) | #if defined(DQN_TEST_WITH_MAIN) | ||||||
|     #define DQN_IMPLEMENTATION |     #define DQN_IMPLEMENTATION | ||||||
|     #include "dqn.h" |     #include "dqn.h" | ||||||
| 
 |  | ||||||
|     #define DQN_KECCAK_IMPLEMENTATION |  | ||||||
|     #include "dqn_keccak.h" |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #if defined(DQN_TEST_WITH_KECCAK) | ||||||
|  |     #define DQN_KECCAK_IMPLEMENTATION | ||||||
|  |     #include "dqn_keccak.h" | ||||||
|     #include "dqn_tests_helpers.cpp" |     #include "dqn_tests_helpers.cpp" | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| #define DQN_TESTER_IMPLEMENTATION | #define DQN_TESTER_IMPLEMENTATION | ||||||
| #include "dqn_tester.h" | #include "dqn_tester.h" | ||||||
| @ -145,7 +148,7 @@ Dqn_Tester TestFixedArray() | |||||||
|     DQN_TESTER_GROUP(test, "Dqn_FArray") { |     DQN_TESTER_GROUP(test, "Dqn_FArray") { | ||||||
|         DQN_TESTER_TEST("Initialise from raw array") { |         DQN_TESTER_TEST("Initialise from raw array") { | ||||||
|             int raw_array[] = {1, 2}; |             int raw_array[] = {1, 2}; | ||||||
|             auto array = Dqn_FArray_Init<int, 4>(raw_array, (int)Dqn_CArray_Count(raw_array)); |             auto array = Dqn_FArray_Init<int, 4>(raw_array, DQN_ARRAY_ICOUNT(raw_array)); | ||||||
|             DQN_TESTER_ASSERT(&test, array.size == 2); |             DQN_TESTER_ASSERT(&test, array.size == 2); | ||||||
|             DQN_TESTER_ASSERT(&test, array.data[0] == 1); |             DQN_TESTER_ASSERT(&test, array.data[0] == 1); | ||||||
|             DQN_TESTER_ASSERT(&test, array.data[1] == 2); |             DQN_TESTER_ASSERT(&test, array.data[1] == 2); | ||||||
| @ -153,7 +156,7 @@ Dqn_Tester TestFixedArray() | |||||||
| 
 | 
 | ||||||
|         DQN_TESTER_TEST("Erase stable 1 element from array") { |         DQN_TESTER_TEST("Erase stable 1 element from array") { | ||||||
|             int raw_array[] = {1, 2, 3}; |             int raw_array[] = {1, 2, 3}; | ||||||
|             auto array = Dqn_FArray_Init<int, 4>(raw_array, (int)Dqn_CArray_Count(raw_array)); |             auto array = Dqn_FArray_Init<int, 4>(raw_array, DQN_ARRAY_ICOUNT(raw_array)); | ||||||
|             Dqn_FArray_EraseStable(&array, 1); |             Dqn_FArray_EraseStable(&array, 1); | ||||||
|             DQN_TESTER_ASSERT(&test, array.size == 2); |             DQN_TESTER_ASSERT(&test, array.size == 2); | ||||||
|             DQN_TESTER_ASSERT(&test, array.data[0] == 1); |             DQN_TESTER_ASSERT(&test, array.data[0] == 1); | ||||||
| @ -162,7 +165,7 @@ Dqn_Tester TestFixedArray() | |||||||
| 
 | 
 | ||||||
|         DQN_TESTER_TEST("Erase unstable 1 element from array") { |         DQN_TESTER_TEST("Erase unstable 1 element from array") { | ||||||
|             int raw_array[] = {1, 2, 3}; |             int raw_array[] = {1, 2, 3}; | ||||||
|             auto array = Dqn_FArray_Init<int, 4>(raw_array, (int)Dqn_CArray_Count(raw_array)); |             auto array = Dqn_FArray_Init<int, 4>(raw_array, DQN_ARRAY_ICOUNT(raw_array)); | ||||||
|             DQN_TESTER_ASSERT(&test, Dqn_FArray_EraseUnstable(&array, 0)); |             DQN_TESTER_ASSERT(&test, Dqn_FArray_EraseUnstable(&array, 0)); | ||||||
|             DQN_TESTER_ASSERT(&test, array.size == 2); |             DQN_TESTER_ASSERT(&test, array.size == 2); | ||||||
|             DQN_TESTER_ASSERT(&test, array.data[0] == 3); |             DQN_TESTER_ASSERT(&test, array.data[0] == 3); | ||||||
| @ -172,7 +175,7 @@ Dqn_Tester TestFixedArray() | |||||||
|         DQN_TESTER_TEST("Add 1 element to array") { |         DQN_TESTER_TEST("Add 1 element to array") { | ||||||
|             int const ITEM  = 2; |             int const ITEM  = 2; | ||||||
|             int raw_array[] = {1}; |             int raw_array[] = {1}; | ||||||
|             auto array      = Dqn_FArray_Init<int, 4>(raw_array, (int)Dqn_CArray_Count(raw_array)); |             auto array      = Dqn_FArray_Init<int, 4>(raw_array, DQN_ARRAY_ICOUNT(raw_array)); | ||||||
|             Dqn_FArray_Add(&array, ITEM); |             Dqn_FArray_Add(&array, ITEM); | ||||||
|             DQN_TESTER_ASSERT(&test, array.size == 2); |             DQN_TESTER_ASSERT(&test, array.size == 2); | ||||||
|             DQN_TESTER_ASSERT(&test, array.data[0] == 1); |             DQN_TESTER_ASSERT(&test, array.data[0] == 1); | ||||||
| @ -181,7 +184,7 @@ Dqn_Tester TestFixedArray() | |||||||
| 
 | 
 | ||||||
|         DQN_TESTER_TEST("Clear array") { |         DQN_TESTER_TEST("Clear array") { | ||||||
|             int raw_array[] = {1}; |             int raw_array[] = {1}; | ||||||
|             auto array      = Dqn_FArray_Init<int, 4>(raw_array, (int)Dqn_CArray_Count(raw_array)); |             auto array      = Dqn_FArray_Init<int, 4>(raw_array, DQN_ARRAY_ICOUNT(raw_array)); | ||||||
|             Dqn_FArray_Clear(&array, Dqn_ZeroMem_No); |             Dqn_FArray_Clear(&array, Dqn_ZeroMem_No); | ||||||
|             DQN_TESTER_ASSERT(&test, array.size == 0); |             DQN_TESTER_ASSERT(&test, array.size == 0); | ||||||
|         } |         } | ||||||
| @ -735,9 +738,9 @@ Dqn_Tester TestOS() | |||||||
|         DQN_TESTER_TEST("Generate secure RNG 32 bytes") { |         DQN_TESTER_TEST("Generate secure RNG 32 bytes") { | ||||||
|             char const ZERO[32] = {}; |             char const ZERO[32] = {}; | ||||||
|             char       buf[32]  = {}; |             char       buf[32]  = {}; | ||||||
|             Dqn_b32 result = Dqn_OS_SecureRNGBytes(buf, Dqn_CArray_CountI(buf)); |             bool result         = Dqn_OS_SecureRNGBytes(buf, DQN_ARRAY_UCOUNT(buf)); | ||||||
|             DQN_TESTER_ASSERT(&test, result); |             DQN_TESTER_ASSERT(&test, result); | ||||||
|             DQN_TESTER_ASSERT(&test, DQN_MEMCMP(buf, ZERO, Dqn_CArray_Count(buf)) != 0); |             DQN_TESTER_ASSERT(&test, DQN_MEMCMP(buf, ZERO, DQN_ARRAY_UCOUNT(buf)) != 0); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         DQN_TESTER_TEST("Generate secure RNG 0 bytes") { |         DQN_TESTER_TEST("Generate secure RNG 0 bytes") { | ||||||
| @ -1236,7 +1239,7 @@ Dqn_Tester TestWin() | |||||||
|             wchar_t const EXPECTED[] = {L'S', L't', L'r', L'i', L'n', L'g', 0}; |             wchar_t const EXPECTED[] = {L'S', L't', L'r', L'i', L'n', L'g', 0}; | ||||||
| 
 | 
 | ||||||
|             DQN_TESTER_ASSERTF(&test, size_required == size_returned, "string_size: %d, result: %d", size_required, size_returned); |             DQN_TESTER_ASSERTF(&test, size_required == size_returned, "string_size: %d, result: %d", size_required, size_returned); | ||||||
|             DQN_TESTER_ASSERTF(&test, size_returned == Dqn_CArray_Count(EXPECTED) - 1, "string_size: %d, expected: %zu", size_returned, Dqn_CArray_Count(EXPECTED) - 1); |             DQN_TESTER_ASSERTF(&test, size_returned == DQN_ARRAY_UCOUNT(EXPECTED) - 1, "string_size: %d, expected: %zu", size_returned, DQN_ARRAY_UCOUNT(EXPECTED) - 1); | ||||||
|             DQN_TESTER_ASSERT(&test, DQN_MEMCMP(EXPECTED, string, sizeof(EXPECTED)) == 0); |             DQN_TESTER_ASSERT(&test, DQN_MEMCMP(EXPECTED, string, sizeof(EXPECTED)) == 0); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -1253,13 +1256,14 @@ Dqn_Tester TestWin() | |||||||
|             char const EXPECTED[] = {'S', 't', 'r', 'i', 'n', 'g', 0}; |             char const EXPECTED[] = {'S', 't', 'r', 'i', 'n', 'g', 0}; | ||||||
| 
 | 
 | ||||||
|             DQN_TESTER_ASSERTF(&test, size_required == size_returned, "string_size: %d, result: %d", size_required, size_returned); |             DQN_TESTER_ASSERTF(&test, size_required == size_returned, "string_size: %d, result: %d", size_required, size_returned); | ||||||
|             DQN_TESTER_ASSERTF(&test, size_returned == Dqn_CArray_Count(EXPECTED) - 1, "string_size: %d, expected: %zu", size_returned, Dqn_CArray_Count(EXPECTED) - 1); |             DQN_TESTER_ASSERTF(&test, size_returned == DQN_ARRAY_UCOUNT(EXPECTED) - 1, "string_size: %d, expected: %zu", size_returned, DQN_ARRAY_UCOUNT(EXPECTED) - 1); | ||||||
|             DQN_TESTER_ASSERT(&test, DQN_MEMCMP(EXPECTED, string, sizeof(EXPECTED)) == 0); |             DQN_TESTER_ASSERT(&test, DQN_MEMCMP(EXPECTED, string, sizeof(EXPECTED)) == 0); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return test; |     return test; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #if defined(DQN_TEST_WITH_KECCAK) | ||||||
| #define DQN_TESTER_HASH_X_MACRO \ | #define DQN_TESTER_HASH_X_MACRO \ | ||||||
|     DQN_TESTER_HASH_X_ENTRY(SHA3_224, "SHA3-224") \ |     DQN_TESTER_HASH_X_ENTRY(SHA3_224, "SHA3-224") \ | ||||||
|     DQN_TESTER_HASH_X_ENTRY(SHA3_256, "SHA3-256") \ |     DQN_TESTER_HASH_X_ENTRY(SHA3_256, "SHA3-256") \ | ||||||
| @ -1470,6 +1474,7 @@ Dqn_Tester TestKeccak() | |||||||
|     } |     } | ||||||
|     return test; |     return test; | ||||||
| } | } | ||||||
|  | #endif // defined(DQN_TEST_WITH_KECCAK)
 | ||||||
| 
 | 
 | ||||||
| void TestRunSuite() | void TestRunSuite() | ||||||
| { | { | ||||||
| @ -1483,7 +1488,9 @@ void TestRunSuite() | |||||||
|         TestFixedArray(), |         TestFixedArray(), | ||||||
|         TestHex(), |         TestHex(), | ||||||
|         TestIntrinsics(), |         TestIntrinsics(), | ||||||
|  |         #if defined(DQN_TEST_WITH_KECCAK) | ||||||
|         TestKeccak(), |         TestKeccak(), | ||||||
|  |         #endif | ||||||
|         TestM4(), |         TestM4(), | ||||||
|         TestOS(), |         TestOS(), | ||||||
|         TestPerfCounter(), |         TestPerfCounter(), | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user