mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-02-23 10:30:16 +00:00
Work out more details of how json_free() needs to work.
The idea is that you can free any element once you are done with it, even if it is part of an array or hash that isn't completely read yet. Removing array elements is reasonably well defined because nothing else depends on them. Removing a hash key or value causes it to be replaced by a null unless the other side of the component has already been nulled out, in which case the whole pair is removed.
This commit is contained in:
parent
f0f73c6dd1
commit
f67e97cd08
65
jsonpull.c
65
jsonpull.c
@ -459,6 +459,17 @@ again:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static json_object *fabricate_null(json_object *parent) {
|
||||
json_object *o = malloc(sizeof(struct json_object));
|
||||
o->type = JSON_NULL;
|
||||
o->parent = parent;
|
||||
o->array = NULL;
|
||||
o->keys = NULL;
|
||||
o->values = NULL;
|
||||
o->length = 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
void json_free(json_object *o) {
|
||||
int i;
|
||||
|
||||
@ -469,14 +480,33 @@ void json_free(json_object *o) {
|
||||
// Free any data linked from here
|
||||
|
||||
if (o->type == JSON_ARRAY) {
|
||||
for (i = 0; i < o->length; i++) {
|
||||
json_free(o->array[i]);
|
||||
json_object **a = o->array;
|
||||
int n = o->length;
|
||||
|
||||
o->array = NULL;
|
||||
o->length = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
json_free(a[i]);
|
||||
}
|
||||
|
||||
free(a);
|
||||
} else if (o->type == JSON_HASH) {
|
||||
for (i = 0; i < o->length; i++) {
|
||||
json_free(o->keys[i]);
|
||||
json_free(o->values[i]);
|
||||
json_object **k = o->keys;
|
||||
json_object **v = o->values;
|
||||
int n = o->length;
|
||||
|
||||
o->keys = NULL;
|
||||
o->values = NULL;
|
||||
o->length = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
json_free(k[i]);
|
||||
json_free(v[i]);
|
||||
}
|
||||
|
||||
free(k);
|
||||
free(v);
|
||||
} else if (o->type == JSON_STRING) {
|
||||
free(o->string);
|
||||
}
|
||||
@ -500,24 +530,25 @@ void json_free(json_object *o) {
|
||||
|
||||
if (o->parent->type == JSON_HASH) {
|
||||
for (i = 0; i < o->parent->length; i++) {
|
||||
if (o->parent->keys[i] == o || o->parent->values[i] == o) {
|
||||
if (o->parent->keys[i] == o) {
|
||||
o->parent->keys[i] = fabricate_null(o->parent);
|
||||
break;
|
||||
}
|
||||
if (o->parent->values[i] == o) {
|
||||
o->parent->values[i] = fabricate_null(o->parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < o->parent->length) {
|
||||
json_object *k = o->parent->keys[i];
|
||||
json_object *v = o->parent->values[i];
|
||||
if (o->parent->keys[i] != NULL && o->parent->keys[i]->type == JSON_NULL) {
|
||||
if (o->parent->values[i] != NULL && o->parent->values[i]->type == JSON_NULL) {
|
||||
free(o->parent->keys[i]);
|
||||
free(o->parent->values[i]);
|
||||
|
||||
memmove(o->parent->keys + i, o->parent->keys + i + 1, o->parent->length - i - 1);
|
||||
memmove(o->parent->values + i, o->parent->values + i + 1, o->parent->length - i - 1);
|
||||
o->parent->length--;
|
||||
|
||||
if (o->parent->values[i] == NULL) {
|
||||
// Have not yet read the value for this pair
|
||||
} else {
|
||||
if (o->parent->keys[i] == o) {
|
||||
} else {
|
||||
memmove(o->parent->keys + i, o->parent->keys + i + 1, o->parent->length - i - 1);
|
||||
memmove(o->parent->values + i, o->parent->values + i + 1, o->parent->length - i - 1);
|
||||
o->parent->length--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,5 +33,6 @@ typedef struct json_pull json_pull;
|
||||
json_pull *json_begin_file(FILE *f);
|
||||
json_pull *json_begin_string(char *s);
|
||||
json_object *json_parse(json_pull *j);
|
||||
void json_free(json_object *j);
|
||||
|
||||
json_object *json_hash_get(json_object *o, char *s);
|
||||
|
Loading…
x
Reference in New Issue
Block a user