aboutsummaryrefslogtreecommitdiffstats
path: root/libparc/parc/algol/parc_JSONValue.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparc/parc/algol/parc_JSONValue.c')
-rwxr-xr-xlibparc/parc/algol/parc_JSONValue.c1018
1 files changed, 0 insertions, 1018 deletions
diff --git a/libparc/parc/algol/parc_JSONValue.c b/libparc/parc/algol/parc_JSONValue.c
deleted file mode 100755
index f5aff0b4..00000000
--- a/libparc/parc/algol/parc_JSONValue.c
+++ /dev/null
@@ -1,1018 +0,0 @@
-/*
- * Copyright (c) 2017 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- */
-#include <config.h>
-
-#include <parc/assert/parc_Assert.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <math.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include <parc/algol/parc_JSONValue.h>
-#include <parc/algol/parc_JSON.h>
-
-#include <parc/algol/parc_DisplayIndented.h>
-#include <parc/algol/parc_Object.h>
-
-typedef enum {
- PARCJSONValueType_Boolean,
- PARCJSONValueType_String,
- PARCJSONValueType_Number,
- PARCJSONValueType_Array,
- PARCJSONValueType_JSON,
- PARCJSONValueType_Null
-} _PARCJSONValueType;
-
-struct parc_json_value {
- _PARCJSONValueType type;
-
- union {
- bool boolean;
- PARCBuffer *string;
- int64_t intValue;
- PARCList *_array;
- PARCJSONArray *array;
- PARCJSON *object;
- struct {
- bool internalDoubleRepresentation;
- long double internalDoubleValue;
-
- int sign;
- int64_t whole;
- int64_t fraction;
- int64_t fractionLog10;
- int64_t exponent;
- } number;
- } value;
-};
-
-
-
-static void
-_parcJSONValueDestroy(PARCJSONValue **valuePtr)
-{
- if (valuePtr != NULL) {
- PARCJSONValue *value = *valuePtr;
- if (value->type == PARCJSONValueType_Array) {
- parcJSONArray_Release(&value->value.array);
- } else if (value->type == PARCJSONValueType_JSON) {
- parcJSON_Release(&value->value.object);
- } else if (value->type == PARCJSONValueType_String) {
- parcBuffer_Release(&value->value.string);
- }
- }
-}
-
-parcObject_ExtendPARCObject(PARCJSONValue, _parcJSONValueDestroy, NULL, NULL, parcJSONValue_Equals, NULL, NULL, NULL);
-
-static PARCJSONValue *
-_createValue(_PARCJSONValueType type)
-{
- PARCJSONValue *result = parcObject_CreateAndClearInstance(PARCJSONValue);
-
- if (result != NULL) {
- result->type = type;
- }
- 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 PARCJSONValue *
-_parcJSONValue_FalseParser(PARCJSONParser *parser)
-{
- PARCJSONValue *result = NULL;
-
- if (parcJSONParser_RequireString(parser, "false")) {
- result = parcJSONValue_CreateFromBoolean(false);
- }
- return result;
-}
-
-static PARCJSONValue *
-_parcJSONValue_NullParser(PARCJSONParser *parser)
-{
- PARCJSONValue *result = NULL;
-
- if (parcJSONParser_RequireString(parser, "null")) {
- result = parcJSONValue_CreateFromNULL();
- }
- return result;
-}
-
-static PARCJSONValue *
-_parcJSONValue_TrueParser(PARCJSONParser *parser)
-{
- PARCJSONValue *result = NULL;
-
- if (parcJSONParser_RequireString(parser, "true")) {
- result = parcJSONValue_CreateFromBoolean(true);
- }
- return result;
-}
-
-static PARCJSONValue *
-_parcJSONValue_StringParser(PARCJSONParser *parser)
-{
- PARCJSONValue *result = NULL;
- PARCBuffer *string = parcJSONParser_ParseString(parser);
-
- if (string != NULL) {
- result = parcJSONValue_CreateFromString(string);
- parcBuffer_Release(&string);
- }
-
- return result;
-}
-
-static int
-_digittoint(char digit)
-{
- return digit - '0';
-}
-
-/*
- * Parse the whole number portion of a number.
- *
- * 0
- * [1-9][0-9]*
- */
-static bool
-_parseWholeNumber(PARCJSONParser *parser, int64_t *value)
-{
- bool result = false;
- int sign = 1;
-
- char nextCharacter;
-
- if (parcJSONParser_Next(parser, &nextCharacter)) {
- if (nextCharacter == '0') {
- *value = 0;
- result = true;
- } else if (isdigit(nextCharacter)) {
- *value = _digittoint(nextCharacter);
- while (parcJSONParser_Next(parser, &nextCharacter)) {
- if (!isdigit(nextCharacter)) {
- parcJSONParser_Advance(parser, -1);
- break;
- }
- *value = *value * 10 + _digittoint(nextCharacter);
- }
- *value = *value * sign;
- result = true;
- }
- }
-
- return result;
-}
-
-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;
-}
-
-/**
- * Parse an optional fractional part of a number.
- *
- * If the parser is positioned at a '.' character, then parse a fraction comprised of numbers.
- * Otherwise, if the parser is positioned at a 'e' ',' ']' or '}' then there is no fraction, but not an error.
- * If the parser is positioned at any other character, then it is a syntax error.
- *
- * @param [in] parser A pointer to a PARCJSONParser instance.
- * @param [out] value A pointer to an integer accumulating the fraction as a whole number.
- * @param [out] log10 A pointer to an integer accumulating the base 10 logarithm of the fraction (as a positive integer).
- *
- * @return true If there was no syntax error.
- * @return false If there was a syntax error.
- */
-static bool
-_parseOptionalFraction(PARCJSONParser *parser, int64_t *value, int *log10)
-{
- bool result = true;
-
- // The parser is either looking at an '.' which signals the start of a fractional part,
- // or a 'e' ',' ']' or '}' which signals a missing fractional part.
- // Any other character would be the beginning of a syntax error.
-
- char nextCharacter;
-
- if (parcJSONParser_Next(parser, &nextCharacter)) {
- if (nextCharacter == '.') {
- if (_parseFractionNumber(parser, value, log10) == false) {
- result = false;
- }
- } else if (nextCharacter == 'e' || nextCharacter == ',' || nextCharacter == ']' || nextCharacter == '}') {
- parcJSONParser_Advance(parser, -1);
- result = true;
- } else {
- parcJSONParser_Advance(parser, -1);
- result = false;
- }
- }
-
- return result;
-}
-
-/**
- * Parse and compute the base 10 value of a a sequence of digits from 0 to 9, inclusive.
- *
- * @param [in] parser A pointer to a PARCJSONParser instance.
- * @param [out] value A pointer to a value that will receive the base 10 value.
- *
- * @return true If there were parsable digits.
- */
-static bool
-_parseDigits09(PARCJSONParser *parser, int64_t *value)
-{
- bool result = false;
-
- *value = 0;
- char nextDigit;
- while (parcJSONParser_Next(parser, &nextDigit)) {
- *value = *value * 10 + _digittoint(nextDigit);
- result = true;
- }
-
- return result;
-}
-
-static bool
-_parseExponentNumber(PARCJSONParser *parser, int64_t *value)
-{
- bool result = false;
- int sign = 1;
-
- char nextCharacter;
- if (parcJSONParser_Next(parser, &nextCharacter)) {
- if (nextCharacter == '-') {
- sign = -1;
- if (_parseDigits09(parser, value)) {
- result = true;
- }
- *value = *value * sign;
- } else if (nextCharacter == '+') {
- sign = 1;
- if (_parseDigits09(parser, value)) {
- result = true;
- }
- *value = *value * sign;
- } else if (isdigit(nextCharacter)) {
- parcJSONParser_Advance(parser, -1);
- if (_parseDigits09(parser, value)) {
- result = true;
- }
- *value = *value * sign;
- } else {
- result = false;
- }
- }
-
- return result;
-}
-
-static bool
-_parseOptionalExponent(PARCJSONParser *parser, int64_t *value)
-{
- // The parser is either looking at a 'e' or 'E' ',' ']' or '}'
- bool result = true;
-
- char nextCharacter;
- if (parcJSONParser_Next(parser, &nextCharacter)) {
- if (nextCharacter == 'e' || nextCharacter == 'E') {
- if (_parseExponentNumber(parser, value) == false) {
- result = false;
- }
- } else if (nextCharacter == ',' || nextCharacter == ']' || nextCharacter == '}') {
- parcJSONParser_Advance(parser, -1);
- result = true;
- } else {
- parcJSONParser_Advance(parser, -1);
- result = false;
- }
- }
-
- return result;
-}
-
-static __attribute__ ((noinline)) PARCJSONValue *
-_parcJSONValue_CreateNumber(int sign, int64_t whole, int64_t fraction, int64_t fractionLog10, int64_t exponent)
-{
- PARCJSONValue *result = _createValue(PARCJSONValueType_Number);
- if (result != NULL) {
- result->value.number.sign = sign;
- result->value.number.whole = whole;
- result->value.number.fraction = fraction;
- result->value.number.fractionLog10 = fractionLog10;
- result->value.number.exponent = exponent;
- }
- return result;
-}
-
-static PARCJSONValue *
-_parcJSONValue_NumberParser(PARCJSONParser *parser)
-{
- PARCJSONValue *result = NULL;
- int sign = 1;
- int64_t whole = 0;
- int64_t fraction = 0;
- int64_t exponent = 0;
- int fractionLog10 = 0;
-
- if (_parseSign(parser, &sign)) {
- if (_parseWholeNumber(parser, &whole)) {
- if (_parseOptionalFraction(parser, &fraction, &fractionLog10)) {
- if (_parseOptionalExponent(parser, &exponent)) {
- result = _parcJSONValue_CreateNumber(sign, whole, fraction, fractionLog10, exponent);
- }
- }
- }
- }
-
- 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;
-}
-
-static void
-_displayBoolean(const PARCJSONValue *value, int indentation)
-{
- parcDisplayIndented_PrintLine(indentation, ".value=%s", value->value.boolean == true ? "true" : "false");
-}
-
-static void
-_displayNumber(const PARCJSONValue *value, int indentation)
-{
- if (value->value.number.internalDoubleRepresentation) {
- parcDisplayIndented_PrintLine(indentation, ".value=%Lf", value->value.number.internalDoubleValue);
- } else {
- parcDisplayIndented_PrintLine(indentation,
- ".value.number={ sign=%d whole=%lld fractionLog10=%d fraction=%lld exponent=%lld",
- value->value.number.sign,
- value->value.number.whole,
- (int) value->value.number.fractionLog10,
- value->value.number.fraction,
- value->value.number.exponent);
- }
-}
-
-void
-parcJSONValue_AssertValid(const PARCJSONValue *value)
-{
- parcAssertNotNull(value, "PARCJSONValue cannot be NULL.");
-}
-
-bool
-parcJSONValue_IsValid(const PARCJSONValue *value)
-{
- bool result = true;
-
- if (value == NULL) {
- result = false;
- }
-
- return result;
-}
-
-bool
-parcJSONValue_IsNull(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- return (value->type == PARCJSONValueType_Null);
-}
-
-bool
-parcJSONValue_IsBoolean(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- return (value->type == PARCJSONValueType_Boolean);
-}
-
-bool
-parcJSONValue_IsNumber(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- return (value->type == PARCJSONValueType_Number);
-}
-
-bool
-parcJSONValue_IsJSON(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- return (value->type == PARCJSONValueType_JSON);
-}
-
-bool
-parcJSONValue_IsString(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- return (value->type == PARCJSONValueType_String);
-}
-
-bool
-parcJSONValue_IsArray(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- return (value->type == PARCJSONValueType_Array);
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromNULL(void)
-{
- // Strictly speaking, this could just be a singleton, rather than allocated every time.
-
- PARCJSONValue *result = _createValue(PARCJSONValueType_Null);
-
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromBoolean(bool value)
-{
- PARCJSONValue *result = _createValue(PARCJSONValueType_Boolean);
- if (result != NULL) {
- result->value.boolean = value;
- }
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromFloat(long double value)
-{
- PARCJSONValue *result = _parcJSONValue_CreateNumber(0, 0, 0, 0, 0);
- result->value.number.internalDoubleRepresentation = true;
- result->value.number.internalDoubleValue = value;
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromInteger(int64_t value)
-{
- PARCJSONValue *result = _parcJSONValue_CreateNumber(1, value, 0, 0, 0);
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromString(PARCBuffer *value)
-{
- parcBuffer_OptionalAssertValid(value);
-
- PARCJSONValue *result = _createValue(PARCJSONValueType_String);
- if (result != NULL) {
- result->value.string = parcBuffer_Acquire(value);
- }
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromCString(const char *value)
-{
- parcAssertNotNull(value, "String cannot be NULL.");
-
- PARCJSONValue *result = _createValue(PARCJSONValueType_String);
- if (result != NULL) {
- result->value.string = parcBuffer_AllocateCString(value);
- }
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromJSONArray(PARCJSONArray *value)
-{
- PARCJSONValue *result = _createValue(PARCJSONValueType_Array);
- if (result != NULL) {
- result->value.array = parcJSONArray_Acquire(value);
- }
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromJSON(PARCJSON *value)
-{
- PARCJSONValue *result = _createValue(PARCJSONValueType_JSON);
- if (result != NULL) {
- result->value.object = parcJSON_Acquire(value);
- }
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromTimeval(const struct timeval *timeval)
-{
- PARCJSON *jsonTimeval = parcJSON_Create();
- parcJSON_AddInteger(jsonTimeval, "seconds", timeval->tv_sec);
- parcJSON_AddInteger(jsonTimeval, "micros", timeval->tv_usec);
-
- PARCJSONValue *result = _createValue(PARCJSONValueType_JSON);
- if (result != NULL) {
- result->value.object = jsonTimeval;
- }
-
- return result;
-}
-
-PARCJSONValue *
-parcJSONValue_CreateFromTimespec(const struct timespec *timespec)
-{
- PARCJSON *jsonTimespec = parcJSON_Create();
- parcJSON_AddInteger(jsonTimespec, "seconds", timespec->tv_sec);
- parcJSON_AddInteger(jsonTimespec, "nanos", timespec->tv_nsec);
-
- PARCJSONValue *result = _createValue(PARCJSONValueType_JSON);
- if (result != NULL) {
- result->value.object = jsonTimespec;
- }
-
- return result;
-}
-
-void
-parcJSONValue_Display(const PARCJSONValue *value, int indentation)
-{
- parcDisplayIndented_PrintLine(indentation, "PARCJSONValue@%p {", value);
- if (value != NULL) {
- parcDisplayIndented_PrintLine(indentation + 1, ".type=%d", value->type);
-
- switch (value->type) {
- case PARCJSONValueType_Boolean:
- _displayBoolean(value, indentation + 1);
- break;
- case PARCJSONValueType_String:
- parcBuffer_Display(value->value.string, indentation + 1);
- break;
- case PARCJSONValueType_Number:
- _displayNumber(value, indentation + 1);
- break;
- case PARCJSONValueType_Array:
- parcJSONArray_Display(value->value.array, indentation + 1);
- break;
- case PARCJSONValueType_JSON:
- parcJSON_Display(value->value.object, indentation + 1);
- break;
- case PARCJSONValueType_Null:
- parcDisplayIndented_PrintLine(indentation + 1, ".value=null");
- break;
- default:
- parcTrapIllegalValue(value->type, "Unknown PARCJSONValue type %d", value->type);
- }
- }
- parcDisplayIndented_PrintLine(indentation, "}");
-}
-
-parcObject_ImplementAcquire(parcJSONValue, PARCJSONValue);
-
-parcObject_ImplementRelease(parcJSONValue, PARCJSONValue);
-
-static bool
-_equalsNumber(const PARCJSONValue *valueA, const PARCJSONValue *valueB)
-{
- bool result = false;
-
- if (valueA->value.number.internalDoubleRepresentation) {
- if (valueB->value.number.internalDoubleRepresentation) {
- if (valueA->value.number.internalDoubleValue == valueB->value.number.internalDoubleValue) {
- result = true;
- }
- }
- } else {
- if (valueA->value.number.sign == valueB->value.number.sign) {
- if (valueA->value.number.whole == valueB->value.number.whole) {
- if (valueA->value.number.fraction == valueB->value.number.fraction) {
- if (valueA->value.number.exponent == valueB->value.number.exponent) {
- result = true;
- }
- }
- }
- }
- }
-
- return result;
-}
-
-bool
-parcJSONValue_Equals(const PARCJSONValue *objA, const PARCJSONValue *objB)
-{
- bool result = false;
-
- if (objA == NULL || objB == NULL) {
- result = (objA == objB);
- } else {
- if (objA->type == objB->type) {
- switch (objA->type) {
- case PARCJSONValueType_Boolean:
- result = objA->value.boolean == objB->value.boolean;
- break;
- case PARCJSONValueType_String:
- result = parcBuffer_Equals(objA->value.string, objB->value.string);
- break;
- case PARCJSONValueType_Number:
- result = _equalsNumber(objA, objB);
- break;
- case PARCJSONValueType_Array:
- result = parcJSONArray_Equals(objA->value.array, objB->value.array);
- break;
- case PARCJSONValueType_JSON:
- result = parcJSON_Equals(objA->value.object, objB->value.object);
- break;
- case PARCJSONValueType_Null:
- result = true;
- break;
- }
- }
- }
-
- return result;
-}
-
-PARCJSONArray *
-parcJSONValue_GetArray(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- parcTrapUnexpectedStateIf(!parcJSONValue_IsArray(value), "Expected type to be array, actual type %d", value->type);
-
- return value->value.array;
-}
-
-bool
-parcJSONValue_GetBoolean(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- parcTrapUnexpectedStateIf(!parcJSONValue_IsBoolean(value), "Expected type to be boolean, actual type %d", value->type);
-
- return value->value.boolean;
-}
-
-static long double
-_parcJSONValue_GetNumber(const PARCJSONValue *value)
-{
- long double fraction = value->value.number.fraction / powl(10.0, value->value.number.fractionLog10);
- long double number = (long double) value->value.number.sign * ((long double) value->value.number.whole + fraction);
-
- long double result = number * powl(10.0, (long double) value->value.number.exponent);
-
- return result;
-}
-
-long double
-parcJSONValue_GetFloat(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- long double result = 0;
-
- if (value->value.number.internalDoubleRepresentation) {
- result = value->value.number.internalDoubleValue;
- } else {
- result = _parcJSONValue_GetNumber(value);
- }
-
- return result;
-}
-
-int64_t
-parcJSONValue_GetInteger(const PARCJSONValue *value)
-{
- int64_t result = llrint(_parcJSONValue_GetNumber(value));
- return result;
-}
-
-PARCBuffer *
-parcJSONValue_GetString(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- parcTrapUnexpectedStateIf(!parcJSONValue_IsString(value), "Expected type to be string, actual type %d", value->type);
-
- return value->value.string;
-}
-
-PARCJSON *
-parcJSONValue_GetJSON(const PARCJSONValue *value)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- parcTrapUnexpectedStateIf(!parcJSONValue_IsJSON(value), "Expected type to be string, actual type %d", value->type);
-
- return value->value.object;
-}
-
-struct timeval *
-parcJSONValue_GetTimeval(const PARCJSONValue *jsonTimeval, struct timeval *timeval)
-{
- parcAssertNotNull(jsonTimeval, "Parameter jsonTimeval must be a non-null PARCJSON pointer.");
-
- PARCJSON *json = parcJSONValue_GetJSON(jsonTimeval);
- PARCJSONValue *value = parcJSON_GetValueByName(json, "seconds");
- timeval->tv_sec = parcJSONValue_GetInteger(value);
- value = parcJSON_GetValueByName(json, "micros");
- timeval->tv_usec = (int) parcJSONValue_GetInteger(value);
-
- return timeval;
-}
-
-struct timespec *
-parcJSONValue_GetTimespec(const PARCJSONValue *jsonTimespec, struct timespec *timespec)
-{
- parcAssertNotNull(jsonTimespec, "Parameter jsonTimeval must be a non-null PARCJSON pointer.");
-
- PARCJSON *json = parcJSONValue_GetJSON(jsonTimespec);
- PARCJSONValue *value = parcJSON_GetValueByName(json, "seconds");
- timespec->tv_sec = parcJSONValue_GetInteger(value);
- value = parcJSON_GetValueByName(json, "nanos");
- timespec->tv_nsec = (int) parcJSONValue_GetInteger(value);
-
- return timespec;
-}
-
-static PARCBufferComposer *
-_buildStringNumber(const PARCJSONValue *value, PARCBufferComposer *string)
-{
- if (value->value.number.internalDoubleRepresentation) {
- parcBufferComposer_Format(string, "%Lf", value->value.number.internalDoubleValue);
- } else {
- parcBufferComposer_Format(string, "%s%" PRId64,
- value->value.number.sign == -1 ? "-" : "",
- value->value.number.whole);
- if (value->value.number.fraction > 0) {
- parcBufferComposer_Format(string, ".%0*" PRId64,
- (int) value->value.number.fractionLog10,
- value->value.number.fraction);
- }
-
- if (value->value.number.exponent != 0) {
- parcBufferComposer_Format(string, "e%" PRId64,
- value->value.number.exponent);
- }
- }
- return string;
-}
-
-static PARCBufferComposer *
-_buildStringString(const PARCJSONValue *value, PARCBufferComposer *composer, bool compact)
-{
- parcBufferComposer_PutChar(composer, '"');
-
- while (parcBuffer_Remaining(value->value.string)) {
- uint8_t c = parcBuffer_GetUint8(value->value.string);
- if (c == '"') {
- parcBufferComposer_PutString(composer, "\\\"");
- } else if (c == '\b') {
- parcBufferComposer_PutString(composer, "\\b");
- } else if (c == '\f') {
- parcBufferComposer_PutString(composer, "\\f");
- } else if (c == '\n') {
- parcBufferComposer_PutString(composer, "\\n");
- } else if (c == '\r') {
- parcBufferComposer_PutString(composer, "\\r");
- } else if (c == '\t') {
- parcBufferComposer_PutString(composer, "\\t");
- } else if ((c == '/') && !compact) {
- parcBufferComposer_PutString(composer, "\\/");
- } else if (c == '\\') {
- parcBufferComposer_PutString(composer, "\\\\");
- } else {
- parcBufferComposer_PutChar(composer, c);
- }
- }
-
- parcBuffer_Rewind(value->value.string);
- parcBufferComposer_PutChar(composer, '"');
-
- return composer;
-}
-
-PARCBufferComposer *
-parcJSONValue_BuildString(const PARCJSONValue *value, PARCBufferComposer *composer, bool compact)
-{
- parcJSONValue_OptionalAssertValid(value);
-
- if (value->type == PARCJSONValueType_Boolean) {
- parcBufferComposer_PutString(composer, value->value.boolean ? "true" : "false");
- } else if (value->type == PARCJSONValueType_String) {
- _buildStringString(value, composer, compact);
- } else if (value->type == PARCJSONValueType_Number) {
- _buildStringNumber(value, composer);
- } else if (value->type == PARCJSONValueType_Array) {
- parcJSONArray_BuildString(value->value.array, composer, compact);
- } else if (value->type == PARCJSONValueType_JSON) {
- parcJSON_BuildString(value->value.object, composer, compact);
- } else if (value->type == PARCJSONValueType_Null) {
- parcBufferComposer_PutString(composer, "null");
- } else {
- parcTrapIllegalValue(value->type, "Unknown value type: %d", value->type);
- }
-
- return composer;
-}
-
-static char *
-_parcJSONValue_ToString(const PARCJSONValue *value, bool compact)
-{
- PARCBufferComposer *composer = parcBufferComposer_Create();
- parcJSONValue_BuildString(value, composer, compact);
-
- PARCBuffer *tempBuffer = parcBufferComposer_ProduceBuffer(composer);
- char *result = parcBuffer_ToString(tempBuffer);
- parcBuffer_Release(&tempBuffer);
-
- parcBufferComposer_Release(&composer);
-
- return result;
-}
-
-char *
-parcJSONValue_ToString(const PARCJSONValue *value)
-{
- return _parcJSONValue_ToString(value, false);
-}
-
-char *
-parcJSONValue_ToCompactString(const PARCJSONValue *value)
-{
- return _parcJSONValue_ToString(value, true);
-}
-
-PARCJSONValue *
-parcJSONValue_Parser(PARCJSONParser *parser)
-{
- char nextCharacter = parcJSONParser_PeekNextChar(parser);
- switch (nextCharacter) {
- case ',':
- break;
-
- case ']':
- return NULL;
-
- case 'n':
- return _parcJSONValue_NullParser(parser);
-
- case 't':
- return _parcJSONValue_TrueParser(parser);
-
- case 'f':
- return _parcJSONValue_FalseParser(parser);
-
- case '"':
- return _parcJSONValue_StringParser(parser);
-
- case '[':
- return _parcJSONValue_ArrayParser(parser);
-
- case '{':
- return parcJSONValue_ObjectParser(parser);
-
- default:
- return _parcJSONValue_NumberParser(parser);
- }
-
- return NULL;
-}
-
-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;
-}
-