PARCJSONValue * parcJSONValue_ObjectParser(PARCJSONParser *parser) { PARCJSONValue *result = NULL; // absorb the (required) '{' character. if (parcJSONParser_NextChar(parser) == '{') { PARCJSON *json = parcJSON_Create(); while (parcJSONParser_Remaining(parser)) { char c = parcJSONParser_PeekNextChar(parser); if (c == '}') { // Absorb the '}' and terminate. parcJSONParser_NextChar(parser); result = parcJSONValue_CreateFromJSON(json); break; } else if (c == ',') { // absorb the ',' character and continue parcJSONParser_NextChar(parser); } else if (c == '"') { PARCJSONPair *pair = parcJSONPair_Parser(parser); if (pair == NULL) { break; } parcJSON_AddPair(json, pair); parcJSONPair_Release(&pair); } else { break; } } parcJSON_Release(&json); } return result; }
bool parcJSONParser_Next(PARCJSONParser *parser, char *value) { bool result = false; parcJSONParser_SkipIgnored(parser); if (parcJSONParser_Remaining(parser) > 0) { *value = (char) parcBuffer_GetUint8(parser->buffer); result = true; } return result; }
static PARCJSONValue * _parcJSONValue_ArrayParser(PARCJSONParser *parser) { PARCJSONValue *result = NULL; if (parcJSONParser_NextChar(parser) == '[') { PARCJSONArray *array = parcJSONArray_Create(); while (parcJSONParser_Remaining(parser)) { char peek = parcJSONParser_PeekNextChar(parser); if (peek == ',') { parcJSONParser_NextChar(parser); } else if (peek == ']') { parcJSONParser_NextChar(parser); // absorb the ']' character result = parcJSONValue_CreateFromJSONArray(array); parcJSONArray_Release(&array); break; } else { PARCJSONValue *value = NULL; if (peek == 'n') { value = _parcJSONValue_NullParser(parser); } else if (peek == 't') { value = _parcJSONValue_TrueParser(parser); } else if (peek == 'f') { value = _parcJSONValue_FalseParser(parser); } else if (peek == '"') { value = _parcJSONValue_StringParser(parser); } else if (peek == '{') { value = parcJSONValue_ObjectParser(parser); } else if (peek == '[') { value = _parcJSONValue_ArrayParser(parser); } else { value = _parcJSONValue_NumberParser(parser); } if (value != NULL) { parcJSONArray_AddValue(array, value); parcJSONValue_Release(&value); } else { parcJSONArray_Release(&array); break; } } } } return result; }
/** * Return true if the parser is currently positioned at the valid beginning of a number. * If true, then return the sign (-1, +1) in the integer pointed to by @p sign. * If false, then return false ensuring that the parser is repositioned to where it started. */ static bool _parseSign(PARCJSONParser *parser, int *sign) { if (parcJSONParser_Remaining(parser) > 0) { uint8_t c = parcJSONParser_NextChar(parser); if (c == '-') { *sign = -1; return true; } if (!isdigit(c)) { return false; } parcJSONParser_Advance(parser, -1); } *sign = 1; return true; }
static bool _parseFractionNumber(PARCJSONParser *parser, int64_t *value, int *log10) { bool result = false; if (parcJSONParser_Remaining(parser) > 0) { *value = 0; *log10 = 0; char nextCharacter; while (parcJSONParser_Next(parser, &nextCharacter)) { if (!isdigit(nextCharacter)) { parcJSONParser_Advance(parser, -1); break; } *value = *value * 10 + _digittoint(nextCharacter); *log10 = *log10 + 1; } result = true; } return result; }