static int32_t parseGeneric(const struct Reader* reader, const struct Allocator* allocator, Object** output) { int ret = 0; char firstChar; for (;;) { ret = reader->read(&firstChar, 0, reader); switch (firstChar) { case ' ': case '\r': case '\n': case '\t': reader->skip(1, reader); continue; case '/':; if ((ret = parseComment(reader)) != 0) { return ret; } continue; default: break; } if (ret) { printf("Unexpected end of input\n"); return OUT_OF_CONTENT_TO_READ; } break; } Object* out = allocator->malloc(sizeof(Object), allocator); switch (firstChar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':; // int64_t. Int is special because it is not a pointer but a int64_t. int64_t bint; ret = parseint64_t(reader, &bint); out->type = Object_INTEGER; out->as.number = bint; break; case '[':; // List. List* list = allocator->calloc(sizeof(List), 1, allocator); ret = parseList(reader, allocator, list); out->type = Object_LIST; out->as.list = list; break; case '{':; // Dictionary Dict* dict = allocator->calloc(sizeof(Dict), 1, allocator); ret = parseDictionary(reader, allocator, dict); out->type = Object_DICT; out->as.dictionary = dict; break; case '"':; // String String* string = NULL; ret = parseString(reader, allocator, &string); out->type = Object_STRING; out->as.string = string; break; default: printf("While looking for something to parse: " "expected one of 0 1 2 3 4 5 6 7 8 9 [ { \", found '%c'\n", firstChar); return UNPARSABLE; } if (ret != 0) { // Something went wrong while parsing. return ret; } *output = out; return 0; }
/** * Parse an unknown data type. * This is not exposed to the world because it is expected that one would * know what type they are parsing to begin with. This is used by parseDictionary * and parseList to grab pieces of data which are of unknown type and parse them. * * @param reader the reader to get the stream of data from. * @param allocator the means of storing the parsed data. * @param output a pointer which will be pointed to the output. */ static int32_t parseGeneric(const struct Reader* reader, const struct Allocator* allocator, Object** output) { #define OUT_OF_CONTENT_TO_READ -2 #define UNPARSABLE -3 int ret; char firstChar; ret = reader->read(&firstChar, 0, reader); if (ret != 0) { return OUT_OF_CONTENT_TO_READ; } Object* out = Allocator_malloc(allocator, sizeof(Object)); if (firstChar <= '9' && firstChar >= '0') { /* It's a string! */ String* string = NULL; ret = parseString(reader, allocator, &string); out->type = Object_STRING; out->as.string = string; } else { switch (firstChar) { case 'i':; /* int64_t. Int is special because it is not a pointer but a int64_t. */ int64_t bint = 0; ret = parseint64_t(reader, &bint); out->type = Object_INTEGER; out->as.number = bint; break; case 'l':; /* List. */ List* list = Allocator_calloc(allocator, sizeof(List), 1); ret = parseList(reader, allocator, list); out->type = Object_LIST; out->as.list = list; break; case 'd':; /* Dictionary. */ Dict* dict = Allocator_calloc(allocator, sizeof(Dict), 1); ret = parseDictionary(reader, allocator, dict); out->type = Object_DICT; out->as.dictionary = dict; break; default: return UNPARSABLE; } } if (ret != 0) { /* Something went wrong while parsing. */ return ret; } *output = out; return 0; #undef OUT_OF_CONTENT_TO_READ #undef UNPARSABLE }