parse_object: simplify to one do-while loop

This commit is contained in:
Max Bruckner 2017-02-16 02:28:32 +01:00
parent 24dbf29360
commit 03f23738bb

122
cJSON.c
View File

@ -1277,96 +1277,88 @@ static unsigned char *print_array(const cJSON *item, size_t depth, cjbool fmt, p
} }
/* Build an object from the text. */ /* Build an object from the text. */
static const unsigned char *parse_object(cJSON *item, const unsigned char *value, const unsigned char **ep) static const unsigned char *parse_object(cJSON *item, const unsigned char *value, const unsigned char **error_pointer)
{ {
cJSON *head = NULL; /* linked list head */ cJSON *head = NULL; /* linked list head */
cJSON *child = NULL; cJSON *current_item = NULL;
if (*value != '{') if (*value != '{')
{ {
/* not an object! */ /* not an object */
*ep = value; *error_pointer = value;
goto fail; goto fail;
} }
value = skip(value + 1); value = skip(value + 1); /* skip whitespace */
if (*value == '}') if (*value == '}')
{ {
/* empty object. */ goto success; /* empty object */
goto success;
} }
head = child = cJSON_New_Item(); /* step back to character in front of the first element */
if (!child) value--;
/* loop through the comma separated array elements */
do
{ {
goto fail; /* allocate next item */
} cJSON *new_item = cJSON_New_Item();
/* parse first key */ if (new_item == NULL)
value = skip(parse_string(child, skip(value), ep));
if (!value)
{
goto fail;
}
/* use string as key, not value */
child->string = child->valuestring;
child->valuestring = NULL;
if (*value != ':')
{
/* invalid object. */
*ep = value;
goto fail;
}
/* skip any spacing, get the value. */
value = skip(parse_value(child, skip(value + 1), ep));
if (!value)
{
goto fail;
}
while (*value == ',')
{
cJSON *new_item = NULL;
if (!(new_item = cJSON_New_Item()))
{ {
/* memory fail */ goto fail; /* allocation failure */
goto fail;
}
/* add to linked list */
child->next = new_item;
new_item->prev = child;
child = new_item;
value = skip(parse_string(child, skip(value + 1), ep));
if (!value)
{
goto fail;
} }
/* use string as key, not value */ /* attach next item to list */
child->string = child->valuestring; if (head == NULL)
child->valuestring = NULL; {
/* start the linked list */
current_item = head = new_item;
}
else
{
/* add to the end and advance */
current_item->next = new_item;
new_item->prev = current_item;
current_item = new_item;
}
/* parse the name of the child */
value = skip(value + 1); /* skip whitespaces before name */
value = parse_string(current_item, value, error_pointer);
value = skip(value); /* skip whitespaces after name */
if (value == NULL)
{
goto fail; /* faile to parse name */
}
/* swap valuestring and string, because we parsed the name */
current_item->string = current_item->valuestring;
current_item->valuestring = NULL;
if (*value != ':') if (*value != ':')
{ {
/* invalid object. */ /* invalid object */
*ep = value; *error_pointer = value;
goto fail; goto fail;
} }
/* skip any spacing, get the value. */
value = skip(parse_value(child, skip(value + 1), ep)); /* parse the value */
if (!value) value = skip(value + 1); /* skip whitespaces before value */
value = parse_value(current_item, value, error_pointer);
value = skip(value); /* skip whitespaces after the value */
if (value == NULL)
{ {
goto fail; goto fail; /* failed to parse value */
} }
} }
/* end of object */ while (*value == ',');
if (*value == '}') if (*value == '}')
{ {
goto success; goto success; /* end of object */
} }
/* malformed */ /* malformed object */
*ep = value; *error_pointer = value;
goto fail; goto fail;
success: success:
@ -1376,9 +1368,9 @@ success:
return value + 1; return value + 1;
fail: fail:
if (child != NULL) if (head != NULL)
{ {
cJSON_Delete(child); cJSON_Delete(head);
} }
return NULL; return NULL;