summary refs log tree commit diff stats
path: root/include/qobject
diff options
context:
space:
mode:
Diffstat (limited to 'include/qobject')
-rw-r--r--include/qobject/json-parser.h46
-rw-r--r--include/qobject/json-writer.h35
-rw-r--r--include/qobject/qbool.h31
-rw-r--r--include/qobject/qdict.h71
-rw-r--r--include/qobject/qjson.h31
-rw-r--r--include/qobject/qlist.h69
-rw-r--r--include/qobject/qlit.h55
-rw-r--r--include/qobject/qnull.h33
-rw-r--r--include/qobject/qnum.h75
-rw-r--r--include/qobject/qobject.h144
-rw-r--r--include/qobject/qstring.h33
11 files changed, 623 insertions, 0 deletions
diff --git a/include/qobject/json-parser.h b/include/qobject/json-parser.h
new file mode 100644
index 0000000000..7345a9bd5c
--- /dev/null
+++ b/include/qobject/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/qobject/json-writer.h b/include/qobject/json-writer.h
new file mode 100644
index 0000000000..b70ba64077
--- /dev/null
+++ b/include/qobject/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/qobject/qbool.h b/include/qobject/qbool.h
new file mode 100644
index 0000000000..b348e17867
--- /dev/null
+++ b/include/qobject/qbool.h
@@ -0,0 +1,31 @@
+/*
+ * 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 "qobject/qobject.h"
+
+struct QBool {
+    struct QObjectBase_ base;
+    bool value;
+};
+
+void qbool_unref(QBool *q);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QBool, qbool_unref)
+
+QBool *qbool_from_bool(bool value);
+bool qbool_get_bool(const QBool *qb);
+
+#endif /* QBOOL_H */
diff --git a/include/qobject/qdict.h b/include/qobject/qdict.h
new file mode 100644
index 0000000000..903e6e5462
--- /dev/null
+++ b/include/qobject/qdict.h
@@ -0,0 +1,71 @@
+/*
+ * 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 "qobject/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];
+};
+
+void qdict_unref(QDict *q);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QDict, qdict_unref)
+
+/* 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);
+
+#endif /* QDICT_H */
diff --git a/include/qobject/qjson.h b/include/qobject/qjson.h
new file mode 100644
index 0000000000..7bd8d2de1b
--- /dev/null
+++ b/include/qobject/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)
+    G_GNUC_PRINTF(1, 0);
+QObject *qobject_from_jsonf_nofail(const char *string, ...)
+    G_GNUC_PRINTF(1, 2);
+QDict *qdict_from_vjsonf_nofail(const char *string, va_list ap)
+    G_GNUC_PRINTF(1, 0);
+QDict *qdict_from_jsonf_nofail(const char *string, ...)
+    G_GNUC_PRINTF(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/qobject/qlist.h b/include/qobject/qlist.h
new file mode 100644
index 0000000000..0377bf824e
--- /dev/null
+++ b/include/qobject/qlist.h
@@ -0,0 +1,69 @@
+/*
+ * 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 "qobject/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;
+};
+
+void qlist_unref(QList *q);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QList, qlist_unref)
+
+#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/qobject/qlit.h b/include/qobject/qlit.h
new file mode 100644
index 0000000000..c0676d5daf
--- /dev/null
+++ b/include/qobject/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/qobject/qnull.h b/include/qobject/qnull.h
new file mode 100644
index 0000000000..4423836a0c
--- /dev/null
+++ b/include/qobject/qnull.h
@@ -0,0 +1,33 @@
+/*
+ * 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 "qobject/qobject.h"
+
+struct QNull {
+    struct QObjectBase_ base;
+};
+
+extern QNull qnull_;
+
+static inline QNull *qnull(void)
+{
+    return qobject_ref(&qnull_);
+}
+
+void qnull_unref(QNull *q);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QNull, qnull_unref)
+
+#endif /* QNULL_H */
diff --git a/include/qobject/qnum.h b/include/qobject/qnum.h
new file mode 100644
index 0000000000..1ce24b3668
--- /dev/null
+++ b/include/qobject/qnum.h
@@ -0,0 +1,75 @@
+/*
+ * 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 "qobject/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;
+};
+
+void qnum_unref(QNum *q);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QNum, qnum_unref)
+
+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/qobject/qobject.h b/include/qobject/qobject.h
new file mode 100644
index 0000000000..a6244d0ce0
--- /dev/null
+++ b/include/qobject/qobject.h
@@ -0,0 +1,144 @@
+/*
+ * 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/qobject/ */
+struct QObjectBase_ {
+    QType type;
+    size_t refcnt;
+};
+
+/* this struct must have no other members than base */
+struct QObject {
+    struct QObjectBase_ base;
+};
+
+/*
+ * Preprocessor sorcery ahead: use a different identifier for the
+ * local variable in each expansion, so we can nest macro calls
+ * without shadowing variables.
+ */
+#define QOBJECT_INTERNAL(obj, _obj) ({                          \
+    typeof(obj) _obj = (obj);                                   \
+    _obj ? container_of(&_obj->base, QObject, base) : NULL;     \
+})
+#define QOBJECT(obj) QOBJECT_INTERNAL((obj), MAKE_IDENTIFIER(_obj))
+
+/* 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/qobject/qstring.h b/include/qobject/qstring.h
new file mode 100644
index 0000000000..1e2abe4032
--- /dev/null
+++ b/include/qobject/qstring.h
@@ -0,0 +1,33 @@
+/*
+ * 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 "qobject/qobject.h"
+
+struct QString {
+    struct QObjectBase_ base;
+    const char *string;
+};
+
+void qstring_unref(QString *q);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QString, qstring_unref)
+
+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 */