aboutsummaryrefslogtreecommitdiffstats
path: root/include/qapi/qmp
diff options
context:
space:
mode:
Diffstat (limited to 'include/qapi/qmp')
-rw-r--r--include/qapi/qmp/dispatch.h67
-rw-r--r--include/qapi/qmp/json-parser.h46
-rw-r--r--include/qapi/qmp/json-writer.h35
-rw-r--r--include/qapi/qmp/qbool.h27
-rw-r--r--include/qapi/qmp/qdict.h70
-rw-r--r--include/qapi/qmp/qerror.h71
-rw-r--r--include/qapi/qmp/qjson.h31
-rw-r--r--include/qapi/qmp/qlist.h65
-rw-r--r--include/qapi/qmp/qlit.h55
-rw-r--r--include/qapi/qmp/qnull.h29
-rw-r--r--include/qapi/qmp/qnum.h71
-rw-r--r--include/qapi/qmp/qobject.h138
-rw-r--r--include/qapi/qmp/qstring.h29
13 files changed, 734 insertions, 0 deletions
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
new file mode 100644
index 000000000..1e4240fd0
--- /dev/null
+++ b/include/qapi/qmp/dispatch.h
@@ -0,0 +1,67 @@
+/*
+ * Core Definitions for QAPI/QMP Dispatch
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_QMP_DISPATCH_H
+#define QAPI_QMP_DISPATCH_H
+
+#include "monitor/monitor.h"
+#include "qemu/queue.h"
+
+typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
+
+typedef enum QmpCommandOptions
+{
+ QCO_NO_SUCCESS_RESP = (1U << 0),
+ QCO_ALLOW_OOB = (1U << 1),
+ QCO_ALLOW_PRECONFIG = (1U << 2),
+ QCO_COROUTINE = (1U << 3),
+} QmpCommandOptions;
+
+typedef struct QmpCommand
+{
+ const char *name;
+ /* Runs in coroutine context if QCO_COROUTINE is set */
+ QmpCommandFunc *fn;
+ QmpCommandOptions options;
+ unsigned special_features;
+ QTAILQ_ENTRY(QmpCommand) node;
+ bool enabled;
+ const char *disable_reason;
+} QmpCommand;
+
+typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
+
+void qmp_register_command(QmpCommandList *cmds, const char *name,
+ QmpCommandFunc *fn, QmpCommandOptions options,
+ unsigned special_features);
+const QmpCommand *qmp_find_command(const QmpCommandList *cmds,
+ const char *name);
+void qmp_disable_command(QmpCommandList *cmds, const char *name,
+ const char *err_msg);
+void qmp_enable_command(QmpCommandList *cmds, const char *name);
+
+bool qmp_command_is_enabled(const QmpCommand *cmd);
+bool qmp_command_available(const QmpCommand *cmd, Error **errp);
+const char *qmp_command_name(const QmpCommand *cmd);
+bool qmp_has_success_response(const QmpCommand *cmd);
+QDict *qmp_error_response(Error *err);
+QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
+ bool allow_oob, Monitor *cur_mon);
+bool qmp_is_oob(const QDict *dict);
+
+typedef void (*qmp_cmd_callback_fn)(const QmpCommand *cmd, void *opaque);
+
+void qmp_for_each_command(const QmpCommandList *cmds, qmp_cmd_callback_fn fn,
+ void *opaque);
+
+#endif
diff --git a/include/qapi/qmp/json-parser.h b/include/qapi/qmp/json-parser.h
new file mode 100644
index 000000000..7345a9bd5
--- /dev/null
+++ b/include/qapi/qmp/json-parser.h
@@ -0,0 +1,46 @@
+/*
+ * JSON Parser
+ *
+ * Copyright IBM, Corp. 2009
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_QMP_JSON_PARSER_H
+#define QAPI_QMP_JSON_PARSER_H
+
+typedef struct JSONLexer {
+ int start_state, state;
+ GString *token;
+ int x, y;
+} JSONLexer;
+
+typedef struct JSONMessageParser {
+ void (*emit)(void *opaque, QObject *json, Error *err);
+ void *opaque;
+ va_list *ap;
+ JSONLexer lexer;
+ int brace_count;
+ int bracket_count;
+ GQueue tokens;
+ uint64_t token_size;
+} JSONMessageParser;
+
+void json_message_parser_init(JSONMessageParser *parser,
+ void (*emit)(void *opaque, QObject *json,
+ Error *err),
+ void *opaque, va_list *ap);
+
+void json_message_parser_feed(JSONMessageParser *parser,
+ const char *buffer, size_t size);
+
+void json_message_parser_flush(JSONMessageParser *parser);
+
+void json_message_parser_destroy(JSONMessageParser *parser);
+
+#endif
diff --git a/include/qapi/qmp/json-writer.h b/include/qapi/qmp/json-writer.h
new file mode 100644
index 000000000..b70ba6407
--- /dev/null
+++ b/include/qapi/qmp/json-writer.h
@@ -0,0 +1,35 @@
+/*
+ * JSON Writer
+ *
+ * Copyright (c) 2020 Red Hat Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef JSON_WRITER_H
+#define JSON_WRITER_H
+
+JSONWriter *json_writer_new(bool pretty);
+const char *json_writer_get(JSONWriter *);
+GString *json_writer_get_and_free(JSONWriter *);
+void json_writer_free(JSONWriter *);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(JSONWriter, json_writer_free)
+
+void json_writer_start_object(JSONWriter *, const char *name);
+void json_writer_end_object(JSONWriter *);
+void json_writer_start_array(JSONWriter *, const char *name);
+void json_writer_end_array(JSONWriter *);
+void json_writer_bool(JSONWriter *, const char *name, bool val);
+void json_writer_null(JSONWriter *, const char *name);
+void json_writer_int64(JSONWriter *, const char *name, int64_t val);
+void json_writer_uint64(JSONWriter *, const char *name, uint64_t val);
+void json_writer_double(JSONWriter *, const char *name, double val);
+void json_writer_str(JSONWriter *, const char *name, const char *str);
+
+#endif
diff --git a/include/qapi/qmp/qbool.h b/include/qapi/qmp/qbool.h
new file mode 100644
index 000000000..2f888d105
--- /dev/null
+++ b/include/qapi/qmp/qbool.h
@@ -0,0 +1,27 @@
+/*
+ * QBool Module
+ *
+ * Copyright IBM, Corp. 2009
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QBOOL_H
+#define QBOOL_H
+
+#include "qapi/qmp/qobject.h"
+
+struct QBool {
+ struct QObjectBase_ base;
+ bool value;
+};
+
+QBool *qbool_from_bool(bool value);
+bool qbool_get_bool(const QBool *qb);
+
+#endif /* QBOOL_H */
diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
new file mode 100644
index 000000000..d5b5430e2
--- /dev/null
+++ b/include/qapi/qmp/qdict.h
@@ -0,0 +1,70 @@
+/*
+ * QDict Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QDICT_H
+#define QDICT_H
+
+#include "qapi/qmp/qobject.h"
+#include "qemu/queue.h"
+
+#define QDICT_BUCKET_MAX 512
+
+typedef struct QDictEntry {
+ char *key;
+ QObject *value;
+ QLIST_ENTRY(QDictEntry) next;
+} QDictEntry;
+
+struct QDict {
+ struct QObjectBase_ base;
+ size_t size;
+ QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX];
+};
+
+/* Object API */
+QDict *qdict_new(void);
+const char *qdict_entry_key(const QDictEntry *entry);
+QObject *qdict_entry_value(const QDictEntry *entry);
+size_t qdict_size(const QDict *qdict);
+void qdict_put_obj(QDict *qdict, const char *key, QObject *value);
+void qdict_del(QDict *qdict, const char *key);
+int qdict_haskey(const QDict *qdict, const char *key);
+QObject *qdict_get(const QDict *qdict, const char *key);
+const QDictEntry *qdict_first(const QDict *qdict);
+const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
+
+/* Helper to qdict_put_obj(), accepts any object */
+#define qdict_put(qdict, key, obj) \
+ qdict_put_obj(qdict, key, QOBJECT(obj))
+
+void qdict_put_bool(QDict *qdict, const char *key, bool value);
+void qdict_put_int(QDict *qdict, const char *key, int64_t value);
+void qdict_put_null(QDict *qdict, const char *key);
+void qdict_put_str(QDict *qdict, const char *key, const char *value);
+
+double qdict_get_double(const QDict *qdict, const char *key);
+int64_t qdict_get_int(const QDict *qdict, const char *key);
+bool qdict_get_bool(const QDict *qdict, const char *key);
+QList *qdict_get_qlist(const QDict *qdict, const char *key);
+QDict *qdict_get_qdict(const QDict *qdict, const char *key);
+const char *qdict_get_str(const QDict *qdict, const char *key);
+int64_t qdict_get_try_int(const QDict *qdict, const char *key,
+ int64_t def_value);
+bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value);
+const char *qdict_get_try_str(const QDict *qdict, const char *key);
+
+QDict *qdict_clone_shallow(const QDict *src);
+
+QObject *qdict_crumple(const QDict *src, Error **errp);
+void qdict_flatten(QDict *qdict);
+
+#endif /* QDICT_H */
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
new file mode 100644
index 000000000..596fce0c5
--- /dev/null
+++ b/include/qapi/qmp/qerror.h
@@ -0,0 +1,71 @@
+/*
+ * QError Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#ifndef QERROR_H
+#define QERROR_H
+
+/*
+ * These macros will go away, please don't use in new code, and do not
+ * add new ones!
+ */
+
+#define QERR_BUS_NO_HOTPLUG \
+ "Bus '%s' does not support hotplugging"
+
+#define QERR_DEVICE_HAS_NO_MEDIUM \
+ "Device '%s' has no medium"
+
+#define QERR_DEVICE_IN_USE \
+ "Device '%s' is in use"
+
+#define QERR_DEVICE_NO_HOTPLUG \
+ "Device '%s' does not support hotplugging"
+
+#define QERR_FEATURE_DISABLED \
+ "The feature '%s' is not enabled"
+
+#define QERR_INVALID_PARAMETER \
+ "Invalid parameter '%s'"
+
+#define QERR_INVALID_PARAMETER_TYPE \
+ "Invalid parameter type for '%s', expected: %s"
+
+#define QERR_INVALID_PARAMETER_VALUE \
+ "Parameter '%s' expects %s"
+
+#define QERR_IO_ERROR \
+ "An IO error has occurred"
+
+#define QERR_MIGRATION_ACTIVE \
+ "There's a migration process in progress"
+
+#define QERR_MISSING_PARAMETER \
+ "Parameter '%s' is missing"
+
+#define QERR_PERMISSION_DENIED \
+ "Insufficient permission to perform this operation"
+
+#define QERR_PROPERTY_VALUE_BAD \
+ "Property '%s.%s' doesn't take value '%s'"
+
+#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
+ "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
+
+#define QERR_QGA_COMMAND_FAILED \
+ "Guest agent command failed, error was '%s'"
+
+#define QERR_REPLAY_NOT_SUPPORTED \
+ "Record/replay feature is not supported for '%s'"
+
+#define QERR_UNSUPPORTED \
+ "this feature or command is not currently supported"
+
+#endif /* QERROR_H */
diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h
new file mode 100644
index 000000000..593b40b4e
--- /dev/null
+++ b/include/qapi/qmp/qjson.h
@@ -0,0 +1,31 @@
+/*
+ * QObject JSON integration
+ *
+ * Copyright IBM, Corp. 2009
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QJSON_H
+#define QJSON_H
+
+QObject *qobject_from_json(const char *string, Error **errp);
+
+QObject *qobject_from_vjsonf_nofail(const char *string, va_list ap)
+ GCC_FMT_ATTR(1, 0);
+QObject *qobject_from_jsonf_nofail(const char *string, ...)
+ GCC_FMT_ATTR(1, 2);
+QDict *qdict_from_vjsonf_nofail(const char *string, va_list ap)
+ GCC_FMT_ATTR(1, 0);
+QDict *qdict_from_jsonf_nofail(const char *string, ...)
+ GCC_FMT_ATTR(1, 2);
+
+GString *qobject_to_json(const QObject *obj);
+GString *qobject_to_json_pretty(const QObject *obj, bool pretty);
+
+#endif /* QJSON_H */
diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h
new file mode 100644
index 000000000..06e98ad5f
--- /dev/null
+++ b/include/qapi/qmp/qlist.h
@@ -0,0 +1,65 @@
+/*
+ * QList Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QLIST_H
+#define QLIST_H
+
+#include "qapi/qmp/qobject.h"
+#include "qemu/queue.h"
+
+typedef struct QListEntry {
+ QObject *value;
+ QTAILQ_ENTRY(QListEntry) next;
+} QListEntry;
+
+struct QList {
+ struct QObjectBase_ base;
+ QTAILQ_HEAD(,QListEntry) head;
+};
+
+#define qlist_append(qlist, obj) \
+ qlist_append_obj(qlist, QOBJECT(obj))
+
+void qlist_append_bool(QList *qlist, bool value);
+void qlist_append_int(QList *qlist, int64_t value);
+void qlist_append_null(QList *qlist);
+void qlist_append_str(QList *qlist, const char *value);
+
+#define QLIST_FOREACH_ENTRY(qlist, var) \
+ for ((var) = QTAILQ_FIRST(&(qlist)->head); \
+ (var); \
+ (var) = QTAILQ_NEXT((var), next))
+
+static inline QObject *qlist_entry_obj(const QListEntry *entry)
+{
+ return entry->value;
+}
+
+QList *qlist_new(void);
+QList *qlist_copy(QList *src);
+void qlist_append_obj(QList *qlist, QObject *obj);
+QObject *qlist_pop(QList *qlist);
+QObject *qlist_peek(QList *qlist);
+int qlist_empty(const QList *qlist);
+size_t qlist_size(const QList *qlist);
+
+static inline const QListEntry *qlist_first(const QList *qlist)
+{
+ return QTAILQ_FIRST(&qlist->head);
+}
+
+static inline const QListEntry *qlist_next(const QListEntry *entry)
+{
+ return QTAILQ_NEXT(entry, next);
+}
+
+#endif /* QLIST_H */
diff --git a/include/qapi/qmp/qlit.h b/include/qapi/qmp/qlit.h
new file mode 100644
index 000000000..c0676d5da
--- /dev/null
+++ b/include/qapi/qmp/qlit.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright IBM, Corp. 2009
+ * Copyright (c) 2013, 2015, 2017 Red Hat Inc.
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Markus Armbruster <armbru@redhat.com>
+ * Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+#ifndef QLIT_H
+#define QLIT_H
+
+#include "qobject.h"
+
+typedef struct QLitDictEntry QLitDictEntry;
+typedef struct QLitObject QLitObject;
+
+struct QLitObject {
+ QType type;
+ union {
+ bool qbool;
+ int64_t qnum;
+ const char *qstr;
+ QLitDictEntry *qdict;
+ QLitObject *qlist;
+ } value;
+};
+
+struct QLitDictEntry {
+ const char *key;
+ QLitObject value;
+};
+
+#define QLIT_QNULL \
+ { .type = QTYPE_QNULL }
+#define QLIT_QBOOL(val) \
+ { .type = QTYPE_QBOOL, .value.qbool = (val) }
+#define QLIT_QNUM(val) \
+ { .type = QTYPE_QNUM, .value.qnum = (val) }
+#define QLIT_QSTR(val) \
+ { .type = QTYPE_QSTRING, .value.qstr = (val) }
+#define QLIT_QDICT(val) \
+ { .type = QTYPE_QDICT, .value.qdict = (val) }
+#define QLIT_QLIST(val) \
+ { .type = QTYPE_QLIST, .value.qlist = (val) }
+
+bool qlit_equal_qobject(const QLitObject *lhs, const QObject *rhs);
+
+QObject *qobject_from_qlit(const QLitObject *qlit);
+
+#endif /* QLIT_H */
diff --git a/include/qapi/qmp/qnull.h b/include/qapi/qmp/qnull.h
new file mode 100644
index 000000000..e84ecceed
--- /dev/null
+++ b/include/qapi/qmp/qnull.h
@@ -0,0 +1,29 @@
+/*
+ * QNull
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QNULL_H
+#define QNULL_H
+
+#include "qapi/qmp/qobject.h"
+
+struct QNull {
+ struct QObjectBase_ base;
+};
+
+extern QNull qnull_;
+
+static inline QNull *qnull(void)
+{
+ return qobject_ref(&qnull_);
+}
+
+#endif /* QNULL_H */
diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h
new file mode 100644
index 000000000..7f84e20bf
--- /dev/null
+++ b/include/qapi/qmp/qnum.h
@@ -0,0 +1,71 @@
+/*
+ * QNum Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Marc-André Lureau <marcandre.lureau@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QNUM_H
+#define QNUM_H
+
+#include "qapi/qmp/qobject.h"
+
+typedef enum {
+ QNUM_I64,
+ QNUM_U64,
+ QNUM_DOUBLE
+} QNumKind;
+
+/*
+ * QNum encapsulates how our dialect of JSON fills in the blanks left
+ * by the JSON specification (RFC 8259) regarding numbers.
+ *
+ * Conceptually, we treat number as an abstract type with three
+ * concrete subtypes: floating-point, signed integer, unsigned
+ * integer. QNum implements this as a discriminated union of double,
+ * int64_t, uint64_t.
+ *
+ * The JSON parser picks the subtype as follows. If the number has a
+ * decimal point or an exponent, it is floating-point. Else if it
+ * fits into int64_t, it's signed integer. Else if it fits into
+ * uint64_t, it's unsigned integer. Else it's floating-point.
+ *
+ * Any number can serve as double: qnum_get_double() converts under
+ * the hood.
+ *
+ * An integer can serve as signed / unsigned integer as long as it is
+ * in range: qnum_get_try_int() / qnum_get_try_uint() check range and
+ * convert under the hood.
+ */
+struct QNum {
+ struct QObjectBase_ base;
+ QNumKind kind;
+ union {
+ int64_t i64;
+ uint64_t u64;
+ double dbl;
+ } u;
+};
+
+QNum *qnum_from_int(int64_t value);
+QNum *qnum_from_uint(uint64_t value);
+QNum *qnum_from_double(double value);
+
+bool qnum_get_try_int(const QNum *qn, int64_t *val);
+int64_t qnum_get_int(const QNum *qn);
+
+bool qnum_get_try_uint(const QNum *qn, uint64_t *val);
+uint64_t qnum_get_uint(const QNum *qn);
+
+double qnum_get_double(QNum *qn);
+
+char *qnum_to_string(QNum *qn);
+
+#endif /* QNUM_H */
diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
new file mode 100644
index 000000000..9003b71fd
--- /dev/null
+++ b/include/qapi/qmp/qobject.h
@@ -0,0 +1,138 @@
+/*
+ * QEMU Object Model.
+ *
+ * Based on ideas by Avi Kivity <avi@redhat.com>
+ *
+ * Copyright (C) 2009, 2015 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ * QObject Reference Counts Terminology
+ * ------------------------------------
+ *
+ * - Returning references: A function that returns an object may
+ * return it as either a weak or a strong reference. If the
+ * reference is strong, you are responsible for calling
+ * qobject_unref() on the reference when you are done.
+ *
+ * If the reference is weak, the owner of the reference may free it at
+ * any time in the future. Before storing the reference anywhere, you
+ * should call qobject_ref() to make the reference strong.
+ *
+ * - Transferring ownership: when you transfer ownership of a reference
+ * by calling a function, you are no longer responsible for calling
+ * qobject_unref() when the reference is no longer needed. In other words,
+ * when the function returns you must behave as if the reference to the
+ * passed object was weak.
+ */
+#ifndef QOBJECT_H
+#define QOBJECT_H
+
+#include "qapi/qapi-builtin-types.h"
+
+/* Not for use outside include/qapi/qmp/ */
+struct QObjectBase_ {
+ QType type;
+ size_t refcnt;
+};
+
+/* this struct must have no other members than base */
+struct QObject {
+ struct QObjectBase_ base;
+};
+
+#define QOBJECT(obj) ({ \
+ typeof(obj) _obj = (obj); \
+ _obj ? container_of(&(_obj)->base, QObject, base) : NULL; \
+})
+
+/* Required for qobject_to() */
+#define QTYPE_CAST_TO_QNull QTYPE_QNULL
+#define QTYPE_CAST_TO_QNum QTYPE_QNUM
+#define QTYPE_CAST_TO_QString QTYPE_QSTRING
+#define QTYPE_CAST_TO_QDict QTYPE_QDICT
+#define QTYPE_CAST_TO_QList QTYPE_QLIST
+#define QTYPE_CAST_TO_QBool QTYPE_QBOOL
+
+QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7,
+ "The QTYPE_CAST_TO_* list needs to be extended");
+
+#define qobject_to(type, obj) \
+ ((type *)qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)))
+
+static inline void qobject_ref_impl(QObject *obj)
+{
+ if (obj) {
+ obj->base.refcnt++;
+ }
+}
+
+/**
+ * qobject_is_equal(): Return whether the two objects are equal.
+ *
+ * Any of the pointers may be NULL; return true if both are. Always
+ * return false if only one is (therefore a QNull object is not
+ * considered equal to a NULL pointer).
+ */
+bool qobject_is_equal(const QObject *x, const QObject *y);
+
+/**
+ * qobject_destroy(): Free resources used by the object
+ * For use via qobject_unref() only!
+ */
+void qobject_destroy(QObject *obj);
+
+static inline void qobject_unref_impl(QObject *obj)
+{
+ assert(!obj || obj->base.refcnt);
+ if (obj && --obj->base.refcnt == 0) {
+ qobject_destroy(obj);
+ }
+}
+
+/**
+ * qobject_ref(): Increment QObject's reference count
+ *
+ * Returns: the same @obj. The type of @obj will be propagated to the
+ * return type.
+ */
+#define qobject_ref(obj) ({ \
+ typeof(obj) _o = (obj); \
+ qobject_ref_impl(QOBJECT(_o)); \
+ _o; \
+})
+
+/**
+ * qobject_unref(): Decrement QObject's reference count, deallocate
+ * when it reaches zero
+ */
+#define qobject_unref(obj) qobject_unref_impl(QOBJECT(obj))
+
+/**
+ * qobject_type(): Return the QObject's type
+ */
+static inline QType qobject_type(const QObject *obj)
+{
+ assert(QTYPE_NONE < obj->base.type && obj->base.type < QTYPE__MAX);
+ return obj->base.type;
+}
+
+/**
+ * qobject_check_type(): Helper function for the qobject_to() macro.
+ * Return @obj, but only if @obj is not NULL and @type is equal to
+ * @obj's type. Return NULL otherwise.
+ */
+static inline QObject *qobject_check_type(const QObject *obj, QType type)
+{
+ if (obj && qobject_type(obj) == type) {
+ return (QObject *)obj;
+ } else {
+ return NULL;
+ }
+}
+
+#endif /* QOBJECT_H */
diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h
new file mode 100644
index 000000000..1d8ba4693
--- /dev/null
+++ b/include/qapi/qmp/qstring.h
@@ -0,0 +1,29 @@
+/*
+ * QString Module
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ * Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QSTRING_H
+#define QSTRING_H
+
+#include "qapi/qmp/qobject.h"
+
+struct QString {
+ struct QObjectBase_ base;
+ const char *string;
+};
+
+QString *qstring_new(void);
+QString *qstring_from_str(const char *str);
+QString *qstring_from_substr(const char *str, size_t start, size_t end);
+QString *qstring_from_gstring(GString *gstr);
+const char *qstring_get_str(const QString *qstring);
+
+#endif /* QSTRING_H */