From nobody Sat Nov 23 16:40:24 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1723672457491305.5801506216163; Wed, 14 Aug 2024 14:54:17 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 62AD8135F; Wed, 14 Aug 2024 17:54:16 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 44682157B; Wed, 14 Aug 2024 17:43:31 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id E1F341370; Wed, 14 Aug 2024 17:43:26 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id F06081441 for ; Wed, 14 Aug 2024 17:43:15 -0400 (EDT) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-157-O58due7EMZ2xPeBbx0gqkA-1; Wed, 14 Aug 2024 17:43:14 -0400 Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 83F171954B0F for ; Wed, 14 Aug 2024 21:43:13 +0000 (UTC) Received: from hjs.brq.redhat.com (unknown [10.43.3.187]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D223B1955E8C for ; Wed, 14 Aug 2024 21:43:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.6 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1723671795; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0QpdawE802YXLyERValDiMOL/VjP1MI54iaHT6+tg1Y=; b=QCZ29PsCEX4UNTfPrAE0YmrCTkEeQ5VyA59kgL3O26tVB/hEODYRSU2uGGzX1Y8PxoLvou Okqu8+EjaP6D9QhNHkgV2VI0yS0/2XwRB6gVzqlttMrbaPab29bG8RdsPXAlnTUX6oLgNM 8L2b12GGLyfWVkOOXOnMKGLfVbgLZwQ= X-MC-Unique: O58due7EMZ2xPeBbx0gqkA-1 From: =?UTF-8?q?J=C3=A1n=20Tomko?= To: devel@lists.libvirt.org Subject: [libvirt PATCH 07/20] util: json: write a json-c implementation Date: Wed, 14 Aug 2024 23:40:22 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: KIKAU6RLXRG75OUFXFJHWPQABGTNDCJR X-Message-ID-Hash: KIKAU6RLXRG75OUFXFJHWPQABGTNDCJR X-MailFrom: jtomko@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1723672458378116600 Content-Type: text/plain; charset="utf-8" Write an alternative implementation of our virJSON functions, using json-c instead of yajl. Signed-off-by: J=C3=A1n Tomko --- src/util/virjson.c | 177 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 2 deletions(-) diff --git a/src/util/virjson.c b/src/util/virjson.c index 0edf86cd1c..7a22c54f03 100644 --- a/src/util/virjson.c +++ b/src/util/virjson.c @@ -32,7 +32,9 @@ #include "virenum.h" #include "virbitmap.h" =20 -#if WITH_YAJL +#if WITH_JSON_C +# include +#elif WITH_YAJL # include # include =20 @@ -1389,8 +1391,179 @@ virJSONValueCopy(const virJSONValue *in) return out; } =20 +#if WITH_JSON_C +static virJSONValue * +virJSONValueFromJsonC(json_object *jobj) +{ + enum json_type type =3D json_object_get_type(jobj); + virJSONValue *ret =3D NULL; =20 -#if WITH_YAJL + switch (type) { + case json_type_null: + ret =3D virJSONValueNewNull(); + break; + case json_type_boolean: + ret =3D virJSONValueNewBoolean(json_object_get_boolean(jobj)); + break; + case json_type_double: + case json_type_int: { + ret =3D virJSONValueNewNumber(g_strdup(json_object_get_string(jobj= ))); + break; + } + case json_type_object: + ret =3D virJSONValueNewObject(); + { + json_object_object_foreach(jobj, key, val) { + virJSONValue *cur =3D virJSONValueFromJsonC(val); + + if (virJSONValueObjectAppend(ret, key, &cur) < 0) { + g_free(ret); + return NULL; + } + } + } + break; + case json_type_array: { + size_t len; + size_t i; + + ret =3D virJSONValueNewArray(); + len =3D json_object_array_length(jobj); + + for (i =3D 0; i < len; i++) { + virJSONValue *cur =3D NULL; + json_object *val =3D NULL; + + val =3D json_object_array_get_idx(jobj, i); + + cur =3D virJSONValueFromJsonC(val); + + virJSONValueArrayAppend(ret, &cur); + } + break; + } + case json_type_string: + ret =3D virJSONValueNewString(g_strdup(json_object_get_string(jobj= ))); + break; + } + + VIR_DEBUG("ret=3D%p", ret); + return ret; +} + +virJSONValue * +virJSONValueFromString(const char *jsonstring) +{ + json_object *jobj =3D NULL; + virJSONValue *ret =3D NULL; + json_tokener *tok =3D NULL; + enum json_tokener_error jerr; + int jsonflags =3D JSON_TOKENER_STRICT | JSON_TOKENER_VALIDATE_UTF8; + + VIR_DEBUG("string=3D%s", jsonstring); + + tok =3D json_tokener_new(); + json_tokener_set_flags(tok, jsonflags); + jobj =3D json_tokener_parse_ex(tok, jsonstring, strlen(jsonstring)); + jerr =3D json_tokener_get_error(tok); + if (jerr !=3D json_tokener_success) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", json_tokener_error_desc(jerr)); + goto cleanup; + } + ret =3D virJSONValueFromJsonC(jobj); + + cleanup: + VIR_DEBUG("result=3D%p", ret); + json_object_put(jobj); + json_tokener_free(tok); + return ret; +} + +static json_object * +virJSONValueToJsonC(virJSONValue *object) +{ + json_object *ret =3D NULL; + size_t i; + + VIR_DEBUG("object=3D%p type=3D%d", object, object->type); + + switch (object->type) { + case VIR_JSON_TYPE_OBJECT: + // constant key? + ret =3D json_object_new_object(); + for (i =3D 0; i < object->data.object.npairs; i++) { + json_object *child =3D virJSONValueToJsonC(object->data.object= .pairs[i].value); + json_object_object_add(ret, object->data.object.pairs[i].key, = child); + } + return ret; + case VIR_JSON_TYPE_ARRAY: + /* json_object_new_array_ext was introduced in json-c 0.16 */ +# if JSON_C_VERSION_NUM < ((0 << 16) | (16 << 8)) + ret =3D json_object_new_array(); +# else + ret =3D json_object_new_array_ext(object->data.array.nvalues); +# endif + for (i =3D 0; i < object->data.array.nvalues; i++) { + json_object_array_add(ret, + virJSONValueToJsonC(object->data.array.v= alues[i])); + } + return ret; + + case VIR_JSON_TYPE_STRING: + return json_object_new_string(object->data.string); + + case VIR_JSON_TYPE_NUMBER: { + /* Yes. That's a random value. We only care about the string. */ + return json_object_new_double_s(299792458, object->data.number); + } + case VIR_JSON_TYPE_BOOLEAN: + return json_object_new_boolean(object->data.boolean); + + case VIR_JSON_TYPE_NULL: + default: + return NULL; + } + return NULL; +} + + +int +virJSONValueToBuffer(virJSONValue *object, + virBuffer *buf, + bool pretty) +{ + json_object *jobj =3D NULL; + const char *str; + size_t len; + int ret =3D -1; + int jsonflags =3D JSON_C_TO_STRING_NOSLASHESCAPE; + + VIR_DEBUG("object=3D%p", object); + + if (pretty) + jsonflags |=3D JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED; + + jobj =3D virJSONValueToJsonC(object); + if (!jobj) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to convert virJSONValue to json-c data")); + goto cleanup; + } + + str =3D json_object_to_json_string_length(jobj, jsonflags, &len); + + virBufferAdd(buf, str, len); + if (pretty) + virBufferAddLit(buf, "\n"); + ret =3D 0; + + cleanup: + json_object_put(jobj); + return ret; +} + +#elif WITH_YAJL static int virJSONParserInsertValue(virJSONParser *parser, virJSONValue **value) --=20 2.45.2