From patchwork Fri Dec 26 14:42:44 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 424130 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 57AD21400A0 for ; Sat, 27 Dec 2014 01:44:56 +1100 (AEDT) Received: from localhost ([::1]:53636 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y4W8M-0004s8-BN for incoming@patchwork.ozlabs.org; Fri, 26 Dec 2014 09:44:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38800) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y4W6U-00015C-5w for qemu-devel@nongnu.org; Fri, 26 Dec 2014 09:42:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Y4W6M-0000PI-Tw for qemu-devel@nongnu.org; Fri, 26 Dec 2014 09:42:58 -0500 Received: from cantor2.suse.de ([195.135.220.15]:59148 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Y4W6M-0000Oq-Kz for qemu-devel@nongnu.org; Fri, 26 Dec 2014 09:42:50 -0500 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id B06F4ACC3; Fri, 26 Dec 2014 14:42:48 +0000 (UTC) From: Alexander Graf To: qemu-devel@nongnu.org Date: Fri, 26 Dec 2014 15:42:44 +0100 Message-Id: <1419604968-87437-2-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1419604968-87437-1-git-send-email-agraf@suse.de> References: <1419604968-87437-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 195.135.220.15 Cc: amit.shah@redhat.com, pbonzini@redhat.com, afaerber@suse.de, quintela@redhat.com Subject: [Qemu-devel] [PATCH v3 1/5] QJSON: Add JSON writer X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org To support programmatic JSON assembly while keeping the code that generates it readable, this patch introduces a simple JSON writer. It emits JSON serially into a buffer in memory. The nice thing about this writer is its simplicity and low memory overhead. Unlike the QMP JSON writer, this one does not need to spawn QObjects for every element it wants to represent. This is a prerequisite for the migration stream format description generator. Signed-off-by: Alexander Graf --- Makefile.objs | 1 + include/qjson.h | 28 +++++++++++++++++ qjson.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 include/qjson.h create mode 100644 qjson.c diff --git a/Makefile.objs b/Makefile.objs index abeb902..28999d3 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -51,6 +51,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/ common-obj-y += migration/ common-obj-y += qemu-char.o #aio.o common-obj-y += page_cache.o +common-obj-y += qjson.o common-obj-$(CONFIG_SPICE) += spice-qemu-char.o diff --git a/include/qjson.h b/include/qjson.h new file mode 100644 index 0000000..8f8c145 --- /dev/null +++ b/include/qjson.h @@ -0,0 +1,28 @@ +/* + * QEMU JSON writer + * + * Copyright Alexander Graf + * + * Authors: + * Alexander Graf +#include +#include +#include + +struct QJSON { + QString *str; + bool omit_comma; + unsigned long self_size_offset; +}; + +static void json_emit_element(QJSON *json, const char *name) +{ + /* Check whether we need to print a , before an element */ + if (json->omit_comma) { + json->omit_comma = false; + } else { + qstring_append(json->str, ", "); + } + + if (name) { + qstring_append(json->str, "\""); + qstring_append(json->str, name); + qstring_append(json->str, "\" : "); + } +} + +void json_start_object(QJSON *json, const char *name) +{ + json_emit_element(json, name); + qstring_append(json->str, "{ "); + json->omit_comma = true; +} + +void json_end_object(QJSON *json) +{ + qstring_append(json->str, " }"); + json->omit_comma = false; +} + +void json_start_array(QJSON *json, const char *name) +{ + json_emit_element(json, name); + qstring_append(json->str, "[ "); + json->omit_comma = true; +} + +void json_end_array(QJSON *json) +{ + qstring_append(json->str, " ]"); + json->omit_comma = false; +} + +void json_prop_int(QJSON *json, const char *name, int64_t val) +{ + json_emit_element(json, name); + qstring_append_int(json->str, val); +} + +void json_prop_str(QJSON *json, const char *name, const char *str) +{ + json_emit_element(json, name); + qstring_append_chr(json->str, '"'); + qstring_append(json->str, str); + qstring_append_chr(json->str, '"'); +} + +const char *qjson_get_str(QJSON *json) +{ + return qstring_get_str(json->str); +} + +QJSON *qjson_new(void) +{ + QJSON *json = g_new(QJSON, 1); + json->str = qstring_from_str("{ "); + json->omit_comma = true; + return json; +} + +void qjson_finish(QJSON *json) +{ + json_end_object(json); +}