From patchwork Mon Aug 15 14:22:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 659247 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 3sCd7k5Zp5z9t2w for ; Tue, 16 Aug 2016 00:25:38 +1000 (AEST) Received: from localhost ([::1]:37286 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bZIpc-0004n6-Et for incoming@patchwork.ozlabs.org; Mon, 15 Aug 2016 10:25:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35178) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bZIn6-0002Yh-GE for qemu-devel@nongnu.org; Mon, 15 Aug 2016 10:23:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bZIn4-0008PX-5I for qemu-devel@nongnu.org; Mon, 15 Aug 2016 10:22:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59194) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bZIn3-0008PT-TM for qemu-devel@nongnu.org; Mon, 15 Aug 2016 10:22:58 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6C30AC057FA7; Mon, 15 Aug 2016 14:22:53 +0000 (UTC) Received: from t530wlan.home.berrange.com.com (vpn1-5-44.ams2.redhat.com [10.36.5.44]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u7FEMTkn008326; Mon, 15 Aug 2016 10:22:51 -0400 From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Mon, 15 Aug 2016 15:22:25 +0100 Message-Id: <1471270945-19975-12-git-send-email-berrange@redhat.com> In-Reply-To: <1471270945-19975-1-git-send-email-berrange@redhat.com> References: <1471270945-19975-1-git-send-email-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Mon, 15 Aug 2016 14:22:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v10 11/11] qmp: add support for mixed typed input visitor X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Markus Armbruster , Max Reitz , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , =?UTF-8?q?Andreas=20F=C3=A4rber?= Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add a qmp_mixed_input_visitor_new() method which returns a QMP input visitor that accepts either strings or the native data types. Signed-off-by: Daniel P. Berrange --- include/qapi/qobject-input-visitor.h | 22 ++++++++ qapi/qobject-input-visitor.c | 98 ++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h index aa911cb..d9fe1d4 100644 --- a/include/qapi/qobject-input-visitor.h +++ b/include/qapi/qobject-input-visitor.h @@ -60,4 +60,26 @@ Visitor *qobject_input_visitor_new(QObject *obj, bool strict); */ Visitor *qobject_string_input_visitor_new(QObject *obj); +/** + * qobject_mixed_input_visitor_new: + * @obj: the input object to visit + * @strict: whether to require that all input keys are consumed + * + * Create a new input visitor that converts a QObject to a QAPI object. + * + * Any scalar values in the @obj input data structure can either be + * represented as the native data type, or as strings. ie if visiting + * a boolean, the value can be a QBoolean or a QString whose contents + * represent a valid boolean. + * + * If @strict is set to true, then an error will be reported if any + * dict keys are not consumed during visitation. + * + * The returned input visitor should be released by calling + * visit_free() when no longer required. + * + * Returns: a new input visitor + */ +Visitor *qobject_mixed_input_visitor_new(QObject *obj, bool strict); + #endif diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index b79c229..d71c195 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -276,6 +276,19 @@ static void qobject_input_type_int64_str(Visitor *v, const char *name, *obj = ret; } +static void qobject_input_type_int64_mixed(Visitor *v, const char *name, + int64_t *obj, Error **errp) +{ + QObjectInputVisitor *qiv = to_qiv(v); + QObject *qobj = qobject_input_get_object(qiv, name, true); + + if (qobj && qobj->type == QTYPE_QSTRING) { + qobject_input_type_int64_str(v, name, obj, errp); + } else { + qobject_input_type_int64(v, name, obj, errp); + } +} + static void qobject_input_type_uint64(Visitor *v, const char *name, uint64_t *obj, Error **errp) { @@ -302,6 +315,19 @@ static void qobject_input_type_uint64_str(Visitor *v, const char *name, parse_option_number(name, qstr ? qstr->string : NULL, obj, errp); } +static void qobject_input_type_uint64_mixed(Visitor *v, const char *name, + uint64_t *obj, Error **errp) +{ + QObjectInputVisitor *qiv = to_qiv(v); + QObject *qobj = qobject_input_get_object(qiv, name, true); + + if (qobj && qobj->type == QTYPE_QSTRING) { + qobject_input_type_uint64_str(v, name, obj, errp); + } else { + qobject_input_type_uint64(v, name, obj, errp); + } +} + static void qobject_input_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) { @@ -327,6 +353,19 @@ static void qobject_input_type_bool_str(Visitor *v, const char *name, bool *obj, parse_option_bool(name, qstr ? qstr->string : NULL, obj, errp); } +static void qobject_input_type_bool_mixed(Visitor *v, const char *name, + bool *obj, Error **errp) +{ + QObjectInputVisitor *qiv = to_qiv(v); + QObject *qobj = qobject_input_get_object(qiv, name, true); + + if (qobj && qobj->type == QTYPE_QSTRING) { + qobject_input_type_bool_str(v, name, obj, errp); + } else { + qobject_input_type_bool(v, name, obj, errp); + } +} + static void qobject_input_type_str(Visitor *v, const char *name, char **obj, Error **errp) { @@ -388,6 +427,19 @@ static void qobject_input_type_number_str(Visitor *v, const char *name, "number"); } +static void qobject_input_type_number_mixed(Visitor *v, const char *name, + double *obj, Error **errp) +{ + QObjectInputVisitor *qiv = to_qiv(v); + QObject *qobj = qobject_input_get_object(qiv, name, true); + + if (qobj && qobj->type == QTYPE_QSTRING) { + qobject_input_type_number_str(v, name, obj, errp); + } else { + qobject_input_type_number(v, name, obj, errp); + } +} + static void qobject_input_type_any(Visitor *v, const char *name, QObject **obj, Error **errp) { @@ -435,6 +487,20 @@ static void qobject_input_type_size_str(Visitor *v, const char *name, "size"); } +static void qobject_input_type_size_mixed(Visitor *v, const char *name, + uint64_t *obj, Error **errp) +{ + QObjectInputVisitor *qiv = to_qiv(v); + QObject *qobj = qobject_input_get_object(qiv, name, true); + + if (qobj && qobj->type == QTYPE_QSTRING) { + qobject_input_type_size_str(v, name, obj, errp); + } else { + qobject_input_type_uint64(v, name, obj, errp); + } +} + + static void qobject_input_optional(Visitor *v, const char *name, bool *present) { QObjectInputVisitor *qiv = to_qiv(v); @@ -524,3 +590,35 @@ Visitor *qobject_string_input_visitor_new(QObject *obj) return &v->visitor; } + +Visitor *qobject_mixed_input_visitor_new(QObject *obj, bool strict) +{ + QObjectInputVisitor *v; + + v = g_malloc0(sizeof(*v)); + + v->visitor.type = VISITOR_INPUT; + v->visitor.start_struct = qobject_input_start_struct; + v->visitor.check_struct = qobject_input_check_struct; + v->visitor.end_struct = qobject_input_pop; + v->visitor.start_list = qobject_input_start_list; + v->visitor.next_list = qobject_input_next_list; + v->visitor.end_list = qobject_input_pop; + v->visitor.start_alternate = qobject_input_start_alternate; + v->visitor.type_int64 = qobject_input_type_int64_mixed; + v->visitor.type_uint64 = qobject_input_type_uint64_mixed; + v->visitor.type_bool = qobject_input_type_bool_mixed; + v->visitor.type_str = qobject_input_type_str; + v->visitor.type_number = qobject_input_type_number_mixed; + v->visitor.type_any = qobject_input_type_any; + v->visitor.type_null = qobject_input_type_null; + v->visitor.type_size = qobject_input_type_size_mixed; + v->visitor.optional = qobject_input_optional; + v->visitor.free = qobject_input_free; + v->strict = strict; + + v->root = obj; + qobject_incref(obj); + + return &v->visitor; +}