From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:42529) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEW-0004Uq-5R for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlAEJ-0005Zt-Pq for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:18 -0400 Received: from e3.ny.us.ibm.com ([32.97.182.143]:43467) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlAEJ-0005Zd-Aq for qemu-devel@nongnu.org; Sun, 24 Jul 2011 21:45:11 -0400 Received: from d01relay04.pok.ibm.com (d01relay04.pok.ibm.com [9.56.227.236]) by e3.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p6P1LXJV004963 for ; Sun, 24 Jul 2011 21:21:33 -0400 Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay04.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p6P1jAvP135640 for ; Sun, 24 Jul 2011 21:45:10 -0400 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p6P1jAUM008053 for ; Sun, 24 Jul 2011 21:45:10 -0400 From: Anthony Liguori Date: Sun, 24 Jul 2011 20:44:50 -0500 Message-Id: <1311558293-5855-19-git-send-email-aliguori@us.ibm.com> In-Reply-To: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> References: <1311558293-5855-1-git-send-email-aliguori@us.ibm.com> Subject: [Qemu-devel] [PATCH 18/21] qom-chrdrv: add memory character driver List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori This is used primarly by QMP. Signed-off-by: Anthony Liguori --- chrdrv/Makefile | 1 + chrdrv/Qconfig | 7 +++++ chrdrv/memchr.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/qemu/memchr.h | 46 ++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 0 deletions(-) create mode 100644 chrdrv/memchr.c create mode 100644 include/qemu/memchr.h diff --git a/chrdrv/Makefile b/chrdrv/Makefile index 43a51e7..6cfdd27 100644 --- a/chrdrv/Makefile +++ b/chrdrv/Makefile @@ -1 +1,2 @@ chrdrv-obj-$(CONFIG_CHRDRV) := chrdrv.o +chrdrv-obj-$(CONFIG_CHRDRV_MEM) += memchr.o diff --git a/chrdrv/Qconfig b/chrdrv/Qconfig index 845c205..f3f939e 100644 --- a/chrdrv/Qconfig +++ b/chrdrv/Qconfig @@ -3,3 +3,10 @@ config CHRDRV default y help Character layer + +config CHRDRV_MEM + bool "Memory character device" + default y + depends on CHRDRV + help + Character device that stores all written data to a memory buffer. diff --git a/chrdrv/memchr.c b/chrdrv/memchr.c new file mode 100644 index 0000000..3046d2e --- /dev/null +++ b/chrdrv/memchr.c @@ -0,0 +1,70 @@ +#include "qemu/memchr.h" + +void memory_char_driver_initialize(MemoryCharDriver *d, const char *id) +{ + type_initialize(d, TYPE_MEMORY_CHAR_DRIVER, id); +} + +void memory_char_driver_finalize(MemoryCharDriver *d) +{ + type_finalize(d); +} + +static int memory_char_driver_write(CharDriver *chr, const uint8_t *buf, + int len) +{ + MemoryCharDriver *d = MEMORY_CHAR_DRIVER(chr); + + /* TODO: the QString implementation has the same code, we should + * introduce a generic way to do this in cutils.c */ + if (d->outbuf_capacity < d->outbuf_size + len) { + /* grow outbuf */ + d->outbuf_capacity += len; + d->outbuf_capacity *= 2; + d->outbuf = qemu_realloc(d->outbuf, d->outbuf_capacity); + } + + memcpy(d->outbuf + d->outbuf_size, buf, len); + d->outbuf_size += len; + + return len; +} + +size_t memory_char_driver_get_osize(MemoryCharDriver *d) +{ + return d->outbuf_size; +} + +QString *memory_char_driver_get_qs(MemoryCharDriver *d) +{ + return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1); +} + +static void memory_char_driver_fini(TypeInstance *inst) +{ + MemoryCharDriver *d = MEMORY_CHAR_DRIVER(inst); + + qemu_free(d->outbuf); +} + +static void memory_char_driver_class_init(TypeClass *class) +{ + CharDriverClass *cdc = CHAR_DRIVER_CLASS(class); + + cdc->write = memory_char_driver_write; +} + +static TypeInfo memory_char_driver_type_info = { + .name = TYPE_MEMORY_CHAR_DRIVER, + .parent = TYPE_CHAR_DRIVER, + .instance_size = sizeof(MemoryCharDriver), + .class_init = memory_char_driver_class_init, + .instance_finalize = memory_char_driver_fini, +}; + +static void register_backends(void) +{ + type_register_static(&memory_char_driver_type_info); +} + +device_init(register_backends); diff --git a/include/qemu/memchr.h b/include/qemu/memchr.h new file mode 100644 index 0000000..0744684 --- /dev/null +++ b/include/qemu/memchr.h @@ -0,0 +1,46 @@ +#ifndef CHAR_DRIVER_MEM_H +#define CHAR_DRIVER_MEM_H + +#include "qemu/chrdrv.h" + +/** + * @MemoryCharDriver: + * + * A @CharDriver that stores all written data to memory. This is useful for + * interfacing directly with objects that expect to work with a @CharDriver. + * + * The accumulated data can be obtained as a QString. + */ +typedef struct MemoryCharDriver +{ + CharDriver parent; + + /* Private */ + size_t outbuf_size; + size_t outbuf_capacity; + uint8_t *outbuf; +} MemoryCharDriver; + +#define TYPE_MEMORY_CHAR_DRIVER "memory-char-driver" +#define MEMORY_CHAR_DRIVER(obj) \ + TYPE_CHECK(MemoryCharDriver, obj, TYPE_MEMORY_CHAR_DRIVER) + +void memory_char_driver_initialize(MemoryCharDriver *d, const char *id); +void memory_char_driver_finalize(MemoryCharDriver *d); + +/** + * @memory_char_driver_get_osize: + * + * Returns: The size of the output buffer. + */ +size_t memory_char_driver_get_osize(MemoryCharDriver *d); + +/** + * @memory_char_driver_get_qs: + * + * Returns: A QString representing the output buffer. The reference ownership + * is transferred to the caller. + */ +QString *memory_char_driver_get_qs(MemoryCharDriver *d); + +#endif -- 1.7.4.1