Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
parser-callbacks.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 <stdio.h>
37 #include <limits.h>
38 #include "./json.h"
39 #include "./jsonp.h"
40 #include "./json-grammar.h"
41 
45 #define THROW_ERROR(msg, off) vThrowError(spJson, (msg), (off), __FILE__, __func__, __LINE__)
46 
47 /*********************************************************
48  * helper functions
49  *********************************************************/
52 uint32_t uiUtf8_2byte(char* cpBytes){
54  uint32_t uiChar = 0;
55  uiChar = ((uint32_t)cpBytes[0] & 0x1f) << 6;
56  uiChar += (uint32_t)cpBytes[1] & 0x3f;
57  return uiChar;
58 }
59 uint32_t uiUtf8_3byte(char* cpBytes){
60  uint32_t uiChar = 0;
61  uiChar = ((uint32_t)cpBytes[0] & 0xf) << 12;
62  uiChar += ((uint32_t)cpBytes[1] & 0x3f) << 6;
63  uiChar += (uint32_t)cpBytes[2] & 0x3f;
64  return uiChar;
65 }
66 uint32_t uiUtf8_4byte(char* cpBytes){
67  uint32_t uiChar = 0;
68  uiChar = ((uint32_t)cpBytes[0] & 0x7) << 18;
69  uiChar += ((uint32_t)cpBytes[1] & 0x3f) << 12;
70  uiChar += ((uint32_t)cpBytes[2] & 0x3f) << 6;
71  uiChar += (uint32_t)cpBytes[3] & 0x3f;
72  return uiChar;
73 }
74 aint uiUtf16_1(char* cpHex, uint32_t* uipChar){
75  char* cpPtr;
76  *uipChar = (uint32_t)strtol(cpHex, &cpPtr, 16);
77  if(*uipChar >= 0xD800 && *uipChar < 0xE000){
78  return JSON_UTF16_BAD_LOW;
79  }
80  return JSON_UTF16_MATCH;
81 }
82 aint uiUtf16_2(char* cpHex, uint32_t* uipChar){
83  char* cpPtr;
84  uint32_t uiHigh = (uint32_t)strtol(cpHex, &cpPtr, 16);
85  if(uiHigh < 0xD800 || uiHigh >= 0xE000){
86  // not a surrogate pair
87  return JSON_UTF16_NOMATCH;
88  }
89  if(uiHigh >= 0xDC00){
90  return JSON_UTF16_BAD_HIGH;
91  }
92  uint32_t uiLow = (uint32_t)strtol(&cpHex[5], &cpPtr, 16);
93  if(!(uiLow >= 0xDC00 && uiLow < 0xE000)){
94  return JSON_UTF16_BAD_LOW;
95  }
96  // decode the surrogate pairs
97  uiHigh = (uiHigh - 0xd800) << 10;
98  uiLow -= 0xdc00;
99  *uipChar = uiHigh + uiLow + 0x10000;
100  return JSON_UTF16_MATCH;
101 }
103 
104 static void vThrowError(json* spJson, char* cpMsg, aint uiOffset,
105  const char* cpFile, const char* cpFunc, unsigned int uiCodeLine){
106  aint uiLine, uiRelOffset;
107  char caBuf[1024];
108  if(bLinesFindLine(spJson->vpLines, uiOffset, &uiLine, &uiRelOffset)){
109  snprintf(caBuf, 1024,
110  "%s: near: line: %"PRIuMAX": character: %"PRIuMAX" (0x%"PRIXMAX")",
111  cpMsg, (luint)uiLine, (luint)uiRelOffset, (luint)uiRelOffset);
112  }else{
113  snprintf(caBuf, 1024,
114  "%s: character offset out of range: %"PRIuMAX" (0x%"PRIXMAX")",
115  cpMsg, (luint)uiOffset, (luint)uiOffset);
116  }
117  vExThrow(spJson->spException, caBuf, uiCodeLine, cpFile, cpFunc);
118 }
119 static void vPushFrameAndValue(callback_data* spData){
120  json* spJson = (json*)spData->vpUserData;
121  frame* spPrev = spJson->spCurrentFrame;
122  frame* spCurrent = (frame*)vpVecPush(spJson->vpVecFrames, NULL);
123  memset((void*)spCurrent, 0, sizeof(frame));
124  spCurrent->uiNextKey = APG_UNDEFINED;
125  spCurrent->vpVecIndexes = vpVecCtor(spJson->vpMem, sizeof(aint), 128);
126  spCurrent->uiValue = uiVecLen(spJson->vpVecValuesr);
127  value_r* spValuer = (value_r*)vpVecPush(spJson->vpVecValuesr, NULL);
128  if(spPrev){
129  spValuer->uiKey = spPrev->uiNextKey;
130  }else{
131  spValuer->uiKey = APG_UNDEFINED;
132  }
133  spJson->spCurrentFrame = spCurrent;
134 }
135 
136 // return remaining number of frames on the stack
137 static void vPopFrame(callback_data* spData){
138  json* spJson = (json*)spData->vpUserData;
139  if(spJson->spCurrentFrame){
140  frame* spFrame = (frame*)vpVecPop(spJson->vpVecFrames);
141  // sanity check
142  if(spFrame != spJson->spCurrentFrame){
143  THROW_ERROR("popped frame not same as current frame", spData->uiParserOffset);
144  }
145  vVecDtor(spFrame->vpVecIndexes);
146  spJson->spCurrentFrame = (frame*)vpVecLast(spJson->vpVecFrames);
147  }
148 }
149 
150 static value_r* spFrameValue(json* spJson, frame* spFrame, aint uiOffset){
151  value_r* spValuer = (value_r*)vpVecAt(spJson->vpVecValuesr, spFrame->uiValue);
152  if(!spValuer){
153  THROW_ERROR("vector index out of range", uiOffset);
154  }
155  return spValuer;
156 }
157 static abool bMultiplyUint(uint64_t uiL, uint64_t uiR, uint64_t* uipA){
158  if(uiL == 0 || uiR == 0){
159  *uipA = 0;
160  return APG_SUCCESS;
161  }
162  uint64_t uiTest = uiL * uiR;
163  uint64_t uiCheck = uiTest / uiR;
164  if(uiCheck != uiL){
165  return APG_FAILURE;
166  }
167  *uipA = uiTest;
168  return APG_SUCCESS;
169 }
170 
171 static abool bSumUint(uint64_t uiL, uint64_t uiR, uint64_t* uipA){
172  uint64_t uiTest = uiL + uiR;
173  if(uiTest < uiR){
174  return APG_FAILURE;
175  }
176  uint64_t uiCheck = uiTest - uiR;
177  if(uiCheck != uiL){
178  return APG_FAILURE;
179  }
180  *uipA = uiTest;
181  return APG_SUCCESS;
182 }
183 static abool bMultiplyInt(int64_t iL, int64_t iR, int64_t * ipA){
184  if(iL == 0 || iR == 0){
185  *ipA = 0;
186  return APG_SUCCESS;
187  }
188  int64_t iTest = iL * iR;
189  if(iTest < 0){
190  return APG_FAILURE;
191  }
192  *ipA = iTest;
193  return APG_SUCCESS;
194 }
195 static abool bSumInt(int64_t iL, int64_t iR, int64_t* ipA){
196  int64_t iTest = iL + iR;
197  if(iTest < 0){
198  return APG_FAILURE;
199  }
200  *ipA = iTest;
201  return APG_SUCCESS;
202 }
203 static abool bStringToInt(char* cpString, int64_t* ipInt){
204  abool bReturn = APG_FAILURE;
205  *ipInt = 0;
206  while(APG_TRUE){
207  char* cpEnd = cpString + strlen(cpString);
208  int64_t iVal = *cpString++ - 48;
209  while(cpString < cpEnd){
210  if(!bMultiplyInt(iVal, 10LL, &iVal)){
211  goto fail;
212  }
213  if(!bSumInt(iVal, (int64_t)(*cpString++ - 48), &iVal)){
214  goto fail;
215  }
216  }
217  *ipInt = iVal;
218  bReturn = APG_SUCCESS;
219  break;
220  }
221  fail:;
222  return bReturn;
223 }
224 static abool bStringToUint(char* cpString, uint64_t* uipInt){
225  abool bReturn = APG_FAILURE;
226  *uipInt = 0;
227  while(APG_TRUE){
228  char* cpEnd = cpString + strlen(cpString);
229  uint64_t uiVal = *cpString++ - 48;
230  while(cpString < cpEnd){
231  if(!bMultiplyUint(uiVal, 10LL, &uiVal)){
232  goto fail;
233  }
234  if(!bSumUint(uiVal, (int64_t)(*cpString++ - 48), &uiVal)){
235  goto fail;
236  }
237  }
238  *uipInt = uiVal;
239  bReturn = APG_SUCCESS;
240  break;
241  }
242  fail:;
243  return bReturn;
244 }
245 /*********************************************************
246  * helper functions
247  *********************************************************/
248 
249 /*********************************************************
250  * call back functions
251  *********************************************************/
252 static void vJsonText(callback_data* spData){
253  json* spJson = (json*)spData->vpUserData;
254  if(spData->uiParserState == ID_ACTIVE){
255  // clear all memory from previous parse, if any
256  vVecClear(spJson->vpVecStringsr);
257  vVecClear(spJson->vpVecChildIndexes);
258  vVecClear(spJson->vpVecChars);
259  vVecClear(spJson->vpVecAscii);
260  vVecClear(spJson->vpVecValuesr);
261  vVecClear(spJson->vpVecNumbers);
262  vVecClear(spJson->vpVecFrames);
263  vVecClear(spJson->vpVecValues);
264  vVecClear(spJson->vpVecStrings);
265  vVecClear(spJson->vpVecChildPointers);
266  }else if(spData->uiParserState == ID_MATCH){
267  if(spData->uiParserPhraseLength < spData->uiStringLength){
268  THROW_ERROR("parser did not match the entire document", spData->uiParserOffset);
269  }
270  char caBuf[64];
271  // convert relative values to absolute values
272  uint32_t* uipChars = (uint32_t*)vpVecFirst(spJson->vpVecChars);
273  string_r* spStringsr = (string_r*)vpVecFirst(spJson->vpVecStringsr);
274  spJson->uiStringCount = uiVecLen(spJson->vpVecStringsr);
275  string_r* spStringrBeg = spStringsr;
276  string_r* spStringrEnd = spStringrBeg + spJson->uiStringCount;
278  value_r* spValuesr = (value_r*)vpVecFirst(spJson->vpVecValuesr);
279  spJson->uiValueCount = uiVecLen(spJson->vpVecValuesr);
280  value_r* spValuerBeg = spValuesr;
281  value_r* spValuerEnd = spValuerBeg + spJson->uiValueCount;
282  aint* uipChildIndexes = (aint*)vpVecFirst(spJson->vpVecChildIndexes);
284  aint* uipChildList;
285  aint ui;
286 
287  // allocate the child value pointer list
288  spJson->sppChildPointers = (struct json_value_tag**)vpVecPushn(spJson->vpVecChildPointers, NULL, uiChildCount);
289 
290  // allocate the strings and convert all relative strings to absolute
291  spJson->spStrings = (u32_phrase*)vpVecPushn(spJson->vpVecStrings, NULL, spJson->uiStringCount);
292  u32_phrase* spString = spJson->spStrings;
293  for(; spStringrBeg < spStringrEnd; spStringrBeg++, spString++){
294  spString->uiLength = spStringrBeg->uiLength;
295  spString->uipPhrase = uipChars + spStringrBeg->uiCharsOffset;
296  }
297 
298  // allocate the values and convert relative indexes to absolute pointers
299  spJson->spValues = (json_value*)vpVecPushn(spJson->vpVecValues, NULL, spJson->uiValueCount);
300  memset((void*)spJson->spValues, 0, (sizeof(json_value) * spJson->uiValueCount));
301  json_value* spValue = spJson->spValues;
302  aint uiChildPointerTop = 0;
303  for(; spValuerBeg < spValuerEnd; spValuerBeg++, spValue++){
304  spValue->uiId = spValuerBeg->uiId;
305  if(spValuerBeg->uiKey == APG_UNDEFINED){
306  spValue->spKey = NULL;
307  }else{
308  spValue->spKey = &spJson->spStrings[spValuerBeg->uiKey];
309  }
310  spValue->sppChildren = NULL;
311  spValue->uiChildCount = 0;
312  switch(spValuerBeg->uiId){
313  case JSON_ID_STRING:
314  spValue->spString = &spJson->spStrings[spValuerBeg->uiString];
315  break;
316  case JSON_ID_TRUE:
317  case JSON_ID_FALSE:
318  case JSON_ID_NULL:
319  break;
320  case JSON_ID_NUMBER:
321  spValue->spNumber = &spNumber[spValuerBeg->uiNumber];
322  break;
323  case JSON_ID_OBJECT:
324  case JSON_ID_ARRAY:
325  // convert the array of child indexes to an array of absolute pointers
326  uipChildList = &uipChildIndexes[spValuerBeg->uiChildListOffset];
327  spValue->uiChildCount = spValuerBeg->uiChildCount;
328  spValue->sppChildren = &spJson->sppChildPointers[uiChildPointerTop];
329  for(ui = 0; ui < spValuerBeg->uiChildCount; ui++, uipChildList++){
330  spJson->sppChildPointers[uiChildPointerTop++] = (struct json_value_tag*)(spJson->spValues + *uipChildList);
331  }
332  break;
333  default:
334  snprintf(caBuf, 64, "unrecognized value type: %"PRIuMAX"", (luint)spValuerBeg->uiId);
335  THROW_ERROR(caBuf, spData->uiParserOffset);
336  break;
337  }
338  }
339  }else if(spData->uiParserState == ID_NOMATCH){
340  THROW_ERROR("JSON-text not matched but no identifiable errors found", spData->uiParserOffset);
341  }
342 }
343 static void vValue(callback_data* spData){
344  json* spJson = (json*)spData->vpUserData;
345  if(spData->uiParserState == ID_ACTIVE){
346  // push value and frame
347  vPushFrameAndValue(spData);
348  }else if(spData->uiParserState == ID_MATCH){
349  // complete the value
350  frame* spFrame = spJson->spCurrentFrame;
351  aint uiValueIndex = spFrame->uiValue;
352  value_r* spValue = spFrameValue(spJson, spFrame, spData->uiParserOffset);
353  spValue->uiChildCount = uiVecLen(spFrame->vpVecIndexes);
354  if(spValue->uiChildCount){
355  // copy the vector of indexes
356  aint* uipChildIndex = (aint*)vpVecFirst(spFrame->vpVecIndexes);
357  spValue->uiChildListOffset = uiVecLen(spJson->vpVecChildIndexes);
358  aint* uipIndex = (aint*)vpVecPushn(spJson->vpVecChildIndexes, NULL, spValue->uiChildCount);
359  aint* uipEnd = uipIndex + spValue->uiChildCount;
360  while(uipIndex < uipEnd){
361  *uipIndex++ = *uipChildIndex++;
362  }
363  }
364  // pop the frame
365  vPopFrame(spData);
366  if(spJson->spCurrentFrame){
367  // report this value as a child of the parent value
368  vpVecPush(spJson->spCurrentFrame->vpVecIndexes, &uiValueIndex);
369  }
370  }else if(spData->uiParserState == ID_NOMATCH){
371  // pop value and frame
372  vPopFrame(spData);
373  vpVecPop(spJson->vpVecValuesr);
374  }
375 }
376 static void vEndMemberSep(callback_data* spData){
377  if(spData->uiParserState == ID_MATCH){
378  json* spJson = (json*)spData->vpUserData;
379  THROW_ERROR("Trailing comma not allowed in objects (REF8259)", spData->uiParserOffset);
380  }
381 }
382 static void vEndValueSep(callback_data* spData){
383  if(spData->uiParserState == ID_MATCH){
384  json* spJson = (json*)spData->vpUserData;
385  THROW_ERROR("Trailing comma not allowed in arrays (REF8259)", spData->uiParserOffset);
386  }
387 }
388 static void vObjectBegin(callback_data* spData){
389  if(spData->uiParserState == ID_MATCH){
390  json* spJson = (json*)spData->vpUserData;
391  frame* spFrame = spJson->spCurrentFrame;
392  value_r* spValue = spFrameValue(spJson, spFrame, spData->uiParserOffset);
393  spValue->uiId = JSON_ID_OBJECT;
394  }
395 }
396 static void vObjectEnd(callback_data* spData){
397  if(spData->uiParserState == ID_NOMATCH){
398  json* spJson = (json*)spData->vpUserData;
399  THROW_ERROR("Expected closing object bracket '}' not found.", spData->uiParserOffset);
400  }
401 }
402 static void vArrayBegin(callback_data* spData){
403  if(spData->uiParserState == ID_MATCH){
404  json* spJson = (json*)spData->vpUserData;
405  frame* spFrame = spJson->spCurrentFrame;
406  value_r* spValue = spFrameValue(spJson, spFrame, spData->uiParserOffset);
407  spValue->uiId = JSON_ID_ARRAY;
408  }
409 }
410 static void vArrayEnd(callback_data* spData){
411  if(spData->uiParserState == ID_NOMATCH){
412  json* spJson = (json*)spData->vpUserData;
413  THROW_ERROR("Expected closing array bracket ']' not found.", spData->uiParserOffset);
414  }
415 }
416 static void vFalse(callback_data* spData){
417  if(spData->uiParserState == ID_MATCH){
418  json* spJson = (json*)spData->vpUserData;
419  frame* spFrame = spJson->spCurrentFrame;
420  value_r* spValue = spFrameValue(spJson, spFrame, spData->uiParserOffset);
421  spValue->uiId = JSON_ID_FALSE;
422  }
423 }
424 static void vTrue(callback_data* spData){
425  if(spData->uiParserState == ID_MATCH){
426  json* spJson = (json*)spData->vpUserData;
427  frame* spFrame = spJson->spCurrentFrame;
428  value_r* spValue = spFrameValue(spJson, spFrame, spData->uiParserOffset);
429  spValue->uiId = JSON_ID_TRUE;
430  }
431 }
432 static void vNull(callback_data* spData){
433  if(spData->uiParserState == ID_MATCH){
434  json* spJson = (json*)spData->vpUserData;
435  frame* spFrame = spJson->spCurrentFrame;
436  value_r* spValue = spFrameValue(spJson, spFrame, spData->uiParserOffset);
437  spValue->uiId = JSON_ID_NULL;
438  }
439 }
440 static void vKeyBegin(callback_data* spData){
441  if(spData->uiParserState == ID_MATCH){
442  json* spJson = (json*)spData->vpUserData;
443  spJson->spCurrentFrame->uiNextKey = uiVecLen(spJson->vpVecStringsr);
444 
445  // push a new string and initialize it
446  string_r* spString = (string_r*)vpVecPush(spJson->vpVecStringsr, NULL);
447  spString->uiCharsOffset = uiVecLen(spJson->vpVecChars);
448  }
449 }
450 static void vStringBegin(callback_data* spData){
451  if(spData->uiParserState == ID_MATCH){
452  json* spJson = (json*)spData->vpUserData;
453  frame* spFrame = spJson->spCurrentFrame;
454  value_r* spValue = spFrameValue(spJson, spFrame, spData->uiParserOffset);
455  spValue->uiId = JSON_ID_STRING;
456  spValue->uiString = uiVecLen(spJson->vpVecStringsr);
457 
458  // push a new string and initialize it
459  string_r* spString = (string_r*)vpVecPush(spJson->vpVecStringsr, NULL);
460  spString->uiCharsOffset = uiVecLen(spJson->vpVecChars);
461  }
462 }
463 static void vStringEnd(callback_data* spData){
464  if (spData->uiParserState == ID_NOMATCH) {
465  json *spJson = (json*) spData->vpUserData;
466  THROW_ERROR("Expected close of string not found.", spData->uiParserOffset);
467  }
468 }
469 static void vStringContent(callback_data* spData){
470  if(spData->uiParserState == ID_MATCH){
471  json* spJson = (json*)spData->vpUserData;
473  spString->uiLength = uiVecLen(spJson->vpVecChars) - spString->uiCharsOffset;
474  }
475 }
476 static void vChar(callback_data* spData){
477  if(spData->uiParserState == ID_MATCH){
478  json* spJson = (json*)spData->vpUserData;
479  // push the character on the character string vector
480  vpVecPush(spJson->vpVecChars, &spJson->uiChar);
481  }else if(spData->uiParserState == ID_NOMATCH){
482  json* spJson = (json*)spData->vpUserData;
483  if((char)spData->acpString[spData->uiParserOffset] != 34){
484  THROW_ERROR("invalid character detected - probably mal-formed UTF-8", spData->uiParserOffset);
485  }
486  }
487 }
488 static void vAscii(callback_data* spData){
489  if(spData->uiParserState == ID_MATCH){
490  json* spJson = (json*)spData->vpUserData;
491  spJson->uiChar = (uint32_t)spData->acpString[spData->uiParserOffset];
492  }
493 }
494 static void vUtf82(callback_data* spData){
495  if(spData->uiParserState == ID_MATCH){
496  json* spJson = (json*)spData->vpUserData;
497  char caHex[] = {
498  (char)spData->acpString[spData->uiParserOffset],
499  (char)spData->acpString[spData->uiParserOffset+1],
500  };
501  spJson->uiChar = uiUtf8_2byte(caHex);
502  }
503 }
504 static void vUtf83(callback_data* spData){
505  if(spData->uiParserState == ID_MATCH){
506  json* spJson = (json*)spData->vpUserData;
507  char caHex[] = {
508  (char)spData->acpString[spData->uiParserOffset],
509  (char)spData->acpString[spData->uiParserOffset+1],
510  (char)spData->acpString[spData->uiParserOffset+2],
511  };
512  spJson->uiChar = uiUtf8_3byte(caHex);
513  }
514 }
515 static void vUtf84(callback_data* spData){
516  if(spData->uiParserState == ID_MATCH){
517  json* spJson = (json*)spData->vpUserData;
518  char caHex[] = {
519  (char)spData->acpString[spData->uiParserOffset],
520  (char)spData->acpString[spData->uiParserOffset+1],
521  (char)spData->acpString[spData->uiParserOffset+2],
522  (char)spData->acpString[spData->uiParserOffset+3],
523  };
524  spJson->uiChar = uiUtf8_4byte(caHex);
525  }
526 }
527 static void vRSolidus(callback_data* spData){
528  if(spData->uiParserState == ID_MATCH){
529  json* spJson = (json*)spData->vpUserData;
530  spJson->uiChar = 0x5C;
531  }
532 }
533 static void vSolidus(callback_data* spData){
534  if(spData->uiParserState == ID_MATCH){
535  json* spJson = (json*)spData->vpUserData;
536  spJson->uiChar = 0x2F;
537  }
538 }
539 static void vQuote(callback_data* spData){
540  if(spData->uiParserState == ID_MATCH){
541  json* spJson = (json*)spData->vpUserData;
542  spJson->uiChar = 0x22;
543  }
544 }
545 static void vBackSpace(callback_data* spData){
546  if(spData->uiParserState == ID_MATCH){
547  json* spJson = (json*)spData->vpUserData;
548  spJson->uiChar = 0x08;
549  }
550 }
551 static void vFormFeed(callback_data* spData){
552  if(spData->uiParserState == ID_MATCH){
553  json* spJson = (json*)spData->vpUserData;
554  spJson->uiChar = 0x0C;
555  }
556 }
557 static void vLineFeed(callback_data* spData){
558  if(spData->uiParserState == ID_MATCH){
559  json* spJson = (json*)spData->vpUserData;
560  spJson->uiChar = 0x0A;
561  }
562 }
563 static void vCr(callback_data* spData){
564  if(spData->uiParserState == ID_MATCH){
565  json* spJson = (json*)spData->vpUserData;
566  spJson->uiChar = 0x0D;
567  }
568 }
569 static void vTab(callback_data* spData){
570  if(spData->uiParserState == ID_MATCH){
571  json* spJson = (json*)spData->vpUserData;
572  spJson->uiChar = 0x09;
573  }
574 }
575 static void vUtf161(callback_data* spData){
576  if(spData->uiParserState == ID_MATCH){
577  json* spJson = (json*)spData->vpUserData;
578  const achar* acpDigits = &spData->acpString[spData->uiParserOffset];
579  char caHex[5];
580  caHex[0] = (char)acpDigits[2];
581  caHex[1] = (char)acpDigits[3];
582  caHex[2] = (char)acpDigits[4];
583  caHex[3] = (char)acpDigits[5];
584  caHex[4] = 0;
585  if(uiUtf16_1(caHex, &spJson->uiChar) != JSON_UTF16_MATCH){
586  THROW_ERROR("UTF-16 encoding error - surrogate pair range not allowed", spData->uiParserOffset);
587  }
588  }
589 }
590 static void vUtf162(callback_data* spData){
591  if(spData->uiParserState == ID_MATCH){
592  json* spJson = (json*)spData->vpUserData;
593  const achar* acpDigits = &spData->acpString[spData->uiParserOffset];
594  char caHex[10];
595  caHex[0] = (char)acpDigits[2];
596  caHex[1] = (char)acpDigits[3];
597  caHex[2] = (char)acpDigits[4];
598  caHex[3] = (char)acpDigits[5];
599  caHex[4] = 0;
600  caHex[5] = (char)acpDigits[8];
601  caHex[6] = (char)acpDigits[9];
602  caHex[7] = (char)acpDigits[10];
603  caHex[8] = (char)acpDigits[11];
604  caHex[9] = 0;
605  aint uiRet = uiUtf16_2(caHex, &spJson->uiChar);
606  switch(uiRet){
607  case JSON_UTF16_MATCH:
608  return;
609  case JSON_UTF16_NOMATCH:
610  spData->uiCallbackState = ID_NOMATCH;
611  return;
612  case JSON_UTF16_BAD_HIGH:
613  THROW_ERROR("UTF-16 encoding error - low surrogate not preceded by high surrogate", spData->uiParserOffset);
614  return;
615  case JSON_UTF16_BAD_LOW:
616  THROW_ERROR("UTF-16 encoding error - high surrogate not followed by low surrogate", spData->uiParserOffset);
617  return;
618  }
619  }
620 }
621 static void vNumber(callback_data* spData){
622  if(spData->uiParserState == ID_ACTIVE){
623  json* spJson = (json*)spData->vpUserData;
624  spJson->bHasFrac = APG_FALSE;
625  spJson->bHasMinus = APG_FALSE;
626  }else if(spData->uiParserState == ID_MATCH){
627  json* spJson = (json*)spData->vpUserData;
628  char caBuf[128];
629  value_r* spValue = spFrameValue(spJson, spJson->spCurrentFrame, spData->uiParserOffset);
630  spValue->uiId = JSON_ID_NUMBER;
631  spValue->uiNumber = uiVecLen(spJson->vpVecNumbers);
633  // use the top of vpVecAscii as a working string
634  aint uiTop = uiVecLen(spJson->vpVecAscii);
635  char* cpNumber = (char*)vpVecPushn(spJson->vpVecAscii, NULL, (spData->uiParserPhraseLength + 1));
636  aint ui = 0;
637  char* cpPtr;
638  const achar* acpParsed = &spData->acpString[spData->uiParserOffset];
639  for(;ui < spData->uiParserPhraseLength; ui++){
640  cpNumber[ui] = (char)acpParsed[ui];
641  }
642  cpNumber[ui] = 0;
643  while(APG_TRUE){
644  if(spJson->bHasFrac){
645  spNumber->dFloat = strtod(cpNumber, &cpPtr);
646  if(cpPtr > cpNumber){
648  break;
649  }
650  snprintf(caBuf, 128, "Unable to convert floating point string with \"strtod()\": %s", cpNumber);
651  THROW_ERROR(caBuf, spData->uiParserOffset);
652  break;
653  }
654  if(spJson->bHasMinus){
655  if(!bStringToInt(&cpNumber[1], &spNumber->iSigned)){
656  snprintf(caBuf, 128, "Integer value too large to convert to int: %s", cpNumber);
657  THROW_ERROR(caBuf, spData->uiParserOffset);
658  }
661  break;
662  }
663  if(!bStringToUint(cpNumber, &spNumber->uiUnsigned)){
664  snprintf(caBuf, 128, "Integer value too large to convert to unsigned int: %s", cpNumber);
665  THROW_ERROR(caBuf, spData->uiParserOffset);
666  }
668  break;
669  }
670  // pop off the working string
671  vpVecPopi(spJson->vpVecAscii, uiTop);
672  }
673 }
674 static void vFracOnly(callback_data* spData){
675  if(spData->uiParserState == ID_MATCH){
676  json* spJson = (json*)spData->vpUserData;
677  THROW_ERROR("Fraction found with no leading integer. Not allowed by RFC 8259.", spData->uiParserOffset);
678  }
679 }
680 static void vFrac(callback_data* spData){
681  if(spData->uiParserState == ID_MATCH){
682  json* spJson = (json*)spData->vpUserData;
683  spJson->bHasFrac= APG_TRUE;
684  }
685 }
686 static void vFracDigits(callback_data* spData){
687  if(spData->uiParserState == ID_NOMATCH){
688  json* spJson = (json*)spData->vpUserData;
689  THROW_ERROR("A decimal point must be followed by one or more digits (REF8259)", spData->uiParserOffset);
690  }
691 }
692 static void vMinus(callback_data* spData){
693  if(spData->uiParserState == ID_MATCH){
694  json* spJson = (json*)spData->vpUserData;
695  spJson->bHasMinus = APG_TRUE;
696  }
697 }
698 static void vPlus(callback_data* spData){
699  if(spData->uiParserState == ID_MATCH){
700  json* spJson = (json*)spData->vpUserData;
701  THROW_ERROR("Leading plus (+) sign not allowed for decimal portion of floating point number (REF8259)", spData->uiParserOffset);
702  }
703 }
704 static void vNameSeparator(callback_data* spData){
705  if(spData->uiParserState == ID_NOMATCH){
706  json* spJson = (json*)spData->vpUserData;
707  THROW_ERROR("Expected key/value name separator (:) not found", spData->uiParserOffset);
708  }
709 }
710 
711 /*********************************************************
712  * call back functions
713  *********************************************************/
717 void vJsonGrammarRuleCallbacks(void* vpParserCtx){
719  aint ui;
721  memset((void*)cb, 0, sizeof(cb));
722  cb[JSON_GRAMMAR_ASCII] = vAscii;
723  cb[JSON_GRAMMAR_BACKSPACE] = vBackSpace;
724  cb[JSON_GRAMMAR_BEGIN_ARRAY] = vArrayBegin;
725  cb[JSON_GRAMMAR_BEGIN_OBJECT] = vObjectBegin;
726  cb[JSON_GRAMMAR_CHAR] = vChar;
727  cb[JSON_GRAMMAR_CR] = vCr;
728  cb[JSON_GRAMMAR_END_ARRAY] = vArrayEnd;
729  cb[JSON_GRAMMAR_END_MEMBER_SEPARATOR] = vEndMemberSep;
730  cb[JSON_GRAMMAR_END_OBJECT] = vObjectEnd;
731  cb[JSON_GRAMMAR_END_VALUE_SEPARATOR] = vEndValueSep;
732  cb[JSON_GRAMMAR_FALSE] = vFalse;
733  cb[JSON_GRAMMAR_FORM_FEED] = vFormFeed;
734  cb[JSON_GRAMMAR_FRAC] = vFrac;
735  cb[JSON_GRAMMAR_FRAC_DIGITS] = vFracDigits;
736  cb[JSON_GRAMMAR_FRAC_ONLY] = vFracOnly;
737  cb[JSON_GRAMMAR_JSON_TEXT] = vJsonText;
738  cb[JSON_GRAMMAR_KEY_BEGIN] = vKeyBegin;
739  cb[JSON_GRAMMAR_LINE_FEED] = vLineFeed;
740  cb[JSON_GRAMMAR_MINUS] = vMinus;
741  cb[JSON_GRAMMAR_NAME_SEPARATOR] = vNameSeparator;
742  cb[JSON_GRAMMAR_NULL] = vNull;
743  cb[JSON_GRAMMAR_NUMBER] = vNumber;
744  cb[JSON_GRAMMAR_PLUS] = vPlus;
745  cb[JSON_GRAMMAR_QUOTE] = vQuote;
746  cb[JSON_GRAMMAR_R_SOLIDUS] = vRSolidus;
747  cb[JSON_GRAMMAR_SOLIDUS] = vSolidus;
748  cb[JSON_GRAMMAR_STRING_BEGIN] = vStringBegin;
749  cb[JSON_GRAMMAR_STRING_CONTENT] = vStringContent;
750  cb[JSON_GRAMMAR_STRING_END] = vStringEnd;
751  cb[JSON_GRAMMAR_TAB] = vTab;
752  cb[JSON_GRAMMAR_TRUE] = vTrue;
753  cb[JSON_GRAMMAR_UTF16_1] = vUtf161;
754  cb[JSON_GRAMMAR_UTF16_2] = vUtf162;
755  cb[JSON_GRAMMAR_UTF8_2] = vUtf82;
756  cb[JSON_GRAMMAR_UTF8_2] = vUtf82;
757  cb[JSON_GRAMMAR_UTF8_3] = vUtf83;
758  cb[JSON_GRAMMAR_UTF8_4] = vUtf84;
759  cb[JSON_GRAMMAR_VALUE] = vValue;
760 
761  for(ui = 0; ui < (aint)RULE_COUNT_JSON_GRAMMAR; ui++){
762  vParserSetRuleCallback(vpParserCtx, ui, cb[ui]);
763  }
764 }
766 
uiUtf16_2
aint uiUtf16_2(char *cpHex, uint32_t *uipChar)
Definition: parser-callbacks.c:82
json_number::iSigned
int64_t iSigned
If uiType = JSON_ID_SIGNED, the signed int value.
Definition: json.h:82
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
json_value_tag::spString
u32_phrase * spString
Pointer to the string value if uiId = JSON_ID_STRING.
Definition: json.h:110
JSON_GRAMMAR_UTF16_2
#define JSON_GRAMMAR_UTF16_2
Definition: json-grammar.h:86
APG_FAILURE
#define APG_FAILURE
Definition: apg.h:308
json::vpVecAscii
void * vpVecAscii
A scratch vector for constructing ASCII strings on the fly.
Definition: jsonp.h:110
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
JSON_GRAMMAR_STRING_BEGIN
#define JSON_GRAMMAR_STRING_BEGIN
Definition: json-grammar.h:79
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
JSON_GRAMMAR_NAME_SEPARATOR
#define JSON_GRAMMAR_NAME_SEPARATOR
Definition: json-grammar.h:70
json::vpVecNumbers
void * vpVecNumbers
Definition: jsonp.h:119
JSON_GRAMMAR_LINE_FEED
#define JSON_GRAMMAR_LINE_FEED
Definition: json-grammar.h:67
callback_data::uiParserOffset
aint uiParserOffset
[read only] Offset from acpString to the first character to match
Definition: parser.h:160
json_number
The structure of a JSON number value.
Definition: json.h:73
string_r::uiCharsOffset
aint uiCharsOffset
The offset from the vector base of 32-bit character codes to the first character in the string.
Definition: jsonp.h:56
JSON_GRAMMAR_END_MEMBER_SEPARATOR
#define JSON_GRAMMAR_END_MEMBER_SEPARATOR
Definition: json-grammar.h:52
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
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
json::spStrings
u32_phrase * spStrings
An array of absolute strings.
Definition: jsonp.h:117
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_FRAC
#define JSON_GRAMMAR_FRAC
Definition: json-grammar.h:59
json::spCurrentFrame
frame * spCurrentFrame
Points to the current stack frame.
Definition: jsonp.h:126
JSON_GRAMMAR_QUOTE
#define JSON_GRAMMAR_QUOTE
Definition: json-grammar.h:75
json::spException
exception * spException
Pointer to the exception structure for reporting errors to the application catch block.
Definition: jsonp.h:97
json::spValues
json_value * spValues
an array of absolute values.
Definition: jsonp.h:113
bLinesFindLine
abool bLinesFindLine(void *vpCtx, aint uiOffset, aint *uipLine, aint *uipRelOffset)
Find the line that the given character is in.
Definition: lines.c:146
JSON_GRAMMAR_FALSE
#define JSON_GRAMMAR_FALSE
Definition: json-grammar.h:57
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
json::vpVecChars
void * vpVecChars
A vector of string characters. 32-bit Unicode code points. All strings are in this single vector.
Definition: jsonp.h:109
JSON_GRAMMAR_CHAR
#define JSON_GRAMMAR_CHAR
Definition: json-grammar.h:44
frame
Each value is a node in the parse tree.
Definition: jsonp.h:85
frame::uiValue
aint uiValue
Index to the value represented by this frame.
Definition: jsonp.h:87
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
json::vpVecChildIndexes
void * vpVecChildIndexes
A vector of number objects.
Definition: jsonp.h:120
JSON_GRAMMAR_BEGIN_OBJECT
#define JSON_GRAMMAR_BEGIN_OBJECT
Definition: json-grammar.h:43
JSON_GRAMMAR_END_ARRAY
#define JSON_GRAMMAR_END_ARRAY
Definition: json-grammar.h:51
JSON_GRAMMAR_JSON_TEXT
#define JSON_GRAMMAR_JSON_TEXT
Definition: json-grammar.h:64
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
vJsonGrammarRuleCallbacks
void vJsonGrammarRuleCallbacks(void *vpParserCtx)
Definition: parser-callbacks.c:718
u32_phrase::uipPhrase
const uint32_t * uipPhrase
Pointer to an array of 32-bit unsigned integers.
Definition: lib.h:74
json::vpVecChildPointers
void * vpVecChildPointers
Definition: jsonp.h:122
parser_callback
void(* parser_callback)(callback_data *spData)
User-written callback function prototype.
Definition: parser.h:178
JSON_GRAMMAR_STRING_END
#define JSON_GRAMMAR_STRING_END
Definition: json-grammar.h:81
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
JSON_GRAMMAR_FRAC_ONLY
#define JSON_GRAMMAR_FRAC_ONLY
Definition: json-grammar.h:61
JSON_UTF16_MATCH
#define JSON_UTF16_MATCH
Definition: jsonp.h:172
vpVecPop
void * vpVecPop(void *vpCtx)
Pops one element from the end of the array.
Definition: vector.c:250
value_r
This is the "relative" value developed during parsing.
Definition: jsonp.h:68
frame::uiNextKey
aint uiNextKey
Used to keep track of the next available key offset to be used by an object member.
Definition: jsonp.h:86
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
vpVecLast
void * vpVecLast(void *vpCtx)
Get the last element one the vector. The vector is not altered.
Definition: vector.c:343
json::sppChildPointers
struct json_value_tag ** sppChildPointers
An array of absolute child value pointers.
Definition: jsonp.h:123
JSON_GRAMMAR_STRING_CONTENT
#define JSON_GRAMMAR_STRING_CONTENT
Definition: json-grammar.h:80
frame::vpVecIndexes
void * vpVecIndexes
Definition: jsonp.h:89
JSON_ID_FALSE
#define JSON_ID_FALSE
Literal value is false.
Definition: json.h:53
callback_data::uiParserPhraseLength
aint uiParserPhraseLength
[read only] The parser's matched phrase length if uiParserState is ID_MATCH or ID_NOMATCH....
Definition: parser.h:161
JSON_ID_OBJECT
#define JSON_ID_OBJECT
Object value.
Definition: json.h:48
json::vpVecFrames
void * vpVecFrames
Frame stack of values to keep track of the current value in the parse tree.
Definition: jsonp.h:121
callback_data::uiCallbackState
aint uiCallbackState
[input/output] Rule name (RNM) callback functions: If ID_ACTIVE, the parser takes no action....
Definition: parser.h:139
value_r::uiChildCount
aint uiChildCount
if uiId is JSON_ID_OBJECT or JSON_ID_ARRAY, the number of members or values.
Definition: jsonp.h:71
json::bHasFrac
abool bHasFrac
A working value signaling presence of fractional value for a number value.
Definition: jsonp.h:129
value_r::uiNumber
aint uiNumber
Offset to a number if JSON_ID_NUMBER.
Definition: jsonp.h:75
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
uiUtf8_2byte
uint32_t uiUtf8_2byte(char *cpBytes)
Definition: parser-callbacks.c:53
json::vpMem
void * vpMem
Pointer to a memory object used for all memory allocations.
Definition: jsonp.h:99
vpVecCtor
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
Definition: vector.c:118
JSON_ID_TRUE
#define JSON_ID_TRUE
Literal value is true.
Definition: json.h:52
APG_SUCCESS
#define APG_SUCCESS
Definition: apg.h:307
json::uiChar
uint32_t uiChar
A working value to hold the value of a single character. Higher level rules will move it to vpVecChar...
Definition: jsonp.h:127
string_r
This is the "relative" string developed during parsing.
Definition: jsonp.h:55
ID_ACTIVE
#define ID_ACTIVE
indicates active parser state, parser has just entered the node and is moving down the parse tree
Definition: parser.h:72
JSON_GRAMMAR_CR
#define JSON_GRAMMAR_CR
Definition: json-grammar.h:45
JSON_GRAMMAR_FRAC_DIGITS
#define JSON_GRAMMAR_FRAC_DIGITS
Definition: json-grammar.h:60
JSON_UTF16_BAD_HIGH
#define JSON_UTF16_BAD_HIGH
Definition: jsonp.h:174
json::uiStringCount
aint uiStringCount
The number of strings in the array.
Definition: jsonp.h:118
json::vpVecStringsr
void * vpVecStringsr
Definition: jsonp.h:115
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
JSON_GRAMMAR_TRUE
#define JSON_GRAMMAR_TRUE
Definition: json-grammar.h:83
callback_data
The data struct passed to each callback function.
Definition: parser.h:134
json_value_tag::uiChildCount
aint uiChildCount
The number of child values if uiId is JSON_ID_OBJECT or JSON_ID_ARRAY.
Definition: json.h:115
APG_UNDEFINED
#define APG_UNDEFINED
Definition: apg.h:318
value_r::uiKey
aint uiKey
If uiID is JSON_ID_OBJECT, offset to the key's string. Otherwise, zero and not used.
Definition: jsonp.h:70
json::vpVecValues
void * vpVecValues
A vector of relative values.
Definition: jsonp.h:112
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
json_value_tag::spNumber
json_number * spNumber
Pointer to the number value if uiId = JSON_ID_NUMBER.
Definition: json.h:111
json::vpVecValuesr
void * vpVecValuesr
Definition: jsonp.h:111
value_r::uiChildListOffset
aint uiChildListOffset
Offset from the base of the vector of child value pointers.
Definition: jsonp.h:72
jsonp.h
Private JSON component header file.
json::uiValueCount
aint uiValueCount
The number of values in the array.
Definition: jsonp.h:114
uiUtf8_4byte
uint32_t uiUtf8_4byte(char *cpBytes)
Definition: parser-callbacks.c:66
JSON_GRAMMAR_MINUS
#define JSON_GRAMMAR_MINUS
Definition: json-grammar.h:69
value_r::uiString
aint uiString
Offset to a string_r if JSON_ID_STRING.
Definition: jsonp.h:74
json::vpLines
void * vpLines
pointer to a lines object context
Definition: jsonp.h:106
uiUtf16_1
aint uiUtf16_1(char *cpHex, uint32_t *uipChar)
Definition: parser-callbacks.c:74
callback_data::vpUserData
void * vpUserData
[input/output] User-defined data passed to to the parser in parser_config.
Definition: parser.h:136
json::vpVecStrings
void * vpVecStrings
A vector of relative strings.
Definition: jsonp.h:116
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
JSON_GRAMMAR_NULL
#define JSON_GRAMMAR_NULL
Definition: json-grammar.h:71
JSON_GRAMMAR_END_VALUE_SEPARATOR
#define JSON_GRAMMAR_END_VALUE_SEPARATOR
Definition: json-grammar.h:54
JSON_GRAMMAR_PLUS
#define JSON_GRAMMAR_PLUS
Definition: json-grammar.h:74
JSON_GRAMMAR_END_OBJECT
#define JSON_GRAMMAR_END_OBJECT
Definition: json-grammar.h:53
json_number::uiUnsigned
uint64_t uiUnsigned
If uiType = JSON_ID_UNSIGNED, the unsigned int value.
Definition: json.h:81
THROW_ERROR
#define THROW_ERROR(msg, off)
A specialized exception thrower for the callback functions.
Definition: parser-callbacks.c:45
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
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
vpVecPopi
void * vpVecPopi(void *vpCtx, aint uiIndex)
Pops the element at the given zero-based index and all higher indexes.
Definition: vector.c:306
ID_NOMATCH
#define ID_NOMATCH
indicates that no phrase was matched on return from parse tree below this node
Definition: parser.h:74
JSON_ID_UNSIGNED
#define JSON_ID_UNSIGNED
Number value is a 64-bit unsigned integer.
Definition: json.h:64
JSON_GRAMMAR_KEY_BEGIN
#define JSON_GRAMMAR_KEY_BEGIN
Definition: json-grammar.h:66
value_r::uiId
aint uiId
The value identifier, JSON_ID_OBJECT, etc.
Definition: jsonp.h:69
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
JSON_GRAMMAR_R_SOLIDUS
#define JSON_GRAMMAR_R_SOLIDUS
Definition: json-grammar.h:76
json::bHasMinus
abool bHasMinus
A working value signaling a minus sign for a number value.
Definition: jsonp.h:130
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
json_value_tag
The structure of a JSON value.
Definition: json.h:99
callback_data::uiStringLength
aint uiStringLength
[read only] The input string length.
Definition: parser.h:157
string_r::uiLength
aint uiLength
The number of characters in the string.
Definition: jsonp.h:57
JSON_GRAMMAR_UTF8_4
#define JSON_GRAMMAR_UTF8_4
Definition: json-grammar.h:91
uiUtf8_3byte
uint32_t uiUtf8_3byte(char *cpBytes)
Definition: parser-callbacks.c:59
vpVecPush
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
Definition: vector.c:193
JSON_ID_NUMBER
#define JSON_ID_NUMBER
Number value.
Definition: json.h:51
JSON_GRAMMAR_NUMBER
#define JSON_GRAMMAR_NUMBER
Definition: json-grammar.h:72
vVecClear
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
Definition: vector.c:420
vExThrow
void vExThrow(exception *spEx, const char *cpMsg, unsigned int uiLine, const char *cpFile, const char *cpFunc)
Throws an exception.
Definition: exception.c:87
APG_FALSE
#define APG_FALSE
Definition: apg.h:292
JSON_GRAMMAR_VALUE
#define JSON_GRAMMAR_VALUE
Definition: json-grammar.h:93
JSON_GRAMMAR_BEGIN_ARRAY
#define JSON_GRAMMAR_BEGIN_ARRAY
Definition: json-grammar.h:42
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.