void ParserImpl::handleArray() { json_type tok = json_peek(_pJSON); while (tok != JSON_ARRAY_END && checkError()) { handle(); tok = json_peek(_pJSON); } if (tok == JSON_ARRAY_END) handle(); else throw JSONException("JSON array end not found"); }
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"); }
static void command_find_by_name_args(char * token, Channel * c, CommandFindByNameArgs * args) { args->ip = 0; json_read_string(&c->inp, args->id, sizeof(args->id)); json_test_char(&c->inp, MARKER_EOA); if (json_peek(&c->inp) != '"' && json_peek(&c->inp) != 'n') { args->ip = (ContextAddress)json_read_uint64(&c->inp); json_test_char(&c->inp, MARKER_EOA); } args->name = json_read_alloc_string(&c->inp); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); strlcpy(args->token, token, sizeof(args->token)); cache_enter(command_find_by_name_cache_client, c, args, sizeof(CommandFindByNameArgs)); }
/* * json_skip -- * Skip over JSON input until one of the specified strings appears. * The tokenizer will be set to point to the beginning of * that string. */ static int json_skip(WT_SESSION *session, JSON_INPUT_STATE *ins, const char **matches) { const char *hit; const char **match; if (ins->kvraw != NULL) return (1); hit = NULL; while (!ins->ateof) { for (match = matches; *match != NULL; match++) if ((hit = strstr(ins->p, *match)) != NULL) goto out; if (util_read_line(&ins->line, 1, &ins->ateof)) { ins->toktype = -1; return (1); } ins->linenum++; ins->p = (const char *)ins->line.mem; } out: if (hit == NULL) return (1); /* Set to this token. */ ins->p = hit; ins->peeking = 0; ins->toktype = 0; (void)json_peek(session, ins); return (0); }
/* * json_expect -- * Ensure that the type of the next token in the input matches * the wanted value, and advance past it. The values of the * input state will be set so specific string or integer values * can be pulled out after this call. */ static int json_expect(WT_SESSION *session, JSON_INPUT_STATE *ins, int wanttok) { if (json_peek(session, ins) < 0) return (1); ins->p += ins->toklen; ins->peeking = 0; if (ins->toktype != wanttok) { fprintf(stderr, "%s: %d: %" WT_SIZET_FMT ": expected %s, got %s\n", ins->filename, ins->linenum, JSON_INPUT_POS(ins) + 1, __wt_json_tokname(wanttok), __wt_json_tokname(ins->toktype)); return (1); } return (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; };
/* * json_column_group_index -- * Parse a column group or index entry from JSON input. */ static int json_column_group_index(WT_SESSION *session, JSON_INPUT_STATE *ins, CONFIG_LIST *clp, int idx) { WT_DECL_RET; char *config, *p, *uri; int isconfig; uri = NULL; config = NULL; while (json_peek(session, ins) == '{') { JSON_EXPECT(session, ins, '{'); JSON_EXPECT(session, ins, 's'); isconfig = JSON_STRING_MATCH(ins, "config"); if (!isconfig && !JSON_STRING_MATCH(ins, "uri")) goto err; JSON_EXPECT(session, ins, ':'); JSON_EXPECT(session, ins, 's'); if ((ret = json_strdup(ins, &p)) != 0) { ret = util_err(ret, NULL); goto err; } if (isconfig) config = p; else uri = p; isconfig = !isconfig; JSON_EXPECT(session, ins, ','); JSON_EXPECT(session, ins, 's'); if (!JSON_STRING_MATCH(ins, isconfig ? "config" : "uri")) goto err; JSON_EXPECT(session, ins, ':'); JSON_EXPECT(session, ins, 's'); if ((ret = json_strdup(ins, &p)) != 0) { ret = util_err(ret, NULL); goto err; } if (isconfig) config = p; else uri = p; JSON_EXPECT(session, ins, '}'); if ((idx && strncmp(uri, "index:", 6) != 0) || (!idx && strncmp(uri, "colgroup:", 9) != 0)) { ret = util_err(EINVAL, "%s: misplaced colgroup or index", uri); goto err; } if ((ret = config_list_add(clp, uri)) != 0 || (ret = config_list_add(clp, config)) != 0) goto err; if (json_peek(session, ins) != ',') break; JSON_EXPECT(session, ins, ','); if (json_peek(session, ins) != '{') goto err; } if (0) { err: if (ret == 0) ret = EINVAL; } return (ret); }
/* * json_top_level -- * Parse the top level JSON input. */ static int json_top_level(WT_SESSION *session, JSON_INPUT_STATE *ins, uint32_t flags) { CONFIG_LIST cl; WT_DECL_RET; char *config, *tableuri; int toktype; static const char *json_markers[] = { "\"config\"", "\"colgroups\"", "\"indices\"", "\"data\"", NULL }; memset(&cl, 0, sizeof(cl)); tableuri = NULL; JSON_EXPECT(session, ins, '{'); while (json_peek(session, ins) == 's') { JSON_EXPECT(session, ins, 's'); tableuri = realloc(tableuri, ins->toklen); snprintf(tableuri, ins->toklen, "%.*s", (int)(ins->toklen - 2), ins->tokstart + 1); JSON_EXPECT(session, ins, ':'); /* * Allow any ordering of 'config', 'colgroups', * 'indices' before 'data', which must appear last. * The non-'data' items build up a list of entries * that created in our session before the data is * inserted. */ for (;;) { if (json_skip(session, ins, json_markers) != 0) goto err; JSON_EXPECT(session, ins, 's'); if (JSON_STRING_MATCH(ins, "config")) { JSON_EXPECT(session, ins, ':'); JSON_EXPECT(session, ins, 's'); if ((ret = json_strdup(ins, &config)) != 0) { ret = util_err(ret, NULL); goto err; } if ((ret = config_list_add(&cl, tableuri)) != 0) goto err; if ((ret = config_list_add(&cl, config)) != 0) goto err; tableuri = NULL; } else if (JSON_STRING_MATCH(ins, "colgroups")) { JSON_EXPECT(session, ins, ':'); JSON_EXPECT(session, ins, '['); if ((ret = json_column_group_index( session, ins, &cl, 0)) != 0) goto err; JSON_EXPECT(session, ins, ']'); } else if (JSON_STRING_MATCH(ins, "indices")) { JSON_EXPECT(session, ins, ':'); JSON_EXPECT(session, ins, '['); if ((ret = json_column_group_index( session, ins, &cl, 1)) != 0) goto err; JSON_EXPECT(session, ins, ']'); } else if (JSON_STRING_MATCH(ins, "data")) { JSON_EXPECT(session, ins, ':'); JSON_EXPECT(session, ins, '['); if ((ret = json_data(session, ins, &cl, flags)) != 0) goto err; config_list_free(&cl); break; } else goto err; } while ((toktype = json_peek(session, ins)) == '}' || toktype == ']') JSON_EXPECT(session, ins, toktype); if (toktype == 0) /* Check EOF. */ break; if (toktype == ',') { JSON_EXPECT(session, ins, ','); if (json_peek(session, ins) != 's') goto err; continue; } } JSON_EXPECT(session, ins, 0); if (0) { err: if (ret == 0) ret = EINVAL; } config_list_free(&cl); if (tableuri != NULL) free(tableuri); return (ret); }
/* * json_data -- * Parse the data portion of the JSON input, and insert all * values. */ static int json_data(WT_SESSION *session, JSON_INPUT_STATE *ins, CONFIG_LIST *clp, uint32_t flags) { WT_CURSOR *cursor; WT_DECL_RET; char config[64], *endp, *uri; const char *keyformat; int isrec, nfield, nkeys, toktype, tret; size_t keystrlen; ssize_t gotnolen; uint64_t gotno, recno; cursor = NULL; uri = NULL; /* Reorder and check the list. */ if ((ret = config_reorder(clp->list)) != 0) goto err; /* Update config based on command-line configuration. */ if ((ret = config_update(session, clp->list)) != 0) goto err; /* Create the items collected. */ if ((ret = config_exec(session, clp->list)) != 0) goto err; uri = clp->list[0]; (void)snprintf(config, sizeof(config), "dump=json%s%s", LF_ISSET(LOAD_JSON_APPEND) ? ",append" : "", LF_ISSET(LOAD_JSON_NO_OVERWRITE) ? ",overwrite=false" : ""); if ((ret = session->open_cursor( session, uri, NULL, config, &cursor)) != 0) { ret = util_err(ret, "%s: session.open", uri); goto err; } keyformat = cursor->key_format; isrec = (strcmp(keyformat, "r") == 0); for (nkeys = 0; *keyformat; keyformat++) if (!isdigit(*keyformat)) nkeys++; recno = 0; while (json_peek(session, ins) == '{') { nfield = 0; JSON_EXPECT(session, ins, '{'); if (ins->kvraw == NULL) { if ((ins->kvraw = (char *)malloc(1)) == NULL) { ret = util_err(errno, NULL); goto err; } } ins->kvraw[0] = '\0'; ins->kvrawstart = JSON_INPUT_POS(ins); keystrlen = 0; while (json_peek(session, ins) == 's') { JSON_EXPECT(session, ins, 's'); JSON_EXPECT(session, ins, ':'); toktype = json_peek(session, ins); JSON_EXPECT(session, ins, toktype); if (isrec && nfield == 0) { /* Verify the dump has recnos in order. */ recno++; gotno = __wt_strtouq(ins->tokstart, &endp, 0); gotnolen = (endp - ins->tokstart); if (recno != gotno || ins->toklen != (size_t)gotnolen) { ret = util_err(0, "%s: recno out of order", uri); goto err; } } if (++nfield == nkeys) { size_t curpos = JSON_INPUT_POS(ins); if ((ret = json_kvraw_append(ins, (char *)ins->line.mem + ins->kvrawstart, curpos - ins->kvrawstart)) != 0) goto err; ins->kvrawstart = curpos; keystrlen = strlen(ins->kvraw); } if (json_peek(session, ins) != ',') break; JSON_EXPECT(session, ins, ','); if (json_peek(session, ins) != 's') goto err; } if (json_kvraw_append(ins, ins->line.mem, JSON_INPUT_POS(ins))) goto err; ins->kvraw[keystrlen] = '\0'; if (!LF_ISSET(LOAD_JSON_APPEND)) cursor->set_key(cursor, ins->kvraw); /* skip over inserted space and comma */ cursor->set_value(cursor, &ins->kvraw[keystrlen+2]); if ((ret = cursor->insert(cursor)) != 0) { ret = util_err(ret, "%s: cursor.insert", uri); goto err; } JSON_EXPECT(session, ins, '}'); if (json_peek(session, ins) != ',') break; JSON_EXPECT(session, ins, ','); if (json_peek(session, ins) != '{') goto err; } if (0) { err: if (ret == 0) ret = EINVAL; } /* * Technically, we don't have to close the cursor because the session * handle will do it for us, but I'd like to see the flush to disk and * the close succeed, it's better to fail early when loading files. */ if (cursor != NULL && (tret = cursor->close(cursor)) != 0) { tret = util_err(tret, "%s: cursor.close", uri); if (ret == 0) ret = tret; } if (ret == 0) ret = util_flush(session, uri); return (ret); }