[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v1 09/16] io: pull Buffer code out of VNC module
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH v1 09/16] io: pull Buffer code out of VNC module |
Date: |
Tue, 22 Sep 2015 14:04:35 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 |
On 18/09/2015 15:19, Daniel P. Berrange wrote:
> The Buffer code in the VNC server is useful for the IO channel
> code, so pull it out into a shared module, QIOBuffer.
Do all traces disappear from VNC once you're done? If not, can you
instead move it to util/?
Paolo
> Signed-off-by: Daniel P. Berrange <address@hidden>
> ---
> include/io/buffer.h | 118
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
> io/Makefile.objs | 3 +-
> io/buffer.c | 65 +++++++++++++++++++++++++++++
> ui/vnc-auth-sasl.c | 4 +-
> ui/vnc-enc-tight.c | 38 ++++++++---------
> ui/vnc-enc-zlib.c | 6 +--
> ui/vnc-enc-zrle.c | 18 ++++----
> ui/vnc-jobs.c | 15 +++----
> ui/vnc-ws.c | 36 ++++++++--------
> ui/vnc-ws.h | 6 +--
> ui/vnc.c | 67 ++++++-----------------------
> ui/vnc.h | 50 ++++++++--------------
> 12 files changed, 277 insertions(+), 149 deletions(-)
> create mode 100644 include/io/buffer.h
> create mode 100644 io/buffer.c
>
> diff --git a/include/io/buffer.h b/include/io/buffer.h
> new file mode 100644
> index 0000000..2b1b261
> --- /dev/null
> +++ b/include/io/buffer.h
> @@ -0,0 +1,118 @@
> +/*
> + * QEMU I/O buffers
> + *
> + * Copyright (c) 2015 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#ifndef QIO_BUFFER_H__
> +#define QIO_BUFFER_H__
> +
> +#include "qemu-common.h"
> +
> +typedef struct QIOBuffer QIOBuffer;
> +
> +/**
> + * QIOBuffer:
> + *
> + * The QIOBuffer object provides a simple dynamically resizing
> + * array, with separate tracking of capacity and usage. This
> + * is typically useful when buffering I/O data.
> + */
> +
> +struct QIOBuffer {
> + size_t capacity;
> + size_t offset;
> + uint8_t *buffer;
> +};
> +
> +/**
> + * qio_buffer_reserve:
> + * @buffer: the buffer object
> + * @len: the minimum required free space
> + *
> + * Ensure that the buffer has space allocated for at least
> + * @len bytes. If the current buffer is too small, it will
> + * be reallocated, possibly to a larger size than requested.
> + */
> +void qio_buffer_reserve(QIOBuffer *buffer, size_t len);
> +
> +/**
> + * qio_buffer_reset:
> + * @buffer: the buffer object
> + *
> + * Reset the length of the stored data to zero, but do
> + * not free / reallocate the memory buffer
> + */
> +void qio_buffer_reset(QIOBuffer *buffer);
> +
> +/**
> + * qio_buffer_free:
> + * @buffer: the buffer object
> + *
> + * Reset the length of the stored data to zero and also
> + * free the internal memory buffer
> + */
> +void qio_buffer_free(QIOBuffer *buffer);
> +
> +/**
> + * qio_buffer_append:
> + * @buffer: the buffer object
> + * @data: the data block to append
> + * @len: the length of @data in bytes
> + *
> + * Append the contents of @data to the end of the buffer.
> + * The caller must ensure that the buffer has sufficient
> + * free space for @len bytes, typically by calling the
> + * qio_buffer_reserve() method prior to appending.
> + */
> +void qio_buffer_append(QIOBuffer *buffer, const void *data, size_t len);
> +
> +/**
> + * qio_buffer_advance:
> + * @buffer: the buffer object
> + * @len: the number of bytes to skip
> + *
> + * Remove @len bytes of data from the head of the buffer.
> + * The internal buffer will not be reallocated, so will
> + * have at least @len bytes of free space after this
> + * call completes
> + */
> +void qio_buffer_advance(QIOBuffer *buffer, size_t len);
> +
> +/**
> + * qio_buffer_end:
> + * @buffer: the buffer object
> + *
> + * Get a pointer to the tail end of the internal buffer
> + * The returned pointer is only valid until the next
> + * call to qio_buffer_reserve().
> + *
> + * Returns: the tail of the buffer
> + */
> +uint8_t *qio_buffer_end(QIOBuffer *buffer);
> +
> +/**
> + * qio_buffer_empty:
> + * @buffer: the buffer object
> + *
> + * Determine if the buffer contains any current data
> + *
> + * Returns: true if the buffer holds data, false otherwise
> + */
> +gboolean qio_buffer_empty(QIOBuffer *buffer);
> +
> +#endif /* QIO_BUFFER_H__ */
> diff --git a/io/Makefile.objs b/io/Makefile.objs
> index b02ea90..593ed9e 100644
> --- a/io/Makefile.objs
> +++ b/io/Makefile.objs
> @@ -1,2 +1,3 @@
> -io-obj-y = channel.o
> +io-obj-y = buffer.o
> +io-obj-y += channel.o
> io-obj-y += channel-watch.o
> diff --git a/io/buffer.c b/io/buffer.c
> new file mode 100644
> index 0000000..68ae68d
> --- /dev/null
> +++ b/io/buffer.c
> @@ -0,0 +1,65 @@
> +/*
> + * QEMU I/O buffers
> + *
> + * Copyright (c) 2015 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see
> <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#include "io/buffer.h"
> +
> +void qio_buffer_reserve(QIOBuffer *buffer, size_t len)
> +{
> + if ((buffer->capacity - buffer->offset) < len) {
> + buffer->capacity += (len + 1024);
> + buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
> + }
> +}
> +
> +gboolean qio_buffer_empty(QIOBuffer *buffer)
> +{
> + return buffer->offset == 0;
> +}
> +
> +uint8_t *qio_buffer_end(QIOBuffer *buffer)
> +{
> + return buffer->buffer + buffer->offset;
> +}
> +
> +void qio_buffer_reset(QIOBuffer *buffer)
> +{
> + buffer->offset = 0;
> +}
> +
> +void qio_buffer_free(QIOBuffer *buffer)
> +{
> + g_free(buffer->buffer);
> + buffer->offset = 0;
> + buffer->capacity = 0;
> + buffer->buffer = NULL;
> +}
> +
> +void qio_buffer_append(QIOBuffer *buffer, const void *data, size_t len)
> +{
> + memcpy(buffer->buffer + buffer->offset, data, len);
> + buffer->offset += len;
> +}
> +
> +void qio_buffer_advance(QIOBuffer *buffer, size_t len)
> +{
> + memmove(buffer->buffer, buffer->buffer + len,
> + (buffer->offset - len));
> + buffer->offset -= len;
> +}
> diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
> index fc732bd..d118266 100644
> --- a/ui/vnc-auth-sasl.c
> +++ b/ui/vnc-auth-sasl.c
> @@ -113,8 +113,8 @@ long vnc_client_read_sasl(VncState *vs)
> return vnc_client_io_error(vs, -1, -EIO);
> VNC_DEBUG("Read SASL Encoded %p size %ld Decoded %p size %d\n",
> encoded, ret, decoded, decodedLen);
> - buffer_reserve(&vs->input, decodedLen);
> - buffer_append(&vs->input, decoded, decodedLen);
> + qio_buffer_reserve(&vs->input, decodedLen);
> + qio_buffer_append(&vs->input, decoded, decodedLen);
> return decodedLen;
> }
>
> diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
> index 9a9ddf2..772ec79 100644
> --- a/ui/vnc-enc-tight.c
> +++ b/ui/vnc-enc-tight.c
> @@ -856,7 +856,7 @@ static int tight_compress_data(VncState *vs, int
> stream_id, size_t bytes,
> }
>
> /* reserve memory in output buffer */
> - buffer_reserve(&vs->tight.zlib, bytes + 64);
> + qio_buffer_reserve(&vs->tight.zlib, bytes + 64);
>
> /* set pointers */
> zstream->next_in = vs->tight.tight.buffer;
> @@ -879,7 +879,7 @@ static int tight_compress_data(VncState *vs, int
> stream_id, size_t bytes,
> tight_send_compact_size(vs, bytes);
> vnc_write(vs, vs->tight.zlib.buffer, bytes);
>
> - buffer_reset(&vs->tight.zlib);
> + qio_buffer_reset(&vs->tight.zlib);
>
> return bytes;
> }
> @@ -1053,7 +1053,7 @@ static bool send_gradient_rect(VncState *vs, int x, int
> y, int w, int h)
> vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
> vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT);
>
> - buffer_reserve(&vs->tight.gradient, w * 3 * sizeof (int));
> + qio_buffer_reserve(&vs->tight.gradient, w * 3 * sizeof(int));
>
> if (vs->tight.pixel24) {
> tight_filter_gradient24(vs, vs->tight.tight.buffer, w, h);
> @@ -1066,7 +1066,7 @@ static bool send_gradient_rect(VncState *vs, int x, int
> y, int w, int h)
> bytes = 2;
> }
>
> - buffer_reset(&vs->tight.gradient);
> + qio_buffer_reset(&vs->tight.gradient);
>
> bytes = w * h * bytes;
> vs->tight.tight.offset = bytes;
> @@ -1149,7 +1149,7 @@ static int send_palette_rect(VncState *vs, int x, int y,
> static void jpeg_init_destination(j_compress_ptr cinfo)
> {
> VncState *vs = cinfo->client_data;
> - Buffer *buffer = &vs->tight.jpeg;
> + QIOBuffer *buffer = &vs->tight.jpeg;
>
> cinfo->dest->next_output_byte = (JOCTET *)buffer->buffer +
> buffer->offset;
> cinfo->dest->free_in_buffer = (size_t)(buffer->capacity -
> buffer->offset);
> @@ -1159,10 +1159,10 @@ static void jpeg_init_destination(j_compress_ptr
> cinfo)
> static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
> {
> VncState *vs = cinfo->client_data;
> - Buffer *buffer = &vs->tight.jpeg;
> + QIOBuffer *buffer = &vs->tight.jpeg;
>
> buffer->offset = buffer->capacity;
> - buffer_reserve(buffer, 2048);
> + qio_buffer_reserve(buffer, 2048);
> jpeg_init_destination(cinfo);
> return TRUE;
> }
> @@ -1171,7 +1171,7 @@ static boolean jpeg_empty_output_buffer(j_compress_ptr
> cinfo)
> static void jpeg_term_destination(j_compress_ptr cinfo)
> {
> VncState *vs = cinfo->client_data;
> - Buffer *buffer = &vs->tight.jpeg;
> + QIOBuffer *buffer = &vs->tight.jpeg;
>
> buffer->offset = buffer->capacity - cinfo->dest->free_in_buffer;
> }
> @@ -1190,7 +1190,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y,
> int w, int h, int quality)
> return send_full_color_rect(vs, x, y, w, h);
> }
>
> - buffer_reserve(&vs->tight.jpeg, 2048);
> + qio_buffer_reserve(&vs->tight.jpeg, 2048);
>
> cinfo.err = jpeg_std_error(&jerr);
> jpeg_create_compress(&cinfo);
> @@ -1227,7 +1227,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y,
> int w, int h, int quality)
>
> tight_send_compact_size(vs, vs->tight.jpeg.offset);
> vnc_write(vs, vs->tight.jpeg.buffer, vs->tight.jpeg.offset);
> - buffer_reset(&vs->tight.jpeg);
> + qio_buffer_reset(&vs->tight.jpeg);
>
> return 1;
> }
> @@ -1270,7 +1270,7 @@ static void png_write_data(png_structp png_ptr,
> png_bytep data,
> {
> VncState *vs = png_get_io_ptr(png_ptr);
>
> - buffer_reserve(&vs->tight.png, vs->tight.png.offset + length);
> + qio_buffer_reserve(&vs->tight.png, vs->tight.png.offset + length);
> memcpy(vs->tight.png.buffer + vs->tight.png.offset, data, length);
>
> vs->tight.png.offset += length;
> @@ -1351,7 +1351,7 @@ static int send_png_rect(VncState *vs, int x, int y,
> int w, int h,
>
> png_write_info(png_ptr, info_ptr);
>
> - buffer_reserve(&vs->tight.png, 2048);
> + qio_buffer_reserve(&vs->tight.png, 2048);
> linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w);
> buf = (uint8_t *)pixman_image_get_data(linebuf);
> for (dy = 0; dy < h; dy++)
> @@ -1377,14 +1377,14 @@ static int send_png_rect(VncState *vs, int x, int y,
> int w, int h,
>
> tight_send_compact_size(vs, vs->tight.png.offset);
> vnc_write(vs, vs->tight.png.buffer, vs->tight.png.offset);
> - buffer_reset(&vs->tight.png);
> + qio_buffer_reset(&vs->tight.png);
> return 1;
> }
> #endif /* CONFIG_VNC_PNG */
>
> static void vnc_tight_start(VncState *vs)
> {
> - buffer_reset(&vs->tight.tight);
> + qio_buffer_reset(&vs->tight.tight);
>
> // make the output buffer be the zlib buffer, so we can compress it later
> vs->tight.tmp = vs->output;
> @@ -1686,13 +1686,13 @@ void vnc_tight_clear(VncState *vs)
> }
> }
>
> - buffer_free(&vs->tight.tight);
> - buffer_free(&vs->tight.zlib);
> - buffer_free(&vs->tight.gradient);
> + qio_buffer_free(&vs->tight.tight);
> + qio_buffer_free(&vs->tight.zlib);
> + qio_buffer_free(&vs->tight.gradient);
> #ifdef CONFIG_VNC_JPEG
> - buffer_free(&vs->tight.jpeg);
> + qio_buffer_free(&vs->tight.jpeg);
> #endif
> #ifdef CONFIG_VNC_PNG
> - buffer_free(&vs->tight.png);
> + qio_buffer_free(&vs->tight.png);
> #endif
> }
> diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
> index d1b97f2..47ba146 100644
> --- a/ui/vnc-enc-zlib.c
> +++ b/ui/vnc-enc-zlib.c
> @@ -47,7 +47,7 @@ void vnc_zlib_zfree(void *x, void *addr)
>
> static void vnc_zlib_start(VncState *vs)
> {
> - buffer_reset(&vs->zlib.zlib);
> + qio_buffer_reset(&vs->zlib.zlib);
>
> // make the output buffer be the zlib buffer, so we can compress it later
> vs->zlib.tmp = vs->output;
> @@ -96,7 +96,7 @@ static int vnc_zlib_stop(VncState *vs)
> }
>
> // reserve memory in output buffer
> - buffer_reserve(&vs->output, vs->zlib.zlib.offset + 64);
> + qio_buffer_reserve(&vs->output, vs->zlib.zlib.offset + 64);
>
> // set pointers
> zstream->next_in = vs->zlib.zlib.buffer;
> @@ -148,5 +148,5 @@ void vnc_zlib_clear(VncState *vs)
> if (vs->zlib.stream.opaque) {
> deflateEnd(&vs->zlib.stream);
> }
> - buffer_free(&vs->zlib.zlib);
> + qio_buffer_free(&vs->zlib.zlib);
> }
> diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c
> index ed3b484..bd1e320 100644
> --- a/ui/vnc-enc-zrle.c
> +++ b/ui/vnc-enc-zrle.c
> @@ -36,7 +36,7 @@ static const int bits_per_packed_pixel[] = {
>
> static void vnc_zrle_start(VncState *vs)
> {
> - buffer_reset(&vs->zrle.zrle);
> + qio_buffer_reset(&vs->zrle.zrle);
>
> /* make the output buffer be the zlib buffer, so we can compress it
> later */
> vs->zrle.tmp = vs->output;
> @@ -53,10 +53,10 @@ static void vnc_zrle_stop(VncState *vs)
> static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h,
> int bpp)
> {
> - Buffer tmp;
> + QIOBuffer tmp;
>
> - buffer_reset(&vs->zrle.fb);
> - buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
> + qio_buffer_reset(&vs->zrle.fb);
> + qio_buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
>
> tmp = vs->output;
> vs->output = vs->zrle.fb;
> @@ -72,7 +72,7 @@ static int zrle_compress_data(VncState *vs, int level)
> {
> z_streamp zstream = &vs->zrle.stream;
>
> - buffer_reset(&vs->zrle.zlib);
> + qio_buffer_reset(&vs->zrle.zlib);
>
> if (zstream->opaque != vs) {
> int err;
> @@ -92,7 +92,7 @@ static int zrle_compress_data(VncState *vs, int level)
> }
>
> /* reserve memory in output buffer */
> - buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
> + qio_buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
>
> /* set pointers */
> zstream->next_in = vs->zrle.zrle.buffer;
> @@ -360,7 +360,7 @@ void vnc_zrle_clear(VncState *vs)
> if (vs->zrle.stream.opaque) {
> deflateEnd(&vs->zrle.stream);
> }
> - buffer_free(&vs->zrle.zrle);
> - buffer_free(&vs->zrle.fb);
> - buffer_free(&vs->zrle.zlib);
> + qio_buffer_free(&vs->zrle.zrle);
> + qio_buffer_free(&vs->zrle.fb);
> + qio_buffer_free(&vs->zrle.zlib);
> }
> diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
> index 22c9abc..9824c34 100644
> --- a/ui/vnc-jobs.c
> +++ b/ui/vnc-jobs.c
> @@ -54,7 +54,7 @@ struct VncJobQueue {
> QemuCond cond;
> QemuMutex mutex;
> QemuThread thread;
> - Buffer buffer;
> + QIOBuffer buffer;
> bool exit;
> QTAILQ_HEAD(, VncJob) jobs;
> };
> @@ -167,7 +167,7 @@ void vnc_jobs_consume_buffer(VncState *vs)
> vnc_lock_output(vs);
> if (vs->jobs_buffer.offset) {
> vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset);
> - buffer_reset(&vs->jobs_buffer);
> + qio_buffer_reset(&vs->jobs_buffer);
> }
> flush = vs->csock != -1 && vs->abort != true;
> vnc_unlock_output(vs);
> @@ -196,7 +196,7 @@ static void vnc_async_encoding_start(VncState *orig,
> VncState *local)
> local->output = queue->buffer;
> local->csock = -1; /* Don't do any network work on this thread */
>
> - buffer_reset(&local->output);
> + qio_buffer_reset(&local->output);
> }
>
> static void vnc_async_encoding_end(VncState *orig, VncState *local)
> @@ -273,10 +273,11 @@ static int vnc_worker_thread_loop(VncJobQueue *queue)
> vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
>
> vnc_lock_output(job->vs);
> +
> if (job->vs->csock != -1) {
> - buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
> - buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
> - vs.output.offset);
> + qio_buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
> + qio_buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
> + vs.output.offset);
> /* Copy persistent encoding data */
> vnc_async_encoding_end(job->vs, &vs);
>
> @@ -310,7 +311,7 @@ static void vnc_queue_clear(VncJobQueue *q)
> {
> qemu_cond_destroy(&queue->cond);
> qemu_mutex_destroy(&queue->mutex);
> - buffer_free(&queue->buffer);
> + qio_buffer_free(&queue->buffer);
> g_free(q);
> queue = NULL; /* Unset global queue */
> }
> diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
> index 175ea50..2fe4476 100644
> --- a/ui/vnc-ws.c
> +++ b/ui/vnc-ws.c
> @@ -95,8 +95,8 @@ void vncws_handshake_read(void *opaque)
> /* Typical HTTP headers from novnc are 512 bytes, so limiting
> * total header size to 4096 is easily enough. */
> size_t want = 4096 - vs->ws_input.offset;
> - buffer_reserve(&vs->ws_input, want);
> - ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want);
> + qio_buffer_reserve(&vs->ws_input, want);
> + ret = vnc_client_read_buf(vs, qio_buffer_end(&vs->ws_input), want);
>
> if (!ret) {
> if (vs->csock == -1) {
> @@ -111,7 +111,7 @@ void vncws_handshake_read(void *opaque)
> if (handshake_end) {
> qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
> vncws_process_handshake(vs, vs->ws_input.buffer,
> vs->ws_input.offset);
> - buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer +
> + qio_buffer_advance(&vs->ws_input, handshake_end -
> vs->ws_input.buffer +
> strlen(WS_HANDSHAKE_END));
> } else if (vs->ws_input.offset >= 4096) {
> VNC_DEBUG("End of headers not found in first 4096 bytes\n");
> @@ -127,8 +127,8 @@ long vnc_client_read_ws(VncState *vs)
> size_t payload_size, header_size;
> VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer,
> vs->ws_input.capacity, vs->ws_input.offset);
> - buffer_reserve(&vs->ws_input, 4096);
> - ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096);
> + qio_buffer_reserve(&vs->ws_input, 4096);
> + ret = vnc_client_read_buf(vs, qio_buffer_end(&vs->ws_input), 4096);
> if (!ret) {
> return 0;
> }
> @@ -146,7 +146,7 @@ long vnc_client_read_ws(VncState *vs)
> return err;
> }
>
> - buffer_advance(&vs->ws_input, header_size);
> + qio_buffer_advance(&vs->ws_input, header_size);
> }
> if (vs->ws_payload_remain != 0) {
> err = vncws_decode_frame_payload(&vs->ws_input,
> @@ -162,10 +162,10 @@ long vnc_client_read_ws(VncState *vs)
> }
> ret += err;
>
> - buffer_reserve(&vs->input, payload_size);
> - buffer_append(&vs->input, payload, payload_size);
> + qio_buffer_reserve(&vs->input, payload_size);
> + qio_buffer_append(&vs->input, payload, payload_size);
>
> - buffer_advance(&vs->ws_input, payload_size);
> + qio_buffer_advance(&vs->ws_input, payload_size);
> }
> } while (vs->ws_input.offset > 0);
>
> @@ -178,13 +178,13 @@ long vnc_client_write_ws(VncState *vs)
> VNC_DEBUG("Write WS: Pending output %p size %zd offset %zd\n",
> vs->output.buffer, vs->output.capacity, vs->output.offset);
> vncws_encode_frame(&vs->ws_output, vs->output.buffer, vs->output.offset);
> - buffer_reset(&vs->output);
> + qio_buffer_reset(&vs->output);
> ret = vnc_client_write_buf(vs, vs->ws_output.buffer,
> vs->ws_output.offset);
> if (!ret) {
> return 0;
> }
>
> - buffer_advance(&vs->ws_output, ret);
> + qio_buffer_advance(&vs->ws_output, ret);
>
> if (vs->ws_output.offset == 0) {
> qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
> @@ -267,8 +267,8 @@ void vncws_process_handshake(VncState *vs, uint8_t *line,
> size_t size)
> g_free(key);
> }
>
> -void vncws_encode_frame(Buffer *output, const void *payload,
> - const size_t payload_size)
> +void vncws_encode_frame(QIOBuffer *output, const void *payload,
> + const size_t payload_size)
> {
> size_t header_size = 0;
> unsigned char opcode = WS_OPCODE_BINARY_FRAME;
> @@ -295,12 +295,12 @@ void vncws_encode_frame(Buffer *output, const void
> *payload,
> header_size = 10;
> }
>
> - buffer_reserve(output, header_size + payload_size);
> - buffer_append(output, header.buf, header_size);
> - buffer_append(output, payload, payload_size);
> + qio_buffer_reserve(output, header_size + payload_size);
> + qio_buffer_append(output, header.buf, header_size);
> + qio_buffer_append(output, payload, payload_size);
> }
>
> -int vncws_decode_frame_header(Buffer *input,
> +int vncws_decode_frame_header(QIOBuffer *input,
> size_t *header_size,
> size_t *payload_remain,
> WsMask *payload_mask)
> @@ -354,7 +354,7 @@ int vncws_decode_frame_header(Buffer *input,
> return 1;
> }
>
> -int vncws_decode_frame_payload(Buffer *input,
> +int vncws_decode_frame_payload(QIOBuffer *input,
> size_t *payload_remain, WsMask *payload_mask,
> uint8_t **payload, size_t *payload_size)
> {
> diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h
> index 4ab0a8c..2a222a8 100644
> --- a/ui/vnc-ws.h
> +++ b/ui/vnc-ws.h
> @@ -77,13 +77,13 @@ void vncws_handshake_read(void *opaque);
> long vnc_client_write_ws(VncState *vs);
> long vnc_client_read_ws(VncState *vs);
> void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size);
> -void vncws_encode_frame(Buffer *output, const void *payload,
> +void vncws_encode_frame(QIOBuffer *output, const void *payload,
> const size_t payload_size);
> -int vncws_decode_frame_header(Buffer *input,
> +int vncws_decode_frame_header(QIOBuffer *input,
> size_t *header_size,
> size_t *payload_remain,
> WsMask *payload_mask);
> -int vncws_decode_frame_payload(Buffer *input,
> +int vncws_decode_frame_payload(QIOBuffer *input,
> size_t *payload_remain, WsMask *payload_mask,
> uint8_t **payload, size_t *payload_size);
>
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 952e551..c4dec90 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -647,49 +647,6 @@ void vnc_framebuffer_update(VncState *vs, int x, int y,
> int w, int h,
> vnc_write_s32(vs, encoding);
> }
>
> -void buffer_reserve(Buffer *buffer, size_t len)
> -{
> - if ((buffer->capacity - buffer->offset) < len) {
> - buffer->capacity += (len + 1024);
> - buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
> - }
> -}
> -
> -static int buffer_empty(Buffer *buffer)
> -{
> - return buffer->offset == 0;
> -}
> -
> -uint8_t *buffer_end(Buffer *buffer)
> -{
> - return buffer->buffer + buffer->offset;
> -}
> -
> -void buffer_reset(Buffer *buffer)
> -{
> - buffer->offset = 0;
> -}
> -
> -void buffer_free(Buffer *buffer)
> -{
> - g_free(buffer->buffer);
> - buffer->offset = 0;
> - buffer->capacity = 0;
> - buffer->buffer = NULL;
> -}
> -
> -void buffer_append(Buffer *buffer, const void *data, size_t len)
> -{
> - memcpy(buffer->buffer + buffer->offset, data, len);
> - buffer->offset += len;
> -}
> -
> -void buffer_advance(Buffer *buf, size_t len)
> -{
> - memmove(buf->buffer, buf->buffer + len,
> - (buf->offset - len));
> - buf->offset -= len;
> -}
>
> static void vnc_desktop_resize(VncState *vs)
> {
> @@ -1220,10 +1177,10 @@ void vnc_disconnect_finish(VncState *vs)
> vnc_lock_output(vs);
> vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
>
> - buffer_free(&vs->input);
> - buffer_free(&vs->output);
> - buffer_free(&vs->ws_input);
> - buffer_free(&vs->ws_output);
> + qio_buffer_free(&vs->input);
> + qio_buffer_free(&vs->output);
> + qio_buffer_free(&vs->ws_input);
> + qio_buffer_free(&vs->ws_output);
>
> qapi_free_VncClientInfo(vs->info);
>
> @@ -1251,7 +1208,7 @@ void vnc_disconnect_finish(VncState *vs)
> if (vs->bh != NULL) {
> qemu_bh_delete(vs->bh);
> }
> - buffer_free(&vs->jobs_buffer);
> + qio_buffer_free(&vs->jobs_buffer);
>
> for (i = 0; i < VNC_STAT_ROWS; ++i) {
> g_free(vs->lossy_rect[i]);
> @@ -1393,7 +1350,7 @@ static ssize_t vnc_client_write_plain(VncState *vs)
> if (!ret)
> return 0;
>
> - buffer_advance(&vs->output, ret);
> + qio_buffer_advance(&vs->output, ret);
>
> if (vs->output.offset == 0) {
> qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
> @@ -1496,8 +1453,8 @@ static ssize_t vnc_client_read_plain(VncState *vs)
> ssize_t ret;
> VNC_DEBUG("Read plain %p size %zd offset %zd\n",
> vs->input.buffer, vs->input.capacity, vs->input.offset);
> - buffer_reserve(&vs->input, 4096);
> - ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
> + qio_buffer_reserve(&vs->input, 4096);
> + ret = vnc_client_read_buf(vs, qio_buffer_end(&vs->input), 4096);
> if (!ret)
> return 0;
> vs->input.offset += ret;
> @@ -1555,7 +1512,7 @@ void vnc_client_read(void *opaque)
> }
>
> if (!ret) {
> - buffer_advance(&vs->input, len);
> + qio_buffer_advance(&vs->input, len);
> } else {
> vs->read_handler_expect = ret;
> }
> @@ -1564,13 +1521,13 @@ void vnc_client_read(void *opaque)
>
> void vnc_write(VncState *vs, const void *data, size_t len)
> {
> - buffer_reserve(&vs->output, len);
> + qio_buffer_reserve(&vs->output, len);
>
> - if (vs->csock != -1 && buffer_empty(&vs->output)) {
> + if (vs->csock != -1 && qio_buffer_empty(&vs->output)) {
> qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write,
> vs);
> }
>
> - buffer_append(&vs->output, data, len);
> + qio_buffer_append(&vs->output, data, len);
> }
>
> void vnc_write_s32(VncState *vs, int32_t value)
> diff --git a/ui/vnc.h b/ui/vnc.h
> index 4dd769c..339a1bf 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -34,6 +34,7 @@
> #include "audio/audio.h"
> #include "qemu/bitmap.h"
> #include "crypto/tlssession.h"
> +#include "io/buffer.h"
> #include <zlib.h>
> #include <stdbool.h>
>
> @@ -56,13 +57,6 @@
> *
>
> *****************************************************************************/
>
> -typedef struct Buffer
> -{
> - size_t capacity;
> - size_t offset;
> - uint8_t *buffer;
> -} Buffer;
> -
> typedef struct VncState VncState;
> typedef struct VncJob VncJob;
> typedef struct VncRect VncRect;
> @@ -191,15 +185,15 @@ typedef struct VncTight {
> uint8_t quality;
> uint8_t compression;
> uint8_t pixel24;
> - Buffer tight;
> - Buffer tmp;
> - Buffer zlib;
> - Buffer gradient;
> + QIOBuffer tight;
> + QIOBuffer tmp;
> + QIOBuffer zlib;
> + QIOBuffer gradient;
> #ifdef CONFIG_VNC_JPEG
> - Buffer jpeg;
> + QIOBuffer jpeg;
> #endif
> #ifdef CONFIG_VNC_PNG
> - Buffer png;
> + QIOBuffer png;
> #endif
> int levels[4];
> z_stream stream[4];
> @@ -210,18 +204,18 @@ typedef struct VncHextile {
> } VncHextile;
>
> typedef struct VncZlib {
> - Buffer zlib;
> - Buffer tmp;
> + QIOBuffer zlib;
> + QIOBuffer tmp;
> z_stream stream;
> int level;
> } VncZlib;
>
> typedef struct VncZrle {
> int type;
> - Buffer fb;
> - Buffer zrle;
> - Buffer tmp;
> - Buffer zlib;
> + QIOBuffer fb;
> + QIOBuffer zrle;
> + QIOBuffer tmp;
> + QIOBuffer zlib;
> z_stream stream;
> VncPalette palette;
> } VncZrle;
> @@ -290,10 +284,10 @@ struct VncState
>
> VncClientInfo *info;
>
> - Buffer output;
> - Buffer input;
> - Buffer ws_input;
> - Buffer ws_output;
> + QIOBuffer output;
> + QIOBuffer input;
> + QIOBuffer ws_input;
> + QIOBuffer ws_output;
> size_t ws_payload_remain;
> WsMask ws_payload_mask;
> /* current output mode information */
> @@ -315,7 +309,7 @@ struct VncState
> bool initialized;
> QemuMutex output_mutex;
> QEMUBH *bh;
> - Buffer jobs_buffer;
> + QIOBuffer jobs_buffer;
>
> /* Encoding specific, if you add something here, don't forget to
> * update vnc_async_encoding_start()
> @@ -535,14 +529,6 @@ ssize_t vnc_client_io_error(VncState *vs, ssize_t ret,
> int last_errno);
> void start_client_init(VncState *vs);
> void start_auth_vnc(VncState *vs);
>
> -/* Buffer management */
> -void buffer_reserve(Buffer *buffer, size_t len);
> -void buffer_reset(Buffer *buffer);
> -void buffer_free(Buffer *buffer);
> -void buffer_append(Buffer *buffer, const void *data, size_t len);
> -void buffer_advance(Buffer *buf, size_t len);
> -uint8_t *buffer_end(Buffer *buffer);
> -
>
> /* Misc helpers */
>
>
- Re: [Qemu-devel] [PATCH v1 07/16] io: add abstract QIOChannel classes, (continued)
[Qemu-devel] [PATCH v1 10/16] io: add QIOTask class for async operations, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 16/16] io: add QIOChannelBuffer class, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 08/16] io: add helper module for creating watches on FDs, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 11/16] io: add QIOChannelSocket class, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 04/16] ui: convert VNC startup code to use SocketAddress, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 06/16] coroutine: move into libqemuutil.a library, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 09/16] io: pull Buffer code out of VNC module, Daniel P. Berrange, 2015/09/18
- Re: [Qemu-devel] [PATCH v1 09/16] io: pull Buffer code out of VNC module,
Paolo Bonzini <=
[Qemu-devel] [PATCH v1 03/16] sockets: allow port to be NULL when listening on IP address, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 01/16] sockets: add helpers for creating SocketAddress from a socket, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 15/16] io: add QIOChannelCommand class, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 13/16] io: add QIOChannelTLS class, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 12/16] io: add QIOChannelFile class, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 05/16] osdep: add qemu_fork() wrapper for safely handling signals, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 02/16] sockets: move qapi_copy_SocketAddress into qemu-sockets.c, Daniel P. Berrange, 2015/09/18
[Qemu-devel] [PATCH v1 14/16] io: add QIOChannelWebsock class, Daniel P. Berrange, 2015/09/18