Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
|
Go to the documentation of this file.
40 static const void* s_vpMagicNumber = (
const void*)
"builder";
114 static json_value* spBuildWalk(
build* spBld,
nexts* spNexts,
bvalue* spBValue);
116 static void vJsonBuilderCallbacks(
void* vpParserCtx);
129 void* vpMem = spJson->
vpMem;
131 memset((
void*)spBld, 0,
sizeof(
build));
132 spBld->vpVec32 =
vpVecCtor(vpMem,
sizeof(uint32_t), 4096);
138 spBld->vpMem = vpMem;
140 spBld->spJson = spJson;
143 spBld->vpValidate = s_vpMagicNumber;
158 void* vpMem = spBld->
vpMem;
169 memset((
void*)spBld, 0,
sizeof(
build));
186 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
225 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
236 memset(spValue, 0,
sizeof(
bvalue));
240 for(ui = 0; ui < uiLength; ui++){
241 if(uipData[ui] >= 0xd800 && uipData[ui] <= 0xdbff){
242 snprintf(caBuf, 128,
"code point uipData[%"PRIuMAX
"]=0x%04"PRIXMAX
" is in surrogate pair range, [0xD800 - 0xDBFF]",
246 if(uipData[ui] > 0x10FFFF){
247 snprintf(caBuf, 128,
"code point uipData[%"PRIuMAX
"]=0x%04"PRIXMAX
" is out of range (> 0x10FFFF)",
251 uipChars[ui] = uipData[ui];
285 if (!spBld || (spBld->
vpValidate != s_vpMagicNumber)) {
288 if (cpString == NULL) {
294 memset(spValue, 0,
sizeof(
bvalue));
295 aint uiLength = (
aint) strlen(cpString);
300 if(
sizeof(
achar) ==
sizeof(char)){
305 for(; ui < uiLength; ui++){
306 acpTemp[ui] = (
achar)((uint8_t)cpString[ui]);
314 vJsonBuilderCallbacks(vpParser);
338 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
343 memset(spValue, 0,
sizeof(
bvalue));
360 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
365 memset(spValue, 0,
sizeof(
bvalue));
372 spValue->
uiNumber = (uint64_t)iNumber;
385 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
390 memset(spValue, 0,
sizeof(
bvalue));
405 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
419 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
433 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
447 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
461 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
481 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
489 XTHROW(spBld->
spException,
"parent object (uiObject) out of range - does not exist");
513 memset(spThis, 0,
sizeof(
bvalue));
526 XTHROW(spBld->
spException,
"parent object has invalid offset to the last child value");
530 spParent->
uiNext = uiThis;
552 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
560 XTHROW(spBld->
spException,
"parent array (uiArray) out of range - does not exist");
574 memset(spThis, 0,
sizeof(
bvalue));
582 XTHROW(spBld->
spException,
"parent object has invalid offset to the last child value");
586 spParent->
uiNext = uiThis;
605 if(!spBld || (spBld->
vpValidate != s_vpMagicNumber)){
630 vCountWalk(spBld, &sCounts, spRoot);
663 json_value* spValues = spBuildWalk(spBld, &sNexts, spRoot);
684 switch(spRoot->
uiId){
701 vCountWalk(spBld, spCounts, spChild);
707 XTHROW(spBld->
spException,
"vCountWalk() sanity check: last child's next index is not zero");
723 spReturn->
uiLength = (uint32_t)uiLength;
746 static json_value* spBuildWalk(
build* spBld,
nexts* spNexts,
bvalue* spBValue){
749 json_value* spThis = spNexts->
spValue;
750 spThis->uiId = spBValue->
uiId;
755 switch(spBValue->
uiId){
760 spThis->spNumber = spMakeNumber(spBld, spNexts, spBValue);
768 spThis->sppChildren = spNexts->
sppList;
773 spThis->sppChildren[ui] = spBuildWalk(spBld, spNexts, spChild);
786 memset(spValue, 0,
sizeof(
bvalue));
787 spValue->
uiId = uiType;
800 uint32_t uiChar = 0x5C;
807 uint32_t uiChar = 0x2F;
814 uint32_t uiChar = 0x22;
821 uint32_t uiChar = 0x08;
828 uint32_t uiChar = 0x0C;
835 uint32_t uiChar = 0x0A;
842 uint32_t uiChar = 0x0D;
849 uint32_t uiChar = 0x09;
894 caHex[0] = (
char)acpDigits[2];
895 caHex[1] = (char)acpDigits[3];
896 caHex[2] = (char)acpDigits[4];
897 caHex[3] = (char)acpDigits[5];
901 XTHROW(spBld->
spException,
"UTF-16 encoding error - surrogate pair range not allowed");
911 caHex[0] = (
char)acpDigits[2];
912 caHex[1] = (char)acpDigits[3];
913 caHex[2] = (char)acpDigits[4];
914 caHex[3] = (char)acpDigits[5];
916 caHex[5] = (char)acpDigits[8];
917 caHex[6] = (char)acpDigits[9];
918 caHex[7] = (char)acpDigits[10];
919 caHex[8] = (char)acpDigits[11];
931 XTHROW(spBld->
spException,
"UTF-16 encoding error - low surrogate not preceded by high surrogate");
934 XTHROW(spBld->
spException,
"UTF-16 encoding error - high surrogate not followed by low surrogate");
939 static void vJsonBuilderCallbacks(
void* vpParserCtx){
942 memset((
void*)cb, 0,
sizeof(cb));
int64_t iSigned
If uiType = JSON_ID_SIGNED, the signed int value.
json_iterator * spJsonIteratorCtor(json *spJson)
Private function for internal object use only. Never called by the application.
double dFloat
If uiType = JSON_ID_FLOAT, the floating point value.
#define JSON_GRAMMAR_SOLIDUS
void * vpParserCtor(exception *spException, void *vpParserInit)
The parser's constructor for file initialization data.
void * vpVec32
vector of 32-bit Unicode code points
#define JSON_GRAMMAR_UTF16_2
#define JSON_UTF16_NOMATCH
#define JSON_GRAMMAR_UTF8_3
#define JSON_GRAMMAR_ASCII
aint uiSuccess
True (>0) if the input string was matched in its entirety, false (0) otherwise.
#define JSON_UTF16_BAD_LOW
The object context. For intenrnal use only.
Internal workings only. Don't worry about it.
#define JSON_GRAMMAR_LINE_FEED
aint uiJsonBuildMakeNumberF(void *vpBuildCtx, double dNumber)
Make a JSON floating point number value.
aint uiParserOffset
[read only] Offset from acpString to the first character to match
A JSON interator object context.
The structure of a JSON number value.
#define JSON_GRAMMAR_UTF8_2
const achar * acpString
[read only] Pointer to the input sub-string,
aint uiUtf16_1(char *cpHex, uint32_t *uipChar)
void vVecDtor(void *vpCtx)
The vector component destructor.
uint32_t uiLength
The number of integers in the array.
const achar * acpInput
Pointer to the input string.
aint uiParserState
[read only] ID_ACTIVE if the parser is going down the tree. ID_MATCH or ID_NOMATCH if coming up the t...
#define JSON_GRAMMAR_QUOTE
void * vpMem
pointer to a memory object context used only for this builder object
void vExContext()
Handles bad context pointers.
void * vpUserData
Pointer to user data, if any. Not examined or used by the parser in any way. Presented to the user's ...
uint_fast8_t achar
achar is the type for the parser's alphabet characters.
aint uiUtf16_2(char *cpHex, uint32_t *uipChar)
uint32_t uiUtf8_3byte(char *cpBytes)
aint uiJsonBuildMakeNumberU(void *vpBuildCtx, uint64_t uiNumber)
Make a JSON unsigned integer number value.
#define JSON_ID_STRING
String value.
void vParserSetRuleCallback(void *vpCtx, aint uiRuleId, parser_callback pfnCallback)
Set a call back function for a specific rule.
void * vpVecAt(void *vpCtx, aint uiIndex)
Get a the indexed vector element. The vector is not altered.
const uint32_t * uipPhrase
Pointer to an array of 32-bit unsigned integers.
#define XTHROW(ctx, msg)
Exception throw macro.
aint uiContextIndex
Index of the saved context pointer in the JSON context;.
void(* parser_callback)(callback_data *spData)
User-written callback function prototype.
#define RULE_COUNT_JSON_GRAMMAR
#define JSON_ID_ARRAY
Array value.
aint uiJsonBuildMakeFalse(void *vpBuildCtx)
Make a JSON false value.
uint_fast32_t aint
The APG parser's unsigned integer type.
#define JSON_GRAMMAR_STRING_CONTENT
char * cpAscii
A buffer to hold all ASCII strings referenced.
json_number * spNumbers
An array of all the referenced numbers.
aint uiInputLength
Number of input string alphabet characters.
exception * spMemException(void *vpCtx)
Get a pointer to this memory objects's exception handler.
aint uiJsonBuildMakeStringA(void *vpBuildCtx, const char *cpString)
Make a string value from a null-terminated ASCII string.
#define JSON_ID_FALSE
Literal value is false.
Defines the input string and other configuration parameters for the parser,.
#define JSON_ID_OBJECT
Object value.
aint uiCallbackState
[input/output] Rule name (RNM) callback functions: If ID_ACTIVE, the parser takes no action....
aint uiRoot
Index of the root node build value (bvalue).
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
uint32_t uiUtf8_4byte(char *cpBytes)
uint32_t uiUtf8_2byte(char *cpBytes)
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
#define JSON_GRAMMAR_BACKSPACE
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
void * vpMem
Pointer to a memory object used for all memory allocations.
#define JSON_ID_TRUE
Literal value is true.
exception * spException
Pointer to the exception structure for reporting errors to the application catch block.
The parser's final state.
A structure to describe the type and location of a caught exception.
aint uiJsonBuildMakeObject(void *vpBuildCtx)
Make a JSON object value.
void vMemFree(void *vpCtx, const void *vpData)
Free memory previously allocated with vpMemAlloc().
abool bJsonValidate(void *vpCtx)
Validate a JSON context pointer.
void * vpJsonBuild(void *vpBuildCtx, aint uiRoot)
Build the JSON object.
#define JSON_UTF16_BAD_HIGH
aint uiJsonBuildMakeStringU(void *vpBuildCtx, const uint32_t *uipData, aint uiLength)
Make a string value from UTF-32 code points.
#define ID_MATCH
indicates a matched phrase parser state on return from parse tree below this node
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
aint uiJsonBuildAddToObject(void *vpBuildCtx, aint uiObject, aint uiKey, aint uiAdd)
Add a child value to a parent object value.
The data struct passed to each callback function.
json * spJson
JSON object context pointer. Used only for string conversions.
void vJsonBuildClear(void *vpBuildCtx)
Clears all memory associated with this builder object.
void * vpVecAchars
Vector for temporary achar representation of a string.
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
#define JSON_ID_FLOAT
Number value is a double floating point number.
void * vpVecPushn(void *vpCtx, void *vpElement, aint uiCount)
Adds one or more elements to the end of the array.
#define JSON_GRAMMAR_UTF16_1
Private JSON component header file.
A builder value. Internal workings only. Don't worry about it.
void vJsonBuildDtor(void *vpBuildCtx)
The builder object destructor.
json_value ** sppChildList
Pointer to a array of pointers to the children values.
uint32_t * uipChars
Points to the list of 32-bit characters.
The builder object context.
aint uiCount
The number of pointers in the list.
aint uiJsonBuildMakeTrue(void *vpBuildCtx)
Make a JSON true value.
void * vpUserData
[input/output] User-defined data passed to to the parser in parser_config.
json_value ** sppValues
List of pointers to values.
const void * vpValidate
"magic number" for object validation
aint uiJsonBuildMakeArray(void *vpBuildCtx)
Makea JSON array value.
void * vpVecBuilders
A vector of builder context pointers remembered for destruction.
void vParserDtor(void *vpCtx)
Clears the parser component's context and frees all heap memory associated with this parser.
aint uiJsonBuildAddToArray(void *vpBuildCtx, aint uiArray, aint uiAdd)
Add a child value to a parent array value.
uint64_t uiUnsigned
If uiType = JSON_ID_UNSIGNED, the unsigned int value.
bvalue * spBValues
Points to the first bvalue.
void * vpVecb
vector of bvalue structs holding the user values from the Make & Add functions
uint8_t abool
abool is the APG bool type.
void * vpUserData
Pointer to user data. Available to the error handling routine.
Header file for the JSON component. Defines API prototypes.
#define JSON_ID_SIGNED
Number value is a 64-bit signed integer.
aint uiStartRule
Index of the start rule. Any rule in the SABNF grammar may be used as the start rule.
#define ID_NOMATCH
indicates that no phrase was matched on return from parse tree below this node
json_value * spValues
An array of the final value tree.
#define JSON_ID_UNSIGNED
Number value is a 64-bit unsigned integer.
aint uiJsonBuildMakeNumberS(void *vpBuildCtx, int64_t iNumber)
Make a JSON signed integer number value.
aint uiType
Identifies the number type. One of.
#define JSON_GRAMMAR_FORM_FEED
aint uiJsonBuildMakeNull(void *vpBuildCtx)
Make a JSON null value.
#define JSON_GRAMMAR_R_SOLIDUS
Defines a pointer to an array of 32-bit unsigned integers plus its length. Typically needed by Unicod...
#define JSON_ID_NULL
Literal value is null.
#define JSON_GRAMMAR_UTF8_4
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
#define JSON_ID_NUMBER
Number value.
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
u32_phrase * spStrings
An array of all the referenced strings.
Internal workings only. Don't worry about it.
void * vpJsonBuildCtor(void *vpJsonCtx)
The builder object constructor.
void vParserParse(void *vpCtx, parser_config *spConfig, parser_state *spState)
Parse an input string of alphabet characters.
APG Version 7.0 is licensed under the
2-Clause BSD License,
an Open Source Initiative Approved License.