/* XXX add an incremental streaming parser - yajl trivially supports it */ virJSONValuePtr virJSONValueFromString(const char *jsonstring) { yajl_handle hand; virJSONParser parser = { NULL, NULL, 0 }; virJSONValuePtr ret = NULL; # ifndef HAVE_YAJL2 yajl_parser_config cfg = { 1, 1 }; # endif VIR_DEBUG("string=%s", jsonstring); # ifdef HAVE_YAJL2 hand = yajl_alloc(&parserCallbacks, NULL, &parser); if (hand) { yajl_config(hand, yajl_allow_comments, 1); yajl_config(hand, yajl_dont_validate_strings, 0); } # else hand = yajl_alloc(&parserCallbacks, &cfg, NULL, &parser); # endif if (!hand) { virJSONError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to create JSON parser")); goto cleanup; } if (yajl_parse(hand, (const unsigned char *)jsonstring, strlen(jsonstring)) != yajl_status_ok) { unsigned char *errstr = yajl_get_error(hand, 1, (const unsigned char*)jsonstring, strlen(jsonstring)); virJSONError(VIR_ERR_INTERNAL_ERROR, _("cannot parse json %s: %s"), jsonstring, (const char*) errstr); VIR_FREE(errstr); virJSONValueFree(parser.head); goto cleanup; } ret = parser.head; cleanup: yajl_free(hand); if (parser.nstate) { int i; VIR_WARN("cleanup state %d", parser.nstate); for (i = 0 ; i < parser.nstate ; i++) { VIR_FREE(parser.state[i].key); } } VIR_DEBUG("result=%p", parser.head); return ret; }
char *virJSONValueToString(virJSONValuePtr object) { yajl_gen g; const unsigned char *str; char *ret = NULL; yajl_size_t len; # ifndef HAVE_YAJL2 yajl_gen_config conf = { 0, " " }; /* Turns off pretty printing since QEMU can't cope */ # endif VIR_DEBUG("object=%p", object); # ifdef HAVE_YAJL2 g = yajl_gen_alloc(NULL); if (g) { yajl_gen_config(g, yajl_gen_beautify, 0); yajl_gen_config(g, yajl_gen_indent_string, " "); yajl_gen_config(g, yajl_gen_validate_utf8, 1); } # else g = yajl_gen_alloc(&conf, NULL); # endif if (!g) { virJSONError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to create JSON formatter")); goto cleanup; } if (virJSONValueToStringOne(object, g) < 0) { virReportOOMError(); goto cleanup; } if (yajl_gen_get_buf(g, &str, &len) != yajl_gen_status_ok) { virReportOOMError(); goto cleanup; } if (!(ret = strdup((const char *)str))) virReportOOMError(); cleanup: yajl_gen_free(g); VIR_DEBUG("result=%s", NULLSTR(ret)); return ret; }