void JsonIn::skip_value() { char ch; eat_whitespace(); ch = peek(); // it's either a string '"' if (ch == '"') { skip_string(); // or an object '{' } else if (ch == '{') { skip_object(); // or an array '[' } else if (ch == '[') { skip_array(); // or a number (-0123456789) } else if (ch == '-' || (ch >= '0' && ch <= '9')) { skip_number(); // or "true", "false" or "null" } else if (ch == 't') { skip_true(); } else if (ch == 'f') { skip_false(); } else if (ch == 'n') { skip_null(); // or an error. } else { std::stringstream err; err << "expected JSON value but got '" << ch << "'"; error(err.str()); } // skip_* end value automatically }
bool JsonIn::skip_value() { char ch; bool foundsep; eat_whitespace(); ch = peek(); // it's either a string '"' if (ch == '"') { foundsep = skip_string(); // or an object '{' } else if (ch == '{') { foundsep = skip_object(); // or an array '[' } else if (ch == '[') { foundsep = skip_array(); // or a number (-0123456789) } else if (ch == '-' || (ch >= '0' && ch <= '9')) { foundsep = skip_number(); // or "true", "false" or "null" } else if (ch == 't') { foundsep = skip_true(); } else if (ch == 'f') { foundsep = skip_false(); } else if (ch == 'n') { foundsep = skip_null(); // or an error. } else { std::stringstream err; err << line_number() << ": expected JSON value but got '" << ch << "'"; throw err.str(); } return foundsep;//b( foundsep || skip_separator() ); }
static int get_tok (char *js, jsmntok_t *tok, int ntok, char *s) { int i; int do_cmp = ~(0); /* only compare first value into token pair */ if (tok->type != JSMN_OBJECT) { return -1; } for (i = 1, tok++; i < ntok; ) { /* we don't expect nested Objects */ if (IS_OBJECT(*tok)) { return -1; } /* if token is an array, skip it */ if (IS_ARRAY(*tok)) { int skip = skip_array (tok + 1, tok->size); if (skip == -1) { return -1; } i += skip + 1; tok += skip + 1; do_cmp = ~(do_cmp); continue; } /* simple token: compare only if first value into pair and return index of second value if matched */ if ((do_cmp) && (TOK_CMP(js, *tok, s))) { return (i + 1); } do_cmp = ~(do_cmp); i += 1; tok += 1; } return -1; }
int skip_array (jsmntok_t *tok, int size) { int i; for (i = 0; i < size; i++, tok++) { if (IS_ARRAY(*tok)) { return (i + skip_array (tok + 1, tok->size)); } if (IS_OBJECT(*tok)) { return -1; } } return i; }
int skip_array(FILE *f) { uint8_t type; uint32_t num_entries; for (num_entries = read_compressed_int(f); num_entries > 0; num_entries--) { type = fgetc(f); if (type == 0 || type == 4) while (fgetc(f) != 0); else if (type == 1 || type == 2) fseek(f, 4, SEEK_CUR); else skip_array(f); } return 0; }
int seek_config_path(FILE *f, char *config_path) { /* * Assumes the file pointer f points at the start of a rapified * class body. The config path should be formatted like one used * by the ingame commands (case insensitive): * * CfgExample >> MyClass >> MyValue * * This function then moves the file pointer to the start of the * desired class entry (or class body for classes). * * Returns a positive integer on failure, a 0 on success and -1 * if the given path doesn't exist. */ int i; uint8_t type; uint32_t num_entries; uint32_t fp; char path[2048]; char target[512]; char buffer[512]; // Trim leading spaces strncpy(path, config_path, sizeof(path)); trim_leading(path, sizeof(path)); // Extract first element for (i = 0; i < sizeof(target) - 1; i++) { if (path[i] == 0 || path[i] == '>' || path[i] == ' ') break; } strncpy(target, path, i); target[i] = 0; // Inherited classname while (fgetc(f) != 0); num_entries = read_compressed_int(f); for (i = 0; i < num_entries; i++) { fp = ftell(f); type = fgetc(f); if (type == 0) { // class if (fgets(buffer, sizeof(buffer), f) == NULL) return 1; fseek(f, fp + strlen(buffer) + 2, SEEK_SET); fread(&fp, 4, 1, f); if (stricmp(buffer, target)) continue; fseek(f, fp, SEEK_SET); if (strchr(path, '>') == NULL) return 0; strcpy(path, strchr(config_path, '>') + 2); return seek_config_path(f, path); } else if (type == 1) { // value type = fgetc(f); if (fgets(buffer, sizeof(buffer), f) == NULL) return 1; if (stricmp(buffer, target) == 0) { fseek(f, fp, SEEK_SET); return 0; } fseek(f, fp + strlen(buffer) + 3, SEEK_SET); if (type == 0) while (fgetc(f) != 0); else fseek(f, 4, SEEK_CUR); } else if (type == 2) { // array if (fgets(buffer, sizeof(buffer), f) == NULL) return 1; if (stricmp(buffer, target) == 0) { fseek(f, fp, SEEK_SET); return 0; } fseek(f, fp + strlen(buffer) + 2, SEEK_SET); skip_array(f); } else { // extern & delete statements while (fgetc(f) != 0); } } return -1; }
int read_classes(FILE *f, char *config_path, char *array, int size, size_t buffsize) { /* * Reads all subclass names for the given config path into the given * array. * * Returns a positive integer on failure, a 0 on success and -1 * if the given path doesn't exist. */ int i; int j; int success; uint8_t type; uint32_t num_entries; uint32_t fp; char target[512]; char buffer[512]; fseek(f, 16, SEEK_SET); success = seek_config_path(f, config_path); if (success) return success; // Inherited classname while (fgetc(f) != 0); num_entries = read_compressed_int(f); for (i = 0; i < num_entries; i++) { fp = ftell(f); type = fgetc(f); if (type == 0) { // class if (fgets(buffer, sizeof(buffer), f) == NULL) return 1; for (j = 0; j < size; j++) { if (*(array + j * buffsize) == 0) break; } if (j == size) return 2; strncpy(array + j * buffsize, buffer, buffsize); fseek(f, fp + strlen(buffer) + 6, SEEK_SET); } else if (type == 1) { // value type = fgetc(f); if (fgets(buffer, sizeof(buffer), f) == NULL) return 1; lower_case(buffer); if (strcmp(buffer, target) == 0) { fseek(f, fp, SEEK_SET); return 0; } fseek(f, fp + strlen(buffer) + 3, SEEK_SET); if (type == 0 || type == 4) while (fgetc(f) != 0); else fseek(f, 4, SEEK_CUR); } else if (type == 2) { // array if (fgets(buffer, sizeof(buffer), f) == NULL) return 1; lower_case(buffer); if (strcmp(buffer, target) == 0) { fseek(f, fp, SEEK_SET); return 0; } fseek(f, fp + strlen(buffer) + 2, SEEK_SET); skip_array(f); } else { // extern & delete statements while (fgetc(f) != 0); } } return 0; }