Skip to content

Instantly share code, notes, and snippets.

@opsJson
Last active May 29, 2022 05:25
Show Gist options
  • Select an option

  • Save opsJson/932789d412734a500edea19c6ecdcf8e to your computer and use it in GitHub Desktop.

Select an option

Save opsJson/932789d412734a500edea19c6ecdcf8e to your computer and use it in GitHub Desktop.
Simple JSON parser. (OLD VERSION)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
enum json_value_type {
jv_string,
jv_number,
jv_array,
jv_object
};
typedef struct json {
char *key;
char *value;
int type;
} json_t;
char **array_parse(char *array, size_t *elem_count) {
int pair = 0;
int i = 0;
size_t size = 0;
size_t count = 1;
char *array_copy;
char **parsed;
int inside_string = 0;
array_copy = array;
while (*array_copy++) {
if (*array_copy == '\"') while (*++array_copy != '\"' || *(array_copy-1) == '\\');
else if (*array_copy == ',') count++;
}
parsed = (char**)malloc(sizeof(char*) * count);
*elem_count = count;
array_copy = array;
while (*array_copy++) {
size++;
if (*array_copy == '\"') inside_string = 1;
if (*array_copy == '\"' && *(array_copy -1) != '\\') inside_string = 0;
if (inside_string == 0)
if (*array_copy == ',') parsed[pair++] = (char*)malloc(sizeof(char) * size + 1), size = 0;
}
parsed[pair++] = (char*)malloc(sizeof(char) * size + 1), size = 0;
pair = 0;
while (*array++) {
if (*array == '\"') inside_string = 1;
if (*array == '\"' && *(array -1) != '\\') inside_string = 0;
if (inside_string == 0)
if (*array == ',') parsed[pair++][i++] = 0, i = 0, array++;
parsed[pair][i++] = *array;
}
parsed[pair++][i-2] = 0;
return parsed;
}
json_t *json_parse(char *json, size_t *pair_count) {
size_t size = 1;
char *json_copy;
int i = 0;
int pair = 0;
int array_pair = 1;
int object_pair = 1;
//count pairs
json_copy = json;
while (*json_copy++) {
if (*json_copy == '\"') while (*++json_copy != '\"' || *(json_copy-1) == '\\');
if (*json_copy == '[') {
while (1) {
json_copy++;
if (*json_copy == '[') array_pair++;
if (*json_copy == ']') array_pair--;
if (array_pair == 0) break;
}
}
if (*json_copy == ',') size++;
}
//allocate
json_t *parsed = (json_t*)calloc(size, sizeof(json_t));
*pair_count = size;
while (*json) {
if (*json == ',') pair++;
//key
else if (*json == '\"') {
json_copy = json;
size = 0;
i = 0;
while (*++json_copy != '\"' || *(json_copy-1) == '\\') size++;
parsed[pair].key = (char*)malloc(sizeof(char) * size + 1);
while(*++json != '\"' || *(json-1) == '\\') parsed[pair].key[i++] = *json;
parsed[pair].key[i++] = 0;
}
else if (*json == ':') {
//string
if (*(json+1) == '\"') {
parsed[pair].type = jv_string;
json_copy = json;
size = 0;
i = 0;
json_copy++;
while (*++json_copy != '\"' || *(json_copy-1) == '\\') size++;
parsed[pair].value = (char*)malloc(sizeof(char) * size + 1);
json++;
while (*++json != '\"' || *(json-1) == '\\') parsed[pair].value[i++] = *json;
parsed[pair].value[i++] = 0;
}
//array
else if (*(json+1) == '[') {
parsed[pair].type = jv_array;
json_copy = json;
size = 0;
i = 0;
json_copy++;
while (*json_copy++) {
if (*json == '[') array_pair++;
if (*json == ']') array_pair--;
if (array_pair == 0) break;
size++;
}
array_pair = 1;
parsed[pair].value = (char*)malloc(sizeof(char) * size + 2 + 1);
json++;
parsed[pair].value[i++] = '[';
while (*json++) {
if (*json == '[') array_pair++;
if (*json == ']') array_pair--;
if (array_pair == 0) break;
parsed[pair].value[i++] = *json;
}
parsed[pair].value[i++] = ']';
array_pair = 1;
parsed[pair].value[i++] = 0;
}
//object
else if (*(json+1) == '{') {
parsed[pair].type = jv_object;
json_copy = json;
size = 0;
i = 0;
json_copy++;
while (*json_copy++) {
if (*json == '{') array_pair++;
if (*json == '}') array_pair--;
if (array_pair == 0) break;
size++;
}
array_pair = 1;
parsed[pair].value = (char*)malloc(sizeof(char) * size + 2 + 1);
json++;
parsed[pair].value[i++] = '{';
while (*json++) {
if (*json == '{') object_pair++;
if (*json == '}') object_pair--;
if (object_pair == 0) break;
parsed[pair].value[i++] = *json;
}
parsed[pair].value[i++] = '}';
object_pair = 1;
parsed[pair].value[i++] = 0;
}
//number or bool
else {
parsed[pair].type = jv_number;
json_copy = json;
size = 0;
i = 0;
while (*++json_copy != ',') {
if (*json_copy == '}') break;
size++;
}
parsed[pair].value = (char*)malloc(sizeof(char) * size + 1);
while (*++json != ',') {
if (*json == '}') break;
parsed[pair].value[i++] = *json;
}
parsed[pair].value[i++] = 0;
json--;
}
}
json++;
}
return parsed;
}
void json_free(json_t *json, int count) {
int i;
for (i=0; i<count; i++) {
if (json[i].value) free(json[i].value);
if (json[i].key) free(json[i].key);
}
free(json);
}
void array_free(char **array, int count) {
int i;
for (i=0; i<count; i++)
if (array[i]) free(array[i]);
free(array);
}
/*///////////////////////////////////
Testing:
///////////////////////////////////*/
int main() {
int i;
size_t count;
size_t elem_count;
char json[] = "{\"string\":\"foo\",\"array\":[1,2,3],\"object\":{\"foo\":\"bar\"},\"bool\":false}";
json_t *parsed = json_parse(json, &count);
for (i=0; i<count; i++) {
printf("%s\n", parsed[i].key);
printf("%s\n", parsed[i].value);
printf("\n");
}
char **parsed_arr = array_parse(parsed[1].value, &elem_count);
printf("parsed array:\n");
for (i=0; i<elem_count; i++)
printf("%s ", parsed_arr[i]);
//free
json_free(parsed, count);
array_free(parsed_arr, elem_count);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment