cJSON_ConfigurationChangeParseEnd

Add a pointer to an end position of parsing to the cJSON_Configuration
object. (Essentially like return_parse_end, but as offset instead of
pointer).
This commit is contained in:
Max Bruckner
2018-02-02 00:57:00 +01:00
parent 95d333b5cf
commit 0474d4d85f
4 changed files with 44 additions and 8 deletions

33
cJSON.c
View File

@@ -130,6 +130,7 @@ typedef struct internal_configuration
cJSON_bool case_sensitive;
cJSON_Allocators allocators;
void *userdata;
size_t *end_position;
} internal_configuration;
#if defined(_MSC_VER)
@@ -194,7 +195,8 @@ static void deallocate(const internal_configuration * const configuration, void
global_deallocate_wrapper,\
global_reallocate_wrapper\
},\
NULL /* no userdata */\
NULL, /* no userdata */\
NULL /* no end position */\
}
/* this is necessary to assign the default configuration after initialization */
@@ -1060,7 +1062,7 @@ static parse_buffer *skip_utf8_bom(parse_buffer * const buffer)
}
/* Parse an object - create a new root, and populate. */
static cJSON *parse(const char * const json, const internal_configuration * const configuration, size_t *end_position)
static cJSON *parse(const char * const json, const internal_configuration * const configuration)
{
parse_buffer buffer = { 0, 0, 0, 0, default_configuration };
cJSON *item = NULL;
@@ -1099,7 +1101,10 @@ static cJSON *parse(const char * const json, const internal_configuration * cons
goto fail;
}
}
*end_position = buffer.offset;
if (configuration->end_position != NULL)
{
*configuration->end_position = buffer.offset;
}
return item;
@@ -1124,7 +1129,10 @@ fail:
local_error.position = buffer.length - 1;
}
*end_position = local_error.position;
if (configuration->end_position != NULL)
{
*configuration->end_position = local_error.position;
}
global_error = local_error;
}
@@ -1139,7 +1147,8 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *json, const char **return_
cJSON *item = NULL;
configuration.allow_data_after_json = !require_null_terminated;
item = parse(json, &configuration, &end_position);
configuration.end_position = &end_position;
item = parse(json, &configuration);
if (return_parse_end != NULL)
{
@@ -1152,8 +1161,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *json, const char **return_
/* Default options for cJSON_Parse */
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *json)
{
size_t end_position = 0;
return parse(json, &global_configuration, &end_position);
return parse(json, &global_configuration);
}
#define cjson_min(a, b) ((a < b) ? a : b)
@@ -3013,6 +3021,17 @@ CJSON_PUBLIC(cJSON_Configuration) cJSON_ConfigurationChangeUserdata(cJSON_Config
return configuration;
}
CJSON_PUBLIC(cJSON_Configuration) cJSON_ConfigurationChangeParseEnd(cJSON_Configuration configuration, size_t * const parse_end)
{
if (configuration == NULL)
{
return NULL;
}
((internal_configuration*)configuration)->end_position = parse_end;
return configuration;
}
static cJSON_bool compare(const cJSON * const a, const cJSON * const b, const internal_configuration * const configuration)
{
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))