From patchwork Fri Oct 2 21:12:48 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Capitulino X-Patchwork-Id: 34909 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id D21CFB7C05 for ; Sat, 3 Oct 2009 07:42:26 +1000 (EST) Received: from localhost ([127.0.0.1]:56658 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MtptK-0000OV-6N for incoming@patchwork.ozlabs.org; Fri, 02 Oct 2009 17:42:18 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MtpR3-0000XZ-A8 for qemu-devel@nongnu.org; Fri, 02 Oct 2009 17:13:05 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MtpQy-0000Pd-0C for qemu-devel@nongnu.org; Fri, 02 Oct 2009 17:13:04 -0400 Received: from [199.232.76.173] (port=40821 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MtpQx-0000PN-PE for qemu-devel@nongnu.org; Fri, 02 Oct 2009 17:12:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57126) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MtpQv-0008QA-Hm for qemu-devel@nongnu.org; Fri, 02 Oct 2009 17:12:59 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n92LCuk0013284 for ; Fri, 2 Oct 2009 17:12:56 -0400 Received: from doriath (vpn-12-200.rdu.redhat.com [10.11.12.200]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id n92LCqg1029770 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Fri, 2 Oct 2009 17:12:54 -0400 Date: Fri, 2 Oct 2009 18:12:48 -0300 From: Luiz Capitulino To: qemu-devel@nongnu.org Message-ID: <20091002181248.7c38185d@doriath> Organization: Red Hat Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Subject: [Qemu-devel] [PATCH] Move QObjects to their own directory X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Luiz Capitulino --- Makefile | 15 ++- check-qdict.c | 6 +- check-qint.c | 2 +- check-qstring.c | 2 +- console.h | 2 +- migration.h | 2 +- monitor.c | 6 +- monitor.h | 2 +- net.h | 2 +- objects/qdict.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++++++ objects/qdict.h | 42 ++++++++ objects/qint.c | 66 ++++++++++++ objects/qint.h | 16 +++ objects/qobject.h | 109 +++++++++++++++++++ objects/qstring.c | 73 +++++++++++++ objects/qstring.h | 15 +++ qdict.c | 297 ----------------------------------------------------- qdict.h | 42 -------- qint.c | 66 ------------ qint.h | 16 --- qobject.h | 109 ------------------- qstring.c | 73 ------------- qstring.h | 15 --- sysemu.h | 2 +- 24 files changed, 641 insertions(+), 636 deletions(-) create mode 100644 objects/qdict.c create mode 100644 objects/qdict.h create mode 100644 objects/qint.c create mode 100644 objects/qint.h create mode 100644 objects/qobject.h create mode 100644 objects/qstring.c create mode 100644 objects/qstring.h delete mode 100644 qdict.c delete mode 100644 qdict.h delete mode 100644 qint.c delete mode 100644 qint.h delete mode 100644 qobject.h delete mode 100644 qstring.c delete mode 100644 qstring.h diff --git a/Makefile b/Makefile index de7c2aa..1d3fe7e 100644 --- a/Makefile +++ b/Makefile @@ -95,7 +95,7 @@ obj-y += buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o obj-y += qemu-char.o aio.o net-checksum.o savevm.o obj-y += msmouse.o ps2.o obj-y += qdev.o qdev-properties.o ssi.o -obj-y += qint.o qstring.o qdict.o qemu-config.o +obj-y += qemu-config.o obj-$(CONFIG_BRLAPI) += baum.o obj-$(CONFIG_WIN32) += tap-win32.o @@ -125,6 +125,9 @@ obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o obj-$(CONFIG_COCOA) += cocoa.o obj-$(CONFIG_IOTHREAD) += qemu-thread.o +objects-obj-y = qint.o qstring.o qdict.o +obj-y += $(addprefix objects/, $(objects-obj-y)) + slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o slirp-obj-y += tcp_subr.o tcp_timer.o udp.o bootp.o tftp.o @@ -179,15 +182,17 @@ qemu-io$(EXESUF): qemu-io.o qemu-tool.o cmd.o $(block-obj-y) qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@") -check-qint: check-qint.o qint.o qemu-malloc.o -check-qstring: check-qstring.o qstring.o qemu-malloc.o -check-qdict: check-qdict.o qdict.o qint.o qstring.o qemu-malloc.o +check-qint: check-qint.o objects/qint.o qemu-malloc.o +check-qstring: check-qstring.o objects/qstring.o qemu-malloc.o +check-qdict: check-qdict.o objects/qdict.o objects/qint.o \ + objects/qstring.o qemu-malloc.o clean: # avoid old build problems by removing potentially incorrect old files rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f *.o *.d *.a $(TOOLS) TAGS cscope.* *.pod *~ */*~ rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d + rm -f objects/*.o objects/*.d rm -f qemu-img-cmds.h $(MAKE) -C tests clean for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser; do \ @@ -370,4 +375,4 @@ tarbin: $(mandir)/man8/qemu-nbd.8 # Include automatically generated dependency files --include $(wildcard *.d audio/*.d slirp/*.d block/*.d) +-include $(wildcard *.d audio/*.d slirp/*.d block/*.d objects/*.d) diff --git a/check-qdict.c b/check-qdict.c index c37d448..20341c3 100644 --- a/check-qdict.c +++ b/check-qdict.c @@ -8,9 +8,9 @@ */ #include -#include "qint.h" -#include "qdict.h" -#include "qstring.h" +#include "objects/qint.h" +#include "objects/qdict.h" +#include "objects/qstring.h" #include "qemu-common.h" /* diff --git a/check-qint.c b/check-qint.c index 49887bb..5795959 100644 --- a/check-qint.c +++ b/check-qint.c @@ -8,7 +8,7 @@ */ #include -#include "qint.h" +#include "objects/qint.h" #include "qemu-common.h" /* diff --git a/check-qstring.c b/check-qstring.c index ea4dfd0..872f550 100644 --- a/check-qstring.c +++ b/check-qstring.c @@ -8,7 +8,7 @@ */ #include -#include "qstring.h" +#include "objects/qstring.h" #include "qemu-common.h" /* diff --git a/console.h b/console.h index 9615f56..e1b19a4 100644 --- a/console.h +++ b/console.h @@ -2,7 +2,7 @@ #define CONSOLE_H #include "qemu-char.h" -#include "qdict.h" +#include "objects/qdict.h" /* keyboard/mouse support */ diff --git a/migration.h b/migration.h index 53b923d..5e5dab5 100644 --- a/migration.h +++ b/migration.h @@ -14,7 +14,7 @@ #ifndef QEMU_MIGRATION_H #define QEMU_MIGRATION_H -#include "qdict.h" +#include "objects/qdict.h" #include "qemu-common.h" #define MIG_STATE_ERROR -1 diff --git a/monitor.c b/monitor.c index f105a2e..58e0234 100644 --- a/monitor.c +++ b/monitor.c @@ -44,9 +44,9 @@ #include "migration.h" #include "kvm.h" #include "acl.h" -#include "qint.h" -#include "qdict.h" -#include "qstring.h" +#include "objects/qint.h" +#include "objects/qdict.h" +#include "objects/qstring.h" //#define DEBUG //#define DEBUG_COMPLETION diff --git a/monitor.h b/monitor.h index c7d2d0b..c13b567 100644 --- a/monitor.h +++ b/monitor.h @@ -3,7 +3,7 @@ #include "qemu-common.h" #include "qemu-char.h" -#include "qdict.h" +#include "objects/qdict.h" #include "block.h" extern Monitor *cur_mon; diff --git a/net.h b/net.h index 1479826..2effe16 100644 --- a/net.h +++ b/net.h @@ -3,7 +3,7 @@ #include "qemu-queue.h" #include "qemu-common.h" -#include "qdict.h" +#include "objects/qdict.h" /* VLANs support */ diff --git a/objects/qdict.c b/objects/qdict.c new file mode 100644 index 0000000..7e075da --- /dev/null +++ b/objects/qdict.c @@ -0,0 +1,297 @@ +/* + * QDict data type. + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include "objects/qint.h" +#include "objects/qdict.h" +#include "objects/qstring.h" +#include "objects/qobject.h" +#include "qemu-queue.h" +#include "qemu-common.h" + +static void qdict_destroy_obj(QObject *obj); + +static const QType qdict_type = { + .code = QTYPE_QDICT, + .destroy = qdict_destroy_obj, +}; + +/** + * qdict_new(): Create a new QDict + * + * Return strong reference. + */ +QDict *qdict_new(void) +{ + QDict *qdict; + + qdict = qemu_mallocz(sizeof(*qdict)); + QOBJECT_INIT(qdict, &qdict_type); + + return qdict; +} + +/** + * qobject_to_qdict(): Convert a QObject into a QDict + */ +QDict *qobject_to_qdict(const QObject *obj) +{ + if (qobject_type(obj) != QTYPE_QDICT) + return NULL; + + return container_of(obj, QDict, base); +} + +/** + * tdb_hash(): based on the hash agorithm from gdbm, via tdb + * (from module-init-tools) + */ +static unsigned int tdb_hash(const char *name) +{ + unsigned value; /* Used to compute the hash value. */ + unsigned i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) + value = (value + (((const unsigned char *)name)[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + +/** + * alloc_entry(): allocate a new QDictEntry + */ +static QDictEntry *alloc_entry(const char *key, QObject *value) +{ + QDictEntry *entry; + + entry = qemu_mallocz(sizeof(*entry)); + entry->key = qemu_strdup(key); + entry->value = value; + + return entry; +} + +/** + * qdict_find(): List lookup function + */ +static QDictEntry *qdict_find(const QDict *qdict, + const char *key, unsigned int hash) +{ + QDictEntry *entry; + + QLIST_FOREACH(entry, &qdict->table[hash], next) + if (!strcmp(entry->key, key)) + return entry; + + return NULL; +} + +/** + * qdict_put_obj(): Put a new QObject into the dictionary + * + * Insert the pair 'key:value' into 'qdict', if 'key' already exists + * its 'value' will be replaced. + * + * This is done by freeing the reference to the stored QObject and + * storing the new one in the same entry. + * + * NOTE: ownership of 'value' is transferred to the QDict + */ +void qdict_put_obj(QDict *qdict, const char *key, QObject *value) +{ + unsigned int hash; + QDictEntry *entry; + + hash = tdb_hash(key) % QDICT_HASH_SIZE; + entry = qdict_find(qdict, key, hash); + if (entry) { + /* replace key's value */ + qobject_decref(entry->value); + entry->value = value; + } else { + /* allocate a new entry */ + entry = alloc_entry(key, value); + QLIST_INSERT_HEAD(&qdict->table[hash], entry, next); + } + + qdict->size++; +} + +/** + * qdict_get(): Lookup for a given 'key' + * + * Return a weak reference to the QObject associated with 'key' if + * 'key' is present in the dictionary, NULL otherwise. + */ +QObject *qdict_get(const QDict *qdict, const char *key) +{ + QDictEntry *entry; + + entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); + return (entry == NULL ? NULL : entry->value); +} + +/** + * qdict_haskey(): Check if 'key' exists + * + * Return 1 if 'key' exists in the dict, 0 otherwise + */ +int qdict_haskey(const QDict *qdict, const char *key) +{ + unsigned int hash = tdb_hash(key) % QDICT_HASH_SIZE; + return (qdict_find(qdict, key, hash) == NULL ? 0 : 1); +} + +/** + * qdict_size(): Return the size of the dictionary + */ +size_t qdict_size(const QDict *qdict) +{ + return qdict->size; +} + +/** + * qdict_get_obj(): Get a QObject of a specific type + */ +static QObject *qdict_get_obj(const QDict *qdict, const char *key, + qtype_code type) +{ + QObject *obj; + + obj = qdict_get(qdict, key); + assert(obj != NULL); + assert(qobject_type(obj) == type); + + return obj; +} + +/** + * qdict_get_int(): Get an integer mapped by 'key' + * + * This function assumes that 'key' exists and it stores a + * QInt object. + * + * Return integer mapped by 'key'. + */ +int64_t qdict_get_int(const QDict *qdict, const char *key) +{ + QObject *obj = qdict_get_obj(qdict, key, QTYPE_QINT); + return qint_get_int(qobject_to_qint(obj)); +} + +/** + * qdict_get_str(): Get a pointer to the stored string mapped + * by 'key' + * + * This function assumes that 'key' exists and it stores a + * QString object. + * + * Return pointer to the string mapped by 'key'. + */ +const char *qdict_get_str(const QDict *qdict, const char *key) +{ + QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING); + return qstring_get_str(qobject_to_qstring(obj)); +} + +/** + * qdict_get_try_int(): Try to get integer mapped by 'key' + * + * Return integer mapped by 'key', if it is not present in + * the dictionary or if the stored object is not of QInt type + * 'err_value' will be returned. + */ +int64_t qdict_get_try_int(const QDict *qdict, const char *key, + int64_t err_value) +{ + QObject *obj; + + obj = qdict_get(qdict, key); + if (!obj || qobject_type(obj) != QTYPE_QINT) + return err_value; + + return qint_get_int(qobject_to_qint(obj)); +} + +/** + * qdict_get_try_str(): Try to get a pointer to the stored string + * mapped by 'key' + * + * Return a pointer to the string mapped by 'key', if it is not present + * in the dictionary or if the stored object is not of QString type + * NULL will be returned. + */ +const char *qdict_get_try_str(const QDict *qdict, const char *key) +{ + QObject *obj; + + obj = qdict_get(qdict, key); + if (!obj || qobject_type(obj) != QTYPE_QSTRING) + return NULL; + + return qstring_get_str(qobject_to_qstring(obj)); +} + +/** + * qentry_destroy(): Free all the memory allocated by a QDictEntry + */ +static void qentry_destroy(QDictEntry *e) +{ + assert(e != NULL); + assert(e->key != NULL); + assert(e->value != NULL); + + qobject_decref(e->value); + qemu_free(e->key); + qemu_free(e); +} + +/** + * qdict_del(): Delete a 'key:value' pair from the dictionary + * + * This will destroy all data allocated by this entry. + */ +void qdict_del(QDict *qdict, const char *key) +{ + QDictEntry *entry; + + entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); + if (entry) { + QLIST_REMOVE(entry, next); + qentry_destroy(entry); + qdict->size--; + } +} + +/** + * qdict_destroy_obj(): Free all the memory allocated by a QDict + */ +static void qdict_destroy_obj(QObject *obj) +{ + int i; + QDict *qdict; + + assert(obj != NULL); + qdict = qobject_to_qdict(obj); + + for (i = 0; i < QDICT_HASH_SIZE; i++) { + QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); + while (entry) { + QDictEntry *tmp = QLIST_NEXT(entry, next); + QLIST_REMOVE(entry, next); + qentry_destroy(entry); + entry = tmp; + } + } + + qemu_free(qdict); +} diff --git a/objects/qdict.h b/objects/qdict.h new file mode 100644 index 0000000..0fca131 --- /dev/null +++ b/objects/qdict.h @@ -0,0 +1,42 @@ +#ifndef QDICT_H +#define QDICT_H + +#include +#include "qemu-queue.h" +#include "objects/qobject.h" + +#define QDICT_HASH_SIZE 512 + +typedef struct QDictEntry { + char *key; + QObject *value; + QLIST_ENTRY(QDictEntry) next; +} QDictEntry; + +typedef struct QDict { + QObject_HEAD; + size_t size; + QLIST_HEAD(,QDictEntry) table[QDICT_HASH_SIZE]; +} QDict; + +/* Object API */ +QDict *qdict_new(void); +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); +QDict *qobject_to_qdict(const QObject *obj); + +/* Helper to qdict_put_obj(), accepts any object */ +#define qdict_put(qdict, key, obj) \ + qdict_put_obj(qdict, key, QOBJECT(obj)) + +/* High level helpers */ +int64_t qdict_get_int(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 err_value); +const char *qdict_get_try_str(const QDict *qdict, const char *key); + +#endif /* QDICT_H */ diff --git a/objects/qint.c b/objects/qint.c new file mode 100644 index 0000000..2f91656 --- /dev/null +++ b/objects/qint.c @@ -0,0 +1,66 @@ +/* + * QInt data type. + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ +#include "objects/qint.h" +#include "objects/qobject.h" +#include "qemu-common.h" + +static void qint_destroy_obj(QObject *obj); + +static const QType qint_type = { + .code = QTYPE_QINT, + .destroy = qint_destroy_obj, +}; + +/** + * qint_from_int(): Create a new QInt from an int64_t + * + * Return strong reference. + */ +QInt *qint_from_int(int64_t value) +{ + QInt *qi; + + qi = qemu_malloc(sizeof(*qi)); + qi->value = value; + QOBJECT_INIT(qi, &qint_type); + + return qi; +} + +/** + * qint_get_int(): Get the stored integer + */ +int64_t qint_get_int(const QInt *qi) +{ + return qi->value; +} + +/** + * qobject_to_qint(): Convert a QObject into a QInt + */ +QInt *qobject_to_qint(const QObject *obj) +{ + if (qobject_type(obj) != QTYPE_QINT) + return NULL; + + return container_of(obj, QInt, base); +} + +/** + * qint_destroy_obj(): Free all memory allocated by a + * QInt object + */ +static void qint_destroy_obj(QObject *obj) +{ + assert(obj != NULL); + qemu_free(qobject_to_qint(obj)); +} diff --git a/objects/qint.h b/objects/qint.h new file mode 100644 index 0000000..4e1a3f8 --- /dev/null +++ b/objects/qint.h @@ -0,0 +1,16 @@ +#ifndef QINT_H +#define QINT_H + +#include +#include "objects/qobject.h" + +typedef struct QInt { + QObject_HEAD; + int64_t value; +} QInt; + +QInt *qint_from_int(int64_t value); +int64_t qint_get_int(const QInt *qi); +QInt *qobject_to_qint(const QObject *obj); + +#endif /* QINT_H */ diff --git a/objects/qobject.h b/objects/qobject.h new file mode 100644 index 0000000..39b8649 --- /dev/null +++ b/objects/qobject.h @@ -0,0 +1,109 @@ +/* + * QEMU Object Model. + * + * Based on ideas by Avi Kivity + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING 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 QDECREF() 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 QINCREF() 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 + * QDECREF() 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 +#include + +typedef enum { + QTYPE_NONE, + QTYPE_QINT, + QTYPE_QSTRING, + QTYPE_QDICT, +} qtype_code; + +struct QObject; + +typedef struct QType { + qtype_code code; + void (*destroy)(struct QObject *); +} QType; + +typedef struct QObject { + const QType *type; + size_t refcnt; +} QObject; + +/* Objects definitions must include this */ +#define QObject_HEAD \ + QObject base + +/* Get the 'base' part of an object */ +#define QOBJECT(obj) (&obj->base) + +/* High-level interface for qobject_incref() */ +#define QINCREF(obj) \ + assert(obj != NULL); \ + qobject_incref(QOBJECT(obj)) + +/* High-level interface for qobject_decref() */ +#define QDECREF(obj) \ + assert(obj != NULL); \ + qobject_decref(QOBJECT(obj)) + +/* Initialize an object to default values */ +#define QOBJECT_INIT(obj, qtype_type) \ + obj->base.refcnt = 1; \ + obj->base.type = qtype_type + +/** + * qobject_incref(): Increment QObject's reference count + */ +static inline void qobject_incref(QObject *obj) +{ + obj->refcnt++; +} + +/** + * qobject_decref(): Decrement QObject's reference count, deallocate + * when it reaches zero + */ +static inline void qobject_decref(QObject *obj) +{ + if (--obj->refcnt == 0) { + assert(obj->type != NULL); + assert(obj->type->destroy != NULL); + obj->type->destroy(obj); + } +} + +/** + * qobject_type(): Return the QObject's type + */ +static inline qtype_code qobject_type(const QObject *obj) +{ + assert(obj->type != NULL); + return obj->type->code; +} + +#endif /* QOBJECT_H */ diff --git a/objects/qstring.c b/objects/qstring.c new file mode 100644 index 0000000..906245f --- /dev/null +++ b/objects/qstring.c @@ -0,0 +1,73 @@ +/* + * QString data type. + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ +#include "objects/qobject.h" +#include "objects/qstring.h" +#include "qemu-common.h" + +static void qstring_destroy_obj(QObject *obj); + +static const QType qstring_type = { + .code = QTYPE_QSTRING, + .destroy = qstring_destroy_obj, +}; + +/** + * qstring_from_str(): Create a new QString from a regular C string + * + * Return strong reference. + */ +QString *qstring_from_str(const char *str) +{ + QString *qstring; + + qstring = qemu_malloc(sizeof(*qstring)); + qstring->string = qemu_strdup(str); + QOBJECT_INIT(qstring, &qstring_type); + + return qstring; +} + +/** + * qobject_to_qstring(): Convert a QObject to a QString + */ +QString *qobject_to_qstring(const QObject *obj) +{ + if (qobject_type(obj) != QTYPE_QSTRING) + return NULL; + + return container_of(obj, QString, base); +} + +/** + * qstring_get_str(): Return a pointer to the stored string + * + * NOTE: Should be used with caution, if the object is deallocated + * this pointer becomes invalid. + */ +const char *qstring_get_str(const QString *qstring) +{ + return qstring->string; +} + +/** + * qstring_destroy_obj(): Free all memory allocated by a QString + * object + */ +static void qstring_destroy_obj(QObject *obj) +{ + QString *qs; + + assert(obj != NULL); + qs = qobject_to_qstring(obj); + qemu_free(qs->string); + qemu_free(qs); +} diff --git a/objects/qstring.h b/objects/qstring.h new file mode 100644 index 0000000..a83c018 --- /dev/null +++ b/objects/qstring.h @@ -0,0 +1,15 @@ +#ifndef QSTRING_H +#define QSTRING_H + +#include "objects/qobject.h" + +typedef struct QString { + QObject_HEAD; + char *string; +} QString; + +QString *qstring_from_str(const char *str); +const char *qstring_get_str(const QString *qstring); +QString *qobject_to_qstring(const QObject *obj); + +#endif /* QSTRING_H */ diff --git a/qdict.c b/qdict.c deleted file mode 100644 index a302f4c..0000000 --- a/qdict.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * QDict data type. - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - * Luiz Capitulino - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - */ - -#include "qint.h" -#include "qdict.h" -#include "qstring.h" -#include "qobject.h" -#include "qemu-queue.h" -#include "qemu-common.h" - -static void qdict_destroy_obj(QObject *obj); - -static const QType qdict_type = { - .code = QTYPE_QDICT, - .destroy = qdict_destroy_obj, -}; - -/** - * qdict_new(): Create a new QDict - * - * Return strong reference. - */ -QDict *qdict_new(void) -{ - QDict *qdict; - - qdict = qemu_mallocz(sizeof(*qdict)); - QOBJECT_INIT(qdict, &qdict_type); - - return qdict; -} - -/** - * qobject_to_qdict(): Convert a QObject into a QDict - */ -QDict *qobject_to_qdict(const QObject *obj) -{ - if (qobject_type(obj) != QTYPE_QDICT) - return NULL; - - return container_of(obj, QDict, base); -} - -/** - * tdb_hash(): based on the hash agorithm from gdbm, via tdb - * (from module-init-tools) - */ -static unsigned int tdb_hash(const char *name) -{ - unsigned value; /* Used to compute the hash value. */ - unsigned i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) - value = (value + (((const unsigned char *)name)[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - -/** - * alloc_entry(): allocate a new QDictEntry - */ -static QDictEntry *alloc_entry(const char *key, QObject *value) -{ - QDictEntry *entry; - - entry = qemu_mallocz(sizeof(*entry)); - entry->key = qemu_strdup(key); - entry->value = value; - - return entry; -} - -/** - * qdict_find(): List lookup function - */ -static QDictEntry *qdict_find(const QDict *qdict, - const char *key, unsigned int hash) -{ - QDictEntry *entry; - - QLIST_FOREACH(entry, &qdict->table[hash], next) - if (!strcmp(entry->key, key)) - return entry; - - return NULL; -} - -/** - * qdict_put_obj(): Put a new QObject into the dictionary - * - * Insert the pair 'key:value' into 'qdict', if 'key' already exists - * its 'value' will be replaced. - * - * This is done by freeing the reference to the stored QObject and - * storing the new one in the same entry. - * - * NOTE: ownership of 'value' is transferred to the QDict - */ -void qdict_put_obj(QDict *qdict, const char *key, QObject *value) -{ - unsigned int hash; - QDictEntry *entry; - - hash = tdb_hash(key) % QDICT_HASH_SIZE; - entry = qdict_find(qdict, key, hash); - if (entry) { - /* replace key's value */ - qobject_decref(entry->value); - entry->value = value; - } else { - /* allocate a new entry */ - entry = alloc_entry(key, value); - QLIST_INSERT_HEAD(&qdict->table[hash], entry, next); - } - - qdict->size++; -} - -/** - * qdict_get(): Lookup for a given 'key' - * - * Return a weak reference to the QObject associated with 'key' if - * 'key' is present in the dictionary, NULL otherwise. - */ -QObject *qdict_get(const QDict *qdict, const char *key) -{ - QDictEntry *entry; - - entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); - return (entry == NULL ? NULL : entry->value); -} - -/** - * qdict_haskey(): Check if 'key' exists - * - * Return 1 if 'key' exists in the dict, 0 otherwise - */ -int qdict_haskey(const QDict *qdict, const char *key) -{ - unsigned int hash = tdb_hash(key) % QDICT_HASH_SIZE; - return (qdict_find(qdict, key, hash) == NULL ? 0 : 1); -} - -/** - * qdict_size(): Return the size of the dictionary - */ -size_t qdict_size(const QDict *qdict) -{ - return qdict->size; -} - -/** - * qdict_get_obj(): Get a QObject of a specific type - */ -static QObject *qdict_get_obj(const QDict *qdict, const char *key, - qtype_code type) -{ - QObject *obj; - - obj = qdict_get(qdict, key); - assert(obj != NULL); - assert(qobject_type(obj) == type); - - return obj; -} - -/** - * qdict_get_int(): Get an integer mapped by 'key' - * - * This function assumes that 'key' exists and it stores a - * QInt object. - * - * Return integer mapped by 'key'. - */ -int64_t qdict_get_int(const QDict *qdict, const char *key) -{ - QObject *obj = qdict_get_obj(qdict, key, QTYPE_QINT); - return qint_get_int(qobject_to_qint(obj)); -} - -/** - * qdict_get_str(): Get a pointer to the stored string mapped - * by 'key' - * - * This function assumes that 'key' exists and it stores a - * QString object. - * - * Return pointer to the string mapped by 'key'. - */ -const char *qdict_get_str(const QDict *qdict, const char *key) -{ - QObject *obj = qdict_get_obj(qdict, key, QTYPE_QSTRING); - return qstring_get_str(qobject_to_qstring(obj)); -} - -/** - * qdict_get_try_int(): Try to get integer mapped by 'key' - * - * Return integer mapped by 'key', if it is not present in - * the dictionary or if the stored object is not of QInt type - * 'err_value' will be returned. - */ -int64_t qdict_get_try_int(const QDict *qdict, const char *key, - int64_t err_value) -{ - QObject *obj; - - obj = qdict_get(qdict, key); - if (!obj || qobject_type(obj) != QTYPE_QINT) - return err_value; - - return qint_get_int(qobject_to_qint(obj)); -} - -/** - * qdict_get_try_str(): Try to get a pointer to the stored string - * mapped by 'key' - * - * Return a pointer to the string mapped by 'key', if it is not present - * in the dictionary or if the stored object is not of QString type - * NULL will be returned. - */ -const char *qdict_get_try_str(const QDict *qdict, const char *key) -{ - QObject *obj; - - obj = qdict_get(qdict, key); - if (!obj || qobject_type(obj) != QTYPE_QSTRING) - return NULL; - - return qstring_get_str(qobject_to_qstring(obj)); -} - -/** - * qentry_destroy(): Free all the memory allocated by a QDictEntry - */ -static void qentry_destroy(QDictEntry *e) -{ - assert(e != NULL); - assert(e->key != NULL); - assert(e->value != NULL); - - qobject_decref(e->value); - qemu_free(e->key); - qemu_free(e); -} - -/** - * qdict_del(): Delete a 'key:value' pair from the dictionary - * - * This will destroy all data allocated by this entry. - */ -void qdict_del(QDict *qdict, const char *key) -{ - QDictEntry *entry; - - entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); - if (entry) { - QLIST_REMOVE(entry, next); - qentry_destroy(entry); - qdict->size--; - } -} - -/** - * qdict_destroy_obj(): Free all the memory allocated by a QDict - */ -static void qdict_destroy_obj(QObject *obj) -{ - int i; - QDict *qdict; - - assert(obj != NULL); - qdict = qobject_to_qdict(obj); - - for (i = 0; i < QDICT_HASH_SIZE; i++) { - QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); - while (entry) { - QDictEntry *tmp = QLIST_NEXT(entry, next); - QLIST_REMOVE(entry, next); - qentry_destroy(entry); - entry = tmp; - } - } - - qemu_free(qdict); -} diff --git a/qdict.h b/qdict.h deleted file mode 100644 index 3102ca2..0000000 --- a/qdict.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef QDICT_H -#define QDICT_H - -#include "qobject.h" -#include "qemu-queue.h" -#include - -#define QDICT_HASH_SIZE 512 - -typedef struct QDictEntry { - char *key; - QObject *value; - QLIST_ENTRY(QDictEntry) next; -} QDictEntry; - -typedef struct QDict { - QObject_HEAD; - size_t size; - QLIST_HEAD(,QDictEntry) table[QDICT_HASH_SIZE]; -} QDict; - -/* Object API */ -QDict *qdict_new(void); -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); -QDict *qobject_to_qdict(const QObject *obj); - -/* Helper to qdict_put_obj(), accepts any object */ -#define qdict_put(qdict, key, obj) \ - qdict_put_obj(qdict, key, QOBJECT(obj)) - -/* High level helpers */ -int64_t qdict_get_int(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 err_value); -const char *qdict_get_try_str(const QDict *qdict, const char *key); - -#endif /* QDICT_H */ diff --git a/qint.c b/qint.c deleted file mode 100644 index 447e847..0000000 --- a/qint.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * QInt data type. - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - * Luiz Capitulino - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - */ -#include "qint.h" -#include "qobject.h" -#include "qemu-common.h" - -static void qint_destroy_obj(QObject *obj); - -static const QType qint_type = { - .code = QTYPE_QINT, - .destroy = qint_destroy_obj, -}; - -/** - * qint_from_int(): Create a new QInt from an int64_t - * - * Return strong reference. - */ -QInt *qint_from_int(int64_t value) -{ - QInt *qi; - - qi = qemu_malloc(sizeof(*qi)); - qi->value = value; - QOBJECT_INIT(qi, &qint_type); - - return qi; -} - -/** - * qint_get_int(): Get the stored integer - */ -int64_t qint_get_int(const QInt *qi) -{ - return qi->value; -} - -/** - * qobject_to_qint(): Convert a QObject into a QInt - */ -QInt *qobject_to_qint(const QObject *obj) -{ - if (qobject_type(obj) != QTYPE_QINT) - return NULL; - - return container_of(obj, QInt, base); -} - -/** - * qint_destroy_obj(): Free all memory allocated by a - * QInt object - */ -static void qint_destroy_obj(QObject *obj) -{ - assert(obj != NULL); - qemu_free(qobject_to_qint(obj)); -} diff --git a/qint.h b/qint.h deleted file mode 100644 index 672b321..0000000 --- a/qint.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef QINT_H -#define QINT_H - -#include -#include "qobject.h" - -typedef struct QInt { - QObject_HEAD; - int64_t value; -} QInt; - -QInt *qint_from_int(int64_t value); -int64_t qint_get_int(const QInt *qi); -QInt *qobject_to_qint(const QObject *obj); - -#endif /* QINT_H */ diff --git a/qobject.h b/qobject.h deleted file mode 100644 index 39b8649..0000000 --- a/qobject.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * QEMU Object Model. - * - * Based on ideas by Avi Kivity - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - * Luiz Capitulino - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING 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 QDECREF() 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 QINCREF() 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 - * QDECREF() 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 -#include - -typedef enum { - QTYPE_NONE, - QTYPE_QINT, - QTYPE_QSTRING, - QTYPE_QDICT, -} qtype_code; - -struct QObject; - -typedef struct QType { - qtype_code code; - void (*destroy)(struct QObject *); -} QType; - -typedef struct QObject { - const QType *type; - size_t refcnt; -} QObject; - -/* Objects definitions must include this */ -#define QObject_HEAD \ - QObject base - -/* Get the 'base' part of an object */ -#define QOBJECT(obj) (&obj->base) - -/* High-level interface for qobject_incref() */ -#define QINCREF(obj) \ - assert(obj != NULL); \ - qobject_incref(QOBJECT(obj)) - -/* High-level interface for qobject_decref() */ -#define QDECREF(obj) \ - assert(obj != NULL); \ - qobject_decref(QOBJECT(obj)) - -/* Initialize an object to default values */ -#define QOBJECT_INIT(obj, qtype_type) \ - obj->base.refcnt = 1; \ - obj->base.type = qtype_type - -/** - * qobject_incref(): Increment QObject's reference count - */ -static inline void qobject_incref(QObject *obj) -{ - obj->refcnt++; -} - -/** - * qobject_decref(): Decrement QObject's reference count, deallocate - * when it reaches zero - */ -static inline void qobject_decref(QObject *obj) -{ - if (--obj->refcnt == 0) { - assert(obj->type != NULL); - assert(obj->type->destroy != NULL); - obj->type->destroy(obj); - } -} - -/** - * qobject_type(): Return the QObject's type - */ -static inline qtype_code qobject_type(const QObject *obj) -{ - assert(obj->type != NULL); - return obj->type->code; -} - -#endif /* QOBJECT_H */ diff --git a/qstring.c b/qstring.c deleted file mode 100644 index 6d411da..0000000 --- a/qstring.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * QString data type. - * - * Copyright (C) 2009 Red Hat Inc. - * - * Authors: - * Luiz Capitulino - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - */ -#include "qobject.h" -#include "qstring.h" -#include "qemu-common.h" - -static void qstring_destroy_obj(QObject *obj); - -static const QType qstring_type = { - .code = QTYPE_QSTRING, - .destroy = qstring_destroy_obj, -}; - -/** - * qstring_from_str(): Create a new QString from a regular C string - * - * Return strong reference. - */ -QString *qstring_from_str(const char *str) -{ - QString *qstring; - - qstring = qemu_malloc(sizeof(*qstring)); - qstring->string = qemu_strdup(str); - QOBJECT_INIT(qstring, &qstring_type); - - return qstring; -} - -/** - * qobject_to_qstring(): Convert a QObject to a QString - */ -QString *qobject_to_qstring(const QObject *obj) -{ - if (qobject_type(obj) != QTYPE_QSTRING) - return NULL; - - return container_of(obj, QString, base); -} - -/** - * qstring_get_str(): Return a pointer to the stored string - * - * NOTE: Should be used with caution, if the object is deallocated - * this pointer becomes invalid. - */ -const char *qstring_get_str(const QString *qstring) -{ - return qstring->string; -} - -/** - * qstring_destroy_obj(): Free all memory allocated by a QString - * object - */ -static void qstring_destroy_obj(QObject *obj) -{ - QString *qs; - - assert(obj != NULL); - qs = qobject_to_qstring(obj); - qemu_free(qs->string); - qemu_free(qs); -} diff --git a/qstring.h b/qstring.h deleted file mode 100644 index e012cb7..0000000 --- a/qstring.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef QSTRING_H -#define QSTRING_H - -#include "qobject.h" - -typedef struct QString { - QObject_HEAD; - char *string; -} QString; - -QString *qstring_from_str(const char *str); -const char *qstring_get_str(const QString *qstring); -QString *qobject_to_qstring(const QObject *obj); - -#endif /* QSTRING_H */ diff --git a/sysemu.h b/sysemu.h index 8bf90ee..1414560 100644 --- a/sysemu.h +++ b/sysemu.h @@ -5,7 +5,7 @@ #include "qemu-common.h" #include "qemu-option.h" #include "qemu-queue.h" -#include "qdict.h" +#include "objects/qdict.h" #ifdef _WIN32 #include