Put arrays in order by getting rid of the linked lists.

Resizing is ugly, but less ugly than backwards arrays.
This commit is contained in:
Eric Fischer
2014-02-05 23:18:27 -08:00
parent 879f9126b3
commit d630aa917e
3 changed files with 45 additions and 45 deletions
+9 -11
View File
@@ -42,16 +42,15 @@ void json_print(json_object *j, int depth) {
printf("{\n"); printf("{\n");
indent(depth + 1); indent(depth + 1);
json_hash *h = j->hash; int i;
while (h != NULL) { for (i = 0; i < j->length; i++) {
json_print(h->key, depth + 1); json_print(j->keys[i], depth + 1);
printf(" : "); printf(" : ");
json_print(h->value, depth + 1); json_print(j->values[i], depth + 1);
if (h->next != NULL) { if (i + 1 < j->length) {
printf(",\n"); printf(",\n");
indent(depth + 1); indent(depth + 1);
} }
h = h->next;
} }
printf("\n"); printf("\n");
indent(depth); indent(depth);
@@ -60,14 +59,13 @@ void json_print(json_object *j, int depth) {
printf("[\n"); printf("[\n");
indent(depth + 1); indent(depth + 1);
json_array *a = j->array; int i;
while (a != NULL) { for (i = 0; i < j->length; i++) {
json_print(a->object, depth + 1); json_print(j->array[i], depth + 1);
if (a->next != NULL) { if (i + 1 < j->length) {
printf(",\n"); printf(",\n");
indent(depth + 1); indent(depth + 1);
} }
a = a->next;
} }
printf("\n"); printf("\n");
indent(depth); indent(depth);
+30 -21
View File
@@ -18,20 +18,25 @@ static json_object *add_object(json_type type, json_object *parent) {
o->type = type; o->type = type;
o->parent = parent; o->parent = parent;
o->array = NULL; o->array = NULL;
o->hash = NULL; o->keys = NULL;
o->values = NULL;
o->length = 0;
o->__allocated = 0;
if (parent != NULL) { if (parent != NULL) {
if (parent->type == JSON_ARRAY) { if (parent->type == JSON_ARRAY) {
json_array *a = malloc(sizeof(json_array)); if (parent->length >= parent->__allocated) {
a->next = parent->array; parent->__allocated += 20;
a->object = o; parent->array = realloc(parent->array, parent->__allocated * sizeof(json_object *));
parent->array = a; }
parent->array[parent->length++] = o;
} }
if (parent->type == JSON_HASH) { if (parent->type == JSON_HASH) {
if (parent->hash != NULL && parent->hash->value == NULL) { if (parent->length > 0 && parent->values[parent->length - 1] == NULL) {
// Hash has key but no value, so this is the value // Hash has key but no value, so this is the value
parent->hash->value = o; parent->values[parent->length - 1] = o;
} else { } else {
// No current hash, so this is a key // No current hash, so this is a key
@@ -39,11 +44,15 @@ static json_object *add_object(json_type type, json_object *parent) {
json_error("Hash key is not a string"); json_error("Hash key is not a string");
} }
json_hash *h = malloc(sizeof(json_hash)); if (parent->length >= parent->__allocated) {
h->next = parent->hash; parent->__allocated += 20;
h->key = o; parent->keys = realloc(parent->keys, parent->__allocated * sizeof(json_object *));
h->value = NULL; parent->values = realloc(parent->values, parent->__allocated * sizeof(json_object *));
parent->hash = h; }
parent->keys[parent->length] = o;
parent->values[parent->length] = NULL;
parent->length++;
} }
} }
} }
@@ -56,11 +65,11 @@ json_object *json_hash_get(json_object *o, char *s) {
return NULL; return NULL;
} }
json_hash *h; int i;
for (h = o->hash; h != NULL; h = h->next) { for (i = 0; i < o->length; i++) {
if (h->key != NULL && h->key->type == JSON_STRING) { if (o->keys[i] != NULL && o->keys[i]->type == JSON_STRING) {
if (strcmp(h->key->string, s) == 0) { if (strcmp(o->keys[i]->string, s) == 0) {
return h->value; return o->values[i];
} }
} }
} }
@@ -125,7 +134,7 @@ json_object *json_parse(FILE *f, json_object *current) {
json_error("] at top level"); json_error("] at top level");
} }
if (current->type == JSON_ARRAY && current->array == NULL) { if (current->type == JSON_ARRAY && current->length == 0) {
return current; // Empty array return current; // Empty array
} }
@@ -145,14 +154,14 @@ json_object *json_parse(FILE *f, json_object *current) {
json_error("} at top level"); json_error("} at top level");
} }
if (current->type == JSON_HASH && current->hash == NULL) { if (current->type == JSON_HASH && current->length == 0) {
return current; // Empty hash return current; // Empty hash
} }
if (current->parent == NULL || current->parent->type != JSON_HASH) { if (current->parent == NULL || current->parent->type != JSON_HASH) {
json_error("} without {\n"); json_error("} without {\n");
} }
if (current->parent->hash != NULL && current->parent->hash->value == NULL) { if (current->parent->length != 0 && current->parent->values[current->parent->length - 1] == NULL) {
json_error("} without hash value\n"); json_error("} without hash value\n");
} }
@@ -215,7 +224,7 @@ json_object *json_parse(FILE *f, json_object *current) {
if (current->parent == NULL || current->parent->type != JSON_HASH) { if (current->parent == NULL || current->parent->type != JSON_HASH) {
json_error(": not in hash\n"); json_error(": not in hash\n");
} }
if (current->parent->hash == NULL || current->parent->hash->key == NULL) { if (current->parent->length == 0 || current->parent->keys[current->parent->length - 1] == NULL) {
json_error(": without key\n"); json_error(": without key\n");
} }
+6 -13
View File
@@ -8,25 +8,18 @@ typedef enum json_type {
JSON_HASH, JSON_ARRAY, JSON_NUMBER, JSON_STRING, JSON_TRUE, JSON_FALSE, JSON_NULL, JSON_HASH, JSON_ARRAY, JSON_NUMBER, JSON_STRING, JSON_TRUE, JSON_FALSE, JSON_NULL,
} json_type; } json_type;
typedef struct json_array {
struct json_object *object;
struct json_array *next;
} json_array;
typedef struct json_hash {
struct json_object *key;
struct json_object *value;
struct json_hash *next;
} json_hash;
typedef struct json_object { typedef struct json_object {
json_type type; json_type type;
struct json_object *parent; struct json_object *parent;
char *string; char *string;
double number; double number;
json_array *array;
json_hash *hash; struct json_object **array;
struct json_object **keys;
struct json_object **values;
int length;
int __allocated;
} json_object; } json_object;
json_object *json_parse(FILE *f, json_object *current); json_object *json_parse(FILE *f, json_object *current);