const jsmntok_t *json_get_member(const char *buffer, const jsmntok_t tok[], const char *label) { const jsmntok_t *t, *end; assert(tok->type == JSMN_OBJECT); end = json_next(tok); for (t = tok + 1; t < end; t = json_next(t+1)) if (json_tok_streq(buffer, t, label)) return t + 1; return NULL; }
void ParserImpl::handle(const std::string& json) { if (!_allowNullByte && json.find("\\u0000") != json.npos) throw JSONException("Null bytes in strings not allowed."); try { json_open_buffer(_pJSON, json.data(), json.size()); checkError(); ////////////////////////////////// // Underlying parser is capable of parsing multiple consecutive JSONs; // we do not currently support this feature; to force error on // excessive characters past valid JSON end, this MUST be called // AFTER opening the buffer - otherwise it is overwritten by // json_open*() call, which calls internal init() json_set_streaming(_pJSON, false); ///////////////////////////////// handle(); checkError(); if (JSON_DONE != json_next(_pJSON)) throw JSONException("Excess characters found after JSON end."); json_close(_pJSON); } catch (std::exception&) { json_close(_pJSON); throw; } }
const jsmntok_t *json_get_arr(const char *buffer, const jsmntok_t tok[], size_t index) { const jsmntok_t *t, *end; assert(tok->type == JSMN_ARRAY); end = json_next(tok); for (t = tok + 1; t < end; t = json_next(t)) { if (index == 0) return t; index--; } return NULL; }
glm::vec3 json_get_vec3(json_stream *json) { glm::vec3 vec; json_type type = json_next(json); assert(type == JSON_NUMBER); vec.x = (float)json_get_number(json); type = json_next(json); assert(type == JSON_NUMBER); vec.y = (float)json_get_number(json); type = json_next(json); assert(type == JSON_NUMBER); vec.z = (float)json_get_number(json); type = json_next(json); assert(type == JSON_ARRAY_END); return vec; }
void json_tok_remove(jsmntok_t **tokens, jsmntok_t *tok, size_t num) { assert(*tokens); assert((*tokens)->type == JSMN_ARRAY || (*tokens)->type == JSMN_OBJECT); const jsmntok_t *src = tok; const jsmntok_t *end = json_next(*tokens); jsmntok_t *dest = tok; int remove_count; for (int i = 0; i < num; i++) src = json_next(src); remove_count = src - tok; memmove(dest, src, sizeof(jsmntok_t) * (end - src)); tal_resize(tokens, tal_count(*tokens) - remove_count); (*tokens)->size -= num; }
const jsmntok_t *json_next(const jsmntok_t *tok) { const jsmntok_t *t; size_t i; for (t = tok + 1, i = 0; i < tok->size; i++) t = json_next(t); return t; }
int main() { FILE *json_input = fopen("example.json", "r"); if (!json_input) return -1; json_next(json_input); fclose(json_input); return 0; }
int getJSONString(json_stream *json, char *aField, const char *aOType, char **var) { if (strcmp(aOType, aField) == 0) { json_type type = json_next(json); assert(type == JSON_STRING); *var = mystrdup(json_get_string(json, 0)); return 1; } return 0; }
int getJSONVec3(json_stream *json, char *aField, const char *aOType, glm::vec3 &var) { if (strcmp(aOType, aField) == 0) { json_type type = json_next(json); assert(type == JSON_ARRAY); var = json_get_vec3(json); return 1; } return 0; }
int getJSONNumber(json_stream *json, char *aField, const char *aOType, float &var) { if (strcmp(aOType, aField) == 0) { json_type type = json_next(json); assert(type == JSON_NUMBER); var = (float)json_get_number(json); return 1; } return 0; }
void json_tok_print(const char *buffer, const jsmntok_t *tok) { const jsmntok_t *first = tok; const jsmntok_t *last = json_next(tok); printf("size: %d, count: %td\n", tok->size, last - first); while (first != last) { printf("%td. %.*s, %s\n", first - tok, first->end - first->start, buffer + first->start, jsmntype_to_string(first->type)); first++; } printf("\n"); }
void json_get_params(const char *buffer, const jsmntok_t param[], ...) { va_list ap; const char *name; const jsmntok_t **tokptr, *p, *end; if (param->type == JSMN_ARRAY) { if (param->size == 0) p = NULL; else p = param + 1; end = json_next(param); } else assert(param->type == JSMN_OBJECT); va_start(ap, param); while ((name = va_arg(ap, const char *)) != NULL) { tokptr = va_arg(ap, const jsmntok_t **); if (param->type == JSMN_ARRAY) { *tokptr = p; if (p) { p = json_next(p); if (p == end) p = NULL; } } else { *tokptr = json_get_member(buffer, param, name); } /* Convert 'null' to NULL */ if (*tokptr && (*tokptr)->type == JSMN_PRIMITIVE && buffer[(*tokptr)->start] == 'n') { *tokptr = NULL; } } va_end(ap); }
static void json_restart(struct command *cmd, const char *buffer, const jsmntok_t *params) { const jsmntok_t *p, *end; size_t n = 0; if (params->type != JSMN_ARRAY) { command_fail(cmd, "Need array to reexec"); return; } end = json_next(params); cmd->dstate->reexec = tal_arrz(cmd->dstate, char *, n+1); for (p = params + 1; p != end; p = json_next(p)) { tal_resizez(&cmd->dstate->reexec, n+2); cmd->dstate->reexec[n++] = tal_strndup(cmd->dstate->reexec, buffer + p->start, p->end - p->start); } debug_dump_peers(cmd->dstate); io_break(cmd->dstate); command_success(cmd, null_response(cmd)); }
void ParserImpl::handleObject() { json_type tok = json_peek(_pJSON); while (tok != JSON_OBJECT_END && checkError()) { json_next(_pJSON); if (_pHandler) _pHandler->key(std::string(json_get_string(_pJSON, NULL))); handle(); tok = json_peek(_pJSON); } if (tok == JSON_OBJECT_END) handle(); else throw JSONException("JSON object end not found"); }
jsmntok_t *json_parse_input(const tal_t *ctx, const char *input, int len, bool *valid) { jsmn_parser parser; jsmntok_t *toks; int ret; toks = tal_arr(ctx, jsmntok_t, 10); toks[0].type = JSMN_UNDEFINED; jsmn_init(&parser); again: ret = jsmn_parse(&parser, input, len, toks, tal_count(toks) - 1); switch (ret) { case JSMN_ERROR_INVAL: *valid = false; return tal_free(toks); case JSMN_ERROR_NOMEM: tal_resize(&toks, tal_count(toks) * 2); goto again; } /* Check whether we read at least one full root element, i.e., root * element has its end set. */ if (toks[0].type == JSMN_UNDEFINED || toks[0].end == -1) { *valid = true; return tal_free(toks); } /* If we read a partial element at the end of the stream we'll get a * ret=JSMN_ERROR_PART, but due to the previous check we know we read at * least one full element, so count tokens that are part of this root * element. */ ret = json_next(toks) - toks; /* Cut to length and return. */ *valid = true; tal_resize(&toks, ret + 1); /* Make sure last one is always referenceable. */ toks[ret].type = -1; toks[ret].start = toks[ret].end = toks[ret].size = 0; return toks; }
int json_tsfile_add_array(tsfile_t* file, json_node_t* node_array) { unsigned long entry_size = file->header->schema.hdr.entry_size; void* entries = NULL; void* entry; int count = json_size(node_array); int ni = 0; int ret; json_node_t* node = json_first(node_array, &ni); entries = mp_malloc(entry_size * count); while(!json_is_end(node_array, node, &ni)) { entry = ((char*) entries) + entry_size * ni; tsfile_fill_entry(file, node, entry); node = json_next(node, &ni); } ret = tsfile_add(file, entries, count); mp_free(entries); return ret; }
jsmntok_t *json_tok_copy(const tal_t *ctx, const jsmntok_t *tok) { return tal_dup_arr(ctx, jsmntok_t, tok, json_next(tok) - tok, 0); }
Scene *loadScene(char *aFilename) { Scene *t = new Scene; json_stream json; FILE * f = fopen(aFilename, "rb"); json_open_stream(&json, f); json_type type = json_next(&json); assert(type == JSON_OBJECT); while (json_peek(&json) != JSON_OBJECT_END && json_peek(&json) != JSON_ERROR) { type = json_next(&json); assert(type == JSON_STRING); const char *otype = json_get_string(&json, 0); if (strcmp(otype, "material") == 0) { const char *name = "[untitled]"; glm::vec3 diffuse(1); glm::vec3 specular(0); glm::vec3 ambient(0); float opacity = 1; float reflection = 0; type = json_next(&json); assert(type == JSON_OBJECT); while (json_peek(&json) != JSON_OBJECT_END) { type = json_next(&json); assert(type == JSON_STRING); otype = json_get_string(&json, 0); if (!getJSONString(&json, "name", otype, (char**)&name)) if (!getJSONVec3(&json, "diffuse", otype, diffuse)) if (!getJSONVec3(&json, "ambient", otype, ambient)) if (!getJSONVec3(&json, "specular", otype, specular)) if (!getJSONNumber(&json, "opacity", otype, opacity)) if (!getJSONNumber(&json, "reflection", otype, reflection)) assert(0 && "error parsing material"); } type = json_next(&json); assert(type == JSON_OBJECT_END); Material *m = new Material(); m->mName = (char*)name; m->mDiffuse = diffuse; m->mAmbient = ambient; m->mSpecular = specular; m->mOpacity = opacity; m->mReflection = reflection; m->mNext = t->mMaterial; t->mMaterial = m; } else if (strcmp(otype, "box") == 0) { const char *name = "[untitled]"; const char *material = "default"; glm::vec3 center; glm::vec3 size; float dynamic = 0; type = json_next(&json); assert(type == JSON_OBJECT); while (json_peek(&json) != JSON_OBJECT_END) { type = json_next(&json); assert(type == JSON_STRING); otype = json_get_string(&json, 0); if (!getJSONString(&json, "name", otype, (char**)&name)) if (!getJSONString(&json, "material", otype, (char**)&material)) if (!getJSONNumber(&json, "dynamic", otype, dynamic)) if (!getJSONVec3(&json, "position", otype, center)) if (!getJSONVec3(&json, "center", otype, center)) if (!getJSONVec3(&json, "size", otype, size)) assert(0 && "error parsing box"); } type = json_next(&json); assert(type == JSON_OBJECT_END); SceneObject *so; t->insert(so = new Box((char*)name, center, size, t->getMaterialByName((char*)material))); so->mDynamic = dynamic != 0; } else if (strcmp(otype, "plane") == 0) { const char *name = "[untitled]"; const char *material = "default"; glm::vec3 point; glm::vec3 normal; float dynamic = 0; type = json_next(&json); assert(type == JSON_OBJECT); while (json_peek(&json) != JSON_OBJECT_END) { type = json_next(&json); assert(type == JSON_STRING); otype = json_get_string(&json, 0); if (!getJSONString(&json, "name", otype, (char**)&name)) if (!getJSONString(&json, "material", otype, (char**)&material)) if (!getJSONNumber(&json, "dynamic", otype, dynamic)) if (!getJSONVec3(&json, "point", otype, point)) if (!getJSONVec3(&json, "normal", otype, normal)) assert(0 && "error parsing box"); } type = json_next(&json); assert(type == JSON_OBJECT_END); SceneObject *so; t->insert(so = new Plane((char*)name, point, normal, t->getMaterialByName((char*)material))); so->mDynamic = dynamic != 0; } else if (strcmp(otype, "sphere") == 0) { const char *name = "[untitled]"; const char *material = "default"; glm::vec3 center; float radius = 5; float dynamic = 0; type = json_next(&json); assert(type == JSON_OBJECT); while (json_peek(&json) != JSON_OBJECT_END) { type = json_next(&json); assert(type == JSON_STRING); otype = json_get_string(&json, 0); if (!getJSONString(&json, "name", otype, (char**)&name)) if (!getJSONString(&json, "material", otype, (char**)&material)) if (!getJSONNumber(&json, "dynamic", otype, dynamic)) if (!getJSONVec3(&json, "center", otype, center)) if (!getJSONVec3(&json, "position", otype, center)) if (!getJSONNumber(&json, "radius", otype, radius)) assert(0 && "error parsing sphere"); } type = json_next(&json); assert(type == JSON_OBJECT_END); SceneObject *so; t->insert(so = new Sphere((char*)name, center, radius, t->getMaterialByName((char*)material))); so->mDynamic = dynamic != 0; } else if (strcmp(otype, "light") == 0) { const char *name = "[untitled]"; const char *material = "default"; glm::vec3 position; type = json_next(&json); assert(type == JSON_OBJECT); while (json_peek(&json) != JSON_OBJECT_END) { type = json_next(&json); assert(type == JSON_STRING); otype = json_get_string(&json, 0); if (!getJSONString(&json, "name", otype, (char**)&name)) if (!getJSONString(&json, "material", otype, (char**)&material)) if (!getJSONVec3(&json, "position", otype, position)) assert(0 && "error parsing light"); } type = json_next(&json); assert(type == JSON_OBJECT_END); t->insert(new Light((char*)name, position, t->getMaterialByName((char*)material))); } else { assert(0); } } type = json_next(&json); if (type == JSON_ERROR) { const char * err = json_get_error(&json); err = err; } assert(type == JSON_OBJECT_END); type = json_next(&json); assert(type == JSON_DONE); json_close(&json); setupScene(t); t->optimize(); return t; };
void ParserImpl::handle() { enum json_type type = json_next(_pJSON); switch (type) { case JSON_DONE: return; case JSON_NULL: _pHandler->null(); break; case JSON_TRUE: if (_pHandler) _pHandler->value(true); break; case JSON_FALSE: if (_pHandler) _pHandler->value(false); break; case JSON_NUMBER: { if (_pHandler) { std::string str(json_get_string(_pJSON, NULL)); if (str.find(_decimalPoint) != str.npos || str.find('e') != str.npos || str.find('E') != str.npos) { _pHandler->value(NumberParser::parseFloat(str)); } else { Poco::Int64 val; if (NumberParser::tryParse64(str, val)) _pHandler->value(val); else _pHandler->value(NumberParser::parseUnsigned64(str)); } } break; } case JSON_STRING: if (_pHandler) _pHandler->value(std::string(json_get_string(_pJSON, NULL))); break; case JSON_OBJECT: if (_pHandler) _pHandler->startObject(); handleObject(); break; case JSON_OBJECT_END: if (_pHandler) _pHandler->endObject(); return; case JSON_ARRAY: if (_pHandler) _pHandler->startArray(); handleArray(); break; case JSON_ARRAY_END: if (_pHandler) _pHandler->endArray(); return; case JSON_ERROR: { const char* pErr = json_get_error(_pJSON); std::string err(pErr ? pErr : "JSON parser error."); throw JSONException(err); } } }
struct _json_attribute *get_next_attribute(FILE *json_input, struct _json_attribute *prev_attr) { struct _json_attribute *attr, *value_attr, *next_attr; int ch, i = 0, inside_quote = 0, got_name = 0, got_object = 0; char name[128], value[128]; attr = malloc(sizeof(*attr)); while (1) { ch = fgetc(json_input); switch (ch) { case EOF: goto end_loop; case '{': if (!got_name) continue; printf("(value of '%s' is an object)\n", name); ungetc(ch, json_input); value_attr = json_next(json_input); got_object = 1; break; case '}': goto end_loop; case '\"': if (!inside_quote) inside_quote = 1; else { inside_quote = 0; } break; case ',': next_attr = get_next_attribute(json_input, prev_attr); //goto end_loop; break; case ':': got_name = 1; name[i] = 0; i = 0; break; case '\n': continue; case ' ': if (!inside_quote) continue; default: if (!got_name) name[i++] = ch; else value[i++] = ch; } } end_loop: value[i] = 0; printf("'%s' : '%s'\n", name, value); attr->name = strdup(name); if (got_object) { attr->value = value_attr; attr->value_type = JSON_OBJECT; } else { attr->value = strdup(value); attr->value_type = JSON_STRING; } if (prev_attr) { // prepend attribute to list. attr->next = prev_attr->children; prev_attr->children = attr; } return attr; }