json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap) { scanner_t s; va_list ap_copy; json_t *value; if(!fmt || !*fmt) { jsonp_error_init(error, "<format>"); jsonp_error_set(error, -1, -1, 0, "NULL or empty format string"); return NULL; } jsonp_error_init(error, NULL); scanner_init(&s, error, flags, fmt); next_token(&s); va_copy(ap_copy, ap); value = pack(&s, &ap_copy); va_end(ap_copy); if(!value) return NULL; next_token(&s); if(s.token) { json_decref(value); set_error(&s, "<format>", "Garbage after format string"); return NULL; } return value; }
json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { json_t *result; FILE *fp; jsonp_error_init(error, path); if (path == NULL) { error_set(error, NULL, "wrong arguments"); return NULL; } fp = fopen(path, "rb"); if(!fp) { error_set(error, NULL, "unable to open %s: %s", path, strerror(errno)); return NULL; } result = json_loadf(fp, flags, error); fclose(fp); return result; }
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) { lex_t lex; const char *source; json_t *result; if(input == stdin) source = "<stdin>"; else source = "<stream>"; jsonp_error_init(error, source); if (input == NULL) { error_set(error, NULL, "wrong arguments"); return NULL; } if(lex_init(&lex, (get_func)fgetc, input)) return NULL; result = parse_json(&lex, flags, error); lex_close(&lex); return result; }
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) { lex_t lex; json_t *result; buffer_data_t stream_data; jsonp_error_init(error, "<buffer>"); if (buffer == NULL) { error_set(error, NULL, "wrong arguments"); return NULL; } stream_data.data = buffer; stream_data.pos = 0; stream_data.len = buflen; if(lex_init(&lex, buffer_get, (void *)&stream_data)) return NULL; result = parse_json(&lex, flags, error); lex_close(&lex); return result; }
json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, json_error_t *error) { lex_t lex; json_t *result; callback_data_t stream_data; memset(&stream_data, 0, sizeof(stream_data)); stream_data.callback = callback; stream_data.arg = arg; jsonp_error_init(error, "<callback>"); if (callback == NULL) { error_set(error, NULL, "wrong arguments"); return NULL; } if(lex_init(&lex, (get_func)callback_get, &stream_data)) return NULL; result = parse_json(&lex, flags, error); lex_close(&lex); return result; }
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) { lex_t lex; const char *source; json_t *result; (void)flags; /* unused */ if(lex_init(&lex, (get_func)fgetc, input)) return NULL; if(input == stdin) source = "<stdin>"; else source = "<stream>"; jsonp_error_init(error, source); result = parse_json(&lex, error); if(!result) goto out; lex_scan(&lex, error); if(lex.token != TOKEN_EOF) { error_set(error, &lex, "end of file expected"); json_decref(result); result = NULL; } out: lex_close(&lex); return result; }
json_t *json_loads(const char *string, size_t flags, json_error_t *error) { lex_t lex; json_t *result; string_data_t stream_data = {string, 0}; (void)flags; /* unused */ if(lex_init(&lex, string_get, (void *)&stream_data)) return NULL; jsonp_error_init(error, "<string>"); result = parse_json(&lex, error); if(!result) goto out; lex_scan(&lex, error); if(lex.token != TOKEN_EOF) { error_set(error, &lex, "end of file expected"); json_decref(result); result = NULL; } out: lex_close(&lex); return result; }
int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap) { scanner_t s; va_list ap_copy; if(!root) { jsonp_error_init(error, "<root>"); jsonp_error_set(error, -1, -1, 0, "NULL root value"); return -1; } if(!fmt || !*fmt) { jsonp_error_init(error, "<format>"); jsonp_error_set(error, -1, -1, 0, "NULL or empty format string"); return -1; } jsonp_error_init(error, NULL); scanner_init(&s, error, flags, fmt); next_token(&s); va_copy(ap_copy, ap); if(unpack(&s, root, &ap_copy)) { va_end(ap_copy); return -1; } va_end(ap_copy); next_token(&s); if(s.token) { set_error(&s, "<format>", "Garbage after format string"); return -1; } return 0; }
json_t *json_bencode_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) { stream_t stream; jsonp_error_init(error, "<buffer>"); if (buffer == NULL) { error_set(error, NULL, "wrong arguments"); return NULL; } init_stream(&stream, buffer, buflen, NULL, NULL); return parse_bencode(&stream, flags, error); }
json_t *json_bencode_loads(const char *string, size_t flags, json_error_t *error) { stream_t stream; jsonp_error_init(error, "<string>"); if (string == NULL) { error_set(error, NULL, "wrong arguments"); return NULL; } init_stream(&stream, string, strlen(string), NULL, NULL); return parse_bencode(&stream, flags, error); }
json_t *json_bencode_loadf(FILE *input, size_t flags, json_error_t *error) { stream_t stream; const char *source; json_t *result; if(input == stdin) source = "<stdin>"; else source = "<stream>"; jsonp_error_init(error, source); if (input == NULL) { error_set(error, NULL, "wrong arguments"); return NULL; } init_stream(&stream, NULL, 0, file_fill, input); result = parse_bencode(&stream, flags, error); finish_stream(&stream); return result; }
json_ref json_loads(const char *string, size_t flags, json_error_t *error) { lex_t lex; string_data_t stream_data; jsonp_error_init(error, "<string>"); if (string == nullptr) { error_set(error, nullptr, "wrong arguments"); return nullptr; } stream_data.data = string; stream_data.pos = 0; if(lex_init(&lex, string_get, (void *)&stream_data)) return nullptr; auto result = parse_json(&lex, flags, error); lex_close(&lex); return result; }
json_ref json_load_file(const char *path, size_t flags, json_error_t *error) { FILE *fp; jsonp_error_init(error, path); if (path == nullptr) { error_set(error, nullptr, "wrong arguments"); return nullptr; } fp = fopen(path, "rb"); if(!fp) { error_set(error, nullptr, "unable to open %s: %s", path, strerror(errno)); return nullptr; } auto result = json_loadf(fp, flags, error); fclose(fp); return result; }