Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
builder.c
Go to the documentation of this file.
1 /* *************************************************************************************
2  Copyright (c) 2021, Lowell D. Thomas
3  All rights reserved.
4 
5  This file is part of APG Version 7.0.
6  APG Version 7.0 may be used under the terms of the BSD 2-Clause License.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 
14  2. Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 * *************************************************************************************/
36 #include "json.h"
37 #include "jsonp.h"
38 #include "./json-grammar.h"
39 
40 static const void* s_vpMagicNumber = (const void*)"builder";
41 
45 typedef struct{
52 } counts;
53 
57 typedef struct{
58  json_value** sppList;
59  json_value* spValue;
62 } nexts;
63 
67 typedef struct{
69  union{
72  double dNumber;
73  uint64_t uiNumber;
74  int64_t iNumber;
75  };
76  union{
80  };
85 } bvalue;
86 
90 typedef struct{
91  const void* vpValidate;
93  aint uiContextIndex;
95  void* vpMem;
96  void* vpVec32;
97  void* vpVecAchars;
98  void* vpVecb;
100  uint32_t* uipChars;
104  char* cpAscii;
105  json_value* spValues;
106  json_value** sppChildList;
108  void* vpUserData;
109 } build;
110 
111 static aint uiMakeSimple(build* spBld, aint uiType);
112 static u32_phrase* spMakeString(build* spBld, nexts* spNexts, aint uiOffset, aint uiLength);
113 static json_number* spMakeNumber(build* spBld, nexts* spNexts, bvalue* spBValue);
114 static json_value* spBuildWalk(build* spBld, nexts* spNexts, bvalue* spBValue);
115 static void vCountWalk(build* spBld, counts* spCounts, bvalue* spRoot);
116 static void vJsonBuilderCallbacks(void* vpParserCtx);
117 
124 void* vpJsonBuildCtor(void* vpJsonCtx){
125  json* spJson = (json*) vpJsonCtx;
126  if(!bJsonValidate(vpJsonCtx)){
127  vExContext();
128  }
129  void* vpMem = spJson->vpMem;
130  build* spBld = (build*)vpMemAlloc(vpMem, sizeof(build));
131  memset((void*)spBld, 0, sizeof(build));
132  spBld->vpVec32 = vpVecCtor(vpMem, sizeof(uint32_t), 4096);
133  spBld->vpVecAchars = vpVecCtor(vpMem, sizeof(achar), 256);
134  spBld->vpVecb = vpVecCtor(vpMem, sizeof(bvalue), 1024);
135  // push a single, dummy value so that the user never gets a `0` index
136  bvalue sB = {};
137  vpVecPush(spBld->vpVecb, &sB);
138  spBld->vpMem = vpMem;
139  spBld->spException = spMemException(vpMem);
140  spBld->spJson = spJson;
141  spBld->uiContextIndex = uiVecLen(spJson->vpVecBuilders);
142  vpVecPush(spJson->vpVecBuilders, &spBld);
143  spBld->vpValidate = s_vpMagicNumber;
144  return (void*)spBld;
145 }
146 
154 void vJsonBuildDtor(void* vpBuildCtx){
155  build* spBld = (build*)vpBuildCtx;
156  if(vpBuildCtx){
157  if(spBld->vpValidate == s_vpMagicNumber){
158  void* vpMem = spBld->vpMem;
159  void** vppContext = (void**)vpVecFirst(spBld->spJson->vpVecBuilders);
160  vppContext[spBld->uiContextIndex] = NULL;
161  vVecDtor(spBld->vpVec32);
162  vVecDtor(spBld->vpVecAchars);
163  vVecDtor(spBld->vpVecb);
164  vMemFree(vpMem, spBld->spValues);
165  vMemFree(vpMem, spBld->sppChildList);
166  vMemFree(vpMem, spBld->spStrings);
167  vMemFree(vpMem, spBld->cpAscii);
168  vMemFree(vpMem, spBld->spNumbers);
169  memset((void*)spBld, 0, sizeof(build));
170  vMemFree(vpMem, spBld);
171  }else{
172  vExContext();
173  }
174  }
175 }
176 
184 void vJsonBuildClear(void* vpBuildCtx){
185  build* spBld = (build*)vpBuildCtx;
186  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
187  vExContext();
188  }
189  // clear previous data, if any (vMemFree ok with NULL pointer)
190  vMemFree(spBld->vpMem, spBld->spValues);
191  vMemFree(spBld->vpMem, spBld->spNumbers);
192  vMemFree(spBld->vpMem, spBld->spStrings);
193  vMemFree(spBld->vpMem, spBld->cpAscii);
194  vMemFree(spBld->vpMem, spBld->sppChildList);
195  spBld->spValues = NULL;
196  spBld->spNumbers = NULL;
197  spBld->spStrings = NULL;
198  spBld->cpAscii = NULL;
199  spBld->sppChildList = NULL;
200  vVecClear(spBld->vpVec32);
201  vVecClear(spBld->vpVecAchars);
202  vVecClear(spBld->vpVecb);
203  spBld->uipChars = NULL;
204  spBld->spBValues = NULL;
205  spBld->uiRoot = 0;
206  // push a single, dummy value so that the user never gets a `0` index
207  bvalue sB = {};
208  vpVecPush(spBld->vpVecb, &sB);
209 }
210 
223 aint uiJsonBuildMakeStringU(void* vpBuildCtx, const uint32_t* uipData, aint uiLength){
224  build* spBld = (build*)vpBuildCtx;
225  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
226  vExContext();
227  }
228  if(uipData == NULL){
229  uiLength = 0;
230  }
231  aint ui;
232  char caBuf[128];
233  aint uiOffset = uiVecLen(spBld->vpVec32);
234  aint uiNext = uiVecLen(spBld->vpVecb);
235  bvalue* spValue = (bvalue*)vpVecPush(spBld->vpVecb, NULL);
236  memset(spValue, 0, sizeof(bvalue));
237  if(uiLength){
238  uint32_t* uipChars = (uint32_t*)vpVecPushn(spBld->vpVec32, NULL, uiLength);
239  // validate a save the characters
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]",
243  (luint)ui, (luint)uipData[ui]);
244  XTHROW(spBld->spException, caBuf);
245  }
246  if(uipData[ui] > 0x10FFFF){
247  snprintf(caBuf, 128, "code point uipData[%"PRIuMAX"]=0x%04"PRIXMAX" is out of range (> 0x10FFFF)",
248  (luint)ui, (luint)uipData[ui]);
249  XTHROW(spBld->spException, caBuf);
250  }
251  uipChars[ui] = uipData[ui];
252  }
253  }
254  spValue->uiId = JSON_ID_STRING;
255  spValue->uiStringOffset = uiOffset;
256  spValue->uiStringLength = uiLength;
257  return uiNext;
258 }
259 
283 aint uiJsonBuildMakeStringA(void *vpBuildCtx, const char *cpString) {
284  build *spBld = (build*) vpBuildCtx;
285  if (!spBld || (spBld->vpValidate != s_vpMagicNumber)) {
286  vExContext();
287  }
288  if (cpString == NULL) {
289  XTHROW(spBld->spException, "input string cpString may not be NULL");
290  }
291  aint uiOffset = uiVecLen(spBld->vpVec32);
292  aint uiNext = uiVecLen(spBld->vpVecb);
293  bvalue *spValue = (bvalue*) vpVecPush(spBld->vpVecb, NULL);
294  memset(spValue, 0, sizeof(bvalue));
295  aint uiLength = (aint) strlen(cpString);
296  if (uiLength) {
297  // parse JSON string to 32-bit UTF-32 code points
298  parser_config sConfig = {};
299  parser_state sState;
300  if(sizeof(achar) == sizeof(char)){
301  sConfig.acpInput = (const achar*)cpString;
302  }else{
303  achar* acpTemp = (achar*)vpVecPushn(spBld->vpVecAchars, NULL, uiLength);
304  aint ui = 0;
305  for(; ui < uiLength; ui++){
306  acpTemp[ui] = (achar)((uint8_t)cpString[ui]);
307  }
308  sConfig.acpInput = (const achar*)acpTemp;
309  }
310  sConfig.uiInputLength = uiLength;
312  sConfig.vpUserData = (void*)spBld;
313  void* vpParser = vpParserCtor(spBld->spException, vpJsonGrammarInit);
314  vJsonBuilderCallbacks(vpParser);
315  vParserParse(vpParser, &sConfig, &sState);
316  if(!sState.uiSuccess){
317  XTHROW(spBld->spException, "unable to parse given JSON string");
318  }
319  vParserDtor(vpParser);
320  }
321  aint uiTest = uiVecLen(spBld->vpVec32);
322  uiTest -= uiOffset;
323  spValue->uiId = JSON_ID_STRING;
324  spValue->uiStringOffset = uiOffset;
325  spValue->uiStringLength = uiVecLen(spBld->vpVec32) - uiOffset;
326  return uiNext;
327 }
328 
336 aint uiJsonBuildMakeNumberF(void* vpBuildCtx, double dNumber){
337  build* spBld = (build*)vpBuildCtx;
338  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
339  vExContext();
340  }
341  aint uiNext = uiVecLen(spBld->vpVecb);
342  bvalue* spValue = (bvalue*)vpVecPush(spBld->vpVecb, NULL);
343  memset(spValue, 0, sizeof(bvalue));
344  spValue->uiId = JSON_ID_NUMBER;
345  spValue->uiNumberId = JSON_ID_FLOAT;
346  spValue->dNumber = dNumber;
347  return uiNext;
348 }
349 
358 aint uiJsonBuildMakeNumberS(void* vpBuildCtx, int64_t iNumber){
359  build* spBld = (build*)vpBuildCtx;
360  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
361  vExContext();
362  }
363  aint uiNext = uiVecLen(spBld->vpVecb);
364  bvalue* spValue = (bvalue*)vpVecPush(spBld->vpVecb, NULL);
365  memset(spValue, 0, sizeof(bvalue));
366  spValue->uiId = JSON_ID_NUMBER;
367  if(iNumber < 0){
368  spValue->uiNumberId = JSON_ID_SIGNED;
369  spValue->iNumber = iNumber;
370  }else{
371  spValue->uiNumberId = JSON_ID_UNSIGNED;
372  spValue->uiNumber = (uint64_t)iNumber;
373  }
374  return uiNext;
375 }
383 aint uiJsonBuildMakeNumberU(void* vpBuildCtx, uint64_t uiNumber){
384  build* spBld = (build*)vpBuildCtx;
385  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
386  vExContext();
387  }
388  aint uiNext = uiVecLen(spBld->vpVecb);
389  bvalue* spValue = (bvalue*)vpVecPush(spBld->vpVecb, NULL);
390  memset(spValue, 0, sizeof(bvalue));
391  spValue->uiId = JSON_ID_NUMBER;
392  spValue->uiNumberId = JSON_ID_UNSIGNED;
393  spValue->uiNumber = uiNumber;
394  return uiNext;
395 }
396 
403 aint uiJsonBuildMakeTrue(void* vpBuildCtx){
404  build* spBld = (build*)vpBuildCtx;
405  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
406  vExContext();
407  }
408  return uiMakeSimple(spBld, JSON_ID_TRUE);
409 }
410 
417 aint uiJsonBuildMakeFalse(void* vpBuildCtx){
418  build* spBld = (build*)vpBuildCtx;
419  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
420  vExContext();
421  }
422  return uiMakeSimple(spBld, JSON_ID_FALSE);
423 }
424 
431 aint uiJsonBuildMakeNull(void* vpBuildCtx){
432  build* spBld = (build*)vpBuildCtx;
433  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
434  vExContext();
435  }
436  return uiMakeSimple(spBld, JSON_ID_NULL);
437 }
438 
445 aint uiJsonBuildMakeObject(void* vpBuildCtx){
446  build* spBld = (build*)vpBuildCtx;
447  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
448  vExContext();
449  }
450  return uiMakeSimple(spBld, JSON_ID_OBJECT);
451 }
452 
459 aint uiJsonBuildMakeArray(void* vpBuildCtx){
460  build* spBld = (build*)vpBuildCtx;
461  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
462  vExContext();
463  }
464  return uiMakeSimple(spBld, JSON_ID_ARRAY);
465 }
466 
479 aint uiJsonBuildAddToObject(void* vpBuildCtx, aint uiObject, aint uiKey, aint uiAdd){
480  build* spBld = (build*)vpBuildCtx;
481  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
482  vExContext();
483  }
484  if(uiObject == 0){
485  XTHROW(spBld->spException, "parent object (uiObject) cannot be zero");
486  }
487  bvalue* spParent = (bvalue*)vpVecAt(spBld->vpVecb, uiObject);
488  if(!spParent){
489  XTHROW(spBld->spException, "parent object (uiObject) out of range - does not exist");
490  }
491  if(spParent->uiId != JSON_ID_OBJECT){
492  XTHROW(spBld->spException, "parent (uiObject) not of type JSON_ID_OBJECT");
493  }
494  if(uiAdd == 0){
495  XTHROW(spBld->spException, "value to add (uiAdd) cannot be zero");
496  }
497  bvalue* spAdd = (bvalue*)vpVecAt(spBld->vpVecb, uiAdd);
498  if(!spAdd){
499  XTHROW(spBld->spException, "value to add out of range - does not exist");
500  }
501  if(uiKey == 0){
502  XTHROW(spBld->spException, "object key (uiKey) cannot be zero");
503  }
504  bvalue* spKey = (bvalue*)vpVecAt(spBld->vpVecb, uiKey);
505  if(!spKey){
506  XTHROW(spBld->spException, "key value out of range - does not exist");
507  }
508  if(spKey->uiId != JSON_ID_STRING){
509  XTHROW(spBld->spException, "key value must type JSON_ID_STRING");
510  }
511  aint uiThis = uiVecLen(spBld->vpVecb);
512  bvalue* spThis = (bvalue*)vpVecPush(spBld->vpVecb, NULL);
513  memset(spThis, 0, sizeof(bvalue));
514 
515  // refresh the pointers
516  spParent = (bvalue*)vpVecAt(spBld->vpVecb, uiObject);
517  spAdd = (bvalue*)vpVecAt(spBld->vpVecb, uiAdd);
518  spKey = (bvalue*)vpVecAt(spBld->vpVecb, uiKey);
519  if(spParent->uiChildOffset == 0){
520  // adding the first child to the parent object
521  spParent->uiChildOffset = uiThis;
522  }else{
523  // link the previous child to this one
524  bvalue* spPrev = (bvalue*)vpVecAt(spBld->vpVecb, spParent->uiNext);
525  if(!spPrev){
526  XTHROW(spBld->spException, "parent object has invalid offset to the last child value");
527  }
528  spPrev->uiNext = uiThis;
529  }
530  spParent->uiNext = uiThis;
531  spParent->uiChildCount++;
532  *spThis = *spAdd;
533  spThis->uiNext = 0;
534  spThis->bKey = APG_TRUE;
535  spThis->uiKeyOffset = spKey->uiStringOffset;
536  spThis->uiKeyLength = spKey->uiStringLength;
537  return uiThis;
538 }
539 
550 aint uiJsonBuildAddToArray(void* vpBuildCtx, aint uiArray, aint uiAdd){
551  build* spBld = (build*)vpBuildCtx;
552  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
553  vExContext();
554  }
555  if(uiArray == 0){
556  XTHROW(spBld->spException, "parent array (uiArray) cannot be zero");
557  }
558  bvalue* spParent = (bvalue*)vpVecAt(spBld->vpVecb, uiArray);
559  if(!spParent){
560  XTHROW(spBld->spException, "parent array (uiArray) out of range - does not exist");
561  }
562  if(spParent->uiId != JSON_ID_ARRAY){
563  XTHROW(spBld->spException, "parent (uiArray) not of type JSON_ID_ARRAY");
564  }
565  if(uiAdd == 0){
566  XTHROW(spBld->spException, "value to add (uiAdd) cannot be zero");
567  }
568  bvalue* spAdd = (bvalue*)vpVecAt(spBld->vpVecb, uiAdd);
569  if(!spAdd){
570  XTHROW(spBld->spException, "value to add out of range - does not exist");
571  }
572  aint uiThis = uiVecLen(spBld->vpVecb);
573  bvalue* spThis = (bvalue*)vpVecPush(spBld->vpVecb, NULL);
574  memset(spThis, 0, sizeof(bvalue));
575  if(spParent->uiChildOffset == 0){
576  // adding the first child to the parent object
577  spParent->uiChildOffset = uiThis;
578  }else{
579  // link the previous child to this one
580  bvalue* spPrev = (bvalue*)vpVecAt(spBld->vpVecb, spParent->uiNext);
581  if(!spPrev){
582  XTHROW(spBld->spException, "parent object has invalid offset to the last child value");
583  }
584  spPrev->uiNext = uiThis;
585  }
586  spParent->uiNext = uiThis;
587  spParent->uiChildCount++;
588  *spThis = *spAdd;
589  spThis->bKey = APG_FALSE;
590  return uiThis;
591 }
592 
603 void* vpJsonBuild(void* vpBuildCtx, aint uiRoot){
604  build* spBld = (build*)vpBuildCtx;
605  if(!spBld || (spBld->vpValidate != s_vpMagicNumber)){
606  vExContext();
607  }
608 
609  if(uiRoot){
610  bvalue* spRoot = (bvalue*)vpVecAt(spBld->vpVecb, uiRoot);
611  if(spRoot){
612  spRoot->uiNext = 0;
613  spBld->uiRoot = uiRoot;
614  }else{
615  XTHROW(spBld->spException, "root value index out of range");
616  }
617  }else{
618  XTHROW(spBld->spException, "root value index may not be zero");
619  }
620 
621  // calculate the space to allocate for each
622  aint uiBValues = uiVecLen(spBld->vpVecb);
623  if(uiBValues <= 1){
624  XTHROW(spBld->spException, "no added values to build");
625  }
626  spBld->uipChars = vpVecFirst(spBld->vpVec32);
627  spBld->spBValues = (bvalue*)vpVecFirst(spBld->vpVecb);
628  bvalue* spRoot = &spBld->spBValues[spBld->uiRoot]; // skip over the dummy build value
629  counts sCounts = {};
630  vCountWalk(spBld, &sCounts, spRoot);
631 
632  // allocate space
633  vMemFree(spBld->vpMem, spBld->spValues);
634  vMemFree(spBld->vpMem, spBld->spNumbers);
635  vMemFree(spBld->vpMem, spBld->spStrings);
636  vMemFree(spBld->vpMem, spBld->cpAscii);
637  vMemFree(spBld->vpMem, spBld->sppChildList);
638  spBld->spValues = NULL;
639  spBld->spNumbers = NULL;
640  spBld->spStrings = NULL;
641  spBld->cpAscii = NULL;
642  spBld->sppChildList = NULL;
643  spBld->spValues = (json_value*)vpMemAlloc(spBld->vpMem, ((aint)sizeof(json_value) * sCounts.uiValues));
644  memset(spBld->spValues, 0, ((aint)sizeof(json_value) * sCounts.uiValues));
645  if(sCounts.uiChildren){
646  spBld->sppChildList = (json_value**)vpMemAlloc(spBld->vpMem, ((aint)sizeof(json_value*) * sCounts.uiChildren));
647  }
648  if(sCounts.uiStrings){
649  spBld->spStrings = (u32_phrase*)vpMemAlloc(spBld->vpMem, ((aint)sizeof(u32_phrase) * sCounts.uiStrings));
650  // max number of ASCII characters needed is the number of 32-bit characters + 1 null terminator for each `string`
651  spBld->cpAscii = (char*)vpMemAlloc(spBld->vpMem, ((aint)sizeof(char) * sCounts.uiAsciis));
652  }
653  if(sCounts.uiNumbers){
654  spBld->spNumbers = (json_number*)vpMemAlloc(spBld->vpMem, ((aint)sizeof(json_number) * sCounts.uiNumbers));
655  }
656 
657  // construct the value tree
658  nexts sNexts;
659  sNexts.spNumber = spBld->spNumbers;
660  sNexts.spString = spBld->spStrings;
661  sNexts.spValue = spBld->spValues;
662  sNexts.sppList = spBld->sppChildList;
663  json_value* spValues = spBuildWalk(spBld, &sNexts, spRoot);
664 
665  // make the tree iterator
666  json_iterator* spIt = spJsonIteratorCtor(spBld->spJson);
667  spIt->sppValues = (json_value**)vpVecPushn(spIt->vpVec, NULL, sCounts.uiValues);
668  aint ui = 0;
669  for(; ui < sCounts.uiValues; ui++){
670  spIt->sppValues[ui] = &spValues[ui];
671  }
672  spIt->uiCount = sCounts.uiValues;
673  return (void*)spIt;
674 }
675 
676 static void vCountWalk(build* spBld, counts* spCounts, bvalue* spRoot){
677  bvalue* spChild;
678  aint ui;
679  spCounts->uiValues++;
680  if(spRoot->bKey){
681  spCounts->uiStrings++;
682  spCounts->uiAsciis += spRoot->uiKeyLength + 1;
683  }
684  switch(spRoot->uiId){
685  case JSON_ID_STRING:
686  spCounts->uiStrings++;
687  spCounts->uiAsciis += spRoot->uiStringLength + 1;
688  break;
689  case JSON_ID_NUMBER:
690  spCounts->uiNumbers++;
691  break;
692  case JSON_ID_TRUE:
693  case JSON_ID_FALSE:
694  case JSON_ID_NULL:
695  break;
696  case JSON_ID_OBJECT:
697  case JSON_ID_ARRAY:
698  spCounts->uiChildren += spRoot->uiChildCount;
699  spChild = spBld->spBValues + spRoot->uiChildOffset;
700  for(ui = 0; ui < spRoot->uiChildCount; ui++){
701  vCountWalk(spBld, spCounts, spChild);
702  spChild = spBld->spBValues + spChild->uiNext;
703 
704  // !!!! DEBUG sanity check
705  if(ui == (spRoot->uiChildCount - 1)){
706  if(spChild->uiNext != 0){
707  XTHROW(spBld->spException, "vCountWalk() sanity check: last child's next index is not zero");
708  break;
709  }
710  }
711  // !!!! DEBUG sanity check
712  }
713  break;
714  default:
715  XTHROW(spBld->spException, "unrecognized value type");
716  break;
717  }
718 }
719 static u32_phrase* spMakeString(build* spBld, nexts* spNexts, aint uiOffset, aint uiLength){
720  u32_phrase* spReturn = spNexts->spString;
721  spNexts->spString++;
722  spReturn->uipPhrase = spBld->uipChars + uiOffset;
723  spReturn->uiLength = (uint32_t)uiLength;
724  return spReturn;
725 }
726 static json_number* spMakeNumber(build* spBld, nexts* spNexts, bvalue* spBValue){
727  json_number* spReturn = spNexts->spNumber;
728  spNexts->spNumber++;
729  spReturn->uiType = spBValue->uiNumberId;
730  switch(spBValue->uiNumberId){
731  case JSON_ID_FLOAT:
732  spReturn->dFloat = spBValue->dNumber;
733  break;
734  case JSON_ID_SIGNED:
735  spReturn->iSigned = spBValue->iNumber;
736  break;
737  case JSON_ID_UNSIGNED:
738  spReturn->uiUnsigned = spBValue->uiNumber;
739  break;
740  default:
741  XTHROW(spBld->spException, "unrecognized number type");
742  break;
743  }
744  return spReturn;
745 }
746 static json_value* spBuildWalk(build* spBld, nexts* spNexts, bvalue* spBValue){
747  bvalue* spChild;
748  aint ui;
749  json_value* spThis = spNexts->spValue;
750  spThis->uiId = spBValue->uiId;
751  spNexts->spValue++;
752  if(spBValue->bKey){
753  spThis->spKey = spMakeString(spBld, spNexts, spBValue->uiKeyOffset, spBValue->uiKeyLength);
754  }
755  switch(spBValue->uiId){
756  case JSON_ID_STRING:
757  spThis->spString = spMakeString(spBld, spNexts, spBValue->uiStringOffset, spBValue->uiStringLength);
758  break;
759  case JSON_ID_NUMBER:
760  spThis->spNumber = spMakeNumber(spBld, spNexts, spBValue);
761  break;
762  case JSON_ID_TRUE:
763  case JSON_ID_FALSE:
764  case JSON_ID_NULL:
765  break;
766  case JSON_ID_OBJECT:
767  case JSON_ID_ARRAY:
768  spThis->sppChildren = spNexts->sppList;
769  spNexts->sppList += spBValue->uiChildCount;
770  spThis->uiChildCount = spBValue->uiChildCount;
771  spChild = spBld->spBValues + spBValue->uiChildOffset;
772  for(ui = 0; ui < spBValue->uiChildCount; ui++){
773  spThis->sppChildren[ui] = spBuildWalk(spBld, spNexts, spChild);
774  spChild = spBld->spBValues + spChild->uiNext;
775  }
776  break;
777  default:
778  XTHROW(spBld->spException, "unrecognized value type");
779  break;
780  }
781  return spThis;
782 }
783 static aint uiMakeSimple(build* spBld, aint uiType){
784  aint uiNext = uiVecLen(spBld->vpVecb);
785  bvalue* spValue = (bvalue*)vpVecPush(spBld->vpVecb, NULL);
786  memset(spValue, 0, sizeof(bvalue));
787  spValue->uiId = uiType;
788  return uiNext;
789 }
790 static void vAscii(callback_data* spData){
791  if(spData->uiParserState == ID_MATCH){
792  build* spBld = (build*)spData->vpUserData;
793  uint32_t uiChar = (uint32_t)spData->acpString[spData->uiParserOffset];
794  vpVecPush(spBld->vpVec32, &uiChar);
795  }
796 }
797 static void vRSolidus(callback_data* spData){
798  if(spData->uiParserState == ID_MATCH){
799  build* spBld = (build*)spData->vpUserData;
800  uint32_t uiChar = 0x5C;
801  vpVecPush(spBld->vpVec32, &uiChar);
802  }
803 }
804 static void vSolidus(callback_data* spData){
805  if(spData->uiParserState == ID_MATCH){
806  build* spBld = (build*)spData->vpUserData;
807  uint32_t uiChar = 0x2F;
808  vpVecPush(spBld->vpVec32, &uiChar);
809  }
810 }
811 static void vQuote(callback_data* spData){
812  if(spData->uiParserState == ID_MATCH){
813  build* spBld = (build*)spData->vpUserData;
814  uint32_t uiChar = 0x22;
815  vpVecPush(spBld->vpVec32, &uiChar);
816  }
817 }
818 static void vBackSpace(callback_data* spData){
819  if(spData->uiParserState == ID_MATCH){
820  build* spBld = (build*)spData->vpUserData;
821  uint32_t uiChar = 0x08;
822  vpVecPush(spBld->vpVec32, &uiChar);
823  }
824 }
825 static void vFormFeed(callback_data* spData){
826  if(spData->uiParserState == ID_MATCH){
827  build* spBld = (build*)spData->vpUserData;
828  uint32_t uiChar = 0x0C;
829  vpVecPush(spBld->vpVec32, &uiChar);
830  }
831 }
832 static void vLineFeed(callback_data* spData){
833  if(spData->uiParserState == ID_MATCH){
834  build* spBld = (build*)spData->vpUserData;
835  uint32_t uiChar = 0x0A;
836  vpVecPush(spBld->vpVec32, &uiChar);
837  }
838 }
839 static void vCr(callback_data* spData){
840  if(spData->uiParserState == ID_MATCH){
841  build* spBld = (build*)spData->vpUserData;
842  uint32_t uiChar = 0x0D;
843  vpVecPush(spBld->vpVec32, &uiChar);
844  }
845 }
846 static void vTab(callback_data* spData){
847  if(spData->uiParserState == ID_MATCH){
848  build* spBld = (build*)spData->vpUserData;
849  uint32_t uiChar = 0x09;
850  vpVecPush(spBld->vpVec32, &uiChar);
851  }
852 }
853 static void vUtf82(callback_data* spData){
854  if(spData->uiParserState == ID_MATCH){
855  build* spBld = (build*)spData->vpUserData;
856  char caHex[] = {
857  (char)spData->acpString[spData->uiParserOffset],
858  (char)spData->acpString[spData->uiParserOffset+1],
859  };
860  uint32_t uiChar = uiUtf8_2byte(caHex);
861  vpVecPush(spBld->vpVec32, &uiChar);
862  }
863 }
864 static void vUtf83(callback_data* spData){
865  if(spData->uiParserState == ID_MATCH){
866  build* spBld = (build*)spData->vpUserData;
867  char caHex[] = {
868  (char)spData->acpString[spData->uiParserOffset],
869  (char)spData->acpString[spData->uiParserOffset+1],
870  (char)spData->acpString[spData->uiParserOffset+2],
871  };
872  uint32_t uiChar = uiUtf8_3byte(caHex);
873  vpVecPush(spBld->vpVec32, &uiChar);
874  }
875 }
876 static void vUtf84(callback_data* spData){
877  if(spData->uiParserState == ID_MATCH){
878  build* spBld = (build*)spData->vpUserData;
879  char caHex[] = {
880  (char)spData->acpString[spData->uiParserOffset],
881  (char)spData->acpString[spData->uiParserOffset+1],
882  (char)spData->acpString[spData->uiParserOffset+2],
883  (char)spData->acpString[spData->uiParserOffset+3],
884  };
885  uint32_t uiChar = uiUtf8_4byte(caHex);
886  vpVecPush(spBld->vpVec32, &uiChar);
887  }
888 }
889 static void vUtf161(callback_data* spData){
890  if(spData->uiParserState == ID_MATCH){
891  build* spBld = (build*)spData->vpUserData;
892  const achar* acpDigits = &spData->acpString[spData->uiParserOffset];
893  char caHex[5];
894  caHex[0] = (char)acpDigits[2];
895  caHex[1] = (char)acpDigits[3];
896  caHex[2] = (char)acpDigits[4];
897  caHex[3] = (char)acpDigits[5];
898  caHex[4] = 0;
899  uint32_t uiChar;
900  if(uiUtf16_1(caHex, &uiChar) != JSON_UTF16_MATCH){
901  XTHROW(spBld->spException, "UTF-16 encoding error - surrogate pair range not allowed");
902  }
903  vpVecPush(spBld->vpVec32, &uiChar);
904  }
905 }
906 static void vUtf162(callback_data* spData){
907  if(spData->uiParserState == ID_MATCH){
908  build* spBld = (build*)spData->vpUserData;
909  const achar* acpDigits = &spData->acpString[spData->uiParserOffset];
910  char caHex[10];
911  caHex[0] = (char)acpDigits[2];
912  caHex[1] = (char)acpDigits[3];
913  caHex[2] = (char)acpDigits[4];
914  caHex[3] = (char)acpDigits[5];
915  caHex[4] = 0;
916  caHex[5] = (char)acpDigits[8];
917  caHex[6] = (char)acpDigits[9];
918  caHex[7] = (char)acpDigits[10];
919  caHex[8] = (char)acpDigits[11];
920  caHex[9] = 0;
921  uint32_t uiChar;
922  aint uiRet = uiUtf16_2(caHex, &uiChar);
923  switch(uiRet){
924  case JSON_UTF16_MATCH:
925  vpVecPush(spBld->vpVec32, &uiChar);
926  return;
927  case JSON_UTF16_NOMATCH:
928  spData->uiCallbackState = ID_NOMATCH;
929  return;
930  case JSON_UTF16_BAD_HIGH:
931  XTHROW(spBld->spException, "UTF-16 encoding error - low surrogate not preceded by high surrogate");
932  return;
933  case JSON_UTF16_BAD_LOW:
934  XTHROW(spBld->spException, "UTF-16 encoding error - high surrogate not followed by low surrogate");
935  return;
936  }
937  }
938 }
939 static void vJsonBuilderCallbacks(void* vpParserCtx){
940  aint ui;
942  memset((void*)cb, 0, sizeof(cb));
943  cb[JSON_GRAMMAR_ASCII] = vAscii;
944  cb[JSON_GRAMMAR_R_SOLIDUS] = vRSolidus;
945  cb[JSON_GRAMMAR_SOLIDUS] = vSolidus;
946  cb[JSON_GRAMMAR_QUOTE] = vQuote;
947  cb[JSON_GRAMMAR_BACKSPACE] = vBackSpace;
948  cb[JSON_GRAMMAR_FORM_FEED] = vFormFeed;
949  cb[JSON_GRAMMAR_LINE_FEED] = vLineFeed;
950  cb[JSON_GRAMMAR_CR] = vCr;
951  cb[JSON_GRAMMAR_TAB] = vTab;
952  cb[JSON_GRAMMAR_UTF16_1] = vUtf161;
953  cb[JSON_GRAMMAR_UTF16_2] = vUtf162;
954  cb[JSON_GRAMMAR_UTF8_2] = vUtf82;
955  cb[JSON_GRAMMAR_UTF8_2] = vUtf82;
956  cb[JSON_GRAMMAR_UTF8_3] = vUtf83;
957  cb[JSON_GRAMMAR_UTF8_4] = vUtf84;
958 
959  for(ui = 0; ui < (aint)RULE_COUNT_JSON_GRAMMAR; ui++){
960  vParserSetRuleCallback(vpParserCtx, ui, cb[ui]);
961  }
962 }
json_number::iSigned
int64_t iSigned
If uiType = JSON_ID_SIGNED, the signed int value.
Definition: json.h:82
spJsonIteratorCtor
json_iterator * spJsonIteratorCtor(json *spJson)
Private function for internal object use only. Never called by the application.
Definition: json.c:561
json_number::dFloat
double dFloat
If uiType = JSON_ID_FLOAT, the floating point value.
Definition: json.h:80
JSON_GRAMMAR_SOLIDUS
#define JSON_GRAMMAR_SOLIDUS
Definition: json-grammar.h:77
vpParserCtor
void * vpParserCtor(exception *spException, void *vpParserInit)
The parser's constructor for file initialization data.
Definition: parser.c:67
build::vpVec32
void * vpVec32
vector of 32-bit Unicode code points
Definition: builder.c:96
JSON_GRAMMAR_UTF16_2
#define JSON_GRAMMAR_UTF16_2
Definition: json-grammar.h:86
JSON_UTF16_NOMATCH
#define JSON_UTF16_NOMATCH
Definition: jsonp.h:173
JSON_GRAMMAR_UTF8_3
#define JSON_GRAMMAR_UTF8_3
Definition: json-grammar.h:90
JSON_GRAMMAR_ASCII
#define JSON_GRAMMAR_ASCII
Definition: json-grammar.h:40
parser_state::uiSuccess
aint uiSuccess
True (>0) if the input string was matched in its entirety, false (0) otherwise.
Definition: parser.h:184
JSON_UTF16_BAD_LOW
#define JSON_UTF16_BAD_LOW
Definition: jsonp.h:175
json
The object context. For intenrnal use only.
Definition: jsonp.h:95
counts
Internal workings only. Don't worry about it.
Definition: builder.c:45
JSON_GRAMMAR_LINE_FEED
#define JSON_GRAMMAR_LINE_FEED
Definition: json-grammar.h:67
uiJsonBuildMakeNumberF
aint uiJsonBuildMakeNumberF(void *vpBuildCtx, double dNumber)
Make a JSON floating point number value.
Definition: builder.c:336
counts::uiLists
aint uiLists
Definition: builder.c:51
callback_data::uiParserOffset
aint uiParserOffset
[read only] Offset from acpString to the first character to match
Definition: parser.h:160
json_iterator
A JSON interator object context.
Definition: jsonp.h:157
json_number
The structure of a JSON number value.
Definition: json.h:73
JSON_GRAMMAR_UTF8_2
#define JSON_GRAMMAR_UTF8_2
Definition: json-grammar.h:89
callback_data::acpString
const achar * acpString
[read only] Pointer to the input sub-string,
Definition: parser.h:156
bvalue::uiChildOffset
aint uiChildOffset
Definition: builder.c:71
uiUtf16_1
aint uiUtf16_1(char *cpHex, uint32_t *uipChar)
Definition: parser-callbacks.c:74
vVecDtor
void vVecDtor(void *vpCtx)
The vector component destructor.
Definition: vector.c:161
u32_phrase::uiLength
uint32_t uiLength
The number of integers in the array.
Definition: lib.h:75
parser_config::acpInput
const achar * acpInput
Pointer to the input string.
Definition: parser.h:199
nexts::spValue
json_value * spValue
Definition: builder.c:59
callback_data::uiParserState
aint uiParserState
[read only] ID_ACTIVE if the parser is going down the tree. ID_MATCH or ID_NOMATCH if coming up the t...
Definition: parser.h:158
JSON_GRAMMAR_QUOTE
#define JSON_GRAMMAR_QUOTE
Definition: json-grammar.h:75
build::vpMem
void * vpMem
pointer to a memory object context used only for this builder object
Definition: builder.c:95
counts::uiNumbers
aint uiNumbers
Definition: builder.c:48
vExContext
void vExContext()
Handles bad context pointers.
Definition: exception.c:126
nexts::spString
u32_phrase * spString
Definition: builder.c:60
parser_config::vpUserData
void * vpUserData
Pointer to user data, if any. Not examined or used by the parser in any way. Presented to the user's ...
Definition: parser.h:210
JSON_GRAMMAR_TAB
#define JSON_GRAMMAR_TAB
Definition: json-grammar.h:82
achar
uint_fast8_t achar
achar is the type for the parser's alphabet characters.
Definition: apg.h:91
uiUtf16_2
aint uiUtf16_2(char *cpHex, uint32_t *uipChar)
Definition: parser-callbacks.c:82
uiUtf8_3byte
uint32_t uiUtf8_3byte(char *cpBytes)
Definition: parser-callbacks.c:59
uiJsonBuildMakeNumberU
aint uiJsonBuildMakeNumberU(void *vpBuildCtx, uint64_t uiNumber)
Make a JSON unsigned integer number value.
Definition: builder.c:383
JSON_ID_STRING
#define JSON_ID_STRING
String value.
Definition: json.h:50
vParserSetRuleCallback
void vParserSetRuleCallback(void *vpCtx, aint uiRuleId, parser_callback pfnCallback)
Set a call back function for a specific rule.
Definition: parser.c:386
bvalue::uiNumberId
aint uiNumberId
Definition: builder.c:77
bvalue::uiKeyOffset
aint uiKeyOffset
Definition: builder.c:82
vpVecAt
void * vpVecAt(void *vpCtx, aint uiIndex)
Get a the indexed vector element. The vector is not altered.
Definition: vector.c:362
json-grammar.h
u32_phrase::uipPhrase
const uint32_t * uipPhrase
Pointer to an array of 32-bit unsigned integers.
Definition: lib.h:74
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
build::uiContextIndex
aint uiContextIndex
Index of the saved context pointer in the JSON context;.
Definition: builder.c:94
parser_callback
void(* parser_callback)(callback_data *spData)
User-written callback function prototype.
Definition: parser.h:178
counts::uiAsciis
aint uiAsciis
Definition: builder.c:50
RULE_COUNT_JSON_GRAMMAR
#define RULE_COUNT_JSON_GRAMMAR
Definition: json-grammar.h:97
JSON_ID_ARRAY
#define JSON_ID_ARRAY
Array value.
Definition: json.h:49
uiJsonBuildMakeFalse
aint uiJsonBuildMakeFalse(void *vpBuildCtx)
Make a JSON false value.
Definition: builder.c:417
JSON_UTF16_MATCH
#define JSON_UTF16_MATCH
Definition: jsonp.h:172
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
bvalue::uiStringOffset
aint uiStringOffset
Definition: builder.c:70
counts::uiChildren
aint uiChildren
Definition: builder.c:49
nexts::sppList
json_value ** sppList
Definition: builder.c:58
JSON_GRAMMAR_STRING_CONTENT
#define JSON_GRAMMAR_STRING_CONTENT
Definition: json-grammar.h:80
build::cpAscii
char * cpAscii
A buffer to hold all ASCII strings referenced.
Definition: builder.c:104
build::spNumbers
json_number * spNumbers
An array of all the referenced numbers.
Definition: builder.c:103
parser_config::uiInputLength
aint uiInputLength
Number of input string alphabet characters.
Definition: parser.h:200
spMemException
exception * spMemException(void *vpCtx)
Get a pointer to this memory objects's exception handler.
Definition: memory.c:174
uiJsonBuildMakeStringA
aint uiJsonBuildMakeStringA(void *vpBuildCtx, const char *cpString)
Make a string value from a null-terminated ASCII string.
Definition: builder.c:283
JSON_ID_FALSE
#define JSON_ID_FALSE
Literal value is false.
Definition: json.h:53
parser_config
Defines the input string and other configuration parameters for the parser,.
Definition: parser.h:198
JSON_ID_OBJECT
#define JSON_ID_OBJECT
Object value.
Definition: json.h:48
bvalue::iNumber
int64_t iNumber
Definition: builder.c:74
callback_data::uiCallbackState
aint uiCallbackState
[input/output] Rule name (RNM) callback functions: If ID_ACTIVE, the parser takes no action....
Definition: parser.h:139
build::uiRoot
aint uiRoot
Index of the root node build value (bvalue).
Definition: builder.c:107
counts::uiStrings
aint uiStrings
Definition: builder.c:47
json_iterator::vpVec
void * vpVec
Work vector.
Definition: jsonp.h:160
vpMemAlloc
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
Definition: memory.c:196
uiUtf8_4byte
uint32_t uiUtf8_4byte(char *cpBytes)
Definition: parser-callbacks.c:66
uiUtf8_2byte
uint32_t uiUtf8_2byte(char *cpBytes)
Definition: parser-callbacks.c:53
uiVecLen
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
Definition: vector.c:385
JSON_GRAMMAR_BACKSPACE
#define JSON_GRAMMAR_BACKSPACE
Definition: json-grammar.h:41
vpVecCtor
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
Definition: vector.c:118
json::vpMem
void * vpMem
Pointer to a memory object used for all memory allocations.
Definition: jsonp.h:99
JSON_ID_TRUE
#define JSON_ID_TRUE
Literal value is true.
Definition: json.h:52
build::spException
exception * spException
Pointer to the exception structure for reporting errors to the application catch block.
Definition: builder.c:92
parser_state
The parser's final state.
Definition: parser.h:183
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
uiJsonBuildMakeObject
aint uiJsonBuildMakeObject(void *vpBuildCtx)
Make a JSON object value.
Definition: builder.c:445
vMemFree
void vMemFree(void *vpCtx, const void *vpData)
Free memory previously allocated with vpMemAlloc().
Definition: memory.c:226
bJsonValidate
abool bJsonValidate(void *vpCtx)
Validate a JSON context pointer.
Definition: json.c:188
JSON_GRAMMAR_CR
#define JSON_GRAMMAR_CR
Definition: json-grammar.h:45
vpJsonBuild
void * vpJsonBuild(void *vpBuildCtx, aint uiRoot)
Build the JSON object.
Definition: builder.c:603
JSON_UTF16_BAD_HIGH
#define JSON_UTF16_BAD_HIGH
Definition: jsonp.h:174
uiJsonBuildMakeStringU
aint uiJsonBuildMakeStringU(void *vpBuildCtx, const uint32_t *uipData, aint uiLength)
Make a string value from UTF-32 code points.
Definition: builder.c:223
ID_MATCH
#define ID_MATCH
indicates a matched phrase parser state on return from parse tree below this node
Definition: parser.h:73
luint
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
Definition: apg.h:133
uiJsonBuildAddToObject
aint uiJsonBuildAddToObject(void *vpBuildCtx, aint uiObject, aint uiKey, aint uiAdd)
Add a child value to a parent object value.
Definition: builder.c:479
callback_data
The data struct passed to each callback function.
Definition: parser.h:134
build::spJson
json * spJson
JSON object context pointer. Used only for string conversions.
Definition: builder.c:99
vJsonBuildClear
void vJsonBuildClear(void *vpBuildCtx)
Clears all memory associated with this builder object.
Definition: builder.c:184
bvalue::uiNumber
uint64_t uiNumber
Definition: builder.c:73
build::vpVecAchars
void * vpVecAchars
Vector for temporary achar representation of a string.
Definition: builder.c:97
bvalue::dNumber
double dNumber
Definition: builder.c:72
vpVecFirst
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
Definition: vector.c:326
JSON_ID_FLOAT
#define JSON_ID_FLOAT
Number value is a double floating point number.
Definition: json.h:62
vpVecPushn
void * vpVecPushn(void *vpCtx, void *vpElement, aint uiCount)
Adds one or more elements to the end of the array.
Definition: vector.c:221
JSON_GRAMMAR_UTF16_1
#define JSON_GRAMMAR_UTF16_1
Definition: json-grammar.h:85
jsonp.h
Private JSON component header file.
bvalue
A builder value. Internal workings only. Don't worry about it.
Definition: builder.c:67
vJsonBuildDtor
void vJsonBuildDtor(void *vpBuildCtx)
The builder object destructor.
Definition: builder.c:154
bvalue::uiChildCount
aint uiChildCount
Definition: builder.c:79
build::sppChildList
json_value ** sppChildList
Pointer to a array of pointers to the children values.
Definition: builder.c:106
nexts::spNumber
json_number * spNumber
Definition: builder.c:61
build::uipChars
uint32_t * uipChars
Points to the list of 32-bit characters.
Definition: builder.c:100
build
The builder object context.
Definition: builder.c:90
json_iterator::uiCount
aint uiCount
The number of pointers in the list.
Definition: jsonp.h:162
counts::uiValues
aint uiValues
Definition: builder.c:46
uiJsonBuildMakeTrue
aint uiJsonBuildMakeTrue(void *vpBuildCtx)
Make a JSON true value.
Definition: builder.c:403
callback_data::vpUserData
void * vpUserData
[input/output] User-defined data passed to to the parser in parser_config.
Definition: parser.h:136
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
json_iterator::sppValues
json_value ** sppValues
List of pointers to values.
Definition: jsonp.h:161
build::vpValidate
const void * vpValidate
"magic number" for object validation
Definition: builder.c:91
uiJsonBuildMakeArray
aint uiJsonBuildMakeArray(void *vpBuildCtx)
Makea JSON array value.
Definition: builder.c:459
json::vpVecBuilders
void * vpVecBuilders
A vector of builder context pointers remembered for destruction.
Definition: jsonp.h:102
vParserDtor
void vParserDtor(void *vpCtx)
Clears the parser component's context and frees all heap memory associated with this parser.
Definition: parser.c:245
uiJsonBuildAddToArray
aint uiJsonBuildAddToArray(void *vpBuildCtx, aint uiArray, aint uiAdd)
Add a child value to a parent array value.
Definition: builder.c:550
json_number::uiUnsigned
uint64_t uiUnsigned
If uiType = JSON_ID_UNSIGNED, the unsigned int value.
Definition: json.h:81
build::spBValues
bvalue * spBValues
Points to the first bvalue.
Definition: builder.c:101
build::vpVecb
void * vpVecb
vector of bvalue structs holding the user values from the Make & Add functions
Definition: builder.c:98
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
build::vpUserData
void * vpUserData
Pointer to user data. Available to the error handling routine.
Definition: builder.c:108
json.h
Header file for the JSON component. Defines API prototypes.
JSON_ID_SIGNED
#define JSON_ID_SIGNED
Number value is a 64-bit signed integer.
Definition: json.h:63
bvalue::uiId
aint uiId
Definition: builder.c:68
parser_config::uiStartRule
aint uiStartRule
Index of the start rule. Any rule in the SABNF grammar may be used as the start rule.
Definition: parser.h:201
ID_NOMATCH
#define ID_NOMATCH
indicates that no phrase was matched on return from parse tree below this node
Definition: parser.h:74
build::spValues
json_value * spValues
An array of the final value tree.
Definition: builder.c:105
JSON_ID_UNSIGNED
#define JSON_ID_UNSIGNED
Number value is a 64-bit unsigned integer.
Definition: json.h:64
uiJsonBuildMakeNumberS
aint uiJsonBuildMakeNumberS(void *vpBuildCtx, int64_t iNumber)
Make a JSON signed integer number value.
Definition: builder.c:358
bvalue::uiNext
aint uiNext
Definition: builder.c:81
json_number::uiType
aint uiType
Identifies the number type. One of.
Definition: json.h:74
JSON_GRAMMAR_FORM_FEED
#define JSON_GRAMMAR_FORM_FEED
Definition: json-grammar.h:58
uiJsonBuildMakeNull
aint uiJsonBuildMakeNull(void *vpBuildCtx)
Make a JSON null value.
Definition: builder.c:431
JSON_GRAMMAR_R_SOLIDUS
#define JSON_GRAMMAR_R_SOLIDUS
Definition: json-grammar.h:76
u32_phrase
Defines a pointer to an array of 32-bit unsigned integers plus its length. Typically needed by Unicod...
Definition: lib.h:73
JSON_ID_NULL
#define JSON_ID_NULL
Literal value is null.
Definition: json.h:54
bvalue::bKey
abool bKey
Definition: builder.c:84
JSON_GRAMMAR_UTF8_4
#define JSON_GRAMMAR_UTF8_4
Definition: json-grammar.h:91
bvalue::uiStringLength
aint uiStringLength
Definition: builder.c:78
vpJsonGrammarInit
void * vpJsonGrammarInit
Definition: json-grammar.c:1631
vpVecPush
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
Definition: vector.c:193
bvalue::uiKeyLength
aint uiKeyLength
Definition: builder.c:83
JSON_ID_NUMBER
#define JSON_ID_NUMBER
Number value.
Definition: json.h:51
vVecClear
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
Definition: vector.c:420
build::spStrings
u32_phrase * spStrings
An array of all the referenced strings.
Definition: builder.c:102
nexts
Internal workings only. Don't worry about it.
Definition: builder.c:57
APG_FALSE
#define APG_FALSE
Definition: apg.h:292
vpJsonBuildCtor
void * vpJsonBuildCtor(void *vpJsonCtx)
The builder object constructor.
Definition: builder.c:124
vParserParse
void vParserParse(void *vpCtx, parser_config *spConfig, parser_state *spState)
Parse an input string of alphabet characters.
Definition: parser.c:268
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.