planarbot/json.c

151 lines
2.9 KiB
C
Raw Normal View History

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "json.h"
#include "sortedmap.h"
#include "arraylist.h"
/* TODO */
Json * parse_map(FILE *stream) { return NULL; /* TODO */ }
Json * parse_list(FILE *stream) { return NULL; /* TODO */ }
Json * parse_string(FILE *stream) {
int i = 0, cap = 10;
char * buffer = calloc(cap, sizeof(char));
char c;
int escaped = 0;
Json * json;
while ((c = getc(stream)) != EOF) {
printf("char: %c, buffer: %s, i: %d\n", c, buffer, i);
switch (c) {
case '\\':
escaped = 1;
break;
case '"':
if (!escaped) {
json = malloc(sizeof(Json));
json->type = STRING;
json->value.string = calloc(i + 1, sizeof(char));
memcpy(json->value.string, buffer, i);
free(buffer);
return json;
}
default:
if (i == cap) {
cap *= 2;
buffer = realloc(buffer, cap * sizeof(char));
}
buffer[i++] = c;
}
}
return NULL;
}
Json * parse_true(FILE *stream) { return NULL; /* TODO */ }
Json * parse_false(FILE *stream) { return NULL; /* TODO */ }
Json * parse_number(FILE *stream, char first) { return NULL; /* TODO */ }
Json * json_parse(FILE *stream) {
char c;
Json * json = NULL;
while ((c = getc(stream)) != EOF) {
switch (c) {
case '{':
return parse_map(stream);
case '[':
return parse_list(stream);
case '"':
return parse_string(stream);
case 't':
return parse_true(stream);
case 'f':
return parse_false(stream);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return parse_number(stream, c);
case ' ':
case '\n':
case '\t':
break; /* whitespace */
default:
fprintf(stderr, "encountered char: '%c'", c);
}
}
return json;
}
struct printacc {
FILE *stream;
int index;
};
void * json_print_map(void * voidacc, char *key, void *value) {
struct printacc *acc = (struct printacc *) voidacc;
return acc;
}
void json_print(Json *this, FILE *stream) {
int i;
struct printacc acc = { NULL, 0 };
switch (this->type) {
case BOOLEAN:
fprintf(stream, this->value.boolean == 0 ? "false" : "true");
break;
case STRING:
fprintf(stream, "\"%s\"", this->value.string);
break;
case NUMBER:
fprintf(stream, "%f", this->value.number);
break;
case LIST:
fprintf(stream, "[");
if (this->value.list->size > 0) {
json_print((Json *) get_list(this->value.list, 0), stream);
for(i = 1; i < this->value.list->size; i++) {
fprintf(stream, ", ");
json_print((Json *) get_list(this->value.list, i), stream);
}
}
fprintf(stream, "]");
break;
case MAP:
fprintf(stream, "{");
acc.stream = stream;
fold_map((void *) &acc, this->value.map, json_print_map);
fprintf(stream, "}");
break;
}
}
void json_free(Json *this) {
switch (this->type) {
case BOOLEAN:
/* TODO */
break;
case STRING:
/* TODO */
free(this->value.string);
break;
case NUMBER:
/* TODO */
break;
case LIST:
/* TODO */
break;
case MAP:
/* TODO */
break;
}
free(this);
}